58#include "llvm/ADT/APFixedPoint.h"
59#include "llvm/ADT/Sequence.h"
60#include "llvm/ADT/SmallBitVector.h"
61#include "llvm/ADT/StringExtras.h"
62#include "llvm/Support/Casting.h"
63#include "llvm/Support/Debug.h"
64#include "llvm/Support/SaveAndRestore.h"
65#include "llvm/Support/SipHash.h"
66#include "llvm/Support/TimeProfiler.h"
67#include "llvm/Support/raw_ostream.h"
73#define DEBUG_TYPE "exprconstant"
76using llvm::APFixedPoint;
80using llvm::FixedPointSemantics;
87 using SourceLocExprScopeGuard =
122 static const CallExpr *tryUnwrapAllocSizeCall(
const Expr *E) {
130 if (
const auto *FE = dyn_cast<FullExpr>(E))
133 if (
const auto *Cast = dyn_cast<CastExpr>(E))
134 E = Cast->getSubExpr()->IgnoreParens();
136 if (
const auto *CE = dyn_cast<CallExpr>(E))
137 return CE->getCalleeAllocSizeAttr() ? CE :
nullptr;
144 const auto *E =
Base.dyn_cast<
const Expr *>();
145 return E && E->getType()->isPointerType() && tryUnwrapAllocSizeCall(E);
153 case ConstantExprKind::Normal:
154 case ConstantExprKind::ClassTemplateArgument:
155 case ConstantExprKind::ImmediateInvocation:
160 case ConstantExprKind::NonClassTemplateArgument:
163 llvm_unreachable(
"unknown ConstantExprKind");
168 case ConstantExprKind::Normal:
169 case ConstantExprKind::ImmediateInvocation:
172 case ConstantExprKind::ClassTemplateArgument:
173 case ConstantExprKind::NonClassTemplateArgument:
176 llvm_unreachable(
"unknown ConstantExprKind");
182 static const uint64_t AssumedSizeForUnsizedArray =
183 std::numeric_limits<uint64_t>::max() / 2;
193 bool &FirstEntryIsUnsizedArray) {
196 assert(!isBaseAnAllocSizeCall(
Base) &&
197 "Unsized arrays shouldn't appear here");
198 unsigned MostDerivedLength = 0;
203 for (
unsigned I = 0, N = Path.size(); I != N; ++I) {
207 MostDerivedLength = I + 1;
210 if (
auto *CAT = dyn_cast<ConstantArrayType>(AT)) {
211 ArraySize = CAT->getZExtSize();
213 assert(I == 0 &&
"unexpected unsized array designator");
214 FirstEntryIsUnsizedArray =
true;
215 ArraySize = AssumedSizeForUnsizedArray;
221 MostDerivedLength = I + 1;
224 Type = VT->getElementType();
225 ArraySize = VT->getNumElements();
226 MostDerivedLength = I + 1;
228 }
else if (
const FieldDecl *FD = getAsField(Path[I])) {
229 Type = FD->getType();
231 MostDerivedLength = I + 1;
239 return MostDerivedLength;
243 struct SubobjectDesignator {
247 LLVM_PREFERRED_TYPE(
bool)
251 LLVM_PREFERRED_TYPE(
bool)
252 unsigned IsOnePastTheEnd : 1;
255 LLVM_PREFERRED_TYPE(
bool)
256 unsigned FirstEntryIsAnUnsizedArray : 1;
259 LLVM_PREFERRED_TYPE(
bool)
260 unsigned MostDerivedIsArrayElement : 1;
264 unsigned MostDerivedPathLength : 28;
273 uint64_t MostDerivedArraySize;
282 SubobjectDesignator() :
Invalid(
true) {}
284 explicit SubobjectDesignator(
QualType T)
285 :
Invalid(
false), IsOnePastTheEnd(
false),
286 FirstEntryIsAnUnsizedArray(
false), MostDerivedIsArrayElement(
false),
287 MostDerivedPathLength(0), MostDerivedArraySize(0),
291 :
Invalid(!
V.isLValue() || !
V.hasLValuePath()), IsOnePastTheEnd(
false),
292 FirstEntryIsAnUnsizedArray(
false), MostDerivedIsArrayElement(
false),
293 MostDerivedPathLength(0), MostDerivedArraySize(0) {
294 assert(
V.isLValue() &&
"Non-LValue used to make an LValue designator?");
296 IsOnePastTheEnd =
V.isLValueOnePastTheEnd();
297 llvm::append_range(Entries,
V.getLValuePath());
298 if (
V.getLValueBase()) {
299 bool IsArray =
false;
300 bool FirstIsUnsizedArray =
false;
301 MostDerivedPathLength = findMostDerivedSubobject(
302 Ctx,
V.getLValueBase(),
V.getLValuePath(), MostDerivedArraySize,
303 MostDerivedType, IsArray, FirstIsUnsizedArray);
304 MostDerivedIsArrayElement = IsArray;
305 FirstEntryIsAnUnsizedArray = FirstIsUnsizedArray;
311 unsigned NewLength) {
315 assert(
Base &&
"cannot truncate path for null pointer");
316 assert(NewLength <= Entries.size() &&
"not a truncation");
318 if (NewLength == Entries.size())
320 Entries.resize(NewLength);
322 bool IsArray =
false;
323 bool FirstIsUnsizedArray =
false;
324 MostDerivedPathLength = findMostDerivedSubobject(
325 Ctx,
Base, Entries, MostDerivedArraySize, MostDerivedType, IsArray,
326 FirstIsUnsizedArray);
327 MostDerivedIsArrayElement = IsArray;
328 FirstEntryIsAnUnsizedArray = FirstIsUnsizedArray;
338 bool isMostDerivedAnUnsizedArray()
const {
339 assert(!
Invalid &&
"Calling this makes no sense on invalid designators");
340 return Entries.size() == 1 && FirstEntryIsAnUnsizedArray;
345 uint64_t getMostDerivedArraySize()
const {
346 assert(!isMostDerivedAnUnsizedArray() &&
"Unsized array has no size");
347 return MostDerivedArraySize;
351 bool isOnePastTheEnd()
const {
355 if (!isMostDerivedAnUnsizedArray() && MostDerivedIsArrayElement &&
356 Entries[MostDerivedPathLength - 1].getAsArrayIndex() ==
357 MostDerivedArraySize)
365 std::pair<uint64_t, uint64_t> validIndexAdjustments() {
366 if (
Invalid || isMostDerivedAnUnsizedArray())
372 bool IsArray = MostDerivedPathLength == Entries.size() &&
373 MostDerivedIsArrayElement;
374 uint64_t ArrayIndex = IsArray ? Entries.back().getAsArrayIndex()
375 : (uint64_t)IsOnePastTheEnd;
377 IsArray ? getMostDerivedArraySize() : (uint64_t)1;
378 return {ArrayIndex, ArraySize - ArrayIndex};
382 bool isValidSubobject()
const {
385 return !isOnePastTheEnd();
393 assert(!
Invalid &&
"invalid designator has no subobject type");
394 return MostDerivedPathLength == Entries.size()
405 MostDerivedIsArrayElement =
true;
407 MostDerivedPathLength = Entries.size();
411 void addUnsizedArrayUnchecked(
QualType ElemTy) {
414 MostDerivedType = ElemTy;
415 MostDerivedIsArrayElement =
true;
419 MostDerivedArraySize = AssumedSizeForUnsizedArray;
420 MostDerivedPathLength = Entries.size();
424 void addDeclUnchecked(
const Decl *D,
bool Virtual =
false) {
428 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
429 MostDerivedType = FD->getType();
430 MostDerivedIsArrayElement =
false;
431 MostDerivedArraySize = 0;
432 MostDerivedPathLength = Entries.size();
436 void addComplexUnchecked(
QualType EltTy,
bool Imag) {
441 MostDerivedType = EltTy;
442 MostDerivedIsArrayElement =
true;
443 MostDerivedArraySize = 2;
444 MostDerivedPathLength = Entries.size();
447 void addVectorElementUnchecked(
QualType EltTy, uint64_t Size,
450 MostDerivedType = EltTy;
451 MostDerivedPathLength = Entries.size();
452 MostDerivedArraySize = 0;
453 MostDerivedIsArrayElement =
false;
456 void diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info,
const Expr *E);
457 void diagnosePointerArithmetic(EvalInfo &Info,
const Expr *E,
460 void adjustIndex(EvalInfo &Info,
const Expr *E,
APSInt N,
const LValue &LV);
464 enum class ScopeKind {
472 CallRef() : OrigCallee(), CallIndex(0), Version() {}
473 CallRef(
const FunctionDecl *Callee,
unsigned CallIndex,
unsigned Version)
474 : OrigCallee(Callee), CallIndex(CallIndex), Version(Version) {}
476 explicit operator bool()
const {
return OrigCallee; }
502 CallStackFrame *Caller;
524 typedef std::pair<const void *, unsigned> MapKeyTy;
525 typedef std::map<MapKeyTy, APValue>
MapTy;
537 unsigned CurTempVersion = TempVersionStack.back();
539 unsigned getTempVersion()
const {
return TempVersionStack.back(); }
541 void pushTempVersion() {
542 TempVersionStack.push_back(++CurTempVersion);
545 void popTempVersion() {
546 TempVersionStack.pop_back();
550 return {Callee, Index, ++CurTempVersion};
561 llvm::DenseMap<const ValueDecl *, FieldDecl *> LambdaCaptureFields;
562 FieldDecl *LambdaThisCaptureField =
nullptr;
564 CallStackFrame(EvalInfo &Info,
SourceRange CallRange,
570 APValue *getTemporary(
const void *Key,
unsigned Version) {
571 MapKeyTy KV(Key, Version);
572 auto LB = Temporaries.lower_bound(KV);
573 if (LB != Temporaries.end() && LB->first == KV)
579 APValue *getCurrentTemporary(
const void *Key) {
580 auto UB = Temporaries.upper_bound(MapKeyTy(Key,
UINT_MAX));
581 if (UB != Temporaries.begin() && std::prev(UB)->first.first == Key)
582 return &std::prev(UB)->second;
587 unsigned getCurrentTemporaryVersion(
const void *Key)
const {
588 auto UB = Temporaries.upper_bound(MapKeyTy(Key,
UINT_MAX));
589 if (UB != Temporaries.begin() && std::prev(UB)->first.first == Key)
590 return std::prev(UB)->first.second;
598 template<
typename KeyT>
600 ScopeKind
Scope, LValue &LV);
605 void describe(llvm::raw_ostream &OS)
const override;
607 Frame *getCaller()
const override {
return Caller; }
608 SourceRange getCallRange()
const override {
return CallRange; }
611 bool isStdFunction()
const {
612 for (
const DeclContext *DC = Callee; DC; DC = DC->getParent())
613 if (DC->isStdNamespace())
620 bool CanEvalMSConstexpr =
false;
628 class ThisOverrideRAII {
630 ThisOverrideRAII(CallStackFrame &Frame,
const LValue *NewThis,
bool Enable)
631 : Frame(Frame), OldThis(Frame.This) {
633 Frame.This = NewThis;
635 ~ThisOverrideRAII() {
636 Frame.This = OldThis;
639 CallStackFrame &Frame;
640 const LValue *OldThis;
645 class ExprTimeTraceScope {
647 ExprTimeTraceScope(
const Expr *E,
const ASTContext &Ctx, StringRef Name)
648 : TimeScope(Name, [E, &Ctx] {
653 llvm::TimeTraceScope TimeScope;
658 struct MSConstexprContextRAII {
659 CallStackFrame &Frame;
661 explicit MSConstexprContextRAII(CallStackFrame &Frame,
bool Value)
662 : Frame(Frame), OldValue(Frame.CanEvalMSConstexpr) {
663 Frame.CanEvalMSConstexpr =
Value;
666 ~MSConstexprContextRAII() { Frame.CanEvalMSConstexpr = OldValue; }
679 llvm::PointerIntPair<APValue*, 2, ScopeKind> Value;
680 APValue::LValueBase Base;
684 Cleanup(
APValue *Val, APValue::LValueBase Base, QualType T,
686 : Value(Val, Scope), Base(Base), T(T) {}
690 bool isDestroyedAtEndOf(ScopeKind K)
const {
691 return (
int)Value.getInt() >= (
int)K;
693 bool endLifetime(EvalInfo &Info,
bool RunDestructors) {
694 if (RunDestructors) {
696 if (
const ValueDecl *VD = Base.dyn_cast<
const ValueDecl*>())
697 Loc = VD->getLocation();
698 else if (
const Expr *E = Base.dyn_cast<
const Expr*>())
699 Loc = E->getExprLoc();
702 *Value.getPointer() =
APValue();
706 bool hasSideEffect() {
707 return T.isDestructedType();
712 struct ObjectUnderConstruction {
713 APValue::LValueBase Base;
714 ArrayRef<APValue::LValuePathEntry> Path;
715 friend bool operator==(
const ObjectUnderConstruction &LHS,
716 const ObjectUnderConstruction &RHS) {
717 return LHS.Base == RHS.Base && LHS.Path == RHS.Path;
719 friend llvm::hash_code
hash_value(
const ObjectUnderConstruction &Obj) {
720 return llvm::hash_combine(Obj.Base, Obj.Path);
723 enum class ConstructionPhase {
734template<>
struct DenseMapInfo<ObjectUnderConstruction> {
735 using Base = DenseMapInfo<APValue::LValueBase>;
737 return {Base::getEmptyKey(), {}}; }
739 return {Base::getTombstoneKey(), {}};
744 static bool isEqual(
const ObjectUnderConstruction &LHS,
745 const ObjectUnderConstruction &RHS) {
759 const Expr *AllocExpr =
nullptr;
770 if (
auto *NE = dyn_cast<CXXNewExpr>(AllocExpr))
771 return NE->isArray() ? ArrayNew : New;
777 struct DynAllocOrder {
778 bool operator()(DynamicAllocLValue L, DynamicAllocLValue R)
const {
800 CallStackFrame *CurrentCall;
803 unsigned CallStackDepth;
806 unsigned NextCallIndex;
815 bool EnableNewConstInterp;
819 CallStackFrame BottomFrame;
823 llvm::SmallVector<Cleanup, 16> CleanupStack;
827 APValue::LValueBase EvaluatingDecl;
829 enum class EvaluatingDeclKind {
836 EvaluatingDeclKind IsEvaluatingDecl = EvaluatingDeclKind::None;
845 SmallVector<const Stmt *> BreakContinueStack;
848 llvm::DenseMap<ObjectUnderConstruction, ConstructionPhase>
849 ObjectsUnderConstruction;
854 std::map<DynamicAllocLValue, DynAlloc, DynAllocOrder> HeapAllocs;
857 unsigned NumHeapAllocs = 0;
859 struct EvaluatingConstructorRAII {
861 ObjectUnderConstruction Object;
863 EvaluatingConstructorRAII(EvalInfo &EI, ObjectUnderConstruction Object,
865 : EI(EI), Object(Object) {
867 EI.ObjectsUnderConstruction
868 .insert({Object, HasBases ? ConstructionPhase::Bases
869 : ConstructionPhase::AfterBases})
872 void finishedConstructingBases() {
873 EI.ObjectsUnderConstruction[Object] = ConstructionPhase::AfterBases;
875 void finishedConstructingFields() {
876 EI.ObjectsUnderConstruction[Object] = ConstructionPhase::AfterFields;
878 ~EvaluatingConstructorRAII() {
879 if (DidInsert) EI.ObjectsUnderConstruction.erase(Object);
883 struct EvaluatingDestructorRAII {
885 ObjectUnderConstruction Object;
887 EvaluatingDestructorRAII(EvalInfo &EI, ObjectUnderConstruction Object)
888 : EI(EI), Object(Object) {
889 DidInsert = EI.ObjectsUnderConstruction
890 .insert({Object, ConstructionPhase::Destroying})
893 void startedDestroyingBases() {
894 EI.ObjectsUnderConstruction[Object] =
895 ConstructionPhase::DestroyingBases;
897 ~EvaluatingDestructorRAII() {
899 EI.ObjectsUnderConstruction.erase(Object);
904 isEvaluatingCtorDtor(APValue::LValueBase Base,
905 ArrayRef<APValue::LValuePathEntry> Path) {
906 return ObjectsUnderConstruction.lookup({
Base, Path});
911 unsigned SpeculativeEvaluationDepth = 0;
917 EvalInfo(
const ASTContext &
C, Expr::EvalStatus &S,
EvaluationMode Mode)
918 : State(const_cast<ASTContext &>(
C), S), CurrentCall(
nullptr),
919 CallStackDepth(0), NextCallIndex(1),
920 StepsLeft(
C.getLangOpts().ConstexprStepLimit),
921 EnableNewConstInterp(
C.getLangOpts().EnableNewConstInterp),
922 BottomFrame(*this, SourceLocation(),
nullptr,
925 EvaluatingDecl((const ValueDecl *)
nullptr),
934 void setEvaluatingDecl(APValue::LValueBase Base,
APValue &
Value,
935 EvaluatingDeclKind EDK = EvaluatingDeclKind::Ctor) {
936 EvaluatingDecl =
Base;
937 IsEvaluatingDecl = EDK;
938 EvaluatingDeclValue = &
Value;
941 bool CheckCallLimit(SourceLocation Loc) {
944 if (checkingPotentialConstantExpression() && CallStackDepth > 1)
946 if (NextCallIndex == 0) {
948 FFDiag(Loc, diag::note_constexpr_call_limit_exceeded);
951 if (CallStackDepth <= getLangOpts().ConstexprCallDepth)
953 FFDiag(Loc, diag::note_constexpr_depth_limit_exceeded)
954 << getLangOpts().ConstexprCallDepth;
959 uint64_t ElemCount,
bool Diag) {
965 ElemCount >
uint64_t(std::numeric_limits<unsigned>::max())) {
967 FFDiag(Loc, diag::note_constexpr_new_too_large) << ElemCount;
976 uint64_t Limit = getLangOpts().ConstexprStepLimit;
977 if (Limit != 0 && ElemCount > Limit) {
979 FFDiag(Loc, diag::note_constexpr_new_exceeds_limits)
980 << ElemCount << Limit;
986 std::pair<CallStackFrame *, unsigned>
987 getCallFrameAndDepth(
unsigned CallIndex) {
988 assert(CallIndex &&
"no call index in getCallFrameAndDepth");
991 unsigned Depth = CallStackDepth;
992 CallStackFrame *Frame = CurrentCall;
993 while (Frame->Index > CallIndex) {
994 Frame = Frame->Caller;
997 if (Frame->Index == CallIndex)
998 return {Frame, Depth};
1002 bool nextStep(
const Stmt *S) {
1003 if (getLangOpts().ConstexprStepLimit == 0)
1007 FFDiag(S->
getBeginLoc(), diag::note_constexpr_step_limit_exceeded);
1014 APValue *createHeapAlloc(
const Expr *E, QualType T, LValue &LV);
1016 std::optional<DynAlloc *> lookupDynamicAlloc(DynamicAllocLValue DA) {
1017 std::optional<DynAlloc *>
Result;
1018 auto It = HeapAllocs.find(DA);
1019 if (It != HeapAllocs.end())
1025 APValue *getParamSlot(CallRef
Call,
const ParmVarDecl *PVD) {
1026 CallStackFrame *Frame = getCallFrameAndDepth(
Call.CallIndex).first;
1027 return Frame ? Frame->getTemporary(
Call.getOrigParam(PVD),
Call.Version)
1032 struct StdAllocatorCaller {
1033 unsigned FrameIndex;
1036 explicit operator bool()
const {
return FrameIndex != 0; };
1039 StdAllocatorCaller getStdAllocatorCaller(StringRef FnName)
const {
1040 for (
const CallStackFrame *
Call = CurrentCall;
Call != &BottomFrame;
1042 const auto *MD = dyn_cast_or_null<CXXMethodDecl>(
Call->Callee);
1045 const IdentifierInfo *FnII = MD->getIdentifier();
1046 if (!FnII || !FnII->
isStr(FnName))
1050 dyn_cast<ClassTemplateSpecializationDecl>(MD->getParent());
1054 const IdentifierInfo *ClassII = CTSD->getIdentifier();
1055 const TemplateArgumentList &TAL = CTSD->getTemplateArgs();
1056 if (CTSD->isInStdNamespace() && ClassII &&
1057 ClassII->
isStr(
"allocator") && TAL.
size() >= 1 &&
1059 return {
Call->Index, TAL[0].getAsType(),
Call->CallExpr};
1065 void performLifetimeExtension() {
1067 llvm::erase_if(CleanupStack, [](Cleanup &
C) {
1068 return !
C.isDestroyedAtEndOf(ScopeKind::FullExpression);
1075 bool discardCleanups() {
1076 for (Cleanup &
C : CleanupStack) {
1077 if (
C.hasSideEffect() && !noteSideEffect()) {
1078 CleanupStack.clear();
1082 CleanupStack.clear();
1087 const interp::Frame *getCurrentFrame()
override {
return CurrentCall; }
1088 const interp::Frame *getBottomFrame()
const override {
return &BottomFrame; }
1090 unsigned getCallStackDepth()
override {
return CallStackDepth; }
1091 bool stepsLeft()
const override {
return StepsLeft > 0; }
1104 [[nodiscard]]
bool noteFailure() {
1112 bool KeepGoing = keepEvaluatingAfterFailure();
1113 EvalStatus.HasSideEffects |= KeepGoing;
1117 class ArrayInitLoopIndex {
1122 ArrayInitLoopIndex(EvalInfo &Info)
1123 : Info(Info), OuterIndex(Info.ArrayInitIndex) {
1124 Info.ArrayInitIndex = 0;
1126 ~ArrayInitLoopIndex() { Info.ArrayInitIndex = OuterIndex; }
1128 operator uint64_t&() {
return Info.ArrayInitIndex; }
1133 struct FoldConstant {
1136 bool HadNoPriorDiags;
1139 explicit FoldConstant(EvalInfo &Info,
bool Enabled)
1142 HadNoPriorDiags(Info.EvalStatus.
Diag &&
1143 Info.EvalStatus.
Diag->empty() &&
1144 !Info.EvalStatus.HasSideEffects),
1145 OldMode(Info.EvalMode) {
1147 Info.EvalMode = EvaluationMode::ConstantFold;
1149 void keepDiagnostics() { Enabled =
false; }
1151 if (Enabled && HadNoPriorDiags && !Info.EvalStatus.Diag->empty() &&
1152 !Info.EvalStatus.HasSideEffects)
1153 Info.EvalStatus.Diag->clear();
1154 Info.EvalMode = OldMode;
1160 struct IgnoreSideEffectsRAII {
1163 explicit IgnoreSideEffectsRAII(EvalInfo &Info)
1164 : Info(Info), OldMode(Info.EvalMode) {
1165 Info.EvalMode = EvaluationMode::IgnoreSideEffects;
1168 ~IgnoreSideEffectsRAII() { Info.EvalMode = OldMode; }
1173 class SpeculativeEvaluationRAII {
1174 EvalInfo *Info =
nullptr;
1175 Expr::EvalStatus OldStatus;
1176 unsigned OldSpeculativeEvaluationDepth = 0;
1178 void moveFromAndCancel(SpeculativeEvaluationRAII &&
Other) {
1180 OldStatus =
Other.OldStatus;
1181 OldSpeculativeEvaluationDepth =
Other.OldSpeculativeEvaluationDepth;
1182 Other.Info =
nullptr;
1185 void maybeRestoreState() {
1189 Info->EvalStatus = OldStatus;
1190 Info->SpeculativeEvaluationDepth = OldSpeculativeEvaluationDepth;
1194 SpeculativeEvaluationRAII() =
default;
1196 SpeculativeEvaluationRAII(
1197 EvalInfo &Info, SmallVectorImpl<PartialDiagnosticAt> *NewDiag =
nullptr)
1198 : Info(&Info), OldStatus(Info.EvalStatus),
1199 OldSpeculativeEvaluationDepth(Info.SpeculativeEvaluationDepth) {
1200 Info.EvalStatus.Diag = NewDiag;
1201 Info.SpeculativeEvaluationDepth = Info.CallStackDepth + 1;
1204 SpeculativeEvaluationRAII(
const SpeculativeEvaluationRAII &
Other) =
delete;
1205 SpeculativeEvaluationRAII(SpeculativeEvaluationRAII &&
Other) {
1206 moveFromAndCancel(std::move(
Other));
1209 SpeculativeEvaluationRAII &operator=(SpeculativeEvaluationRAII &&
Other) {
1210 maybeRestoreState();
1211 moveFromAndCancel(std::move(
Other));
1215 ~SpeculativeEvaluationRAII() { maybeRestoreState(); }
1220 template<ScopeKind Kind>
1223 unsigned OldStackSize;
1225 ScopeRAII(EvalInfo &Info)
1226 : Info(Info), OldStackSize(Info.CleanupStack.size()) {
1229 Info.CurrentCall->pushTempVersion();
1231 bool destroy(
bool RunDestructors =
true) {
1232 bool OK =
cleanup(Info, RunDestructors, OldStackSize);
1233 OldStackSize = std::numeric_limits<unsigned>::max();
1237 if (OldStackSize != std::numeric_limits<unsigned>::max())
1241 Info.CurrentCall->popTempVersion();
1244 static bool cleanup(EvalInfo &Info,
bool RunDestructors,
1245 unsigned OldStackSize) {
1246 assert(OldStackSize <= Info.CleanupStack.size() &&
1247 "running cleanups out of order?");
1252 for (
unsigned I = Info.CleanupStack.size(); I > OldStackSize; --I) {
1253 if (Info.CleanupStack[I - 1].isDestroyedAtEndOf(Kind)) {
1254 if (!Info.CleanupStack[I - 1].endLifetime(Info, RunDestructors)) {
1262 auto NewEnd = Info.CleanupStack.begin() + OldStackSize;
1263 if (Kind != ScopeKind::Block)
1265 std::remove_if(NewEnd, Info.CleanupStack.end(), [](Cleanup &
C) {
1266 return C.isDestroyedAtEndOf(Kind);
1268 Info.CleanupStack.erase(NewEnd, Info.CleanupStack.end());
1272 typedef ScopeRAII<ScopeKind::Block> BlockScopeRAII;
1273 typedef ScopeRAII<ScopeKind::FullExpression> FullExpressionRAII;
1274 typedef ScopeRAII<ScopeKind::Call> CallScopeRAII;
1277bool SubobjectDesignator::checkSubobject(EvalInfo &Info,
const Expr *E,
1281 if (isOnePastTheEnd()) {
1282 Info.CCEDiag(E, diag::note_constexpr_past_end_subobject)
1293void SubobjectDesignator::diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info,
1295 Info.CCEDiag(E, diag::note_constexpr_unsized_array_indexed);
1300void SubobjectDesignator::diagnosePointerArithmetic(EvalInfo &Info,
1305 if (MostDerivedPathLength == Entries.size() && MostDerivedIsArrayElement)
1306 Info.CCEDiag(E, diag::note_constexpr_array_index)
1308 <<
static_cast<unsigned>(getMostDerivedArraySize());
1310 Info.CCEDiag(E, diag::note_constexpr_array_index)
1315CallStackFrame::CallStackFrame(EvalInfo &Info, SourceRange CallRange,
1316 const FunctionDecl *Callee,
const LValue *This,
1317 const Expr *CallExpr, CallRef Call)
1319 CallExpr(CallExpr),
Arguments(Call), CallRange(CallRange),
1320 Index(Info.NextCallIndex++) {
1321 Info.CurrentCall =
this;
1322 ++Info.CallStackDepth;
1325CallStackFrame::~CallStackFrame() {
1326 assert(Info.CurrentCall ==
this &&
"calls retired out of order");
1327 --Info.CallStackDepth;
1328 Info.CurrentCall = Caller;
1353 llvm_unreachable(
"unknown access kind");
1390 llvm_unreachable(
"unknown access kind");
1394 struct ComplexValue {
1402 ComplexValue() : FloatReal(
APFloat::Bogus()), FloatImag(
APFloat::Bogus()) {}
1404 void makeComplexFloat() { IsInt =
false; }
1405 bool isComplexFloat()
const {
return !IsInt; }
1406 APFloat &getComplexFloatReal() {
return FloatReal; }
1407 APFloat &getComplexFloatImag() {
return FloatImag; }
1409 void makeComplexInt() { IsInt =
true; }
1410 bool isComplexInt()
const {
return IsInt; }
1411 APSInt &getComplexIntReal() {
return IntReal; }
1412 APSInt &getComplexIntImag() {
return IntImag; }
1414 void moveInto(
APValue &v)
const {
1415 if (isComplexFloat())
1416 v =
APValue(FloatReal, FloatImag);
1418 v =
APValue(IntReal, IntImag);
1420 void setFrom(
const APValue &v) {
1435 APValue::LValueBase
Base;
1437 SubobjectDesignator Designator;
1439 bool InvalidBase : 1;
1441 bool AllowConstexprUnknown =
false;
1443 const APValue::LValueBase getLValueBase()
const {
return Base; }
1444 bool allowConstexprUnknown()
const {
return AllowConstexprUnknown; }
1445 CharUnits &getLValueOffset() {
return Offset; }
1446 const CharUnits &getLValueOffset()
const {
return Offset; }
1447 SubobjectDesignator &getLValueDesignator() {
return Designator; }
1448 const SubobjectDesignator &getLValueDesignator()
const {
return Designator;}
1449 bool isNullPointer()
const {
return IsNullPtr;}
1451 unsigned getLValueCallIndex()
const {
return Base.getCallIndex(); }
1452 unsigned getLValueVersion()
const {
return Base.getVersion(); }
1455 if (Designator.Invalid)
1456 V =
APValue(Base, Offset, APValue::NoLValuePath(), IsNullPtr);
1458 assert(!InvalidBase &&
"APValues can't handle invalid LValue bases");
1459 V =
APValue(Base, Offset, Designator.Entries,
1460 Designator.IsOnePastTheEnd, IsNullPtr);
1462 if (AllowConstexprUnknown)
1463 V.setConstexprUnknown();
1465 void setFrom(
const ASTContext &Ctx,
const APValue &
V) {
1466 assert(
V.isLValue() &&
"Setting LValue from a non-LValue?");
1467 Base =
V.getLValueBase();
1468 Offset =
V.getLValueOffset();
1469 InvalidBase =
false;
1470 Designator = SubobjectDesignator(Ctx,
V);
1471 IsNullPtr =
V.isNullPointer();
1472 AllowConstexprUnknown =
V.allowConstexprUnknown();
1475 void set(APValue::LValueBase B,
bool BInvalid =
false) {
1479 const auto *E = B.
get<
const Expr *>();
1481 "Unexpected type of invalid base");
1487 InvalidBase = BInvalid;
1488 Designator = SubobjectDesignator(
getType(B));
1490 AllowConstexprUnknown =
false;
1493 void setNull(ASTContext &Ctx, QualType PointerTy) {
1494 Base = (
const ValueDecl *)
nullptr;
1497 InvalidBase =
false;
1500 AllowConstexprUnknown =
false;
1503 void setInvalid(APValue::LValueBase B,
unsigned I = 0) {
1507 std::string
toString(ASTContext &Ctx, QualType T)
const {
1509 moveInto(Printable);
1516 template <
typename GenDiagType>
1517 bool checkNullPointerDiagnosingWith(
const GenDiagType &GenDiag) {
1518 if (Designator.Invalid)
1522 Designator.setInvalid();
1529 bool checkNullPointer(EvalInfo &Info,
const Expr *E,
1531 return checkNullPointerDiagnosingWith([&Info, E, CSK] {
1532 Info.CCEDiag(E, diag::note_constexpr_null_subobject) << CSK;
1536 bool checkNullPointerForFoldAccess(EvalInfo &Info,
const Expr *E,
1538 return checkNullPointerDiagnosingWith([&Info, E, AK] {
1539 if (AK == AccessKinds::AK_Dereference)
1540 Info.FFDiag(E, diag::note_constexpr_dereferencing_null);
1542 Info.FFDiag(E, diag::note_constexpr_access_null) << AK;
1550 Designator.checkSubobject(Info, E, CSK);
1553 void addDecl(EvalInfo &Info,
const Expr *E,
1554 const Decl *D,
bool Virtual =
false) {
1556 Designator.addDeclUnchecked(D,
Virtual);
1558 void addUnsizedArray(EvalInfo &Info,
const Expr *E, QualType ElemTy) {
1559 if (!Designator.Entries.empty()) {
1560 Info.CCEDiag(E, diag::note_constexpr_unsupported_unsized_array);
1561 Designator.setInvalid();
1565 assert(
getType(Base).getNonReferenceType()->isPointerType() ||
1566 getType(Base).getNonReferenceType()->isArrayType());
1567 Designator.FirstEntryIsAnUnsizedArray =
true;
1568 Designator.addUnsizedArrayUnchecked(ElemTy);
1571 void addArray(EvalInfo &Info,
const Expr *E,
const ConstantArrayType *CAT) {
1573 Designator.addArrayUnchecked(CAT);
1575 void addComplex(EvalInfo &Info,
const Expr *E, QualType EltTy,
bool Imag) {
1577 Designator.addComplexUnchecked(EltTy, Imag);
1579 void addVectorElement(EvalInfo &Info,
const Expr *E, QualType EltTy,
1580 uint64_t Size, uint64_t Idx) {
1582 Designator.addVectorElementUnchecked(EltTy, Size, Idx);
1584 void clearIsNullPointer() {
1587 void adjustOffsetAndIndex(EvalInfo &Info,
const Expr *E,
1588 const APSInt &Index, CharUnits ElementSize) {
1599 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
1603 Designator.adjustIndex(Info, E, Index, *
this);
1604 clearIsNullPointer();
1606 void adjustOffset(CharUnits N) {
1609 clearIsNullPointer();
1615 explicit MemberPtr(
const ValueDecl *Decl)
1616 : DeclAndIsDerivedMember(
Decl,
false) {}
1620 const ValueDecl *getDecl()
const {
1621 return DeclAndIsDerivedMember.getPointer();
1624 bool isDerivedMember()
const {
1625 return DeclAndIsDerivedMember.getInt();
1628 const CXXRecordDecl *getContainingRecord()
const {
1630 DeclAndIsDerivedMember.getPointer()->getDeclContext());
1634 V =
APValue(getDecl(), isDerivedMember(), Path);
1637 assert(
V.isMemberPointer());
1638 DeclAndIsDerivedMember.setPointer(
V.getMemberPointerDecl());
1639 DeclAndIsDerivedMember.setInt(
V.isMemberPointerToDerivedMember());
1641 llvm::append_range(Path,
V.getMemberPointerPath());
1647 llvm::PointerIntPair<const ValueDecl*, 1, bool> DeclAndIsDerivedMember;
1650 SmallVector<const CXXRecordDecl*, 4> Path;
1654 bool castBack(
const CXXRecordDecl *
Class) {
1655 assert(!Path.empty());
1656 const CXXRecordDecl *Expected;
1657 if (Path.size() >= 2)
1658 Expected = Path[Path.size() - 2];
1660 Expected = getContainingRecord();
1674 bool castToDerived(
const CXXRecordDecl *Derived) {
1677 if (!isDerivedMember()) {
1678 Path.push_back(Derived);
1681 if (!castBack(Derived))
1684 DeclAndIsDerivedMember.setInt(
false);
1692 DeclAndIsDerivedMember.setInt(
true);
1693 if (isDerivedMember()) {
1694 Path.push_back(Base);
1697 return castBack(Base);
1702 static bool operator==(
const MemberPtr &LHS,
const MemberPtr &RHS) {
1703 if (!LHS.getDecl() || !RHS.getDecl())
1704 return !LHS.getDecl() && !RHS.getDecl();
1705 if (LHS.getDecl()->getCanonicalDecl() != RHS.getDecl()->getCanonicalDecl())
1707 return LHS.Path == RHS.Path;
1711void SubobjectDesignator::adjustIndex(EvalInfo &Info,
const Expr *E,
APSInt N,
1715 uint64_t TruncatedN = N.extOrTrunc(64).getZExtValue();
1716 if (isMostDerivedAnUnsizedArray()) {
1717 diagnoseUnsizedArrayPointerArithmetic(Info, E);
1722 PathEntry::ArrayIndex(Entries.back().getAsArrayIndex() + TruncatedN);
1730 MostDerivedPathLength == Entries.size() && MostDerivedIsArrayElement;
1732 IsArray ? Entries.back().getAsArrayIndex() : (
uint64_t)IsOnePastTheEnd;
1735 if (N < -(int64_t)ArrayIndex || N > ArraySize - ArrayIndex) {
1736 if (!Info.checkingPotentialConstantExpression() ||
1737 !LV.AllowConstexprUnknown) {
1740 N = N.extend(std::max<unsigned>(N.getBitWidth() + 1, 65));
1741 (llvm::APInt &)N += ArrayIndex;
1742 assert(N.ugt(ArraySize) &&
"bounds check failed for in-bounds index");
1743 diagnosePointerArithmetic(Info, E, N);
1749 ArrayIndex += TruncatedN;
1750 assert(ArrayIndex <= ArraySize &&
1751 "bounds check succeeded for out-of-bounds index");
1754 Entries.back() = PathEntry::ArrayIndex(ArrayIndex);
1756 IsOnePastTheEnd = (ArrayIndex != 0);
1761 const LValue &This,
const Expr *E,
1762 bool AllowNonLiteralTypes =
false);
1764 bool InvalidBaseOK =
false);
1766 bool InvalidBaseOK =
false);
1774static bool EvaluateComplex(
const Expr *E, ComplexValue &Res, EvalInfo &Info);
1779static std::optional<uint64_t>
1781 std::string *StringResult =
nullptr);
1798 if (Int.isUnsigned() || Int.isMinSignedValue()) {
1799 Int = Int.extend(Int.getBitWidth() + 1);
1800 Int.setIsSigned(
true);
1805template<
typename KeyT>
1806APValue &CallStackFrame::createTemporary(
const KeyT *Key, QualType T,
1807 ScopeKind Scope, LValue &LV) {
1808 unsigned Version = getTempVersion();
1809 APValue::LValueBase
Base(Key, Index, Version);
1811 return createLocal(Base, Key, T, Scope);
1815APValue &CallStackFrame::createParam(CallRef Args,
const ParmVarDecl *PVD,
1817 assert(Args.CallIndex == Index &&
"creating parameter in wrong frame");
1818 APValue::LValueBase
Base(PVD, Index, Args.Version);
1823 return createLocal(Base, PVD, PVD->
getType(), ScopeKind::Call);
1826APValue &CallStackFrame::createLocal(APValue::LValueBase Base,
const void *Key,
1827 QualType T, ScopeKind Scope) {
1828 assert(
Base.getCallIndex() == Index &&
"lvalue for wrong frame");
1829 unsigned Version =
Base.getVersion();
1831 assert(
Result.isAbsent() &&
"local created multiple times");
1837 if (Index <= Info.SpeculativeEvaluationDepth) {
1839 Info.noteSideEffect();
1841 Info.CleanupStack.push_back(Cleanup(&
Result, Base, T, Scope));
1846APValue *EvalInfo::createHeapAlloc(
const Expr *E, QualType T, LValue &LV) {
1848 FFDiag(E, diag::note_constexpr_heap_alloc_limit_exceeded);
1852 DynamicAllocLValue DA(NumHeapAllocs++);
1854 auto Result = HeapAllocs.emplace(std::piecewise_construct,
1855 std::forward_as_tuple(DA), std::tuple<>());
1856 assert(
Result.second &&
"reused a heap alloc index?");
1857 Result.first->second.AllocExpr = E;
1858 return &
Result.first->second.Value;
1862void CallStackFrame::describe(raw_ostream &Out)
const {
1863 bool IsMemberCall =
false;
1864 bool ExplicitInstanceParam =
false;
1865 clang::PrintingPolicy PrintingPolicy = Info.Ctx.getPrintingPolicy();
1868 if (
const auto *MD = dyn_cast<CXXMethodDecl>(Callee)) {
1870 ExplicitInstanceParam = MD->isExplicitObjectMemberFunction();
1874 Callee->getNameForDiagnostic(Out, PrintingPolicy,
1877 if (This && IsMemberCall) {
1878 if (
const auto *MCE = dyn_cast_if_present<CXXMemberCallExpr>(CallExpr)) {
1879 const Expr *
Object = MCE->getImplicitObjectArgument();
1880 Object->printPretty(Out,
nullptr, PrintingPolicy,
1882 if (
Object->getType()->isPointerType())
1886 }
else if (
const auto *OCE =
1887 dyn_cast_if_present<CXXOperatorCallExpr>(CallExpr)) {
1888 OCE->getArg(0)->printPretty(Out,
nullptr, PrintingPolicy,
1893 This->moveInto(Val);
1896 Info.Ctx.getLValueReferenceType(
This->Designator.MostDerivedType));
1899 Callee->getNameForDiagnostic(Out, PrintingPolicy,
1905 llvm::ListSeparator
Comma;
1906 for (
const ParmVarDecl *Param :
1907 Callee->parameters().slice(ExplicitInstanceParam)) {
1909 const APValue *
V = Info.getParamSlot(Arguments, Param);
1911 V->printPretty(Out, Info.Ctx, Param->getType());
1927 return Info.noteSideEffect();
1934 return (
Builtin == Builtin::BI__builtin___CFStringMakeConstantString ||
1935 Builtin == Builtin::BI__builtin___NSStringMakeConstantString ||
1936 Builtin == Builtin::BI__builtin_ptrauth_sign_constant ||
1937 Builtin == Builtin::BI__builtin_function_start);
1941 const auto *BaseExpr =
1942 llvm::dyn_cast_if_present<CallExpr>(LVal.Base.
dyn_cast<
const Expr *>());
1957 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
1958 return VD->hasGlobalStorage();
1974 case Expr::CompoundLiteralExprClass: {
1978 case Expr::MaterializeTemporaryExprClass:
1983 case Expr::StringLiteralClass:
1984 case Expr::PredefinedExprClass:
1985 case Expr::ObjCStringLiteralClass:
1986 case Expr::ObjCEncodeExprClass:
1988 case Expr::ObjCBoxedExprClass:
1989 case Expr::ObjCArrayLiteralClass:
1990 case Expr::ObjCDictionaryLiteralClass:
1992 case Expr::CallExprClass:
1995 case Expr::AddrLabelExprClass:
1999 case Expr::BlockExprClass:
2003 case Expr::SourceLocExprClass:
2005 case Expr::ImplicitValueInitExprClass:
2030 const auto *BaseExpr = LVal.Base.
dyn_cast<
const Expr *>();
2035 if (
const auto *EE = dyn_cast<ObjCEncodeExpr>(BaseExpr)) {
2036 Info.Ctx.getObjCEncodingForType(EE->getEncodedType(),
2044 const auto *Lit = dyn_cast<StringLiteral>(BaseExpr);
2045 if (
const auto *PE = dyn_cast<PredefinedExpr>(BaseExpr))
2046 Lit = PE->getFunctionName();
2051 AsString.
Bytes = Lit->getBytes();
2052 AsString.
CharWidth = Lit->getCharByteWidth();
2072 const LValue &RHS) {
2081 CharUnits Offset = RHS.Offset - LHS.Offset;
2082 if (Offset.isNegative()) {
2083 if (LHSString.
Bytes.size() < (
size_t)-Offset.getQuantity())
2085 LHSString.
Bytes = LHSString.
Bytes.drop_front(-Offset.getQuantity());
2087 if (RHSString.
Bytes.size() < (
size_t)Offset.getQuantity())
2089 RHSString.
Bytes = RHSString.
Bytes.drop_front(Offset.getQuantity());
2092 bool LHSIsLonger = LHSString.
Bytes.size() > RHSString.
Bytes.size();
2093 StringRef Longer = LHSIsLonger ? LHSString.
Bytes : RHSString.
Bytes;
2094 StringRef Shorter = LHSIsLonger ? RHSString.
Bytes : LHSString.
Bytes;
2095 int ShorterCharWidth = (LHSIsLonger ? RHSString : LHSString).CharWidth;
2100 for (
int NullByte : llvm::seq(ShorterCharWidth)) {
2101 if (Shorter.size() + NullByte >= Longer.size())
2103 if (Longer[Shorter.size() + NullByte])
2109 return Shorter == Longer.take_front(Shorter.size());
2119 if (isa_and_nonnull<VarDecl>(
Decl)) {
2129 if (!A.getLValueBase())
2130 return !B.getLValueBase();
2131 if (!B.getLValueBase())
2134 if (A.getLValueBase().getOpaqueValue() !=
2135 B.getLValueBase().getOpaqueValue())
2138 return A.getLValueCallIndex() == B.getLValueCallIndex() &&
2139 A.getLValueVersion() == B.getLValueVersion();
2143 assert(
Base &&
"no location for a null lvalue");
2149 if (
auto *PVD = dyn_cast_or_null<ParmVarDecl>(VD)) {
2151 for (CallStackFrame *F = Info.CurrentCall; F; F = F->Caller) {
2152 if (F->Arguments.CallIndex ==
Base.getCallIndex() &&
2153 F->Arguments.Version ==
Base.getVersion() && F->Callee &&
2154 Idx < F->Callee->getNumParams()) {
2155 VD = F->Callee->getParamDecl(Idx);
2162 Info.Note(VD->
getLocation(), diag::note_declared_at);
2164 Info.Note(E->
getExprLoc(), diag::note_constexpr_temporary_here);
2167 if (std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA))
2168 Info.Note((*Alloc)->AllocExpr->getExprLoc(),
2169 diag::note_constexpr_dynamic_alloc_here);
2202 const SubobjectDesignator &
Designator = LVal.getLValueDesignator();
2210 if (isTemplateArgument(Kind)) {
2211 int InvalidBaseKind = -1;
2214 InvalidBaseKind = 0;
2215 else if (isa_and_nonnull<StringLiteral>(BaseE))
2216 InvalidBaseKind = 1;
2217 else if (isa_and_nonnull<MaterializeTemporaryExpr>(BaseE) ||
2218 isa_and_nonnull<LifetimeExtendedTemporaryDecl>(BaseVD))
2219 InvalidBaseKind = 2;
2220 else if (
auto *PE = dyn_cast_or_null<PredefinedExpr>(BaseE)) {
2221 InvalidBaseKind = 3;
2222 Ident = PE->getIdentKindName();
2225 if (InvalidBaseKind != -1) {
2226 Info.FFDiag(Loc, diag::note_constexpr_invalid_template_arg)
2227 << IsReferenceType << !
Designator.Entries.empty() << InvalidBaseKind
2233 if (
auto *FD = dyn_cast_or_null<FunctionDecl>(BaseVD);
2234 FD && FD->isImmediateFunction()) {
2235 Info.FFDiag(Loc, diag::note_consteval_address_accessible)
2237 Info.Note(FD->getLocation(), diag::note_declared_at);
2245 if (Info.getLangOpts().CPlusPlus11) {
2246 Info.FFDiag(Loc, diag::note_constexpr_non_global, 1)
2247 << IsReferenceType << !
Designator.Entries.empty() << !!BaseVD
2249 auto *VarD = dyn_cast_or_null<VarDecl>(BaseVD);
2250 if (VarD && VarD->isConstexpr()) {
2256 Info.Note(VarD->getLocation(), diag::note_constexpr_not_static)
2268 assert((Info.checkingPotentialConstantExpression() ||
2269 LVal.getLValueCallIndex() == 0) &&
2270 "have call index for global lvalue");
2272 if (LVal.allowConstexprUnknown()) {
2274 Info.FFDiag(Loc, diag::note_constexpr_var_init_non_constant, 1) << BaseVD;
2283 Info.FFDiag(Loc, diag::note_constexpr_dynamic_alloc)
2284 << IsReferenceType << !
Designator.Entries.empty();
2290 if (
const VarDecl *Var = dyn_cast<const VarDecl>(BaseVD)) {
2292 if (Var->getTLSKind())
2300 if (!isForManglingOnly(Kind) && Var->hasAttr<DLLImportAttr>() &&
2301 !Var->isStaticLocal())
2306 if (Info.getLangOpts().CUDA && Info.getLangOpts().CUDAIsDevice &&
2307 Info.Ctx.CUDAConstantEvalCtx.NoWrongSidedVars) {
2308 if ((!Var->hasAttr<CUDADeviceAttr>() &&
2309 !Var->hasAttr<CUDAConstantAttr>() &&
2310 !Var->getType()->isCUDADeviceBuiltinSurfaceType() &&
2311 !Var->getType()->isCUDADeviceBuiltinTextureType()) ||
2312 Var->hasAttr<HIPManagedAttr>())
2316 if (
const auto *FD = dyn_cast<const FunctionDecl>(BaseVD)) {
2327 if (Info.getLangOpts().CPlusPlus && !isForManglingOnly(Kind) &&
2328 FD->hasAttr<DLLImportAttr>())
2332 }
else if (
const auto *MTE =
2333 dyn_cast_or_null<MaterializeTemporaryExpr>(BaseE)) {
2334 if (CheckedTemps.insert(MTE).second) {
2337 Info.FFDiag(MTE->getExprLoc(),
2338 diag::note_constexpr_unsupported_temporary_nontrivial_dtor)
2343 APValue *
V = MTE->getOrCreateValue(
false);
2344 assert(
V &&
"evasluation result refers to uninitialised temporary");
2346 Info, MTE->getExprLoc(), TempType, *
V, Kind,
2347 nullptr, CheckedTemps))
2354 if (!IsReferenceType)
2366 Info.FFDiag(Loc, diag::note_constexpr_past_end, 1)
2367 << !
Designator.Entries.empty() << !!BaseVD << BaseVD;
2382 const auto *FD = dyn_cast_or_null<CXXMethodDecl>(
Member);
2385 if (FD->isImmediateFunction()) {
2386 Info.FFDiag(Loc, diag::note_consteval_address_accessible) << 0;
2387 Info.Note(FD->getLocation(), diag::note_declared_at);
2390 return isForManglingOnly(Kind) || FD->isVirtual() ||
2391 !FD->hasAttr<DLLImportAttr>();
2397 const LValue *
This =
nullptr) {
2399 if (Info.getLangOpts().CPlusPlus23)
2418 if (
This && Info.EvaluatingDecl ==
This->getLValueBase())
2422 if (Info.getLangOpts().CPlusPlus11)
2423 Info.FFDiag(E, diag::note_constexpr_nonliteral)
2426 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
2437 if (SubobjectDecl) {
2438 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
2439 << 1 << SubobjectDecl;
2441 diag::note_constexpr_subobject_declared_here);
2443 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
2452 Type = AT->getValueType();
2457 if (
Value.isArray()) {
2459 for (
unsigned I = 0, N =
Value.getArrayInitializedElts(); I != N; ++I) {
2461 Value.getArrayInitializedElt(I), Kind,
2462 SubobjectDecl, CheckedTemps))
2465 if (!
Value.hasArrayFiller())
2468 Value.getArrayFiller(), Kind, SubobjectDecl,
2471 if (
Value.isUnion() &&
Value.getUnionField()) {
2474 Value.getUnionValue(), Kind,
Value.getUnionField(), CheckedTemps);
2476 if (
Value.isStruct()) {
2478 if (
const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {
2479 unsigned BaseIndex = 0;
2481 const APValue &BaseValue =
Value.getStructBase(BaseIndex);
2484 Info.FFDiag(TypeBeginLoc, diag::note_constexpr_uninitialized_base)
2485 << BS.getType() <<
SourceRange(TypeBeginLoc, BS.getEndLoc());
2495 for (
const auto *I : RD->fields()) {
2496 if (I->isUnnamedBitField())
2500 Value.getStructField(I->getFieldIndex()), Kind,
2506 if (
Value.isLValue() &&
2509 LVal.setFrom(Info.Ctx,
Value);
2514 if (
Value.isMemberPointer() &&
2535 nullptr, CheckedTemps);
2545 ConstantExprKind::Normal,
nullptr, CheckedTemps);
2551 if (!Info.HeapAllocs.empty()) {
2555 Info.CCEDiag(Info.HeapAllocs.begin()->second.AllocExpr,
2556 diag::note_constexpr_memory_leak)
2557 <<
unsigned(Info.HeapAllocs.size() - 1);
2565 if (!
Value.getLValueBase()) {
2567 Result = !
Value.getLValueOffset().isZero();
2585 Result = Val.
getInt().getBoolValue();
2618 llvm_unreachable(
"unknown APValue kind");
2624 assert(E->
isPRValue() &&
"missing lvalue-to-rvalue conv in bool condition");
2633 const T &SrcValue,
QualType DestType) {
2634 Info.CCEDiag(E, diag::note_constexpr_overflow) << SrcValue << DestType;
2635 if (
const auto *OBT = DestType->
getAs<OverflowBehaviorType>();
2636 OBT && OBT->isTrapKind()) {
2639 return Info.noteUndefinedBehavior();
2645 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
2649 Result =
APSInt(DestWidth, !DestSigned);
2651 if (
Value.convertToInteger(Result, llvm::APFloat::rmTowardZero, &ignored)
2652 & APFloat::opInvalidOp)
2663 llvm::RoundingMode RM =
2665 if (RM == llvm::RoundingMode::Dynamic)
2666 RM = llvm::RoundingMode::NearestTiesToEven;
2672 APFloat::opStatus St) {
2675 if (Info.InConstantContext)
2679 if ((St & APFloat::opInexact) &&
2683 Info.FFDiag(E, diag::note_constexpr_dynamic_rounding);
2687 if ((St != APFloat::opOK) &&
2690 FPO.getAllowFEnvAccess())) {
2691 Info.FFDiag(E, diag::note_constexpr_float_arithmetic_strict);
2695 if ((St & APFloat::opStatus::opInvalidOp) &&
2716 "HandleFloatToFloatCast has been checked with only CastExpr, "
2717 "CompoundAssignOperator and ConvertVectorExpr. Please either validate "
2718 "the new expression or address the root cause of this usage.");
2720 APFloat::opStatus St;
2721 APFloat
Value = Result;
2723 St = Result.convert(Info.Ctx.getFloatTypeSemantics(DestType), RM, &ignored);
2730 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
2736 Result =
Value.getBoolValue();
2743 QualType DestType, APFloat &Result) {
2744 Result = APFloat(Info.Ctx.getFloatTypeSemantics(DestType), 1);
2746 APFloat::opStatus St = Result.convertFromAPInt(
Value,
Value.isSigned(), RM);
2752 assert(FD->
isBitField() &&
"truncateBitfieldValue on non-bitfield");
2754 if (!
Value.isInt()) {
2758 assert(
Value.isLValue() &&
"integral value neither int nor lvalue?");
2764 unsigned OldBitWidth = Int.getBitWidth();
2766 if (NewBitWidth < OldBitWidth)
2767 Int = Int.trunc(NewBitWidth).extend(OldBitWidth);
2774template<
typename Operation>
2777 unsigned BitWidth, Operation Op,
2779 if (LHS.isUnsigned()) {
2780 Result = Op(LHS, RHS);
2784 APSInt Value(Op(LHS.extend(BitWidth), RHS.extend(BitWidth)),
false);
2785 Result =
Value.trunc(LHS.getBitWidth());
2787 if (Info.checkingForUndefinedBehavior())
2788 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
2789 diag::warn_integer_constant_overflow)
2790 <<
toString(Result, 10, Result.isSigned(),
false,
2802 bool HandleOverflowResult =
true;
2809 std::multiplies<APSInt>(), Result);
2812 std::plus<APSInt>(), Result);
2815 std::minus<APSInt>(), Result);
2816 case BO_And: Result = LHS & RHS;
return true;
2817 case BO_Xor: Result = LHS ^ RHS;
return true;
2818 case BO_Or: Result = LHS | RHS;
return true;
2822 Info.FFDiag(E, diag::note_expr_divide_by_zero)
2828 if (RHS.isNegative() && RHS.isAllOnes() && LHS.isSigned() &&
2829 LHS.isMinSignedValue())
2831 Info, E, -LHS.extend(LHS.getBitWidth() + 1), E->
getType());
2832 Result = (Opcode == BO_Rem ? LHS % RHS : LHS / RHS);
2833 return HandleOverflowResult;
2835 if (Info.getLangOpts().OpenCL)
2837 RHS &=
APSInt(llvm::APInt(RHS.getBitWidth(),
2838 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2840 else if (RHS.isSigned() && RHS.isNegative()) {
2843 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
2844 if (!Info.noteUndefinedBehavior())
2852 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
2854 Info.CCEDiag(E, diag::note_constexpr_large_shift)
2855 << RHS << E->
getType() << LHS.getBitWidth();
2856 if (!Info.noteUndefinedBehavior())
2858 }
else if (LHS.isSigned() && !Info.getLangOpts().CPlusPlus20) {
2863 if (LHS.isNegative()) {
2864 Info.CCEDiag(E, diag::note_constexpr_lshift_of_negative) << LHS;
2865 if (!Info.noteUndefinedBehavior())
2867 }
else if (LHS.countl_zero() < SA) {
2868 Info.CCEDiag(E, diag::note_constexpr_lshift_discards);
2869 if (!Info.noteUndefinedBehavior())
2877 if (Info.getLangOpts().OpenCL)
2879 RHS &=
APSInt(llvm::APInt(RHS.getBitWidth(),
2880 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2882 else if (RHS.isSigned() && RHS.isNegative()) {
2885 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
2886 if (!Info.noteUndefinedBehavior())
2894 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
2896 Info.CCEDiag(E, diag::note_constexpr_large_shift)
2897 << RHS << E->
getType() << LHS.getBitWidth();
2898 if (!Info.noteUndefinedBehavior())
2906 case BO_LT: Result = LHS < RHS;
return true;
2907 case BO_GT: Result = LHS > RHS;
return true;
2908 case BO_LE: Result = LHS <= RHS;
return true;
2909 case BO_GE: Result = LHS >= RHS;
return true;
2910 case BO_EQ: Result = LHS == RHS;
return true;
2911 case BO_NE: Result = LHS != RHS;
return true;
2913 llvm_unreachable(
"BO_Cmp should be handled elsewhere");
2920 const APFloat &RHS) {
2922 APFloat::opStatus St;
2928 St = LHS.multiply(RHS, RM);
2931 St = LHS.add(RHS, RM);
2934 St = LHS.subtract(RHS, RM);
2940 Info.CCEDiag(E, diag::note_expr_divide_by_zero);
2941 St = LHS.divide(RHS, RM);
2950 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << LHS.isNaN();
2951 return Info.noteUndefinedBehavior();
2959 const APInt &RHSValue, APInt &Result) {
2960 bool LHS = (LHSValue != 0);
2961 bool RHS = (RHSValue != 0);
2963 if (Opcode == BO_LAnd)
2964 Result = LHS && RHS;
2966 Result = LHS || RHS;
2971 const APFloat &RHSValue, APInt &Result) {
2972 bool LHS = !LHSValue.isZero();
2973 bool RHS = !RHSValue.isZero();
2975 if (Opcode == BO_LAnd)
2976 Result = LHS && RHS;
2978 Result = LHS || RHS;
2984 const APValue &RHSValue, APInt &Result) {
2988 RHSValue.
getInt(), Result);
2994template <
typename APTy>
2997 const APTy &RHSValue, APInt &Result) {
3000 llvm_unreachable(
"unsupported binary operator");
3002 Result = (LHSValue == RHSValue);
3005 Result = (LHSValue != RHSValue);
3008 Result = (LHSValue < RHSValue);
3011 Result = (LHSValue > RHSValue);
3014 Result = (LHSValue <= RHSValue);
3017 Result = (LHSValue >= RHSValue);
3031 const APValue &RHSValue, APInt &Result) {
3035 RHSValue.
getInt(), Result);
3046 assert(Opcode != BO_PtrMemD && Opcode != BO_PtrMemI &&
3047 "Operation not supported on vector types");
3051 QualType EltTy = VT->getElementType();
3058 "A vector result that isn't a vector OR uncalculated LValue");
3064 RHSValue.
getVectorLength() == NumElements &&
"Different vector sizes");
3068 for (
unsigned EltNum = 0; EltNum < NumElements; ++EltNum) {
3073 APSInt EltResult{Info.Ctx.getIntWidth(EltTy),
3083 RHSElt.
getInt(), EltResult);
3089 ResultElements.emplace_back(EltResult);
3094 "Mismatched LHS/RHS/Result Type");
3095 APFloat LHSFloat = LHSElt.
getFloat();
3103 ResultElements.emplace_back(LHSFloat);
3107 LHSValue =
APValue(ResultElements.data(), ResultElements.size());
3115 unsigned TruncatedElements) {
3116 SubobjectDesignator &D = Result.Designator;
3119 if (TruncatedElements == D.Entries.size())
3121 assert(TruncatedElements >= D.MostDerivedPathLength &&
3122 "not casting to a derived class");
3128 for (
unsigned I = TruncatedElements, N = D.Entries.size(); I != N; ++I) {
3132 if (isVirtualBaseClass(D.Entries[I]))
3138 D.Entries.resize(TruncatedElements);
3148 RL = &Info.Ctx.getASTRecordLayout(Derived);
3151 Obj.addDecl(Info, E,
Base,
false);
3152 Obj.getLValueOffset() += RL->getBaseClassOffset(
Base);
3161 if (!
Base->isVirtual())
3164 SubobjectDesignator &D = Obj.Designator;
3179 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(DerivedDecl);
3180 Obj.addDecl(Info, E, BaseDecl,
true);
3189 PathI != PathE; ++PathI) {
3193 Type = (*PathI)->getType();
3205 llvm_unreachable(
"Class must be derived from the passed in base class!");
3220 RL = &Info.Ctx.getASTRecordLayout(FD->
getParent());
3224 LVal.addDecl(Info, E, FD);
3225 LVal.adjustOffset(Info.Ctx.toCharUnitsFromBits(RL->getFieldOffset(I)));
3233 for (
const auto *
C : IFD->
chain())
3267 Size = Info.Ctx.getTypeSizeInChars(
Type);
3269 Size = Info.Ctx.getTypeInfoDataSizeInChars(
Type).Width;
3286 LVal.adjustOffsetAndIndex(Info, E, Adjustment, SizeOfPointee);
3292 int64_t Adjustment) {
3294 APSInt::get(Adjustment));
3309 LVal.Offset += SizeOfComponent;
3311 LVal.addComplex(Info, E, EltTy, Imag);
3317 uint64_t Size, uint64_t Idx) {
3322 LVal.Offset += SizeOfElement * Idx;
3324 LVal.addVectorElement(Info, E, EltTy, Size, Idx);
3338 const VarDecl *VD, CallStackFrame *Frame,
3339 unsigned Version,
APValue *&Result) {
3342 bool AllowConstexprUnknown =
3347 auto CheckUninitReference = [&](
bool IsLocalVariable) {
3359 if (!AllowConstexprUnknown || IsLocalVariable) {
3360 if (!Info.checkingPotentialConstantExpression())
3361 Info.FFDiag(E, diag::note_constexpr_use_uninit_reference);
3371 Result = Frame->getTemporary(VD, Version);
3373 return CheckUninitReference(
true);
3382 "missing value for local variable");
3383 if (Info.checkingPotentialConstantExpression())
3387 "A variable in a frame should either be a local or a parameter");
3393 if (Info.EvaluatingDecl ==
Base) {
3394 Result = Info.EvaluatingDeclValue;
3395 return CheckUninitReference(
false);
3403 if (AllowConstexprUnknown) {
3410 if (!Info.checkingPotentialConstantExpression() ||
3411 !Info.CurrentCall->Callee ||
3413 if (Info.getLangOpts().CPlusPlus11) {
3414 Info.FFDiag(E, diag::note_constexpr_function_param_value_unknown)
3435 if (!
Init && !AllowConstexprUnknown) {
3438 if (!Info.checkingPotentialConstantExpression()) {
3439 Info.FFDiag(E, diag::note_constexpr_var_init_unknown, 1)
3450 if (
Init &&
Init->isValueDependent()) {
3457 if (!Info.checkingPotentialConstantExpression()) {
3458 Info.FFDiag(E, Info.getLangOpts().CPlusPlus11
3459 ? diag::note_constexpr_ltor_non_constexpr
3460 : diag::note_constexpr_ltor_non_integral, 1)
3474 Info.FFDiag(E, diag::note_constexpr_var_init_non_constant, 1) << VD;
3490 !AllowConstexprUnknown) ||
3491 ((Info.getLangOpts().CPlusPlus || Info.getLangOpts().OpenCL) &&
3494 Info.CCEDiag(E, diag::note_constexpr_var_init_non_constant, 1) << VD;
3504 Info.FFDiag(E, diag::note_constexpr_var_init_weak) << VD;
3511 if (!Result && !AllowConstexprUnknown)
3514 return CheckUninitReference(
false);
3524 E = Derived->
bases_end(); I != E; ++I, ++Index) {
3525 if (I->getType()->getAsCXXRecordDecl()->getCanonicalDecl() ==
Base)
3529 llvm_unreachable(
"base class missing from derived class's bases list");
3536 "SourceLocExpr should have already been converted to a StringLiteral");
3539 if (
const auto *ObjCEnc = dyn_cast<ObjCEncodeExpr>(Lit)) {
3541 Info.Ctx.getObjCEncodingForType(ObjCEnc->getEncodedType(), Str);
3542 assert(Index <= Str.size() &&
"Index too large");
3543 return APSInt::getUnsigned(Str.c_str()[Index]);
3546 if (
auto PE = dyn_cast<PredefinedExpr>(Lit))
3547 Lit = PE->getFunctionName();
3550 Info.Ctx.getAsConstantArrayType(S->
getType());
3551 assert(CAT &&
"string literal isn't an array");
3553 assert(CharType->
isIntegerType() &&
"unexpected character type");
3556 if (Index < S->getLength())
3569 AllocType.isNull() ? S->
getType() : AllocType);
3570 assert(CAT &&
"string literal isn't an array");
3572 assert(CharType->
isIntegerType() &&
"unexpected character type");
3579 if (Result.hasArrayFiller())
3581 for (
unsigned I = 0, N = Result.getArrayInitializedElts(); I != N; ++I) {
3589 unsigned Size =
Array.getArraySize();
3590 assert(Index < Size);
3593 unsigned OldElts =
Array.getArrayInitializedElts();
3594 unsigned NewElts = std::max(Index+1, OldElts * 2);
3595 NewElts = std::min(Size, std::max(NewElts, 8u));
3599 for (
unsigned I = 0; I != OldElts; ++I)
3601 for (
unsigned I = OldElts; I != NewElts; ++I)
3605 Array.swap(NewValue);
3612 Vec =
APValue(Elts.data(), Elts.size());
3622 CXXRecordDecl *RD = T->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
3633 for (
auto *Field : RD->
fields())
3634 if (!Field->isUnnamedBitField() &&
3638 for (
auto &BaseSpec : RD->
bases())
3649 CXXRecordDecl *RD = T->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
3656 for (
auto *Field : RD->
fields()) {
3661 if (Field->isMutable() &&
3663 Info.FFDiag(E, diag::note_constexpr_access_mutable, 1) << AK << Field;
3664 Info.Note(Field->getLocation(), diag::note_declared_at);
3672 for (
auto &BaseSpec : RD->
bases())
3682 bool MutableSubobject =
false) {
3687 switch (Info.IsEvaluatingDecl) {
3688 case EvalInfo::EvaluatingDeclKind::None:
3691 case EvalInfo::EvaluatingDeclKind::Ctor:
3693 if (Info.EvaluatingDecl ==
Base)
3698 if (
auto *BaseE =
Base.dyn_cast<
const Expr *>())
3699 if (
auto *BaseMTE = dyn_cast<MaterializeTemporaryExpr>(BaseE))
3700 return Info.EvaluatingDecl == BaseMTE->getExtendingDecl();
3703 case EvalInfo::EvaluatingDeclKind::Dtor:
3708 if (MutableSubobject ||
Base != Info.EvaluatingDecl)
3714 return T.isConstQualified() || T->isReferenceType();
3717 llvm_unreachable(
"unknown evaluating decl kind");
3722 return Info.CheckArraySize(
3742 uint64_t IntResult = BoolResult;
3745 : Info.Ctx.getIntTypeForBitwidth(64,
false);
3746 Result =
APValue(Info.Ctx.MakeIntValue(IntResult, IntType));
3751 Info.Ctx.getIntTypeForBitwidth(64,
false),
3752 Result.getInt(), DestTy, Result2.
getFloat()))
3754 Result = std::move(Result2);
3760 Result =
APValue(APFloat(0.0));
3762 DestTy, Result.getFloat());
3768 uint64_t IntResult = BoolResult;
3769 Result =
APValue(Info.Ctx.MakeIntValue(IntResult, DestTy));
3787 uint64_t IntResult = BoolResult;
3788 Result =
APValue(Info.Ctx.MakeIntValue(IntResult, DestTy));
3794 DestTy, Result.getInt());
3798 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
3811 {&Result, ResultType, 0}};
3814 while (!WorkList.empty() && ElI < Elements.size()) {
3815 auto [Res,
Type, BitWidth] = WorkList.pop_back_val();
3831 APSInt &Int = Res->getInt();
3832 unsigned OldBitWidth = Int.getBitWidth();
3833 unsigned NewBitWidth = BitWidth;
3834 if (NewBitWidth < OldBitWidth)
3835 Int = Int.trunc(NewBitWidth).extend(OldBitWidth);
3844 for (
unsigned I = 0; I < NumEl; ++I) {
3850 *Res =
APValue(Vals.data(), NumEl);
3859 for (int64_t I = Size - 1; I > -1; --I)
3860 WorkList.emplace_back(&Res->getArrayInitializedElt(I), ElTy, 0u);
3866 unsigned NumBases = 0;
3867 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
3868 NumBases = CXXRD->getNumBases();
3875 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
3876 if (CXXRD->getNumBases() > 0) {
3877 assert(CXXRD->getNumBases() == 1);
3879 ReverseList.emplace_back(&Res->getStructBase(0), BS.
getType(), 0u);
3886 if (FD->isUnnamedBitField())
3888 if (FD->isBitField()) {
3889 FDBW = FD->getBitWidthValue();
3892 ReverseList.emplace_back(&Res->getStructField(FD->getFieldIndex()),
3893 FD->getType(), FDBW);
3896 std::reverse(ReverseList.begin(), ReverseList.end());
3897 llvm::append_range(WorkList, ReverseList);
3900 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
3913 assert((Elements.size() == SrcTypes.size()) &&
3914 (Elements.size() == DestTypes.size()));
3916 for (
unsigned I = 0, ESz = Elements.size(); I < ESz; ++I) {
3917 APValue Original = Elements[I];
3921 if (!
handleScalarCast(Info, FPO, E, SourceTy, DestTy, Original, Results[I]))
3932 while (!WorkList.empty()) {
3955 for (uint64_t I = 0; I < ArrSize; ++I) {
3956 WorkList.push_back(ElTy);
3964 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
3965 if (CXXRD->getNumBases() > 0) {
3966 assert(CXXRD->getNumBases() == 1);
3968 WorkList.push_back(BS.
getType());
3974 if (FD->isUnnamedBitField())
3976 WorkList.push_back(FD->getType());
3993 "Not a valid HLSLAggregateSplatCast.");
4013 unsigned Populated = 0;
4014 while (!WorkList.empty() && Populated < Size) {
4015 auto [Work,
Type] = WorkList.pop_back_val();
4017 if (Work.isFloat() || Work.isInt()) {
4018 Elements.push_back(Work);
4019 Types.push_back(
Type);
4023 if (Work.isVector()) {
4026 for (
unsigned I = 0; I < Work.getVectorLength() && Populated < Size;
4028 Elements.push_back(Work.getVectorElt(I));
4029 Types.push_back(ElTy);
4034 if (Work.isMatrix()) {
4037 QualType ElTy = MT->getElementType();
4039 for (
unsigned Row = 0; Row < Work.getMatrixNumRows() && Populated < Size;
4041 for (
unsigned Col = 0;
4042 Col < Work.getMatrixNumColumns() && Populated < Size; Col++) {
4043 Elements.push_back(Work.getMatrixElt(Row, Col));
4044 Types.push_back(ElTy);
4050 if (Work.isArray()) {
4054 for (int64_t I = Work.getArraySize() - 1; I > -1; --I) {
4055 WorkList.emplace_back(Work.getArrayInitializedElt(I), ElTy);
4060 if (Work.isStruct()) {
4068 if (FD->isUnnamedBitField())
4070 ReverseList.emplace_back(Work.getStructField(FD->getFieldIndex()),
4074 std::reverse(ReverseList.begin(), ReverseList.end());
4075 llvm::append_range(WorkList, ReverseList);
4078 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4079 if (CXXRD->getNumBases() > 0) {
4080 assert(CXXRD->getNumBases() == 1);
4085 if (!
Base.isStruct())
4093 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
4102struct CompleteObject {
4104 APValue::LValueBase
Base;
4114 bool mayAccessMutableMembers(EvalInfo &Info,
AccessKinds AK)
const {
4125 if (!Info.getLangOpts().CPlusPlus14 &&
4126 AK != AccessKinds::AK_IsWithinLifetime)
4131 explicit operator bool()
const {
return !
Type.isNull(); }
4136 bool IsMutable =
false) {
4150template <
typename Sub
objectHandler>
4151static typename SubobjectHandler::result_type
4153 const SubobjectDesignator &Sub, SubobjectHandler &handler) {
4156 return handler.failed();
4157 if (Sub.isOnePastTheEnd() || Sub.isMostDerivedAnUnsizedArray()) {
4158 if (Info.getLangOpts().CPlusPlus11)
4159 Info.FFDiag(E, Sub.isOnePastTheEnd()
4160 ? diag::note_constexpr_access_past_end
4161 : diag::note_constexpr_access_unsized_array)
4162 << handler.AccessKind;
4165 return handler.failed();
4171 const FieldDecl *VolatileField =
nullptr;
4174 for (
unsigned I = 0, N = Sub.Entries.size(); ; ++I) {
4185 if (!Info.checkingPotentialConstantExpression()) {
4186 Info.FFDiag(E, diag::note_constexpr_access_uninit)
4191 return handler.failed();
4199 Info.isEvaluatingCtorDtor(
4200 Obj.Base,
ArrayRef(Sub.Entries.begin(), Sub.Entries.begin() + I)) !=
4201 ConstructionPhase::None) {
4202 ObjType = Info.Ctx.getCanonicalType(ObjType);
4211 if (Info.getLangOpts().CPlusPlus) {
4215 if (VolatileField) {
4218 Decl = VolatileField;
4221 Loc = VD->getLocation();
4228 Info.FFDiag(E, diag::note_constexpr_access_volatile_obj, 1)
4229 << handler.AccessKind << DiagKind <<
Decl;
4230 Info.Note(Loc, diag::note_constexpr_volatile_here) << DiagKind;
4232 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
4234 return handler.failed();
4242 !Obj.mayAccessMutableMembers(Info, handler.AccessKind) &&
4244 return handler.failed();
4248 if (!handler.found(*O, ObjType))
4260 LastField =
nullptr;
4263 const ArrayType *AT = Info.Ctx.getAsArrayType(ObjType);
4265 "vla in literal type?");
4266 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4267 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT);
4268 CAT && CAT->
getSize().ule(Index)) {
4271 if (Info.getLangOpts().CPlusPlus11)
4272 Info.FFDiag(E, diag::note_constexpr_access_past_end)
4273 << handler.AccessKind;
4276 return handler.failed();
4283 else if (!
isRead(handler.AccessKind)) {
4284 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT);
4286 return handler.failed();
4294 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4296 if (Info.getLangOpts().CPlusPlus11)
4297 Info.FFDiag(E, diag::note_constexpr_access_past_end)
4298 << handler.AccessKind;
4301 return handler.failed();
4307 assert(I == N - 1 &&
"extracting subobject of scalar?");
4317 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4318 unsigned NumElements = VT->getNumElements();
4319 if (Index == NumElements) {
4320 if (Info.getLangOpts().CPlusPlus11)
4321 Info.FFDiag(E, diag::note_constexpr_access_past_end)
4322 << handler.AccessKind;
4325 return handler.failed();
4328 if (Index > NumElements) {
4329 Info.CCEDiag(E, diag::note_constexpr_array_index)
4330 << Index << 0 << NumElements;
4331 return handler.failed();
4334 ObjType = VT->getElementType();
4335 assert(I == N - 1 &&
"extracting subobject of scalar?");
4338 if (
isRead(handler.AccessKind)) {
4340 return handler.failed();
4344 assert(O->
isVector() &&
"unexpected object during vector element access");
4346 }
else if (
const FieldDecl *Field = getAsField(Sub.Entries[I])) {
4347 if (Field->isMutable() &&
4348 !Obj.mayAccessMutableMembers(Info, handler.AccessKind)) {
4349 Info.FFDiag(E, diag::note_constexpr_access_mutable, 1)
4350 << handler.AccessKind << Field;
4351 Info.Note(Field->getLocation(), diag::note_declared_at);
4352 return handler.failed();
4361 if (I == N - 1 && handler.AccessKind ==
AK_Construct) {
4372 Info.FFDiag(E, diag::note_constexpr_access_inactive_union_member)
4373 << handler.AccessKind << Field << !UnionField << UnionField;
4374 return handler.failed();
4383 if (Field->getType().isVolatileQualified())
4384 VolatileField = Field;
4397struct ExtractSubobjectHandler {
4403 typedef bool result_type;
4404 bool failed() {
return false; }
4405 bool found(
APValue &Subobj, QualType SubobjType) {
4415 bool found(APFloat &
Value, QualType SubobjType) {
4424 const CompleteObject &Obj,
4425 const SubobjectDesignator &Sub,
APValue &Result,
4428 ExtractSubobjectHandler Handler = {Info, E, Result, AK};
4433struct ModifySubobjectHandler {
4438 typedef bool result_type;
4441 bool checkConst(QualType QT) {
4444 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
4450 bool failed() {
return false; }
4451 bool found(
APValue &Subobj, QualType SubobjType) {
4452 if (!checkConst(SubobjType))
4455 Subobj.
swap(NewVal);
4459 if (!checkConst(SubobjType))
4461 if (!NewVal.
isInt()) {
4469 bool found(APFloat &
Value, QualType SubobjType) {
4470 if (!checkConst(SubobjType))
4478const AccessKinds ModifySubobjectHandler::AccessKind;
4482 const CompleteObject &Obj,
4483 const SubobjectDesignator &Sub,
4485 ModifySubobjectHandler Handler = { Info, NewVal, E };
4492 const SubobjectDesignator &A,
4493 const SubobjectDesignator &B,
4494 bool &WasArrayIndex) {
4495 unsigned I = 0, N = std::min(A.Entries.size(), B.Entries.size());
4496 for (; I != N; ++I) {
4500 if (A.Entries[I].getAsArrayIndex() != B.Entries[I].getAsArrayIndex()) {
4501 WasArrayIndex =
true;
4509 if (A.Entries[I].getAsBaseOrMember() !=
4510 B.Entries[I].getAsBaseOrMember()) {
4511 WasArrayIndex =
false;
4514 if (
const FieldDecl *FD = getAsField(A.Entries[I]))
4516 ObjType = FD->getType();
4522 WasArrayIndex =
false;
4529 const SubobjectDesignator &A,
4530 const SubobjectDesignator &B) {
4531 if (A.Entries.size() != B.Entries.size())
4534 bool IsArray = A.MostDerivedIsArrayElement;
4535 if (IsArray && A.MostDerivedPathLength != A.Entries.size())
4544 return CommonLength >= A.Entries.size() - IsArray;
4551 if (LVal.InvalidBase) {
4553 return CompleteObject();
4558 Info.FFDiag(E, diag::note_constexpr_dereferencing_null);
4560 Info.FFDiag(E, diag::note_constexpr_access_null) << AK;
4561 return CompleteObject();
4564 CallStackFrame *Frame =
nullptr;
4566 if (LVal.getLValueCallIndex()) {
4567 std::tie(Frame, Depth) =
4568 Info.getCallFrameAndDepth(LVal.getLValueCallIndex());
4570 Info.FFDiag(E, diag::note_constexpr_access_uninit, 1)
4573 return CompleteObject();
4584 if (Info.getLangOpts().CPlusPlus)
4585 Info.FFDiag(E, diag::note_constexpr_access_volatile_type)
4589 return CompleteObject();
4596 if (Info.getLangOpts().CPlusPlus14 && LVal.Base == Info.EvaluatingDecl &&
4600 BaseVal = Info.EvaluatingDeclValue;
4603 if (
auto *GD = dyn_cast<MSGuidDecl>(D)) {
4606 Info.FFDiag(E, diag::note_constexpr_modify_global);
4607 return CompleteObject();
4611 Info.FFDiag(E, diag::note_constexpr_unsupported_layout)
4613 return CompleteObject();
4615 return CompleteObject(LVal.Base, &
V, GD->getType());
4619 if (
auto *GCD = dyn_cast<UnnamedGlobalConstantDecl>(D)) {
4621 Info.FFDiag(E, diag::note_constexpr_modify_global);
4622 return CompleteObject();
4624 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&GCD->getValue()),
4629 if (
auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
4631 Info.FFDiag(E, diag::note_constexpr_modify_global);
4632 return CompleteObject();
4634 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&TPO->getValue()),
4645 const VarDecl *VD = dyn_cast<VarDecl>(D);
4652 return CompleteObject();
4655 bool IsConstant = BaseType.isConstant(Info.Ctx);
4656 bool ConstexprVar =
false;
4657 if (
const auto *VD = dyn_cast_if_present<VarDecl>(
4669 }
else if (Info.getLangOpts().CPlusPlus14 &&
4676 Info.FFDiag(E, diag::note_constexpr_modify_global);
4677 return CompleteObject();
4680 }
else if (Info.getLangOpts().C23 && ConstexprVar) {
4682 return CompleteObject();
4683 }
else if (BaseType->isIntegralOrEnumerationType()) {
4686 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4687 if (Info.getLangOpts().CPlusPlus) {
4688 Info.FFDiag(E, diag::note_constexpr_ltor_non_const_int, 1) << VD;
4689 Info.Note(VD->
getLocation(), diag::note_declared_at);
4693 return CompleteObject();
4695 }
else if (!IsAccess) {
4696 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4697 }
else if ((IsConstant || BaseType->isReferenceType()) &&
4698 Info.checkingPotentialConstantExpression() &&
4699 BaseType->isLiteralType(Info.Ctx) && !VD->
hasDefinition()) {
4701 }
else if (IsConstant) {
4705 if (Info.getLangOpts().CPlusPlus) {
4706 Info.CCEDiag(E, Info.getLangOpts().CPlusPlus11
4707 ? diag::note_constexpr_ltor_non_constexpr
4708 : diag::note_constexpr_ltor_non_integral, 1)
4710 Info.Note(VD->
getLocation(), diag::note_declared_at);
4716 if (Info.getLangOpts().CPlusPlus) {
4717 Info.FFDiag(E, Info.getLangOpts().CPlusPlus11
4718 ? diag::note_constexpr_ltor_non_constexpr
4719 : diag::note_constexpr_ltor_non_integral, 1)
4721 Info.Note(VD->
getLocation(), diag::note_declared_at);
4725 return CompleteObject();
4734 return CompleteObject();
4739 if (!Info.checkingPotentialConstantExpression()) {
4740 Info.FFDiag(E, diag::note_constexpr_access_unknown_variable, 1)
4742 Info.Note(VD->getLocation(), diag::note_declared_at);
4744 return CompleteObject();
4747 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
4749 Info.FFDiag(E, diag::note_constexpr_access_deleted_object) << AK;
4750 return CompleteObject();
4752 return CompleteObject(LVal.Base, &(*Alloc)->Value,
4762 dyn_cast_or_null<MaterializeTemporaryExpr>(
Base)) {
4763 assert(MTE->getStorageDuration() ==
SD_Static &&
4764 "should have a frame for a non-global materialized temporary");
4791 if (!MTE->isUsableInConstantExpressions(Info.Ctx) &&
4794 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4795 Info.FFDiag(E, diag::note_constexpr_access_static_temporary, 1) << AK;
4796 Info.Note(MTE->getExprLoc(), diag::note_constexpr_temporary_here);
4797 return CompleteObject();
4800 BaseVal = MTE->getOrCreateValue(
false);
4801 assert(BaseVal &&
"got reference to unevaluated temporary");
4803 dyn_cast_or_null<CompoundLiteralExpr>(
Base)) {
4819 !CLETy.isConstant(Info.Ctx)) {
4821 Info.Note(CLE->getExprLoc(), diag::note_declared_at);
4822 return CompleteObject();
4825 BaseVal = &CLE->getStaticValue();
4828 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4831 Info.FFDiag(E, diag::note_constexpr_access_unreadable_object)
4834 Info.Ctx.getLValueReferenceType(LValType));
4836 return CompleteObject();
4840 assert(BaseVal &&
"missing value for temporary");
4851 unsigned VisibleDepth = Depth;
4852 if (llvm::isa_and_nonnull<ParmVarDecl>(
4855 if ((Frame && Info.getLangOpts().CPlusPlus14 &&
4856 Info.EvalStatus.HasSideEffects) ||
4857 (
isModification(AK) && VisibleDepth < Info.SpeculativeEvaluationDepth))
4858 return CompleteObject();
4860 return CompleteObject(LVal.getLValueBase(), BaseVal, BaseType);
4879 const LValue &LVal,
APValue &RVal,
4880 bool WantObjectRepresentation =
false) {
4881 if (LVal.Designator.Invalid)
4890 if (
Base && !LVal.getLValueCallIndex() && !
Type.isVolatileQualified()) {
4894 assert(LVal.Designator.Entries.size() <= 1 &&
4895 "Can only read characters from string literals");
4896 if (LVal.Designator.Entries.empty()) {
4903 if (LVal.Designator.isOnePastTheEnd()) {
4904 if (Info.getLangOpts().CPlusPlus11)
4905 Info.FFDiag(Conv, diag::note_constexpr_access_past_end) << AK;
4910 uint64_t CharIndex = LVal.Designator.Entries[0].getAsArrayIndex();
4917 return Obj &&
extractSubobject(Info, Conv, Obj, LVal.Designator, RVal, AK);
4931 LVal.setFrom(Info.Ctx, Val);
4947 if (LVal.Designator.Invalid)
4950 if (!Info.getLangOpts().CPlusPlus14) {
4960struct CompoundAssignSubobjectHandler {
4962 const CompoundAssignOperator *E;
4963 QualType PromotedLHSType;
4969 typedef bool result_type;
4971 bool checkConst(QualType QT) {
4974 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
4980 bool failed() {
return false; }
4981 bool found(
APValue &Subobj, QualType SubobjType) {
4984 return found(Subobj.
getInt(), SubobjType);
4986 return found(Subobj.
getFloat(), SubobjType);
4993 return foundPointer(Subobj, SubobjType);
4995 return foundVector(Subobj, SubobjType);
4997 Info.FFDiag(E, diag::note_constexpr_access_uninit)
5008 bool foundVector(
APValue &
Value, QualType SubobjType) {
5009 if (!checkConst(SubobjType))
5020 if (!checkConst(SubobjType))
5039 Info.Ctx.getLangOpts());
5042 PromotedLHSType, FValue) &&
5051 bool found(APFloat &
Value, QualType SubobjType) {
5052 return checkConst(SubobjType) &&
5058 bool foundPointer(
APValue &Subobj, QualType SubobjType) {
5059 if (!checkConst(SubobjType))
5062 QualType PointeeType;
5063 if (
const PointerType *PT = SubobjType->
getAs<PointerType>())
5067 (Opcode != BO_Add && Opcode != BO_Sub)) {
5073 if (Opcode == BO_Sub)
5077 LVal.setFrom(Info.Ctx, Subobj);
5080 LVal.moveInto(Subobj);
5086const AccessKinds CompoundAssignSubobjectHandler::AccessKind;
5091 const LValue &LVal,
QualType LValType,
5095 if (LVal.Designator.Invalid)
5098 if (!Info.getLangOpts().CPlusPlus14) {
5104 CompoundAssignSubobjectHandler Handler = { Info, E, PromotedLValType, Opcode,
5106 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
5110struct IncDecSubobjectHandler {
5112 const UnaryOperator *E;
5116 typedef bool result_type;
5118 bool checkConst(QualType QT) {
5121 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
5127 bool failed() {
return false; }
5128 bool found(
APValue &Subobj, QualType SubobjType) {
5138 return found(Subobj.
getInt(), SubobjType);
5140 return found(Subobj.
getFloat(), SubobjType);
5143 SubobjType->
castAs<ComplexType>()->getElementType()
5147 SubobjType->
castAs<ComplexType>()->getElementType()
5150 return foundPointer(Subobj, SubobjType);
5158 if (!checkConst(SubobjType))
5180 bool WasNegative =
Value.isNegative();
5194 unsigned BitWidth =
Value.getBitWidth();
5195 APSInt ActualValue(
Value.sext(BitWidth + 1),
false);
5196 ActualValue.setBit(BitWidth);
5202 bool found(APFloat &
Value, QualType SubobjType) {
5203 if (!checkConst(SubobjType))
5210 APFloat::opStatus St;
5212 St =
Value.add(One, RM);
5214 St =
Value.subtract(One, RM);
5217 bool foundPointer(
APValue &Subobj, QualType SubobjType) {
5218 if (!checkConst(SubobjType))
5221 QualType PointeeType;
5222 if (
const PointerType *PT = SubobjType->
getAs<PointerType>())
5230 LVal.setFrom(Info.Ctx, Subobj);
5234 LVal.moveInto(Subobj);
5243 if (LVal.Designator.Invalid)
5246 if (!Info.getLangOpts().CPlusPlus14) {
5254 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
5260 if (
Object->getType()->isPointerType() &&
Object->isPRValue())
5266 if (
Object->getType()->isLiteralType(Info.Ctx))
5269 if (
Object->getType()->isRecordType() &&
Object->isPRValue())
5272 Info.FFDiag(
Object, diag::note_constexpr_nonliteral) <<
Object->getType();
5291 bool IncludeMember =
true) {
5298 if (!MemPtr.getDecl()) {
5304 if (MemPtr.isDerivedMember()) {
5311 if (LV.Designator.MostDerivedPathLength + MemPtr.Path.size() >
5312 LV.Designator.Entries.size()) {
5316 unsigned PathLengthToMember =
5317 LV.Designator.Entries.size() - MemPtr.Path.size();
5318 for (
unsigned I = 0, N = MemPtr.Path.size(); I != N; ++I) {
5320 LV.Designator.Entries[PathLengthToMember + I]);
5337 (PathLengthToMember > LV.Designator.MostDerivedPathLength)
5338 ? getAsBaseClass(LV.Designator.Entries[PathLengthToMember - 1])
5340 const CXXRecordDecl *LastMPDecl = MemPtr.getContainingRecord();
5348 PathLengthToMember))
5350 }
else if (!MemPtr.Path.empty()) {
5352 LV.Designator.Entries.reserve(LV.Designator.Entries.size() +
5353 MemPtr.Path.size() + IncludeMember);
5359 assert(RD &&
"member pointer access on non-class-type expression");
5361 for (
unsigned I = 1, N = MemPtr.Path.size(); I != N; ++I) {
5369 MemPtr.getContainingRecord()))
5374 if (IncludeMember) {
5375 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(MemPtr.getDecl())) {
5379 dyn_cast<IndirectFieldDecl>(MemPtr.getDecl())) {
5383 llvm_unreachable(
"can't construct reference to bound member function");
5387 return MemPtr.getDecl();
5393 bool IncludeMember =
true) {
5397 if (Info.noteFailure()) {
5405 BO->
getRHS(), IncludeMember);
5412 SubobjectDesignator &D = Result.Designator;
5413 if (D.Invalid || !Result.checkNullPointer(Info, E,
CSK_Derived))
5420 auto InvalidCast = [&]() {
5421 if (!Info.checkingPotentialConstantExpression() ||
5422 !Result.AllowConstexprUnknown) {
5423 Info.CCEDiag(E, diag::note_constexpr_invalid_downcast)
5424 << D.MostDerivedType << TargetQT;
5430 if (D.MostDerivedPathLength + E->
path_size() > D.Entries.size())
5431 return InvalidCast();
5435 unsigned NewEntriesSize = D.Entries.size() - E->
path_size();
5438 if (NewEntriesSize == D.MostDerivedPathLength)
5441 FinalType = getAsBaseClass(D.Entries[NewEntriesSize - 1]);
5443 return InvalidCast();
5455 if (!Result.isAbsent())
5458 if (
auto *RD = T->getAsCXXRecordDecl()) {
5459 if (RD->isInvalidDecl()) {
5463 if (RD->isUnion()) {
5472 End = RD->bases_end();
5473 I != End; ++I, ++Index)
5477 for (
const auto *I : RD->fields()) {
5478 if (I->isUnnamedBitField())
5481 I->getType(), Result.getStructField(I->getFieldIndex()));
5487 dyn_cast_or_null<ConstantArrayType>(T->getAsArrayTypeUnsafe())) {
5489 if (Result.hasArrayFiller())
5501enum EvalStmtResult {
5530 if (!Result.Designator.Invalid && Result.Designator.isOnePastTheEnd()) {
5536 Result.moveInto(Val);
5548 APValue &Val = Info.CurrentCall->createTemporary(VD, VD->
getType(),
5549 ScopeKind::Block, Result);
5554 return Info.noteSideEffect();
5575 const DecompositionDecl *DD);
5578 bool EvaluateConditionDecl =
false) {
5580 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
5584 EvaluateConditionDecl && DD)
5594 if (
auto *VD = BD->getHoldingVar())
5602 if (
auto *DD = dyn_cast_if_present<DecompositionDecl>(VD)) {
5611 if (Info.noteSideEffect())
5613 assert(E->
containsErrors() &&
"valid value-dependent expression should never "
5614 "reach invalid code path.");
5621 if (
Cond->isValueDependent())
5623 FullExpressionRAII
Scope(Info);
5630 return Scope.destroy();
5643struct TempVersionRAII {
5644 CallStackFrame &Frame;
5646 TempVersionRAII(CallStackFrame &Frame) : Frame(Frame) {
5647 Frame.pushTempVersion();
5650 ~TempVersionRAII() {
5651 Frame.popTempVersion();
5659 const SwitchCase *SC =
nullptr);
5665 const Stmt *LoopOrSwitch,
5667 EvalStmtResult &ESR) {
5671 if (!IsSwitch && ESR == ESR_Succeeded) {
5676 if (ESR != ESR_Break && ESR != ESR_Continue)
5680 bool CanBreakOrContinue = !IsSwitch || ESR == ESR_Break;
5681 const Stmt *StackTop = Info.BreakContinueStack.back();
5682 if (CanBreakOrContinue && (StackTop ==
nullptr || StackTop == LoopOrSwitch)) {
5683 Info.BreakContinueStack.pop_back();
5684 if (ESR == ESR_Break)
5685 ESR = ESR_Succeeded;
5690 for (BlockScopeRAII *S : Scopes) {
5691 if (!S->destroy()) {
5703 BlockScopeRAII
Scope(Info);
5705 EvalStmtResult ESR =
EvaluateStmt(Result, Info, Body, Case);
5706 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5715 BlockScopeRAII
Scope(Info);
5722 if (ESR != ESR_Succeeded) {
5723 if (ESR != ESR_Failed && !
Scope.destroy())
5729 FullExpressionRAII CondScope(Info);
5744 if (!CondScope.destroy())
5765 if (LHSValue <=
Value &&
Value <= RHSValue) {
5772 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5776 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5783 llvm_unreachable(
"Should have been converted to Succeeded");
5789 case ESR_CaseNotFound:
5792 Info.FFDiag(
Found->getBeginLoc(),
5793 diag::note_constexpr_stmt_expr_unsupported);
5796 llvm_unreachable(
"Invalid EvalStmtResult!");
5806 Info.CCEDiag(VD->
getLocation(), diag::note_constexpr_static_local)
5816 if (!Info.nextStep(S))
5823 case Stmt::CompoundStmtClass:
5827 case Stmt::LabelStmtClass:
5828 case Stmt::AttributedStmtClass:
5829 case Stmt::DoStmtClass:
5832 case Stmt::CaseStmtClass:
5833 case Stmt::DefaultStmtClass:
5838 case Stmt::IfStmtClass: {
5845 BlockScopeRAII
Scope(Info);
5851 if (ESR != ESR_CaseNotFound) {
5852 assert(ESR != ESR_Succeeded);
5863 if (ESR == ESR_Failed)
5865 if (ESR != ESR_CaseNotFound)
5866 return Scope.destroy() ? ESR : ESR_Failed;
5868 return ESR_CaseNotFound;
5871 if (ESR == ESR_Failed)
5873 if (ESR != ESR_CaseNotFound)
5874 return Scope.destroy() ? ESR : ESR_Failed;
5875 return ESR_CaseNotFound;
5878 case Stmt::WhileStmtClass: {
5879 EvalStmtResult ESR =
5883 if (ESR != ESR_Continue)
5888 case Stmt::ForStmtClass: {
5890 BlockScopeRAII
Scope(Info);
5896 if (ESR != ESR_CaseNotFound) {
5897 assert(ESR != ESR_Succeeded);
5902 EvalStmtResult ESR =
5906 if (ESR != ESR_Continue)
5908 if (
const auto *Inc = FS->
getInc()) {
5909 if (Inc->isValueDependent()) {
5913 FullExpressionRAII IncScope(Info);
5921 case Stmt::DeclStmtClass: {
5925 for (
const auto *D : DS->
decls()) {
5926 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
5929 if (VD->hasLocalStorage() && !VD->getInit())
5937 return ESR_CaseNotFound;
5941 return ESR_CaseNotFound;
5947 if (
const Expr *E = dyn_cast<Expr>(S)) {
5956 FullExpressionRAII
Scope(Info);
5960 return ESR_Succeeded;
5966 case Stmt::NullStmtClass:
5967 return ESR_Succeeded;
5969 case Stmt::DeclStmtClass: {
5971 for (
const auto *D : DS->
decls()) {
5972 const VarDecl *VD = dyn_cast_or_null<VarDecl>(D);
5976 FullExpressionRAII
Scope(Info);
5978 !Info.noteFailure())
5980 if (!
Scope.destroy())
5983 return ESR_Succeeded;
5986 case Stmt::ReturnStmtClass: {
5988 FullExpressionRAII
Scope(Info);
5997 :
Evaluate(Result.Value, Info, RetExpr)))
5999 return Scope.destroy() ? ESR_Returned : ESR_Failed;
6002 case Stmt::CompoundStmtClass: {
6003 BlockScopeRAII
Scope(Info);
6006 for (
const auto *BI : CS->
body()) {
6007 EvalStmtResult ESR =
EvaluateStmt(Result, Info, BI, Case);
6008 if (ESR == ESR_Succeeded)
6010 else if (ESR != ESR_CaseNotFound) {
6011 if (ESR != ESR_Failed && !
Scope.destroy())
6017 return ESR_CaseNotFound;
6018 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
6021 case Stmt::IfStmtClass: {
6025 BlockScopeRAII
Scope(Info);
6028 if (ESR != ESR_Succeeded) {
6029 if (ESR != ESR_Failed && !
Scope.destroy())
6039 if (!Info.InConstantContext)
6046 EvalStmtResult ESR =
EvaluateStmt(Result, Info, SubStmt);
6047 if (ESR != ESR_Succeeded) {
6048 if (ESR != ESR_Failed && !
Scope.destroy())
6053 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
6056 case Stmt::WhileStmtClass: {
6059 BlockScopeRAII
Scope(Info);
6071 if (ESR != ESR_Continue) {
6072 if (ESR != ESR_Failed && !
Scope.destroy())
6076 if (!
Scope.destroy())
6079 return ESR_Succeeded;
6082 case Stmt::DoStmtClass: {
6089 if (ESR != ESR_Continue)
6098 FullExpressionRAII CondScope(Info);
6100 !CondScope.destroy())
6103 return ESR_Succeeded;
6106 case Stmt::ForStmtClass: {
6108 BlockScopeRAII ForScope(Info);
6111 if (ESR != ESR_Succeeded) {
6112 if (ESR != ESR_Failed && !ForScope.destroy())
6118 BlockScopeRAII IterScope(Info);
6119 bool Continue =
true;
6125 if (!IterScope.destroy())
6133 if (ESR != ESR_Continue) {
6134 if (ESR != ESR_Failed && (!IterScope.destroy() || !ForScope.destroy()))
6139 if (
const auto *Inc = FS->
getInc()) {
6140 if (Inc->isValueDependent()) {
6144 FullExpressionRAII IncScope(Info);
6150 if (!IterScope.destroy())
6153 return ForScope.destroy() ? ESR_Succeeded : ESR_Failed;
6156 case Stmt::CXXForRangeStmtClass: {
6158 BlockScopeRAII
Scope(Info);
6163 if (ESR != ESR_Succeeded) {
6164 if (ESR != ESR_Failed && !
Scope.destroy())
6172 if (ESR != ESR_Succeeded) {
6173 if (ESR != ESR_Failed && !
Scope.destroy())
6185 if (ESR != ESR_Succeeded) {
6186 if (ESR != ESR_Failed && !
Scope.destroy())
6191 if (ESR != ESR_Succeeded) {
6192 if (ESR != ESR_Failed && !
Scope.destroy())
6205 bool Continue =
true;
6206 FullExpressionRAII CondExpr(Info);
6214 BlockScopeRAII InnerScope(Info);
6216 if (ESR != ESR_Succeeded) {
6217 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
6226 if (ESR != ESR_Continue) {
6227 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
6240 if (!InnerScope.destroy())
6244 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
6247 case Stmt::SwitchStmtClass:
6250 case Stmt::ContinueStmtClass:
6251 case Stmt::BreakStmtClass: {
6253 Info.BreakContinueStack.push_back(B->getNamedLoopOrSwitch());
6257 case Stmt::LabelStmtClass:
6260 case Stmt::AttributedStmtClass: {
6262 const auto *SS = AS->getSubStmt();
6263 MSConstexprContextRAII ConstexprContext(
6267 auto LO = Info.Ctx.getLangOpts();
6268 if (LO.CXXAssumptions && !LO.MSVCCompat) {
6269 for (
auto *
Attr : AS->getAttrs()) {
6270 auto *AA = dyn_cast<CXXAssumeAttr>(
Attr);
6274 auto *Assumption = AA->getAssumption();
6275 if (Assumption->isValueDependent())
6278 if (Assumption->HasSideEffects(Info.Ctx))
6285 Info.CCEDiag(Assumption->getExprLoc(),
6286 diag::note_constexpr_assumption_failed);
6295 case Stmt::CaseStmtClass:
6296 case Stmt::DefaultStmtClass:
6298 case Stmt::CXXTryStmtClass:
6310 bool IsValueInitialization) {
6317 if (!CD->
isConstexpr() && !IsValueInitialization) {
6318 if (Info.getLangOpts().CPlusPlus11) {
6321 Info.CCEDiag(Loc, diag::note_constexpr_invalid_function, 1)
6323 Info.Note(CD->
getLocation(), diag::note_declared_at);
6325 Info.CCEDiag(Loc, diag::note_invalid_subexpr_in_const_expr);
6339 if (Info.checkingPotentialConstantExpression() && !
Definition &&
6347 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6356 Info.CCEDiag(CallLoc, diag::note_constexpr_virtual_call);
6359 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6365 (
Definition->isConstexpr() || (Info.CurrentCall->CanEvalMSConstexpr &&
6375 StringRef Name = DiagDecl->
getName();
6377 Name ==
"__assert_rtn" || Name ==
"__assert_fail" || Name ==
"_wassert";
6379 Info.FFDiag(CallLoc, diag::note_constexpr_assert_failed);
6384 if (Info.getLangOpts().CPlusPlus11) {
6387 auto *CD = dyn_cast<CXXConstructorDecl>(DiagDecl);
6388 if (CD && CD->isInheritingConstructor()) {
6389 auto *Inherited = CD->getInheritedConstructor().getConstructor();
6390 if (!Inherited->isConstexpr())
6391 DiagDecl = CD = Inherited;
6397 if (CD && CD->isInheritingConstructor())
6398 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_inhctor, 1)
6399 << CD->getInheritedConstructor().getConstructor()->getParent();
6401 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_function, 1)
6403 Info.Note(DiagDecl->
getLocation(), diag::note_declared_at);
6405 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6411struct CheckDynamicTypeHandler {
6413 typedef bool result_type;
6414 bool failed() {
return false; }
6415 bool found(
APValue &Subobj, QualType SubobjType) {
return true; }
6416 bool found(
APSInt &
Value, QualType SubobjType) {
return true; }
6417 bool found(APFloat &
Value, QualType SubobjType) {
return true; }
6425 if (
This.Designator.Invalid)
6437 if (
This.Designator.isOnePastTheEnd() ||
6438 This.Designator.isMostDerivedAnUnsizedArray()) {
6439 Info.FFDiag(E,
This.Designator.isOnePastTheEnd()
6440 ? diag::note_constexpr_access_past_end
6441 : diag::note_constexpr_access_unsized_array)
6444 }
else if (Polymorphic) {
6447 if (!Info.checkingPotentialConstantExpression() ||
6448 !
This.AllowConstexprUnknown) {
6452 Info.Ctx.getLValueReferenceType(
This.Designator.getType(Info.Ctx));
6453 Info.FFDiag(E, diag::note_constexpr_polymorphic_unknown_dynamic_type)
6461 CheckDynamicTypeHandler Handler{AK};
6484 unsigned PathLength) {
6485 assert(PathLength >=
Designator.MostDerivedPathLength && PathLength <=
6486 Designator.Entries.size() &&
"invalid path length");
6487 return (PathLength ==
Designator.MostDerivedPathLength)
6488 ?
Designator.MostDerivedType->getAsCXXRecordDecl()
6489 : getAsBaseClass(
Designator.Entries[PathLength - 1]);
6502 return std::nullopt;
6504 if (
This.Designator.Invalid)
6505 return std::nullopt;
6514 This.Designator.MostDerivedType->getAsCXXRecordDecl();
6515 if (!Class || Class->getNumVBases()) {
6517 return std::nullopt;
6525 for (
unsigned PathLength =
This.Designator.MostDerivedPathLength;
6526 PathLength <= Path.size(); ++PathLength) {
6527 switch (Info.isEvaluatingCtorDtor(
This.getLValueBase(),
6528 Path.slice(0, PathLength))) {
6529 case ConstructionPhase::Bases:
6530 case ConstructionPhase::DestroyingBases:
6535 case ConstructionPhase::None:
6536 case ConstructionPhase::AfterBases:
6537 case ConstructionPhase::AfterFields:
6538 case ConstructionPhase::Destroying:
6550 return std::nullopt;
6568 unsigned PathLength = DynType->PathLength;
6569 for (; PathLength <=
This.Designator.Entries.size(); ++PathLength) {
6572 Found->getCorrespondingMethodDeclaredInClass(Class,
false);
6582 if (Callee->isPureVirtual()) {
6583 Info.FFDiag(E, diag::note_constexpr_pure_virtual_call, 1) << Callee;
6584 Info.Note(Callee->getLocation(), diag::note_declared_at);
6590 if (!Info.Ctx.hasSameUnqualifiedType(Callee->getReturnType(),
6591 Found->getReturnType())) {
6592 CovariantAdjustmentPath.push_back(Callee->getReturnType());
6593 for (
unsigned CovariantPathLength = PathLength + 1;
6594 CovariantPathLength !=
This.Designator.Entries.size();
6595 ++CovariantPathLength) {
6599 Found->getCorrespondingMethodDeclaredInClass(NextClass,
false);
6600 if (
Next && !Info.Ctx.hasSameUnqualifiedType(
6601 Next->getReturnType(), CovariantAdjustmentPath.back()))
6602 CovariantAdjustmentPath.push_back(
Next->getReturnType());
6604 if (!Info.Ctx.hasSameUnqualifiedType(
Found->getReturnType(),
6605 CovariantAdjustmentPath.back()))
6606 CovariantAdjustmentPath.push_back(
Found->getReturnType());
6622 assert(Result.isLValue() &&
6623 "unexpected kind of APValue for covariant return");
6624 if (Result.isNullPointer())
6628 LVal.setFrom(Info.Ctx, Result);
6630 const CXXRecordDecl *OldClass = Path[0]->getPointeeCXXRecordDecl();
6631 for (
unsigned I = 1; I != Path.size(); ++I) {
6632 const CXXRecordDecl *NewClass = Path[I]->getPointeeCXXRecordDecl();
6633 assert(OldClass && NewClass &&
"unexpected kind of covariant return");
6634 if (OldClass != NewClass &&
6637 OldClass = NewClass;
6640 LVal.moveInto(Result);
6649 auto *BaseClass = BaseSpec.getType()->getAsCXXRecordDecl();
6651 return BaseSpec.getAccessSpecifier() ==
AS_public;
6653 llvm_unreachable(
"Base is not a direct base of Derived");
6663 SubobjectDesignator &D = Ptr.Designator;
6669 if (Ptr.isNullPointer() && !E->
isGLValue())
6675 std::optional<DynamicType> DynType =
6687 assert(
C &&
"dynamic_cast target is not void pointer nor class");
6695 Ptr.setNull(Info.Ctx, E->
getType());
6702 DynType->Type->isDerivedFrom(
C)))
6704 else if (!Paths || Paths->begin() == Paths->end())
6706 else if (Paths->isAmbiguous(CQT))
6709 assert(Paths->front().Access !=
AS_public &&
"why did the cast fail?");
6712 Info.FFDiag(E, diag::note_constexpr_dynamic_cast_to_reference_failed)
6713 << DiagKind << Ptr.Designator.getType(Info.Ctx)
6714 << Info.Ctx.getCanonicalTagType(DynType->Type)
6722 for (
int PathLength = Ptr.Designator.Entries.size();
6723 PathLength >= (
int)DynType->PathLength; --PathLength) {
6728 if (PathLength > (
int)DynType->PathLength &&
6731 return RuntimeCheckFailed(
nullptr);
6738 if (DynType->Type->isDerivedFrom(
C, Paths) && !Paths.
isAmbiguous(CQT) &&
6751 return RuntimeCheckFailed(&Paths);
6755struct StartLifetimeOfUnionMemberHandler {
6757 const Expr *LHSExpr;
6758 const FieldDecl *
Field;
6760 bool Failed =
false;
6763 typedef bool result_type;
6764 bool failed() {
return Failed; }
6765 bool found(
APValue &Subobj, QualType SubobjType) {
6780 }
else if (DuringInit) {
6784 Info.FFDiag(LHSExpr,
6785 diag::note_constexpr_union_member_change_during_init);
6794 llvm_unreachable(
"wrong value kind for union object");
6796 bool found(APFloat &
Value, QualType SubobjType) {
6797 llvm_unreachable(
"wrong value kind for union object");
6802const AccessKinds StartLifetimeOfUnionMemberHandler::AccessKind;
6809 const Expr *LHSExpr,
6810 const LValue &LHS) {
6811 if (LHS.InvalidBase || LHS.Designator.Invalid)
6817 unsigned PathLength = LHS.Designator.Entries.size();
6818 for (
const Expr *E = LHSExpr; E !=
nullptr;) {
6820 if (
auto *ME = dyn_cast<MemberExpr>(E)) {
6821 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
6824 if (!FD || FD->getType()->isReferenceType())
6828 if (FD->getParent()->isUnion()) {
6833 FD->getType()->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
6834 if (!RD || RD->hasTrivialDefaultConstructor())
6835 UnionPathLengths.push_back({PathLength - 1, FD});
6841 LHS.Designator.Entries[PathLength]
6842 .getAsBaseOrMember().getPointer()));
6846 }
else if (
auto *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
6848 auto *
Base = ASE->getBase()->IgnoreImplicit();
6849 if (!
Base->getType()->isArrayType())
6855 }
else if (
auto *ICE = dyn_cast<ImplicitCastExpr>(E)) {
6858 if (ICE->getCastKind() == CK_NoOp)
6860 if (ICE->getCastKind() != CK_DerivedToBase &&
6861 ICE->getCastKind() != CK_UncheckedDerivedToBase)
6865 if (Elt->isVirtual()) {
6874 LHS.Designator.Entries[PathLength]
6875 .getAsBaseOrMember().getPointer()));
6885 if (UnionPathLengths.empty())
6890 CompleteObject Obj =
6894 for (std::pair<unsigned, const FieldDecl *> LengthAndField :
6895 llvm::reverse(UnionPathLengths)) {
6897 SubobjectDesignator D = LHS.Designator;
6898 D.truncate(Info.Ctx, LHS.Base, LengthAndField.first);
6900 bool DuringInit = Info.isEvaluatingCtorDtor(LHS.Base, D.Entries) ==
6901 ConstructionPhase::AfterBases;
6902 StartLifetimeOfUnionMemberHandler StartLifetime{
6903 Info, LHSExpr, LengthAndField.second, DuringInit};
6912 CallRef
Call, EvalInfo &Info,
bool NonNull =
false,
6913 APValue **EvaluatedArg =
nullptr) {
6920 APValue &
V = PVD ? Info.CurrentCall->createParam(
Call, PVD, LV)
6921 : Info.CurrentCall->createTemporary(Arg, Arg->
getType(),
6922 ScopeKind::Call, LV);
6928 if (
NonNull &&
V.isLValue() &&
V.isNullPointer()) {
6929 Info.CCEDiag(Arg, diag::note_non_null_attribute_failed);
6942 bool RightToLeft =
false,
6943 LValue *ObjectArg =
nullptr) {
6945 llvm::SmallBitVector ForbiddenNullArgs;
6946 if (Callee->hasAttr<NonNullAttr>()) {
6947 ForbiddenNullArgs.resize(Args.size());
6948 for (
const auto *
Attr : Callee->specific_attrs<NonNullAttr>()) {
6949 if (!
Attr->args_size()) {
6950 ForbiddenNullArgs.set();
6953 for (
auto Idx :
Attr->args()) {
6954 unsigned ASTIdx = Idx.getASTIndex();
6955 if (ASTIdx >= Args.size())
6957 ForbiddenNullArgs[ASTIdx] =
true;
6961 for (
unsigned I = 0; I < Args.size(); I++) {
6962 unsigned Idx = RightToLeft ? Args.size() - I - 1 : I;
6964 Idx < Callee->getNumParams() ? Callee->getParamDecl(Idx) :
nullptr;
6965 bool NonNull = !ForbiddenNullArgs.empty() && ForbiddenNullArgs[Idx];
6970 if (!Info.noteFailure())
6975 ObjectArg->setFrom(Info.Ctx, *That);
6984 bool CopyObjectRepresentation) {
6986 CallStackFrame *Frame = Info.CurrentCall;
6987 APValue *RefValue = Info.getParamSlot(Frame->Arguments, Param);
6995 RefLValue.setFrom(Info.Ctx, *RefValue);
6998 CopyObjectRepresentation);
7004 const LValue *ObjectArg,
const Expr *E,
7006 const Stmt *Body, EvalInfo &Info,
7007 APValue &Result,
const LValue *ResultSlot) {
7008 if (!Info.CheckCallLimit(CallLoc))
7037 ObjectArg->moveInto(Result);
7046 if (!Info.checkingPotentialConstantExpression())
7048 Frame.LambdaThisCaptureField);
7051 StmtResult Ret = {Result, ResultSlot};
7053 if (ESR == ESR_Succeeded) {
7054 if (Callee->getReturnType()->isVoidType())
7056 Info.FFDiag(Callee->getEndLoc(), diag::note_constexpr_no_return);
7058 return ESR == ESR_Returned;
7065 EvalInfo &Info,
APValue &Result) {
7067 if (!Info.CheckCallLimit(CallLoc))
7072 Info.FFDiag(CallLoc, diag::note_constexpr_virtual_base) << RD;
7076 EvalInfo::EvaluatingConstructorRAII EvalObj(
7078 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries},
7085 StmtResult Ret = {RetVal,
nullptr};
7090 if ((*I)->getInit()->isValueDependent()) {
7094 FullExpressionRAII InitScope(Info);
7096 !InitScope.destroy())
7119 if (!Result.hasValue()) {
7132 BlockScopeRAII LifetimeExtendedScope(Info);
7135 unsigned BasesSeen = 0;
7140 auto SkipToField = [&](
FieldDecl *FD,
bool Indirect) {
7145 assert(Indirect &&
"fields out of order?");
7151 assert(FieldIt != RD->
field_end() &&
"missing field?");
7152 if (!FieldIt->isUnnamedBitField())
7155 Result.getStructField(FieldIt->getFieldIndex()));
7160 LValue Subobject =
This;
7161 LValue SubobjectParent =
This;
7166 if (I->isBaseInitializer()) {
7167 QualType BaseType(I->getBaseClass(), 0);
7171 assert(!BaseIt->
isVirtual() &&
"virtual base for literal type");
7172 assert(Info.Ctx.hasSameUnqualifiedType(BaseIt->
getType(), BaseType) &&
7173 "base class initializers not in expected order");
7177 BaseType->getAsCXXRecordDecl(), &Layout))
7179 Value = &Result.getStructBase(BasesSeen++);
7180 }
else if ((FD = I->getMember())) {
7185 Value = &Result.getUnionValue();
7187 SkipToField(FD,
false);
7193 auto IndirectFieldChain = IFD->chain();
7194 for (
auto *
C : IndirectFieldChain) {
7203 (
Value->isUnion() &&
7216 if (
C == IndirectFieldChain.back())
7217 SubobjectParent = Subobject;
7223 if (
C == IndirectFieldChain.front() && !RD->
isUnion())
7224 SkipToField(FD,
true);
7229 llvm_unreachable(
"unknown base initializer kind");
7236 if (
Init->isValueDependent()) {
7240 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &SubobjectParent,
7242 FullExpressionRAII InitScope(Info);
7248 if (!Info.noteFailure())
7257 if (!Info.noteFailure())
7265 if (I->isBaseInitializer() && BasesSeen == RD->
getNumBases())
7266 EvalObj.finishedConstructingBases();
7271 for (; FieldIt != RD->
field_end(); ++FieldIt) {
7272 if (!FieldIt->isUnnamedBitField())
7275 Result.getStructField(FieldIt->getFieldIndex()));
7279 EvalObj.finishedConstructingFields();
7283 LifetimeExtendedScope.destroy();
7289 EvalInfo &Info,
APValue &Result) {
7290 CallScopeRAII CallScope(Info);
7296 CallScope.destroy();
7306 if (
Value.isAbsent() && !T->isNullPtrType()) {
7308 This.moveInto(Printable);
7310 diag::note_constexpr_destroy_out_of_lifetime)
7311 << Printable.
getAsString(Info.Ctx, Info.Ctx.getLValueReferenceType(T));
7327 LValue ElemLV =
This;
7328 ElemLV.addArray(Info, &LocE, CAT);
7335 if (Size && Size >
Value.getArrayInitializedElts())
7340 for (Size =
Value.getArraySize(); Size != 0; --Size) {
7341 APValue &Elem =
Value.getArrayInitializedElt(Size - 1);
7354 if (T.isDestructedType()) {
7356 diag::note_constexpr_unsupported_destruction)
7366 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_virtual_base) << RD;
7391 if (!Info.CheckCallLimit(CallRange.
getBegin()))
7400 CallStackFrame Frame(Info, CallRange,
Definition, &
This,
nullptr,
7405 EvalInfo::EvaluatingDestructorRAII EvalObj(
7407 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries});
7408 if (!EvalObj.DidInsert) {
7415 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_double_destroy);
7422 StmtResult Ret = {RetVal,
nullptr};
7435 for (
const FieldDecl *FD : llvm::reverse(Fields)) {
7436 if (FD->isUnnamedBitField())
7439 LValue Subobject =
This;
7443 APValue *SubobjectValue = &
Value.getStructField(FD->getFieldIndex());
7450 EvalObj.startedDestroyingBases();
7457 LValue Subobject =
This;
7459 BaseType->getAsCXXRecordDecl(), &Layout))
7462 APValue *SubobjectValue = &
Value.getStructBase(BasesLeft);
7467 assert(BasesLeft == 0 &&
"NumBases was wrong?");
7475struct DestroyObjectHandler {
7481 typedef bool result_type;
7482 bool failed() {
return false; }
7483 bool found(
APValue &Subobj, QualType SubobjType) {
7488 Info.FFDiag(E, diag::note_constexpr_destroy_complex_elem);
7491 bool found(APFloat &
Value, QualType SubobjType) {
7492 Info.FFDiag(E, diag::note_constexpr_destroy_complex_elem);
7513 if (Info.EvalStatus.HasSideEffects)
7524 if (Info.checkingPotentialConstantExpression() ||
7525 Info.SpeculativeEvaluationDepth)
7529 auto Caller = Info.getStdAllocatorCaller(
"allocate");
7531 Info.FFDiag(E->
getExprLoc(), Info.getLangOpts().CPlusPlus20
7532 ? diag::note_constexpr_new_untyped
7533 : diag::note_constexpr_new);
7537 QualType ElemType = Caller.ElemType;
7540 diag::note_constexpr_new_not_complete_object_type)
7548 bool IsNothrow =
false;
7549 for (
unsigned I = 1, N = E->
getNumArgs(); I != N; ++I) {
7557 APInt Size, Remainder;
7558 APInt ElemSizeAP(ByteSize.getBitWidth(), ElemSize.
getQuantity());
7559 APInt::udivrem(ByteSize, ElemSizeAP, Size, Remainder);
7560 if (Remainder != 0) {
7562 Info.FFDiag(E->
getExprLoc(), diag::note_constexpr_operator_new_bad_size)
7563 << ByteSize <<
APSInt(ElemSizeAP,
true) << ElemType;
7567 if (!Info.CheckArraySize(E->
getBeginLoc(), ByteSize.getActiveBits(),
7568 Size.getZExtValue(), !IsNothrow)) {
7570 Result.setNull(Info.Ctx, E->
getType());
7576 QualType AllocType = Info.Ctx.getConstantArrayType(
7578 APValue *Val = Info.createHeapAlloc(Caller.Call, AllocType, Result);
7587 return DD->isVirtual();
7594 return DD->isVirtual() ? DD->getOperatorDelete() :
nullptr;
7605 DynAlloc::Kind DeallocKind) {
7606 auto PointerAsString = [&] {
7607 return Pointer.toString(Info.Ctx, Info.Ctx.VoidPtrTy);
7612 Info.FFDiag(E, diag::note_constexpr_delete_not_heap_alloc)
7613 << PointerAsString();
7616 return std::nullopt;
7619 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
7621 Info.FFDiag(E, diag::note_constexpr_double_delete);
7622 return std::nullopt;
7625 if (DeallocKind != (*Alloc)->getKind()) {
7627 Info.FFDiag(E, diag::note_constexpr_new_delete_mismatch)
7628 << DeallocKind << (*Alloc)->getKind() << AllocType;
7630 return std::nullopt;
7633 bool Subobject =
false;
7634 if (DeallocKind == DynAlloc::New) {
7635 Subobject =
Pointer.Designator.MostDerivedPathLength != 0 ||
7636 Pointer.Designator.isOnePastTheEnd();
7638 Subobject =
Pointer.Designator.Entries.size() != 1 ||
7639 Pointer.Designator.Entries[0].getAsArrayIndex() != 0;
7642 Info.FFDiag(E, diag::note_constexpr_delete_subobject)
7643 << PointerAsString() <<
Pointer.Designator.isOnePastTheEnd();
7644 return std::nullopt;
7652 if (Info.checkingPotentialConstantExpression() ||
7653 Info.SpeculativeEvaluationDepth)
7657 if (!Info.getStdAllocatorCaller(
"deallocate")) {
7665 for (
unsigned I = 1, N = E->
getNumArgs(); I != N; ++I)
7668 if (
Pointer.Designator.Invalid)
7673 if (
Pointer.isNullPointer()) {
7674 Info.CCEDiag(E->
getExprLoc(), diag::note_constexpr_deallocate_null);
7690class BitCastBuffer {
7696 SmallVector<std::optional<unsigned char>, 32> Bytes;
7698 static_assert(std::numeric_limits<unsigned char>::digits >= 8,
7699 "Need at least 8 bit unsigned char");
7701 bool TargetIsLittleEndian;
7704 BitCastBuffer(CharUnits Width,
bool TargetIsLittleEndian)
7705 : Bytes(Width.getQuantity()),
7706 TargetIsLittleEndian(TargetIsLittleEndian) {}
7708 [[nodiscard]]
bool readObject(CharUnits Offset, CharUnits Width,
7709 SmallVectorImpl<unsigned char> &Output)
const {
7710 for (CharUnits I = Offset, E = Offset + Width; I != E; ++I) {
7713 if (!Bytes[I.getQuantity()])
7715 Output.push_back(*Bytes[I.getQuantity()]);
7717 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
7718 std::reverse(Output.begin(), Output.end());
7722 void writeObject(CharUnits Offset, SmallVectorImpl<unsigned char> &Input) {
7723 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
7724 std::reverse(Input.begin(), Input.end());
7727 for (
unsigned char Byte : Input) {
7728 assert(!Bytes[Offset.
getQuantity() + Index] &&
"overwriting a byte?");
7734 size_t size() {
return Bytes.size(); }
7739class APValueToBufferConverter {
7741 BitCastBuffer Buffer;
7744 APValueToBufferConverter(EvalInfo &Info, CharUnits ObjectWidth,
7747 Buffer(ObjectWidth, Info.Ctx.getTargetInfo().isLittleEndian()),
7750 bool visit(
const APValue &Val, QualType Ty) {
7755 bool visit(
const APValue &Val, QualType Ty, CharUnits Offset) {
7756 assert((
size_t)Offset.
getQuantity() <= Buffer.size());
7769 return visitInt(Val.
getInt(), Ty, Offset);
7771 return visitFloat(Val.
getFloat(), Ty, Offset);
7773 return visitArray(Val, Ty, Offset);
7775 return visitRecord(Val, Ty, Offset);
7777 return visitVector(Val, Ty, Offset);
7781 return visitComplex(Val, Ty, Offset);
7791 diag::note_constexpr_bit_cast_unsupported_type)
7796 llvm_unreachable(
"Unhandled APValue::ValueKind");
7799 bool visitRecord(
const APValue &Val, QualType Ty, CharUnits Offset) {
7801 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD);
7804 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
7805 for (
size_t I = 0, E = CXXRD->getNumBases(); I != E; ++I) {
7806 const CXXBaseSpecifier &BS = CXXRD->bases_begin()[I];
7811 if (!
Base.isStruct())
7814 if (!visitRecord(Base, BS.
getType(),
7821 unsigned FieldIdx = 0;
7822 for (FieldDecl *FD : RD->
fields()) {
7823 if (FD->isBitField()) {
7825 diag::note_constexpr_bit_cast_unsupported_bitfield);
7831 assert(FieldOffsetBits % Info.Ctx.getCharWidth() == 0 &&
7832 "only bit-fields can have sub-char alignment");
7833 CharUnits FieldOffset =
7834 Info.Ctx.toCharUnitsFromBits(FieldOffsetBits) + Offset;
7835 QualType FieldTy = FD->getType();
7844 bool visitArray(
const APValue &Val, QualType Ty, CharUnits Offset) {
7850 CharUnits ElemWidth = Info.Ctx.getTypeSizeInChars(CAT->
getElementType());
7854 for (
unsigned I = 0; I != NumInitializedElts; ++I) {
7856 if (!visit(SubObj, CAT->
getElementType(), Offset + I * ElemWidth))
7863 for (
unsigned I = NumInitializedElts; I != ArraySize; ++I) {
7864 if (!visit(Filler, CAT->
getElementType(), Offset + I * ElemWidth))
7872 bool visitComplex(
const APValue &Val, QualType Ty, CharUnits Offset) {
7873 const ComplexType *ComplexTy = Ty->
castAs<ComplexType>();
7875 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
7880 Offset + (0 * EltSizeChars)))
7883 Offset + (1 * EltSizeChars)))
7887 Offset + (0 * EltSizeChars)))
7890 Offset + (1 * EltSizeChars)))
7897 bool visitVector(
const APValue &Val, QualType Ty, CharUnits Offset) {
7898 const VectorType *VTy = Ty->
castAs<VectorType>();
7911 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
7913 llvm::APInt Res = llvm::APInt::getZero(NElts);
7914 for (
unsigned I = 0; I < NElts; ++I) {
7916 assert(EltAsInt.isUnsigned() && EltAsInt.getBitWidth() == 1 &&
7917 "bool vector element must be 1-bit unsigned integer!");
7919 Res.insertBits(EltAsInt, BigEndian ? (NElts - I - 1) : I);
7922 SmallVector<uint8_t, 8> Bytes(NElts / 8);
7923 llvm::StoreIntToMemory(Res, &*Bytes.begin(), NElts / 8);
7924 Buffer.writeObject(Offset, Bytes);
7928 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
7929 for (
unsigned I = 0; I < NElts; ++I) {
7930 if (!visit(Val.
getVectorElt(I), EltTy, Offset + I * EltSizeChars))
7938 bool visitInt(
const APSInt &Val, QualType Ty, CharUnits Offset) {
7939 APSInt AdjustedVal = Val;
7940 unsigned Width = AdjustedVal.getBitWidth();
7942 Width = Info.Ctx.getTypeSize(Ty);
7943 AdjustedVal = AdjustedVal.extend(Width);
7946 SmallVector<uint8_t, 8> Bytes(Width / 8);
7947 llvm::StoreIntToMemory(AdjustedVal, &*Bytes.begin(), Width / 8);
7948 Buffer.writeObject(Offset, Bytes);
7952 bool visitFloat(
const APFloat &Val, QualType Ty, CharUnits Offset) {
7953 APSInt AsInt(Val.bitcastToAPInt());
7954 return visitInt(AsInt, Ty, Offset);
7958 static std::optional<BitCastBuffer>
7960 CharUnits DstSize = Info.Ctx.getTypeSizeInChars(BCE->
getType());
7961 APValueToBufferConverter Converter(Info, DstSize, BCE);
7963 return std::nullopt;
7964 return Converter.Buffer;
7969class BufferToAPValueConverter {
7971 const BitCastBuffer &Buffer;
7974 BufferToAPValueConverter(EvalInfo &Info,
const BitCastBuffer &Buffer,
7976 : Info(Info), Buffer(Buffer), BCE(BCE) {}
7981 std::nullopt_t unsupportedType(QualType Ty) {
7983 diag::note_constexpr_bit_cast_unsupported_type)
7985 return std::nullopt;
7988 std::nullopt_t unrepresentableValue(QualType Ty,
const APSInt &Val) {
7990 diag::note_constexpr_bit_cast_unrepresentable_value)
7992 return std::nullopt;
7995 std::optional<APValue> visit(
const BuiltinType *T, CharUnits Offset,
7996 const EnumType *EnumSugar =
nullptr) {
7998 uint64_t NullValue = Info.Ctx.getTargetNullPointerValue(QualType(T, 0));
7999 return APValue((Expr *)
nullptr,
8001 APValue::NoLValuePath{},
true);
8004 CharUnits
SizeOf = Info.Ctx.getTypeSizeInChars(T);
8010 const llvm::fltSemantics &Semantics =
8011 Info.Ctx.getFloatTypeSemantics(QualType(T, 0));
8012 unsigned NumBits = llvm::APFloatBase::getSizeInBits(Semantics);
8013 assert(NumBits % 8 == 0);
8019 SmallVector<uint8_t, 8> Bytes;
8020 if (!Buffer.readObject(Offset,
SizeOf, Bytes)) {
8023 bool IsStdByte = EnumSugar && EnumSugar->isStdByteType();
8027 if (!IsStdByte && !IsUChar) {
8028 QualType DisplayType(EnumSugar ? (
const Type *)EnumSugar : T, 0);
8030 diag::note_constexpr_bit_cast_indet_dest)
8031 << DisplayType << Info.Ctx.getLangOpts().CharIsSigned;
8032 return std::nullopt;
8038 APSInt Val(
SizeOf.getQuantity() * Info.Ctx.getCharWidth(),
true);
8039 llvm::LoadIntFromMemory(Val, &*Bytes.begin(), Bytes.size());
8044 unsigned IntWidth = Info.Ctx.getIntWidth(QualType(T, 0));
8045 if (IntWidth != Val.getBitWidth()) {
8046 APSInt Truncated = Val.trunc(IntWidth);
8047 if (Truncated.extend(Val.getBitWidth()) != Val)
8048 return unrepresentableValue(QualType(T, 0), Val);
8056 const llvm::fltSemantics &Semantics =
8057 Info.Ctx.getFloatTypeSemantics(QualType(T, 0));
8061 return unsupportedType(QualType(T, 0));
8064 std::optional<APValue> visit(
const RecordType *RTy, CharUnits Offset) {
8065 const RecordDecl *RD = RTy->getAsRecordDecl();
8066 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD);
8068 unsigned NumBases = 0;
8069 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
8070 NumBases = CXXRD->getNumBases();
8075 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
8076 for (
size_t I = 0, E = CXXRD->getNumBases(); I != E; ++I) {
8077 const CXXBaseSpecifier &BS = CXXRD->bases_begin()[I];
8080 std::optional<APValue> SubObj = visitType(
8083 return std::nullopt;
8084 ResultVal.getStructBase(I) = *SubObj;
8089 unsigned FieldIdx = 0;
8090 for (FieldDecl *FD : RD->
fields()) {
8093 if (FD->isBitField()) {
8095 diag::note_constexpr_bit_cast_unsupported_bitfield);
8096 return std::nullopt;
8100 assert(FieldOffsetBits % Info.Ctx.getCharWidth() == 0);
8102 CharUnits FieldOffset =
8105 QualType FieldTy = FD->getType();
8106 std::optional<APValue> SubObj = visitType(FieldTy, FieldOffset);
8108 return std::nullopt;
8109 ResultVal.getStructField(FieldIdx) = *SubObj;
8116 std::optional<APValue> visit(
const EnumType *Ty, CharUnits Offset) {
8117 QualType RepresentationType =
8118 Ty->getDecl()->getDefinitionOrSelf()->getIntegerType();
8119 assert(!RepresentationType.
isNull() &&
8120 "enum forward decl should be caught by Sema");
8121 const auto *AsBuiltin =
8125 return visit(AsBuiltin, Offset, Ty);
8128 std::optional<APValue> visit(
const ConstantArrayType *Ty, CharUnits Offset) {
8130 CharUnits ElementWidth = Info.Ctx.getTypeSizeInChars(Ty->
getElementType());
8132 APValue ArrayValue(APValue::UninitArray(), Size, Size);
8133 for (
size_t I = 0; I !=
Size; ++I) {
8134 std::optional<APValue> ElementValue =
8137 return std::nullopt;
8138 ArrayValue.getArrayInitializedElt(I) = std::move(*ElementValue);
8144 std::optional<APValue> visit(
const ComplexType *Ty, CharUnits Offset) {
8146 CharUnits ElementWidth = Info.Ctx.getTypeSizeInChars(ElementType);
8149 std::optional<APValue> Values[2];
8150 for (
unsigned I = 0; I != 2; ++I) {
8151 Values[I] = visitType(Ty->
getElementType(), Offset + I * ElementWidth);
8153 return std::nullopt;
8157 return APValue(Values[0]->getInt(), Values[1]->getInt());
8158 return APValue(Values[0]->getFloat(), Values[1]->getFloat());
8161 std::optional<APValue> visit(
const VectorType *VTy, CharUnits Offset) {
8167 SmallVector<APValue, 4> Elts;
8168 Elts.reserve(NElts);
8178 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
8180 SmallVector<uint8_t, 8> Bytes;
8181 Bytes.reserve(NElts / 8);
8183 return std::nullopt;
8185 APSInt SValInt(NElts,
true);
8186 llvm::LoadIntFromMemory(SValInt, &*Bytes.begin(), Bytes.size());
8188 for (
unsigned I = 0; I < NElts; ++I) {
8190 SValInt.extractBits(1, (BigEndian ? NElts - I - 1 : I) * EltSize);
8197 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
8198 for (
unsigned I = 0; I < NElts; ++I) {
8199 std::optional<APValue> EltValue =
8200 visitType(EltTy, Offset + I * EltSizeChars);
8202 return std::nullopt;
8203 Elts.push_back(std::move(*EltValue));
8207 return APValue(Elts.data(), Elts.size());
8210 std::optional<APValue> visit(
const Type *Ty, CharUnits Offset) {
8211 return unsupportedType(QualType(Ty, 0));
8214 std::optional<APValue> visitType(QualType Ty, CharUnits Offset) {
8218#define TYPE(Class, Base) \
8220 return visit(cast<Class##Type>(Can.getTypePtr()), Offset);
8221#define ABSTRACT_TYPE(Class, Base)
8222#define NON_CANONICAL_TYPE(Class, Base) \
8224 llvm_unreachable("non-canonical type should be impossible!");
8225#define DEPENDENT_TYPE(Class, Base) \
8228 "dependent types aren't supported in the constant evaluator!");
8229#define NON_CANONICAL_UNLESS_DEPENDENT(Class, Base) \
8231 llvm_unreachable("either dependent or not canonical!");
8232#include "clang/AST/TypeNodes.inc"
8234 llvm_unreachable(
"Unhandled Type::TypeClass");
8239 static std::optional<APValue> convert(EvalInfo &Info, BitCastBuffer &Buffer,
8241 BufferToAPValueConverter Converter(Info, Buffer, BCE);
8246static bool checkBitCastConstexprEligibilityType(SourceLocation Loc,
8247 QualType Ty, EvalInfo *Info,
8248 const ASTContext &Ctx,
8249 bool CheckingDest) {
8252 auto diag = [&](
int Reason) {
8254 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_invalid_type)
8255 << CheckingDest << (Reason == 4) << Reason;
8258 auto note = [&](
int Construct, QualType NoteTy, SourceLocation NoteLoc) {
8260 Info->Note(NoteLoc, diag::note_constexpr_bit_cast_invalid_subtype)
8261 << NoteTy << Construct << Ty;
8275 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(
Record)) {
8276 for (CXXBaseSpecifier &BS : CXXRD->bases())
8277 if (!checkBitCastConstexprEligibilityType(Loc, BS.
getType(), Info, Ctx,
8281 for (FieldDecl *FD :
Record->fields()) {
8282 if (FD->getType()->isReferenceType())
8284 if (!checkBitCastConstexprEligibilityType(Loc, FD->getType(), Info, Ctx,
8286 return note(0, FD->getType(), FD->getBeginLoc());
8292 Info, Ctx, CheckingDest))
8295 if (
const auto *VTy = Ty->
getAs<VectorType>()) {
8307 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_invalid_vector)
8308 << QualType(VTy, 0) << EltSize << NElts << Ctx.
getCharWidth();
8318 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_unsupported_type)
8327static bool checkBitCastConstexprEligibility(EvalInfo *Info,
8328 const ASTContext &Ctx,
8330 bool DestOK = checkBitCastConstexprEligibilityType(
8332 bool SourceOK = DestOK && checkBitCastConstexprEligibilityType(
8338static bool handleRValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
8341 assert(
CHAR_BIT == 8 && Info.Ctx.getTargetInfo().getCharWidth() == 8 &&
8342 "no host or target supports non 8-bit chars");
8344 if (!checkBitCastConstexprEligibility(&Info, Info.Ctx, BCE))
8348 std::optional<BitCastBuffer> Buffer =
8349 APValueToBufferConverter::convert(Info, SourceRValue, BCE);
8354 std::optional<APValue> MaybeDestValue =
8355 BufferToAPValueConverter::convert(Info, *Buffer, BCE);
8356 if (!MaybeDestValue)
8359 DestValue = std::move(*MaybeDestValue);
8363static bool handleLValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
8366 assert(
CHAR_BIT == 8 && Info.Ctx.getTargetInfo().getCharWidth() == 8 &&
8367 "no host or target supports non 8-bit chars");
8369 "LValueToRValueBitcast requires an lvalue operand!");
8371 LValue SourceLValue;
8373 SourceLValue.setFrom(Info.Ctx, SourceValue);
8376 SourceRValue,
true))
8379 return handleRValueToRValueBitCast(Info, DestValue, SourceRValue, BCE);
8382template <
class Derived>
8383class ExprEvaluatorBase
8384 :
public ConstStmtVisitor<Derived, bool> {
8386 Derived &getDerived() {
return static_cast<Derived&
>(*this); }
8387 bool DerivedSuccess(
const APValue &
V,
const Expr *E) {
8388 return getDerived().Success(
V, E);
8390 bool DerivedZeroInitialization(
const Expr *E) {
8391 return getDerived().ZeroInitialization(E);
8397 template<
typename ConditionalOperator>
8398 void CheckPotentialConstantConditional(
const ConditionalOperator *E) {
8399 assert(Info.checkingPotentialConstantExpression());
8402 SmallVector<PartialDiagnosticAt, 8>
Diag;
8404 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
8411 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
8418 Error(E, diag::note_constexpr_conditional_never_const);
8422 template<
typename ConditionalOperator>
8423 bool HandleConditionalOperator(
const ConditionalOperator *E) {
8426 if (Info.checkingPotentialConstantExpression() && Info.noteFailure()) {
8427 CheckPotentialConstantConditional(E);
8430 if (Info.noteFailure()) {
8438 return StmtVisitorTy::Visit(EvalExpr);
8443 typedef ConstStmtVisitor<Derived, bool> StmtVisitorTy;
8444 typedef ExprEvaluatorBase ExprEvaluatorBaseTy;
8446 OptionalDiagnostic CCEDiag(
const Expr *E,
diag::kind D) {
8447 return Info.CCEDiag(E, D);
8450 bool ZeroInitialization(
const Expr *E) {
return Error(E); }
8452 bool IsConstantEvaluatedBuiltinCall(
const CallExpr *E) {
8454 return BuiltinOp != 0 &&
8455 Info.Ctx.BuiltinInfo.isConstantEvaluated(BuiltinOp);
8459 ExprEvaluatorBase(EvalInfo &Info) : Info(Info) {}
8461 EvalInfo &getEvalInfo() {
return Info; }
8469 bool Error(
const Expr *E) {
8470 return Error(E, diag::note_invalid_subexpr_in_const_expr);
8473 bool VisitStmt(
const Stmt *) {
8474 llvm_unreachable(
"Expression evaluator should not be called on stmts");
8476 bool VisitExpr(
const Expr *E) {
8480 bool VisitEmbedExpr(
const EmbedExpr *E) {
8481 const auto It = E->
begin();
8482 return StmtVisitorTy::Visit(*It);
8485 bool VisitPredefinedExpr(
const PredefinedExpr *E) {
8488 bool VisitConstantExpr(
const ConstantExpr *E) {
8492 return StmtVisitorTy::Visit(E->
getSubExpr());
8495 bool VisitParenExpr(
const ParenExpr *E)
8496 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8497 bool VisitUnaryExtension(
const UnaryOperator *E)
8498 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8499 bool VisitUnaryPlus(
const UnaryOperator *E)
8500 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8501 bool VisitChooseExpr(
const ChooseExpr *E)
8503 bool VisitGenericSelectionExpr(
const GenericSelectionExpr *E)
8505 bool VisitSubstNonTypeTemplateParmExpr(
const SubstNonTypeTemplateParmExpr *E)
8507 bool VisitCXXDefaultArgExpr(
const CXXDefaultArgExpr *E) {
8508 TempVersionRAII RAII(*Info.CurrentCall);
8509 SourceLocExprScopeGuard Guard(E, Info.CurrentCall->CurSourceLocExprScope);
8510 return StmtVisitorTy::Visit(E->
getExpr());
8512 bool VisitCXXDefaultInitExpr(
const CXXDefaultInitExpr *E) {
8513 TempVersionRAII RAII(*Info.CurrentCall);
8517 SourceLocExprScopeGuard Guard(E, Info.CurrentCall->CurSourceLocExprScope);
8518 return StmtVisitorTy::Visit(E->
getExpr());
8521 bool VisitExprWithCleanups(
const ExprWithCleanups *E) {
8522 FullExpressionRAII Scope(Info);
8523 return StmtVisitorTy::Visit(E->
getSubExpr()) && Scope.destroy();
8528 bool VisitCXXBindTemporaryExpr(
const CXXBindTemporaryExpr *E) {
8529 return StmtVisitorTy::Visit(E->
getSubExpr());
8532 bool VisitCXXReinterpretCastExpr(
const CXXReinterpretCastExpr *E) {
8533 CCEDiag(E, diag::note_constexpr_invalid_cast)
8534 << diag::ConstexprInvalidCastKind::Reinterpret;
8535 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8537 bool VisitCXXDynamicCastExpr(
const CXXDynamicCastExpr *E) {
8538 if (!Info.Ctx.getLangOpts().CPlusPlus20)
8539 CCEDiag(E, diag::note_constexpr_invalid_cast)
8540 << diag::ConstexprInvalidCastKind::Dynamic;
8541 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8543 bool VisitBuiltinBitCastExpr(
const BuiltinBitCastExpr *E) {
8544 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8547 bool VisitBinaryOperator(
const BinaryOperator *E) {
8553 VisitIgnoredValue(E->
getLHS());
8554 return StmtVisitorTy::Visit(E->
getRHS());
8564 return DerivedSuccess(
Result, E);
8569 bool VisitCXXRewrittenBinaryOperator(
const CXXRewrittenBinaryOperator *E) {
8573 bool VisitBinaryConditionalOperator(
const BinaryConditionalOperator *E) {
8577 if (!
Evaluate(Info.CurrentCall->createTemporary(
8580 ScopeKind::FullExpression, CommonLV),
8584 return HandleConditionalOperator(E);
8587 bool VisitConditionalOperator(
const ConditionalOperator *E) {
8588 bool IsBcpCall =
false;
8593 if (
const CallExpr *CallCE =
8595 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
8602 if (Info.checkingPotentialConstantExpression() && IsBcpCall)
8605 FoldConstant Fold(Info, IsBcpCall);
8606 if (!HandleConditionalOperator(E)) {
8607 Fold.keepDiagnostics();
8614 bool VisitOpaqueValueExpr(
const OpaqueValueExpr *E) {
8615 if (
APValue *
Value = Info.CurrentCall->getCurrentTemporary(E);
8617 return DerivedSuccess(*
Value, E);
8623 assert(0 &&
"OpaqueValueExpr recursively refers to itself");
8626 return StmtVisitorTy::Visit(Source);
8629 bool VisitPseudoObjectExpr(
const PseudoObjectExpr *E) {
8630 for (
const Expr *SemE : E->
semantics()) {
8631 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
8640 if (OVE->isUnique())
8644 if (!
Evaluate(Info.CurrentCall->createTemporary(
8645 OVE, getStorageType(Info.Ctx, OVE),
8646 ScopeKind::FullExpression, LV),
8647 Info, OVE->getSourceExpr()))
8650 if (!StmtVisitorTy::Visit(SemE))
8660 bool VisitCallExpr(
const CallExpr *E) {
8662 if (!handleCallExpr(E,
Result,
nullptr))
8664 return DerivedSuccess(
Result, E);
8668 const LValue *ResultSlot) {
8669 CallScopeRAII CallScope(Info);
8672 QualType CalleeType =
Callee->getType();
8674 const FunctionDecl *FD =
nullptr;
8675 LValue *
This =
nullptr, ObjectArg;
8677 bool HasQualifier =
false;
8683 const CXXMethodDecl *
Member =
nullptr;
8684 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(Callee)) {
8688 Member = dyn_cast<CXXMethodDecl>(ME->getMemberDecl());
8690 return Error(Callee);
8692 HasQualifier = ME->hasQualifier();
8693 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(Callee)) {
8695 const ValueDecl *D =
8699 Member = dyn_cast<CXXMethodDecl>(D);
8701 return Error(Callee);
8703 }
else if (
const auto *PDE = dyn_cast<CXXPseudoDestructorExpr>(Callee)) {
8704 if (!Info.getLangOpts().CPlusPlus20)
8705 Info.CCEDiag(PDE, diag::note_constexpr_pseudo_destructor);
8709 return Error(Callee);
8716 if (!CalleeLV.getLValueOffset().isZero())
8717 return Error(Callee);
8718 if (CalleeLV.isNullPointer()) {
8719 Info.FFDiag(Callee, diag::note_constexpr_null_callee)
8720 <<
const_cast<Expr *
>(
Callee);
8723 FD = dyn_cast_or_null<FunctionDecl>(
8724 CalleeLV.getLValueBase().dyn_cast<
const ValueDecl *>());
8726 return Error(Callee);
8729 if (!Info.Ctx.hasSameFunctionTypeIgnoringExceptionSpec(
8736 auto *OCE = dyn_cast<CXXOperatorCallExpr>(E);
8737 if (OCE && OCE->isAssignmentOp()) {
8738 assert(Args.size() == 2 &&
"wrong number of arguments in assignment");
8739 Call = Info.CurrentCall->createCall(FD);
8740 bool HasThis =
false;
8741 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FD))
8742 HasThis = MD->isImplicitObjectMemberFunction();
8750 const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD);
8770 if (Info.getLangOpts().CPlusPlus20 && OCE &&
8771 OCE->getOperator() == OO_Equal && MD->
isTrivial() &&
8775 Args = Args.slice(1);
8781 const CXXRecordDecl *ClosureClass = MD->
getParent();
8783 ClosureClass->
captures().empty() &&
8784 "Number of captures must be zero for conversion to function-ptr");
8786 const CXXMethodDecl *LambdaCallOp =
8795 "A generic lambda's static-invoker function must be a "
8796 "template specialization");
8798 FunctionTemplateDecl *CallOpTemplate =
8800 void *InsertPos =
nullptr;
8801 FunctionDecl *CorrespondingCallOpSpecialization =
8803 assert(CorrespondingCallOpSpecialization &&
8804 "We must always have a function call operator specialization "
8805 "that corresponds to our static invoker specialization");
8807 FD = CorrespondingCallOpSpecialization;
8816 return CallScope.destroy();
8826 Call = Info.CurrentCall->createCall(FD);
8832 SmallVector<QualType, 4> CovariantAdjustmentPath;
8834 auto *NamedMember = dyn_cast<CXXMethodDecl>(FD);
8835 if (NamedMember && NamedMember->isVirtual() && !HasQualifier) {
8838 CovariantAdjustmentPath);
8841 }
else if (NamedMember && NamedMember->isImplicitObjectMemberFunction()) {
8851 if (
auto *DD = dyn_cast<CXXDestructorDecl>(FD)) {
8852 assert(This &&
"no 'this' pointer for destructor call");
8854 Info.Ctx.getCanonicalTagType(DD->getParent())) &&
8855 CallScope.destroy();
8872 if (!CovariantAdjustmentPath.empty() &&
8874 CovariantAdjustmentPath))
8877 return CallScope.destroy();
8880 bool VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E) {
8883 bool VisitInitListExpr(
const InitListExpr *E) {
8885 return DerivedZeroInitialization(E);
8887 return StmtVisitorTy::Visit(E->
getInit(0));
8890 bool VisitImplicitValueInitExpr(
const ImplicitValueInitExpr *E) {
8891 return DerivedZeroInitialization(E);
8893 bool VisitCXXScalarValueInitExpr(
const CXXScalarValueInitExpr *E) {
8894 return DerivedZeroInitialization(E);
8896 bool VisitCXXNullPtrLiteralExpr(
const CXXNullPtrLiteralExpr *E) {
8897 return DerivedZeroInitialization(E);
8901 bool VisitMemberExpr(
const MemberExpr *E) {
8902 assert(!Info.Ctx.getLangOpts().CPlusPlus11 &&
8903 "missing temporary materialization conversion");
8904 assert(!E->
isArrow() &&
"missing call to bound member function?");
8912 const FieldDecl *FD = dyn_cast<FieldDecl>(E->
getMemberDecl());
8913 if (!FD)
return Error(E);
8917 "record / field mismatch");
8922 CompleteObject Obj(APValue::LValueBase(), &Val, BaseTy);
8923 SubobjectDesignator Designator(BaseTy);
8924 Designator.addDeclUnchecked(FD);
8928 DerivedSuccess(
Result, E);
8931 bool VisitExtVectorElementExpr(
const ExtVectorElementExpr *E) {
8937 SmallVector<uint32_t, 4> Indices;
8939 if (Indices.size() == 1) {
8941 return DerivedSuccess(Val.
getVectorElt(Indices[0]), E);
8944 SmallVector<APValue, 4> Elts;
8945 for (
unsigned I = 0; I < Indices.size(); ++I) {
8948 APValue VecResult(Elts.data(), Indices.size());
8949 return DerivedSuccess(VecResult, E);
8956 bool VisitCastExpr(
const CastExpr *E) {
8961 case CK_AtomicToNonAtomic: {
8968 return DerivedSuccess(AtomicVal, E);
8972 case CK_UserDefinedConversion:
8973 return StmtVisitorTy::Visit(E->
getSubExpr());
8975 case CK_HLSLArrayRValue: {
8981 return DerivedSuccess(Val, E);
8992 return DerivedSuccess(RVal, E);
8994 case CK_LValueToRValue: {
9003 return DerivedSuccess(RVal, E);
9005 case CK_LValueToRValueBitCast: {
9006 APValue DestValue, SourceValue;
9009 if (!handleLValueToRValueBitCast(Info, DestValue, SourceValue, E))
9011 return DerivedSuccess(DestValue, E);
9014 case CK_AddressSpaceConversion: {
9018 return DerivedSuccess(
Value, E);
9025 bool VisitUnaryPostInc(
const UnaryOperator *UO) {
9026 return VisitUnaryPostIncDec(UO);
9028 bool VisitUnaryPostDec(
const UnaryOperator *UO) {
9029 return VisitUnaryPostIncDec(UO);
9031 bool VisitUnaryPostIncDec(
const UnaryOperator *UO) {
9032 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9042 return DerivedSuccess(RVal, UO);
9045 bool VisitStmtExpr(
const StmtExpr *E) {
9048 llvm::SaveAndRestore NotCheckingForUB(Info.CheckingForUndefinedBehavior,
9055 BlockScopeRAII Scope(Info);
9060 const Expr *FinalExpr = dyn_cast<Expr>(*BI);
9062 Info.FFDiag((*BI)->getBeginLoc(),
9063 diag::note_constexpr_stmt_expr_unsupported);
9066 return this->Visit(FinalExpr) && Scope.destroy();
9072 if (ESR != ESR_Succeeded) {
9076 if (ESR != ESR_Failed)
9077 Info.FFDiag((*BI)->getBeginLoc(),
9078 diag::note_constexpr_stmt_expr_unsupported);
9083 llvm_unreachable(
"Return from function from the loop above.");
9086 bool VisitPackIndexingExpr(
const PackIndexingExpr *E) {
9091 void VisitIgnoredValue(
const Expr *E) {
9096 void VisitIgnoredBaseExpression(
const Expr *E) {
9099 if (Info.getLangOpts().MSVCCompat && !E->
HasSideEffects(Info.Ctx))
9101 VisitIgnoredValue(E);
9111template<
class Derived>
9112class LValueExprEvaluatorBase
9113 :
public ExprEvaluatorBase<Derived> {
9117 typedef LValueExprEvaluatorBase LValueExprEvaluatorBaseTy;
9118 typedef ExprEvaluatorBase<Derived> ExprEvaluatorBaseTy;
9120 bool Success(APValue::LValueBase B) {
9125 bool evaluatePointer(
const Expr *E, LValue &
Result) {
9130 LValueExprEvaluatorBase(EvalInfo &Info, LValue &
Result,
bool InvalidBaseOK)
9132 InvalidBaseOK(InvalidBaseOK) {}
9135 Result.setFrom(this->Info.Ctx,
V);
9139 bool VisitMemberExpr(
const MemberExpr *E) {
9151 EvalOK = this->Visit(E->
getBase());
9162 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(E->
getMemberDecl())) {
9165 "record / field mismatch");
9169 }
else if (
const IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(MD)) {
9173 return this->
Error(E);
9185 bool VisitBinaryOperator(
const BinaryOperator *E) {
9188 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
9196 bool VisitCastExpr(
const CastExpr *E) {
9199 return ExprEvaluatorBaseTy::VisitCastExpr(E);
9201 case CK_DerivedToBase:
9202 case CK_UncheckedDerivedToBase:
9249class LValueExprEvaluator
9250 :
public LValueExprEvaluatorBase<LValueExprEvaluator> {
9252 LValueExprEvaluator(EvalInfo &Info, LValue &
Result,
bool InvalidBaseOK) :
9253 LValueExprEvaluatorBaseTy(Info,
Result, InvalidBaseOK) {}
9255 bool VisitVarDecl(
const Expr *E,
const VarDecl *VD);
9256 bool VisitUnaryPreIncDec(
const UnaryOperator *UO);
9258 bool VisitCallExpr(
const CallExpr *E);
9259 bool VisitDeclRefExpr(
const DeclRefExpr *E);
9260 bool VisitPredefinedExpr(
const PredefinedExpr *E) {
return Success(E); }
9261 bool VisitMaterializeTemporaryExpr(
const MaterializeTemporaryExpr *E);
9262 bool VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E);
9263 bool VisitMemberExpr(
const MemberExpr *E);
9264 bool VisitStringLiteral(
const StringLiteral *E) {
9266 APValue::LValueBase(E, 0, Info.Ctx.getNextStringLiteralVersion()));
9268 bool VisitObjCEncodeExpr(
const ObjCEncodeExpr *E) {
return Success(E); }
9269 bool VisitCXXTypeidExpr(
const CXXTypeidExpr *E);
9270 bool VisitCXXUuidofExpr(
const CXXUuidofExpr *E);
9271 bool VisitArraySubscriptExpr(
const ArraySubscriptExpr *E);
9272 bool VisitExtVectorElementExpr(
const ExtVectorElementExpr *E);
9273 bool VisitUnaryDeref(
const UnaryOperator *E);
9274 bool VisitUnaryReal(
const UnaryOperator *E);
9275 bool VisitUnaryImag(
const UnaryOperator *E);
9276 bool VisitUnaryPreInc(
const UnaryOperator *UO) {
9277 return VisitUnaryPreIncDec(UO);
9279 bool VisitUnaryPreDec(
const UnaryOperator *UO) {
9280 return VisitUnaryPreIncDec(UO);
9282 bool VisitBinAssign(
const BinaryOperator *BO);
9283 bool VisitCompoundAssignOperator(
const CompoundAssignOperator *CAO);
9285 bool VisitCastExpr(
const CastExpr *E) {
9288 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
9290 case CK_LValueBitCast:
9291 this->CCEDiag(E, diag::note_constexpr_invalid_cast)
9292 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
9293 << Info.Ctx.getLangOpts().CPlusPlus;
9296 Result.Designator.setInvalid();
9299 case CK_BaseToDerived:
9316 bool LValueToRValueConversion) {
9320 assert(Info.CurrentCall->This ==
nullptr &&
9321 "This should not be set for a static call operator");
9329 if (
Self->getType()->isReferenceType()) {
9330 APValue *RefValue = Info.getParamSlot(Info.CurrentCall->Arguments,
Self);
9332 Result.setFrom(Info.Ctx, *RefValue);
9334 const ParmVarDecl *VD = Info.CurrentCall->Arguments.getOrigParam(
Self);
9335 CallStackFrame *Frame =
9336 Info.getCallFrameAndDepth(Info.CurrentCall->Arguments.CallIndex)
9338 unsigned Version = Info.CurrentCall->Arguments.Version;
9339 Result.set({VD, Frame->Index, Version});
9342 Result = *Info.CurrentCall->This;
9352 if (LValueToRValueConversion) {
9356 Result.setFrom(Info.Ctx, RVal);
9367 bool InvalidBaseOK) {
9371 return LValueExprEvaluator(Info, Result, InvalidBaseOK).Visit(E);
9374bool LValueExprEvaluator::VisitDeclRefExpr(
const DeclRefExpr *E) {
9375 const ValueDecl *D = E->
getDecl();
9387 if (Info.checkingPotentialConstantExpression())
9390 if (
auto *FD = Info.CurrentCall->LambdaCaptureFields.lookup(D)) {
9397 if (
isa<FunctionDecl, MSGuidDecl, TemplateParamObjectDecl,
9398 UnnamedGlobalConstantDecl>(D))
9400 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
9401 return VisitVarDecl(E, VD);
9402 if (
const BindingDecl *BD = dyn_cast<BindingDecl>(D))
9403 return Visit(BD->getBinding());
9407bool LValueExprEvaluator::VisitVarDecl(
const Expr *E,
const VarDecl *VD) {
9408 CallStackFrame *Frame =
nullptr;
9409 unsigned Version = 0;
9417 CallStackFrame *CurrFrame = Info.CurrentCall;
9422 if (
auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
9423 if (CurrFrame->Arguments) {
9424 VD = CurrFrame->Arguments.getOrigParam(PVD);
9426 Info.getCallFrameAndDepth(CurrFrame->Arguments.CallIndex).first;
9427 Version = CurrFrame->Arguments.Version;
9431 Version = CurrFrame->getCurrentTemporaryVersion(VD);
9438 Result.set({VD, Frame->Index, Version});
9444 if (!Info.getLangOpts().CPlusPlus11) {
9445 Info.CCEDiag(E, diag::note_constexpr_ltor_non_integral, 1)
9447 Info.Note(VD->
getLocation(), diag::note_declared_at);
9456 Result.AllowConstexprUnknown =
true;
9463bool LValueExprEvaluator::VisitCallExpr(
const CallExpr *E) {
9464 if (!IsConstantEvaluatedBuiltinCall(E))
9465 return ExprEvaluatorBaseTy::VisitCallExpr(E);
9470 case Builtin::BIas_const:
9471 case Builtin::BIforward:
9472 case Builtin::BIforward_like:
9473 case Builtin::BImove:
9474 case Builtin::BImove_if_noexcept:
9476 return Visit(E->
getArg(0));
9480 return ExprEvaluatorBaseTy::VisitCallExpr(E);
9483bool LValueExprEvaluator::VisitMaterializeTemporaryExpr(
9484 const MaterializeTemporaryExpr *E) {
9492 for (
const Expr *E : CommaLHSs)
9501 if (Info.EvalMode == EvaluationMode::ConstantFold)
9508 Value = &Info.CurrentCall->createTemporary(
9524 for (
unsigned I = Adjustments.size(); I != 0; ) {
9526 switch (Adjustments[I].Kind) {
9531 Type = Adjustments[I].DerivedToBase.BasePath->getType();
9537 Type = Adjustments[I].Field->getType();
9542 Adjustments[I].Ptr.RHS))
9544 Type = Adjustments[I].Ptr.MPT->getPointeeType();
9553LValueExprEvaluator::VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E) {
9554 assert((!Info.getLangOpts().CPlusPlus || E->
isFileScope()) &&
9555 "lvalue compound literal in c++?");
9567 assert(!Info.getLangOpts().CPlusPlus);
9569 ScopeKind::Block,
Result);
9581bool LValueExprEvaluator::VisitCXXTypeidExpr(
const CXXTypeidExpr *E) {
9582 TypeInfoLValue TypeInfo;
9590 if (!Info.Ctx.getLangOpts().CPlusPlus20) {
9591 Info.CCEDiag(E, diag::note_constexpr_typeid_polymorphic)
9599 std::optional<DynamicType> DynType =
9604 TypeInfo = TypeInfoLValue(
9605 Info.Ctx.getCanonicalTagType(DynType->Type).getTypePtr());
9611bool LValueExprEvaluator::VisitCXXUuidofExpr(
const CXXUuidofExpr *E) {
9615bool LValueExprEvaluator::VisitMemberExpr(
const MemberExpr *E) {
9617 if (
const VarDecl *VD = dyn_cast<VarDecl>(E->
getMemberDecl())) {
9618 VisitIgnoredBaseExpression(E->
getBase());
9619 return VisitVarDecl(E, VD);
9623 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(E->
getMemberDecl())) {
9624 if (MD->isStatic()) {
9625 VisitIgnoredBaseExpression(E->
getBase());
9631 return LValueExprEvaluatorBaseTy::VisitMemberExpr(E);
9634bool LValueExprEvaluator::VisitExtVectorElementExpr(
9635 const ExtVectorElementExpr *E) {
9640 if (!Info.noteFailure())
9648 if (Indices.size() > 1)
9652 Result.setFrom(Info.Ctx, Val);
9656 const auto *VT = BaseType->
castAs<VectorType>();
9658 VT->getNumElements(), Indices[0]);
9664bool LValueExprEvaluator::VisitArraySubscriptExpr(
const ArraySubscriptExpr *E) {
9674 if (!Info.noteFailure())
9680 if (!Info.noteFailure())
9686 Result.setFrom(Info.Ctx, Val);
9688 VT->getNumElements(), Index.getZExtValue());
9696 for (
const Expr *SubExpr : {E->
getLHS(), E->
getRHS()}) {
9697 if (SubExpr == E->
getBase() ? !evaluatePointer(SubExpr,
Result)
9699 if (!Info.noteFailure())
9709bool LValueExprEvaluator::VisitUnaryDeref(
const UnaryOperator *E) {
9720 Info.noteUndefinedBehavior();
9723bool LValueExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
9732bool LValueExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
9734 "lvalue __imag__ on scalar?");
9741bool LValueExprEvaluator::VisitUnaryPreIncDec(
const UnaryOperator *UO) {
9742 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9753bool LValueExprEvaluator::VisitCompoundAssignOperator(
9754 const CompoundAssignOperator *CAO) {
9755 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9763 if (!Info.noteFailure())
9778bool LValueExprEvaluator::VisitBinAssign(
const BinaryOperator *E) {
9779 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9787 if (!Info.noteFailure())
9795 if (Info.getLangOpts().CPlusPlus20 &&
9811 llvm::APInt &Result) {
9812 assert(isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
9813 "Can't get the size of a non alloc_size function");
9814 const auto *
Base = LVal.getLValueBase().get<
const Expr *>();
9816 std::optional<llvm::APInt> Size =
9817 CE->evaluateBytesReturnedByAllocSizeCall(Ctx);
9821 Result = std::move(*Size);
9840 dyn_cast_or_null<VarDecl>(
Base.dyn_cast<
const ValueDecl *>());
9845 if (!
Init ||
Init->getType().isNull())
9848 const Expr *E =
Init->IgnoreParens();
9849 if (!tryUnwrapAllocSizeCall(E))
9854 Result.setInvalid(E);
9857 Result.addUnsizedArray(Info, E, Pointee);
9862class PointerExprEvaluator
9863 :
public ExprEvaluatorBase<PointerExprEvaluator> {
9872 bool evaluateLValue(
const Expr *E, LValue &
Result) {
9876 bool evaluatePointer(
const Expr *E, LValue &
Result) {
9880 bool visitNonBuiltinCallExpr(
const CallExpr *E);
9883 PointerExprEvaluator(EvalInfo &info, LValue &
Result,
bool InvalidBaseOK)
9885 InvalidBaseOK(InvalidBaseOK) {}
9891 bool ZeroInitialization(
const Expr *E) {
9896 bool VisitBinaryOperator(
const BinaryOperator *E);
9897 bool VisitCastExpr(
const CastExpr* E);
9898 bool VisitUnaryAddrOf(
const UnaryOperator *E);
9899 bool VisitObjCStringLiteral(
const ObjCStringLiteral *E)
9901 bool VisitObjCBoxedExpr(
const ObjCBoxedExpr *E) {
9904 if (Info.noteFailure())
9908 bool VisitObjCArrayLiteral(
const ObjCArrayLiteral *E) {
9911 bool VisitObjCDictionaryLiteral(
const ObjCDictionaryLiteral *E) {
9914 bool VisitAddrLabelExpr(
const AddrLabelExpr *E)
9916 bool VisitCallExpr(
const CallExpr *E);
9917 bool VisitBuiltinCallExpr(
const CallExpr *E,
unsigned BuiltinOp);
9918 bool VisitBlockExpr(
const BlockExpr *E) {
9923 bool VisitCXXThisExpr(
const CXXThisExpr *E) {
9924 auto DiagnoseInvalidUseOfThis = [&] {
9925 if (Info.getLangOpts().CPlusPlus11)
9926 Info.FFDiag(E, diag::note_constexpr_this) << E->
isImplicit();
9932 if (Info.checkingPotentialConstantExpression())
9935 bool IsExplicitLambda =
9937 if (!IsExplicitLambda) {
9938 if (!Info.CurrentCall->This) {
9939 DiagnoseInvalidUseOfThis();
9943 Result = *Info.CurrentCall->This;
9951 if (!Info.CurrentCall->LambdaThisCaptureField) {
9952 if (IsExplicitLambda && !Info.CurrentCall->This) {
9953 DiagnoseInvalidUseOfThis();
9962 Info, E,
Result, MD, Info.CurrentCall->LambdaThisCaptureField,
9968 bool VisitCXXNewExpr(
const CXXNewExpr *E);
9970 bool VisitSourceLocExpr(
const SourceLocExpr *E) {
9971 assert(!E->
isIntType() &&
"SourceLocExpr isn't a pointer type?");
9973 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.
getDefaultExpr());
9974 Result.setFrom(Info.Ctx, LValResult);
9978 bool VisitEmbedExpr(
const EmbedExpr *E) {
9979 llvm::report_fatal_error(
"Not yet implemented for ExprConstant.cpp");
9983 bool VisitSYCLUniqueStableNameExpr(
const SYCLUniqueStableNameExpr *E) {
9986 QualType CharTy = Info.Ctx.CharTy.withConst();
9987 APInt Size(Info.Ctx.getTypeSize(Info.Ctx.getSizeType()),
9988 ResultStr.size() + 1);
9989 QualType ArrayTy = Info.Ctx.getConstantArrayType(
9990 CharTy, Size,
nullptr, ArraySizeModifier::Normal, 0);
9993 StringLiteral::Create(Info.Ctx, ResultStr, StringLiteralKind::Ordinary,
9996 evaluateLValue(SL,
Result);
10006 bool InvalidBaseOK) {
10009 return PointerExprEvaluator(Info, Result, InvalidBaseOK).Visit(E);
10012bool PointerExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
10015 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
10017 const Expr *PExp = E->
getLHS();
10018 const Expr *IExp = E->
getRHS();
10020 std::swap(PExp, IExp);
10022 bool EvalPtrOK = evaluatePointer(PExp,
Result);
10023 if (!EvalPtrOK && !Info.noteFailure())
10026 llvm::APSInt Offset;
10037bool PointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
10046 if (!FnII || !FnII->
isStr(
"current"))
10049 const auto *RD = dyn_cast<RecordDecl>(FD->
getParent());
10057bool PointerExprEvaluator::VisitCastExpr(
const CastExpr *E) {
10064 case CK_CPointerToObjCPointerCast:
10065 case CK_BlockPointerToObjCPointerCast:
10066 case CK_AnyPointerToBlockPointerCast:
10067 case CK_AddressSpaceConversion:
10068 if (!Visit(SubExpr))
10074 CCEDiag(E, diag::note_constexpr_invalid_cast)
10075 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
10076 << Info.Ctx.getLangOpts().CPlusPlus;
10077 Result.Designator.setInvalid();
10085 bool HasValidResult = !
Result.InvalidBase && !
Result.Designator.Invalid &&
10087 bool VoidPtrCastMaybeOK =
10090 Info.Ctx.hasSimilarType(
Result.Designator.getType(Info.Ctx),
10099 if (VoidPtrCastMaybeOK &&
10100 (Info.getStdAllocatorCaller(
"allocate") ||
10102 Info.getLangOpts().CPlusPlus26)) {
10106 Info.getLangOpts().CPlusPlus) {
10107 if (HasValidResult)
10108 CCEDiag(E, diag::note_constexpr_invalid_void_star_cast)
10109 << SubExpr->
getType() << Info.getLangOpts().CPlusPlus26
10110 <<
Result.Designator.getType(Info.Ctx).getCanonicalType()
10113 CCEDiag(E, diag::note_constexpr_invalid_cast)
10114 << diag::ConstexprInvalidCastKind::CastFrom
10117 CCEDiag(E, diag::note_constexpr_invalid_cast)
10118 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
10119 << Info.Ctx.getLangOpts().CPlusPlus;
10120 Result.Designator.setInvalid();
10124 ZeroInitialization(E);
10127 case CK_DerivedToBase:
10128 case CK_UncheckedDerivedToBase:
10140 case CK_BaseToDerived:
10152 case CK_NullToPointer:
10154 return ZeroInitialization(E);
10156 case CK_IntegralToPointer: {
10157 CCEDiag(E, diag::note_constexpr_invalid_cast)
10158 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
10159 << Info.Ctx.getLangOpts().CPlusPlus;
10165 if (
Value.isInt()) {
10166 unsigned Size = Info.Ctx.getTypeSize(E->
getType());
10167 uint64_t N =
Value.getInt().extOrTrunc(Size).getZExtValue();
10168 if (N == Info.Ctx.getTargetNullPointerValue(E->
getType())) {
10171 Result.Base = (Expr *)
nullptr;
10172 Result.InvalidBase =
false;
10174 Result.Designator.setInvalid();
10175 Result.IsNullPtr =
false;
10183 if (!
Value.isLValue())
10192 case CK_ArrayToPointerDecay: {
10194 if (!evaluateLValue(SubExpr,
Result))
10198 SubExpr, SubExpr->
getType(), ScopeKind::FullExpression,
Result);
10203 auto *AT = Info.Ctx.getAsArrayType(SubExpr->
getType());
10204 if (
auto *CAT = dyn_cast<ConstantArrayType>(AT))
10205 Result.addArray(Info, E, CAT);
10207 Result.addUnsizedArray(Info, E, AT->getElementType());
10211 case CK_FunctionToPointerDecay:
10212 return evaluateLValue(SubExpr,
Result);
10214 case CK_LValueToRValue: {
10223 return InvalidBaseOK &&
10229 return ExprEvaluatorBaseTy::VisitCastExpr(E);
10237 T = T.getNonReferenceType();
10239 if (T.getQualifiers().hasUnaligned())
10242 const bool AlignOfReturnsPreferred =
10243 Ctx.
getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver7;
10248 if (ExprKind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
10251 else if (ExprKind == UETT_AlignOf)
10254 llvm_unreachable(
"GetAlignOfType on a non-alignment ExprKind");
10267 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
10271 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(E))
10280 return Info.Ctx.getDeclAlign(VD);
10281 if (
const auto *E =
Value.Base.dyn_cast<
const Expr *>())
10289 EvalInfo &Info,
APSInt &Alignment) {
10292 if (Alignment < 0 || !Alignment.isPowerOf2()) {
10293 Info.FFDiag(E, diag::note_constexpr_invalid_alignment) << Alignment;
10296 unsigned SrcWidth = Info.Ctx.getIntWidth(ForType);
10297 APSInt MaxValue(APInt::getOneBitSet(SrcWidth, SrcWidth - 1));
10298 if (APSInt::compareValues(Alignment, MaxValue) > 0) {
10299 Info.FFDiag(E, diag::note_constexpr_alignment_too_big)
10300 << MaxValue << ForType << Alignment;
10306 APSInt(Alignment.zextOrTrunc(SrcWidth),
true);
10307 assert(APSInt::compareValues(Alignment, ExtAlignment) == 0 &&
10308 "Alignment should not be changed by ext/trunc");
10309 Alignment = ExtAlignment;
10310 assert(Alignment.getBitWidth() == SrcWidth);
10315bool PointerExprEvaluator::visitNonBuiltinCallExpr(
const CallExpr *E) {
10316 if (ExprEvaluatorBaseTy::VisitCallExpr(E))
10324 Result.addUnsizedArray(Info, E, PointeeTy);
10328bool PointerExprEvaluator::VisitCallExpr(
const CallExpr *E) {
10329 if (!IsConstantEvaluatedBuiltinCall(E))
10330 return visitNonBuiltinCallExpr(E);
10337 return T->isCharType() || T->isChar8Type();
10340bool PointerExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *E,
10341 unsigned BuiltinOp) {
10345 switch (BuiltinOp) {
10346 case Builtin::BIaddressof:
10347 case Builtin::BI__addressof:
10348 case Builtin::BI__builtin_addressof:
10350 case Builtin::BI__builtin_assume_aligned: {
10357 LValue OffsetResult(
Result);
10369 int64_t AdditionalOffset = -Offset.getZExtValue();
10374 if (OffsetResult.Base) {
10377 if (BaseAlignment < Align) {
10378 Result.Designator.setInvalid();
10379 CCEDiag(E->
getArg(0), diag::note_constexpr_baa_insufficient_alignment)
10386 if (OffsetResult.Offset.alignTo(Align) != OffsetResult.Offset) {
10387 Result.Designator.setInvalid();
10391 diag::note_constexpr_baa_insufficient_alignment)
10394 diag::note_constexpr_baa_value_insufficient_alignment))
10395 << OffsetResult.Offset.getQuantity() << Align.
getQuantity();
10401 case Builtin::BI__builtin_align_up:
10402 case Builtin::BI__builtin_align_down: {
10422 assert(Alignment.getBitWidth() <= 64 &&
10423 "Cannot handle > 64-bit address-space");
10424 uint64_t Alignment64 = Alignment.getZExtValue();
10426 BuiltinOp == Builtin::BI__builtin_align_down
10427 ? llvm::alignDown(
Result.Offset.getQuantity(), Alignment64)
10428 : llvm::alignTo(
Result.Offset.getQuantity(), Alignment64));
10434 Info.FFDiag(E->
getArg(0), diag::note_constexpr_alignment_adjust)
10438 case Builtin::BI__builtin_operator_new:
10440 case Builtin::BI__builtin_launder:
10442 case Builtin::BIstrchr:
10443 case Builtin::BIwcschr:
10444 case Builtin::BImemchr:
10445 case Builtin::BIwmemchr:
10446 if (Info.getLangOpts().CPlusPlus11)
10447 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
10449 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
10451 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
10453 case Builtin::BI__builtin_strchr:
10454 case Builtin::BI__builtin_wcschr:
10455 case Builtin::BI__builtin_memchr:
10456 case Builtin::BI__builtin_char_memchr:
10457 case Builtin::BI__builtin_wmemchr: {
10458 if (!Visit(E->
getArg(0)))
10464 if (BuiltinOp != Builtin::BIstrchr &&
10465 BuiltinOp != Builtin::BIwcschr &&
10466 BuiltinOp != Builtin::BI__builtin_strchr &&
10467 BuiltinOp != Builtin::BI__builtin_wcschr) {
10471 MaxLength = N.getZExtValue();
10474 if (MaxLength == 0u)
10475 return ZeroInitialization(E);
10476 if (!
Result.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
10477 Result.Designator.Invalid)
10479 QualType CharTy =
Result.Designator.getType(Info.Ctx);
10480 bool IsRawByte = BuiltinOp == Builtin::BImemchr ||
10481 BuiltinOp == Builtin::BI__builtin_memchr;
10482 assert(IsRawByte ||
10483 Info.Ctx.hasSameUnqualifiedType(
10487 Info.FFDiag(E, diag::note_constexpr_ltor_incomplete_type) << CharTy;
10493 Info.FFDiag(E, diag::note_constexpr_memchr_unsupported)
10494 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp) << CharTy;
10500 bool StopAtNull =
false;
10501 switch (BuiltinOp) {
10502 case Builtin::BIstrchr:
10503 case Builtin::BI__builtin_strchr:
10510 return ZeroInitialization(E);
10513 case Builtin::BImemchr:
10514 case Builtin::BI__builtin_memchr:
10515 case Builtin::BI__builtin_char_memchr:
10519 DesiredVal = Desired.trunc(Info.Ctx.getCharWidth()).getZExtValue();
10522 case Builtin::BIwcschr:
10523 case Builtin::BI__builtin_wcschr:
10526 case Builtin::BIwmemchr:
10527 case Builtin::BI__builtin_wmemchr:
10529 DesiredVal = Desired.getZExtValue();
10533 for (; MaxLength; --MaxLength) {
10538 if (Char.
getInt().getZExtValue() == DesiredVal)
10540 if (StopAtNull && !Char.
getInt())
10546 return ZeroInitialization(E);
10549 case Builtin::BImemcpy:
10550 case Builtin::BImemmove:
10551 case Builtin::BIwmemcpy:
10552 case Builtin::BIwmemmove:
10553 if (Info.getLangOpts().CPlusPlus11)
10554 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
10556 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
10558 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
10560 case Builtin::BI__builtin_memcpy:
10561 case Builtin::BI__builtin_memmove:
10562 case Builtin::BI__builtin_wmemcpy:
10563 case Builtin::BI__builtin_wmemmove: {
10564 bool WChar = BuiltinOp == Builtin::BIwmemcpy ||
10565 BuiltinOp == Builtin::BIwmemmove ||
10566 BuiltinOp == Builtin::BI__builtin_wmemcpy ||
10567 BuiltinOp == Builtin::BI__builtin_wmemmove;
10568 bool Move = BuiltinOp == Builtin::BImemmove ||
10569 BuiltinOp == Builtin::BIwmemmove ||
10570 BuiltinOp == Builtin::BI__builtin_memmove ||
10571 BuiltinOp == Builtin::BI__builtin_wmemmove;
10574 if (!Visit(E->
getArg(0)))
10585 assert(!N.isSigned() &&
"memcpy and friends take an unsigned size");
10595 if (!Src.Base || !Dest.Base) {
10597 (!Src.Base ? Src : Dest).moveInto(Val);
10598 Info.FFDiag(E, diag::note_constexpr_memcpy_null)
10599 <<
Move << WChar << !!Src.Base
10603 if (Src.Designator.Invalid || Dest.Designator.Invalid)
10609 QualType T = Dest.Designator.getType(Info.Ctx);
10610 QualType SrcT = Src.Designator.getType(Info.Ctx);
10611 if (!Info.Ctx.hasSameUnqualifiedType(T, SrcT)) {
10613 Info.FFDiag(E, diag::note_constexpr_memcpy_type_pun) <<
Move << SrcT << T;
10617 Info.FFDiag(E, diag::note_constexpr_memcpy_incomplete_type) <<
Move << T;
10621 Info.FFDiag(E, diag::note_constexpr_memcpy_nontrivial) <<
Move << T;
10626 uint64_t TSize = Info.Ctx.getTypeSizeInChars(T).getQuantity();
10631 llvm::APInt OrigN = N;
10632 llvm::APInt::udivrem(OrigN, TSize, N, Remainder);
10634 Info.FFDiag(E, diag::note_constexpr_memcpy_unsupported)
10635 <<
Move << WChar << 0 << T <<
toString(OrigN, 10,
false)
10636 << (unsigned)TSize;
10644 uint64_t RemainingSrcSize = Src.Designator.validIndexAdjustments().second;
10645 uint64_t RemainingDestSize = Dest.Designator.validIndexAdjustments().second;
10646 if (N.ugt(RemainingSrcSize) || N.ugt(RemainingDestSize)) {
10647 Info.FFDiag(E, diag::note_constexpr_memcpy_unsupported)
10648 <<
Move << WChar << (N.ugt(RemainingSrcSize) ? 1 : 2) << T
10652 uint64_t NElems = N.getZExtValue();
10658 uint64_t SrcOffset = Src.getLValueOffset().getQuantity();
10659 uint64_t DestOffset = Dest.getLValueOffset().getQuantity();
10660 if (DestOffset >= SrcOffset && DestOffset - SrcOffset < NBytes) {
10663 Info.FFDiag(E, diag::note_constexpr_memcpy_overlap) << WChar;
10671 }
else if (!Move && SrcOffset >= DestOffset &&
10672 SrcOffset - DestOffset < NBytes) {
10674 Info.FFDiag(E, diag::note_constexpr_memcpy_overlap) << WChar;
10703 QualType AllocType);
10706 const CXXConstructExpr *CCE,
10707 QualType AllocType);
10709bool PointerExprEvaluator::VisitCXXNewExpr(
const CXXNewExpr *E) {
10710 if (!Info.getLangOpts().CPlusPlus20)
10711 Info.CCEDiag(E, diag::note_constexpr_new);
10714 if (Info.SpeculativeEvaluationDepth)
10719 QualType TargetType = AllocType;
10721 bool IsNothrow =
false;
10722 bool IsPlacement =
false;
10740 }
else if (OperatorNew->isReservedGlobalPlacementOperator()) {
10741 if (Info.CurrentCall->isStdFunction() || Info.getLangOpts().CPlusPlus26 ||
10742 (Info.CurrentCall->CanEvalMSConstexpr &&
10743 OperatorNew->hasAttr<MSConstexprAttr>())) {
10746 if (
Result.Designator.Invalid)
10749 IsPlacement =
true;
10751 Info.FFDiag(E, diag::note_constexpr_new_placement)
10756 Info.FFDiag(E, diag::note_constexpr_new_placement)
10759 }
else if (!OperatorNew
10760 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
10761 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
10767 const InitListExpr *ResizedArrayILE =
nullptr;
10768 const CXXConstructExpr *ResizedArrayCCE =
nullptr;
10769 bool ValueInit =
false;
10771 if (std::optional<const Expr *> ArraySize = E->
getArraySize()) {
10772 const Expr *Stripped = *ArraySize;
10773 for (;
auto *ICE = dyn_cast<ImplicitCastExpr>(Stripped);
10774 Stripped = ICE->getSubExpr())
10775 if (ICE->getCastKind() != CK_NoOp &&
10776 ICE->getCastKind() != CK_IntegralCast)
10789 return ZeroInitialization(E);
10791 Info.FFDiag(*ArraySize, diag::note_constexpr_new_negative)
10792 <<
ArrayBound << (*ArraySize)->getSourceRange();
10798 if (!Info.CheckArraySize(ArraySize.value()->getExprLoc(),
10803 return ZeroInitialization(E);
10815 }
else if (
auto *CCE = dyn_cast<CXXConstructExpr>(
Init)) {
10816 ResizedArrayCCE = CCE;
10818 auto *CAT = Info.Ctx.getAsConstantArrayType(
Init->getType());
10819 assert(CAT &&
"unexpected type for array initializer");
10823 llvm::APInt InitBound = CAT->
getSize().zext(Bits);
10824 llvm::APInt AllocBound =
ArrayBound.zext(Bits);
10825 if (InitBound.ugt(AllocBound)) {
10827 return ZeroInitialization(E);
10829 Info.FFDiag(*ArraySize, diag::note_constexpr_new_too_small)
10830 <<
toString(AllocBound, 10,
false)
10832 << (*ArraySize)->getSourceRange();
10838 if (InitBound != AllocBound)
10842 AllocType = Info.Ctx.getConstantArrayType(AllocType,
ArrayBound,
nullptr,
10843 ArraySizeModifier::Normal, 0);
10846 "array allocation with non-array new");
10852 struct FindObjectHandler {
10855 QualType AllocType;
10859 typedef bool result_type;
10860 bool failed() {
return false; }
10861 bool checkConst(QualType QT) {
10863 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
10868 bool found(
APValue &Subobj, QualType SubobjType) {
10869 if (!checkConst(SubobjType))
10873 unsigned SubobjectSize = 1;
10874 unsigned AllocSize = 1;
10875 if (
auto *CAT = dyn_cast<ConstantArrayType>(AllocType))
10877 if (
auto *CAT = dyn_cast<ConstantArrayType>(SubobjType))
10879 if (SubobjectSize < AllocSize ||
10880 !Info.Ctx.hasSimilarType(Info.Ctx.getBaseElementType(SubobjType),
10881 Info.Ctx.getBaseElementType(AllocType))) {
10882 Info.FFDiag(E, diag::note_constexpr_placement_new_wrong_type)
10883 << SubobjType << AllocType;
10890 Info.FFDiag(E, diag::note_constexpr_construct_complex_elem);
10893 bool found(APFloat &
Value, QualType SubobjType) {
10894 Info.FFDiag(E, diag::note_constexpr_construct_complex_elem);
10897 } Handler = {Info, E, AllocType, AK,
nullptr};
10903 Val = Handler.Value;
10912 Val = Info.createHeapAlloc(E, AllocType,
Result);
10918 ImplicitValueInitExpr VIE(AllocType);
10921 }
else if (ResizedArrayILE) {
10925 }
else if (ResizedArrayCCE) {
10948class MemberPointerExprEvaluator
10949 :
public ExprEvaluatorBase<MemberPointerExprEvaluator> {
10952 bool Success(
const ValueDecl *D) {
10958 MemberPointerExprEvaluator(EvalInfo &Info, MemberPtr &
Result)
10965 bool ZeroInitialization(
const Expr *E) {
10966 return Success((
const ValueDecl*)
nullptr);
10969 bool VisitCastExpr(
const CastExpr *E);
10970 bool VisitUnaryAddrOf(
const UnaryOperator *E);
10978 return MemberPointerExprEvaluator(Info, Result).Visit(E);
10981bool MemberPointerExprEvaluator::VisitCastExpr(
const CastExpr *E) {
10984 return ExprEvaluatorBaseTy::VisitCastExpr(E);
10986 case CK_NullToMemberPointer:
10988 return ZeroInitialization(E);
10990 case CK_BaseToDerivedMemberPointer: {
10998 typedef std::reverse_iterator<CastExpr::path_const_iterator> ReverseIter;
11000 PathI != PathE; ++PathI) {
11001 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
11002 const CXXRecordDecl *Derived = (*PathI)->getType()->getAsCXXRecordDecl();
11003 if (!
Result.castToDerived(Derived))
11007 ->
castAs<MemberPointerType>()
11008 ->getMostRecentCXXRecordDecl()))
11013 case CK_DerivedToBaseMemberPointer:
11017 PathE = E->
path_end(); PathI != PathE; ++PathI) {
11018 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
11019 const CXXRecordDecl *
Base = (*PathI)->getType()->getAsCXXRecordDecl();
11020 if (!
Result.castToBase(Base))
11027bool MemberPointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
11038 class RecordExprEvaluator
11039 :
public ExprEvaluatorBase<RecordExprEvaluator> {
11040 const LValue &
This;
11044 RecordExprEvaluator(EvalInfo &info,
const LValue &This,
APValue &
Result)
11051 bool ZeroInitialization(
const Expr *E) {
11052 return ZeroInitialization(E, E->
getType());
11054 bool ZeroInitialization(
const Expr *E, QualType T);
11056 bool VisitCallExpr(
const CallExpr *E) {
11057 return handleCallExpr(E,
Result, &This);
11059 bool VisitCastExpr(
const CastExpr *E);
11060 bool VisitInitListExpr(
const InitListExpr *E);
11061 bool VisitCXXConstructExpr(
const CXXConstructExpr *E) {
11062 return VisitCXXConstructExpr(E, E->
getType());
11065 bool VisitCXXInheritedCtorInitExpr(
const CXXInheritedCtorInitExpr *E);
11066 bool VisitCXXConstructExpr(
const CXXConstructExpr *E, QualType T);
11067 bool VisitCXXStdInitializerListExpr(
const CXXStdInitializerListExpr *E);
11068 bool VisitBinCmp(
const BinaryOperator *E);
11069 bool VisitCXXParenListInitExpr(
const CXXParenListInitExpr *E);
11070 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
11071 ArrayRef<Expr *> Args);
11085 assert(!RD->
isUnion() &&
"Expected non-union class type");
11094 unsigned Index = 0;
11096 End = CD->
bases_end(); I != End; ++I, ++Index) {
11098 LValue Subobject =
This;
11102 Result.getStructBase(Index)))
11107 for (
const auto *I : RD->
fields()) {
11109 if (I->isUnnamedBitField() || I->getType()->isReferenceType())
11112 LValue Subobject =
This;
11118 Result.getStructField(I->getFieldIndex()), Info, Subobject, &VIE))
11125bool RecordExprEvaluator::ZeroInitialization(
const Expr *E, QualType T) {
11132 while (I != RD->
field_end() && (*I)->isUnnamedBitField())
11139 LValue Subobject =
This;
11143 ImplicitValueInitExpr VIE(I->getType());
11148 Info.FFDiag(E, diag::note_constexpr_virtual_base) << RD;
11155bool RecordExprEvaluator::VisitCastExpr(
const CastExpr *E) {
11158 return ExprEvaluatorBaseTy::VisitCastExpr(E);
11160 case CK_ConstructorConversion:
11163 case CK_DerivedToBase:
11164 case CK_UncheckedDerivedToBase: {
11175 PathE = E->
path_end(); PathI != PathE; ++PathI) {
11176 assert(!(*PathI)->isVirtual() &&
"record rvalue with virtual base");
11177 const CXXRecordDecl *
Base = (*PathI)->getType()->getAsCXXRecordDecl();
11184 case CK_HLSLAggregateSplatCast: {
11204 case CK_HLSLElementwiseCast: {
11223bool RecordExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
11226 return VisitCXXParenListOrInitListExpr(E, E->
inits());
11229bool RecordExprEvaluator::VisitCXXParenListOrInitListExpr(
11233 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD);
11234 auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
11236 EvalInfo::EvaluatingConstructorRAII EvalObj(
11238 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries},
11239 CXXRD && CXXRD->getNumBases());
11242 const FieldDecl *
Field;
11243 if (
auto *ILE = dyn_cast<InitListExpr>(ExprToVisit)) {
11244 Field = ILE->getInitializedFieldInUnion();
11245 }
else if (
auto *PLIE = dyn_cast<CXXParenListInitExpr>(ExprToVisit)) {
11246 Field = PLIE->getInitializedFieldInUnion();
11249 "Expression is neither an init list nor a C++ paren list");
11261 ImplicitValueInitExpr VIE(
Field->getType());
11262 const Expr *InitExpr = Args.empty() ? &VIE : Args[0];
11264 LValue Subobject =
This;
11269 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
11273 if (
Field->isBitField())
11283 Result =
APValue(APValue::UninitStruct(), CXXRD ? CXXRD->getNumBases() : 0,
11285 unsigned ElementNo = 0;
11289 if (CXXRD && CXXRD->getNumBases()) {
11290 for (
const auto &Base : CXXRD->bases()) {
11291 assert(ElementNo < Args.size() &&
"missing init for base class");
11292 const Expr *
Init = Args[ElementNo];
11294 LValue Subobject =
This;
11300 if (!Info.noteFailure())
11307 EvalObj.finishedConstructingBases();
11311 for (
const auto *Field : RD->
fields()) {
11314 if (
Field->isUnnamedBitField())
11317 LValue Subobject =
This;
11319 bool HaveInit = ElementNo < Args.size();
11324 Subobject, Field, &Layout))
11329 ImplicitValueInitExpr VIE(HaveInit ? Info.Ctx.IntTy :
Field->getType());
11330 const Expr *
Init = HaveInit ? Args[ElementNo++] : &VIE;
11332 if (
Field->getType()->isIncompleteArrayType()) {
11333 if (
auto *CAT = Info.Ctx.getAsConstantArrayType(
Init->getType())) {
11337 Info.FFDiag(
Init, diag::note_constexpr_unsupported_flexible_array);
11344 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
11348 if (
Field->getType()->isReferenceType()) {
11352 if (!Info.noteFailure())
11357 (
Field->isBitField() &&
11359 if (!Info.noteFailure())
11365 EvalObj.finishedConstructingFields();
11370bool RecordExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E,
11380 return ZeroInitialization(E, T);
11398 const Expr *SrcObj = E->
getArg(0);
11400 assert(Info.Ctx.hasSameUnqualifiedType(E->
getType(), SrcObj->
getType()));
11401 if (
const MaterializeTemporaryExpr *ME =
11402 dyn_cast<MaterializeTemporaryExpr>(SrcObj))
11403 return Visit(ME->getSubExpr());
11406 if (ZeroInit && !ZeroInitialization(E, T))
11415bool RecordExprEvaluator::VisitCXXInheritedCtorInitExpr(
11416 const CXXInheritedCtorInitExpr *E) {
11417 if (!Info.CurrentCall) {
11418 assert(Info.checkingPotentialConstantExpression());
11437bool RecordExprEvaluator::VisitCXXStdInitializerListExpr(
11438 const CXXStdInitializerListExpr *E) {
11439 const ConstantArrayType *ArrayType =
11446 assert(ArrayType &&
"unexpected type for array initializer");
11449 Array.addArray(Info, E, ArrayType);
11457 assert(Field !=
Record->field_end() &&
11458 Info.Ctx.hasSameType(
Field->getType()->getPointeeType(),
11460 "Expected std::initializer_list first field to be const E *");
11462 assert(Field !=
Record->field_end() &&
11463 "Expected std::initializer_list to have two fields");
11465 if (Info.Ctx.hasSameType(
Field->getType(), Info.Ctx.getSizeType())) {
11470 assert(Info.Ctx.hasSameType(
Field->getType()->getPointeeType(),
11472 "Expected std::initializer_list second field to be const E *");
11480 assert(++Field ==
Record->field_end() &&
11481 "Expected std::initializer_list to only have two fields");
11486bool RecordExprEvaluator::VisitLambdaExpr(
const LambdaExpr *E) {
11491 const size_t NumFields = ClosureClass->
getNumFields();
11495 "The number of lambda capture initializers should equal the number of "
11496 "fields within the closure type");
11503 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(ClosureClass);
11504 for (
const auto *Field : ClosureClass->
fields()) {
11507 Expr *
const CurFieldInit = *CaptureInitIt++;
11514 LValue Subobject =
This;
11521 if (!Info.keepEvaluatingAfterFailure())
11530 APValue &Result, EvalInfo &Info) {
11533 "can't evaluate expression as a record rvalue");
11534 return RecordExprEvaluator(Info,
This, Result).Visit(E);
11545class TemporaryExprEvaluator
11546 :
public LValueExprEvaluatorBase<TemporaryExprEvaluator> {
11548 TemporaryExprEvaluator(EvalInfo &Info, LValue &
Result) :
11549 LValueExprEvaluatorBaseTy(Info,
Result,
false) {}
11552 bool VisitConstructExpr(
const Expr *E) {
11558 bool VisitCastExpr(
const CastExpr *E) {
11561 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
11563 case CK_ConstructorConversion:
11567 bool VisitInitListExpr(
const InitListExpr *E) {
11568 return VisitConstructExpr(E);
11570 bool VisitCXXConstructExpr(
const CXXConstructExpr *E) {
11571 return VisitConstructExpr(E);
11573 bool VisitCallExpr(
const CallExpr *E) {
11574 return VisitConstructExpr(E);
11576 bool VisitCXXStdInitializerListExpr(
const CXXStdInitializerListExpr *E) {
11577 return VisitConstructExpr(E);
11580 return VisitConstructExpr(E);
11589 return TemporaryExprEvaluator(Info, Result).Visit(E);
11597 class VectorExprEvaluator
11598 :
public ExprEvaluatorBase<VectorExprEvaluator> {
11605 bool Success(ArrayRef<APValue>
V,
const Expr *E) {
11606 assert(
V.size() == E->
getType()->
castAs<VectorType>()->getNumElements());
11612 assert(
V.isVector());
11616 bool ZeroInitialization(
const Expr *E);
11618 bool VisitUnaryReal(
const UnaryOperator *E)
11620 bool VisitCastExpr(
const CastExpr* E);
11621 bool VisitInitListExpr(
const InitListExpr *E);
11622 bool VisitUnaryImag(
const UnaryOperator *E);
11623 bool VisitBinaryOperator(
const BinaryOperator *E);
11624 bool VisitUnaryOperator(
const UnaryOperator *E);
11625 bool VisitCallExpr(
const CallExpr *E);
11626 bool VisitConvertVectorExpr(
const ConvertVectorExpr *E);
11627 bool VisitShuffleVectorExpr(
const ShuffleVectorExpr *E);
11636 "not a vector prvalue");
11637 return VectorExprEvaluator(Info, Result).Visit(E);
11641 assert(Val.
isVector() &&
"expected vector APValue");
11645 llvm::APInt
Result(NumElts, 0);
11647 for (
unsigned I = 0; I < NumElts; ++I) {
11649 assert(Elt.
isInt() &&
"expected integer element in bool vector");
11651 if (Elt.
getInt().getBoolValue())
11658bool VectorExprEvaluator::VisitCastExpr(
const CastExpr *E) {
11659 const VectorType *VTy = E->
getType()->
castAs<VectorType>();
11663 QualType SETy = SE->
getType();
11666 case CK_VectorSplat: {
11672 Val =
APValue(std::move(IntResult));
11677 Val =
APValue(std::move(FloatResult));
11694 Info.FFDiag(E, diag::note_constexpr_invalid_cast)
11695 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
11696 << Info.Ctx.getLangOpts().CPlusPlus;
11700 if (!handleRValueToRValueBitCast(Info,
Result, SVal, E))
11705 case CK_HLSLVectorTruncation: {
11710 for (
unsigned I = 0; I < NElts; I++)
11714 case CK_HLSLMatrixTruncation: {
11720 for (
unsigned Row = 0;
11722 for (
unsigned Col = 0;
11727 case CK_HLSLAggregateSplatCast: {
11744 case CK_HLSLElementwiseCast: {
11757 return Success(ResultEls, E);
11760 return ExprEvaluatorBaseTy::VisitCastExpr(E);
11765VectorExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
11782 unsigned CountInits = 0, CountElts = 0;
11783 while (CountElts < NumElements) {
11785 if (CountInits < NumInits
11791 for (
unsigned j = 0; j < vlen; j++)
11795 llvm::APSInt sInt(32);
11796 if (CountInits < NumInits) {
11800 sInt = Info.Ctx.MakeIntValue(0, EltTy);
11801 Elements.push_back(
APValue(sInt));
11804 llvm::APFloat f(0.0);
11805 if (CountInits < NumInits) {
11809 f = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy));
11810 Elements.push_back(
APValue(f));
11819VectorExprEvaluator::ZeroInitialization(
const Expr *E) {
11823 if (EltTy->isIntegerType())
11824 ZeroElement =
APValue(Info.Ctx.MakeIntValue(0, EltTy));
11827 APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy)));
11833bool VectorExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
11835 return ZeroInitialization(E);
11838bool VectorExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
11840 assert(Op != BO_PtrMemD && Op != BO_PtrMemI && Op != BO_Cmp &&
11841 "Operation not supported on vector types");
11843 if (Op == BO_Comma)
11844 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
11846 Expr *LHS = E->
getLHS();
11847 Expr *RHS = E->
getRHS();
11850 "Must both be vector types");
11853 assert(LHS->
getType()->
castAs<VectorType>()->getNumElements() ==
11857 "All operands must be the same size.");
11861 bool LHSOK =
Evaluate(LHSValue, Info, LHS);
11862 if (!LHSOK && !Info.noteFailure())
11864 if (!
Evaluate(RHSValue, Info, RHS) || !LHSOK)
11886 "Vector can only be int or float type");
11894 "Vector operator ~ can only be int");
11895 Elt.
getInt().flipAllBits();
11905 "Vector can only be int or float type");
11911 EltResult.setAllBits();
11913 EltResult.clearAllBits();
11919 return std::nullopt;
11923bool VectorExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
11929 const QualType ResultEltTy = VD->getElementType();
11933 if (!
Evaluate(SubExprValue, Info, SubExpr))
11946 "Vector length doesn't match type?");
11949 for (
unsigned EltNum = 0; EltNum < VD->getNumElements(); ++EltNum) {
11951 Info.Ctx, ResultEltTy, Op, SubExprValue.
getVectorElt(EltNum));
11954 ResultElements.push_back(*Elt);
11956 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
11965 Result =
APValue(APFloat(0.0));
11967 DestTy, Result.getFloat());
11978 Result.getFloat());
11983 DestTy, Result.getInt());
11987 Info.FFDiag(E, diag::err_convertvector_constexpr_unsupported_vector_cast)
11988 << SourceTy << DestTy;
11993 llvm::function_ref<APInt(
const APSInt &)> PackFn) {
12002 assert(LHSVecLen != 0 && LHSVecLen == RHSVecLen &&
12003 "pack builtin LHSVecLen must equal to RHSVecLen");
12006 const unsigned SrcBits = Info.Ctx.getIntWidth(VT0->
getElementType());
12012 const unsigned SrcPerLane = 128 / SrcBits;
12013 const unsigned Lanes = LHSVecLen * SrcBits / 128;
12016 Out.reserve(LHSVecLen + RHSVecLen);
12018 for (
unsigned Lane = 0; Lane != Lanes; ++Lane) {
12019 unsigned base = Lane * SrcPerLane;
12020 for (
unsigned I = 0; I != SrcPerLane; ++I)
12023 for (
unsigned I = 0; I != SrcPerLane; ++I)
12028 Result =
APValue(Out.data(), Out.size());
12034 llvm::function_ref<std::pair<unsigned, int>(
unsigned,
unsigned)>
12041 unsigned ShuffleMask = 0;
12043 bool IsVectorMask =
false;
12044 bool IsSingleOperand = (
Call->getNumArgs() == 2);
12046 if (IsSingleOperand) {
12049 IsVectorMask =
true;
12058 ShuffleMask =
static_cast<unsigned>(MaskImm.getZExtValue());
12068 IsVectorMask =
true;
12077 ShuffleMask =
static_cast<unsigned>(MaskImm.getZExtValue());
12088 ResultElements.reserve(NumElts);
12090 for (
unsigned DstIdx = 0; DstIdx != NumElts; ++DstIdx) {
12091 if (IsVectorMask) {
12092 ShuffleMask =
static_cast<unsigned>(
12093 MaskVector.getVectorElt(DstIdx).getInt().getZExtValue());
12095 auto [SrcVecIdx, SrcIdx] = GetSourceIndex(DstIdx, ShuffleMask);
12101 ResultElements.push_back(
12102 APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(ElemTy))));
12108 ResultElements.push_back(
APValue());
12111 const APValue &Src = (SrcVecIdx == 0) ? A : B;
12116 Out =
APValue(ResultElements.data(), ResultElements.size());
12120 APFloat OrigVal,
APValue &Result) {
12122 if (OrigVal.isInfinity()) {
12123 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << 0;
12126 if (OrigVal.isNaN()) {
12127 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << 1;
12131 APFloat Val = OrigVal;
12132 bool LosesInfo =
false;
12133 APFloat::opStatus Status = Val.convert(
12134 APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven, &LosesInfo);
12136 if (LosesInfo || Val.isDenormal()) {
12137 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic_strict);
12141 if (Status != APFloat::opOK) {
12142 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
12151 llvm::function_ref<APInt(
const APInt &, uint64_t)> ShiftOp,
12152 llvm::function_ref<APInt(
const APInt &,
unsigned)> OverflowOp) {
12159 assert(
Call->getNumArgs() == 2);
12163 Call->getArg(1)->getType()->isVectorType());
12166 unsigned DestEltWidth = Source.getVectorElt(0).getInt().getBitWidth();
12167 unsigned DestLen = Source.getVectorLength();
12170 unsigned NumBitsInQWord = 64;
12171 unsigned NumCountElts = NumBitsInQWord / CountEltWidth;
12173 Result.reserve(DestLen);
12175 uint64_t CountLQWord = 0;
12176 for (
unsigned EltIdx = 0; EltIdx != NumCountElts; ++EltIdx) {
12178 CountLQWord |= (Elt << (EltIdx * CountEltWidth));
12181 for (
unsigned EltIdx = 0; EltIdx != DestLen; ++EltIdx) {
12182 APInt Elt = Source.getVectorElt(EltIdx).getInt();
12183 if (CountLQWord < DestEltWidth) {
12185 APValue(
APSInt(ShiftOp(Elt, CountLQWord), IsDestUnsigned)));
12188 APValue(
APSInt(OverflowOp(Elt, DestEltWidth), IsDestUnsigned)));
12191 Out =
APValue(Result.data(), Result.size());
12196 std::optional<APSInt> RoundingMode,
12198 APSInt DefaultMode(APInt(32, 4),
true);
12199 if (RoundingMode.value_or(DefaultMode) != 4)
12200 return std::nullopt;
12201 if (A.isNaN() || A.isInfinity() || A.isDenormal() || B.isNaN() ||
12202 B.isInfinity() || B.isDenormal())
12203 return std::nullopt;
12204 if (A.isZero() && B.isZero())
12206 return IsMin ? llvm::minimum(A, B) : llvm::maximum(A, B);
12209bool VectorExprEvaluator::VisitCallExpr(
const CallExpr *E) {
12210 if (!IsConstantEvaluatedBuiltinCall(E))
12211 return ExprEvaluatorBaseTy::VisitCallExpr(E);
12213 auto EvaluateBinOpExpr =
12215 APValue SourceLHS, SourceRHS;
12221 QualType DestEltTy = DestTy->getElementType();
12222 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
12225 ResultElements.reserve(SourceLen);
12227 if (SourceRHS.
isInt()) {
12229 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12231 ResultElements.push_back(
12235 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12238 ResultElements.push_back(
12245 auto EvaluateFpBinOpExpr =
12246 [&](llvm::function_ref<std::optional<APFloat>(
12247 const APFloat &,
const APFloat &, std::optional<APSInt>)>
12249 bool IsScalar =
false) {
12259 std::optional<APSInt> RoundingMode;
12264 RoundingMode = Imm;
12269 ResultElements.reserve(NumElems);
12271 for (
unsigned EltNum = 0; EltNum < NumElems; ++EltNum) {
12272 if (IsScalar && EltNum > 0) {
12278 std::optional<APFloat>
Result =
Fn(EltA, EltB, RoundingMode);
12286 auto EvaluateScalarFpRoundMaskBinOp =
12287 [&](llvm::function_ref<std::optional<APFloat>(
12288 const APFloat &,
const APFloat &, std::optional<APSInt>)>
12292 APSInt MaskVal, Rounding;
12303 ResultElements.reserve(NumElems);
12305 if (MaskVal.getZExtValue() & 1) {
12308 std::optional<APFloat>
Result =
Fn(EltA, EltB, Rounding);
12316 for (
unsigned I = 1; I < NumElems; ++I)
12322 auto EvalSelectScalar = [&](
unsigned Len) ->
bool {
12330 bool TakeA0 = (Mask.getZExtValue() & 1u) != 0;
12334 for (
unsigned I = 1; I < Len; ++I)
12336 APValue V(Res.data(), Res.size());
12343 case Builtin::BI__builtin_elementwise_popcount:
12344 case Builtin::BI__builtin_elementwise_bitreverse: {
12349 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12352 ResultElements.reserve(SourceLen);
12354 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12357 case Builtin::BI__builtin_elementwise_popcount:
12358 ResultElements.push_back(
APValue(
12359 APSInt(
APInt(Info.Ctx.getIntWidth(DestEltTy), Elt.popcount()),
12362 case Builtin::BI__builtin_elementwise_bitreverse:
12363 ResultElements.push_back(
12370 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12372 case Builtin::BI__builtin_elementwise_abs: {
12377 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12380 ResultElements.reserve(SourceLen);
12382 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12387 CurrentEle.getInt().
abs(),
12388 DestEltTy->isUnsignedIntegerOrEnumerationType()));
12389 ResultElements.push_back(Val);
12392 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12395 case Builtin::BI__builtin_elementwise_add_sat:
12396 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12397 return LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS);
12400 case Builtin::BI__builtin_elementwise_sub_sat:
12401 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12402 return LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
12405 case X86::BI__builtin_ia32_extract128i256:
12406 case X86::BI__builtin_ia32_vextractf128_pd256:
12407 case X86::BI__builtin_ia32_vextractf128_ps256:
12408 case X86::BI__builtin_ia32_vextractf128_si256: {
12409 APValue SourceVec, SourceImm;
12418 unsigned RetLen = RetVT->getNumElements();
12419 unsigned Idx = SourceImm.
getInt().getZExtValue() & 1;
12422 ResultElements.reserve(RetLen);
12424 for (
unsigned I = 0; I < RetLen; I++)
12425 ResultElements.push_back(SourceVec.
getVectorElt(Idx * RetLen + I));
12430 case clang::X86::BI__builtin_ia32_cvtmask2b128:
12431 case clang::X86::BI__builtin_ia32_cvtmask2b256:
12432 case clang::X86::BI__builtin_ia32_cvtmask2b512:
12433 case clang::X86::BI__builtin_ia32_cvtmask2w128:
12434 case clang::X86::BI__builtin_ia32_cvtmask2w256:
12435 case clang::X86::BI__builtin_ia32_cvtmask2w512:
12436 case clang::X86::BI__builtin_ia32_cvtmask2d128:
12437 case clang::X86::BI__builtin_ia32_cvtmask2d256:
12438 case clang::X86::BI__builtin_ia32_cvtmask2d512:
12439 case clang::X86::BI__builtin_ia32_cvtmask2q128:
12440 case clang::X86::BI__builtin_ia32_cvtmask2q256:
12441 case clang::X86::BI__builtin_ia32_cvtmask2q512: {
12447 QualType VecTy = E->
getType();
12448 const VectorType *VT = VecTy->
castAs<VectorType>();
12451 unsigned ElemWidth = Info.Ctx.getTypeSize(ElemTy);
12454 for (
unsigned I = 0; I != VectorLen; ++I) {
12455 bool BitSet = Mask[I];
12456 APSInt ElemVal(ElemWidth,
false);
12458 ElemVal.setAllBits();
12460 Elems.push_back(
APValue(ElemVal));
12465 case X86::BI__builtin_ia32_extracti32x4_256_mask:
12466 case X86::BI__builtin_ia32_extractf32x4_256_mask:
12467 case X86::BI__builtin_ia32_extracti32x4_mask:
12468 case X86::BI__builtin_ia32_extractf32x4_mask:
12469 case X86::BI__builtin_ia32_extracti32x8_mask:
12470 case X86::BI__builtin_ia32_extractf32x8_mask:
12471 case X86::BI__builtin_ia32_extracti64x2_256_mask:
12472 case X86::BI__builtin_ia32_extractf64x2_256_mask:
12473 case X86::BI__builtin_ia32_extracti64x2_512_mask:
12474 case X86::BI__builtin_ia32_extractf64x2_512_mask:
12475 case X86::BI__builtin_ia32_extracti64x4_mask:
12476 case X86::BI__builtin_ia32_extractf64x4_mask: {
12487 unsigned RetLen = RetVT->getNumElements();
12492 unsigned Lanes = SrcLen / RetLen;
12493 unsigned Lane =
static_cast<unsigned>(Imm.getZExtValue() % Lanes);
12494 unsigned Base = Lane * RetLen;
12497 ResultElements.reserve(RetLen);
12498 for (
unsigned I = 0; I < RetLen; ++I) {
12500 ResultElements.push_back(SourceVec.
getVectorElt(Base + I));
12504 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12507 case clang::X86::BI__builtin_ia32_pavgb128:
12508 case clang::X86::BI__builtin_ia32_pavgw128:
12509 case clang::X86::BI__builtin_ia32_pavgb256:
12510 case clang::X86::BI__builtin_ia32_pavgw256:
12511 case clang::X86::BI__builtin_ia32_pavgb512:
12512 case clang::X86::BI__builtin_ia32_pavgw512:
12513 return EvaluateBinOpExpr(llvm::APIntOps::avgCeilU);
12515 case clang::X86::BI__builtin_ia32_pmulhrsw128:
12516 case clang::X86::BI__builtin_ia32_pmulhrsw256:
12517 case clang::X86::BI__builtin_ia32_pmulhrsw512:
12518 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12519 return (llvm::APIntOps::mulsExtended(LHS, RHS).ashr(14) + 1)
12520 .extractBits(16, 1);
12523 case clang::X86::BI__builtin_ia32_pmaddubsw128:
12524 case clang::X86::BI__builtin_ia32_pmaddubsw256:
12525 case clang::X86::BI__builtin_ia32_pmaddubsw512:
12526 case clang::X86::BI__builtin_ia32_pmaddwd128:
12527 case clang::X86::BI__builtin_ia32_pmaddwd256:
12528 case clang::X86::BI__builtin_ia32_pmaddwd512: {
12529 APValue SourceLHS, SourceRHS;
12535 QualType DestEltTy = DestTy->getElementType();
12537 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
12539 ResultElements.reserve(SourceLen / 2);
12541 for (
unsigned EltNum = 0; EltNum < SourceLen; EltNum += 2) {
12546 unsigned BitWidth = 2 * LoLHS.getBitWidth();
12549 case clang::X86::BI__builtin_ia32_pmaddubsw128:
12550 case clang::X86::BI__builtin_ia32_pmaddubsw256:
12551 case clang::X86::BI__builtin_ia32_pmaddubsw512:
12552 ResultElements.push_back(
APValue(
12553 APSInt((LoLHS.zext(BitWidth) * LoRHS.sext(BitWidth))
12554 .sadd_sat((HiLHS.zext(BitWidth) * HiRHS.sext(BitWidth))),
12557 case clang::X86::BI__builtin_ia32_pmaddwd128:
12558 case clang::X86::BI__builtin_ia32_pmaddwd256:
12559 case clang::X86::BI__builtin_ia32_pmaddwd512:
12560 ResultElements.push_back(
12561 APValue(
APSInt((LoLHS.sext(BitWidth) * LoRHS.sext(BitWidth)) +
12562 (HiLHS.sext(BitWidth) * HiRHS.sext(BitWidth)),
12568 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12571 case clang::X86::BI__builtin_ia32_pmulhuw128:
12572 case clang::X86::BI__builtin_ia32_pmulhuw256:
12573 case clang::X86::BI__builtin_ia32_pmulhuw512:
12574 return EvaluateBinOpExpr(llvm::APIntOps::mulhu);
12576 case clang::X86::BI__builtin_ia32_pmulhw128:
12577 case clang::X86::BI__builtin_ia32_pmulhw256:
12578 case clang::X86::BI__builtin_ia32_pmulhw512:
12579 return EvaluateBinOpExpr(llvm::APIntOps::mulhs);
12581 case clang::X86::BI__builtin_ia32_psllv2di:
12582 case clang::X86::BI__builtin_ia32_psllv4di:
12583 case clang::X86::BI__builtin_ia32_psllv4si:
12584 case clang::X86::BI__builtin_ia32_psllv8di:
12585 case clang::X86::BI__builtin_ia32_psllv8hi:
12586 case clang::X86::BI__builtin_ia32_psllv8si:
12587 case clang::X86::BI__builtin_ia32_psllv16hi:
12588 case clang::X86::BI__builtin_ia32_psllv16si:
12589 case clang::X86::BI__builtin_ia32_psllv32hi:
12590 case clang::X86::BI__builtin_ia32_psllwi128:
12591 case clang::X86::BI__builtin_ia32_pslldi128:
12592 case clang::X86::BI__builtin_ia32_psllqi128:
12593 case clang::X86::BI__builtin_ia32_psllwi256:
12594 case clang::X86::BI__builtin_ia32_pslldi256:
12595 case clang::X86::BI__builtin_ia32_psllqi256:
12596 case clang::X86::BI__builtin_ia32_psllwi512:
12597 case clang::X86::BI__builtin_ia32_pslldi512:
12598 case clang::X86::BI__builtin_ia32_psllqi512:
12599 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12600 if (RHS.uge(LHS.getBitWidth())) {
12601 return APInt::getZero(LHS.getBitWidth());
12603 return LHS.shl(RHS.getZExtValue());
12606 case clang::X86::BI__builtin_ia32_psrav4si:
12607 case clang::X86::BI__builtin_ia32_psrav8di:
12608 case clang::X86::BI__builtin_ia32_psrav8hi:
12609 case clang::X86::BI__builtin_ia32_psrav8si:
12610 case clang::X86::BI__builtin_ia32_psrav16hi:
12611 case clang::X86::BI__builtin_ia32_psrav16si:
12612 case clang::X86::BI__builtin_ia32_psrav32hi:
12613 case clang::X86::BI__builtin_ia32_psravq128:
12614 case clang::X86::BI__builtin_ia32_psravq256:
12615 case clang::X86::BI__builtin_ia32_psrawi128:
12616 case clang::X86::BI__builtin_ia32_psradi128:
12617 case clang::X86::BI__builtin_ia32_psraqi128:
12618 case clang::X86::BI__builtin_ia32_psrawi256:
12619 case clang::X86::BI__builtin_ia32_psradi256:
12620 case clang::X86::BI__builtin_ia32_psraqi256:
12621 case clang::X86::BI__builtin_ia32_psrawi512:
12622 case clang::X86::BI__builtin_ia32_psradi512:
12623 case clang::X86::BI__builtin_ia32_psraqi512:
12624 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12625 if (RHS.uge(LHS.getBitWidth())) {
12626 return LHS.ashr(LHS.getBitWidth() - 1);
12628 return LHS.ashr(RHS.getZExtValue());
12631 case clang::X86::BI__builtin_ia32_psrlv2di:
12632 case clang::X86::BI__builtin_ia32_psrlv4di:
12633 case clang::X86::BI__builtin_ia32_psrlv4si:
12634 case clang::X86::BI__builtin_ia32_psrlv8di:
12635 case clang::X86::BI__builtin_ia32_psrlv8hi:
12636 case clang::X86::BI__builtin_ia32_psrlv8si:
12637 case clang::X86::BI__builtin_ia32_psrlv16hi:
12638 case clang::X86::BI__builtin_ia32_psrlv16si:
12639 case clang::X86::BI__builtin_ia32_psrlv32hi:
12640 case clang::X86::BI__builtin_ia32_psrlwi128:
12641 case clang::X86::BI__builtin_ia32_psrldi128:
12642 case clang::X86::BI__builtin_ia32_psrlqi128:
12643 case clang::X86::BI__builtin_ia32_psrlwi256:
12644 case clang::X86::BI__builtin_ia32_psrldi256:
12645 case clang::X86::BI__builtin_ia32_psrlqi256:
12646 case clang::X86::BI__builtin_ia32_psrlwi512:
12647 case clang::X86::BI__builtin_ia32_psrldi512:
12648 case clang::X86::BI__builtin_ia32_psrlqi512:
12649 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12650 if (RHS.uge(LHS.getBitWidth())) {
12651 return APInt::getZero(LHS.getBitWidth());
12653 return LHS.lshr(RHS.getZExtValue());
12655 case X86::BI__builtin_ia32_packsswb128:
12656 case X86::BI__builtin_ia32_packsswb256:
12657 case X86::BI__builtin_ia32_packsswb512:
12658 case X86::BI__builtin_ia32_packssdw128:
12659 case X86::BI__builtin_ia32_packssdw256:
12660 case X86::BI__builtin_ia32_packssdw512:
12662 return APSInt(Src).truncSSat(Src.getBitWidth() / 2);
12664 case X86::BI__builtin_ia32_packusdw128:
12665 case X86::BI__builtin_ia32_packusdw256:
12666 case X86::BI__builtin_ia32_packusdw512:
12667 case X86::BI__builtin_ia32_packuswb128:
12668 case X86::BI__builtin_ia32_packuswb256:
12669 case X86::BI__builtin_ia32_packuswb512:
12671 return APSInt(Src).truncSSatU(Src.getBitWidth() / 2);
12673 case clang::X86::BI__builtin_ia32_selectss_128:
12674 return EvalSelectScalar(4);
12675 case clang::X86::BI__builtin_ia32_selectsd_128:
12676 return EvalSelectScalar(2);
12677 case clang::X86::BI__builtin_ia32_selectsh_128:
12678 case clang::X86::BI__builtin_ia32_selectsbf_128:
12679 return EvalSelectScalar(8);
12680 case clang::X86::BI__builtin_ia32_pmuldq128:
12681 case clang::X86::BI__builtin_ia32_pmuldq256:
12682 case clang::X86::BI__builtin_ia32_pmuldq512:
12683 case clang::X86::BI__builtin_ia32_pmuludq128:
12684 case clang::X86::BI__builtin_ia32_pmuludq256:
12685 case clang::X86::BI__builtin_ia32_pmuludq512: {
12686 APValue SourceLHS, SourceRHS;
12693 ResultElements.reserve(SourceLen / 2);
12695 for (
unsigned EltNum = 0; EltNum < SourceLen; EltNum += 2) {
12700 case clang::X86::BI__builtin_ia32_pmuludq128:
12701 case clang::X86::BI__builtin_ia32_pmuludq256:
12702 case clang::X86::BI__builtin_ia32_pmuludq512:
12703 ResultElements.push_back(
12704 APValue(
APSInt(llvm::APIntOps::muluExtended(LHS, RHS),
true)));
12706 case clang::X86::BI__builtin_ia32_pmuldq128:
12707 case clang::X86::BI__builtin_ia32_pmuldq256:
12708 case clang::X86::BI__builtin_ia32_pmuldq512:
12709 ResultElements.push_back(
12710 APValue(
APSInt(llvm::APIntOps::mulsExtended(LHS, RHS),
false)));
12715 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12718 case X86::BI__builtin_ia32_vpmadd52luq128:
12719 case X86::BI__builtin_ia32_vpmadd52luq256:
12720 case X86::BI__builtin_ia32_vpmadd52luq512: {
12729 ResultElements.reserve(ALen);
12731 for (
unsigned EltNum = 0; EltNum < ALen; EltNum += 1) {
12734 APInt CElt =
C.getVectorElt(EltNum).getInt().trunc(52);
12735 APSInt ResElt(AElt + (BElt * CElt).zext(64),
false);
12736 ResultElements.push_back(
APValue(ResElt));
12739 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12741 case X86::BI__builtin_ia32_vpmadd52huq128:
12742 case X86::BI__builtin_ia32_vpmadd52huq256:
12743 case X86::BI__builtin_ia32_vpmadd52huq512: {
12752 ResultElements.reserve(ALen);
12754 for (
unsigned EltNum = 0; EltNum < ALen; EltNum += 1) {
12757 APInt CElt =
C.getVectorElt(EltNum).getInt().trunc(52);
12758 APSInt ResElt(AElt + llvm::APIntOps::mulhu(BElt, CElt).zext(64),
false);
12759 ResultElements.push_back(
APValue(ResElt));
12762 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12765 case clang::X86::BI__builtin_ia32_vprotbi:
12766 case clang::X86::BI__builtin_ia32_vprotdi:
12767 case clang::X86::BI__builtin_ia32_vprotqi:
12768 case clang::X86::BI__builtin_ia32_vprotwi:
12769 case clang::X86::BI__builtin_ia32_prold128:
12770 case clang::X86::BI__builtin_ia32_prold256:
12771 case clang::X86::BI__builtin_ia32_prold512:
12772 case clang::X86::BI__builtin_ia32_prolq128:
12773 case clang::X86::BI__builtin_ia32_prolq256:
12774 case clang::X86::BI__builtin_ia32_prolq512:
12775 return EvaluateBinOpExpr(
12776 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS.rotl(RHS); });
12778 case clang::X86::BI__builtin_ia32_prord128:
12779 case clang::X86::BI__builtin_ia32_prord256:
12780 case clang::X86::BI__builtin_ia32_prord512:
12781 case clang::X86::BI__builtin_ia32_prorq128:
12782 case clang::X86::BI__builtin_ia32_prorq256:
12783 case clang::X86::BI__builtin_ia32_prorq512:
12784 return EvaluateBinOpExpr(
12785 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS.rotr(RHS); });
12787 case Builtin::BI__builtin_elementwise_max:
12788 case Builtin::BI__builtin_elementwise_min: {
12789 APValue SourceLHS, SourceRHS;
12794 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12801 ResultElements.reserve(SourceLen);
12803 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12807 case Builtin::BI__builtin_elementwise_max:
12808 ResultElements.push_back(
12812 case Builtin::BI__builtin_elementwise_min:
12813 ResultElements.push_back(
12820 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12822 case X86::BI__builtin_ia32_vpshldd128:
12823 case X86::BI__builtin_ia32_vpshldd256:
12824 case X86::BI__builtin_ia32_vpshldd512:
12825 case X86::BI__builtin_ia32_vpshldq128:
12826 case X86::BI__builtin_ia32_vpshldq256:
12827 case X86::BI__builtin_ia32_vpshldq512:
12828 case X86::BI__builtin_ia32_vpshldw128:
12829 case X86::BI__builtin_ia32_vpshldw256:
12830 case X86::BI__builtin_ia32_vpshldw512: {
12831 APValue SourceHi, SourceLo, SourceAmt;
12837 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12840 ResultElements.reserve(SourceLen);
12843 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12846 APInt R = llvm::APIntOps::fshl(Hi, Lo, Amt);
12847 ResultElements.push_back(
12851 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12853 case X86::BI__builtin_ia32_vpshrdd128:
12854 case X86::BI__builtin_ia32_vpshrdd256:
12855 case X86::BI__builtin_ia32_vpshrdd512:
12856 case X86::BI__builtin_ia32_vpshrdq128:
12857 case X86::BI__builtin_ia32_vpshrdq256:
12858 case X86::BI__builtin_ia32_vpshrdq512:
12859 case X86::BI__builtin_ia32_vpshrdw128:
12860 case X86::BI__builtin_ia32_vpshrdw256:
12861 case X86::BI__builtin_ia32_vpshrdw512: {
12863 APValue SourceHi, SourceLo, SourceAmt;
12869 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12872 ResultElements.reserve(SourceLen);
12875 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12878 APInt R = llvm::APIntOps::fshr(Hi, Lo, Amt);
12879 ResultElements.push_back(
12883 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12885 case X86::BI__builtin_ia32_compressdf128_mask:
12886 case X86::BI__builtin_ia32_compressdf256_mask:
12887 case X86::BI__builtin_ia32_compressdf512_mask:
12888 case X86::BI__builtin_ia32_compressdi128_mask:
12889 case X86::BI__builtin_ia32_compressdi256_mask:
12890 case X86::BI__builtin_ia32_compressdi512_mask:
12891 case X86::BI__builtin_ia32_compresshi128_mask:
12892 case X86::BI__builtin_ia32_compresshi256_mask:
12893 case X86::BI__builtin_ia32_compresshi512_mask:
12894 case X86::BI__builtin_ia32_compressqi128_mask:
12895 case X86::BI__builtin_ia32_compressqi256_mask:
12896 case X86::BI__builtin_ia32_compressqi512_mask:
12897 case X86::BI__builtin_ia32_compresssf128_mask:
12898 case X86::BI__builtin_ia32_compresssf256_mask:
12899 case X86::BI__builtin_ia32_compresssf512_mask:
12900 case X86::BI__builtin_ia32_compresssi128_mask:
12901 case X86::BI__builtin_ia32_compresssi256_mask:
12902 case X86::BI__builtin_ia32_compresssi512_mask: {
12913 ResultElements.reserve(NumElts);
12915 for (
unsigned I = 0; I != NumElts; ++I) {
12919 for (
unsigned I = ResultElements.size(); I != NumElts; ++I) {
12923 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12925 case X86::BI__builtin_ia32_expanddf128_mask:
12926 case X86::BI__builtin_ia32_expanddf256_mask:
12927 case X86::BI__builtin_ia32_expanddf512_mask:
12928 case X86::BI__builtin_ia32_expanddi128_mask:
12929 case X86::BI__builtin_ia32_expanddi256_mask:
12930 case X86::BI__builtin_ia32_expanddi512_mask:
12931 case X86::BI__builtin_ia32_expandhi128_mask:
12932 case X86::BI__builtin_ia32_expandhi256_mask:
12933 case X86::BI__builtin_ia32_expandhi512_mask:
12934 case X86::BI__builtin_ia32_expandqi128_mask:
12935 case X86::BI__builtin_ia32_expandqi256_mask:
12936 case X86::BI__builtin_ia32_expandqi512_mask:
12937 case X86::BI__builtin_ia32_expandsf128_mask:
12938 case X86::BI__builtin_ia32_expandsf256_mask:
12939 case X86::BI__builtin_ia32_expandsf512_mask:
12940 case X86::BI__builtin_ia32_expandsi128_mask:
12941 case X86::BI__builtin_ia32_expandsi256_mask:
12942 case X86::BI__builtin_ia32_expandsi512_mask: {
12953 ResultElements.reserve(NumElts);
12955 unsigned SourceIdx = 0;
12956 for (
unsigned I = 0; I != NumElts; ++I) {
12958 ResultElements.push_back(Source.
getVectorElt(SourceIdx++));
12962 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12964 case X86::BI__builtin_ia32_vpconflictsi_128:
12965 case X86::BI__builtin_ia32_vpconflictsi_256:
12966 case X86::BI__builtin_ia32_vpconflictsi_512:
12967 case X86::BI__builtin_ia32_vpconflictdi_128:
12968 case X86::BI__builtin_ia32_vpconflictdi_256:
12969 case X86::BI__builtin_ia32_vpconflictdi_512: {
12977 ResultElements.reserve(SourceLen);
12980 bool DestUnsigned =
12981 VecT->getElementType()->isUnsignedIntegerOrEnumerationType();
12983 for (
unsigned I = 0; I != SourceLen; ++I) {
12986 APInt ConflictMask(EltI.
getInt().getBitWidth(), 0);
12987 for (
unsigned J = 0; J != I; ++J) {
12989 ConflictMask.setBitVal(J, EltI.
getInt() == EltJ.
getInt());
12991 ResultElements.push_back(
APValue(
APSInt(ConflictMask, DestUnsigned)));
12993 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12995 case X86::BI__builtin_ia32_blendpd:
12996 case X86::BI__builtin_ia32_blendpd256:
12997 case X86::BI__builtin_ia32_blendps:
12998 case X86::BI__builtin_ia32_blendps256:
12999 case X86::BI__builtin_ia32_pblendw128:
13000 case X86::BI__builtin_ia32_pblendw256:
13001 case X86::BI__builtin_ia32_pblendd128:
13002 case X86::BI__builtin_ia32_pblendd256: {
13003 APValue SourceF, SourceT, SourceC;
13012 ResultElements.reserve(SourceLen);
13013 for (
unsigned EltNum = 0; EltNum != SourceLen; ++EltNum) {
13016 ResultElements.push_back(
C[EltNum % 8] ? T : F);
13019 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13022 case X86::BI__builtin_ia32_psignb128:
13023 case X86::BI__builtin_ia32_psignb256:
13024 case X86::BI__builtin_ia32_psignw128:
13025 case X86::BI__builtin_ia32_psignw256:
13026 case X86::BI__builtin_ia32_psignd128:
13027 case X86::BI__builtin_ia32_psignd256:
13028 return EvaluateBinOpExpr([](
const APInt &AElem,
const APInt &BElem) {
13029 if (BElem.isZero())
13030 return APInt::getZero(AElem.getBitWidth());
13031 if (BElem.isNegative())
13036 case X86::BI__builtin_ia32_blendvpd:
13037 case X86::BI__builtin_ia32_blendvpd256:
13038 case X86::BI__builtin_ia32_blendvps:
13039 case X86::BI__builtin_ia32_blendvps256:
13040 case X86::BI__builtin_ia32_pblendvb128:
13041 case X86::BI__builtin_ia32_pblendvb256: {
13043 APValue SourceF, SourceT, SourceC;
13051 ResultElements.reserve(SourceLen);
13053 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13057 APInt M =
C.isInt() ? (
APInt)
C.getInt() :
C.getFloat().bitcastToAPInt();
13058 ResultElements.push_back(M.isNegative() ? T : F);
13061 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13063 case X86::BI__builtin_ia32_selectb_128:
13064 case X86::BI__builtin_ia32_selectb_256:
13065 case X86::BI__builtin_ia32_selectb_512:
13066 case X86::BI__builtin_ia32_selectw_128:
13067 case X86::BI__builtin_ia32_selectw_256:
13068 case X86::BI__builtin_ia32_selectw_512:
13069 case X86::BI__builtin_ia32_selectd_128:
13070 case X86::BI__builtin_ia32_selectd_256:
13071 case X86::BI__builtin_ia32_selectd_512:
13072 case X86::BI__builtin_ia32_selectq_128:
13073 case X86::BI__builtin_ia32_selectq_256:
13074 case X86::BI__builtin_ia32_selectq_512:
13075 case X86::BI__builtin_ia32_selectph_128:
13076 case X86::BI__builtin_ia32_selectph_256:
13077 case X86::BI__builtin_ia32_selectph_512:
13078 case X86::BI__builtin_ia32_selectpbf_128:
13079 case X86::BI__builtin_ia32_selectpbf_256:
13080 case X86::BI__builtin_ia32_selectpbf_512:
13081 case X86::BI__builtin_ia32_selectps_128:
13082 case X86::BI__builtin_ia32_selectps_256:
13083 case X86::BI__builtin_ia32_selectps_512:
13084 case X86::BI__builtin_ia32_selectpd_128:
13085 case X86::BI__builtin_ia32_selectpd_256:
13086 case X86::BI__builtin_ia32_selectpd_512: {
13088 APValue SourceMask, SourceLHS, SourceRHS;
13097 ResultElements.reserve(SourceLen);
13099 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13102 ResultElements.push_back(Mask[EltNum] ? LHS : RHS);
13105 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13108 case X86::BI__builtin_ia32_cvtsd2ss: {
13121 Elements.push_back(ResultVal);
13124 for (
unsigned I = 1; I < NumEltsA; ++I) {
13130 case X86::BI__builtin_ia32_cvtsd2ss_round_mask: {
13131 APValue VecA, VecB, VecSrc, MaskValue;
13139 unsigned Mask = MaskValue.
getInt().getZExtValue();
13147 Elements.push_back(ResultVal);
13153 for (
unsigned I = 1; I < NumEltsA; ++I) {
13159 case X86::BI__builtin_ia32_cvtpd2ps:
13160 case X86::BI__builtin_ia32_cvtpd2ps256:
13161 case X86::BI__builtin_ia32_cvtpd2ps_mask:
13162 case X86::BI__builtin_ia32_cvtpd2ps512_mask: {
13165 bool IsMasked = (BuiltinID == X86::BI__builtin_ia32_cvtpd2ps_mask ||
13166 BuiltinID == X86::BI__builtin_ia32_cvtpd2ps512_mask);
13173 unsigned Mask = 0xFFFFFFFF;
13174 bool NeedsMerge =
false;
13179 Mask = MaskValue.
getInt().getZExtValue();
13180 auto NumEltsResult = E->
getType()->
getAs<VectorType>()->getNumElements();
13181 for (
unsigned I = 0; I < NumEltsResult; ++I) {
13182 if (!((Mask >> I) & 1)) {
13193 unsigned NumEltsResult =
13197 for (
unsigned I = 0; I < NumEltsResult; ++I) {
13198 if (IsMasked && !((Mask >> I) & 1)) {
13206 if (I >= NumEltsInput) {
13207 Elements.push_back(
APValue(APFloat::getZero(APFloat::IEEEsingle())));
13216 Elements.push_back(ResultVal);
13221 case X86::BI__builtin_ia32_shufps:
13222 case X86::BI__builtin_ia32_shufps256:
13223 case X86::BI__builtin_ia32_shufps512: {
13227 [](
unsigned DstIdx,
13228 unsigned ShuffleMask) -> std::pair<unsigned, int> {
13229 constexpr unsigned LaneBits = 128u;
13230 unsigned NumElemPerLane = LaneBits / 32;
13231 unsigned NumSelectableElems = NumElemPerLane / 2;
13232 unsigned BitsPerElem = 2;
13233 unsigned IndexMask = (1u << BitsPerElem) - 1;
13234 unsigned MaskBits = 8;
13235 unsigned Lane = DstIdx / NumElemPerLane;
13236 unsigned ElemInLane = DstIdx % NumElemPerLane;
13237 unsigned LaneOffset = Lane * NumElemPerLane;
13238 unsigned BitIndex = (DstIdx * BitsPerElem) % MaskBits;
13239 unsigned SrcIdx = (ElemInLane < NumSelectableElems) ? 0 : 1;
13240 unsigned Index = (ShuffleMask >> BitIndex) & IndexMask;
13241 return {SrcIdx,
static_cast<int>(LaneOffset + Index)};
13246 case X86::BI__builtin_ia32_shufpd:
13247 case X86::BI__builtin_ia32_shufpd256:
13248 case X86::BI__builtin_ia32_shufpd512: {
13252 [](
unsigned DstIdx,
13253 unsigned ShuffleMask) -> std::pair<unsigned, int> {
13254 constexpr unsigned LaneBits = 128u;
13255 unsigned NumElemPerLane = LaneBits / 64;
13256 unsigned NumSelectableElems = NumElemPerLane / 2;
13257 unsigned BitsPerElem = 1;
13258 unsigned IndexMask = (1u << BitsPerElem) - 1;
13259 unsigned MaskBits = 8;
13260 unsigned Lane = DstIdx / NumElemPerLane;
13261 unsigned ElemInLane = DstIdx % NumElemPerLane;
13262 unsigned LaneOffset = Lane * NumElemPerLane;
13263 unsigned BitIndex = (DstIdx * BitsPerElem) % MaskBits;
13264 unsigned SrcIdx = (ElemInLane < NumSelectableElems) ? 0 : 1;
13265 unsigned Index = (ShuffleMask >> BitIndex) & IndexMask;
13266 return {SrcIdx,
static_cast<int>(LaneOffset + Index)};
13271 case X86::BI__builtin_ia32_insertps128: {
13275 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13277 if ((Mask & (1 << DstIdx)) != 0) {
13282 unsigned SrcElem = (Mask >> 6) & 0x3;
13283 unsigned DstElem = (Mask >> 4) & 0x3;
13284 if (DstIdx == DstElem) {
13286 return {1,
static_cast<int>(SrcElem)};
13289 return {0,
static_cast<int>(DstIdx)};
13295 case X86::BI__builtin_ia32_pshufb128:
13296 case X86::BI__builtin_ia32_pshufb256:
13297 case X86::BI__builtin_ia32_pshufb512: {
13301 [](
unsigned DstIdx,
13302 unsigned ShuffleMask) -> std::pair<unsigned, int> {
13303 uint8_t Ctlb =
static_cast<uint8_t
>(ShuffleMask);
13305 return std::make_pair(0, -1);
13307 unsigned LaneBase = (DstIdx / 16) * 16;
13308 unsigned SrcOffset = Ctlb & 0x0F;
13309 unsigned SrcIdx = LaneBase + SrcOffset;
13310 return std::make_pair(0,
static_cast<int>(SrcIdx));
13316 case X86::BI__builtin_ia32_pshuflw:
13317 case X86::BI__builtin_ia32_pshuflw256:
13318 case X86::BI__builtin_ia32_pshuflw512: {
13322 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13323 constexpr unsigned LaneBits = 128u;
13324 constexpr unsigned ElemBits = 16u;
13325 constexpr unsigned LaneElts = LaneBits / ElemBits;
13326 constexpr unsigned HalfSize = 4;
13327 unsigned LaneBase = (DstIdx / LaneElts) * LaneElts;
13328 unsigned LaneIdx = DstIdx % LaneElts;
13329 if (LaneIdx < HalfSize) {
13330 unsigned Sel = (Mask >> (2 * LaneIdx)) & 0x3;
13331 return std::make_pair(0,
static_cast<int>(LaneBase + Sel));
13333 return std::make_pair(0,
static_cast<int>(DstIdx));
13339 case X86::BI__builtin_ia32_pshufhw:
13340 case X86::BI__builtin_ia32_pshufhw256:
13341 case X86::BI__builtin_ia32_pshufhw512: {
13345 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13346 constexpr unsigned LaneBits = 128u;
13347 constexpr unsigned ElemBits = 16u;
13348 constexpr unsigned LaneElts = LaneBits / ElemBits;
13349 constexpr unsigned HalfSize = 4;
13350 unsigned LaneBase = (DstIdx / LaneElts) * LaneElts;
13351 unsigned LaneIdx = DstIdx % LaneElts;
13352 if (LaneIdx >= HalfSize) {
13353 unsigned Rel = LaneIdx - HalfSize;
13354 unsigned Sel = (Mask >> (2 * Rel)) & 0x3;
13355 return std::make_pair(
13356 0,
static_cast<int>(LaneBase + HalfSize + Sel));
13358 return std::make_pair(0,
static_cast<int>(DstIdx));
13364 case X86::BI__builtin_ia32_pshufd:
13365 case X86::BI__builtin_ia32_pshufd256:
13366 case X86::BI__builtin_ia32_pshufd512:
13367 case X86::BI__builtin_ia32_vpermilps:
13368 case X86::BI__builtin_ia32_vpermilps256:
13369 case X86::BI__builtin_ia32_vpermilps512: {
13373 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13374 constexpr unsigned LaneBits = 128u;
13375 constexpr unsigned ElemBits = 32u;
13376 constexpr unsigned LaneElts = LaneBits / ElemBits;
13377 unsigned LaneBase = (DstIdx / LaneElts) * LaneElts;
13378 unsigned LaneIdx = DstIdx % LaneElts;
13379 unsigned Sel = (Mask >> (2 * LaneIdx)) & 0x3;
13380 return std::make_pair(0,
static_cast<int>(LaneBase + Sel));
13386 case X86::BI__builtin_ia32_vpermilvarpd:
13387 case X86::BI__builtin_ia32_vpermilvarpd256:
13388 case X86::BI__builtin_ia32_vpermilvarpd512: {
13392 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13393 unsigned NumElemPerLane = 2;
13394 unsigned Lane = DstIdx / NumElemPerLane;
13395 unsigned Offset = Mask & 0b10 ? 1 : 0;
13396 return std::make_pair(
13397 0,
static_cast<int>(Lane * NumElemPerLane + Offset));
13403 case X86::BI__builtin_ia32_vpermilpd:
13404 case X86::BI__builtin_ia32_vpermilpd256:
13405 case X86::BI__builtin_ia32_vpermilpd512: {
13408 unsigned NumElemPerLane = 2;
13409 unsigned BitsPerElem = 1;
13410 unsigned MaskBits = 8;
13411 unsigned IndexMask = 0x1;
13412 unsigned Lane = DstIdx / NumElemPerLane;
13413 unsigned LaneOffset = Lane * NumElemPerLane;
13414 unsigned BitIndex = (DstIdx * BitsPerElem) % MaskBits;
13415 unsigned Index = (Control >> BitIndex) & IndexMask;
13416 return std::make_pair(0,
static_cast<int>(LaneOffset + Index));
13422 case X86::BI__builtin_ia32_permdf256:
13423 case X86::BI__builtin_ia32_permdi256: {
13428 unsigned Index = (Control >> (2 * DstIdx)) & 0x3;
13429 return std::make_pair(0,
static_cast<int>(Index));
13435 case X86::BI__builtin_ia32_vpermilvarps:
13436 case X86::BI__builtin_ia32_vpermilvarps256:
13437 case X86::BI__builtin_ia32_vpermilvarps512: {
13441 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13442 unsigned NumElemPerLane = 4;
13443 unsigned Lane = DstIdx / NumElemPerLane;
13444 unsigned Offset = Mask & 0b11;
13445 return std::make_pair(
13446 0,
static_cast<int>(Lane * NumElemPerLane + Offset));
13452 case X86::BI__builtin_ia32_vpmultishiftqb128:
13453 case X86::BI__builtin_ia32_vpmultishiftqb256:
13454 case X86::BI__builtin_ia32_vpmultishiftqb512: {
13462 unsigned NumBytesInQWord = 8;
13463 unsigned NumBitsInByte = 8;
13465 unsigned NumQWords = NumBytes / NumBytesInQWord;
13467 Result.reserve(NumBytes);
13469 for (
unsigned QWordId = 0; QWordId != NumQWords; ++QWordId) {
13470 APInt BQWord(64, 0);
13471 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
13472 unsigned Idx = QWordId * NumBytesInQWord + ByteIdx;
13474 BQWord.insertBits(
APInt(8, Byte & 0xFF), ByteIdx * NumBitsInByte);
13477 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
13478 unsigned Idx = QWordId * NumBytesInQWord + ByteIdx;
13482 for (
unsigned BitIdx = 0; BitIdx != NumBitsInByte; ++BitIdx) {
13483 Byte.setBitVal(BitIdx, BQWord[(Ctrl + BitIdx) & 0x3F]);
13491 case X86::BI__builtin_ia32_phminposuw128: {
13498 unsigned ElemBitWidth = Info.Ctx.getTypeSize(ElemQT);
13500 APInt MinIndex(ElemBitWidth, 0);
13502 for (
unsigned I = 1; I != SourceLen; ++I) {
13504 if (MinVal.ugt(Val)) {
13513 ->isUnsignedIntegerOrEnumerationType();
13516 Result.reserve(SourceLen);
13518 Result.emplace_back(
APSInt(MinIndex, ResultUnsigned));
13519 for (
unsigned I = 0; I != SourceLen - 2; ++I) {
13525 case X86::BI__builtin_ia32_psraq128:
13526 case X86::BI__builtin_ia32_psraq256:
13527 case X86::BI__builtin_ia32_psraq512:
13528 case X86::BI__builtin_ia32_psrad128:
13529 case X86::BI__builtin_ia32_psrad256:
13530 case X86::BI__builtin_ia32_psrad512:
13531 case X86::BI__builtin_ia32_psraw128:
13532 case X86::BI__builtin_ia32_psraw256:
13533 case X86::BI__builtin_ia32_psraw512: {
13537 [](
const APInt &Elt, uint64_t Count) {
return Elt.ashr(Count); },
13538 [](
const APInt &Elt,
unsigned Width) {
13539 return Elt.ashr(Width - 1);
13545 case X86::BI__builtin_ia32_psllq128:
13546 case X86::BI__builtin_ia32_psllq256:
13547 case X86::BI__builtin_ia32_psllq512:
13548 case X86::BI__builtin_ia32_pslld128:
13549 case X86::BI__builtin_ia32_pslld256:
13550 case X86::BI__builtin_ia32_pslld512:
13551 case X86::BI__builtin_ia32_psllw128:
13552 case X86::BI__builtin_ia32_psllw256:
13553 case X86::BI__builtin_ia32_psllw512: {
13557 [](
const APInt &Elt, uint64_t Count) {
return Elt.shl(Count); },
13558 [](
const APInt &Elt,
unsigned Width) {
13559 return APInt::getZero(Width);
13565 case X86::BI__builtin_ia32_psrlq128:
13566 case X86::BI__builtin_ia32_psrlq256:
13567 case X86::BI__builtin_ia32_psrlq512:
13568 case X86::BI__builtin_ia32_psrld128:
13569 case X86::BI__builtin_ia32_psrld256:
13570 case X86::BI__builtin_ia32_psrld512:
13571 case X86::BI__builtin_ia32_psrlw128:
13572 case X86::BI__builtin_ia32_psrlw256:
13573 case X86::BI__builtin_ia32_psrlw512: {
13577 [](
const APInt &Elt, uint64_t Count) {
return Elt.lshr(Count); },
13578 [](
const APInt &Elt,
unsigned Width) {
13579 return APInt::getZero(Width);
13585 case X86::BI__builtin_ia32_pternlogd128_mask:
13586 case X86::BI__builtin_ia32_pternlogd256_mask:
13587 case X86::BI__builtin_ia32_pternlogd512_mask:
13588 case X86::BI__builtin_ia32_pternlogq128_mask:
13589 case X86::BI__builtin_ia32_pternlogq256_mask:
13590 case X86::BI__builtin_ia32_pternlogq512_mask: {
13591 APValue AValue, BValue, CValue, ImmValue, UValue;
13599 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13605 ResultElements.reserve(ResultLen);
13607 for (
unsigned EltNum = 0; EltNum < ResultLen; ++EltNum) {
13613 unsigned BitWidth = ALane.getBitWidth();
13614 APInt ResLane(BitWidth, 0);
13616 for (
unsigned Bit = 0; Bit < BitWidth; ++Bit) {
13617 unsigned ABit = ALane[Bit];
13618 unsigned BBit = BLane[Bit];
13619 unsigned CBit = CLane[Bit];
13621 unsigned Idx = (ABit << 2) | (BBit << 1) | CBit;
13622 ResLane.setBitVal(Bit, Imm[Idx]);
13624 ResultElements.push_back(
APValue(
APSInt(ResLane, DestUnsigned)));
13626 ResultElements.push_back(
APValue(
APSInt(ALane, DestUnsigned)));
13629 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13631 case X86::BI__builtin_ia32_pternlogd128_maskz:
13632 case X86::BI__builtin_ia32_pternlogd256_maskz:
13633 case X86::BI__builtin_ia32_pternlogd512_maskz:
13634 case X86::BI__builtin_ia32_pternlogq128_maskz:
13635 case X86::BI__builtin_ia32_pternlogq256_maskz:
13636 case X86::BI__builtin_ia32_pternlogq512_maskz: {
13637 APValue AValue, BValue, CValue, ImmValue, UValue;
13645 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13651 ResultElements.reserve(ResultLen);
13653 for (
unsigned EltNum = 0; EltNum < ResultLen; ++EltNum) {
13658 unsigned BitWidth = ALane.getBitWidth();
13659 APInt ResLane(BitWidth, 0);
13662 for (
unsigned Bit = 0; Bit < BitWidth; ++Bit) {
13663 unsigned ABit = ALane[Bit];
13664 unsigned BBit = BLane[Bit];
13665 unsigned CBit = CLane[Bit];
13667 unsigned Idx = (ABit << 2) | (BBit << 1) | CBit;
13668 ResLane.setBitVal(Bit, Imm[Idx]);
13671 ResultElements.push_back(
APValue(
APSInt(ResLane, DestUnsigned)));
13673 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13676 case Builtin::BI__builtin_elementwise_clzg:
13677 case Builtin::BI__builtin_elementwise_ctzg: {
13679 std::optional<APValue> Fallback;
13686 Fallback = FallbackTmp;
13689 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13692 ResultElements.reserve(SourceLen);
13694 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13699 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
13701 Builtin::BI__builtin_elementwise_ctzg);
13704 ResultElements.push_back(Fallback->getVectorElt(EltNum));
13708 case Builtin::BI__builtin_elementwise_clzg:
13709 ResultElements.push_back(
APValue(
13710 APSInt(
APInt(Info.Ctx.getIntWidth(DestEltTy), LHS.countl_zero()),
13713 case Builtin::BI__builtin_elementwise_ctzg:
13714 ResultElements.push_back(
APValue(
13715 APSInt(
APInt(Info.Ctx.getIntWidth(DestEltTy), LHS.countr_zero()),
13721 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13724 case Builtin::BI__builtin_elementwise_fma: {
13725 APValue SourceX, SourceY, SourceZ;
13733 ResultElements.reserve(SourceLen);
13735 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13740 (void)
Result.fusedMultiplyAdd(Y, Z, RM);
13743 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13746 case clang::X86::BI__builtin_ia32_phaddw128:
13747 case clang::X86::BI__builtin_ia32_phaddw256:
13748 case clang::X86::BI__builtin_ia32_phaddd128:
13749 case clang::X86::BI__builtin_ia32_phaddd256:
13750 case clang::X86::BI__builtin_ia32_phaddsw128:
13751 case clang::X86::BI__builtin_ia32_phaddsw256:
13753 case clang::X86::BI__builtin_ia32_phsubw128:
13754 case clang::X86::BI__builtin_ia32_phsubw256:
13755 case clang::X86::BI__builtin_ia32_phsubd128:
13756 case clang::X86::BI__builtin_ia32_phsubd256:
13757 case clang::X86::BI__builtin_ia32_phsubsw128:
13758 case clang::X86::BI__builtin_ia32_phsubsw256: {
13759 APValue SourceLHS, SourceRHS;
13763 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13767 unsigned EltBits = Info.Ctx.getIntWidth(DestEltTy);
13768 unsigned EltsPerLane = 128 / EltBits;
13770 ResultElements.reserve(NumElts);
13772 for (
unsigned LaneStart = 0; LaneStart != NumElts;
13773 LaneStart += EltsPerLane) {
13774 for (
unsigned I = 0; I != EltsPerLane; I += 2) {
13778 case clang::X86::BI__builtin_ia32_phaddw128:
13779 case clang::X86::BI__builtin_ia32_phaddw256:
13780 case clang::X86::BI__builtin_ia32_phaddd128:
13781 case clang::X86::BI__builtin_ia32_phaddd256: {
13782 APSInt Res(LHSA + LHSB, DestUnsigned);
13783 ResultElements.push_back(
APValue(Res));
13786 case clang::X86::BI__builtin_ia32_phaddsw128:
13787 case clang::X86::BI__builtin_ia32_phaddsw256: {
13788 APSInt Res(LHSA.sadd_sat(LHSB));
13789 ResultElements.push_back(
APValue(Res));
13792 case clang::X86::BI__builtin_ia32_phsubw128:
13793 case clang::X86::BI__builtin_ia32_phsubw256:
13794 case clang::X86::BI__builtin_ia32_phsubd128:
13795 case clang::X86::BI__builtin_ia32_phsubd256: {
13796 APSInt Res(LHSA - LHSB, DestUnsigned);
13797 ResultElements.push_back(
APValue(Res));
13800 case clang::X86::BI__builtin_ia32_phsubsw128:
13801 case clang::X86::BI__builtin_ia32_phsubsw256: {
13802 APSInt Res(LHSA.ssub_sat(LHSB));
13803 ResultElements.push_back(
APValue(Res));
13808 for (
unsigned I = 0; I != EltsPerLane; I += 2) {
13812 case clang::X86::BI__builtin_ia32_phaddw128:
13813 case clang::X86::BI__builtin_ia32_phaddw256:
13814 case clang::X86::BI__builtin_ia32_phaddd128:
13815 case clang::X86::BI__builtin_ia32_phaddd256: {
13816 APSInt Res(RHSA + RHSB, DestUnsigned);
13817 ResultElements.push_back(
APValue(Res));
13820 case clang::X86::BI__builtin_ia32_phaddsw128:
13821 case clang::X86::BI__builtin_ia32_phaddsw256: {
13822 APSInt Res(RHSA.sadd_sat(RHSB));
13823 ResultElements.push_back(
APValue(Res));
13826 case clang::X86::BI__builtin_ia32_phsubw128:
13827 case clang::X86::BI__builtin_ia32_phsubw256:
13828 case clang::X86::BI__builtin_ia32_phsubd128:
13829 case clang::X86::BI__builtin_ia32_phsubd256: {
13830 APSInt Res(RHSA - RHSB, DestUnsigned);
13831 ResultElements.push_back(
APValue(Res));
13834 case clang::X86::BI__builtin_ia32_phsubsw128:
13835 case clang::X86::BI__builtin_ia32_phsubsw256: {
13836 APSInt Res(RHSA.ssub_sat(RHSB));
13837 ResultElements.push_back(
APValue(Res));
13843 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13845 case clang::X86::BI__builtin_ia32_haddpd:
13846 case clang::X86::BI__builtin_ia32_haddps:
13847 case clang::X86::BI__builtin_ia32_haddps256:
13848 case clang::X86::BI__builtin_ia32_haddpd256:
13849 case clang::X86::BI__builtin_ia32_hsubpd:
13850 case clang::X86::BI__builtin_ia32_hsubps:
13851 case clang::X86::BI__builtin_ia32_hsubps256:
13852 case clang::X86::BI__builtin_ia32_hsubpd256: {
13853 APValue SourceLHS, SourceRHS;
13859 ResultElements.reserve(NumElts);
13861 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13862 unsigned EltBits = Info.Ctx.getTypeSize(DestEltTy);
13863 unsigned NumLanes = NumElts * EltBits / 128;
13864 unsigned NumElemsPerLane = NumElts / NumLanes;
13865 unsigned HalfElemsPerLane = NumElemsPerLane / 2;
13867 for (
unsigned L = 0; L != NumElts; L += NumElemsPerLane) {
13868 for (
unsigned I = 0; I != HalfElemsPerLane; ++I) {
13872 case clang::X86::BI__builtin_ia32_haddpd:
13873 case clang::X86::BI__builtin_ia32_haddps:
13874 case clang::X86::BI__builtin_ia32_haddps256:
13875 case clang::X86::BI__builtin_ia32_haddpd256:
13876 LHSA.add(LHSB, RM);
13878 case clang::X86::BI__builtin_ia32_hsubpd:
13879 case clang::X86::BI__builtin_ia32_hsubps:
13880 case clang::X86::BI__builtin_ia32_hsubps256:
13881 case clang::X86::BI__builtin_ia32_hsubpd256:
13882 LHSA.subtract(LHSB, RM);
13885 ResultElements.push_back(
APValue(LHSA));
13887 for (
unsigned I = 0; I != HalfElemsPerLane; ++I) {
13891 case clang::X86::BI__builtin_ia32_haddpd:
13892 case clang::X86::BI__builtin_ia32_haddps:
13893 case clang::X86::BI__builtin_ia32_haddps256:
13894 case clang::X86::BI__builtin_ia32_haddpd256:
13895 RHSA.add(RHSB, RM);
13897 case clang::X86::BI__builtin_ia32_hsubpd:
13898 case clang::X86::BI__builtin_ia32_hsubps:
13899 case clang::X86::BI__builtin_ia32_hsubps256:
13900 case clang::X86::BI__builtin_ia32_hsubpd256:
13901 RHSA.subtract(RHSB, RM);
13904 ResultElements.push_back(
APValue(RHSA));
13907 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13909 case clang::X86::BI__builtin_ia32_addsubpd:
13910 case clang::X86::BI__builtin_ia32_addsubps:
13911 case clang::X86::BI__builtin_ia32_addsubpd256:
13912 case clang::X86::BI__builtin_ia32_addsubps256: {
13915 APValue SourceLHS, SourceRHS;
13921 ResultElements.reserve(NumElems);
13924 for (
unsigned I = 0; I != NumElems; ++I) {
13929 LHS.subtract(RHS, RM);
13934 ResultElements.push_back(
APValue(LHS));
13936 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13938 case clang::X86::BI__builtin_ia32_pclmulqdq128:
13939 case clang::X86::BI__builtin_ia32_pclmulqdq256:
13940 case clang::X86::BI__builtin_ia32_pclmulqdq512: {
13944 APValue SourceLHS, SourceRHS;
13954 bool SelectUpperA = (Imm8 & 0x01) != 0;
13955 bool SelectUpperB = (Imm8 & 0x10) != 0;
13959 ResultElements.reserve(NumElems);
13960 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13964 for (
unsigned Lane = 0; Lane < NumElems; Lane += 2) {
13973 APInt A = SelectUpperA ? A1 : A0;
13974 APInt B = SelectUpperB ? B1 : B0;
13977 APInt A128 = A.zext(128);
13978 APInt B128 = B.zext(128);
13981 APInt Result = llvm::APIntOps::clmul(A128, B128);
13984 APSInt ResultLow(
Result.extractBits(64, 0), DestUnsigned);
13985 APSInt ResultHigh(
Result.extractBits(64, 64), DestUnsigned);
13987 ResultElements.push_back(
APValue(ResultLow));
13988 ResultElements.push_back(
APValue(ResultHigh));
13991 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13993 case Builtin::BI__builtin_elementwise_fshl:
13994 case Builtin::BI__builtin_elementwise_fshr: {
13995 APValue SourceHi, SourceLo, SourceShift;
14001 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14007 ResultElements.reserve(SourceLen);
14008 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
14013 case Builtin::BI__builtin_elementwise_fshl:
14014 ResultElements.push_back(
APValue(
14015 APSInt(llvm::APIntOps::fshl(Hi, Lo, Shift), Hi.isUnsigned())));
14017 case Builtin::BI__builtin_elementwise_fshr:
14018 ResultElements.push_back(
APValue(
14019 APSInt(llvm::APIntOps::fshr(Hi, Lo, Shift), Hi.isUnsigned())));
14024 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14027 case X86::BI__builtin_ia32_shuf_f32x4_256:
14028 case X86::BI__builtin_ia32_shuf_i32x4_256:
14029 case X86::BI__builtin_ia32_shuf_f64x2_256:
14030 case X86::BI__builtin_ia32_shuf_i64x2_256:
14031 case X86::BI__builtin_ia32_shuf_f32x4:
14032 case X86::BI__builtin_ia32_shuf_i32x4:
14033 case X86::BI__builtin_ia32_shuf_f64x2:
14034 case X86::BI__builtin_ia32_shuf_i64x2: {
14048 unsigned ElemBits = Info.Ctx.getTypeSize(ElemQT);
14049 unsigned LaneBits = 128u;
14050 unsigned NumLanes = (NumElems * ElemBits) / LaneBits;
14051 unsigned NumElemsPerLane = LaneBits / ElemBits;
14055 ResultElements.reserve(DstLen);
14060 [NumLanes, NumElemsPerLane](
unsigned DstIdx,
unsigned ShuffleMask)
14061 -> std::pair<unsigned, int> {
14063 unsigned BitsPerElem = NumLanes / 2;
14064 unsigned IndexMask = (1u << BitsPerElem) - 1;
14065 unsigned Lane = DstIdx / NumElemsPerLane;
14066 unsigned SrcIdx = (Lane < NumLanes / 2) ? 0 : 1;
14067 unsigned BitIdx = BitsPerElem * Lane;
14068 unsigned SrcLaneIdx = (ShuffleMask >> BitIdx) & IndexMask;
14069 unsigned ElemInLane = DstIdx % NumElemsPerLane;
14070 unsigned IdxToPick = SrcLaneIdx * NumElemsPerLane + ElemInLane;
14071 return {SrcIdx, IdxToPick};
14077 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v16qi:
14078 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v32qi:
14079 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v64qi:
14080 case X86::BI__builtin_ia32_vgf2p8affineqb_v16qi:
14081 case X86::BI__builtin_ia32_vgf2p8affineqb_v32qi:
14082 case X86::BI__builtin_ia32_vgf2p8affineqb_v64qi: {
14094 bool IsInverse =
false;
14096 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v16qi:
14097 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v32qi:
14098 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v64qi: {
14103 unsigned NumBitsInByte = 8;
14104 unsigned NumBytesInQWord = 8;
14105 unsigned NumBitsInQWord = 64;
14107 unsigned NumQWords = NumBytes / NumBytesInQWord;
14109 Result.reserve(NumBytes);
14112 for (
unsigned QWordIdx = 0; QWordIdx != NumQWords; ++QWordIdx) {
14114 APInt XQWord(NumBitsInQWord, 0);
14115 APInt AQWord(NumBitsInQWord, 0);
14116 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
14117 unsigned Idx = QWordIdx * NumBytesInQWord + ByteIdx;
14118 APInt XByte =
X.getVectorElt(Idx).getInt();
14120 XQWord.insertBits(XByte, ByteIdx * NumBitsInByte);
14121 AQWord.insertBits(AByte, ByteIdx * NumBitsInByte);
14124 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
14126 XQWord.lshr(ByteIdx * NumBitsInByte).getLoBits(8).getZExtValue();
14135 case X86::BI__builtin_ia32_vgf2p8mulb_v16qi:
14136 case X86::BI__builtin_ia32_vgf2p8mulb_v32qi:
14137 case X86::BI__builtin_ia32_vgf2p8mulb_v64qi: {
14148 Result.reserve(NumBytes);
14150 for (
unsigned ByteIdx = 0; ByteIdx != NumBytes; ++ByteIdx) {
14160 case X86::BI__builtin_ia32_insertf32x4_256:
14161 case X86::BI__builtin_ia32_inserti32x4_256:
14162 case X86::BI__builtin_ia32_insertf64x2_256:
14163 case X86::BI__builtin_ia32_inserti64x2_256:
14164 case X86::BI__builtin_ia32_insertf32x4:
14165 case X86::BI__builtin_ia32_inserti32x4:
14166 case X86::BI__builtin_ia32_insertf64x2_512:
14167 case X86::BI__builtin_ia32_inserti64x2_512:
14168 case X86::BI__builtin_ia32_insertf32x8:
14169 case X86::BI__builtin_ia32_inserti32x8:
14170 case X86::BI__builtin_ia32_insertf64x4:
14171 case X86::BI__builtin_ia32_inserti64x4:
14172 case X86::BI__builtin_ia32_vinsertf128_ps256:
14173 case X86::BI__builtin_ia32_vinsertf128_pd256:
14174 case X86::BI__builtin_ia32_vinsertf128_si256:
14175 case X86::BI__builtin_ia32_insert128i256: {
14176 APValue SourceDst, SourceSub;
14188 assert(SubLen != 0 && DstLen != 0 && (DstLen % SubLen) == 0);
14189 unsigned NumLanes = DstLen / SubLen;
14190 unsigned LaneIdx = (Imm.getZExtValue() % NumLanes) * SubLen;
14193 ResultElements.reserve(DstLen);
14195 for (
unsigned EltNum = 0; EltNum < DstLen; ++EltNum) {
14196 if (EltNum >= LaneIdx && EltNum < LaneIdx + SubLen)
14197 ResultElements.push_back(SourceSub.
getVectorElt(EltNum - LaneIdx));
14199 ResultElements.push_back(SourceDst.
getVectorElt(EltNum));
14202 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14205 case clang::X86::BI__builtin_ia32_vec_set_v4hi:
14206 case clang::X86::BI__builtin_ia32_vec_set_v16qi:
14207 case clang::X86::BI__builtin_ia32_vec_set_v8hi:
14208 case clang::X86::BI__builtin_ia32_vec_set_v4si:
14209 case clang::X86::BI__builtin_ia32_vec_set_v2di:
14210 case clang::X86::BI__builtin_ia32_vec_set_v32qi:
14211 case clang::X86::BI__builtin_ia32_vec_set_v16hi:
14212 case clang::X86::BI__builtin_ia32_vec_set_v8si:
14213 case clang::X86::BI__builtin_ia32_vec_set_v4di: {
14221 QualType ElemTy = E->
getType()->
castAs<VectorType>()->getElementType();
14222 unsigned ElemWidth = Info.Ctx.getIntWidth(ElemTy);
14224 Scalar.setIsUnsigned(ElemUnsigned);
14230 static_cast<unsigned>(IndexAPS.getZExtValue() & (NumElems - 1));
14233 Elems.reserve(NumElems);
14234 for (
unsigned ElemNum = 0; ElemNum != NumElems; ++ElemNum)
14235 Elems.push_back(ElemNum == Index ? ElemAV : VecVal.
getVectorElt(ElemNum));
14240 case X86::BI__builtin_ia32_pslldqi128_byteshift:
14241 case X86::BI__builtin_ia32_pslldqi256_byteshift:
14242 case X86::BI__builtin_ia32_pslldqi512_byteshift: {
14246 [](
unsigned DstIdx,
unsigned Shift) -> std::pair<unsigned, int> {
14247 unsigned LaneBase = (DstIdx / 16) * 16;
14248 unsigned LaneIdx = DstIdx % 16;
14249 if (LaneIdx < Shift)
14250 return std::make_pair(0, -1);
14252 return std::make_pair(
14253 0,
static_cast<int>(LaneBase + LaneIdx - Shift));
14259 case X86::BI__builtin_ia32_psrldqi128_byteshift:
14260 case X86::BI__builtin_ia32_psrldqi256_byteshift:
14261 case X86::BI__builtin_ia32_psrldqi512_byteshift: {
14265 [](
unsigned DstIdx,
unsigned Shift) -> std::pair<unsigned, int> {
14266 unsigned LaneBase = (DstIdx / 16) * 16;
14267 unsigned LaneIdx = DstIdx % 16;
14268 if (LaneIdx + Shift < 16)
14269 return std::make_pair(
14270 0,
static_cast<int>(LaneBase + LaneIdx + Shift));
14272 return std::make_pair(0, -1);
14278 case X86::BI__builtin_ia32_palignr128:
14279 case X86::BI__builtin_ia32_palignr256:
14280 case X86::BI__builtin_ia32_palignr512: {
14284 unsigned VecIdx = 1;
14287 int Lane = DstIdx / 16;
14288 int Offset = DstIdx % 16;
14291 unsigned ShiftedIdx = Offset + (
Shift & 0xFF);
14292 if (ShiftedIdx < 16) {
14293 ElemIdx = ShiftedIdx + (Lane * 16);
14294 }
else if (ShiftedIdx < 32) {
14296 ElemIdx = (ShiftedIdx - 16) + (Lane * 16);
14299 return std::pair<unsigned, int>{VecIdx, ElemIdx};
14304 case X86::BI__builtin_ia32_alignd128:
14305 case X86::BI__builtin_ia32_alignd256:
14306 case X86::BI__builtin_ia32_alignd512:
14307 case X86::BI__builtin_ia32_alignq128:
14308 case X86::BI__builtin_ia32_alignq256:
14309 case X86::BI__builtin_ia32_alignq512: {
14311 unsigned NumElems = E->
getType()->
castAs<VectorType>()->getNumElements();
14313 [NumElems](
unsigned DstIdx,
unsigned Shift) {
14314 unsigned Imm =
Shift & 0xFF;
14315 unsigned EffectiveShift = Imm & (NumElems - 1);
14316 unsigned SourcePos = DstIdx + EffectiveShift;
14317 unsigned VecIdx = SourcePos < NumElems ? 1 : 0;
14318 unsigned ElemIdx = SourcePos & (NumElems - 1);
14320 return std::pair<unsigned, int>{
14321 VecIdx,
static_cast<int>(ElemIdx)};
14326 case X86::BI__builtin_ia32_permvarsi256:
14327 case X86::BI__builtin_ia32_permvarsf256:
14328 case X86::BI__builtin_ia32_permvardf512:
14329 case X86::BI__builtin_ia32_permvardi512:
14330 case X86::BI__builtin_ia32_permvarhi128: {
14333 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14334 int Offset = ShuffleMask & 0x7;
14335 return std::pair<unsigned, int>{0, Offset};
14340 case X86::BI__builtin_ia32_permvarqi128:
14341 case X86::BI__builtin_ia32_permvarhi256:
14342 case X86::BI__builtin_ia32_permvarsi512:
14343 case X86::BI__builtin_ia32_permvarsf512: {
14346 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14347 int Offset = ShuffleMask & 0xF;
14348 return std::pair<unsigned, int>{0, Offset};
14353 case X86::BI__builtin_ia32_permvardi256:
14354 case X86::BI__builtin_ia32_permvardf256: {
14357 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14358 int Offset = ShuffleMask & 0x3;
14359 return std::pair<unsigned, int>{0, Offset};
14364 case X86::BI__builtin_ia32_permvarqi256:
14365 case X86::BI__builtin_ia32_permvarhi512: {
14368 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14369 int Offset = ShuffleMask & 0x1F;
14370 return std::pair<unsigned, int>{0, Offset};
14375 case X86::BI__builtin_ia32_permvarqi512: {
14378 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14379 int Offset = ShuffleMask & 0x3F;
14380 return std::pair<unsigned, int>{0, Offset};
14385 case X86::BI__builtin_ia32_vpermi2varq128:
14386 case X86::BI__builtin_ia32_vpermi2varpd128: {
14389 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14390 int Offset = ShuffleMask & 0x1;
14391 unsigned SrcIdx = (ShuffleMask >> 1) & 0x1;
14392 return std::pair<unsigned, int>{SrcIdx, Offset};
14397 case X86::BI__builtin_ia32_vpermi2vard128:
14398 case X86::BI__builtin_ia32_vpermi2varps128:
14399 case X86::BI__builtin_ia32_vpermi2varq256:
14400 case X86::BI__builtin_ia32_vpermi2varpd256: {
14403 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14404 int Offset = ShuffleMask & 0x3;
14405 unsigned SrcIdx = (ShuffleMask >> 2) & 0x1;
14406 return std::pair<unsigned, int>{SrcIdx, Offset};
14411 case X86::BI__builtin_ia32_vpermi2varhi128:
14412 case X86::BI__builtin_ia32_vpermi2vard256:
14413 case X86::BI__builtin_ia32_vpermi2varps256:
14414 case X86::BI__builtin_ia32_vpermi2varq512:
14415 case X86::BI__builtin_ia32_vpermi2varpd512: {
14418 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14419 int Offset = ShuffleMask & 0x7;
14420 unsigned SrcIdx = (ShuffleMask >> 3) & 0x1;
14421 return std::pair<unsigned, int>{SrcIdx, Offset};
14426 case X86::BI__builtin_ia32_vpermi2varqi128:
14427 case X86::BI__builtin_ia32_vpermi2varhi256:
14428 case X86::BI__builtin_ia32_vpermi2vard512:
14429 case X86::BI__builtin_ia32_vpermi2varps512: {
14432 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14433 int Offset = ShuffleMask & 0xF;
14434 unsigned SrcIdx = (ShuffleMask >> 4) & 0x1;
14435 return std::pair<unsigned, int>{SrcIdx, Offset};
14440 case X86::BI__builtin_ia32_vpermi2varqi256:
14441 case X86::BI__builtin_ia32_vpermi2varhi512: {
14444 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14445 int Offset = ShuffleMask & 0x1F;
14446 unsigned SrcIdx = (ShuffleMask >> 5) & 0x1;
14447 return std::pair<unsigned, int>{SrcIdx, Offset};
14452 case X86::BI__builtin_ia32_vpermi2varqi512: {
14455 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14456 int Offset = ShuffleMask & 0x3F;
14457 unsigned SrcIdx = (ShuffleMask >> 6) & 0x1;
14458 return std::pair<unsigned, int>{SrcIdx, Offset};
14464 case clang::X86::BI__builtin_ia32_minps:
14465 case clang::X86::BI__builtin_ia32_minpd:
14466 case clang::X86::BI__builtin_ia32_minps256:
14467 case clang::X86::BI__builtin_ia32_minpd256:
14468 case clang::X86::BI__builtin_ia32_minps512:
14469 case clang::X86::BI__builtin_ia32_minpd512:
14470 case clang::X86::BI__builtin_ia32_minph128:
14471 case clang::X86::BI__builtin_ia32_minph256:
14472 case clang::X86::BI__builtin_ia32_minph512:
14473 return EvaluateFpBinOpExpr(
14474 [](
const APFloat &A,
const APFloat &B,
14475 std::optional<APSInt>) -> std::optional<APFloat> {
14476 if (A.isNaN() || A.isInfinity() || A.isDenormal() || B.isNaN() ||
14477 B.isInfinity() || B.isDenormal())
14478 return std::nullopt;
14479 if (A.isZero() && B.isZero())
14481 return llvm::minimum(A, B);
14484 case clang::X86::BI__builtin_ia32_minss:
14485 case clang::X86::BI__builtin_ia32_minsd:
14486 return EvaluateFpBinOpExpr(
14487 [](
const APFloat &A,
const APFloat &B,
14488 std::optional<APSInt> RoundingMode) -> std::optional<APFloat> {
14493 case clang::X86::BI__builtin_ia32_minsd_round_mask:
14494 case clang::X86::BI__builtin_ia32_minss_round_mask:
14495 case clang::X86::BI__builtin_ia32_minsh_round_mask:
14496 case clang::X86::BI__builtin_ia32_maxsd_round_mask:
14497 case clang::X86::BI__builtin_ia32_maxss_round_mask:
14498 case clang::X86::BI__builtin_ia32_maxsh_round_mask: {
14501 clang::X86::BI__builtin_ia32_minsd_round_mask ||
14503 clang::X86::BI__builtin_ia32_minss_round_mask ||
14505 return EvaluateScalarFpRoundMaskBinOp(
14506 [IsMin](
const APFloat &A,
const APFloat &B,
14507 std::optional<APSInt> RoundingMode) -> std::optional<APFloat> {
14512 case clang::X86::BI__builtin_ia32_maxps:
14513 case clang::X86::BI__builtin_ia32_maxpd:
14514 case clang::X86::BI__builtin_ia32_maxps256:
14515 case clang::X86::BI__builtin_ia32_maxpd256:
14516 case clang::X86::BI__builtin_ia32_maxps512:
14517 case clang::X86::BI__builtin_ia32_maxpd512:
14518 case clang::X86::BI__builtin_ia32_maxph128:
14519 case clang::X86::BI__builtin_ia32_maxph256:
14520 case clang::X86::BI__builtin_ia32_maxph512:
14521 return EvaluateFpBinOpExpr(
14522 [](
const APFloat &A,
const APFloat &B,
14523 std::optional<APSInt>) -> std::optional<APFloat> {
14524 if (A.isNaN() || A.isInfinity() || A.isDenormal() || B.isNaN() ||
14525 B.isInfinity() || B.isDenormal())
14526 return std::nullopt;
14527 if (A.isZero() && B.isZero())
14529 return llvm::maximum(A, B);
14532 case clang::X86::BI__builtin_ia32_maxss:
14533 case clang::X86::BI__builtin_ia32_maxsd:
14534 return EvaluateFpBinOpExpr(
14535 [](
const APFloat &A,
const APFloat &B,
14536 std::optional<APSInt> RoundingMode) -> std::optional<APFloat> {
14541 case clang::X86::BI__builtin_ia32_vcvtps2ph:
14542 case clang::X86::BI__builtin_ia32_vcvtps2ph256: {
14552 unsigned SrcNumElems = SrcVTy->getNumElements();
14554 unsigned DstNumElems = DstVTy->getNumElements();
14555 QualType DstElemTy = DstVTy->getElementType();
14557 const llvm::fltSemantics &HalfSem =
14558 Info.Ctx.getFloatTypeSemantics(Info.Ctx.HalfTy);
14560 int ImmVal = Imm.getZExtValue();
14561 bool UseMXCSR = (ImmVal & 4) != 0;
14562 bool IsFPConstrained =
14565 llvm::RoundingMode RM;
14567 switch (ImmVal & 3) {
14569 RM = llvm::RoundingMode::NearestTiesToEven;
14572 RM = llvm::RoundingMode::TowardNegative;
14575 RM = llvm::RoundingMode::TowardPositive;
14578 RM = llvm::RoundingMode::TowardZero;
14581 llvm_unreachable(
"Invalid immediate rounding mode");
14584 RM = llvm::RoundingMode::NearestTiesToEven;
14588 ResultElements.reserve(DstNumElems);
14590 for (
unsigned I = 0; I < SrcNumElems; ++I) {
14594 APFloat::opStatus St = SrcVal.convert(HalfSem, RM, &LostInfo);
14596 if (UseMXCSR && IsFPConstrained && St != APFloat::opOK) {
14597 Info.FFDiag(E, diag::note_constexpr_dynamic_rounding);
14601 APSInt DstInt(SrcVal.bitcastToAPInt(),
14603 ResultElements.push_back(
APValue(DstInt));
14606 if (DstNumElems > SrcNumElems) {
14607 APSInt Zero = Info.Ctx.MakeIntValue(0, DstElemTy);
14608 for (
unsigned I = SrcNumElems; I < DstNumElems; ++I) {
14613 return Success(ResultElements, E);
14615 case X86::BI__builtin_ia32_vperm2f128_pd256:
14616 case X86::BI__builtin_ia32_vperm2f128_ps256:
14617 case X86::BI__builtin_ia32_vperm2f128_si256:
14618 case X86::BI__builtin_ia32_permti256: {
14619 unsigned NumElements =
14621 unsigned PreservedBitsCnt = NumElements >> 2;
14625 [PreservedBitsCnt](
unsigned DstIdx,
unsigned ShuffleMask) {
14626 unsigned ControlBitsCnt = DstIdx >> PreservedBitsCnt << 2;
14627 unsigned ControlBits = ShuffleMask >> ControlBitsCnt;
14629 if (ControlBits & 0b1000)
14630 return std::make_pair(0u, -1);
14632 unsigned SrcVecIdx = (ControlBits & 0b10) >> 1;
14633 unsigned PreservedBitsMask = (1 << PreservedBitsCnt) - 1;
14634 int SrcIdx = ((ControlBits & 0b1) << PreservedBitsCnt) |
14635 (DstIdx & PreservedBitsMask);
14636 return std::make_pair(SrcVecIdx, SrcIdx);
14644bool VectorExprEvaluator::VisitConvertVectorExpr(
const ConvertVectorExpr *E) {
14650 QualType DestTy = E->
getType()->
castAs<VectorType>()->getElementType();
14651 QualType SourceTy = SourceVecType->
castAs<VectorType>()->getElementType();
14657 ResultElements.reserve(SourceLen);
14658 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
14663 ResultElements.push_back(std::move(Elt));
14666 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14671 APValue const &VecVal2,
unsigned EltNum,
14673 unsigned const TotalElementsInInputVector1 = VecVal1.
getVectorLength();
14674 unsigned const TotalElementsInInputVector2 = VecVal2.
getVectorLength();
14677 int64_t
index = IndexVal.getExtValue();
14684 E, diag::err_shufflevector_minus_one_is_undefined_behavior_constexpr)
14690 index >= TotalElementsInInputVector1 + TotalElementsInInputVector2)
14691 llvm_unreachable(
"Out of bounds shuffle index");
14693 if (
index >= TotalElementsInInputVector1)
14700bool VectorExprEvaluator::VisitShuffleVectorExpr(
const ShuffleVectorExpr *E) {
14705 const Expr *Vec1 = E->
getExpr(0);
14709 const Expr *Vec2 = E->
getExpr(1);
14713 VectorType
const *DestVecTy = E->
getType()->
castAs<VectorType>();
14719 ResultElements.reserve(TotalElementsInOutputVector);
14720 for (
unsigned EltNum = 0; EltNum < TotalElementsInOutputVector; ++EltNum) {
14724 ResultElements.push_back(std::move(Elt));
14727 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14735class MatrixExprEvaluator :
public ExprEvaluatorBase<MatrixExprEvaluator> {
14742 bool Success(ArrayRef<APValue> M,
const Expr *E) {
14744 assert(M.size() == CMTy->getNumElementsFlattened());
14746 Result =
APValue(M.data(), CMTy->getNumRows(), CMTy->getNumColumns());
14750 assert(M.
isMatrix() &&
"expected matrix");
14755 bool VisitCastExpr(
const CastExpr *E);
14756 bool VisitInitListExpr(
const InitListExpr *E);
14762 "not a matrix prvalue");
14763 return MatrixExprEvaluator(Info, Result).Visit(E);
14766bool MatrixExprEvaluator::VisitCastExpr(
const CastExpr *E) {
14767 const auto *MT = E->
getType()->
castAs<ConstantMatrixType>();
14768 unsigned NumRows = MT->getNumRows();
14769 unsigned NumCols = MT->getNumColumns();
14770 unsigned NElts = NumRows * NumCols;
14771 QualType EltTy = MT->getElementType();
14775 case CK_HLSLAggregateSplatCast: {
14790 case CK_HLSLElementwiseCast: {
14803 return Success(ResultEls, E);
14806 return ExprEvaluatorBaseTy::VisitCastExpr(E);
14810bool MatrixExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
14811 const auto *MT = E->
getType()->
castAs<ConstantMatrixType>();
14812 QualType EltTy = MT->getElementType();
14814 assert(E->
getNumInits() == MT->getNumElementsFlattened() &&
14815 "Expected number of elements in initializer list to match the number "
14816 "of matrix elements");
14819 Elements.reserve(MT->getNumElementsFlattened());
14824 for (
unsigned I = 0, N = MT->getNumElementsFlattened(); I < N; ++I) {
14825 if (EltTy->isIntegerType()) {
14826 llvm::APSInt IntVal;
14829 Elements.push_back(
APValue(IntVal));
14831 llvm::APFloat FloatVal(0.0);
14834 Elements.push_back(
APValue(FloatVal));
14846 class ArrayExprEvaluator
14847 :
public ExprEvaluatorBase<ArrayExprEvaluator> {
14848 const LValue &
This;
14852 ArrayExprEvaluator(EvalInfo &Info,
const LValue &This,
APValue &
Result)
14856 assert(
V.isArray() &&
"expected array");
14861 bool ZeroInitialization(
const Expr *E) {
14862 const ConstantArrayType *CAT =
14863 Info.Ctx.getAsConstantArrayType(E->
getType());
14877 if (!
Result.hasArrayFiller())
14881 LValue Subobject =
This;
14882 Subobject.addArray(Info, E, CAT);
14887 bool VisitCallExpr(
const CallExpr *E) {
14888 return handleCallExpr(E,
Result, &This);
14890 bool VisitCastExpr(
const CastExpr *E);
14891 bool VisitInitListExpr(
const InitListExpr *E,
14892 QualType AllocType = QualType());
14893 bool VisitArrayInitLoopExpr(
const ArrayInitLoopExpr *E);
14894 bool VisitCXXConstructExpr(
const CXXConstructExpr *E);
14895 bool VisitCXXConstructExpr(
const CXXConstructExpr *E,
14896 const LValue &Subobject,
14898 bool VisitStringLiteral(
const StringLiteral *E,
14899 QualType AllocType = QualType()) {
14903 bool VisitCXXParenListInitExpr(
const CXXParenListInitExpr *E);
14904 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
14905 ArrayRef<Expr *> Args,
14906 const Expr *ArrayFiller,
14907 QualType AllocType = QualType());
14912 APValue &Result, EvalInfo &Info) {
14915 "not an array prvalue");
14916 return ArrayExprEvaluator(Info,
This, Result).Visit(E);
14924 "not an array prvalue");
14925 return ArrayExprEvaluator(Info,
This, Result)
14926 .VisitInitListExpr(ILE, AllocType);
14935 "not an array prvalue");
14936 return ArrayExprEvaluator(Info,
This, Result)
14937 .VisitCXXConstructExpr(CCE,
This, &Result, AllocType);
14946 if (
const InitListExpr *ILE = dyn_cast<InitListExpr>(FillerExpr)) {
14947 for (
unsigned I = 0, E = ILE->
getNumInits(); I != E; ++I) {
14952 if (ILE->hasArrayFiller() &&
14961bool ArrayExprEvaluator::VisitCastExpr(
const CastExpr *E) {
14966 return ExprEvaluatorBaseTy::VisitCastExpr(E);
14967 case CK_HLSLAggregateSplatCast: {
14987 case CK_HLSLElementwiseCast: {
15004bool ArrayExprEvaluator::VisitInitListExpr(
const InitListExpr *E,
15005 QualType AllocType) {
15006 const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(
15019 return VisitStringLiteral(SL, AllocType);
15024 "transparent array list initialization is not string literal init?");
15030bool ArrayExprEvaluator::VisitCXXParenListOrInitListExpr(
15032 QualType AllocType) {
15033 const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(
15038 assert((!
Result.isArray() ||
Result.getArrayInitializedElts() == 0) &&
15039 "zero-initialized array shouldn't have any initialized elts");
15044 unsigned NumEltsToInit = Args.size();
15049 if (NumEltsToInit != NumElts &&
15051 NumEltsToInit = NumElts;
15053 for (
auto *
Init : Args) {
15054 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts()))
15055 NumEltsToInit += EmbedS->getDataElementCount() - 1;
15057 if (NumEltsToInit > NumElts)
15058 NumEltsToInit = NumElts;
15061 LLVM_DEBUG(llvm::dbgs() <<
"The number of elements to initialize: "
15062 << NumEltsToInit <<
".\n");
15064 Result =
APValue(APValue::UninitArray(), NumEltsToInit, NumElts);
15069 for (
unsigned I = 0, E =
Result.getArrayInitializedElts(); I != E; ++I)
15070 Result.getArrayInitializedElt(I) = Filler;
15071 if (
Result.hasArrayFiller())
15075 LValue Subobject =
This;
15076 Subobject.addArray(Info, ExprToVisit, CAT);
15077 auto Eval = [&](
const Expr *
Init,
unsigned ArrayIndex) {
15078 if (
Init->isValueDependent())
15082 Subobject,
Init) ||
15085 if (!Info.noteFailure())
15091 unsigned ArrayIndex = 0;
15094 for (
unsigned Index = 0; Index != NumEltsToInit; ++Index) {
15095 const Expr *
Init = Index < Args.size() ? Args[Index] : ArrayFiller;
15096 if (ArrayIndex >= NumEltsToInit)
15098 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
15099 StringLiteral *SL = EmbedS->getDataStringLiteral();
15100 for (
unsigned I = EmbedS->getStartingElementPos(),
15101 N = EmbedS->getDataElementCount();
15102 I != EmbedS->getStartingElementPos() + N; ++I) {
15108 const FPOptions FPO =
15109 Init->getFPFeaturesInEffect(Info.Ctx.getLangOpts());
15114 Result.getArrayInitializedElt(ArrayIndex) =
APValue(FValue);
15119 if (!Eval(
Init, ArrayIndex))
15125 if (!
Result.hasArrayFiller())
15130 assert(ArrayFiller &&
"no array filler for incomplete init list");
15136bool ArrayExprEvaluator::VisitArrayInitLoopExpr(
const ArrayInitLoopExpr *E) {
15139 !
Evaluate(Info.CurrentCall->createTemporary(
15142 ScopeKind::FullExpression, CommonLV),
15149 Result =
APValue(APValue::UninitArray(), Elements, Elements);
15151 LValue Subobject =
This;
15152 Subobject.addArray(Info, E, CAT);
15155 for (EvalInfo::ArrayInitLoopIndex Index(Info); Index != Elements; ++Index) {
15164 FullExpressionRAII Scope(Info);
15170 if (!Info.noteFailure())
15182bool ArrayExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E) {
15183 return VisitCXXConstructExpr(E, This, &
Result, E->
getType());
15186bool ArrayExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E,
15187 const LValue &Subobject,
15190 bool HadZeroInit =
Value->hasValue();
15192 if (
const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(
Type)) {
15197 HadZeroInit &&
Value->hasArrayFiller() ?
Value->getArrayFiller()
15200 *
Value =
APValue(APValue::UninitArray(), 0, FinalSize);
15201 if (FinalSize == 0)
15207 LValue ArrayElt = Subobject;
15208 ArrayElt.addArray(Info, E, CAT);
15214 for (
const unsigned N : {1u, FinalSize}) {
15215 unsigned OldElts =
Value->getArrayInitializedElts();
15220 APValue NewValue(APValue::UninitArray(), N, FinalSize);
15221 for (
unsigned I = 0; I < OldElts; ++I)
15222 NewValue.getArrayInitializedElt(I).swap(
15223 Value->getArrayInitializedElt(I));
15224 Value->swap(NewValue);
15227 for (
unsigned I = OldElts; I < N; ++I)
15228 Value->getArrayInitializedElt(I) = Filler;
15230 if (HasTrivialConstructor && N == FinalSize && FinalSize != 1) {
15233 APValue &FirstResult =
Value->getArrayInitializedElt(0);
15234 for (
unsigned I = OldElts; I < FinalSize; ++I)
15235 Value->getArrayInitializedElt(I) = FirstResult;
15237 for (
unsigned I = OldElts; I < N; ++I) {
15238 if (!VisitCXXConstructExpr(E, ArrayElt,
15239 &
Value->getArrayInitializedElt(I),
15246 if (Info.EvalStatus.Diag && !Info.EvalStatus.Diag->empty() &&
15247 !Info.keepEvaluatingAfterFailure())
15256 if (!
Type->isRecordType())
15259 return RecordExprEvaluator(Info, Subobject, *
Value)
15260 .VisitCXXConstructExpr(E,
Type);
15263bool ArrayExprEvaluator::VisitCXXParenListInitExpr(
15264 const CXXParenListInitExpr *E) {
15266 "Expression result is not a constant array type");
15268 return VisitCXXParenListOrInitListExpr(E, E->
getInitExprs(),
15281class IntExprEvaluator
15282 :
public ExprEvaluatorBase<IntExprEvaluator> {
15285 IntExprEvaluator(EvalInfo &info,
APValue &result)
15286 : ExprEvaluatorBaseTy(info),
Result(result) {}
15290 "Invalid evaluation result.");
15292 "Invalid evaluation result.");
15293 assert(SI.getBitWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
15294 "Invalid evaluation result.");
15298 bool Success(
const llvm::APSInt &SI,
const Expr *E) {
15304 "Invalid evaluation result.");
15305 assert(I.getBitWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
15306 "Invalid evaluation result.");
15308 Result.getInt().setIsUnsigned(
15312 bool Success(
const llvm::APInt &I,
const Expr *E) {
15318 "Invalid evaluation result.");
15326 bool Success(CharUnits Size,
const Expr *E) {
15333 if (
V.isLValue() ||
V.isAddrLabelDiff() ||
V.isIndeterminate() ||
15334 V.allowConstexprUnknown()) {
15341 bool ZeroInitialization(
const Expr *E) {
return Success(0, E); }
15343 friend std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &,
15350 bool VisitIntegerLiteral(
const IntegerLiteral *E) {
15353 bool VisitCharacterLiteral(
const CharacterLiteral *E) {
15357 bool CheckReferencedDecl(
const Expr *E,
const Decl *D);
15358 bool VisitDeclRefExpr(
const DeclRefExpr *E) {
15359 if (CheckReferencedDecl(E, E->
getDecl()))
15362 return ExprEvaluatorBaseTy::VisitDeclRefExpr(E);
15364 bool VisitMemberExpr(
const MemberExpr *E) {
15366 VisitIgnoredBaseExpression(E->
getBase());
15370 return ExprEvaluatorBaseTy::VisitMemberExpr(E);
15373 bool VisitCallExpr(
const CallExpr *E);
15374 bool VisitBuiltinCallExpr(
const CallExpr *E,
unsigned BuiltinOp);
15375 bool VisitBinaryOperator(
const BinaryOperator *E);
15376 bool VisitOffsetOfExpr(
const OffsetOfExpr *E);
15377 bool VisitUnaryOperator(
const UnaryOperator *E);
15379 bool VisitCastExpr(
const CastExpr* E);
15380 bool VisitUnaryExprOrTypeTraitExpr(
const UnaryExprOrTypeTraitExpr *E);
15382 bool VisitCXXBoolLiteralExpr(
const CXXBoolLiteralExpr *E) {
15386 bool VisitObjCBoolLiteralExpr(
const ObjCBoolLiteralExpr *E) {
15390 bool VisitArrayInitIndexExpr(
const ArrayInitIndexExpr *E) {
15391 if (Info.ArrayInitIndex ==
uint64_t(-1)) {
15397 return Success(Info.ArrayInitIndex, E);
15401 bool VisitGNUNullExpr(
const GNUNullExpr *E) {
15402 return ZeroInitialization(E);
15405 bool VisitTypeTraitExpr(
const TypeTraitExpr *E) {
15414 bool VisitArrayTypeTraitExpr(
const ArrayTypeTraitExpr *E) {
15418 bool VisitExpressionTraitExpr(
const ExpressionTraitExpr *E) {
15422 bool VisitOpenACCAsteriskSizeExpr(
const OpenACCAsteriskSizeExpr *E) {
15429 bool VisitUnaryReal(
const UnaryOperator *E);
15430 bool VisitUnaryImag(
const UnaryOperator *E);
15432 bool VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E);
15433 bool VisitSizeOfPackExpr(
const SizeOfPackExpr *E);
15434 bool VisitSourceLocExpr(
const SourceLocExpr *E);
15435 bool VisitConceptSpecializationExpr(
const ConceptSpecializationExpr *E);
15440class FixedPointExprEvaluator
15441 :
public ExprEvaluatorBase<FixedPointExprEvaluator> {
15445 FixedPointExprEvaluator(EvalInfo &info,
APValue &result)
15446 : ExprEvaluatorBaseTy(info),
Result(result) {}
15448 bool Success(
const llvm::APInt &I,
const Expr *E) {
15450 APFixedPoint(I, Info.Ctx.getFixedPointSemantics(E->
getType())), E);
15455 APFixedPoint(
Value, Info.Ctx.getFixedPointSemantics(E->
getType())), E);
15459 return Success(
V.getFixedPoint(), E);
15462 bool Success(
const APFixedPoint &
V,
const Expr *E) {
15464 assert(
V.getWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
15465 "Invalid evaluation result.");
15470 bool ZeroInitialization(
const Expr *E) {
15478 bool VisitFixedPointLiteral(
const FixedPointLiteral *E) {
15482 bool VisitCastExpr(
const CastExpr *E);
15483 bool VisitUnaryOperator(
const UnaryOperator *E);
15484 bool VisitBinaryOperator(
const BinaryOperator *E);
15500 return IntExprEvaluator(Info, Result).Visit(E);
15508 if (!Val.
isInt()) {
15511 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
15518bool IntExprEvaluator::VisitSourceLocExpr(
const SourceLocExpr *E) {
15520 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.
getDefaultExpr());
15529 if (!FixedPointExprEvaluator(Info, Val).Visit(E))
15544 auto FXSema = Info.Ctx.getFixedPointSemantics(E->
getType());
15548 Result = APFixedPoint(Val, FXSema);
15559bool IntExprEvaluator::CheckReferencedDecl(
const Expr* E,
const Decl* D) {
15561 if (
const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(D)) {
15563 bool SameSign = (ECD->getInitVal().isSigned()
15565 bool SameWidth = (ECD->getInitVal().
getBitWidth()
15566 == Info.Ctx.getIntWidth(E->
getType()));
15567 if (SameSign && SameWidth)
15568 return Success(ECD->getInitVal(), E);
15572 llvm::APSInt Val = ECD->getInitVal();
15574 Val.setIsSigned(!ECD->getInitVal().isSigned());
15576 Val = Val.extOrTrunc(Info.Ctx.getIntWidth(E->
getType()));
15587 assert(!T->isDependentType() &&
"unexpected dependent type");
15592#define TYPE(ID, BASE)
15593#define DEPENDENT_TYPE(ID, BASE) case Type::ID:
15594#define NON_CANONICAL_TYPE(ID, BASE) case Type::ID:
15595#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(ID, BASE) case Type::ID:
15596#include "clang/AST/TypeNodes.inc"
15598 case Type::DeducedTemplateSpecialization:
15599 llvm_unreachable(
"unexpected non-canonical or dependent type");
15601 case Type::Builtin:
15603#define BUILTIN_TYPE(ID, SINGLETON_ID)
15604#define SIGNED_TYPE(ID, SINGLETON_ID) \
15605 case BuiltinType::ID: return GCCTypeClass::Integer;
15606#define FLOATING_TYPE(ID, SINGLETON_ID) \
15607 case BuiltinType::ID: return GCCTypeClass::RealFloat;
15608#define PLACEHOLDER_TYPE(ID, SINGLETON_ID) \
15609 case BuiltinType::ID: break;
15610#include "clang/AST/BuiltinTypes.def"
15611 case BuiltinType::Void:
15614 case BuiltinType::Bool:
15617 case BuiltinType::Char_U:
15618 case BuiltinType::UChar:
15619 case BuiltinType::WChar_U:
15620 case BuiltinType::Char8:
15621 case BuiltinType::Char16:
15622 case BuiltinType::Char32:
15623 case BuiltinType::UShort:
15624 case BuiltinType::UInt:
15625 case BuiltinType::ULong:
15626 case BuiltinType::ULongLong:
15627 case BuiltinType::UInt128:
15630 case BuiltinType::UShortAccum:
15631 case BuiltinType::UAccum:
15632 case BuiltinType::ULongAccum:
15633 case BuiltinType::UShortFract:
15634 case BuiltinType::UFract:
15635 case BuiltinType::ULongFract:
15636 case BuiltinType::SatUShortAccum:
15637 case BuiltinType::SatUAccum:
15638 case BuiltinType::SatULongAccum:
15639 case BuiltinType::SatUShortFract:
15640 case BuiltinType::SatUFract:
15641 case BuiltinType::SatULongFract:
15644 case BuiltinType::NullPtr:
15646 case BuiltinType::ObjCId:
15647 case BuiltinType::ObjCClass:
15648 case BuiltinType::ObjCSel:
15649#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
15650 case BuiltinType::Id:
15651#include "clang/Basic/OpenCLImageTypes.def"
15652#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
15653 case BuiltinType::Id:
15654#include "clang/Basic/OpenCLExtensionTypes.def"
15655 case BuiltinType::OCLSampler:
15656 case BuiltinType::OCLEvent:
15657 case BuiltinType::OCLClkEvent:
15658 case BuiltinType::OCLQueue:
15659 case BuiltinType::OCLReserveID:
15660#define SVE_TYPE(Name, Id, SingletonId) \
15661 case BuiltinType::Id:
15662#include "clang/Basic/AArch64ACLETypes.def"
15663#define PPC_VECTOR_TYPE(Name, Id, Size) \
15664 case BuiltinType::Id:
15665#include "clang/Basic/PPCTypes.def"
15666#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
15667#include "clang/Basic/RISCVVTypes.def"
15668#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
15669#include "clang/Basic/WebAssemblyReferenceTypes.def"
15670#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
15671#include "clang/Basic/AMDGPUTypes.def"
15672#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
15673#include "clang/Basic/HLSLIntangibleTypes.def"
15676 case BuiltinType::Dependent:
15677 llvm_unreachable(
"unexpected dependent type");
15679 llvm_unreachable(
"unexpected placeholder type");
15684 case Type::Pointer:
15685 case Type::ConstantArray:
15686 case Type::VariableArray:
15687 case Type::IncompleteArray:
15688 case Type::FunctionNoProto:
15689 case Type::FunctionProto:
15690 case Type::ArrayParameter:
15693 case Type::MemberPointer:
15698 case Type::Complex:
15711 case Type::ExtVector:
15714 case Type::BlockPointer:
15715 case Type::ConstantMatrix:
15716 case Type::ObjCObject:
15717 case Type::ObjCInterface:
15718 case Type::ObjCObjectPointer:
15720 case Type::HLSLAttributedResource:
15721 case Type::HLSLInlineSpirv:
15722 case Type::OverflowBehavior:
15730 case Type::LValueReference:
15731 case Type::RValueReference:
15732 llvm_unreachable(
"invalid type for expression");
15735 llvm_unreachable(
"unexpected type class");
15760 if (
Base.isNull()) {
15763 }
else if (
const Expr *E =
Base.dyn_cast<
const Expr *>()) {
15782 SpeculativeEvaluationRAII SpeculativeEval(Info);
15787 FoldConstant Fold(Info,
true);
15805 if (ArgType->isIntegralOrEnumerationType() || ArgType->isFloatingType() ||
15806 ArgType->isAnyComplexType() || ArgType->isPointerType() ||
15807 ArgType->isNullPtrType()) {
15810 Fold.keepDiagnostics();
15819 return V.hasValue();
15830 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
15854 const auto *Cast = dyn_cast<CastExpr>(NoParens);
15855 if (Cast ==
nullptr)
15860 auto CastKind = Cast->getCastKind();
15862 CastKind != CK_AddressSpaceConversion)
15865 const auto *SubExpr = Cast->getSubExpr();
15887 assert(!LVal.Designator.Invalid);
15889 auto IsLastOrInvalidFieldDecl = [&Ctx](
const FieldDecl *FD) {
15897 auto &
Base = LVal.getLValueBase();
15898 if (
auto *ME = dyn_cast_or_null<MemberExpr>(
Base.dyn_cast<
const Expr *>())) {
15899 if (
auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
15900 if (!IsLastOrInvalidFieldDecl(FD))
15902 }
else if (
auto *IFD = dyn_cast<IndirectFieldDecl>(ME->getMemberDecl())) {
15903 for (
auto *FD : IFD->chain()) {
15912 if (LVal.Designator.FirstEntryIsAnUnsizedArray) {
15916 if (BaseType->isIncompleteArrayType())
15922 for (
unsigned E = LVal.Designator.Entries.size(); I != E; ++I) {
15923 const auto &Entry = LVal.Designator.Entries[I];
15924 if (BaseType->isArrayType()) {
15930 uint64_t Index = Entry.getAsArrayIndex();
15934 }
else if (BaseType->isAnyComplexType()) {
15935 const auto *CT = BaseType->castAs<
ComplexType>();
15936 uint64_t Index = Entry.getAsArrayIndex();
15939 BaseType = CT->getElementType();
15940 }
else if (
auto *FD = getAsField(Entry)) {
15941 if (!IsLastOrInvalidFieldDecl(FD))
15945 assert(getAsBaseClass(Entry) &&
"Expecting cast to a base class");
15957 if (LVal.Designator.Invalid)
15960 if (!LVal.Designator.Entries.empty())
15961 return LVal.Designator.isMostDerivedAnUnsizedArray();
15963 if (!LVal.InvalidBase)
15975 const SubobjectDesignator &
Designator = LVal.Designator;
15987 auto isFlexibleArrayMember = [&] {
15989 FAMKind StrictFlexArraysLevel =
15992 if (
Designator.isMostDerivedAnUnsizedArray())
15995 if (StrictFlexArraysLevel == FAMKind::Default)
15998 if (
Designator.getMostDerivedArraySize() == 0 &&
15999 StrictFlexArraysLevel != FAMKind::IncompleteOnly)
16002 if (
Designator.getMostDerivedArraySize() == 1 &&
16003 StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete)
16009 return LVal.InvalidBase &&
16011 Designator.MostDerivedIsArrayElement && isFlexibleArrayMember() &&
16019 auto CharUnitsMax = std::numeric_limits<CharUnits::QuantityType>::max();
16020 if (Int.ugt(CharUnitsMax))
16030 if (!T.isNull() && T->isStructureType() &&
16031 T->castAsRecordDecl()->hasFlexibleArrayMember())
16032 if (
const auto *
V = LV.getLValueBase().dyn_cast<
const ValueDecl *>())
16033 if (
const auto *VD = dyn_cast<VarDecl>(
V))
16045 unsigned Type,
const LValue &LVal,
16064 if (!(
Type & 1) || LVal.Designator.Invalid || DetermineForCompleteObject) {
16066 if (
Type == 3 && !DetermineForCompleteObject)
16069 llvm::APInt APEndOffset;
16070 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
16074 if (LVal.InvalidBase)
16078 const bool Ret = CheckedHandleSizeof(BaseTy, EndOffset);
16084 const SubobjectDesignator &
Designator = LVal.Designator;
16096 llvm::APInt APEndOffset;
16097 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
16109 if (!CheckedHandleSizeof(
Designator.MostDerivedType, BytesPerElem))
16115 int64_t ElemsRemaining;
16118 uint64_t ArraySize =
Designator.getMostDerivedArraySize();
16119 uint64_t ArrayIndex =
Designator.Entries.back().getAsArrayIndex();
16120 ElemsRemaining = ArraySize <= ArrayIndex ? 0 : ArraySize - ArrayIndex;
16122 ElemsRemaining =
Designator.isOnePastTheEnd() ? 0 : 1;
16125 EndOffset = LVal.getLValueOffset() + BytesPerElem * ElemsRemaining;
16134static std::optional<uint64_t>
16142 SpeculativeEvaluationRAII SpeculativeEval(Info);
16143 IgnoreSideEffectsRAII Fold(Info);
16150 return std::nullopt;
16151 LVal.setFrom(Info.Ctx, RVal);
16154 return std::nullopt;
16159 if (LVal.getLValueOffset().isNegative())
16164 return std::nullopt;
16168 if (EndOffset <= LVal.getLValueOffset())
16170 return (EndOffset - LVal.getLValueOffset()).
getQuantity();
16173bool IntExprEvaluator::VisitCallExpr(
const CallExpr *E) {
16174 if (!IsConstantEvaluatedBuiltinCall(E))
16175 return ExprEvaluatorBaseTy::VisitCallExpr(E);
16192 Info.FFDiag(E->
getArg(0));
16198 assert(SrcInt.getBitWidth() >= Alignment.getBitWidth() &&
16199 "Bit widths must be the same");
16206bool IntExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *E,
16207 unsigned BuiltinOp) {
16208 auto EvalTestOp = [&](llvm::function_ref<
bool(
const APInt &,
const APInt &)>
16210 APValue SourceLHS, SourceRHS;
16218 unsigned LaneWidth = Info.Ctx.getTypeSize(ElemQT);
16220 APInt AWide(LaneWidth * SourceLen, 0);
16221 APInt BWide(LaneWidth * SourceLen, 0);
16223 for (
unsigned I = 0; I != SourceLen; ++I) {
16226 if (ElemQT->isIntegerType()) {
16229 }
else if (ElemQT->isFloatingType()) {
16237 AWide.insertBits(ALane, I * LaneWidth);
16238 BWide.insertBits(BLane, I * LaneWidth);
16243 auto HandleMaskBinOp =
16256 auto HandleCRC32 = [&](
unsigned DataBytes) ->
bool {
16262 uint64_t CRCVal = CRC.getZExtValue();
16266 static const uint32_t CRC32C_POLY = 0x82F63B78;
16270 for (
unsigned I = 0; I != DataBytes; ++I) {
16271 uint8_t Byte =
static_cast<uint8_t
>((DataVal >> (I * 8)) & 0xFF);
16273 for (
int J = 0; J != 8; ++J) {
16281 switch (BuiltinOp) {
16285 case X86::BI__builtin_ia32_crc32qi:
16286 return HandleCRC32(1);
16287 case X86::BI__builtin_ia32_crc32hi:
16288 return HandleCRC32(2);
16289 case X86::BI__builtin_ia32_crc32si:
16290 return HandleCRC32(4);
16291 case X86::BI__builtin_ia32_crc32di:
16292 return HandleCRC32(8);
16294 case Builtin::BI__builtin_dynamic_object_size:
16295 case Builtin::BI__builtin_object_size: {
16299 assert(
Type <= 3 &&
"unexpected type");
16301 if (std::optional<uint64_t> Size =
16310 switch (Info.EvalMode) {
16311 case EvaluationMode::ConstantExpression:
16312 case EvaluationMode::ConstantFold:
16313 case EvaluationMode::IgnoreSideEffects:
16316 case EvaluationMode::ConstantExpressionUnevaluated:
16321 llvm_unreachable(
"unexpected EvalMode");
16324 case Builtin::BI__builtin_os_log_format_buffer_size: {
16325 analyze_os_log::OSLogBufferLayout Layout;
16330 case Builtin::BI__builtin_is_aligned: {
16338 Ptr.setFrom(Info.Ctx, Src);
16344 assert(Alignment.isPowerOf2());
16357 Info.FFDiag(E->
getArg(0), diag::note_constexpr_alignment_compute)
16361 assert(Src.
isInt());
16362 return Success((Src.
getInt() & (Alignment - 1)) == 0 ? 1 : 0, E);
16364 case Builtin::BI__builtin_align_up: {
16372 APSInt((Src.
getInt() + (Alignment - 1)) & ~(Alignment - 1),
16373 Src.
getInt().isUnsigned());
16374 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
16375 return Success(AlignedVal, E);
16377 case Builtin::BI__builtin_align_down: {
16386 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
16387 return Success(AlignedVal, E);
16390 case Builtin::BI__builtin_bitreverseg:
16391 case Builtin::BI__builtin_bitreverse8:
16392 case Builtin::BI__builtin_bitreverse16:
16393 case Builtin::BI__builtin_bitreverse32:
16394 case Builtin::BI__builtin_bitreverse64:
16395 case Builtin::BI__builtin_elementwise_bitreverse: {
16400 return Success(Val.reverseBits(), E);
16402 case Builtin::BI__builtin_bswapg:
16403 case Builtin::BI__builtin_bswap16:
16404 case Builtin::BI__builtin_bswap32:
16405 case Builtin::BI__builtin_bswap64: {
16409 if (Val.getBitWidth() == 8 || Val.getBitWidth() == 1)
16412 return Success(Val.byteSwap(), E);
16415 case Builtin::BI__builtin_classify_type:
16418 case Builtin::BI__builtin_clrsb:
16419 case Builtin::BI__builtin_clrsbl:
16420 case Builtin::BI__builtin_clrsbll: {
16425 return Success(Val.getBitWidth() - Val.getSignificantBits(), E);
16428 case Builtin::BI__builtin_clz:
16429 case Builtin::BI__builtin_clzl:
16430 case Builtin::BI__builtin_clzll:
16431 case Builtin::BI__builtin_clzs:
16432 case Builtin::BI__builtin_clzg:
16433 case Builtin::BI__builtin_elementwise_clzg:
16434 case Builtin::BI__lzcnt16:
16435 case Builtin::BI__lzcnt:
16436 case Builtin::BI__lzcnt64: {
16447 std::optional<APSInt> Fallback;
16448 if ((BuiltinOp == Builtin::BI__builtin_clzg ||
16449 BuiltinOp == Builtin::BI__builtin_elementwise_clzg) &&
16454 Fallback = FallbackTemp;
16459 return Success(*Fallback, E);
16464 bool ZeroIsUndefined = BuiltinOp != Builtin::BI__lzcnt16 &&
16465 BuiltinOp != Builtin::BI__lzcnt &&
16466 BuiltinOp != Builtin::BI__lzcnt64;
16468 if (BuiltinOp == Builtin::BI__builtin_elementwise_clzg) {
16469 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
16473 if (ZeroIsUndefined)
16477 return Success(Val.countl_zero(), E);
16480 case Builtin::BI__builtin_constant_p: {
16481 const Expr *Arg = E->
getArg(0);
16490 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
16494 case Builtin::BI__noop:
16498 case Builtin::BI__builtin_is_constant_evaluated: {
16499 const auto *
Callee = Info.CurrentCall->getCallee();
16500 if (Info.InConstantContext && !Info.CheckingPotentialConstantExpression &&
16501 (Info.CallStackDepth == 1 ||
16502 (Info.CallStackDepth == 2 &&
Callee->isInStdNamespace() &&
16503 Callee->getIdentifier() &&
16504 Callee->getIdentifier()->isStr(
"is_constant_evaluated")))) {
16506 if (Info.EvalStatus.Diag)
16507 Info.report((Info.CallStackDepth == 1)
16509 : Info.CurrentCall->getCallRange().getBegin(),
16510 diag::warn_is_constant_evaluated_always_true_constexpr)
16511 << (Info.CallStackDepth == 1 ?
"__builtin_is_constant_evaluated"
16512 :
"std::is_constant_evaluated");
16515 return Success(Info.InConstantContext, E);
16518 case Builtin::BI__builtin_is_within_lifetime:
16519 if (
auto result = EvaluateBuiltinIsWithinLifetime(*
this, E))
16523 case Builtin::BI__builtin_ctz:
16524 case Builtin::BI__builtin_ctzl:
16525 case Builtin::BI__builtin_ctzll:
16526 case Builtin::BI__builtin_ctzs:
16527 case Builtin::BI__builtin_ctzg:
16528 case Builtin::BI__builtin_elementwise_ctzg: {
16539 std::optional<APSInt> Fallback;
16540 if ((BuiltinOp == Builtin::BI__builtin_ctzg ||
16541 BuiltinOp == Builtin::BI__builtin_elementwise_ctzg) &&
16546 Fallback = FallbackTemp;
16551 return Success(*Fallback, E);
16553 if (BuiltinOp == Builtin::BI__builtin_elementwise_ctzg) {
16554 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
16560 return Success(Val.countr_zero(), E);
16563 case Builtin::BI__builtin_eh_return_data_regno: {
16565 Operand = Info.Ctx.getTargetInfo().getEHDataRegisterNumber(Operand);
16569 case Builtin::BI__builtin_elementwise_abs: {
16574 return Success(Val.abs(), E);
16577 case Builtin::BI__builtin_expect:
16578 case Builtin::BI__builtin_expect_with_probability:
16579 return Visit(E->
getArg(0));
16581 case Builtin::BI__builtin_ptrauth_string_discriminator: {
16588 case Builtin::BI__builtin_infer_alloc_token: {
16594 E, diag::note_constexpr_infer_alloc_token_type_inference_failed);
16597 return Error(E, diag::note_constexpr_infer_alloc_token_no_metadata);
16599 Info.getLangOpts().AllocTokenMode.value_or(llvm::DefaultAllocTokenMode);
16600 uint64_t BitWidth = Info.Ctx.getTypeSize(Info.Ctx.getSizeType());
16601 auto MaxTokensOpt = Info.getLangOpts().AllocTokenMax;
16603 MaxTokensOpt.value_or(0) ? *MaxTokensOpt : (~0ULL >> (64 - BitWidth));
16604 auto MaybeToken = llvm::getAllocToken(Mode, *ATMD, MaxTokens);
16606 return Error(E, diag::note_constexpr_infer_alloc_token_stateful_mode);
16607 return Success(llvm::APInt(BitWidth, *MaybeToken), E);
16610 case Builtin::BI__builtin_ffs:
16611 case Builtin::BI__builtin_ffsl:
16612 case Builtin::BI__builtin_ffsll: {
16617 unsigned N = Val.countr_zero();
16618 return Success(N == Val.getBitWidth() ? 0 : N + 1, E);
16621 case Builtin::BI__builtin_fpclassify: {
16626 switch (Val.getCategory()) {
16627 case APFloat::fcNaN: Arg = 0;
break;
16628 case APFloat::fcInfinity: Arg = 1;
break;
16629 case APFloat::fcNormal: Arg = Val.isDenormal() ? 3 : 2;
break;
16630 case APFloat::fcZero: Arg = 4;
break;
16632 return Visit(E->
getArg(Arg));
16635 case Builtin::BI__builtin_isinf_sign: {
16638 Success(Val.isInfinity() ? (Val.isNegative() ? -1 : 1) : 0, E);
16641 case Builtin::BI__builtin_isinf: {
16644 Success(Val.isInfinity() ? 1 : 0, E);
16647 case Builtin::BI__builtin_isfinite: {
16650 Success(Val.isFinite() ? 1 : 0, E);
16653 case Builtin::BI__builtin_isnan: {
16656 Success(Val.isNaN() ? 1 : 0, E);
16659 case Builtin::BI__builtin_isnormal: {
16662 Success(Val.isNormal() ? 1 : 0, E);
16665 case Builtin::BI__builtin_issubnormal: {
16668 Success(Val.isDenormal() ? 1 : 0, E);
16671 case Builtin::BI__builtin_iszero: {
16674 Success(Val.isZero() ? 1 : 0, E);
16677 case Builtin::BI__builtin_signbit:
16678 case Builtin::BI__builtin_signbitf:
16679 case Builtin::BI__builtin_signbitl: {
16682 Success(Val.isNegative() ? 1 : 0, E);
16685 case Builtin::BI__builtin_isgreater:
16686 case Builtin::BI__builtin_isgreaterequal:
16687 case Builtin::BI__builtin_isless:
16688 case Builtin::BI__builtin_islessequal:
16689 case Builtin::BI__builtin_islessgreater:
16690 case Builtin::BI__builtin_isunordered: {
16699 switch (BuiltinOp) {
16700 case Builtin::BI__builtin_isgreater:
16702 case Builtin::BI__builtin_isgreaterequal:
16704 case Builtin::BI__builtin_isless:
16706 case Builtin::BI__builtin_islessequal:
16708 case Builtin::BI__builtin_islessgreater: {
16709 APFloat::cmpResult cmp = LHS.compare(RHS);
16710 return cmp == APFloat::cmpResult::cmpLessThan ||
16711 cmp == APFloat::cmpResult::cmpGreaterThan;
16713 case Builtin::BI__builtin_isunordered:
16714 return LHS.compare(RHS) == APFloat::cmpResult::cmpUnordered;
16716 llvm_unreachable(
"Unexpected builtin ID: Should be a floating "
16717 "point comparison function");
16725 case Builtin::BI__builtin_issignaling: {
16728 Success(Val.isSignaling() ? 1 : 0, E);
16731 case Builtin::BI__builtin_isfpclass: {
16735 unsigned Test =
static_cast<llvm::FPClassTest
>(MaskVal.getZExtValue());
16738 Success((Val.classify() & Test) ? 1 : 0, E);
16741 case Builtin::BI__builtin_parity:
16742 case Builtin::BI__builtin_parityl:
16743 case Builtin::BI__builtin_parityll: {
16748 return Success(Val.popcount() % 2, E);
16751 case Builtin::BI__builtin_abs:
16752 case Builtin::BI__builtin_labs:
16753 case Builtin::BI__builtin_llabs: {
16757 if (Val ==
APSInt(APInt::getSignedMinValue(Val.getBitWidth()),
16760 if (Val.isNegative())
16765 case Builtin::BI__builtin_popcount:
16766 case Builtin::BI__builtin_popcountl:
16767 case Builtin::BI__builtin_popcountll:
16768 case Builtin::BI__builtin_popcountg:
16769 case Builtin::BI__builtin_elementwise_popcount:
16770 case Builtin::BI__popcnt16:
16771 case Builtin::BI__popcnt:
16772 case Builtin::BI__popcnt64: {
16783 return Success(Val.popcount(), E);
16786 case Builtin::BI__builtin_rotateleft8:
16787 case Builtin::BI__builtin_rotateleft16:
16788 case Builtin::BI__builtin_rotateleft32:
16789 case Builtin::BI__builtin_rotateleft64:
16790 case Builtin::BI__builtin_rotateright8:
16791 case Builtin::BI__builtin_rotateright16:
16792 case Builtin::BI__builtin_rotateright32:
16793 case Builtin::BI__builtin_rotateright64:
16794 case Builtin::BI__builtin_stdc_rotate_left:
16795 case Builtin::BI__builtin_stdc_rotate_right:
16796 case Builtin::BI_rotl8:
16797 case Builtin::BI_rotl16:
16798 case Builtin::BI_rotl:
16799 case Builtin::BI_lrotl:
16800 case Builtin::BI_rotl64:
16801 case Builtin::BI_rotr8:
16802 case Builtin::BI_rotr16:
16803 case Builtin::BI_rotr:
16804 case Builtin::BI_lrotr:
16805 case Builtin::BI_rotr64: {
16813 switch (BuiltinOp) {
16814 case Builtin::BI__builtin_rotateright8:
16815 case Builtin::BI__builtin_rotateright16:
16816 case Builtin::BI__builtin_rotateright32:
16817 case Builtin::BI__builtin_rotateright64:
16818 case Builtin::BI__builtin_stdc_rotate_right:
16819 case Builtin::BI_rotr8:
16820 case Builtin::BI_rotr16:
16821 case Builtin::BI_rotr:
16822 case Builtin::BI_lrotr:
16823 case Builtin::BI_rotr64:
16832 case Builtin::BIstdc_leading_zeros:
16833 case Builtin::BIstdc_leading_ones:
16834 case Builtin::BIstdc_trailing_zeros:
16835 case Builtin::BIstdc_trailing_ones:
16836 case Builtin::BIstdc_first_leading_zero:
16837 case Builtin::BIstdc_first_leading_one:
16838 case Builtin::BIstdc_first_trailing_zero:
16839 case Builtin::BIstdc_first_trailing_one:
16840 case Builtin::BIstdc_count_zeros:
16841 case Builtin::BIstdc_count_ones:
16842 case Builtin::BIstdc_has_single_bit:
16843 case Builtin::BIstdc_bit_width:
16844 case Builtin::BIstdc_bit_floor:
16845 case Builtin::BIstdc_bit_ceil:
16846 case Builtin::BI__builtin_stdc_leading_zeros:
16847 case Builtin::BI__builtin_stdc_leading_ones:
16848 case Builtin::BI__builtin_stdc_trailing_zeros:
16849 case Builtin::BI__builtin_stdc_trailing_ones:
16850 case Builtin::BI__builtin_stdc_first_leading_zero:
16851 case Builtin::BI__builtin_stdc_first_leading_one:
16852 case Builtin::BI__builtin_stdc_first_trailing_zero:
16853 case Builtin::BI__builtin_stdc_first_trailing_one:
16854 case Builtin::BI__builtin_stdc_count_zeros:
16855 case Builtin::BI__builtin_stdc_count_ones:
16856 case Builtin::BI__builtin_stdc_has_single_bit:
16857 case Builtin::BI__builtin_stdc_bit_width:
16858 case Builtin::BI__builtin_stdc_bit_floor:
16859 case Builtin::BI__builtin_stdc_bit_ceil: {
16864 unsigned BitWidth = Val.getBitWidth();
16865 const unsigned ResBitWidth = Info.Ctx.getIntWidth(E->
getType());
16867 switch (BuiltinOp) {
16868 case Builtin::BI__builtin_stdc_leading_zeros:
16869 return Success(
APInt(ResBitWidth, Val.countl_zero()), E);
16870 case Builtin::BI__builtin_stdc_leading_ones:
16871 return Success(
APInt(ResBitWidth, Val.countl_one()), E);
16872 case Builtin::BI__builtin_stdc_trailing_zeros:
16873 return Success(
APInt(ResBitWidth, Val.countr_zero()), E);
16874 case Builtin::BI__builtin_stdc_trailing_ones:
16875 return Success(
APInt(ResBitWidth, Val.countr_one()), E);
16876 case Builtin::BI__builtin_stdc_first_leading_zero:
16878 APInt(ResBitWidth, Val.isAllOnes() ? 0 : Val.countl_one() + 1), E);
16879 case Builtin::BI__builtin_stdc_first_leading_one:
16881 APInt(ResBitWidth, Val.isZero() ? 0 : Val.countl_zero() + 1), E);
16882 case Builtin::BI__builtin_stdc_first_trailing_zero:
16884 APInt(ResBitWidth, Val.isAllOnes() ? 0 : Val.countr_one() + 1), E);
16885 case Builtin::BI__builtin_stdc_first_trailing_one:
16887 APInt(ResBitWidth, Val.isZero() ? 0 : Val.countr_zero() + 1), E);
16888 case Builtin::BI__builtin_stdc_count_zeros: {
16889 APInt Cnt(ResBitWidth, BitWidth - Val.popcount());
16892 case Builtin::BI__builtin_stdc_count_ones: {
16893 APInt Cnt(ResBitWidth, Val.popcount());
16896 case Builtin::BI__builtin_stdc_has_single_bit: {
16897 APInt Res(ResBitWidth, Val.popcount() == 1 ? 1 : 0);
16900 case Builtin::BI__builtin_stdc_bit_width:
16901 return Success(
APInt(ResBitWidth, BitWidth - Val.countl_zero()), E);
16902 case Builtin::BI__builtin_stdc_bit_floor: {
16905 unsigned Exp = BitWidth - Val.countl_zero() - 1;
16907 APSInt(APInt::getOneBitSet(BitWidth, Exp),
true), E);
16909 case Builtin::BI__builtin_stdc_bit_ceil: {
16912 APInt ValMinusOne = Val - 1;
16913 unsigned LZ = ValMinusOne.countl_zero();
16917 APInt Result = APInt::getOneBitSet(BitWidth, BitWidth - LZ);
16921 llvm_unreachable(
"Unknown stdc builtin");
16925 case Builtin::BI__builtin_elementwise_add_sat: {
16931 APInt Result = LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS);
16934 case Builtin::BI__builtin_elementwise_sub_sat: {
16940 APInt Result = LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
16943 case Builtin::BI__builtin_elementwise_max: {
16952 case Builtin::BI__builtin_elementwise_min: {
16961 case Builtin::BI__builtin_elementwise_fshl:
16962 case Builtin::BI__builtin_elementwise_fshr: {
16969 switch (BuiltinOp) {
16970 case Builtin::BI__builtin_elementwise_fshl: {
16971 APSInt Result(llvm::APIntOps::fshl(Hi, Lo, Shift), Hi.isUnsigned());
16974 case Builtin::BI__builtin_elementwise_fshr: {
16975 APSInt Result(llvm::APIntOps::fshr(Hi, Lo, Shift), Hi.isUnsigned());
16979 llvm_unreachable(
"Fully covered switch above");
16981 case Builtin::BIstrlen:
16982 case Builtin::BIwcslen:
16984 if (Info.getLangOpts().CPlusPlus11)
16985 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
16987 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
16989 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
16991 case Builtin::BI__builtin_strlen:
16992 case Builtin::BI__builtin_wcslen: {
16995 if (std::optional<uint64_t> StrLen =
17001 case Builtin::BIstrcmp:
17002 case Builtin::BIwcscmp:
17003 case Builtin::BIstrncmp:
17004 case Builtin::BIwcsncmp:
17005 case Builtin::BImemcmp:
17006 case Builtin::BIbcmp:
17007 case Builtin::BIwmemcmp:
17009 if (Info.getLangOpts().CPlusPlus11)
17010 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
17012 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
17014 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
17016 case Builtin::BI__builtin_strcmp:
17017 case Builtin::BI__builtin_wcscmp:
17018 case Builtin::BI__builtin_strncmp:
17019 case Builtin::BI__builtin_wcsncmp:
17020 case Builtin::BI__builtin_memcmp:
17021 case Builtin::BI__builtin_bcmp:
17022 case Builtin::BI__builtin_wmemcmp: {
17023 LValue String1, String2;
17029 if (BuiltinOp != Builtin::BIstrcmp &&
17030 BuiltinOp != Builtin::BIwcscmp &&
17031 BuiltinOp != Builtin::BI__builtin_strcmp &&
17032 BuiltinOp != Builtin::BI__builtin_wcscmp) {
17036 MaxLength = N.getZExtValue();
17040 if (MaxLength == 0u)
17043 if (!String1.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
17044 !String2.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
17045 String1.Designator.Invalid || String2.Designator.Invalid)
17048 QualType CharTy1 = String1.Designator.getType(Info.Ctx);
17049 QualType CharTy2 = String2.Designator.getType(Info.Ctx);
17051 bool IsRawByte = BuiltinOp == Builtin::BImemcmp ||
17052 BuiltinOp == Builtin::BIbcmp ||
17053 BuiltinOp == Builtin::BI__builtin_memcmp ||
17054 BuiltinOp == Builtin::BI__builtin_bcmp;
17056 assert(IsRawByte ||
17057 (Info.Ctx.hasSameUnqualifiedType(
17059 Info.Ctx.hasSameUnqualifiedType(CharTy1, CharTy2)));
17066 Info.FFDiag(E, diag::note_constexpr_memcmp_unsupported)
17067 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp) << CharTy1
17072 const auto &ReadCurElems = [&](
APValue &Char1,
APValue &Char2) {
17075 Char1.
isInt() && Char2.isInt();
17077 const auto &AdvanceElems = [&] {
17083 (BuiltinOp != Builtin::BImemcmp && BuiltinOp != Builtin::BIbcmp &&
17084 BuiltinOp != Builtin::BIwmemcmp &&
17085 BuiltinOp != Builtin::BI__builtin_memcmp &&
17086 BuiltinOp != Builtin::BI__builtin_bcmp &&
17087 BuiltinOp != Builtin::BI__builtin_wmemcmp);
17088 bool IsWide = BuiltinOp == Builtin::BIwcscmp ||
17089 BuiltinOp == Builtin::BIwcsncmp ||
17090 BuiltinOp == Builtin::BIwmemcmp ||
17091 BuiltinOp == Builtin::BI__builtin_wcscmp ||
17092 BuiltinOp == Builtin::BI__builtin_wcsncmp ||
17093 BuiltinOp == Builtin::BI__builtin_wmemcmp;
17095 for (; MaxLength; --MaxLength) {
17097 if (!ReadCurElems(Char1, Char2))
17105 if (StopAtNull && !Char1.
getInt())
17107 assert(!(StopAtNull && !Char2.
getInt()));
17108 if (!AdvanceElems())
17115 case Builtin::BI__atomic_always_lock_free:
17116 case Builtin::BI__atomic_is_lock_free:
17117 case Builtin::BI__c11_atomic_is_lock_free: {
17133 if (
Size.isPowerOfTwo()) {
17135 unsigned InlineWidthBits =
17136 Info.Ctx.getTargetInfo().getMaxAtomicInlineWidth();
17137 if (Size <= Info.Ctx.toCharUnitsFromBits(InlineWidthBits)) {
17138 if (BuiltinOp == Builtin::BI__c11_atomic_is_lock_free ||
17144 const Expr *PtrArg = E->
getArg(1);
17150 IntResult.isAligned(
Size.getAsAlign()))
17154 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(PtrArg)) {
17157 if (ICE->getCastKind() == CK_BitCast)
17158 PtrArg = ICE->getSubExpr();
17161 if (
auto PtrTy = PtrArg->
getType()->
getAs<PointerType>()) {
17164 Info.Ctx.getTypeAlignInChars(PointeeType) >= Size) {
17172 return BuiltinOp == Builtin::BI__atomic_always_lock_free ?
17175 case Builtin::BI__builtin_addcb:
17176 case Builtin::BI__builtin_addcs:
17177 case Builtin::BI__builtin_addc:
17178 case Builtin::BI__builtin_addcl:
17179 case Builtin::BI__builtin_addcll:
17180 case Builtin::BI__builtin_subcb:
17181 case Builtin::BI__builtin_subcs:
17182 case Builtin::BI__builtin_subc:
17183 case Builtin::BI__builtin_subcl:
17184 case Builtin::BI__builtin_subcll: {
17185 LValue CarryOutLValue;
17197 bool FirstOverflowed =
false;
17198 bool SecondOverflowed =
false;
17199 switch (BuiltinOp) {
17201 llvm_unreachable(
"Invalid value for BuiltinOp");
17202 case Builtin::BI__builtin_addcb:
17203 case Builtin::BI__builtin_addcs:
17204 case Builtin::BI__builtin_addc:
17205 case Builtin::BI__builtin_addcl:
17206 case Builtin::BI__builtin_addcll:
17208 LHS.uadd_ov(RHS, FirstOverflowed).uadd_ov(CarryIn, SecondOverflowed);
17210 case Builtin::BI__builtin_subcb:
17211 case Builtin::BI__builtin_subcs:
17212 case Builtin::BI__builtin_subc:
17213 case Builtin::BI__builtin_subcl:
17214 case Builtin::BI__builtin_subcll:
17216 LHS.usub_ov(RHS, FirstOverflowed).usub_ov(CarryIn, SecondOverflowed);
17222 CarryOut = (
uint64_t)(FirstOverflowed | SecondOverflowed);
17228 case Builtin::BI__builtin_add_overflow:
17229 case Builtin::BI__builtin_sub_overflow:
17230 case Builtin::BI__builtin_mul_overflow:
17231 case Builtin::BI__builtin_sadd_overflow:
17232 case Builtin::BI__builtin_uadd_overflow:
17233 case Builtin::BI__builtin_uaddl_overflow:
17234 case Builtin::BI__builtin_uaddll_overflow:
17235 case Builtin::BI__builtin_usub_overflow:
17236 case Builtin::BI__builtin_usubl_overflow:
17237 case Builtin::BI__builtin_usubll_overflow:
17238 case Builtin::BI__builtin_umul_overflow:
17239 case Builtin::BI__builtin_umull_overflow:
17240 case Builtin::BI__builtin_umulll_overflow:
17241 case Builtin::BI__builtin_saddl_overflow:
17242 case Builtin::BI__builtin_saddll_overflow:
17243 case Builtin::BI__builtin_ssub_overflow:
17244 case Builtin::BI__builtin_ssubl_overflow:
17245 case Builtin::BI__builtin_ssubll_overflow:
17246 case Builtin::BI__builtin_smul_overflow:
17247 case Builtin::BI__builtin_smull_overflow:
17248 case Builtin::BI__builtin_smulll_overflow: {
17249 LValue ResultLValue;
17259 bool DidOverflow =
false;
17262 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
17263 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
17264 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
17265 bool IsSigned = LHS.isSigned() || RHS.isSigned() ||
17267 bool AllSigned = LHS.isSigned() && RHS.isSigned() &&
17269 uint64_t LHSSize = LHS.getBitWidth();
17270 uint64_t RHSSize = RHS.getBitWidth();
17271 uint64_t ResultSize = Info.Ctx.getTypeSize(ResultType);
17272 uint64_t MaxBits = std::max(std::max(LHSSize, RHSSize), ResultSize);
17278 if (IsSigned && !AllSigned)
17281 LHS =
APSInt(LHS.extOrTrunc(MaxBits), !IsSigned);
17282 RHS =
APSInt(RHS.extOrTrunc(MaxBits), !IsSigned);
17287 switch (BuiltinOp) {
17289 llvm_unreachable(
"Invalid value for BuiltinOp");
17290 case Builtin::BI__builtin_add_overflow:
17291 case Builtin::BI__builtin_sadd_overflow:
17292 case Builtin::BI__builtin_saddl_overflow:
17293 case Builtin::BI__builtin_saddll_overflow:
17294 case Builtin::BI__builtin_uadd_overflow:
17295 case Builtin::BI__builtin_uaddl_overflow:
17296 case Builtin::BI__builtin_uaddll_overflow:
17297 Result = LHS.isSigned() ? LHS.sadd_ov(RHS, DidOverflow)
17298 : LHS.uadd_ov(RHS, DidOverflow);
17300 case Builtin::BI__builtin_sub_overflow:
17301 case Builtin::BI__builtin_ssub_overflow:
17302 case Builtin::BI__builtin_ssubl_overflow:
17303 case Builtin::BI__builtin_ssubll_overflow:
17304 case Builtin::BI__builtin_usub_overflow:
17305 case Builtin::BI__builtin_usubl_overflow:
17306 case Builtin::BI__builtin_usubll_overflow:
17307 Result = LHS.isSigned() ? LHS.ssub_ov(RHS, DidOverflow)
17308 : LHS.usub_ov(RHS, DidOverflow);
17310 case Builtin::BI__builtin_mul_overflow:
17311 case Builtin::BI__builtin_smul_overflow:
17312 case Builtin::BI__builtin_smull_overflow:
17313 case Builtin::BI__builtin_smulll_overflow:
17314 case Builtin::BI__builtin_umul_overflow:
17315 case Builtin::BI__builtin_umull_overflow:
17316 case Builtin::BI__builtin_umulll_overflow:
17317 Result = LHS.isSigned() ? LHS.smul_ov(RHS, DidOverflow)
17318 : LHS.umul_ov(RHS, DidOverflow);
17324 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
17325 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
17326 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
17332 APSInt Temp =
Result.extOrTrunc(Info.Ctx.getTypeSize(ResultType));
17335 if (!APSInt::isSameValue(Temp,
Result))
17336 DidOverflow =
true;
17343 return Success(DidOverflow, E);
17346 case Builtin::BI__builtin_reduce_add:
17347 case Builtin::BI__builtin_reduce_mul:
17348 case Builtin::BI__builtin_reduce_and:
17349 case Builtin::BI__builtin_reduce_or:
17350 case Builtin::BI__builtin_reduce_xor:
17351 case Builtin::BI__builtin_reduce_min:
17352 case Builtin::BI__builtin_reduce_max: {
17359 for (
unsigned EltNum = 1; EltNum < SourceLen; ++EltNum) {
17360 switch (BuiltinOp) {
17363 case Builtin::BI__builtin_reduce_add: {
17366 Reduced.getBitWidth() + 1, std::plus<APSInt>(), Reduced))
17370 case Builtin::BI__builtin_reduce_mul: {
17373 Reduced.getBitWidth() * 2, std::multiplies<APSInt>(), Reduced))
17377 case Builtin::BI__builtin_reduce_and: {
17381 case Builtin::BI__builtin_reduce_or: {
17385 case Builtin::BI__builtin_reduce_xor: {
17389 case Builtin::BI__builtin_reduce_min: {
17393 case Builtin::BI__builtin_reduce_max: {
17403 case clang::X86::BI__builtin_ia32_addcarryx_u32:
17404 case clang::X86::BI__builtin_ia32_addcarryx_u64:
17405 case clang::X86::BI__builtin_ia32_subborrow_u32:
17406 case clang::X86::BI__builtin_ia32_subborrow_u64: {
17407 LValue ResultLValue;
17408 APSInt CarryIn, LHS, RHS;
17416 bool IsAdd = BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u32 ||
17417 BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u64;
17419 unsigned BitWidth = LHS.getBitWidth();
17420 unsigned CarryInBit = CarryIn.ugt(0) ? 1 : 0;
17423 ? (LHS.zext(BitWidth + 1) + (RHS.zext(BitWidth + 1) + CarryInBit))
17424 : (LHS.zext(BitWidth + 1) - (RHS.zext(BitWidth + 1) + CarryInBit));
17426 APInt Result = ExResult.extractBits(BitWidth, 0);
17427 uint64_t CarryOut = ExResult.extractBitsAsZExtValue(1, BitWidth);
17435 case clang::X86::BI__builtin_ia32_movmskps:
17436 case clang::X86::BI__builtin_ia32_movmskpd:
17437 case clang::X86::BI__builtin_ia32_pmovmskb128:
17438 case clang::X86::BI__builtin_ia32_pmovmskb256:
17439 case clang::X86::BI__builtin_ia32_movmskps256:
17440 case clang::X86::BI__builtin_ia32_movmskpd256: {
17447 unsigned ResultLen = Info.Ctx.getTypeSize(
17451 for (
unsigned I = 0; I != SourceLen; ++I) {
17453 if (ElemQT->isIntegerType()) {
17455 }
else if (ElemQT->isRealFloatingType()) {
17460 Result.setBitVal(I, Elem.isNegative());
17465 case clang::X86::BI__builtin_ia32_bextr_u32:
17466 case clang::X86::BI__builtin_ia32_bextr_u64:
17467 case clang::X86::BI__builtin_ia32_bextri_u32:
17468 case clang::X86::BI__builtin_ia32_bextri_u64: {
17474 unsigned BitWidth = Val.getBitWidth();
17476 uint64_t Length = Idx.extractBitsAsZExtValue(8, 8);
17477 Length = Length > BitWidth ? BitWidth : Length;
17480 if (Length == 0 || Shift >= BitWidth)
17484 Result &= llvm::maskTrailingOnes<uint64_t>(Length);
17488 case clang::X86::BI__builtin_ia32_bzhi_si:
17489 case clang::X86::BI__builtin_ia32_bzhi_di: {
17495 unsigned BitWidth = Val.getBitWidth();
17496 unsigned Index = Idx.extractBitsAsZExtValue(8, 0);
17497 if (Index < BitWidth)
17498 Val.clearHighBits(BitWidth - Index);
17502 case clang::X86::BI__builtin_ia32_ktestcqi:
17503 case clang::X86::BI__builtin_ia32_ktestchi:
17504 case clang::X86::BI__builtin_ia32_ktestcsi:
17505 case clang::X86::BI__builtin_ia32_ktestcdi: {
17511 return Success((~A & B) == 0, E);
17514 case clang::X86::BI__builtin_ia32_ktestzqi:
17515 case clang::X86::BI__builtin_ia32_ktestzhi:
17516 case clang::X86::BI__builtin_ia32_ktestzsi:
17517 case clang::X86::BI__builtin_ia32_ktestzdi: {
17523 return Success((A & B) == 0, E);
17526 case clang::X86::BI__builtin_ia32_kortestcqi:
17527 case clang::X86::BI__builtin_ia32_kortestchi:
17528 case clang::X86::BI__builtin_ia32_kortestcsi:
17529 case clang::X86::BI__builtin_ia32_kortestcdi: {
17535 return Success(~(A | B) == 0, E);
17538 case clang::X86::BI__builtin_ia32_kortestzqi:
17539 case clang::X86::BI__builtin_ia32_kortestzhi:
17540 case clang::X86::BI__builtin_ia32_kortestzsi:
17541 case clang::X86::BI__builtin_ia32_kortestzdi: {
17547 return Success((A | B) == 0, E);
17550 case clang::X86::BI__builtin_ia32_kunpckhi:
17551 case clang::X86::BI__builtin_ia32_kunpckdi:
17552 case clang::X86::BI__builtin_ia32_kunpcksi: {
17560 unsigned BW = A.getBitWidth();
17561 APSInt Result(A.trunc(BW / 2).concat(B.trunc(BW / 2)), A.isUnsigned());
17565 case clang::X86::BI__builtin_ia32_lzcnt_u16:
17566 case clang::X86::BI__builtin_ia32_lzcnt_u32:
17567 case clang::X86::BI__builtin_ia32_lzcnt_u64: {
17571 return Success(Val.countLeadingZeros(), E);
17574 case clang::X86::BI__builtin_ia32_tzcnt_u16:
17575 case clang::X86::BI__builtin_ia32_tzcnt_u32:
17576 case clang::X86::BI__builtin_ia32_tzcnt_u64: {
17580 return Success(Val.countTrailingZeros(), E);
17583 case clang::X86::BI__builtin_ia32_pdep_si:
17584 case clang::X86::BI__builtin_ia32_pdep_di: {
17590 unsigned BitWidth = Val.getBitWidth();
17592 for (
unsigned I = 0, P = 0; I != BitWidth; ++I)
17594 Result.setBitVal(I, Val[P++]);
17598 case clang::X86::BI__builtin_ia32_pext_si:
17599 case clang::X86::BI__builtin_ia32_pext_di: {
17605 unsigned BitWidth = Val.getBitWidth();
17607 for (
unsigned I = 0, P = 0; I != BitWidth; ++I)
17609 Result.setBitVal(P++, Val[I]);
17612 case X86::BI__builtin_ia32_ptestz128:
17613 case X86::BI__builtin_ia32_ptestz256:
17614 case X86::BI__builtin_ia32_vtestzps:
17615 case X86::BI__builtin_ia32_vtestzps256:
17616 case X86::BI__builtin_ia32_vtestzpd:
17617 case X86::BI__builtin_ia32_vtestzpd256: {
17619 [](
const APInt &A,
const APInt &B) {
return (A & B) == 0; });
17621 case X86::BI__builtin_ia32_ptestc128:
17622 case X86::BI__builtin_ia32_ptestc256:
17623 case X86::BI__builtin_ia32_vtestcps:
17624 case X86::BI__builtin_ia32_vtestcps256:
17625 case X86::BI__builtin_ia32_vtestcpd:
17626 case X86::BI__builtin_ia32_vtestcpd256: {
17628 [](
const APInt &A,
const APInt &B) {
return (~A & B) == 0; });
17630 case X86::BI__builtin_ia32_ptestnzc128:
17631 case X86::BI__builtin_ia32_ptestnzc256:
17632 case X86::BI__builtin_ia32_vtestnzcps:
17633 case X86::BI__builtin_ia32_vtestnzcps256:
17634 case X86::BI__builtin_ia32_vtestnzcpd:
17635 case X86::BI__builtin_ia32_vtestnzcpd256: {
17636 return EvalTestOp([](
const APInt &A,
const APInt &B) {
17637 return ((A & B) != 0) && ((~A & B) != 0);
17640 case X86::BI__builtin_ia32_kandqi:
17641 case X86::BI__builtin_ia32_kandhi:
17642 case X86::BI__builtin_ia32_kandsi:
17643 case X86::BI__builtin_ia32_kanddi: {
17644 return HandleMaskBinOp(
17645 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS & RHS; });
17648 case X86::BI__builtin_ia32_kandnqi:
17649 case X86::BI__builtin_ia32_kandnhi:
17650 case X86::BI__builtin_ia32_kandnsi:
17651 case X86::BI__builtin_ia32_kandndi: {
17652 return HandleMaskBinOp(
17653 [](
const APSInt &LHS,
const APSInt &RHS) {
return ~LHS & RHS; });
17656 case X86::BI__builtin_ia32_korqi:
17657 case X86::BI__builtin_ia32_korhi:
17658 case X86::BI__builtin_ia32_korsi:
17659 case X86::BI__builtin_ia32_kordi: {
17660 return HandleMaskBinOp(
17661 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS | RHS; });
17664 case X86::BI__builtin_ia32_kxnorqi:
17665 case X86::BI__builtin_ia32_kxnorhi:
17666 case X86::BI__builtin_ia32_kxnorsi:
17667 case X86::BI__builtin_ia32_kxnordi: {
17668 return HandleMaskBinOp(
17669 [](
const APSInt &LHS,
const APSInt &RHS) {
return ~(LHS ^ RHS); });
17672 case X86::BI__builtin_ia32_kxorqi:
17673 case X86::BI__builtin_ia32_kxorhi:
17674 case X86::BI__builtin_ia32_kxorsi:
17675 case X86::BI__builtin_ia32_kxordi: {
17676 return HandleMaskBinOp(
17677 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS ^ RHS; });
17680 case X86::BI__builtin_ia32_knotqi:
17681 case X86::BI__builtin_ia32_knothi:
17682 case X86::BI__builtin_ia32_knotsi:
17683 case X86::BI__builtin_ia32_knotdi: {
17691 case X86::BI__builtin_ia32_kaddqi:
17692 case X86::BI__builtin_ia32_kaddhi:
17693 case X86::BI__builtin_ia32_kaddsi:
17694 case X86::BI__builtin_ia32_kadddi: {
17695 return HandleMaskBinOp(
17696 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS + RHS; });
17699 case X86::BI__builtin_ia32_kmovb:
17700 case X86::BI__builtin_ia32_kmovw:
17701 case X86::BI__builtin_ia32_kmovd:
17702 case X86::BI__builtin_ia32_kmovq: {
17709 case X86::BI__builtin_ia32_kshiftliqi:
17710 case X86::BI__builtin_ia32_kshiftlihi:
17711 case X86::BI__builtin_ia32_kshiftlisi:
17712 case X86::BI__builtin_ia32_kshiftlidi: {
17713 return HandleMaskBinOp([](
const APSInt &LHS,
const APSInt &RHS) {
17714 unsigned Amt = RHS.getZExtValue() & 0xFF;
17715 if (Amt >= LHS.getBitWidth())
17716 return APSInt(APInt::getZero(LHS.getBitWidth()), LHS.isUnsigned());
17717 return APSInt(LHS.shl(Amt), LHS.isUnsigned());
17721 case X86::BI__builtin_ia32_kshiftriqi:
17722 case X86::BI__builtin_ia32_kshiftrihi:
17723 case X86::BI__builtin_ia32_kshiftrisi:
17724 case X86::BI__builtin_ia32_kshiftridi: {
17725 return HandleMaskBinOp([](
const APSInt &LHS,
const APSInt &RHS) {
17726 unsigned Amt = RHS.getZExtValue() & 0xFF;
17727 if (Amt >= LHS.getBitWidth())
17728 return APSInt(APInt::getZero(LHS.getBitWidth()), LHS.isUnsigned());
17729 return APSInt(LHS.lshr(Amt), LHS.isUnsigned());
17733 case clang::X86::BI__builtin_ia32_vec_ext_v4hi:
17734 case clang::X86::BI__builtin_ia32_vec_ext_v16qi:
17735 case clang::X86::BI__builtin_ia32_vec_ext_v8hi:
17736 case clang::X86::BI__builtin_ia32_vec_ext_v4si:
17737 case clang::X86::BI__builtin_ia32_vec_ext_v2di:
17738 case clang::X86::BI__builtin_ia32_vec_ext_v32qi:
17739 case clang::X86::BI__builtin_ia32_vec_ext_v16hi:
17740 case clang::X86::BI__builtin_ia32_vec_ext_v8si:
17741 case clang::X86::BI__builtin_ia32_vec_ext_v4di: {
17748 unsigned Idx =
static_cast<unsigned>(IdxAPS.getZExtValue() & (N - 1));
17752 case clang::X86::BI__builtin_ia32_cvtb2mask128:
17753 case clang::X86::BI__builtin_ia32_cvtb2mask256:
17754 case clang::X86::BI__builtin_ia32_cvtb2mask512:
17755 case clang::X86::BI__builtin_ia32_cvtw2mask128:
17756 case clang::X86::BI__builtin_ia32_cvtw2mask256:
17757 case clang::X86::BI__builtin_ia32_cvtw2mask512:
17758 case clang::X86::BI__builtin_ia32_cvtd2mask128:
17759 case clang::X86::BI__builtin_ia32_cvtd2mask256:
17760 case clang::X86::BI__builtin_ia32_cvtd2mask512:
17761 case clang::X86::BI__builtin_ia32_cvtq2mask128:
17762 case clang::X86::BI__builtin_ia32_cvtq2mask256:
17763 case clang::X86::BI__builtin_ia32_cvtq2mask512: {
17770 unsigned RetWidth = Info.Ctx.getIntWidth(E->
getType());
17771 llvm::APInt Bits(RetWidth, 0);
17773 for (
unsigned ElemNum = 0; ElemNum != VectorLen; ++ElemNum) {
17775 unsigned MSB = A[A.getBitWidth() - 1];
17776 Bits.setBitVal(ElemNum, MSB);
17779 APSInt RetMask(Bits,
true);
17783 case clang::X86::BI__builtin_ia32_cmpb128_mask:
17784 case clang::X86::BI__builtin_ia32_cmpw128_mask:
17785 case clang::X86::BI__builtin_ia32_cmpd128_mask:
17786 case clang::X86::BI__builtin_ia32_cmpq128_mask:
17787 case clang::X86::BI__builtin_ia32_cmpb256_mask:
17788 case clang::X86::BI__builtin_ia32_cmpw256_mask:
17789 case clang::X86::BI__builtin_ia32_cmpd256_mask:
17790 case clang::X86::BI__builtin_ia32_cmpq256_mask:
17791 case clang::X86::BI__builtin_ia32_cmpb512_mask:
17792 case clang::X86::BI__builtin_ia32_cmpw512_mask:
17793 case clang::X86::BI__builtin_ia32_cmpd512_mask:
17794 case clang::X86::BI__builtin_ia32_cmpq512_mask:
17795 case clang::X86::BI__builtin_ia32_ucmpb128_mask:
17796 case clang::X86::BI__builtin_ia32_ucmpw128_mask:
17797 case clang::X86::BI__builtin_ia32_ucmpd128_mask:
17798 case clang::X86::BI__builtin_ia32_ucmpq128_mask:
17799 case clang::X86::BI__builtin_ia32_ucmpb256_mask:
17800 case clang::X86::BI__builtin_ia32_ucmpw256_mask:
17801 case clang::X86::BI__builtin_ia32_ucmpd256_mask:
17802 case clang::X86::BI__builtin_ia32_ucmpq256_mask:
17803 case clang::X86::BI__builtin_ia32_ucmpb512_mask:
17804 case clang::X86::BI__builtin_ia32_ucmpw512_mask:
17805 case clang::X86::BI__builtin_ia32_ucmpd512_mask:
17806 case clang::X86::BI__builtin_ia32_ucmpq512_mask: {
17810 (BuiltinOp >= clang::X86::BI__builtin_ia32_ucmpb128_mask &&
17811 BuiltinOp <= clang::X86::BI__builtin_ia32_ucmpw512_mask);
17824 unsigned RetWidth = Mask.getBitWidth();
17826 APSInt RetMask(llvm::APInt(RetWidth, 0),
true);
17828 for (
unsigned ElemNum = 0; ElemNum < VectorLen; ++ElemNum) {
17833 switch (
Opcode.getExtValue() & 0x7) {
17838 Result = IsUnsigned ? A.ult(B) : A.slt(B);
17841 Result = IsUnsigned ? A.ule(B) : A.sle(B);
17850 Result = IsUnsigned ? A.uge(B) : A.sge(B);
17853 Result = IsUnsigned ? A.ugt(B) : A.sgt(B);
17860 RetMask.setBitVal(ElemNum, Mask[ElemNum] &&
Result);
17865 case X86::BI__builtin_ia32_vpshufbitqmb128_mask:
17866 case X86::BI__builtin_ia32_vpshufbitqmb256_mask:
17867 case X86::BI__builtin_ia32_vpshufbitqmb512_mask: {
17880 unsigned NumBytesInQWord = 8;
17881 unsigned NumBitsInByte = 8;
17883 unsigned NumQWords = NumBytes / NumBytesInQWord;
17884 unsigned RetWidth = ZeroMask.getBitWidth();
17885 APSInt RetMask(llvm::APInt(RetWidth, 0),
true);
17887 for (
unsigned QWordId = 0; QWordId != NumQWords; ++QWordId) {
17888 APInt SourceQWord(64, 0);
17889 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
17893 SourceQWord.insertBits(
APInt(8, Byte & 0xFF), ByteIdx * NumBitsInByte);
17896 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
17897 unsigned SelIdx = QWordId * NumBytesInQWord + ByteIdx;
17900 if (ZeroMask[SelIdx]) {
17901 RetMask.setBitVal(SelIdx, SourceQWord[M]);
17913 const LValue &LV) {
17916 if (!LV.getLValueBase())
17921 if (!LV.getLValueDesignator().Invalid &&
17922 !LV.getLValueDesignator().isOnePastTheEnd())
17932 if (LV.getLValueDesignator().Invalid)
17938 return LV.getLValueOffset() == Size;
17948class DataRecursiveIntBinOpEvaluator {
17949 struct EvalResult {
17951 bool Failed =
false;
17953 EvalResult() =
default;
17955 void swap(EvalResult &RHS) {
17957 Failed = RHS.Failed;
17958 RHS.Failed =
false;
17964 EvalResult LHSResult;
17965 enum { AnyExprKind, BinOpKind, BinOpVisitedLHSKind }
Kind;
17968 Job(Job &&) =
default;
17970 void startSpeculativeEval(EvalInfo &Info) {
17971 SpecEvalRAII = SpeculativeEvaluationRAII(Info);
17975 SpeculativeEvaluationRAII SpecEvalRAII;
17978 SmallVector<Job, 16> Queue;
17980 IntExprEvaluator &IntEval;
17985 DataRecursiveIntBinOpEvaluator(IntExprEvaluator &IntEval,
APValue &
Result)
17986 : IntEval(IntEval), Info(IntEval.getEvalInfo()), FinalResult(
Result) { }
17992 static bool shouldEnqueue(
const BinaryOperator *E) {
17999 bool Traverse(
const BinaryOperator *E) {
18001 EvalResult PrevResult;
18002 while (!Queue.empty())
18003 process(PrevResult);
18005 if (PrevResult.Failed)
return false;
18007 FinalResult.
swap(PrevResult.Val);
18018 bool Error(
const Expr *E) {
18019 return IntEval.Error(E);
18022 return IntEval.Error(E, D);
18025 OptionalDiagnostic CCEDiag(
const Expr *E,
diag::kind D) {
18026 return Info.CCEDiag(E, D);
18030 bool VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
18031 bool &SuppressRHSDiags);
18033 bool VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
18036 void EvaluateExpr(
const Expr *E, EvalResult &
Result) {
18042 void process(EvalResult &
Result);
18044 void enqueue(
const Expr *E) {
18046 Queue.resize(Queue.size()+1);
18047 Queue.back().E = E;
18048 Queue.back().Kind = Job::AnyExprKind;
18054bool DataRecursiveIntBinOpEvaluator::
18055 VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
18056 bool &SuppressRHSDiags) {
18059 if (LHSResult.Failed)
18060 return Info.noteSideEffect();
18069 if (LHSAsBool == (E->
getOpcode() == BO_LOr)) {
18070 Success(LHSAsBool, E, LHSResult.Val);
18074 LHSResult.Failed =
true;
18078 if (!Info.noteSideEffect())
18084 SuppressRHSDiags =
true;
18093 if (LHSResult.Failed && !Info.noteFailure())
18104 assert(!LVal.
hasLValuePath() &&
"have designator for integer lvalue");
18106 uint64_t Offset64 = Offset.getQuantity();
18107 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
18109 : Offset64 + Index64);
18112bool DataRecursiveIntBinOpEvaluator::
18113 VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
18116 if (RHSResult.Failed)
18123 bool lhsResult, rhsResult;
18138 if (rhsResult == (E->
getOpcode() == BO_LOr))
18149 if (LHSResult.Failed || RHSResult.Failed)
18152 const APValue &LHSVal = LHSResult.Val;
18153 const APValue &RHSVal = RHSResult.Val;
18177 if (!LHSExpr || !RHSExpr)
18179 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
18180 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
18181 if (!LHSAddrExpr || !RHSAddrExpr)
18206void DataRecursiveIntBinOpEvaluator::process(EvalResult &
Result) {
18207 Job &job = Queue.back();
18209 switch (job.Kind) {
18210 case Job::AnyExprKind: {
18211 if (
const BinaryOperator *Bop = dyn_cast<BinaryOperator>(job.E)) {
18212 if (shouldEnqueue(Bop)) {
18213 job.Kind = Job::BinOpKind;
18214 enqueue(Bop->getLHS());
18219 EvaluateExpr(job.E,
Result);
18224 case Job::BinOpKind: {
18226 bool SuppressRHSDiags =
false;
18227 if (!VisitBinOpLHSOnly(
Result, Bop, SuppressRHSDiags)) {
18231 if (SuppressRHSDiags)
18232 job.startSpeculativeEval(Info);
18233 job.LHSResult.swap(
Result);
18234 job.Kind = Job::BinOpVisitedLHSKind;
18239 case Job::BinOpVisitedLHSKind: {
18243 Result.Failed = !VisitBinOp(job.LHSResult, RHS, Bop,
Result.Val);
18249 llvm_unreachable(
"Invalid Job::Kind!");
18253enum class CmpResult {
18262template <
class SuccessCB,
class AfterCB>
18265 SuccessCB &&
Success, AfterCB &&DoAfter) {
18270 "unsupported binary expression evaluation");
18272 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
18286 if (!LHSOK && !Info.noteFailure())
18291 return Success(CmpResult::Less, E);
18293 return Success(CmpResult::Greater, E);
18294 return Success(CmpResult::Equal, E);
18298 APFixedPoint LHSFX(Info.Ctx.getFixedPointSemantics(LHSTy));
18299 APFixedPoint RHSFX(Info.Ctx.getFixedPointSemantics(RHSTy));
18302 if (!LHSOK && !Info.noteFailure())
18307 return Success(CmpResult::Less, E);
18309 return Success(CmpResult::Greater, E);
18310 return Success(CmpResult::Equal, E);
18314 ComplexValue LHS, RHS;
18323 LHS.makeComplexFloat();
18324 LHS.FloatImag = APFloat(LHS.FloatReal.getSemantics());
18329 if (!LHSOK && !Info.noteFailure())
18335 RHS.makeComplexFloat();
18336 RHS.FloatImag = APFloat(RHS.FloatReal.getSemantics());
18340 if (LHS.isComplexFloat()) {
18341 APFloat::cmpResult CR_r =
18342 LHS.getComplexFloatReal().compare(RHS.getComplexFloatReal());
18343 APFloat::cmpResult CR_i =
18344 LHS.getComplexFloatImag().compare(RHS.getComplexFloatImag());
18345 bool IsEqual = CR_r == APFloat::cmpEqual && CR_i == APFloat::cmpEqual;
18346 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal, E);
18348 assert(IsEquality &&
"invalid complex comparison");
18349 bool IsEqual = LHS.getComplexIntReal() == RHS.getComplexIntReal() &&
18350 LHS.getComplexIntImag() == RHS.getComplexIntImag();
18351 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal, E);
18357 APFloat RHS(0.0), LHS(0.0);
18360 if (!LHSOK && !Info.noteFailure())
18367 llvm::APFloatBase::cmpResult APFloatCmpResult = LHS.compare(RHS);
18368 if (!Info.InConstantContext &&
18369 APFloatCmpResult == APFloat::cmpUnordered &&
18372 Info.FFDiag(E, diag::note_constexpr_float_arithmetic_strict);
18375 auto GetCmpRes = [&]() {
18376 switch (APFloatCmpResult) {
18377 case APFloat::cmpEqual:
18378 return CmpResult::Equal;
18379 case APFloat::cmpLessThan:
18380 return CmpResult::Less;
18381 case APFloat::cmpGreaterThan:
18382 return CmpResult::Greater;
18383 case APFloat::cmpUnordered:
18384 return CmpResult::Unordered;
18386 llvm_unreachable(
"Unrecognised APFloat::cmpResult enum");
18388 return Success(GetCmpRes(), E);
18392 LValue LHSValue, RHSValue;
18395 if (!LHSOK && !Info.noteFailure())
18406 if (Info.checkingPotentialConstantExpression() &&
18407 (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown))
18409 auto DiagComparison = [&] (
unsigned DiagID,
bool Reversed =
false) {
18410 std::string LHS = LHSValue.toString(Info.Ctx, E->
getLHS()->
getType());
18411 std::string RHS = RHSValue.toString(Info.Ctx, E->
getRHS()->
getType());
18412 Info.FFDiag(E, DiagID)
18419 return DiagComparison(
18420 diag::note_constexpr_pointer_comparison_unspecified);
18426 if ((!LHSValue.Base && !LHSValue.Offset.
isZero()) ||
18427 (!RHSValue.Base && !RHSValue.Offset.
isZero()))
18428 return DiagComparison(diag::note_constexpr_pointer_constant_comparison,
18442 return DiagComparison(diag::note_constexpr_literal_comparison);
18444 return DiagComparison(diag::note_constexpr_opaque_call_comparison,
18449 return DiagComparison(diag::note_constexpr_pointer_weak_comparison,
18453 if (LHSValue.Base && LHSValue.Offset.
isZero() &&
18455 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
18457 if (RHSValue.Base && RHSValue.Offset.
isZero() &&
18459 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
18465 return DiagComparison(
18466 diag::note_constexpr_pointer_comparison_zero_sized);
18467 if (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown)
18468 return DiagComparison(
18469 diag::note_constexpr_pointer_comparison_unspecified);
18471 return Success(CmpResult::Unequal, E);
18474 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
18475 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
18477 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
18478 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
18488 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid && IsRelational) {
18489 bool WasArrayIndex;
18492 :
getType(LHSValue.Base).getNonReferenceType(),
18493 LHSDesignator, RHSDesignator, WasArrayIndex);
18500 if (!WasArrayIndex && Mismatch < LHSDesignator.Entries.size() &&
18501 Mismatch < RHSDesignator.Entries.size()) {
18502 const FieldDecl *LF = getAsField(LHSDesignator.Entries[Mismatch]);
18503 const FieldDecl *RF = getAsField(RHSDesignator.Entries[Mismatch]);
18505 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_classes);
18507 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
18508 << getAsBaseClass(LHSDesignator.Entries[Mismatch])
18511 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
18512 << getAsBaseClass(RHSDesignator.Entries[Mismatch])
18517 diag::note_constexpr_pointer_comparison_differing_access)
18525 unsigned PtrSize = Info.Ctx.getTypeSize(LHSTy);
18528 assert(PtrSize <= 64 &&
"Unexpected pointer width");
18529 uint64_t Mask = ~0ULL >> (64 - PtrSize);
18530 CompareLHS &= Mask;
18531 CompareRHS &= Mask;
18536 if (!LHSValue.Base.
isNull() && IsRelational) {
18540 CharUnits Size = Info.Ctx.getTypeSizeInChars(BaseTy);
18541 uint64_t OffsetLimit = Size.getQuantity();
18542 if (CompareLHS > OffsetLimit || CompareRHS > OffsetLimit)
18546 if (CompareLHS < CompareRHS)
18547 return Success(CmpResult::Less, E);
18548 if (CompareLHS > CompareRHS)
18549 return Success(CmpResult::Greater, E);
18550 return Success(CmpResult::Equal, E);
18554 assert(IsEquality &&
"unexpected member pointer operation");
18557 MemberPtr LHSValue, RHSValue;
18560 if (!LHSOK && !Info.noteFailure())
18568 if (LHSValue.getDecl() && LHSValue.getDecl()->isWeak()) {
18569 Info.FFDiag(E, diag::note_constexpr_mem_pointer_weak_comparison)
18570 << LHSValue.getDecl();
18573 if (RHSValue.getDecl() && RHSValue.getDecl()->isWeak()) {
18574 Info.FFDiag(E, diag::note_constexpr_mem_pointer_weak_comparison)
18575 << RHSValue.getDecl();
18582 if (!LHSValue.getDecl() || !RHSValue.getDecl()) {
18583 bool Equal = !LHSValue.getDecl() && !RHSValue.getDecl();
18584 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal, E);
18589 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(LHSValue.getDecl()))
18590 if (MD->isVirtual())
18591 Info.CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
18592 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(RHSValue.getDecl()))
18593 if (MD->isVirtual())
18594 Info.CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
18600 bool Equal = LHSValue == RHSValue;
18601 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal, E);
18606 assert(RHSTy->
isNullPtrType() &&
"missing pointer conversion");
18614 return Success(CmpResult::Equal, E);
18620bool RecordExprEvaluator::VisitBinCmp(
const BinaryOperator *E) {
18624 auto OnSuccess = [&](CmpResult CR,
const BinaryOperator *E) {
18627 case CmpResult::Unequal:
18628 llvm_unreachable(
"should never produce Unequal for three-way comparison");
18629 case CmpResult::Less:
18630 CCR = ComparisonCategoryResult::Less;
18632 case CmpResult::Equal:
18633 CCR = ComparisonCategoryResult::Equal;
18635 case CmpResult::Greater:
18636 CCR = ComparisonCategoryResult::Greater;
18638 case CmpResult::Unordered:
18639 CCR = ComparisonCategoryResult::Unordered;
18644 const ComparisonCategoryInfo &CmpInfo =
18645 Info.Ctx.CompCategories.getInfoForType(E->
getType());
18653 ConstantExprKind::Normal);
18656 return ExprEvaluatorBaseTy::VisitBinCmp(E);
18660bool RecordExprEvaluator::VisitCXXParenListInitExpr(
18661 const CXXParenListInitExpr *E) {
18662 return VisitCXXParenListOrInitListExpr(E, E->
getInitExprs());
18665bool IntExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
18670 if (!Info.noteFailure())
18674 if (DataRecursiveIntBinOpEvaluator::shouldEnqueue(E))
18675 return DataRecursiveIntBinOpEvaluator(*
this,
Result).Traverse(E);
18679 "DataRecursiveIntBinOpEvaluator should have handled integral types");
18684 auto OnSuccess = [&](CmpResult CR,
const BinaryOperator *E) {
18685 assert((CR != CmpResult::Unequal || E->
isEqualityOp()) &&
18686 "should only produce Unequal for equality comparisons");
18687 bool IsEqual = CR == CmpResult::Equal,
18688 IsLess = CR == CmpResult::Less,
18689 IsGreater = CR == CmpResult::Greater;
18693 llvm_unreachable(
"unsupported binary operator");
18696 return Success(IsEqual == (Op == BO_EQ), E);
18700 return Success(IsGreater, E);
18702 return Success(IsEqual || IsLess, E);
18704 return Success(IsEqual || IsGreater, E);
18708 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
18717 LValue LHSValue, RHSValue;
18720 if (!LHSOK && !Info.noteFailure())
18729 if (Info.checkingPotentialConstantExpression() &&
18730 (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown))
18733 const Expr *LHSExpr = LHSValue.Base.
dyn_cast<
const Expr *>();
18734 const Expr *RHSExpr = RHSValue.Base.
dyn_cast<
const Expr *>();
18736 auto DiagArith = [&](
unsigned DiagID) {
18737 std::string LHS = LHSValue.toString(Info.Ctx, E->
getLHS()->
getType());
18738 std::string RHS = RHSValue.toString(Info.Ctx, E->
getRHS()->
getType());
18739 Info.FFDiag(E, DiagID) << LHS << RHS;
18740 if (LHSExpr && LHSExpr == RHSExpr)
18742 diag::note_constexpr_repeated_literal_eval)
18747 if (!LHSExpr || !RHSExpr)
18748 return DiagArith(diag::note_constexpr_pointer_arith_unspecified);
18751 return DiagArith(diag::note_constexpr_literal_arith);
18753 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
18754 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
18755 if (!LHSAddrExpr || !RHSAddrExpr)
18763 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
18764 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
18766 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
18767 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
18773 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid &&
18776 Info.CCEDiag(E, diag::note_constexpr_pointer_subtraction_not_same_array);
18781 CharUnits ElementSize;
18788 if (ElementSize.
isZero()) {
18789 Info.FFDiag(E, diag::note_constexpr_pointer_subtraction_zero_size)
18806 APSInt TrueResult = (LHS - RHS) / ElemSize;
18809 if (
Result.extend(65) != TrueResult &&
18815 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
18820bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr(
18821 const UnaryExprOrTypeTraitExpr *E) {
18823 case UETT_PreferredAlignOf:
18824 case UETT_AlignOf: {
18833 case UETT_PtrAuthTypeDiscriminator: {
18839 case UETT_VecStep: {
18843 unsigned n = Ty->
castAs<VectorType>()->getNumElements();
18855 case UETT_DataSizeOf:
18856 case UETT_SizeOf: {
18860 if (
const ReferenceType *Ref = SrcTy->
getAs<ReferenceType>())
18871 case UETT_OpenMPRequiredSimdAlign:
18874 Info.Ctx.toCharUnitsFromBits(
18878 case UETT_VectorElements: {
18882 if (
const auto *VT = Ty->
getAs<VectorType>())
18886 if (Info.InConstantContext)
18887 Info.CCEDiag(E, diag::note_constexpr_non_const_vectorelements)
18892 case UETT_CountOf: {
18898 if (
const auto *CAT =
18908 const auto *VAT = Info.Ctx.getAsVariableArrayType(Ty);
18910 if (VAT->getElementType()->isArrayType()) {
18913 if (!VAT->getSizeExpr()) {
18918 std::optional<APSInt> Res =
18919 VAT->getSizeExpr()->getIntegerConstantExpr(Info.Ctx);
18924 static_cast<unsigned>(Info.Ctx.getTypeSize(Info.Ctx.getSizeType())),
18925 Res->getZExtValue()};
18937 llvm_unreachable(
"unknown expr/type trait");
18940bool IntExprEvaluator::VisitOffsetOfExpr(
const OffsetOfExpr *OOE) {
18941 Info.Ctx.recordOffsetOfEvaluation(OOE);
18947 for (
unsigned i = 0; i != n; ++i) {
18955 const ArrayType *AT = Info.Ctx.getAsArrayType(CurrentType);
18959 CharUnits ElementSize = Info.Ctx.getTypeSizeInChars(CurrentType);
18960 Result += IdxResult.getSExtValue() * ElementSize;
18965 FieldDecl *MemberDecl = ON.
getField();
18970 const ASTRecordLayout &RL = Info.Ctx.getASTRecordLayout(RD);
18972 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
18979 llvm_unreachable(
"dependent __builtin_offsetof");
18982 CXXBaseSpecifier *BaseSpec = ON.
getBase();
18991 const ASTRecordLayout &RL = Info.Ctx.getASTRecordLayout(RD);
18994 CurrentType = BaseSpec->
getType();
19008bool IntExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
19028 if (Info.checkingForUndefinedBehavior())
19029 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
19030 diag::warn_integer_constant_overflow)
19058bool IntExprEvaluator::VisitCastExpr(
const CastExpr *E) {
19060 QualType DestType = E->
getType();
19061 QualType SrcType = SubExpr->
getType();
19064 case CK_BaseToDerived:
19065 case CK_DerivedToBase:
19066 case CK_UncheckedDerivedToBase:
19069 case CK_ArrayToPointerDecay:
19070 case CK_FunctionToPointerDecay:
19071 case CK_NullToPointer:
19072 case CK_NullToMemberPointer:
19073 case CK_BaseToDerivedMemberPointer:
19074 case CK_DerivedToBaseMemberPointer:
19075 case CK_ReinterpretMemberPointer:
19076 case CK_ConstructorConversion:
19077 case CK_IntegralToPointer:
19079 case CK_VectorSplat:
19080 case CK_IntegralToFloating:
19081 case CK_FloatingCast:
19082 case CK_CPointerToObjCPointerCast:
19083 case CK_BlockPointerToObjCPointerCast:
19084 case CK_AnyPointerToBlockPointerCast:
19085 case CK_ObjCObjectLValueCast:
19086 case CK_FloatingRealToComplex:
19087 case CK_FloatingComplexToReal:
19088 case CK_FloatingComplexCast:
19089 case CK_FloatingComplexToIntegralComplex:
19090 case CK_IntegralRealToComplex:
19091 case CK_IntegralComplexCast:
19092 case CK_IntegralComplexToFloatingComplex:
19093 case CK_BuiltinFnToFnPtr:
19094 case CK_ZeroToOCLOpaqueType:
19095 case CK_NonAtomicToAtomic:
19096 case CK_AddressSpaceConversion:
19097 case CK_IntToOCLSampler:
19098 case CK_FloatingToFixedPoint:
19099 case CK_FixedPointToFloating:
19100 case CK_FixedPointCast:
19101 case CK_IntegralToFixedPoint:
19102 case CK_MatrixCast:
19103 case CK_HLSLAggregateSplatCast:
19104 llvm_unreachable(
"invalid cast kind for integral value");
19108 case CK_LValueBitCast:
19109 case CK_ARCProduceObject:
19110 case CK_ARCConsumeObject:
19111 case CK_ARCReclaimReturnedObject:
19112 case CK_ARCExtendBlockObject:
19113 case CK_CopyAndAutoreleaseBlockObject:
19116 case CK_UserDefinedConversion:
19117 case CK_LValueToRValue:
19118 case CK_AtomicToNonAtomic:
19120 case CK_LValueToRValueBitCast:
19121 case CK_HLSLArrayRValue:
19122 return ExprEvaluatorBaseTy::VisitCastExpr(E);
19124 case CK_MemberPointerToBoolean:
19125 case CK_PointerToBoolean:
19126 case CK_IntegralToBoolean:
19127 case CK_FloatingToBoolean:
19128 case CK_BooleanToSignedIntegral:
19129 case CK_FloatingComplexToBoolean:
19130 case CK_IntegralComplexToBoolean: {
19135 if (BoolResult && E->
getCastKind() == CK_BooleanToSignedIntegral)
19137 return Success(IntResult, E);
19140 case CK_FixedPointToIntegral: {
19141 APFixedPoint Src(Info.Ctx.getFixedPointSemantics(SrcType));
19145 llvm::APSInt
Result = Src.convertToInt(
19146 Info.Ctx.getIntWidth(DestType),
19153 case CK_FixedPointToBoolean: {
19156 if (!
Evaluate(Val, Info, SubExpr))
19161 case CK_IntegralCast: {
19162 if (!Visit(SubExpr))
19172 if (
Result.isAddrLabelDiff()) {
19173 unsigned DestBits = Info.Ctx.getTypeSize(DestType);
19174 return DestBits >= 32 && DestBits <= Info.Ctx.getTypeSize(SrcType);
19177 return Info.Ctx.getTypeSize(DestType) == Info.Ctx.getTypeSize(SrcType);
19180 if (Info.Ctx.getLangOpts().CPlusPlus && DestType->
isEnumeralType()) {
19192 if (!ED->isFixed()) {
19196 ED->getValueRange(
Max,
Min);
19199 if (ED->getNumNegativeBits() &&
19200 (
Max.slt(
Result.getInt().getSExtValue()) ||
19201 Min.sgt(
Result.getInt().getSExtValue())))
19202 Info.CCEDiag(E, diag::note_constexpr_unscoped_enum_out_of_range)
19203 << llvm::toString(
Result.getInt(), 10) <<
Min.getSExtValue()
19204 <<
Max.getSExtValue() << ED;
19205 else if (!ED->getNumNegativeBits() &&
19206 Max.ult(
Result.getInt().getZExtValue()))
19207 Info.CCEDiag(E, diag::note_constexpr_unscoped_enum_out_of_range)
19208 << llvm::toString(
Result.getInt(), 10) <<
Min.getZExtValue()
19209 <<
Max.getZExtValue() << ED;
19217 case CK_PointerToIntegral: {
19218 CCEDiag(E, diag::note_constexpr_invalid_cast)
19219 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
19226 if (LV.getLValueBase()) {
19231 if (Info.Ctx.getTypeSize(DestType) != Info.Ctx.getTypeSize(SrcType))
19234 LV.Designator.setInvalid();
19242 if (!
V.toIntegralConstant(AsInt, SrcType, Info.Ctx))
19243 llvm_unreachable(
"Can't cast this!");
19248 case CK_IntegralComplexToReal: {
19252 return Success(
C.getComplexIntReal(), E);
19255 case CK_FloatingToIntegral: {
19265 case CK_HLSLVectorTruncation: {
19271 case CK_HLSLMatrixTruncation: {
19277 case CK_HLSLElementwiseCast: {
19290 return Success(ResultVal, E);
19294 llvm_unreachable(
"unknown cast resulting in integral value");
19297bool IntExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
19302 if (!LV.isComplexInt())
19304 return Success(LV.getComplexIntReal(), E);
19310bool IntExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
19315 if (!LV.isComplexInt())
19317 return Success(LV.getComplexIntImag(), E);
19324bool IntExprEvaluator::VisitSizeOfPackExpr(
const SizeOfPackExpr *E) {
19328bool IntExprEvaluator::VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E) {
19332bool IntExprEvaluator::VisitConceptSpecializationExpr(
19333 const ConceptSpecializationExpr *E) {
19337bool IntExprEvaluator::VisitRequiresExpr(
const RequiresExpr *E) {
19341bool FixedPointExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
19351 if (!
Result.isFixedPoint())
19354 APFixedPoint Negated =
Result.getFixedPoint().negate(&Overflowed);
19368bool FixedPointExprEvaluator::VisitCastExpr(
const CastExpr *E) {
19370 QualType DestType = E->
getType();
19372 "Expected destination type to be a fixed point type");
19373 auto DestFXSema = Info.Ctx.getFixedPointSemantics(DestType);
19376 case CK_FixedPointCast: {
19377 APFixedPoint Src(Info.Ctx.getFixedPointSemantics(SubExpr->
getType()));
19381 APFixedPoint
Result = Src.convert(DestFXSema, &Overflowed);
19383 if (Info.checkingForUndefinedBehavior())
19384 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
19385 diag::warn_fixedpoint_constant_overflow)
19392 case CK_IntegralToFixedPoint: {
19398 APFixedPoint IntResult = APFixedPoint::getFromIntValue(
19399 Src, Info.Ctx.getFixedPointSemantics(DestType), &Overflowed);
19402 if (Info.checkingForUndefinedBehavior())
19403 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
19404 diag::warn_fixedpoint_constant_overflow)
19405 << IntResult.toString() << E->
getType();
19410 return Success(IntResult, E);
19412 case CK_FloatingToFixedPoint: {
19418 APFixedPoint
Result = APFixedPoint::getFromFloatValue(
19419 Src, Info.Ctx.getFixedPointSemantics(DestType), &Overflowed);
19422 if (Info.checkingForUndefinedBehavior())
19423 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
19424 diag::warn_fixedpoint_constant_overflow)
19433 case CK_LValueToRValue:
19434 return ExprEvaluatorBaseTy::VisitCastExpr(E);
19440bool FixedPointExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
19442 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
19444 const Expr *LHS = E->
getLHS();
19445 const Expr *RHS = E->
getRHS();
19447 Info.Ctx.getFixedPointSemantics(E->
getType());
19449 APFixedPoint LHSFX(Info.Ctx.getFixedPointSemantics(LHS->
getType()));
19452 APFixedPoint RHSFX(Info.Ctx.getFixedPointSemantics(RHS->
getType()));
19456 bool OpOverflow =
false, ConversionOverflow =
false;
19457 APFixedPoint
Result(LHSFX.getSemantics());
19460 Result = LHSFX.add(RHSFX, &OpOverflow)
19461 .convert(ResultFXSema, &ConversionOverflow);
19465 Result = LHSFX.sub(RHSFX, &OpOverflow)
19466 .convert(ResultFXSema, &ConversionOverflow);
19470 Result = LHSFX.mul(RHSFX, &OpOverflow)
19471 .convert(ResultFXSema, &ConversionOverflow);
19475 if (RHSFX.getValue() == 0) {
19476 Info.FFDiag(E, diag::note_expr_divide_by_zero);
19479 Result = LHSFX.div(RHSFX, &OpOverflow)
19480 .convert(ResultFXSema, &ConversionOverflow);
19486 llvm::APSInt RHSVal = RHSFX.getValue();
19489 LHSSema.getWidth() - (unsigned)LHSSema.hasUnsignedPadding();
19490 unsigned Amt = RHSVal.getLimitedValue(ShiftBW - 1);
19494 if (RHSVal.isNegative())
19495 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHSVal;
19496 else if (Amt != RHSVal)
19497 Info.CCEDiag(E, diag::note_constexpr_large_shift)
19498 << RHSVal << E->
getType() << ShiftBW;
19501 Result = LHSFX.shl(Amt, &OpOverflow);
19503 Result = LHSFX.shr(Amt, &OpOverflow);
19509 if (OpOverflow || ConversionOverflow) {
19510 if (Info.checkingForUndefinedBehavior())
19511 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
19512 diag::warn_fixedpoint_constant_overflow)
19525class FloatExprEvaluator
19526 :
public ExprEvaluatorBase<FloatExprEvaluator> {
19529 FloatExprEvaluator(EvalInfo &info, APFloat &result)
19530 : ExprEvaluatorBaseTy(info),
Result(result) {}
19537 bool ZeroInitialization(
const Expr *E) {
19538 Result = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(E->
getType()));
19542 bool VisitCallExpr(
const CallExpr *E);
19544 bool VisitUnaryOperator(
const UnaryOperator *E);
19545 bool VisitBinaryOperator(
const BinaryOperator *E);
19546 bool VisitFloatingLiteral(
const FloatingLiteral *E);
19547 bool VisitCastExpr(
const CastExpr *E);
19549 bool VisitUnaryReal(
const UnaryOperator *E);
19550 bool VisitUnaryImag(
const UnaryOperator *E);
19559 return FloatExprEvaluator(Info, Result).Visit(E);
19566 llvm::APFloat &Result) {
19568 if (!S)
return false;
19570 const llvm::fltSemantics &Sem = Context.getFloatTypeSemantics(ResultTy);
19576 fill = llvm::APInt(32, 0);
19577 else if (S->
getString().getAsInteger(0, fill))
19580 if (Context.getTargetInfo().isNan2008()) {
19582 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
19584 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
19592 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
19594 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
19600bool FloatExprEvaluator::VisitCallExpr(
const CallExpr *E) {
19601 if (!IsConstantEvaluatedBuiltinCall(E))
19602 return ExprEvaluatorBaseTy::VisitCallExpr(E);
19608 case Builtin::BI__builtin_huge_val:
19609 case Builtin::BI__builtin_huge_valf:
19610 case Builtin::BI__builtin_huge_vall:
19611 case Builtin::BI__builtin_huge_valf16:
19612 case Builtin::BI__builtin_huge_valf128:
19613 case Builtin::BI__builtin_inf:
19614 case Builtin::BI__builtin_inff:
19615 case Builtin::BI__builtin_infl:
19616 case Builtin::BI__builtin_inff16:
19617 case Builtin::BI__builtin_inff128: {
19618 const llvm::fltSemantics &Sem =
19619 Info.Ctx.getFloatTypeSemantics(E->
getType());
19620 Result = llvm::APFloat::getInf(Sem);
19624 case Builtin::BI__builtin_nans:
19625 case Builtin::BI__builtin_nansf:
19626 case Builtin::BI__builtin_nansl:
19627 case Builtin::BI__builtin_nansf16:
19628 case Builtin::BI__builtin_nansf128:
19634 case Builtin::BI__builtin_nan:
19635 case Builtin::BI__builtin_nanf:
19636 case Builtin::BI__builtin_nanl:
19637 case Builtin::BI__builtin_nanf16:
19638 case Builtin::BI__builtin_nanf128:
19646 case Builtin::BI__builtin_elementwise_abs:
19647 case Builtin::BI__builtin_fabs:
19648 case Builtin::BI__builtin_fabsf:
19649 case Builtin::BI__builtin_fabsl:
19650 case Builtin::BI__builtin_fabsf128:
19659 if (
Result.isNegative())
19663 case Builtin::BI__arithmetic_fence:
19670 case Builtin::BI__builtin_copysign:
19671 case Builtin::BI__builtin_copysignf:
19672 case Builtin::BI__builtin_copysignl:
19673 case Builtin::BI__builtin_copysignf128: {
19682 case Builtin::BI__builtin_fmax:
19683 case Builtin::BI__builtin_fmaxf:
19684 case Builtin::BI__builtin_fmaxl:
19685 case Builtin::BI__builtin_fmaxf16:
19686 case Builtin::BI__builtin_fmaxf128: {
19695 case Builtin::BI__builtin_fmin:
19696 case Builtin::BI__builtin_fminf:
19697 case Builtin::BI__builtin_fminl:
19698 case Builtin::BI__builtin_fminf16:
19699 case Builtin::BI__builtin_fminf128: {
19708 case Builtin::BI__builtin_fmaximum_num:
19709 case Builtin::BI__builtin_fmaximum_numf:
19710 case Builtin::BI__builtin_fmaximum_numl:
19711 case Builtin::BI__builtin_fmaximum_numf16:
19712 case Builtin::BI__builtin_fmaximum_numf128: {
19721 case Builtin::BI__builtin_fminimum_num:
19722 case Builtin::BI__builtin_fminimum_numf:
19723 case Builtin::BI__builtin_fminimum_numl:
19724 case Builtin::BI__builtin_fminimum_numf16:
19725 case Builtin::BI__builtin_fminimum_numf128: {
19734 case Builtin::BI__builtin_elementwise_fma: {
19739 APFloat SourceY(0.), SourceZ(0.);
19745 (void)
Result.fusedMultiplyAdd(SourceY, SourceZ, RM);
19749 case clang::X86::BI__builtin_ia32_vec_ext_v4sf: {
19756 unsigned Idx =
static_cast<unsigned>(IdxAPS.getZExtValue() & (N - 1));
19762bool FloatExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
19774bool FloatExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
19784 const llvm::fltSemantics &Sem = Info.Ctx.getFloatTypeSemantics(E->
getType());
19785 Result = llvm::APFloat::getZero(Sem);
19789bool FloatExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
19791 default:
return Error(E);
19805bool FloatExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
19807 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
19811 if (!LHSOK && !Info.noteFailure())
19817bool FloatExprEvaluator::VisitFloatingLiteral(
const FloatingLiteral *E) {
19822bool FloatExprEvaluator::VisitCastExpr(
const CastExpr *E) {
19827 return ExprEvaluatorBaseTy::VisitCastExpr(E);
19829 case CK_HLSLAggregateSplatCast:
19830 llvm_unreachable(
"invalid cast kind for floating value");
19832 case CK_IntegralToFloating: {
19835 Info.Ctx.getLangOpts());
19841 case CK_FixedPointToFloating: {
19842 APFixedPoint FixResult(Info.Ctx.getFixedPointSemantics(SubExpr->
getType()));
19846 FixResult.convertToFloat(Info.Ctx.getFloatTypeSemantics(E->
getType()));
19850 case CK_FloatingCast: {
19851 if (!Visit(SubExpr))
19857 case CK_FloatingComplexToReal: {
19861 Result =
V.getComplexFloatReal();
19864 case CK_HLSLVectorTruncation: {
19870 case CK_HLSLMatrixTruncation: {
19876 case CK_HLSLElementwiseCast: {
19891 return Success(ResultVal, E);
19901class ComplexExprEvaluator
19902 :
public ExprEvaluatorBase<ComplexExprEvaluator> {
19906 ComplexExprEvaluator(EvalInfo &info, ComplexValue &
Result)
19914 bool ZeroInitialization(
const Expr *E);
19920 bool VisitImaginaryLiteral(
const ImaginaryLiteral *E);
19921 bool VisitCastExpr(
const CastExpr *E);
19922 bool VisitBinaryOperator(
const BinaryOperator *E);
19923 bool VisitUnaryOperator(
const UnaryOperator *E);
19924 bool VisitInitListExpr(
const InitListExpr *E);
19925 bool VisitCallExpr(
const CallExpr *E);
19933 return ComplexExprEvaluator(Info, Result).Visit(E);
19936bool ComplexExprEvaluator::ZeroInitialization(
const Expr *E) {
19937 QualType ElemTy = E->
getType()->
castAs<ComplexType>()->getElementType();
19939 Result.makeComplexFloat();
19940 APFloat Zero = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(ElemTy));
19944 Result.makeComplexInt();
19945 APSInt Zero = Info.Ctx.MakeIntValue(0, ElemTy);
19952bool ComplexExprEvaluator::VisitImaginaryLiteral(
const ImaginaryLiteral *E) {
19956 Result.makeComplexFloat();
19965 "Unexpected imaginary literal.");
19967 Result.makeComplexInt();
19972 Result.IntReal =
APSInt(Imag.getBitWidth(), !Imag.isSigned());
19977bool ComplexExprEvaluator::VisitCastExpr(
const CastExpr *E) {
19981 case CK_BaseToDerived:
19982 case CK_DerivedToBase:
19983 case CK_UncheckedDerivedToBase:
19986 case CK_ArrayToPointerDecay:
19987 case CK_FunctionToPointerDecay:
19988 case CK_NullToPointer:
19989 case CK_NullToMemberPointer:
19990 case CK_BaseToDerivedMemberPointer:
19991 case CK_DerivedToBaseMemberPointer:
19992 case CK_MemberPointerToBoolean:
19993 case CK_ReinterpretMemberPointer:
19994 case CK_ConstructorConversion:
19995 case CK_IntegralToPointer:
19996 case CK_PointerToIntegral:
19997 case CK_PointerToBoolean:
19999 case CK_VectorSplat:
20000 case CK_IntegralCast:
20001 case CK_BooleanToSignedIntegral:
20002 case CK_IntegralToBoolean:
20003 case CK_IntegralToFloating:
20004 case CK_FloatingToIntegral:
20005 case CK_FloatingToBoolean:
20006 case CK_FloatingCast:
20007 case CK_CPointerToObjCPointerCast:
20008 case CK_BlockPointerToObjCPointerCast:
20009 case CK_AnyPointerToBlockPointerCast:
20010 case CK_ObjCObjectLValueCast:
20011 case CK_FloatingComplexToReal:
20012 case CK_FloatingComplexToBoolean:
20013 case CK_IntegralComplexToReal:
20014 case CK_IntegralComplexToBoolean:
20015 case CK_ARCProduceObject:
20016 case CK_ARCConsumeObject:
20017 case CK_ARCReclaimReturnedObject:
20018 case CK_ARCExtendBlockObject:
20019 case CK_CopyAndAutoreleaseBlockObject:
20020 case CK_BuiltinFnToFnPtr:
20021 case CK_ZeroToOCLOpaqueType:
20022 case CK_NonAtomicToAtomic:
20023 case CK_AddressSpaceConversion:
20024 case CK_IntToOCLSampler:
20025 case CK_FloatingToFixedPoint:
20026 case CK_FixedPointToFloating:
20027 case CK_FixedPointCast:
20028 case CK_FixedPointToBoolean:
20029 case CK_FixedPointToIntegral:
20030 case CK_IntegralToFixedPoint:
20031 case CK_MatrixCast:
20032 case CK_HLSLVectorTruncation:
20033 case CK_HLSLMatrixTruncation:
20034 case CK_HLSLElementwiseCast:
20035 case CK_HLSLAggregateSplatCast:
20036 llvm_unreachable(
"invalid cast kind for complex value");
20038 case CK_LValueToRValue:
20039 case CK_AtomicToNonAtomic:
20041 case CK_LValueToRValueBitCast:
20042 case CK_HLSLArrayRValue:
20043 return ExprEvaluatorBaseTy::VisitCastExpr(E);
20046 case CK_LValueBitCast:
20047 case CK_UserDefinedConversion:
20050 case CK_FloatingRealToComplex: {
20055 Result.makeComplexFloat();
20060 case CK_FloatingComplexCast: {
20064 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
20072 case CK_FloatingComplexToIntegralComplex: {
20076 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
20079 Result.makeComplexInt();
20086 case CK_IntegralRealToComplex: {
20091 Result.makeComplexInt();
20092 Result.IntImag =
APSInt(Real.getBitWidth(), !Real.isSigned());
20096 case CK_IntegralComplexCast: {
20100 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
20109 case CK_IntegralComplexToFloatingComplex: {
20114 Info.Ctx.getLangOpts());
20115 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
20118 Result.makeComplexFloat();
20120 To,
Result.FloatReal) &&
20126 llvm_unreachable(
"unknown cast resulting in complex value");
20131 const uint8_t GFInv[256] = {
20132 0x00, 0x01, 0x8d, 0xf6, 0xcb, 0x52, 0x7b, 0xd1, 0xe8, 0x4f, 0x29, 0xc0,
20133 0xb0, 0xe1, 0xe5, 0xc7, 0x74, 0xb4, 0xaa, 0x4b, 0x99, 0x2b, 0x60, 0x5f,
20134 0x58, 0x3f, 0xfd, 0xcc, 0xff, 0x40, 0xee, 0xb2, 0x3a, 0x6e, 0x5a, 0xf1,
20135 0x55, 0x4d, 0xa8, 0xc9, 0xc1, 0x0a, 0x98, 0x15, 0x30, 0x44, 0xa2, 0xc2,
20136 0x2c, 0x45, 0x92, 0x6c, 0xf3, 0x39, 0x66, 0x42, 0xf2, 0x35, 0x20, 0x6f,
20137 0x77, 0xbb, 0x59, 0x19, 0x1d, 0xfe, 0x37, 0x67, 0x2d, 0x31, 0xf5, 0x69,
20138 0xa7, 0x64, 0xab, 0x13, 0x54, 0x25, 0xe9, 0x09, 0xed, 0x5c, 0x05, 0xca,
20139 0x4c, 0x24, 0x87, 0xbf, 0x18, 0x3e, 0x22, 0xf0, 0x51, 0xec, 0x61, 0x17,
20140 0x16, 0x5e, 0xaf, 0xd3, 0x49, 0xa6, 0x36, 0x43, 0xf4, 0x47, 0x91, 0xdf,
20141 0x33, 0x93, 0x21, 0x3b, 0x79, 0xb7, 0x97, 0x85, 0x10, 0xb5, 0xba, 0x3c,
20142 0xb6, 0x70, 0xd0, 0x06, 0xa1, 0xfa, 0x81, 0x82, 0x83, 0x7e, 0x7f, 0x80,
20143 0x96, 0x73, 0xbe, 0x56, 0x9b, 0x9e, 0x95, 0xd9, 0xf7, 0x02, 0xb9, 0xa4,
20144 0xde, 0x6a, 0x32, 0x6d, 0xd8, 0x8a, 0x84, 0x72, 0x2a, 0x14, 0x9f, 0x88,
20145 0xf9, 0xdc, 0x89, 0x9a, 0xfb, 0x7c, 0x2e, 0xc3, 0x8f, 0xb8, 0x65, 0x48,
20146 0x26, 0xc8, 0x12, 0x4a, 0xce, 0xe7, 0xd2, 0x62, 0x0c, 0xe0, 0x1f, 0xef,
20147 0x11, 0x75, 0x78, 0x71, 0xa5, 0x8e, 0x76, 0x3d, 0xbd, 0xbc, 0x86, 0x57,
20148 0x0b, 0x28, 0x2f, 0xa3, 0xda, 0xd4, 0xe4, 0x0f, 0xa9, 0x27, 0x53, 0x04,
20149 0x1b, 0xfc, 0xac, 0xe6, 0x7a, 0x07, 0xae, 0x63, 0xc5, 0xdb, 0xe2, 0xea,
20150 0x94, 0x8b, 0xc4, 0xd5, 0x9d, 0xf8, 0x90, 0x6b, 0xb1, 0x0d, 0xd6, 0xeb,
20151 0xc6, 0x0e, 0xcf, 0xad, 0x08, 0x4e, 0xd7, 0xe3, 0x5d, 0x50, 0x1e, 0xb3,
20152 0x5b, 0x23, 0x38, 0x34, 0x68, 0x46, 0x03, 0x8c, 0xdd, 0x9c, 0x7d, 0xa0,
20153 0xcd, 0x1a, 0x41, 0x1c};
20155 return GFInv[Byte];
20160 unsigned NumBitsInByte = 8;
20162 uint8_t RetByte = 0;
20163 for (uint32_t BitIdx = 0; BitIdx != NumBitsInByte; ++BitIdx) {
20165 AQword.lshr((7 -
static_cast<int32_t
>(BitIdx)) * NumBitsInByte)
20172 Product = AByte & XByte;
20174 uint8_t Parity = 0;
20177 for (
unsigned PBitIdx = 0; PBitIdx != NumBitsInByte; ++PBitIdx) {
20178 Parity = Parity ^ ((Product >> PBitIdx) & 0x1);
20181 uint8_t Temp = Imm[BitIdx] ? 1 : 0;
20182 RetByte |= (Temp ^ Parity) << BitIdx;
20191 uint16_t TWord = 0;
20192 unsigned NumBitsInByte = 8;
20193 for (
unsigned BitIdx = 0; BitIdx != NumBitsInByte; ++BitIdx) {
20194 if ((BByte >> BitIdx) & 0x1) {
20195 TWord = TWord ^ (AByte << BitIdx);
20203 for (int32_t BitIdx = 14; BitIdx > 7; --BitIdx) {
20204 if ((TWord >> BitIdx) & 0x1) {
20205 TWord = TWord ^ (0x11B << (BitIdx - 8));
20208 return (TWord & 0xFF);
20212 APFloat &ResR, APFloat &ResI) {
20218 APFloat AC = A *
C;
20219 APFloat BD = B * D;
20220 APFloat AD = A * D;
20221 APFloat BC = B *
C;
20224 if (ResR.isNaN() && ResI.isNaN()) {
20225 bool Recalc =
false;
20226 if (A.isInfinity() || B.isInfinity()) {
20227 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
20229 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
20232 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
20234 D = APFloat::copySign(APFloat(D.getSemantics()), D);
20237 if (
C.isInfinity() || D.isInfinity()) {
20238 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
20240 D = APFloat::copySign(APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0),
20243 A = APFloat::copySign(APFloat(A.getSemantics()), A);
20245 B = APFloat::copySign(APFloat(B.getSemantics()), B);
20248 if (!Recalc && (AC.isInfinity() || BD.isInfinity() || AD.isInfinity() ||
20249 BC.isInfinity())) {
20251 A = APFloat::copySign(APFloat(A.getSemantics()), A);
20253 B = APFloat::copySign(APFloat(B.getSemantics()), B);
20255 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
20257 D = APFloat::copySign(APFloat(D.getSemantics()), D);
20261 ResR = APFloat::getInf(A.getSemantics()) * (A *
C - B * D);
20262 ResI = APFloat::getInf(A.getSemantics()) * (A * D + B *
C);
20268 APFloat &ResR, APFloat &ResI) {
20275 APFloat MaxCD = maxnum(
abs(
C),
abs(D));
20276 if (MaxCD.isFinite()) {
20277 DenomLogB =
ilogb(MaxCD);
20278 C =
scalbn(
C, -DenomLogB, APFloat::rmNearestTiesToEven);
20279 D =
scalbn(D, -DenomLogB, APFloat::rmNearestTiesToEven);
20281 APFloat Denom =
C *
C + D * D;
20283 scalbn((A *
C + B * D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
20285 scalbn((B *
C - A * D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
20286 if (ResR.isNaN() && ResI.isNaN()) {
20287 if (Denom.isPosZero() && (!A.isNaN() || !B.isNaN())) {
20288 ResR = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * A;
20289 ResI = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * B;
20290 }
else if ((A.isInfinity() || B.isInfinity()) &&
C.isFinite() &&
20292 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
20294 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
20296 ResR = APFloat::getInf(ResR.getSemantics()) * (A *
C + B * D);
20297 ResI = APFloat::getInf(ResI.getSemantics()) * (B *
C - A * D);
20298 }
else if (MaxCD.isInfinity() && A.isFinite() && B.isFinite()) {
20299 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
20301 D = APFloat::copySign(APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0),
20303 ResR = APFloat::getZero(ResR.getSemantics()) * (A *
C + B * D);
20304 ResI = APFloat::getZero(ResI.getSemantics()) * (B *
C - A * D);
20311 APSInt NormAmt = Amount;
20312 unsigned BitWidth =
Value.getBitWidth();
20313 unsigned AmtBitWidth = NormAmt.getBitWidth();
20314 if (BitWidth == 1) {
20316 NormAmt =
APSInt(APInt(AmtBitWidth, 0), NormAmt.isUnsigned());
20317 }
else if (BitWidth == 2) {
20322 APSInt(APInt(AmtBitWidth, NormAmt[0] ? 1 : 0), NormAmt.isUnsigned());
20325 if (AmtBitWidth > BitWidth) {
20326 Divisor = llvm::APInt(AmtBitWidth, BitWidth);
20328 Divisor = llvm::APInt(BitWidth, BitWidth);
20329 if (AmtBitWidth < BitWidth) {
20330 NormAmt = NormAmt.extend(BitWidth);
20335 if (NormAmt.isSigned()) {
20336 NormAmt =
APSInt(NormAmt.srem(Divisor),
false);
20337 if (NormAmt.isNegative()) {
20338 APSInt SignedDivisor(Divisor,
false);
20339 NormAmt += SignedDivisor;
20342 NormAmt =
APSInt(NormAmt.urem(Divisor),
true);
20349bool ComplexExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
20351 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
20355 bool LHSReal =
false, RHSReal =
false;
20363 Result.makeComplexFloat();
20367 LHSOK = Visit(E->
getLHS());
20369 if (!LHSOK && !Info.noteFailure())
20375 APFloat &Real = RHS.FloatReal;
20378 RHS.makeComplexFloat();
20379 RHS.FloatImag =
APFloat(Real.getSemantics());
20383 assert(!(LHSReal && RHSReal) &&
20384 "Cannot have both operands of a complex operation be real.");
20386 default:
return Error(E);
20388 if (
Result.isComplexFloat()) {
20389 Result.getComplexFloatReal().add(RHS.getComplexFloatReal(),
20390 APFloat::rmNearestTiesToEven);
20392 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
20394 Result.getComplexFloatImag().add(RHS.getComplexFloatImag(),
20395 APFloat::rmNearestTiesToEven);
20397 Result.getComplexIntReal() += RHS.getComplexIntReal();
20398 Result.getComplexIntImag() += RHS.getComplexIntImag();
20402 if (
Result.isComplexFloat()) {
20403 Result.getComplexFloatReal().subtract(RHS.getComplexFloatReal(),
20404 APFloat::rmNearestTiesToEven);
20406 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
20407 Result.getComplexFloatImag().changeSign();
20408 }
else if (!RHSReal) {
20409 Result.getComplexFloatImag().subtract(RHS.getComplexFloatImag(),
20410 APFloat::rmNearestTiesToEven);
20413 Result.getComplexIntReal() -= RHS.getComplexIntReal();
20414 Result.getComplexIntImag() -= RHS.getComplexIntImag();
20418 if (
Result.isComplexFloat()) {
20423 ComplexValue LHS =
Result;
20424 APFloat &A = LHS.getComplexFloatReal();
20425 APFloat &B = LHS.getComplexFloatImag();
20426 APFloat &
C = RHS.getComplexFloatReal();
20427 APFloat &D = RHS.getComplexFloatImag();
20431 assert(!RHSReal &&
"Cannot have two real operands for a complex op!");
20439 }
else if (RHSReal) {
20451 ComplexValue LHS =
Result;
20452 Result.getComplexIntReal() =
20453 (LHS.getComplexIntReal() * RHS.getComplexIntReal() -
20454 LHS.getComplexIntImag() * RHS.getComplexIntImag());
20455 Result.getComplexIntImag() =
20456 (LHS.getComplexIntReal() * RHS.getComplexIntImag() +
20457 LHS.getComplexIntImag() * RHS.getComplexIntReal());
20461 if (
Result.isComplexFloat()) {
20466 ComplexValue LHS =
Result;
20467 APFloat &A = LHS.getComplexFloatReal();
20468 APFloat &B = LHS.getComplexFloatImag();
20469 APFloat &
C = RHS.getComplexFloatReal();
20470 APFloat &D = RHS.getComplexFloatImag();
20484 B = APFloat::getZero(A.getSemantics());
20489 ComplexValue LHS =
Result;
20490 APSInt Den = RHS.getComplexIntReal() * RHS.getComplexIntReal() +
20491 RHS.getComplexIntImag() * RHS.getComplexIntImag();
20493 return Error(E, diag::note_expr_divide_by_zero);
20495 Result.getComplexIntReal() =
20496 (LHS.getComplexIntReal() * RHS.getComplexIntReal() +
20497 LHS.getComplexIntImag() * RHS.getComplexIntImag()) / Den;
20498 Result.getComplexIntImag() =
20499 (LHS.getComplexIntImag() * RHS.getComplexIntReal() -
20500 LHS.getComplexIntReal() * RHS.getComplexIntImag()) / Den;
20508bool ComplexExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
20522 if (
Result.isComplexFloat()) {
20523 Result.getComplexFloatReal().changeSign();
20524 Result.getComplexFloatImag().changeSign();
20527 Result.getComplexIntReal() = -
Result.getComplexIntReal();
20528 Result.getComplexIntImag() = -
Result.getComplexIntImag();
20532 if (
Result.isComplexFloat())
20533 Result.getComplexFloatImag().changeSign();
20535 Result.getComplexIntImag() = -
Result.getComplexIntImag();
20540bool ComplexExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
20543 Result.makeComplexFloat();
20549 Result.makeComplexInt();
20557 return ExprEvaluatorBaseTy::VisitInitListExpr(E);
20560bool ComplexExprEvaluator::VisitCallExpr(
const CallExpr *E) {
20561 if (!IsConstantEvaluatedBuiltinCall(E))
20562 return ExprEvaluatorBaseTy::VisitCallExpr(E);
20565 case Builtin::BI__builtin_complex:
20566 Result.makeComplexFloat();
20584class AtomicExprEvaluator :
20585 public ExprEvaluatorBase<AtomicExprEvaluator> {
20586 const LValue *
This;
20589 AtomicExprEvaluator(EvalInfo &Info,
const LValue *This,
APValue &
Result)
20597 bool ZeroInitialization(
const Expr *E) {
20598 ImplicitValueInitExpr VIE(
20606 bool VisitCastExpr(
const CastExpr *E) {
20609 return ExprEvaluatorBaseTy::VisitCastExpr(E);
20610 case CK_NullToPointer:
20612 return ZeroInitialization(E);
20613 case CK_NonAtomicToAtomic:
20625 return AtomicExprEvaluator(Info,
This, Result).Visit(E);
20634class VoidExprEvaluator
20635 :
public ExprEvaluatorBase<VoidExprEvaluator> {
20637 VoidExprEvaluator(EvalInfo &Info) : ExprEvaluatorBaseTy(Info) {}
20641 bool ZeroInitialization(
const Expr *E) {
return true; }
20643 bool VisitCastExpr(
const CastExpr *E) {
20646 return ExprEvaluatorBaseTy::VisitCastExpr(E);
20653 bool VisitCallExpr(
const CallExpr *E) {
20654 if (!IsConstantEvaluatedBuiltinCall(E))
20655 return ExprEvaluatorBaseTy::VisitCallExpr(E);
20658 case Builtin::BI__assume:
20659 case Builtin::BI__builtin_assume:
20663 case Builtin::BI__builtin_operator_delete:
20671 bool VisitCXXDeleteExpr(
const CXXDeleteExpr *E);
20675bool VoidExprEvaluator::VisitCXXDeleteExpr(
const CXXDeleteExpr *E) {
20677 if (Info.SpeculativeEvaluationDepth)
20681 if (!OperatorDelete
20682 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
20683 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
20693 if (
Pointer.Designator.Invalid)
20697 if (
Pointer.isNullPointer()) {
20701 if (!Info.getLangOpts().CPlusPlus20)
20702 Info.CCEDiag(E, diag::note_constexpr_new);
20710 QualType AllocType =
Pointer.Base.getDynamicAllocType();
20716 Info.FFDiag(E, diag::note_constexpr_delete_base_nonvirt_dtor)
20725 if (VirtualDelete &&
20727 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
20728 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
20735 (*Alloc)->Value, AllocType))
20738 if (!Info.HeapAllocs.erase(
Pointer.Base.dyn_cast<DynamicAllocLValue>())) {
20743 Info.FFDiag(E, diag::note_constexpr_double_delete);
20753 return VoidExprEvaluator(Info).Visit(E);
20765 if (E->
isGLValue() || T->isFunctionType()) {
20769 LV.moveInto(Result);
20770 }
else if (T->isVectorType()) {
20773 }
else if (T->isConstantMatrixType()) {
20776 }
else if (T->isIntegralOrEnumerationType()) {
20777 if (!IntExprEvaluator(Info, Result).Visit(E))
20779 }
else if (T->hasPointerRepresentation()) {
20783 LV.moveInto(Result);
20784 }
else if (T->isRealFloatingType()) {
20785 llvm::APFloat F(0.0);
20789 }
else if (T->isAnyComplexType()) {
20793 C.moveInto(Result);
20794 }
else if (T->isFixedPointType()) {
20795 if (!FixedPointExprEvaluator(Info, Result).Visit(E))
return false;
20796 }
else if (T->isMemberPointerType()) {
20800 P.moveInto(Result);
20802 }
else if (T->isArrayType()) {
20805 Info.CurrentCall->createTemporary(E, T, ScopeKind::FullExpression, LV);
20809 }
else if (T->isRecordType()) {
20812 Info.CurrentCall->createTemporary(E, T, ScopeKind::FullExpression, LV);
20816 }
else if (T->isVoidType()) {
20817 if (!Info.getLangOpts().CPlusPlus11)
20818 Info.CCEDiag(E, diag::note_constexpr_nonliteral)
20822 }
else if (T->isAtomicType()) {
20827 E, Unqual, ScopeKind::FullExpression, LV);
20835 }
else if (Info.getLangOpts().CPlusPlus11) {
20836 Info.FFDiag(E, diag::note_constexpr_nonliteral) << E->
getType();
20839 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
20850 const Expr *E,
bool AllowNonLiteralTypes) {
20866 if (T->isArrayType())
20868 else if (T->isRecordType())
20870 else if (T->isAtomicType()) {
20892 if (Info.EnableNewConstInterp) {
20893 if (!Info.Ctx.getInterpContext().evaluateAsRValue(Info, E, Result))
20896 ConstantExprKind::Normal);
20905 LV.setFrom(Info.Ctx, Result);
20912 ConstantExprKind::Normal) &&
20920 if (
const auto *L = dyn_cast<IntegerLiteral>(Exp)) {
20922 APValue(
APSInt(L->getValue(), L->getType()->isUnsignedIntegerType()));
20927 if (
const auto *L = dyn_cast<CXXBoolLiteralExpr>(Exp)) {
20933 if (
const auto *FL = dyn_cast<FloatingLiteral>(Exp)) {
20934 Result =
APValue(FL->getValue());
20939 if (
const auto *L = dyn_cast<CharacterLiteral>(Exp)) {
20945 if (
const auto *CE = dyn_cast<ConstantExpr>(Exp)) {
20946 if (CE->hasAPValueResult()) {
20947 APValue APV = CE->getAPValueResult();
20949 Result = std::move(APV);
21025 bool InConstantContext)
const {
21027 "Expression evaluator can't be called on a dependent expression.");
21028 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsRValue");
21030 Info.InConstantContext = InConstantContext;
21031 return ::EvaluateAsRValue(
this,
Result, Ctx, Info);
21035 bool InConstantContext)
const {
21037 "Expression evaluator can't be called on a dependent expression.");
21038 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsBooleanCondition");
21046 bool InConstantContext)
const {
21048 "Expression evaluator can't be called on a dependent expression.");
21049 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsInt");
21051 Info.InConstantContext = InConstantContext;
21052 return ::EvaluateAsInt(
this,
Result, Ctx, AllowSideEffects, Info);
21057 bool InConstantContext)
const {
21059 "Expression evaluator can't be called on a dependent expression.");
21060 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFixedPoint");
21062 Info.InConstantContext = InConstantContext;
21063 return ::EvaluateAsFixedPoint(
this,
Result, Ctx, AllowSideEffects, Info);
21068 bool InConstantContext)
const {
21070 "Expression evaluator can't be called on a dependent expression.");
21072 if (!
getType()->isRealFloatingType())
21075 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFloat");
21087 bool InConstantContext)
const {
21089 "Expression evaluator can't be called on a dependent expression.");
21091 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsLValue");
21093 Info.InConstantContext = InConstantContext;
21097 if (Info.EnableNewConstInterp) {
21098 if (!Info.Ctx.getInterpContext().evaluate(Info,
this,
Result.Val,
21099 ConstantExprKind::Normal))
21102 LV.setFrom(Ctx,
Result.Val);
21105 ConstantExprKind::Normal, CheckedTemps);
21108 if (!
EvaluateLValue(
this, LV, Info) || !Info.discardCleanups() ||
21109 Result.HasSideEffects ||
21112 ConstantExprKind::Normal, CheckedTemps))
21115 LV.moveInto(
Result.Val);
21122 bool IsConstantDestruction) {
21123 EvalInfo Info(Ctx, EStatus,
21126 Info.setEvaluatingDecl(
Base, DestroyedValue,
21127 EvalInfo::EvaluatingDeclKind::Dtor);
21128 Info.InConstantContext = IsConstantDestruction;
21137 if (!Info.discardCleanups())
21138 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
21146 "Expression evaluator can't be called on a dependent expression.");
21152 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsConstantExpr");
21154 EvalInfo Info(Ctx,
Result, EM);
21155 Info.InConstantContext =
true;
21157 if (Info.EnableNewConstInterp) {
21158 if (!Info.Ctx.getInterpContext().evaluate(Info,
this,
Result.Val, Kind))
21161 getStorageType(Ctx,
this),
Result.Val, Kind);
21166 if (Kind == ConstantExprKind::ClassTemplateArgument)
21182 FullExpressionRAII
Scope(Info);
21187 if (!Info.discardCleanups())
21188 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
21198 if (Kind == ConstantExprKind::ClassTemplateArgument &&
21201 Result.HasSideEffects)) {
21213 bool IsConstantInitialization)
const {
21215 "Expression evaluator can't be called on a dependent expression.");
21216 assert(VD &&
"Need a valid VarDecl");
21218 llvm::TimeTraceScope TimeScope(
"EvaluateAsInitializer", [&] {
21220 llvm::raw_string_ostream OS(Name);
21226 EStatus.
Diag = &Notes;
21228 EvalInfo Info(Ctx, EStatus,
21229 (IsConstantInitialization &&
21233 Info.setEvaluatingDecl(VD,
Value);
21234 Info.InConstantContext = IsConstantInitialization;
21239 if (Info.EnableNewConstInterp) {
21241 if (!InterpCtx.evaluateAsInitializer(Info, VD,
this,
Value))
21245 ConstantExprKind::Normal);
21260 FullExpressionRAII
Scope(Info);
21263 EStatus.HasSideEffects)
21269 Info.performLifetimeExtension();
21271 if (!Info.discardCleanups())
21272 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
21276 ConstantExprKind::Normal) &&
21283 EStatus.
Diag = &Notes;
21300 IsConstantDestruction) ||
21312 "Expression evaluator can't be called on a dependent expression.");
21321 "Expression evaluator can't be called on a dependent expression.");
21323 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstInt");
21326 Info.InConstantContext =
true;
21330 assert(
Result &&
"Could not evaluate expression");
21331 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
21333 return EVResult.Val.getInt();
21339 "Expression evaluator can't be called on a dependent expression.");
21341 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstIntCheckOverflow");
21343 EVResult.Diag =
Diag;
21345 Info.InConstantContext =
true;
21346 Info.CheckingForUndefinedBehavior =
true;
21350 assert(
Result &&
"Could not evaluate expression");
21351 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
21353 return EVResult.Val.getInt();
21358 "Expression evaluator can't be called on a dependent expression.");
21360 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateForOverflow");
21365 Info.CheckingForUndefinedBehavior =
true;
21371 assert(
Val.isLValue());
21397 IK_ICEIfUnevaluated,
21413static ICEDiag
Worst(ICEDiag A, ICEDiag B) {
return A.Kind >= B.Kind ? A : B; }
21420 Info.InConstantContext =
true;
21429 assert(!E->
isValueDependent() &&
"Should not see value dependent exprs!");
21434#define ABSTRACT_STMT(Node)
21435#define STMT(Node, Base) case Expr::Node##Class:
21436#define EXPR(Node, Base)
21437#include "clang/AST/StmtNodes.inc"
21438 case Expr::PredefinedExprClass:
21439 case Expr::FloatingLiteralClass:
21440 case Expr::ImaginaryLiteralClass:
21441 case Expr::StringLiteralClass:
21442 case Expr::ArraySubscriptExprClass:
21443 case Expr::MatrixSingleSubscriptExprClass:
21444 case Expr::MatrixSubscriptExprClass:
21445 case Expr::ArraySectionExprClass:
21446 case Expr::OMPArrayShapingExprClass:
21447 case Expr::OMPIteratorExprClass:
21448 case Expr::CompoundAssignOperatorClass:
21449 case Expr::CompoundLiteralExprClass:
21450 case Expr::ExtVectorElementExprClass:
21451 case Expr::MatrixElementExprClass:
21452 case Expr::DesignatedInitExprClass:
21453 case Expr::ArrayInitLoopExprClass:
21454 case Expr::ArrayInitIndexExprClass:
21455 case Expr::NoInitExprClass:
21456 case Expr::DesignatedInitUpdateExprClass:
21457 case Expr::ImplicitValueInitExprClass:
21458 case Expr::ParenListExprClass:
21459 case Expr::VAArgExprClass:
21460 case Expr::AddrLabelExprClass:
21461 case Expr::StmtExprClass:
21462 case Expr::CXXMemberCallExprClass:
21463 case Expr::CUDAKernelCallExprClass:
21464 case Expr::CXXAddrspaceCastExprClass:
21465 case Expr::CXXDynamicCastExprClass:
21466 case Expr::CXXTypeidExprClass:
21467 case Expr::CXXUuidofExprClass:
21468 case Expr::MSPropertyRefExprClass:
21469 case Expr::MSPropertySubscriptExprClass:
21470 case Expr::CXXNullPtrLiteralExprClass:
21471 case Expr::UserDefinedLiteralClass:
21472 case Expr::CXXThisExprClass:
21473 case Expr::CXXThrowExprClass:
21474 case Expr::CXXNewExprClass:
21475 case Expr::CXXDeleteExprClass:
21476 case Expr::CXXPseudoDestructorExprClass:
21477 case Expr::UnresolvedLookupExprClass:
21478 case Expr::RecoveryExprClass:
21479 case Expr::DependentScopeDeclRefExprClass:
21480 case Expr::CXXConstructExprClass:
21481 case Expr::CXXInheritedCtorInitExprClass:
21482 case Expr::CXXStdInitializerListExprClass:
21483 case Expr::CXXBindTemporaryExprClass:
21484 case Expr::ExprWithCleanupsClass:
21485 case Expr::CXXTemporaryObjectExprClass:
21486 case Expr::CXXUnresolvedConstructExprClass:
21487 case Expr::CXXDependentScopeMemberExprClass:
21488 case Expr::UnresolvedMemberExprClass:
21489 case Expr::ObjCStringLiteralClass:
21490 case Expr::ObjCBoxedExprClass:
21491 case Expr::ObjCArrayLiteralClass:
21492 case Expr::ObjCDictionaryLiteralClass:
21493 case Expr::ObjCEncodeExprClass:
21494 case Expr::ObjCMessageExprClass:
21495 case Expr::ObjCSelectorExprClass:
21496 case Expr::ObjCProtocolExprClass:
21497 case Expr::ObjCIvarRefExprClass:
21498 case Expr::ObjCPropertyRefExprClass:
21499 case Expr::ObjCSubscriptRefExprClass:
21500 case Expr::ObjCIsaExprClass:
21501 case Expr::ObjCAvailabilityCheckExprClass:
21502 case Expr::ShuffleVectorExprClass:
21503 case Expr::ConvertVectorExprClass:
21504 case Expr::BlockExprClass:
21506 case Expr::OpaqueValueExprClass:
21507 case Expr::PackExpansionExprClass:
21508 case Expr::SubstNonTypeTemplateParmPackExprClass:
21509 case Expr::FunctionParmPackExprClass:
21510 case Expr::AsTypeExprClass:
21511 case Expr::ObjCIndirectCopyRestoreExprClass:
21512 case Expr::MaterializeTemporaryExprClass:
21513 case Expr::PseudoObjectExprClass:
21514 case Expr::AtomicExprClass:
21515 case Expr::LambdaExprClass:
21516 case Expr::CXXFoldExprClass:
21517 case Expr::CoawaitExprClass:
21518 case Expr::DependentCoawaitExprClass:
21519 case Expr::CoyieldExprClass:
21520 case Expr::SYCLUniqueStableNameExprClass:
21521 case Expr::CXXParenListInitExprClass:
21522 case Expr::HLSLOutArgExprClass:
21525 case Expr::MemberExprClass: {
21528 while (
const auto *M = dyn_cast<MemberExpr>(ME)) {
21531 ME = M->getBase()->IgnoreParenImpCasts();
21533 const auto *DRE = dyn_cast<DeclRefExpr>(ME);
21535 if (
const auto *VD = dyn_cast<VarDecl>(DRE->getDecl());
21543 case Expr::InitListExprClass: {
21554 case Expr::SizeOfPackExprClass:
21555 case Expr::GNUNullExprClass:
21556 case Expr::SourceLocExprClass:
21557 case Expr::EmbedExprClass:
21558 case Expr::OpenACCAsteriskSizeExprClass:
21561 case Expr::PackIndexingExprClass:
21564 case Expr::SubstNonTypeTemplateParmExprClass:
21568 case Expr::ConstantExprClass:
21571 case Expr::ParenExprClass:
21573 case Expr::GenericSelectionExprClass:
21575 case Expr::IntegerLiteralClass:
21576 case Expr::FixedPointLiteralClass:
21577 case Expr::CharacterLiteralClass:
21578 case Expr::ObjCBoolLiteralExprClass:
21579 case Expr::CXXBoolLiteralExprClass:
21580 case Expr::CXXScalarValueInitExprClass:
21581 case Expr::TypeTraitExprClass:
21582 case Expr::ConceptSpecializationExprClass:
21583 case Expr::RequiresExprClass:
21584 case Expr::ArrayTypeTraitExprClass:
21585 case Expr::ExpressionTraitExprClass:
21586 case Expr::CXXNoexceptExprClass:
21587 case Expr::CXXReflectExprClass:
21589 case Expr::CallExprClass:
21590 case Expr::CXXOperatorCallExprClass: {
21599 case Expr::CXXRewrittenBinaryOperatorClass:
21602 case Expr::DeclRefExprClass: {
21616 const VarDecl *VD = dyn_cast<VarDecl>(D);
21623 case Expr::UnaryOperatorClass: {
21646 llvm_unreachable(
"invalid unary operator class");
21648 case Expr::OffsetOfExprClass: {
21657 case Expr::UnaryExprOrTypeTraitExprClass: {
21659 if ((Exp->
getKind() == UETT_SizeOf) &&
21662 if (Exp->
getKind() == UETT_CountOf) {
21669 if (VAT->getElementType()->isArrayType())
21681 case Expr::BinaryOperatorClass: {
21726 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE) {
21729 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
21730 if (REval.isSigned() && REval.isAllOnes()) {
21732 if (LEval.isMinSignedValue())
21733 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
21741 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE)
21742 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
21748 return Worst(LHSResult, RHSResult);
21754 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICEIfUnevaluated) {
21764 return Worst(LHSResult, RHSResult);
21767 llvm_unreachable(
"invalid binary operator kind");
21769 case Expr::ImplicitCastExprClass:
21770 case Expr::CStyleCastExprClass:
21771 case Expr::CXXFunctionalCastExprClass:
21772 case Expr::CXXStaticCastExprClass:
21773 case Expr::CXXReinterpretCastExprClass:
21774 case Expr::CXXConstCastExprClass:
21775 case Expr::ObjCBridgedCastExprClass: {
21782 APSInt IgnoredVal(DestWidth, !DestSigned);
21787 if (FL->getValue().convertToInteger(IgnoredVal,
21788 llvm::APFloat::rmTowardZero,
21789 &Ignored) & APFloat::opInvalidOp)
21795 case CK_LValueToRValue:
21796 case CK_AtomicToNonAtomic:
21797 case CK_NonAtomicToAtomic:
21799 case CK_IntegralToBoolean:
21800 case CK_IntegralCast:
21806 case Expr::BinaryConditionalOperatorClass: {
21809 if (CommonResult.Kind == IK_NotICE)
return CommonResult;
21811 if (FalseResult.Kind == IK_NotICE)
return FalseResult;
21812 if (CommonResult.Kind == IK_ICEIfUnevaluated)
return CommonResult;
21813 if (FalseResult.Kind == IK_ICEIfUnevaluated &&
21815 return FalseResult;
21817 case Expr::ConditionalOperatorClass: {
21825 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
21828 if (CondResult.Kind == IK_NotICE)
21834 if (TrueResult.Kind == IK_NotICE)
21836 if (FalseResult.Kind == IK_NotICE)
21837 return FalseResult;
21838 if (CondResult.Kind == IK_ICEIfUnevaluated)
21840 if (TrueResult.Kind == IK_ICE && FalseResult.Kind == IK_ICE)
21846 return FalseResult;
21849 case Expr::CXXDefaultArgExprClass:
21851 case Expr::CXXDefaultInitExprClass:
21853 case Expr::ChooseExprClass: {
21856 case Expr::BuiltinBitCastExprClass: {
21857 if (!checkBitCastConstexprEligibility(
nullptr, Ctx,
cast<CastExpr>(E)))
21863 llvm_unreachable(
"Invalid StmtClass!");
21869 llvm::APSInt *
Value) {
21877 if (!Result.isInt())
21886 "Expression evaluator can't be called on a dependent expression.");
21888 ExprTimeTraceScope TimeScope(
this, Ctx,
"isIntegerConstantExpr");
21894 if (D.Kind != IK_ICE)
21899std::optional<llvm::APSInt>
21903 return std::nullopt;
21910 return std::nullopt;
21914 return std::nullopt;
21923 Info.InConstantContext =
true;
21926 llvm_unreachable(
"ICE cannot be evaluated!");
21933 "Expression evaluator can't be called on a dependent expression.");
21935 return CheckICE(
this, Ctx).Kind == IK_ICE;
21940 "Expression evaluator can't be called on a dependent expression.");
21950 *
Result = std::move(Scratch);
21957 Status.Diag = &Diags;
21964 Info.discardCleanups() && !Status.HasSideEffects;
21966 return IsConstExpr && Diags.empty();
21974 "Expression evaluator can't be called on a dependent expression.");
21976 llvm::TimeTraceScope TimeScope(
"EvaluateWithSubstitution", [&] {
21978 llvm::raw_string_ostream OS(Name);
21986 Info.InConstantContext =
true;
21989 const LValue *ThisPtr =
nullptr;
21992 auto *MD = dyn_cast<CXXMethodDecl>(Callee);
21993 assert(MD &&
"Don't provide `this` for non-methods.");
21994 assert(MD->isImplicitObjectMemberFunction() &&
21995 "Don't provide `this` for methods without an implicit object.");
21997 if (!
This->isValueDependent() &&
21999 !Info.EvalStatus.HasSideEffects)
22000 ThisPtr = &ThisVal;
22004 Info.EvalStatus.HasSideEffects =
false;
22007 CallRef
Call = Info.CurrentCall->createCall(Callee);
22010 unsigned Idx = I - Args.begin();
22011 if (Idx >= Callee->getNumParams())
22013 const ParmVarDecl *PVD = Callee->getParamDecl(Idx);
22014 if ((*I)->isValueDependent() ||
22016 Info.EvalStatus.HasSideEffects) {
22018 if (
APValue *Slot = Info.getParamSlot(
Call, PVD))
22024 Info.EvalStatus.HasSideEffects =
false;
22029 Info.discardCleanups();
22030 Info.EvalStatus.HasSideEffects =
false;
22033 CallStackFrame Frame(Info, Callee->getLocation(), Callee, ThisPtr,
This,
22036 FullExpressionRAII
Scope(Info);
22038 !Info.EvalStatus.HasSideEffects;
22050 llvm::TimeTraceScope TimeScope(
"isPotentialConstantExpr", [&] {
22052 llvm::raw_string_ostream OS(Name);
22059 Status.
Diag = &Diags;
22063 Info.InConstantContext =
true;
22064 Info.CheckingPotentialConstantExpression =
true;
22067 if (Info.EnableNewConstInterp) {
22068 Info.Ctx.getInterpContext().isPotentialConstantExpr(Info, FD);
22069 return Diags.empty();
22080 This.set({&VIE, Info.CurrentCall->Index});
22088 Info.setEvaluatingDecl(
This.getLValueBase(), Scratch);
22094 &VIE, Args, CallRef(), FD->
getBody(), Info, Scratch,
22098 return Diags.empty();
22106 "Expression evaluator can't be called on a dependent expression.");
22109 Status.
Diag = &Diags;
22113 Info.InConstantContext =
true;
22114 Info.CheckingPotentialConstantExpression =
true;
22116 if (Info.EnableNewConstInterp) {
22117 Info.Ctx.getInterpContext().isPotentialConstantExprUnevaluated(Info, E, FD);
22118 return Diags.empty();
22123 nullptr, CallRef());
22127 return Diags.empty();
22131 unsigned Type)
const {
22132 if (!
getType()->isPointerType())
22133 return std::nullopt;
22137 if (Info.EnableNewConstInterp)
22138 return Info.Ctx.getInterpContext().tryEvaluateObjectSize(Info,
this,
Type);
22142static std::optional<uint64_t>
22144 std::string *StringResult) {
22146 return std::nullopt;
22151 return std::nullopt;
22156 if (
const StringLiteral *S = dyn_cast_or_null<StringLiteral>(
22157 String.getLValueBase().dyn_cast<
const Expr *>())) {
22160 if (Off >= 0 && (uint64_t)Off <= (uint64_t)Str.size() &&
22163 Info.Ctx.hasSameUnqualifiedType(CharTy, Info.Ctx.CharTy)) {
22164 Str = Str.substr(Off);
22166 StringRef::size_type Pos = Str.find(0);
22167 if (Pos != StringRef::npos)
22168 Str = Str.substr(0, Pos);
22171 *StringResult = Str;
22179 for (uint64_t Strlen = 0; ; ++Strlen) {
22183 return std::nullopt;
22186 else if (StringResult)
22187 StringResult->push_back(Char.
getInt().getExtValue());
22189 return std::nullopt;
22196 std::string StringResult;
22198 if (Info.EnableNewConstInterp) {
22199 if (!Info.Ctx.getInterpContext().evaluateString(Info,
this, StringResult))
22200 return std::nullopt;
22201 return StringResult;
22205 return StringResult;
22206 return std::nullopt;
22209template <
typename T>
22211 const Expr *SizeExpression,
22212 const Expr *PtrExpression,
22216 Info.InConstantContext =
true;
22218 if (Info.EnableNewConstInterp)
22219 return Info.Ctx.getInterpContext().evaluateCharRange(Info, SizeExpression,
22220 PtrExpression, Result);
22223 FullExpressionRAII
Scope(Info);
22228 uint64_t Size = SizeValue.getZExtValue();
22231 if constexpr (std::is_same_v<APValue, T>)
22234 if (Size < Result.max_size())
22235 Result.reserve(Size);
22241 for (uint64_t I = 0; I < Size; ++I) {
22247 if constexpr (std::is_same_v<APValue, T>) {
22248 Result.getArrayInitializedElt(I) = std::move(Char);
22252 assert(
C.getBitWidth() <= 8 &&
22253 "string element not representable in char");
22255 Result.push_back(
static_cast<char>(
C.getExtValue()));
22266 const Expr *SizeExpression,
22270 PtrExpression, Ctx, Status);
22274 const Expr *SizeExpression,
22278 PtrExpression, Ctx, Status);
22285 if (Info.EnableNewConstInterp)
22286 return Info.Ctx.getInterpContext().evaluateStrlen(Info,
this);
22291struct IsWithinLifetimeHandler {
22294 using result_type = std::optional<bool>;
22295 std::optional<bool> failed() {
return std::nullopt; }
22296 template <
typename T>
22297 std::optional<bool> found(T &Subobj,
QualType SubobjType) {
22302std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &IEE,
22303 const CallExpr *E) {
22304 EvalInfo &Info = IEE.Info;
22309 if (!Info.InConstantContext)
22310 return std::nullopt;
22312 const Expr *Arg = E->
getArg(0);
22314 return std::nullopt;
22317 return std::nullopt;
22319 if (Val.allowConstexprUnknown())
22323 bool CalledFromStd =
false;
22324 const auto *
Callee = Info.CurrentCall->getCallee();
22325 if (Callee &&
Callee->isInStdNamespace()) {
22326 const IdentifierInfo *Identifier =
Callee->getIdentifier();
22327 CalledFromStd = Identifier && Identifier->
isStr(
"is_within_lifetime");
22329 Info.CCEDiag(CalledFromStd ? Info.CurrentCall->getCallRange().getBegin()
22331 diag::err_invalid_is_within_lifetime)
22332 << (CalledFromStd ?
"std::is_within_lifetime"
22333 :
"__builtin_is_within_lifetime")
22335 return std::nullopt;
22345 if (Val.isNullPointer() || Val.getLValueBase().isNull())
22347 QualType T = Val.getLValueBase().getType();
22349 "Pointers to functions should have been typed as function pointers "
22350 "which would have been rejected earlier");
22353 if (Val.getLValueDesignator().isOnePastTheEnd())
22355 assert(Val.getLValueDesignator().isValidSubobject() &&
22356 "Unchecked case for valid subobject");
22360 CompleteObject CO =
22364 if (Info.EvaluatingDeclValue && CO.Value == Info.EvaluatingDeclValue)
22369 IsWithinLifetimeHandler handler{Info};
22370 return findSubobject(Info, E, CO, Val.getLValueDesignator(), handler);
Defines the clang::ASTContext interface.
This file provides some common utility functions for processing Lambda related AST Constructs.
Defines enum values for all the target-independent builtin functions.
static Address castToBase(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy, Address OriginalBaseAddress, llvm::Value *Addr)
static uint32_t getBitWidth(const Expr *E)
static Decl::Kind getKind(const Decl *D)
GCCTypeClass
Values returned by __builtin_classify_type, chosen to match the values produced by GCC's builtin.
@ PointerToMemberFunction
static bool isRead(AccessKinds AK)
static bool EvaluateCharRangeAsStringImpl(const Expr *, T &Result, const Expr *SizeExpression, const Expr *PtrExpression, ASTContext &Ctx, Expr::EvalResult &Status)
static bool isValidIndeterminateAccess(AccessKinds AK)
Is this kind of access valid on an indeterminate object value?
static unsigned elementwiseSize(EvalInfo &Info, QualType BaseTy)
static bool EvaluateMemberPointer(const Expr *E, MemberPtr &Result, EvalInfo &Info)
static bool hasUnacceptableSideEffect(Expr::EvalStatus &Result, Expr::SideEffectsKind SEK)
static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E, AccessKinds AK, const LValue &LVal, QualType LValType)
Find the complete object to which an LValue refers.
static bool evaluateLValueAsAllocSize(EvalInfo &Info, APValue::LValueBase Base, LValue &Result)
Attempts to evaluate the given LValueBase as the result of a call to a function with the alloc_size a...
static const CXXMethodDecl * HandleVirtualDispatch(EvalInfo &Info, const Expr *E, LValue &This, const CXXMethodDecl *Found, llvm::SmallVectorImpl< QualType > &CovariantAdjustmentPath)
Perform virtual dispatch.
static bool EvaluateVarDecl(EvalInfo &Info, const VarDecl *VD)
static bool CheckEvaluationResult(CheckEvaluationResultKind CERK, EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value, ConstantExprKind Kind, const FieldDecl *SubobjectDecl, CheckedTemporaries &CheckedTemps)
static bool HandleLValueComplexElement(EvalInfo &Info, const Expr *E, LValue &LVal, QualType EltTy, bool Imag)
Update an lvalue to refer to a component of a complex number.
static bool evalPackBuiltin(const CallExpr *E, EvalInfo &Info, APValue &Result, llvm::function_ref< APInt(const APSInt &)> PackFn)
static bool HandleSizeof(EvalInfo &Info, SourceLocation Loc, QualType Type, CharUnits &Size, SizeOfType SOT=SizeOfType::SizeOf)
Get the size of the given type in char units.
static bool HandleConstructorCall(const Expr *E, const LValue &This, CallRef Call, const CXXConstructorDecl *Definition, EvalInfo &Info, APValue &Result)
Evaluate a constructor call.
static bool hlslElementwiseCastHelper(EvalInfo &Info, const Expr *E, QualType DestTy, SmallVectorImpl< APValue > &SrcVals, SmallVectorImpl< QualType > &SrcTypes)
static bool ShouldPropagateBreakContinue(EvalInfo &Info, const Stmt *LoopOrSwitch, ArrayRef< BlockScopeRAII * > Scopes, EvalStmtResult &ESR)
Helper to implement named break/continue.
static EvalStmtResult EvaluateLoopBody(StmtResult &Result, EvalInfo &Info, const Stmt *Body, const SwitchCase *Case=nullptr)
Evaluate the body of a loop, and translate the result as appropriate.
static bool EvaluatePointer(const Expr *E, LValue &Result, EvalInfo &Info, bool InvalidBaseOK=false)
static bool CheckTrivialDefaultConstructor(EvalInfo &Info, SourceLocation Loc, const CXXConstructorDecl *CD, bool IsValueInitialization)
CheckTrivialDefaultConstructor - Check whether a constructor is a trivial default constructor.
static bool EvaluateVector(const Expr *E, APValue &Result, EvalInfo &Info)
static const ValueDecl * GetLValueBaseDecl(const LValue &LVal)
static bool TryEvaluateBuiltinNaN(const ASTContext &Context, QualType ResultTy, const Expr *Arg, bool SNaN, llvm::APFloat &Result)
static const Expr * ignorePointerCastsAndParens(const Expr *E)
A more selective version of E->IgnoreParenCasts for tryEvaluateBuiltinObjectSize. This ignores some c...
static bool isAnyAccess(AccessKinds AK)
static bool EvaluateComparisonBinaryOperator(EvalInfo &Info, const BinaryOperator *E, SuccessCB &&Success, AfterCB &&DoAfter)
static bool HandleClassZeroInitialization(EvalInfo &Info, const Expr *E, const RecordDecl *RD, const LValue &This, APValue &Result)
Perform zero-initialization on an object of non-union class type. C++11 [dcl.init]p5: To zero-initial...
static bool EvaluateComplex(const Expr *E, ComplexValue &Res, EvalInfo &Info)
std::optional< APFloat > EvalScalarMinMaxFp(const APFloat &A, const APFloat &B, std::optional< APSInt > RoundingMode, bool IsMin)
static bool CheckMemoryLeaks(EvalInfo &Info)
Enforce C++2a [expr.const]/4.17, which disallows new-expressions unless "the allocated storage is dea...
static bool handleScalarCast(EvalInfo &Info, const FPOptions FPO, const Expr *E, QualType SourceTy, QualType DestTy, APValue const &Original, APValue &Result)
static ICEDiag CheckEvalInICE(const Expr *E, const ASTContext &Ctx)
static llvm::APInt ConvertBoolVectorToInt(const APValue &Val)
static bool flattenAPValue(EvalInfo &Info, const Expr *E, APValue Value, QualType BaseTy, SmallVectorImpl< APValue > &Elements, SmallVectorImpl< QualType > &Types, unsigned Size)
static bool hlslAggSplatHelper(EvalInfo &Info, const Expr *E, APValue &SrcVal, QualType &SrcTy)
static bool isBaseClassPublic(const CXXRecordDecl *Derived, const CXXRecordDecl *Base)
Determine whether Base, which is known to be a direct base class of Derived, is a public base class.
static bool hasVirtualDestructor(QualType T)
static bool HandleOverflow(EvalInfo &Info, const Expr *E, const T &SrcValue, QualType DestType)
static CharUnits getBaseAlignment(EvalInfo &Info, const LValue &Value)
static bool HandleLValueIndirectMember(EvalInfo &Info, const Expr *E, LValue &LVal, const IndirectFieldDecl *IFD)
Update LVal to refer to the given indirect field.
static bool ConvertDoubleToFloatStrict(EvalInfo &Info, const Expr *E, APFloat OrigVal, APValue &Result)
static ICEDiag Worst(ICEDiag A, ICEDiag B)
static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E, const VarDecl *VD, CallStackFrame *Frame, unsigned Version, APValue *&Result)
Try to evaluate the initializer for a variable declaration.
static bool handleDefaultInitValue(QualType T, APValue &Result)
Get the value to use for a default-initialized object of type T.
static bool HandleLValueVectorElement(EvalInfo &Info, const Expr *E, LValue &LVal, QualType EltTy, uint64_t Size, uint64_t Idx)
static void NoteLValueLocation(EvalInfo &Info, APValue::LValueBase Base)
static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc, QualType Type, const LValue &LVal, ConstantExprKind Kind, CheckedTemporaries &CheckedTemps)
Check that this reference or pointer core constant expression is a valid value for an address or refe...
static bool CheckedIntArithmetic(EvalInfo &Info, const Expr *E, const APSInt &LHS, const APSInt &RHS, unsigned BitWidth, Operation Op, APSInt &Result)
Perform the given integer operation, which is known to need at most BitWidth bits,...
static bool EvaluateTemporary(const Expr *E, LValue &Result, EvalInfo &Info)
Evaluate an expression of record type as a temporary.
static bool EvaluateArray(const Expr *E, const LValue &This, APValue &Result, EvalInfo &Info)
static bool truncateBitfieldValue(EvalInfo &Info, const Expr *E, APValue &Value, const FieldDecl *FD)
static bool handleVectorShuffle(EvalInfo &Info, const ShuffleVectorExpr *E, QualType ElemType, APValue const &VecVal1, APValue const &VecVal2, unsigned EltNum, APValue &Result)
static bool handleVectorElementCast(EvalInfo &Info, const FPOptions FPO, const Expr *E, QualType SourceTy, QualType DestTy, APValue const &Original, APValue &Result)
static const ValueDecl * HandleMemberPointerAccess(EvalInfo &Info, QualType LVType, LValue &LV, const Expr *RHS, bool IncludeMember=true)
HandleMemberPointerAccess - Evaluate a member access operation and build an lvalue referring to the r...
static bool HandleBaseToDerivedCast(EvalInfo &Info, const CastExpr *E, LValue &Result)
HandleBaseToDerivedCast - Apply the given base-to-derived cast operation on the provided lvalue,...
static bool EvaluateFloat(const Expr *E, APFloat &Result, EvalInfo &Info)
static bool IsOpaqueConstantCall(const CallExpr *E)
Should this call expression be treated as forming an opaque constant?
static bool CheckMemberPointerConstantExpression(EvalInfo &Info, SourceLocation Loc, QualType Type, const APValue &Value, ConstantExprKind Kind)
Member pointers are constant expressions unless they point to a non-virtual dllimport member function...
static bool EvaluateAsInt(const Expr *E, Expr::EvalResult &ExprResult, const ASTContext &Ctx, Expr::SideEffectsKind AllowSideEffects, EvalInfo &Info)
static bool handleLValueToRValueConversion(EvalInfo &Info, const Expr *Conv, QualType Type, const LValue &LVal, APValue &RVal, bool WantObjectRepresentation=false)
Perform an lvalue-to-rvalue conversion on the given glvalue.
static bool handleElementwiseCast(EvalInfo &Info, const Expr *E, const FPOptions FPO, SmallVectorImpl< APValue > &Elements, SmallVectorImpl< QualType > &SrcTypes, SmallVectorImpl< QualType > &DestTypes, SmallVectorImpl< APValue > &Results)
static bool refersToCompleteObject(const LValue &LVal)
Tests to see if the LValue has a user-specified designator (that isn't necessarily valid)....
static bool AreElementsOfSameArray(QualType ObjType, const SubobjectDesignator &A, const SubobjectDesignator &B)
Determine whether the given subobject designators refer to elements of the same array object.
static bool EvaluateDecompositionDeclInit(EvalInfo &Info, const DecompositionDecl *DD)
static bool IsWeakLValue(const LValue &Value)
static bool EvaluateArrayNewConstructExpr(EvalInfo &Info, LValue &This, APValue &Result, const CXXConstructExpr *CCE, QualType AllocType)
static bool EvaluateRecord(const Expr *E, const LValue &This, APValue &Result, EvalInfo &Info)
static bool handleAssignment(EvalInfo &Info, const Expr *E, const LValue &LVal, QualType LValType, APValue &Val)
Perform an assignment of Val to LVal. Takes ownership of Val.
static bool CastToDerivedClass(EvalInfo &Info, const Expr *E, LValue &Result, const RecordDecl *TruncatedType, unsigned TruncatedElements)
Cast an lvalue referring to a base subobject to a derived class, by truncating the lvalue's path to t...
static bool EvaluateIgnoredValue(EvalInfo &Info, const Expr *E)
Evaluate an expression to see if it had side-effects, and discard its result.
static bool constructAggregate(EvalInfo &Info, const FPOptions FPO, const Expr *E, APValue &Result, QualType ResultType, SmallVectorImpl< APValue > &Elements, SmallVectorImpl< QualType > &ElTypes)
static void addFlexibleArrayMemberInitSize(EvalInfo &Info, const QualType &T, const LValue &LV, CharUnits &Size)
If we're evaluating the object size of an instance of a struct that contains a flexible array member,...
static bool HandleLValueBasePath(EvalInfo &Info, const CastExpr *E, QualType Type, LValue &Result)
static bool evalShuffleGeneric(EvalInfo &Info, const CallExpr *Call, APValue &Out, llvm::function_ref< std::pair< unsigned, int >(unsigned, unsigned)> GetSourceIndex)
static QualType getSubobjectType(QualType ObjType, QualType SubobjType, bool IsMutable=false)
static bool EvaluateFixedPointOrInteger(const Expr *E, APFixedPoint &Result, EvalInfo &Info)
Evaluate an integer or fixed point expression into an APResult.
static std::optional< uint64_t > tryEvaluateBuiltinObjectSize(const Expr *E, unsigned Type, EvalInfo &Info)
Tries to evaluate the __builtin_object_size for E. If successful, returns true and stores the result ...
static bool HandleIntToFloatCast(EvalInfo &Info, const Expr *E, const FPOptions FPO, QualType SrcType, const APSInt &Value, QualType DestType, APFloat &Result)
static const CXXRecordDecl * getBaseClassType(SubobjectDesignator &Designator, unsigned PathLength)
static bool CastToBaseClass(EvalInfo &Info, const Expr *E, LValue &Result, const CXXRecordDecl *DerivedRD, const CXXRecordDecl *BaseRD)
Cast an lvalue referring to a derived class to a known base subobject.
static bool HandleLValueBase(EvalInfo &Info, const Expr *E, LValue &Obj, const CXXRecordDecl *DerivedDecl, const CXXBaseSpecifier *Base)
static bool HandleConversionToBool(const APValue &Val, bool &Result)
static void expandVector(APValue &Vec, unsigned NumElements)
CharUnits GetAlignOfExpr(const ASTContext &Ctx, const Expr *E, UnaryExprOrTypeTrait ExprKind)
static bool isModification(AccessKinds AK)
static bool handleCompareOpForVector(const APValue &LHSValue, BinaryOperatorKind Opcode, const APValue &RHSValue, APInt &Result)
static bool MaybeElementDependentArrayFiller(const Expr *FillerExpr)
static bool EvaluateObjectArgument(EvalInfo &Info, const Expr *Object, LValue &This)
Build an lvalue for the object argument of a member function call.
static bool CheckLiteralType(EvalInfo &Info, const Expr *E, const LValue *This=nullptr)
Check that this core constant expression is of literal type, and if not, produce an appropriate diagn...
static bool EvaluateInteger(const Expr *E, APSInt &Result, EvalInfo &Info)
CheckEvaluationResultKind
static bool isZeroSized(const LValue &Value)
static APSInt extractStringLiteralCharacter(EvalInfo &Info, const Expr *Lit, uint64_t Index)
Extract the value of a character from a string literal.
static bool modifySubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, const SubobjectDesignator &Sub, APValue &NewVal)
Update the designated sub-object of an rvalue to the given value.
static bool EvaluateCPlusPlus11IntegralConstantExpr(const ASTContext &Ctx, const Expr *E, llvm::APSInt *Value)
Evaluate an expression as a C++11 integral constant expression.
static CharUnits GetAlignOfType(const ASTContext &Ctx, QualType T, UnaryExprOrTypeTrait ExprKind)
static bool getBuiltinAlignArguments(const CallExpr *E, EvalInfo &Info, APValue &Val, APSInt &Alignment)
static bool HandleLValueArrayAdjustment(EvalInfo &Info, const Expr *E, LValue &LVal, QualType EltTy, APSInt Adjustment)
Update a pointer value to model pointer arithmetic.
static bool extractSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, const SubobjectDesignator &Sub, APValue &Result, AccessKinds AK=AK_Read)
Extract the designated sub-object of an rvalue.
static bool HandleLValueMember(EvalInfo &Info, const Expr *E, LValue &LVal, const FieldDecl *FD, const ASTRecordLayout *RL=nullptr)
Update LVal to refer to the given field, which must be a member of the type currently described by LV...
static void addOrSubLValueAsInteger(APValue &LVal, const APSInt &Index, bool IsSub)
static bool IsDeclSourceLocationCurrent(const FunctionDecl *FD)
static std::optional< uint64_t > EvaluateBuiltinStrLen(const Expr *E, EvalInfo &Info, std::string *StringResult=nullptr)
void HandleComplexComplexDiv(APFloat A, APFloat B, APFloat C, APFloat D, APFloat &ResR, APFloat &ResI)
static bool handleTrivialCopy(EvalInfo &Info, const ParmVarDecl *Param, const Expr *E, APValue &Result, bool CopyObjectRepresentation)
Perform a trivial copy from Param, which is the parameter of a copy or move constructor or assignment...
static bool checkFloatingPointResult(EvalInfo &Info, const Expr *E, APFloat::opStatus St)
Check if the given evaluation result is allowed for constant evaluation.
static bool EvaluateBuiltinConstantPForLValue(const APValue &LV)
EvaluateBuiltinConstantPForLValue - Determine the result of __builtin_constant_p when applied to the ...
static bool EvaluateBuiltinConstantP(EvalInfo &Info, const Expr *Arg)
EvaluateBuiltinConstantP - Evaluate __builtin_constant_p as similarly to GCC as we can manage.
static bool checkNonVirtualMemberCallThisPointer(EvalInfo &Info, const Expr *E, const LValue &This, const CXXMethodDecl *NamedMember)
Check that the pointee of the 'this' pointer in a member function call is either within its lifetime ...
static bool CheckConstantExpression(EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value, ConstantExprKind Kind)
Check that this core constant expression value is a valid value for a constant expression.
static bool EvaluateAsBooleanCondition(const Expr *E, bool &Result, EvalInfo &Info)
static std::optional< DynamicType > ComputeDynamicType(EvalInfo &Info, const Expr *E, LValue &This, AccessKinds AK)
Determine the dynamic type of an object.
static bool EvaluateDecl(EvalInfo &Info, const Decl *D, bool EvaluateConditionDecl=false)
static void expandArray(APValue &Array, unsigned Index)
static bool handleLogicalOpForVector(const APInt &LHSValue, BinaryOperatorKind Opcode, const APInt &RHSValue, APInt &Result)
static unsigned FindDesignatorMismatch(QualType ObjType, const SubobjectDesignator &A, const SubobjectDesignator &B, bool &WasArrayIndex)
Find the position where two subobject designators diverge, or equivalently the length of the common i...
static bool isOnePastTheEndOfCompleteObject(const ASTContext &Ctx, const LValue &LV)
Determine whether this is a pointer past the end of the complete object referred to by the lvalue.
static unsigned getBaseIndex(const CXXRecordDecl *Derived, const CXXRecordDecl *Base)
Get the base index of the given base class within an APValue representing the given derived class.
static bool EvaluateFixedPoint(const Expr *E, APFixedPoint &Result, EvalInfo &Info)
Evaluate only a fixed point expression into an APResult.
void HandleComplexComplexMul(APFloat A, APFloat B, APFloat C, APFloat D, APFloat &ResR, APFloat &ResI)
static bool EvalPointerValueAsBool(const APValue &Value, bool &Result)
static bool handleVectorVectorBinOp(EvalInfo &Info, const BinaryOperator *E, BinaryOperatorKind Opcode, APValue &LHSValue, const APValue &RHSValue)
static bool EvaluateMatrix(const Expr *E, APValue &Result, EvalInfo &Info)
static const FunctionDecl * getVirtualOperatorDelete(QualType T)
static bool isDesignatorAtObjectEnd(const ASTContext &Ctx, const LValue &LVal)
Checks to see if the given LValue's Designator is at the end of the LValue's record layout....
static bool CheckArraySize(EvalInfo &Info, const ConstantArrayType *CAT, SourceLocation CallLoc={})
static bool EvaluateInPlace(APValue &Result, EvalInfo &Info, const LValue &This, const Expr *E, bool AllowNonLiteralTypes=false)
EvaluateInPlace - Evaluate an expression in-place in an APValue. In some cases, the in-place evaluati...
static bool handleFloatFloatBinOp(EvalInfo &Info, const BinaryOperator *E, APFloat &LHS, BinaryOperatorKind Opcode, const APFloat &RHS)
Perform the given binary floating-point operation, in-place, on LHS.
static std::optional< DynAlloc * > CheckDeleteKind(EvalInfo &Info, const Expr *E, const LValue &Pointer, DynAlloc::Kind DeallocKind)
Check that the given object is a suitable pointer to a heap allocation that still exists and is of th...
static bool EvaluateLValue(const Expr *E, LValue &Result, EvalInfo &Info, bool InvalidBaseOK=false)
Evaluate an expression as an lvalue. This can be legitimately called on expressions which are not glv...
static bool FastEvaluateAsRValue(const Expr *Exp, APValue &Result, const ASTContext &Ctx, bool &IsConst)
static bool HandleCovariantReturnAdjustment(EvalInfo &Info, const Expr *E, APValue &Result, ArrayRef< QualType > Path)
Perform the adjustment from a value returned by a virtual function to a value of the statically expec...
static bool evalShiftWithCount(EvalInfo &Info, const CallExpr *Call, APValue &Out, llvm::function_ref< APInt(const APInt &, uint64_t)> ShiftOp, llvm::function_ref< APInt(const APInt &, unsigned)> OverflowOp)
static EvalStmtResult EvaluateSwitch(StmtResult &Result, EvalInfo &Info, const SwitchStmt *SS)
Evaluate a switch statement.
static void expandStringLiteral(EvalInfo &Info, const StringLiteral *S, APValue &Result, QualType AllocType=QualType())
static bool EvaluateArgs(ArrayRef< const Expr * > Args, CallRef Call, EvalInfo &Info, const FunctionDecl *Callee, bool RightToLeft=false, LValue *ObjectArg=nullptr)
Evaluate the arguments to a function call.
static bool EvaluateAtomic(const Expr *E, const LValue *This, APValue &Result, EvalInfo &Info)
static bool getBytesReturnedByAllocSizeCall(const ASTContext &Ctx, const LValue &LVal, llvm::APInt &Result)
Convenience function. LVal's base must be a call to an alloc_size function.
static bool handleIntIntBinOp(EvalInfo &Info, const BinaryOperator *E, const APSInt &LHS, BinaryOperatorKind Opcode, APSInt RHS, APSInt &Result)
Perform the given binary integer operation.
static bool EvaluateInitForDeclOfReferenceType(EvalInfo &Info, const ValueDecl *D, const Expr *Init, LValue &Result, APValue &Val)
Evaluates the initializer of a reference.
static bool checkDynamicType(EvalInfo &Info, const Expr *E, const LValue &This, AccessKinds AK, bool Polymorphic)
Check that we can access the notional vptr of an object / determine its dynamic type.
static bool HandleFloatToIntCast(EvalInfo &Info, const Expr *E, QualType SrcType, const APFloat &Value, QualType DestType, APSInt &Result)
static bool getAlignmentArgument(const Expr *E, QualType ForType, EvalInfo &Info, APSInt &Alignment)
Evaluate the value of the alignment argument to __builtin_align_{up,down}, __builtin_is_aligned and _...
static bool CheckFullyInitialized(EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value)
Check that this evaluated value is fully-initialized and can be loaded by an lvalue-to-rvalue convers...
static SubobjectHandler::result_type findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, const SubobjectDesignator &Sub, SubobjectHandler &handler)
Find the designated sub-object of an rvalue.
static bool determineEndOffset(EvalInfo &Info, SourceLocation ExprLoc, unsigned Type, const LValue &LVal, CharUnits &EndOffset)
Helper for tryEvaluateBuiltinObjectSize – Given an LValue, this will determine how many bytes exist f...
static bool convertUnsignedAPIntToCharUnits(const llvm::APInt &Int, CharUnits &Result)
Converts the given APInt to CharUnits, assuming the APInt is unsigned. Fails if the conversion would ...
static bool EvaluateCallArg(const ParmVarDecl *PVD, const Expr *Arg, CallRef Call, EvalInfo &Info, bool NonNull=false, APValue **EvaluatedArg=nullptr)
llvm::SmallPtrSet< const MaterializeTemporaryExpr *, 8 > CheckedTemporaries
Materialized temporaries that we've already checked to determine if they're initializsed by a constan...
GCCTypeClass EvaluateBuiltinClassifyType(QualType T, const LangOptions &LangOpts)
EvaluateBuiltinClassifyType - Evaluate __builtin_classify_type the same way as GCC.
static bool EvaluateDependentExpr(const Expr *E, EvalInfo &Info)
static bool MaybeEvaluateDeferredVarDeclInit(EvalInfo &Info, const VarDecl *VD)
static APSInt HandleIntToIntCast(EvalInfo &Info, const Expr *E, QualType DestType, QualType SrcType, const APSInt &Value)
static std::optional< APValue > handleVectorUnaryOperator(ASTContext &Ctx, QualType ResultTy, UnaryOperatorKind Op, APValue Elt)
static bool lifetimeStartedInEvaluation(EvalInfo &Info, APValue::LValueBase Base, bool MutableSubobject=false)
static bool isOneByteCharacterType(QualType T)
static bool HandleLambdaCapture(EvalInfo &Info, const Expr *E, LValue &Result, const CXXMethodDecl *MD, const FieldDecl *FD, bool LValueToRValueConversion)
Get an lvalue to a field of a lambda's closure type.
static bool EvaluateCond(EvalInfo &Info, const VarDecl *CondDecl, const Expr *Cond, bool &Result)
Evaluate a condition (either a variable declaration or an expression).
static bool EvaluateAsFixedPoint(const Expr *E, Expr::EvalResult &ExprResult, const ASTContext &Ctx, Expr::SideEffectsKind AllowSideEffects, EvalInfo &Info)
static bool EvaluateAsRValue(EvalInfo &Info, const Expr *E, APValue &Result)
EvaluateAsRValue - Try to evaluate this expression, performing an implicit lvalue-to-rvalue cast if i...
static bool diagnoseMutableFields(EvalInfo &Info, const Expr *E, AccessKinds AK, QualType T)
Diagnose an attempt to read from any unreadable field within the specified type, which might be a cla...
static ICEDiag CheckICE(const Expr *E, const ASTContext &Ctx)
static bool CheckConstexprFunction(EvalInfo &Info, SourceLocation CallLoc, const FunctionDecl *Declaration, const FunctionDecl *Definition, const Stmt *Body)
CheckConstexprFunction - Check that a function can be called in a constant expression.
static bool EvaluateDestruction(const ASTContext &Ctx, APValue::LValueBase Base, APValue DestroyedValue, QualType Type, SourceLocation Loc, Expr::EvalStatus &EStatus, bool IsConstantDestruction)
static EvalStmtResult EvaluateStmt(StmtResult &Result, EvalInfo &Info, const Stmt *S, const SwitchCase *SC=nullptr)
static bool EvaluateArrayNewInitList(EvalInfo &Info, LValue &This, APValue &Result, const InitListExpr *ILE, QualType AllocType)
static bool HasSameBase(const LValue &A, const LValue &B)
static bool CheckLocalVariableDeclaration(EvalInfo &Info, const VarDecl *VD)
static bool HandleLValueDirectBase(EvalInfo &Info, const Expr *E, LValue &Obj, const CXXRecordDecl *Derived, const CXXRecordDecl *Base, const ASTRecordLayout *RL=nullptr)
static bool IsGlobalLValue(APValue::LValueBase B)
static llvm::RoundingMode getActiveRoundingMode(EvalInfo &Info, const Expr *E)
Get rounding mode to use in evaluation of the specified expression.
static QualType getObjectType(APValue::LValueBase B)
Retrieves the "underlying object type" of the given expression, as used by __builtin_object_size.
static bool handleCompareOpForVectorHelper(const APTy &LHSValue, BinaryOperatorKind Opcode, const APTy &RHSValue, APInt &Result)
static bool Evaluate(APValue &Result, EvalInfo &Info, const Expr *E)
static bool isReadByLvalueToRvalueConversion(const CXXRecordDecl *RD)
Determine whether a type would actually be read by an lvalue-to-rvalue conversion.
static void negateAsSigned(APSInt &Int)
Negate an APSInt in place, converting it to a signed form if necessary, and preserving its value (by ...
static bool HandleFunctionCall(SourceLocation CallLoc, const FunctionDecl *Callee, const LValue *ObjectArg, const Expr *E, ArrayRef< const Expr * > Args, CallRef Call, const Stmt *Body, EvalInfo &Info, APValue &Result, const LValue *ResultSlot)
Evaluate a function call.
static bool isUserWritingOffTheEnd(const ASTContext &Ctx, const LValue &LVal)
Attempts to detect a user writing into a piece of memory that's impossible to figure out the size of ...
static bool GetLValueBaseAsString(const EvalInfo &Info, const LValue &LVal, LValueBaseString &AsString)
static bool HandleOperatorDeleteCall(EvalInfo &Info, const CallExpr *E)
static bool EvaluateIntegerOrLValue(const Expr *E, APValue &Result, EvalInfo &Info)
EvaluateIntegerOrLValue - Evaluate an rvalue integral-typed expression, and produce either the intege...
static bool HandleDynamicCast(EvalInfo &Info, const ExplicitCastExpr *E, LValue &Ptr)
Apply the given dynamic cast operation on the provided lvalue.
static bool HandleOperatorNewCall(EvalInfo &Info, const CallExpr *E, LValue &Result)
Perform a call to 'operator new' or to ‘__builtin_operator_new’.
static bool HandleFloatToFloatCast(EvalInfo &Info, const Expr *E, QualType SrcType, QualType DestType, APFloat &Result)
static bool MaybeHandleUnionActiveMemberChange(EvalInfo &Info, const Expr *LHSExpr, const LValue &LHS)
Handle a builtin simple-assignment or a call to a trivial assignment operator whose left-hand side mi...
uint8_t GFNIMul(uint8_t AByte, uint8_t BByte)
static bool isFormalAccess(AccessKinds AK)
Is this an access per the C++ definition?
static bool handleCompoundAssignment(EvalInfo &Info, const CompoundAssignOperator *E, const LValue &LVal, QualType LValType, QualType PromotedLValType, BinaryOperatorKind Opcode, const APValue &RVal)
Perform a compound assignment of LVal <op>= RVal.
static bool handleIncDec(EvalInfo &Info, const Expr *E, const LValue &LVal, QualType LValType, bool IsIncrement, APValue *Old)
Perform an increment or decrement on LVal.
static bool EvaluateVoid(const Expr *E, EvalInfo &Info)
static bool HandleDestruction(EvalInfo &Info, const Expr *E, const LValue &This, QualType ThisType)
Perform a destructor or pseudo-destructor call on the given object, which might in general not be a c...
static bool HandleDestructionImpl(EvalInfo &Info, SourceRange CallRange, const LValue &This, APValue &Value, QualType T)
static bool ArePotentiallyOverlappingStringLiterals(const EvalInfo &Info, const LValue &LHS, const LValue &RHS)
uint8_t GFNIMultiplicativeInverse(uint8_t Byte)
uint8_t GFNIAffine(uint8_t XByte, const APInt &AQword, const APSInt &Imm, bool Inverse)
APSInt NormalizeRotateAmount(const APSInt &Value, const APSInt &Amount)
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.
llvm::json::Object Object
Expr * getExpr()
Get 'expr' part of the associated expression/statement.
static QualType getPointeeType(const MemRegion *R)
Enumerates target-specific builtins in their own namespaces within namespace clang.
Defines the clang::TypeLoc interface and its subclasses.
C Language Family Type Representation.
__DEVICE__ long long abs(long long __n)
a trap message and trap category.
llvm::APInt getValue() const
unsigned getVersion() const
QualType getDynamicAllocType() const
QualType getTypeInfoType() const
static LValueBase getTypeInfo(TypeInfoLValue LV, QualType TypeInfo)
static LValueBase getDynamicAlloc(DynamicAllocLValue LV, QualType Type)
A non-discriminated union of a base, field, or array index.
BaseOrMemberType getAsBaseOrMember() const
static LValuePathEntry ArrayIndex(uint64_t Index)
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
bool hasArrayFiller() const
const LValueBase getLValueBase() const
APValue & getArrayInitializedElt(unsigned I)
void swap(APValue &RHS)
Swaps the contents of this and the given APValue.
APValue & getStructField(unsigned i)
unsigned getMatrixNumColumns() const
const FieldDecl * getUnionField() const
APSInt & getComplexIntImag()
bool isComplexInt() const
llvm::PointerIntPair< const Decl *, 1, bool > BaseOrMemberType
A FieldDecl or CXXRecordDecl, along with a flag indicating whether we mean a virtual or non-virtual b...
ValueKind getKind() const
unsigned getArrayInitializedElts() const
static APValue IndeterminateValue()
APFixedPoint & getFixedPoint()
bool hasLValuePath() const
const ValueDecl * getMemberPointerDecl() const
APValue & getUnionValue()
CharUnits & getLValueOffset()
void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const
bool isComplexFloat() const
APValue & getVectorElt(unsigned I)
APValue & getArrayFiller()
unsigned getVectorLength() const
void setUnion(const FieldDecl *Field, const APValue &Value)
bool isIndeterminate() const
unsigned getMatrixNumRows() const
unsigned getArraySize() const
bool allowConstexprUnknown() const
std::string getAsString(const ASTContext &Ctx, QualType Ty) const
bool isFixedPoint() const
APValue & getMatrixElt(unsigned Idx)
@ Indeterminate
This object has an indeterminate value (C++ [basic.indet]).
@ None
There is no such object (it's outside its lifetime).
APSInt & getComplexIntReal()
APFloat & getComplexFloatImag()
APFloat & getComplexFloatReal()
APValue & getStructBase(unsigned i)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
SourceManager & getSourceManager()
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
unsigned getIntWidth(QualType T) const
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
uint64_t getTargetNullPointerValue(QualType QT) const
Get target-dependent integer value for null pointer which is used for constant folding.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
unsigned getPreferredTypeAlign(QualType T) const
Return the "preferred" alignment of the specified type T for the current target, in bits.
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
const LangOptions & getLangOpts() const
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
interp::Context & getInterpContext() const
Returns the clang bytecode interpreter context.
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
const clang::PrintingPolicy & getPrintingPolicy() const
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
llvm::APSInt MakeIntValue(uint64_t Value, QualType Type) const
Make an APSInt of the appropriate width and signedness for the given Value and integer Type.
const VariableArrayType * getAsVariableArrayType(QualType T) const
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
CanQualType getCanonicalTagType(const TagDecl *TD) const
uint64_t getCharWidth() const
Return the size of the character type, in bits.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
unsigned getFieldCount() const
getFieldCount - Get the number of fields in the layout.
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - Get the offset, in chars, for the given base class.
LabelDecl * getLabel() const
OpaqueValueExpr * getCommonExpr() const
Get the common subexpression shared by all initializations (the source array).
Expr * getSubExpr() const
Get the initializer to use for each array element.
Expr * getLHS()
An array access can be written A[4] or 4[A] (both are equivalent).
uint64_t getValue() const
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
QualType getValueType() const
Gets the type contained by this atomic type, i.e.
Attr - This represents one attribute.
BinaryConditionalOperator - The GNU extension to the conditional operator which allows the middle ope...
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression which will be evaluated if the condition evaluates to false; ...
OpaqueValueExpr * getOpaqueValue() const
getOpaqueValue - Return the opaque value placeholder.
Expr * getCommon() const
getCommon - Return the common expression, written to the left of the condition.
A builtin binary operation expression such as "x + y" or "x <= y".
static bool isLogicalOp(Opcode Opc)
static bool isRelationalOp(Opcode Opc)
static bool isComparisonOp(Opcode Opc)
static Opcode getOpForCompoundAssignment(Opcode Opc)
SourceLocation getExprLoc() const
static bool isAdditiveOp(Opcode Opc)
static bool isPtrMemOp(Opcode Opc)
predicates to categorize the respective opcodes.
static bool isAssignmentOp(Opcode Opc)
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
static bool isEqualityOp(Opcode Opc)
bool hasCaptures() const
True if this block (or its nested blocks) captures anything of local storage from its enclosing scope...
const BlockDecl * getBlockDecl() const
AccessSpecifier Access
The access along this inheritance path.
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
bool isAmbiguous(CanQualType BaseType) const
Determine whether the path from the most-derived type to the given base type is ambiguous (i....
Represents a base class of a C++ class.
SourceLocation getBeginLoc() const LLVM_READONLY
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
QualType getType() const
Retrieves the type of the base class.
const Expr * getSubExpr() const
Represents a call to a C++ constructor.
bool isElidable() const
Whether this construction is elidable.
Expr * getArg(unsigned Arg)
Return the specified argument.
bool requiresZeroInitialization() const
Whether this construction first requires zero-initialization before the initializer is called.
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
unsigned getNumArgs() const
Return the number of arguments to the constructor call.
Represents a C++ constructor within a class.
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
CXXCtorInitializer *const * init_const_iterator
Iterates through the member/base initializer list.
Expr * getExpr()
Get the initialization expression that will be used.
FunctionDecl * getOperatorDelete() const
bool isGlobalDelete() const
Represents a C++ destructor within a class.
CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for statement, represented as 'for (ra...
DeclStmt * getBeginStmt()
DeclStmt * getLoopVarStmt()
DeclStmt * getRangeStmt()
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will call.
Represents a static or instance method of a struct/union/class.
bool isExplicitObjectMemberFunction() const
[C++2b][dcl.fct]/p7 An explicit object member function is a non-static member function with an explic...
bool isImplicitObjectMemberFunction() const
[C++2b][dcl.fct]/p7 An implicit object member function is a non-static member function without an exp...
QualType getFunctionObjectParameterReferenceType() const
Return the type of the object pointed by this.
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
bool isMoveAssignmentOperator() const
Determine whether this is a move assignment operator.
bool isCopyAssignmentOperator() const
Determine whether this is a copy-assignment operator, regardless of whether it was declared implicitl...
bool isLambdaStaticInvoker() const
Determine whether this is a lambda closure type's static member function that is used for the result ...
QualType getAllocatedType() const
std::optional< Expr * > getArraySize()
This might return std::nullopt even if isArray() returns true, since there might not be an array size...
Expr * getPlacementArg(unsigned I)
unsigned getNumPlacementArgs() const
SourceRange getSourceRange() const
FunctionDecl * getOperatorNew() const
Expr * getInitializer()
The initializer of this new-expression.
MutableArrayRef< Expr * > getInitExprs()
Represents a C++ struct/union/class.
bool hasMutableFields() const
Determine whether this class, or any of its class subobjects, contains a mutable field.
bool isGenericLambda() const
Determine whether this class describes a generic lambda function object (i.e.
base_class_iterator bases_end()
bool hasTrivialDestructor() const
Determine whether this class has a trivial destructor (C++ [class.dtor]p3)
void getCaptureFields(llvm::DenseMap< const ValueDecl *, FieldDecl * > &Captures, FieldDecl *&ThisCapture) const
For a closure type, retrieve the mapping from captured variables and this to the non-static data memb...
unsigned getNumBases() const
Retrieves the number of base classes of this class.
base_class_iterator bases_begin()
const CXXBaseSpecifier * base_class_const_iterator
Iterator that traverses the base classes of a class.
capture_const_range captures() const
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
CXXMethodDecl * getLambdaCallOperator() const
Retrieve the lambda call operator of the closure type if this is a closure type.
CXXRecordDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
bool isDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is derived from the class Base.
Expr * getSemanticForm()
Get an equivalent semantic form for this expression.
bool isTypeOperand() const
QualType getTypeOperand(const ASTContext &Context) const
Retrieves the type operand of this typeid() expression after various required adjustments (removing r...
Expr * getExprOperand() const
bool isPotentiallyEvaluated() const
Determine whether this typeid has a type operand which is potentially evaluated, per C++11 [expr....
MSGuidDecl * getGuidDecl() const
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
SourceLocation getBeginLoc() const
const AllocSizeAttr * getCalleeAllocSizeAttr() const
Try to get the alloc_size attribute of the callee. May return null.
unsigned getBuiltinCallee() const
getBuiltinCallee - If this is a call to a builtin, return the builtin ID of the callee.
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
Expr ** getArgs()
Retrieve the call arguments.
QualType getCallReturnType(const ASTContext &Ctx) const
getCallReturnType - Get the return type of the call expr.
CaseStmt - Represent a case statement.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
path_iterator path_begin()
unsigned path_size() const
CastKind getCastKind() const
const CXXBaseSpecifier *const * path_const_iterator
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operation.
CharUnits - This is an opaque type for sizes expressed in character units.
bool isPowerOfTwo() const
isPowerOfTwo - Test whether the quantity is a power of two.
CharUnits alignmentAtOffset(CharUnits offset) const
Given that this is a non-zero alignment value, what is the alignment at the given offset?
bool isZero() const
isZero - Test whether the quantity equals zero.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
unsigned getValue() const
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
const ValueInfo * getValueInfo(ComparisonCategoryResult ValueKind) const
ComparisonCategoryResult makeWeakResult(ComparisonCategoryResult Res) const
Converts the specified result kind into the correct result kind for this category.
Complex values, per C99 6.2.5p11.
QualType getElementType() const
CompoundAssignOperator - For compound assignments (e.g.
QualType getComputationLHSType() const
CompoundLiteralExpr - [C99 6.5.2.5].
bool hasStaticStorage() const
APValue & getOrCreateStaticValue(ASTContext &Ctx) const
const Expr * getInitializer() const
CompoundStmt - This represents a group of statements like { stmt stmt }.
Stmt *const * const_body_iterator
body_iterator body_begin()
bool isSatisfied() const
Whether or not the concept with the given arguments was satisfied when the expression was created.
ConditionalOperator - The ?
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
Expr * getCond() const
getCond - Return the expression representing the condition for the ?
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
Represents the canonical version of C arrays with a specified constant size.
unsigned getSizeBitWidth() const
Return the bit width of the size type.
static unsigned getNumAddressingBits(const ASTContext &Context, QualType ElementType, const llvm::APInt &NumElements)
Determine the number of bits required to address a member of.
static unsigned getMaxSizeBits(const ASTContext &Context)
Determine the maximum number of active bits that an array's size can require, which limits the maximu...
uint64_t getLimitedSize() const
Return the size zero-extended to uint64_t or UINT64_MAX if the value is larger than UINT64_MAX.
bool isZeroSize() const
Return true if the size is zero.
const Expr * getSizeExpr() const
Return a pointer to the size expression.
llvm::APInt getSize() const
Return the constant array size as an APInt.
uint64_t getZExtSize() const
Return the size zero-extended as a uint64_t.
APValue getAPValueResult() const
bool hasAPValueResult() const
Represents a concrete matrix type with constant number of rows and columns.
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
Represents the current source location and context used to determine the value of the source location...
const Expr * getDefaultExpr() const
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool Equals(const DeclContext *DC) const
Determine whether this declaration context is equivalent to the declaration context DC.
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
A reference to a declared variable, function, enum, etc.
bool refersToEnclosingVariableOrCapture() const
Does this DeclRefExpr refer to an enclosing local or a captured variable?
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Decl - This represents one declaration (or definition), e.g.
bool isInStdNamespace() const
ASTContext & getASTContext() const LLVM_READONLY
bool isInvalidDecl() const
SourceLocation getLocation() const
DeclContext * getDeclContext()
AccessSpecifier getAccess() const
bool isAnyOperatorNew() const
A decomposition declaration.
auto flat_bindings() const
Designator - A designator in a C99 designated initializer.
DoStmt - This represents a 'do/while' stmt.
Symbolic representation of a dynamic allocation.
static unsigned getMaxIndex()
const Expr * getBase() const
ChildElementIter< false > begin()
ExplicitCastExpr - An explicit cast written in the source code.
QualType getTypeAsWritten() const
getTypeAsWritten - Returns the type that this expression is casting to, as written in the source code...
This represents one expression.
const Expr * skipRValueSubobjectAdjustments(SmallVectorImpl< const Expr * > &CommaLHS, SmallVectorImpl< SubobjectAdjustment > &Adjustments) const
Walk outwards from an expression we want to bind a reference to and find the expression whose lifetim...
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
static bool isPotentialConstantExpr(const FunctionDecl *FD, SmallVectorImpl< PartialDiagnosticAt > &Diags)
isPotentialConstantExpr - Return true if this function's definition might be usable in a constant exp...
bool isIntegerConstantExpr(const ASTContext &Ctx) const
static bool isPotentialConstantExprUnevaluated(Expr *E, const FunctionDecl *FD, SmallVectorImpl< PartialDiagnosticAt > &Diags)
isPotentialConstantExprUnevaluated - Return true if this expression might be usable in a constant exp...
@ SE_AllowSideEffects
Allow any unmodeled side effect.
@ SE_AllowUndefinedBehavior
Allow UB that we can give a value, but not arbitrary unmodeled side effects.
bool isCXX11ConstantExpr(const ASTContext &Ctx, APValue *Result=nullptr) const
isCXX11ConstantExpr - Return true if this expression is a constant expression in C++11.
bool EvaluateCharRangeAsString(std::string &Result, const Expr *SizeExpression, const Expr *PtrExpression, ASTContext &Ctx, EvalResult &Status) const
llvm::APSInt EvaluateKnownConstIntCheckOverflow(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
bool isValueDependent() const
Determines whether the value of this expression depends on.
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Returns the set of floating point options that apply to this expression.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
bool containsErrors() const
Whether this expression contains subexpressions which had errors.
bool EvaluateAsFloat(llvm::APFloat &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsFloat - Return true if this is a constant which we can fold and convert to a floating point...
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsLValue - Evaluate an expression to see if we can fold it to an lvalue with link time known ...
bool EvaluateAsFixedPoint(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsFixedPoint - Return true if this is a constant which we can fold and convert to a fixed poi...
bool isEvaluatable(const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
isEvaluatable - Call EvaluateAsRValue to see if this expression can be constant folded without side-e...
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language.
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...
std::optional< uint64_t > tryEvaluateStrLen(const ASTContext &Ctx) const
If the current Expr is a pointer, this will try to statically determine the strlen of the string poin...
bool HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects=true) const
HasSideEffects - This routine returns true for all those expressions which have any effect other than...
bool EvaluateAsConstantExpr(EvalResult &Result, const ASTContext &Ctx, ConstantExprKind Kind=ConstantExprKind::Normal) const
Evaluate an expression that is required to be a constant expression.
std::optional< std::string > tryEvaluateString(ASTContext &Ctx) const
If the current Expr can be evaluated to a pointer to a null-terminated constant string,...
bool EvaluateAsBooleanCondition(bool &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsBooleanCondition - Return true if this is a constant which we can fold and convert to a boo...
bool isTemporaryObject(ASTContext &Ctx, const CXXRecordDecl *TempTy) const
Determine whether the result of this expression is a temporary object of the given class type.
std::optional< uint64_t > tryEvaluateObjectSize(const ASTContext &Ctx, unsigned Type) const
If the current Expr is a pointer, this will try to statically determine the number of bytes available...
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
bool isCXX98IntegralConstantExpr(const ASTContext &Ctx) const
isCXX98IntegralConstantExpr - Return true if this expression is an integral constant expression in C+...
bool EvaluateWithSubstitution(APValue &Value, ASTContext &Ctx, const FunctionDecl *Callee, ArrayRef< const Expr * > Args, const Expr *This=nullptr) const
EvaluateWithSubstitution - Evaluate an expression as if from the context of a call to the given funct...
bool EvaluateAsInitializer(APValue &Result, const ASTContext &Ctx, const VarDecl *VD, SmallVectorImpl< PartialDiagnosticAt > &Notes, bool IsConstantInitializer) const
EvaluateAsInitializer - Evaluate an expression as if it were the initializer of the given declaration...
void EvaluateForOverflow(const ASTContext &Ctx) const
bool isArrow() const
isArrow - Return true if the base expression is a pointer to vector, return false if the base express...
void getEncodedElementAccess(SmallVectorImpl< uint32_t > &Elts) const
getEncodedElementAccess - Encode the elements accessed into an llvm aggregate Constant of ConstantInt...
bool isFPConstrained() const
LangOptions::FPExceptionModeKind getExceptionMode() const
RoundingMode getRoundingMode() const
Represents a member of a struct/union/class.
bool isBitField() const
Determines whether this field is a bitfield.
unsigned getBitWidthValue() const
Computes the bit width of this field, if this is a bit field.
unsigned getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
FieldDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this field.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
llvm::APInt getValue() const
Returns an internal integer representation of the literal.
llvm::APFloat getValue() const
ForStmt - This represents a 'for (init;cond;inc)' stmt.
VarDecl * getConditionVariable() const
Retrieve the variable declared in this "for" statement, if any.
const Expr * getSubExpr() const
Represents a function declaration or definition.
const ParmVarDecl * getParamDecl(unsigned i) const
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
bool isFunctionTemplateSpecialization() const
Determine whether this function is a function template specialization.
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
bool hasCXXExplicitFunctionObjectParameter() const
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
bool isConstexpr() const
Whether this is a (C++11) constexpr function or constexpr constructor.
bool isUsableAsGlobalAllocationFunctionInConstantEvaluation(UnsignedOrNone *AlignmentParam=nullptr, bool *IsNothrow=nullptr) const
Determines whether this function is one of the replaceable global allocation functions described in i...
bool isDefaulted() const
Whether this function is defaulted.
void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override
Appends a human-readable name for this declaration into the given stream.
FunctionDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
Expr * getResultExpr()
Return the result expression of this controlling expression.
One of these records is kept for each identifier that is lexed.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
IfStmt - This represents an if/then/else.
bool isNonNegatedConsteval() const
VarDecl * getConditionVariable()
Retrieve the variable declared in this "if" statement, if any.
const Expr * getSubExpr() const
Represents an implicitly-generated value initialization of an object of a given type.
Represents a field injected from an anonymous union/struct into the parent scope.
ArrayRef< NamedDecl * > chain() const
Describes an C or C++ initializer list.
bool isTransparent() const
Is this a transparent initializer list (that is, an InitListExpr that is purely syntactic,...
bool isStringLiteralInit() const
Is this an initializer for an array of characters, initialized by a string literal or an @encode?
unsigned getNumInits() const
Expr * getArrayFiller()
If this initializer list initializes an array with more elements than there are initializers in the l...
const Expr * getInit(unsigned Init) const
ArrayRef< Expr * > inits()
capture_init_iterator capture_init_end()
Retrieve the iterator pointing one past the last initialization argument for this lambda expression.
capture_init_iterator capture_init_begin()
Retrieve the first initialization argument for this lambda expression (which initializes the first ca...
CXXRecordDecl * getLambdaClass() const
Retrieve the class that corresponds to the lambda.
StrictFlexArraysLevelKind
@ FPE_Ignore
Assume that floating-point exceptions are masked.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
StorageDuration getStorageDuration() const
Retrieve the storage duration for the materialized temporary.
Expr * getSubExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue.
APValue * getOrCreateValue(bool MayCreate) const
Get the storage for the constant value of a materialized temporary of static storage duration.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
void printQualifiedName(raw_ostream &OS) const
Returns a human-readable qualified name for this declaration, like A::B::i, for i being member of nam...
bool isExpressibleAsConstantInitializer() const
Expr * getIndexExpr(unsigned Idx)
const OffsetOfNode & getComponent(unsigned Idx) const
TypeSourceInfo * getTypeSourceInfo() const
unsigned getNumComponents() const
unsigned getArrayExprIndex() const
For an array element node, returns the index into the array of expressions.
FieldDecl * getField() const
For a field offsetof node, returns the field.
@ Array
An index into an array.
@ Identifier
A field in a dependent type, known only by its name.
@ Base
An implicit indirection through a C++ base class, when the field found is in a base class.
Kind getKind() const
Determine what kind of offsetof node this is.
CXXBaseSpecifier * getBase() const
For a base class node, returns the base specifier.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
Expr * getSelectedExpr() const
const Expr * getSubExpr() const
Represents a parameter to a function.
unsigned getFunctionScopeIndex() const
Returns the index of this parameter in its prototype or method scope.
bool isExplicitObjectParameter() const
PointerType - C99 6.7.5.1 - Pointer Declarators.
StringLiteral * getFunctionName()
Expr * getResultExpr()
Return the result-bearing expression, or null if there is none.
ArrayRef< Expr * > semantics()
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
bool isTriviallyCopyableType(const ASTContext &Context) const
Return true if this is a trivially copyable type (C++0x [basic.types]p9)
QualType withConst() const
void addConst()
Add the const type qualifier to this QualType.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
void removeLocalVolatile()
void addVolatile()
Add the volatile type qualifier to this QualType.
bool isConstQualified() const
Determine whether this type is const-qualified.
QualType getAtomicUnqualifiedType() const
Remove all qualifiers including _Atomic.
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after.
unsigned getCVRQualifiers() const
Retrieve the set of CVR (const-volatile-restrict) qualifiers applied to this type.
bool isWrapType() const
Returns true if it is a OverflowBehaviorType of Wrap kind.
Represents a struct/union/class.
unsigned getNumFields() const
Returns the number of fields (non-static data members) in this record.
field_iterator field_end() const
field_range fields() const
specific_decl_iterator< FieldDecl > field_iterator
bool isAnonymousStructOrUnion() const
Whether this is an anonymous struct or union.
field_iterator field_begin() const
bool isSatisfied() const
Whether or not the requires clause is satisfied.
SourceLocation getLocation() const
std::string ComputeName(ASTContext &Context) const
Scope - A scope is a transient data structure that is used while parsing the program.
ShuffleVectorExpr - clang-specific builtin-in function __builtin_shufflevector.
llvm::APSInt getShuffleMaskIdx(unsigned N) const
unsigned getNumSubExprs() const
getNumSubExprs - Return the size of the SubExprs array.
Expr * getExpr(unsigned Index)
getExpr - Return the Expr at the specified index.
unsigned getPackLength() const
Retrieve the length of the parameter pack.
APValue EvaluateInContext(const ASTContext &Ctx, const Expr *DefaultExpr) const
Return the result of evaluating this SourceLocExpr in the specified (and possibly null) default argum...
Encodes a location in the source.
A trivial tuple used to represent a source range.
SourceLocation getBegin() const
std::string printToString(const SourceManager &SM) const
CompoundStmt * getSubStmt()
Stmt - This represents one statement.
StmtClass getStmtClass() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
SourceLocation getBeginLoc() const LLVM_READONLY
StringLiteral - This represents a string literal expression, e.g.
unsigned getLength() const
StringRef getBytes() const
Allow access to clients that need the byte representation, such as ASTWriterStmt::VisitStringLiteral(...
uint32_t getCodeUnit(size_t i) const
StringRef getString() const
unsigned getCharByteWidth() const
Expr * getReplacement() const
const SwitchCase * getNextSwitchCase() const
SwitchStmt - This represents a 'switch' stmt.
VarDecl * getConditionVariable()
Retrieve the variable declared in this "switch" statement, if any.
SwitchCase * getSwitchCaseList()
TagDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
unsigned size() const
Retrieve the number of template arguments in this template argument list.
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
@ Type
The template argument is a type.
Symbolic representation of typeid(T) for some type T.
QualType getType() const
Return the type wrapped by this type source info.
bool getBoolValue() const
const APValue & getAPValue() const
bool isStoredAsBoolean() const
The base class of the type hierarchy.
bool isBooleanType() const
bool isFunctionReferenceType() const
bool isMFloat8Type() const
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
bool isPackedVectorBoolType(const ASTContext &ctx) const
bool isLiteralType(const ASTContext &Ctx) const
Return true if this is a literal type (C++11 [basic.types]p10)
bool isIncompleteArrayType() const
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
bool isComplexType() const
isComplexType() does not include complex integers (a GCC extension).
const ArrayType * castAsArrayTypeUnsafe() const
A variant of castAs<> for array type which silently discards qualifiers from the outermost type.
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
bool isIntegralOrUnscopedEnumerationType() const
Determine whether this type is an integral or unscoped enumeration type.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isConstantArrayType() const
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isVoidPointerType() const
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6....
bool isFunctionPointerType() const
bool isConstantMatrixType() const
bool isPointerType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isEnumeralType() const
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
bool isVariableArrayType() const
bool isSveVLSBuiltinType() const
Determines if this is a sizeless type supported by the 'arm_sve_vector_bits' type attribute,...
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
bool isExtVectorBoolType() const
bool isMemberDataPointerType() const
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
RecordDecl * castAsRecordDecl() const
bool isAnyComplexType() const
bool isFixedPointType() const
Return true if this is a fixed point type according to ISO/IEC JTC1 SC22 WG14 N1169.
bool isMemberPointerType() const
bool isAtomicType() const
bool isComplexIntegerType() const
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isObjectType() const
Determine whether this type is an object type.
EnumDecl * getAsEnumDecl() const
Retrieves the EnumDecl this type refers to.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
bool isFunctionType() const
bool isVectorType() const
bool isRealFloatingType() const
Floating point categories.
bool isFloatingType() const
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
const T * castAsCanonical() const
Return this type's canonical type cast to the specified type.
bool isAnyPointerType() const
TypeClass getTypeClass() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isNullPtrType() const
bool isRecordType() const
bool isSizelessVectorType() const
Returns true for all scalable vector types.
bool hasPointerRepresentation() const
Whether this type is represented natively as a pointer.
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
QualType getArgumentType() const
SourceLocation getBeginLoc() const LLVM_READONLY
QualType getTypeOfArgument() const
Gets the argument type, or the type of the argument expression, whichever is appropriate.
bool isArgumentType() const
UnaryExprOrTypeTrait getKind() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
SourceLocation getExprLoc() const
Expr * getSubExpr() const
static bool isIncrementOp(Opcode Op)
bool canOverflow() const
Returns true if the unary operator can cause an overflow.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
bool isWeak() const
Determine whether this symbol is weakly-imported, or declared with the weak or weak-ref attr.
Represents a variable declaration or definition.
bool isConstexpr() const
Whether this variable is (C++11) constexpr.
bool hasICEInitializer(const ASTContext &Context) const
Determine whether the initializer of this variable is an integer constant expression.
bool isInitCapture() const
Whether this variable is the implicit variable for a lambda init-capture.
APValue * evaluateValue() const
Attempt to evaluate the value of the initializer attached to this declaration, and produce notes expl...
CharUnits getFlexibleArrayInitChars(const ASTContext &Ctx) const
If hasFlexibleArrayInit is true, compute the number of additional bytes necessary to store those elem...
bool hasConstantInitialization() const
Determine whether this variable has constant initialization.
VarDecl * getDefinition(ASTContext &)
Get the real (not just tentative) definition for this declaration.
bool mightBeUsableInConstantExpressions(const ASTContext &C) const
Determine whether this variable's value might be usable in a constant expression, according to the re...
EvaluatedStmt * ensureEvaluatedStmt() const
Convert the initializer for this declaration to the elaborated EvaluatedStmt form,...
bool evaluateDestruction(SmallVectorImpl< PartialDiagnosticAt > &Notes) const
Evaluate the destruction of this variable to determine if it constitutes constant destruction.
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
ThreadStorageClassSpecifier getTSCSpec() const
const Expr * getInit() const
APValue * getEvaluatedValue() const
Return the already-evaluated value of this variable's initializer, or NULL if the value is not yet kn...
bool hasLocalStorage() const
Returns true if a variable with function scope is a non-static local variable.
DefinitionKind hasDefinition(ASTContext &) const
Check whether this variable is defined in this translation unit.
bool isLocalVarDecl() const
Returns true for local variable declarations other than parameters.
bool isUsableInConstantExpressions(const ASTContext &C) const
Determine whether this variable's value can be used in a constant expression, according to the releva...
const Expr * getAnyInitializer() const
Get the initializer for this variable, no matter which declaration it is attached to.
Expr * getSizeExpr() const
Represents a GCC generic vector type.
unsigned getNumElements() const
QualType getElementType() const
WhileStmt - This represents a 'while' stmt.
VarDecl * getConditionVariable()
Retrieve the variable declared in this "while" statement, if any.
Base class for stack frames, shared between VM and walker.
Interface for the VM to interact with the AST walker's context.
Defines the clang::TargetInfo interface.
bool computeOSLogBufferLayout(clang::ASTContext &Ctx, const clang::CallExpr *E, OSLogBufferLayout &layout)
static const FunctionDecl * getCallee(const CXXConstructExpr &D)
uint32_t Literal
Literals are represented as positive integers.
unsigned kind
All of the diagnostics that can be emitted by the frontend.
std::optional< llvm::AllocTokenMetadata > getAllocTokenMetadata(QualType T, const ASTContext &Ctx)
Get the information required for construction of an allocation token ID.
QualType inferPossibleType(const CallExpr *E, const ASTContext &Ctx, const CastExpr *CastE)
Infer the possible allocated type from an allocation call expression.
bool NE(InterpState &S, CodePtr OpPC)
llvm::FixedPointSemantics FixedPointSemantics
bool This(InterpState &S, CodePtr OpPC)
bool Alloc(InterpState &S, CodePtr OpPC, const Descriptor *Desc)
std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl
All declarations that can appear in a module declaration.
AccessKind
This enum distinguishes between different ways to access (read or write) a variable.
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
bool isa(CodeGen::Address addr)
bool hasSpecificAttr(const Container &container)
@ NonNull
Values of this type can never be null.
@ Success
Annotation was successful.
Expr::ConstantExprKind ConstantExprKind
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
bool operator==(const CallGraphNode::CallRecord &LHS, const CallGraphNode::CallRecord &RHS)
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
bool isLambdaCallWithExplicitObjectParameter(const DeclContext *DC)
UnaryExprOrTypeTrait
Names for the "expression or type" traits.
ComparisonCategoryResult
An enumeration representing the possible results of a three-way comparison.
CheckSubobjectKind
The order of this enum is important for diagnostics.
@ SD_Static
Static storage duration.
@ SD_FullExpression
Full-expression storage duration (for temporaries).
bool isLambdaCallOperator(const CXXMethodDecl *MD)
@ Result
The result type of a method or function.
AccessKinds
Kinds of access we can perform on an object, for diagnostics.
@ AK_ReadObjectRepresentation
@ Type
The name was classified as a type.
CastKind
CastKind - The kind of operation required for a conversion.
llvm::hash_code hash_value(const CustomizableOptional< T > &O)
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs.
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
@ ConstantFold
Fold the expression to a constant.
@ ConstantExpressionUnevaluated
Evaluate as a constant expression.
@ ConstantExpression
Evaluate as a constant expression.
@ IgnoreSideEffects
Evaluate in any way we know how.
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
U cast(CodeGen::Address addr)
@ None
The alignment was not explicit in code.
@ ArrayBound
Array bound in array declarator or new-expression.
@ Class
The "class" keyword introduces the elaborated-type-specifier.
ActionResult< Expr * > ExprResult
@ Other
Other implicit parameter.
ActionResult< Stmt * > StmtResult
Diagnostic wrappers for TextAPI types for error reporting.
hash_code hash_value(const clang::dependencies::ModuleID &ID)
unsigned PathLength
The corresponding path length in the lvalue.
const CXXRecordDecl * Type
The dynamic class type of the object.
std::string ObjCEncodeStorage
Represents an element in a path from a derived class to a base class.
EvalResult is a struct with detailed info about an evaluated expression.
APValue Val
Val - This is the value the expression can be folded to.
bool isGlobalLValue() const
Return true if the evaluated lvalue expression is global.
EvalStatus is a struct with detailed info about an evaluation in progress.
SmallVectorImpl< PartialDiagnosticAt > * Diag
Diag - If this is non-null, it will be filled in with a stack of notes indicating why evaluation fail...
bool HasSideEffects
Whether the evaluated expression has side effects.
unsigned SuppressLambdaBody
Whether to suppress printing the body of a lambda.
@ DerivedToBaseAdjustment
@ MemberPointerAdjustment
static ObjectUnderConstruction getTombstoneKey()
DenseMapInfo< APValue::LValueBase > Base
static ObjectUnderConstruction getEmptyKey()
static unsigned getHashValue(const ObjectUnderConstruction &Object)
static bool isEqual(const ObjectUnderConstruction &LHS, const ObjectUnderConstruction &RHS)