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 =
118 static unsigned countNonVirtualBases(
const CXXRecordDecl *RD) {
119 return llvm::count_if(RD->
bases(), [](
auto &B) { return !B.isVirtual(); });
126 static const CallExpr *tryUnwrapAllocSizeCall(
const Expr *E) {
134 if (
const auto *FE = dyn_cast<FullExpr>(E))
137 if (
const auto *Cast = dyn_cast<CastExpr>(E))
138 E = Cast->getSubExpr()->IgnoreParens();
140 if (
const auto *CE = dyn_cast<CallExpr>(E))
141 return CE->getCalleeAllocSizeAttr() ? CE :
nullptr;
148 const auto *E =
Base.dyn_cast<
const Expr *>();
149 return E && E->getType()->isPointerType() && tryUnwrapAllocSizeCall(E);
157 case ConstantExprKind::Normal:
158 case ConstantExprKind::ClassTemplateArgument:
159 case ConstantExprKind::ImmediateInvocation:
164 case ConstantExprKind::NonClassTemplateArgument:
167 llvm_unreachable(
"unknown ConstantExprKind");
172 case ConstantExprKind::Normal:
173 case ConstantExprKind::ImmediateInvocation:
176 case ConstantExprKind::ClassTemplateArgument:
177 case ConstantExprKind::NonClassTemplateArgument:
180 llvm_unreachable(
"unknown ConstantExprKind");
186 static const uint64_t AssumedSizeForUnsizedArray =
187 std::numeric_limits<uint64_t>::max() / 2;
197 bool &FirstEntryIsUnsizedArray) {
200 assert(!isBaseAnAllocSizeCall(
Base) &&
201 "Unsized arrays shouldn't appear here");
202 unsigned MostDerivedLength = 0;
207 for (
unsigned I = 0, N = Path.size(); I != N; ++I) {
211 MostDerivedLength = I + 1;
214 if (
auto *CAT = dyn_cast<ConstantArrayType>(AT)) {
215 ArraySize = CAT->getZExtSize();
217 assert(I == 0 &&
"unexpected unsized array designator");
218 FirstEntryIsUnsizedArray =
true;
219 ArraySize = AssumedSizeForUnsizedArray;
225 MostDerivedLength = I + 1;
228 Type = VT->getElementType();
229 ArraySize = VT->getNumElements();
230 MostDerivedLength = I + 1;
232 }
else if (
const FieldDecl *FD = getAsField(Path[I])) {
233 Type = FD->getType();
235 MostDerivedLength = I + 1;
243 return MostDerivedLength;
247 struct SubobjectDesignator {
251 LLVM_PREFERRED_TYPE(
bool)
255 LLVM_PREFERRED_TYPE(
bool)
256 unsigned IsOnePastTheEnd : 1;
259 LLVM_PREFERRED_TYPE(
bool)
260 unsigned FirstEntryIsAnUnsizedArray : 1;
263 LLVM_PREFERRED_TYPE(
bool)
264 unsigned MostDerivedIsArrayElement : 1;
268 unsigned MostDerivedPathLength : 28;
277 uint64_t MostDerivedArraySize;
286 SubobjectDesignator() :
Invalid(
true) {}
289 :
Invalid(
false), IsOnePastTheEnd(
false),
290 FirstEntryIsAnUnsizedArray(
false), MostDerivedIsArrayElement(
false),
291 MostDerivedPathLength(0), MostDerivedArraySize(0),
292 MostDerivedType(
T.isNull() ?
QualType() :
T.getNonReferenceType()) {}
295 :
Invalid(!
V.isLValue() || !
V.hasLValuePath()), IsOnePastTheEnd(
false),
296 FirstEntryIsAnUnsizedArray(
false), MostDerivedIsArrayElement(
false),
297 MostDerivedPathLength(0), MostDerivedArraySize(0) {
298 assert(
V.isLValue() &&
"Non-LValue used to make an LValue designator?");
300 IsOnePastTheEnd =
V.isLValueOnePastTheEnd();
301 llvm::append_range(Entries,
V.getLValuePath());
302 if (
V.getLValueBase()) {
303 bool IsArray =
false;
304 bool FirstIsUnsizedArray =
false;
305 MostDerivedPathLength = findMostDerivedSubobject(
306 Ctx,
V.getLValueBase(),
V.getLValuePath(), MostDerivedArraySize,
307 MostDerivedType, IsArray, FirstIsUnsizedArray);
308 MostDerivedIsArrayElement = IsArray;
309 FirstEntryIsAnUnsizedArray = FirstIsUnsizedArray;
315 unsigned NewLength) {
319 assert(
Base &&
"cannot truncate path for null pointer");
320 assert(NewLength <= Entries.size() &&
"not a truncation");
322 if (NewLength == Entries.size())
324 Entries.resize(NewLength);
326 bool IsArray =
false;
327 bool FirstIsUnsizedArray =
false;
328 MostDerivedPathLength = findMostDerivedSubobject(
329 Ctx,
Base, Entries, MostDerivedArraySize, MostDerivedType, IsArray,
330 FirstIsUnsizedArray);
331 MostDerivedIsArrayElement = IsArray;
332 FirstEntryIsAnUnsizedArray = FirstIsUnsizedArray;
342 bool isMostDerivedAnUnsizedArray()
const {
343 assert(!
Invalid &&
"Calling this makes no sense on invalid designators");
344 return Entries.size() == 1 && FirstEntryIsAnUnsizedArray;
349 uint64_t getMostDerivedArraySize()
const {
350 assert(!isMostDerivedAnUnsizedArray() &&
"Unsized array has no size");
351 return MostDerivedArraySize;
355 bool isOnePastTheEnd()
const {
359 if (!isMostDerivedAnUnsizedArray() && MostDerivedIsArrayElement &&
360 Entries[MostDerivedPathLength - 1].getAsArrayIndex() ==
361 MostDerivedArraySize)
369 std::pair<uint64_t, uint64_t> validIndexAdjustments() {
370 if (
Invalid || isMostDerivedAnUnsizedArray())
376 bool IsArray = MostDerivedPathLength == Entries.size() &&
377 MostDerivedIsArrayElement;
378 uint64_t ArrayIndex = IsArray ? Entries.back().getAsArrayIndex()
379 : (uint64_t)IsOnePastTheEnd;
381 IsArray ? getMostDerivedArraySize() : (uint64_t)1;
382 return {ArrayIndex, ArraySize - ArrayIndex};
386 bool isValidSubobject()
const {
389 return !isOnePastTheEnd();
397 assert(!
Invalid &&
"invalid designator has no subobject type");
398 return MostDerivedPathLength == Entries.size()
409 MostDerivedIsArrayElement =
true;
411 MostDerivedPathLength = Entries.size();
415 void addUnsizedArrayUnchecked(
QualType ElemTy) {
418 MostDerivedType = ElemTy;
419 MostDerivedIsArrayElement =
true;
423 MostDerivedArraySize = AssumedSizeForUnsizedArray;
424 MostDerivedPathLength = Entries.size();
428 void addDeclUnchecked(
const Decl *D,
bool Virtual =
false) {
432 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
433 MostDerivedType = FD->getType();
434 MostDerivedIsArrayElement =
false;
435 MostDerivedArraySize = 0;
436 MostDerivedPathLength = Entries.size();
440 void addComplexUnchecked(
QualType EltTy,
bool Imag) {
445 MostDerivedType = EltTy;
446 MostDerivedIsArrayElement =
true;
447 MostDerivedArraySize = 2;
448 MostDerivedPathLength = Entries.size();
451 void addVectorElementUnchecked(
QualType EltTy, uint64_t Size,
454 MostDerivedType = EltTy;
455 MostDerivedPathLength = Entries.size();
456 MostDerivedArraySize = 0;
457 MostDerivedIsArrayElement =
false;
460 void diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info,
const Expr *E);
461 void diagnosePointerArithmetic(EvalInfo &Info,
const Expr *E,
464 void adjustIndex(EvalInfo &Info,
const Expr *E,
APSInt N,
const LValue &LV);
468 enum class ScopeKind {
476 CallRef() : OrigCallee(), CallIndex(0), Version() {}
477 CallRef(
const FunctionDecl *Callee,
unsigned CallIndex,
unsigned Version)
478 : OrigCallee(Callee), CallIndex(CallIndex), Version(Version) {}
480 explicit operator bool()
const {
return OrigCallee; }
506 CallStackFrame *Caller;
528 typedef std::pair<const void *, unsigned> MapKeyTy;
529 typedef std::map<MapKeyTy, APValue>
MapTy;
541 unsigned CurTempVersion = TempVersionStack.back();
543 unsigned getTempVersion()
const {
return TempVersionStack.back(); }
545 void pushTempVersion() {
546 TempVersionStack.push_back(++CurTempVersion);
549 void popTempVersion() {
550 TempVersionStack.pop_back();
554 return {Callee, Index, ++CurTempVersion};
565 llvm::DenseMap<const ValueDecl *, FieldDecl *> LambdaCaptureFields;
566 FieldDecl *LambdaThisCaptureField =
nullptr;
568 CallStackFrame(EvalInfo &Info,
SourceRange CallRange,
574 APValue *getTemporary(
const void *Key,
unsigned Version) {
575 MapKeyTy KV(Key, Version);
576 auto LB = Temporaries.lower_bound(KV);
577 if (LB != Temporaries.end() && LB->first == KV)
583 APValue *getCurrentTemporary(
const void *Key) {
584 auto UB = Temporaries.upper_bound(MapKeyTy(Key,
UINT_MAX));
585 if (UB != Temporaries.begin() && std::prev(UB)->first.first == Key)
586 return &std::prev(UB)->second;
591 unsigned getCurrentTemporaryVersion(
const void *Key)
const {
592 auto UB = Temporaries.upper_bound(MapKeyTy(Key,
UINT_MAX));
593 if (UB != Temporaries.begin() && std::prev(UB)->first.first == Key)
594 return std::prev(UB)->first.second;
602 template<
typename KeyT>
604 ScopeKind
Scope, LValue &LV);
609 void describe(llvm::raw_ostream &OS)
const override;
611 Frame *getCaller()
const override {
return Caller; }
612 SourceRange getCallRange()
const override {
return CallRange; }
615 bool isStdFunction()
const {
616 for (
const DeclContext *DC = Callee; DC; DC = DC->getParent())
617 if (DC->isStdNamespace())
624 bool CanEvalMSConstexpr =
false;
632 class ThisOverrideRAII {
634 ThisOverrideRAII(CallStackFrame &Frame,
const LValue *NewThis,
bool Enable)
635 : Frame(Frame), OldThis(Frame.This) {
637 Frame.This = NewThis;
639 ~ThisOverrideRAII() {
640 Frame.This = OldThis;
643 CallStackFrame &Frame;
644 const LValue *OldThis;
649 class ExprTimeTraceScope {
651 ExprTimeTraceScope(
const Expr *E,
const ASTContext &Ctx, StringRef Name)
652 : TimeScope(Name, [E, &Ctx] {
657 llvm::TimeTraceScope TimeScope;
662 struct MSConstexprContextRAII {
663 CallStackFrame &Frame;
665 explicit MSConstexprContextRAII(CallStackFrame &Frame,
bool Value)
666 : Frame(Frame), OldValue(Frame.CanEvalMSConstexpr) {
667 Frame.CanEvalMSConstexpr =
Value;
670 ~MSConstexprContextRAII() { Frame.CanEvalMSConstexpr = OldValue; }
683 llvm::PointerIntPair<APValue*, 2, ScopeKind> Value;
684 APValue::LValueBase Base;
688 Cleanup(
APValue *Val, APValue::LValueBase Base, QualType T,
690 : Value(Val, Scope), Base(Base), T(T) {}
694 bool isDestroyedAtEndOf(ScopeKind K)
const {
695 return (
int)Value.getInt() >= (
int)K;
697 bool endLifetime(EvalInfo &Info,
bool RunDestructors) {
698 if (RunDestructors) {
700 if (
const ValueDecl *VD = Base.dyn_cast<
const ValueDecl*>())
701 Loc = VD->getLocation();
702 else if (
const Expr *E = Base.dyn_cast<
const Expr*>())
703 Loc = E->getExprLoc();
706 *Value.getPointer() =
APValue();
710 bool hasSideEffect() {
711 return T.isDestructedType();
716 struct ObjectUnderConstruction {
717 APValue::LValueBase Base;
718 ArrayRef<APValue::LValuePathEntry> Path;
719 friend bool operator==(
const ObjectUnderConstruction &LHS,
720 const ObjectUnderConstruction &RHS) {
721 return LHS.Base == RHS.Base && LHS.Path == RHS.Path;
723 friend llvm::hash_code
hash_value(
const ObjectUnderConstruction &Obj) {
724 return llvm::hash_combine(Obj.Base, Obj.Path);
727 enum class ConstructionPhase {
738template<>
struct DenseMapInfo<ObjectUnderConstruction> {
739 using Base = DenseMapInfo<APValue::LValueBase>;
743 static bool isEqual(
const ObjectUnderConstruction &LHS,
744 const ObjectUnderConstruction &RHS) {
758 const Expr *AllocExpr =
nullptr;
769 if (
auto *NE = dyn_cast<CXXNewExpr>(AllocExpr))
770 return NE->isArray() ? ArrayNew : New;
776 struct DynAllocOrder {
777 bool operator()(DynamicAllocLValue L, DynamicAllocLValue R)
const {
799 CallStackFrame *CurrentCall;
802 unsigned CallStackDepth;
805 unsigned NextCallIndex;
814 bool EnableNewConstInterp;
818 CallStackFrame BottomFrame;
822 llvm::SmallVector<Cleanup, 16> CleanupStack;
826 APValue::LValueBase EvaluatingDecl;
828 enum class EvaluatingDeclKind {
835 EvaluatingDeclKind IsEvaluatingDecl = EvaluatingDeclKind::None;
844 SmallVector<const Stmt *> BreakContinueStack;
847 llvm::DenseMap<ObjectUnderConstruction, ConstructionPhase>
848 ObjectsUnderConstruction;
853 std::map<DynamicAllocLValue, DynAlloc, DynAllocOrder> HeapAllocs;
856 unsigned NumHeapAllocs = 0;
858 struct EvaluatingConstructorRAII {
860 ObjectUnderConstruction Object;
862 EvaluatingConstructorRAII(EvalInfo &EI, ObjectUnderConstruction Object,
864 : EI(EI), Object(Object) {
866 EI.ObjectsUnderConstruction
867 .insert({Object, HasBases ? ConstructionPhase::Bases
868 : ConstructionPhase::AfterBases})
871 void finishedConstructingBases() {
872 EI.ObjectsUnderConstruction[Object] = ConstructionPhase::AfterBases;
874 void finishedConstructingFields() {
875 EI.ObjectsUnderConstruction[Object] = ConstructionPhase::AfterFields;
877 ~EvaluatingConstructorRAII() {
878 if (DidInsert) EI.ObjectsUnderConstruction.erase(Object);
882 struct EvaluatingDestructorRAII {
884 ObjectUnderConstruction Object;
886 EvaluatingDestructorRAII(EvalInfo &EI, ObjectUnderConstruction Object)
887 : EI(EI), Object(Object) {
888 DidInsert = EI.ObjectsUnderConstruction
889 .insert({Object, ConstructionPhase::Destroying})
892 void startedDestroyingBases() {
893 EI.ObjectsUnderConstruction[Object] =
894 ConstructionPhase::DestroyingBases;
896 ~EvaluatingDestructorRAII() {
898 EI.ObjectsUnderConstruction.erase(Object);
903 isEvaluatingCtorDtor(APValue::LValueBase Base,
904 ArrayRef<APValue::LValuePathEntry> Path) {
905 return ObjectsUnderConstruction.lookup({
Base, Path});
910 unsigned SpeculativeEvaluationDepth = 0;
916 EvalInfo(
const ASTContext &
C, Expr::EvalStatus &S,
EvaluationMode Mode)
917 : State(const_cast<ASTContext &>(
C), S), CurrentCall(
nullptr),
918 CallStackDepth(0), NextCallIndex(1),
919 StepsLeft(
C.getLangOpts().ConstexprStepLimit),
920 EnableNewConstInterp(
C.getLangOpts().EnableNewConstInterp),
921 BottomFrame(*this, SourceLocation(),
nullptr,
924 EvaluatingDecl((const ValueDecl *)
nullptr),
933 void setEvaluatingDecl(APValue::LValueBase Base,
APValue &
Value,
934 EvaluatingDeclKind EDK = EvaluatingDeclKind::Ctor) {
935 EvaluatingDecl =
Base;
936 IsEvaluatingDecl = EDK;
937 EvaluatingDeclValue = &
Value;
940 bool CheckCallLimit(SourceLocation Loc) {
943 if (checkingPotentialConstantExpression() && CallStackDepth > 1)
945 if (NextCallIndex == 0) {
947 FFDiag(Loc, diag::note_constexpr_call_limit_exceeded);
950 if (CallStackDepth <= getLangOpts().ConstexprCallDepth)
952 FFDiag(Loc, diag::note_constexpr_depth_limit_exceeded)
953 << getLangOpts().ConstexprCallDepth;
958 uint64_t ElemCount,
bool Diag) {
964 ElemCount >
uint64_t(std::numeric_limits<unsigned>::max())) {
966 FFDiag(Loc, diag::note_constexpr_new_too_large) << ElemCount;
975 uint64_t Limit = getLangOpts().ConstexprStepLimit;
976 if (Limit != 0 && ElemCount > Limit) {
978 FFDiag(Loc, diag::note_constexpr_new_exceeds_limits, 1)
979 << ElemCount << Limit;
980 Note(Loc, diag::note_constexpr_steps);
987 std::pair<CallStackFrame *, unsigned>
988 getCallFrameAndDepth(
unsigned CallIndex) {
989 assert(CallIndex &&
"no call index in getCallFrameAndDepth");
992 unsigned Depth = CallStackDepth;
993 CallStackFrame *Frame = CurrentCall;
994 while (Frame->Index > CallIndex) {
995 Frame = Frame->Caller;
998 if (Frame->Index == CallIndex)
999 return {Frame, Depth};
1000 return {
nullptr, 0};
1003 bool nextStep(
const Stmt *S) {
1004 if (getLangOpts().ConstexprStepLimit == 0)
1008 FFDiag(S->
getBeginLoc(), diag::note_constexpr_step_limit_exceeded, 1)
1009 << getLangOpts().ConstexprStepLimit;
1017 APValue *createHeapAlloc(
const Expr *E, QualType
T, LValue &LV);
1019 std::optional<DynAlloc *> lookupDynamicAlloc(DynamicAllocLValue DA) {
1020 std::optional<DynAlloc *>
Result;
1021 auto It = HeapAllocs.find(DA);
1022 if (It != HeapAllocs.end())
1028 APValue *getParamSlot(CallRef
Call,
const ParmVarDecl *PVD) {
1029 CallStackFrame *Frame = getCallFrameAndDepth(
Call.CallIndex).first;
1030 return Frame ? Frame->getTemporary(
Call.getOrigParam(PVD),
Call.Version)
1035 struct StdAllocatorCaller {
1036 unsigned FrameIndex;
1039 explicit operator bool()
const {
return FrameIndex != 0; };
1042 StdAllocatorCaller getStdAllocatorCaller(StringRef FnName)
const {
1043 for (
const CallStackFrame *
Call = CurrentCall;
Call->Caller !=
nullptr;
1045 const auto *MD = dyn_cast_or_null<CXXMethodDecl>(
Call->Callee);
1048 const IdentifierInfo *FnII = MD->getIdentifier();
1049 if (!FnII || !FnII->
isStr(FnName))
1053 dyn_cast<ClassTemplateSpecializationDecl>(MD->getParent());
1057 const IdentifierInfo *ClassII = CTSD->getIdentifier();
1058 const TemplateArgumentList &TAL = CTSD->getTemplateArgs();
1059 if (CTSD->isInStdNamespace() && ClassII &&
1060 ClassII->
isStr(
"allocator") && TAL.
size() >= 1 &&
1062 return {
Call->Index, TAL[0].getAsType(),
Call->CallExpr};
1068 void performLifetimeExtension() {
1070 llvm::erase_if(CleanupStack, [](Cleanup &
C) {
1071 return !
C.isDestroyedAtEndOf(ScopeKind::FullExpression);
1078 bool discardCleanups() {
1079 for (Cleanup &
C : CleanupStack) {
1080 if (
C.hasSideEffect() && !noteSideEffect()) {
1081 CleanupStack.clear();
1085 CleanupStack.clear();
1090 const interp::Frame *getCurrentFrame()
override {
return CurrentCall; }
1092 unsigned getCallStackDepth()
override {
return CallStackDepth; }
1093 bool stepsLeft()
const override {
return StepsLeft > 0; }
1106 [[nodiscard]]
bool noteFailure() {
1114 bool KeepGoing = keepEvaluatingAfterFailure();
1115 EvalStatus.HasSideEffects |= KeepGoing;
1119 class ArrayInitLoopIndex {
1124 ArrayInitLoopIndex(EvalInfo &Info)
1125 : Info(Info), OuterIndex(Info.ArrayInitIndex) {
1126 Info.ArrayInitIndex = 0;
1128 ~ArrayInitLoopIndex() { Info.ArrayInitIndex = OuterIndex; }
1130 operator uint64_t&() {
return Info.ArrayInitIndex; }
1135 struct FoldConstant {
1138 bool HadNoPriorDiags;
1141 explicit FoldConstant(EvalInfo &Info,
bool Enabled)
1144 HadNoPriorDiags(Info.EvalStatus.
Diag &&
1145 Info.EvalStatus.
Diag->empty() &&
1146 !Info.EvalStatus.HasSideEffects),
1147 OldMode(Info.EvalMode) {
1149 Info.EvalMode = EvaluationMode::ConstantFold;
1151 void keepDiagnostics() { Enabled =
false; }
1153 if (Enabled && HadNoPriorDiags && !Info.EvalStatus.Diag->empty() &&
1154 !Info.EvalStatus.HasSideEffects) {
1155 Info.EvalStatus.Diag->clear();
1156 Info.EvalStatus.DiagEmitted =
false;
1158 Info.EvalMode = OldMode;
1164 struct IgnoreSideEffectsRAII {
1167 explicit IgnoreSideEffectsRAII(EvalInfo &Info)
1168 : Info(Info), OldMode(Info.EvalMode) {
1169 Info.EvalMode = EvaluationMode::IgnoreSideEffects;
1172 ~IgnoreSideEffectsRAII() { Info.EvalMode = OldMode; }
1177 class SpeculativeEvaluationRAII {
1178 EvalInfo *Info =
nullptr;
1179 Expr::EvalStatus OldStatus;
1180 unsigned OldSpeculativeEvaluationDepth = 0;
1182 void moveFromAndCancel(SpeculativeEvaluationRAII &&
Other) {
1184 OldStatus =
Other.OldStatus;
1185 OldSpeculativeEvaluationDepth =
Other.OldSpeculativeEvaluationDepth;
1186 Other.Info =
nullptr;
1189 void maybeRestoreState() {
1193 Info->EvalStatus = OldStatus;
1194 Info->SpeculativeEvaluationDepth = OldSpeculativeEvaluationDepth;
1198 SpeculativeEvaluationRAII() =
default;
1200 SpeculativeEvaluationRAII(
1201 EvalInfo &Info, SmallVectorImpl<PartialDiagnosticAt> *NewDiag =
nullptr)
1202 : Info(&Info), OldStatus(Info.EvalStatus),
1203 OldSpeculativeEvaluationDepth(Info.SpeculativeEvaluationDepth) {
1204 Info.EvalStatus.Diag = NewDiag;
1205 Info.SpeculativeEvaluationDepth = Info.CallStackDepth + 1;
1208 SpeculativeEvaluationRAII(
const SpeculativeEvaluationRAII &
Other) =
delete;
1209 SpeculativeEvaluationRAII(SpeculativeEvaluationRAII &&
Other) {
1210 moveFromAndCancel(std::move(
Other));
1213 SpeculativeEvaluationRAII &operator=(SpeculativeEvaluationRAII &&
Other) {
1214 maybeRestoreState();
1215 moveFromAndCancel(std::move(
Other));
1219 ~SpeculativeEvaluationRAII() { maybeRestoreState(); }
1224 template<ScopeKind Kind>
1227 unsigned OldStackSize;
1229 ScopeRAII(EvalInfo &Info)
1230 : Info(Info), OldStackSize(Info.CleanupStack.size()) {
1233 Info.CurrentCall->pushTempVersion();
1235 bool destroy(
bool RunDestructors =
true) {
1236 bool OK =
cleanup(Info, RunDestructors, OldStackSize);
1237 OldStackSize = std::numeric_limits<unsigned>::max();
1241 if (OldStackSize != std::numeric_limits<unsigned>::max())
1245 Info.CurrentCall->popTempVersion();
1248 static bool cleanup(EvalInfo &Info,
bool RunDestructors,
1249 unsigned OldStackSize) {
1250 assert(OldStackSize <= Info.CleanupStack.size() &&
1251 "running cleanups out of order?");
1256 for (
unsigned I = Info.CleanupStack.size(); I > OldStackSize; --I) {
1257 if (Info.CleanupStack[I - 1].isDestroyedAtEndOf(Kind)) {
1258 if (!Info.CleanupStack[I - 1].endLifetime(Info, RunDestructors)) {
1266 auto NewEnd = Info.CleanupStack.begin() + OldStackSize;
1267 if (Kind != ScopeKind::Block)
1269 std::remove_if(NewEnd, Info.CleanupStack.end(), [](Cleanup &
C) {
1270 return C.isDestroyedAtEndOf(Kind);
1272 Info.CleanupStack.erase(NewEnd, Info.CleanupStack.end());
1276 typedef ScopeRAII<ScopeKind::Block> BlockScopeRAII;
1277 typedef ScopeRAII<ScopeKind::FullExpression> FullExpressionRAII;
1278 typedef ScopeRAII<ScopeKind::Call> CallScopeRAII;
1281bool SubobjectDesignator::checkSubobject(EvalInfo &Info,
const Expr *E,
1285 if (isOnePastTheEnd()) {
1286 Info.CCEDiag(E, diag::note_constexpr_past_end_subobject)
1297void SubobjectDesignator::diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info,
1299 Info.CCEDiag(E, diag::note_constexpr_unsized_array_indexed);
1304void SubobjectDesignator::diagnosePointerArithmetic(EvalInfo &Info,
1309 if (MostDerivedPathLength == Entries.size() && MostDerivedIsArrayElement)
1310 Info.CCEDiag(E, diag::note_constexpr_array_index)
1312 <<
static_cast<unsigned>(getMostDerivedArraySize());
1314 Info.CCEDiag(E, diag::note_constexpr_array_index)
1319CallStackFrame::CallStackFrame(EvalInfo &Info, SourceRange CallRange,
1320 const FunctionDecl *Callee,
const LValue *This,
1321 const Expr *CallExpr, CallRef Call)
1323 CallExpr(CallExpr),
Arguments(Call), CallRange(CallRange),
1324 Index(Info.NextCallIndex++) {
1325 Info.CurrentCall =
this;
1326 ++Info.CallStackDepth;
1329CallStackFrame::~CallStackFrame() {
1330 assert(Info.CurrentCall ==
this &&
"calls retired out of order");
1331 --Info.CallStackDepth;
1332 Info.CurrentCall = Caller;
1357 llvm_unreachable(
"unknown access kind");
1394 llvm_unreachable(
"unknown access kind");
1398 struct ComplexValue {
1406 ComplexValue() : FloatReal(
APFloat::Bogus()), FloatImag(
APFloat::Bogus()) {}
1408 void makeComplexFloat() { IsInt =
false; }
1409 bool isComplexFloat()
const {
return !IsInt; }
1410 APFloat &getComplexFloatReal() {
return FloatReal; }
1411 APFloat &getComplexFloatImag() {
return FloatImag; }
1413 void makeComplexInt() { IsInt =
true; }
1414 bool isComplexInt()
const {
return IsInt; }
1415 APSInt &getComplexIntReal() {
return IntReal; }
1416 APSInt &getComplexIntImag() {
return IntImag; }
1418 void moveInto(
APValue &v)
const {
1419 if (isComplexFloat())
1420 v =
APValue(FloatReal, FloatImag);
1422 v =
APValue(IntReal, IntImag);
1424 void setFrom(
const APValue &v) {
1439 APValue::LValueBase
Base;
1441 SubobjectDesignator Designator;
1443 bool InvalidBase : 1;
1445 bool AllowConstexprUnknown =
false;
1447 const APValue::LValueBase getLValueBase()
const {
return Base; }
1448 bool allowConstexprUnknown()
const {
return AllowConstexprUnknown; }
1449 CharUnits &getLValueOffset() {
return Offset; }
1450 const CharUnits &getLValueOffset()
const {
return Offset; }
1451 SubobjectDesignator &getLValueDesignator() {
return Designator; }
1452 const SubobjectDesignator &getLValueDesignator()
const {
return Designator;}
1453 bool isNullPointer()
const {
return IsNullPtr;}
1455 unsigned getLValueCallIndex()
const {
return Base.getCallIndex(); }
1456 unsigned getLValueVersion()
const {
return Base.getVersion(); }
1458 bool pointsToCompleteClass(
const CXXRecordDecl *D)
const {
1459 if (Designator.Entries.empty())
1466 if (Designator.Invalid)
1467 V =
APValue(Base, Offset, APValue::NoLValuePath(), IsNullPtr);
1469 assert(!InvalidBase &&
"APValues can't handle invalid LValue bases");
1470 V =
APValue(Base, Offset, Designator.Entries,
1471 Designator.IsOnePastTheEnd, IsNullPtr);
1473 if (AllowConstexprUnknown)
1474 V.setConstexprUnknown();
1476 void setFrom(
const ASTContext &Ctx,
const APValue &
V) {
1477 assert(
V.isLValue() &&
"Setting LValue from a non-LValue?");
1478 Base =
V.getLValueBase();
1479 Offset =
V.getLValueOffset();
1480 InvalidBase =
false;
1481 Designator = SubobjectDesignator(Ctx,
V);
1482 IsNullPtr =
V.isNullPointer();
1483 AllowConstexprUnknown =
V.allowConstexprUnknown();
1486 void set(APValue::LValueBase B,
bool BInvalid =
false) {
1490 const auto *E = B.
get<
const Expr *>();
1492 "Unexpected type of invalid base");
1498 InvalidBase = BInvalid;
1499 Designator = SubobjectDesignator(
getType(B));
1501 AllowConstexprUnknown =
false;
1504 void setNull(ASTContext &Ctx, QualType PointerTy) {
1505 Base = (
const ValueDecl *)
nullptr;
1508 InvalidBase =
false;
1511 AllowConstexprUnknown =
false;
1514 void setInvalid(APValue::LValueBase B,
unsigned I = 0) {
1518 std::string
toString(ASTContext &Ctx, QualType
T)
const {
1520 moveInto(Printable);
1527 template <
typename GenDiagType>
1528 bool checkNullPointerDiagnosingWith(
const GenDiagType &GenDiag) {
1529 if (Designator.Invalid)
1533 Designator.setInvalid();
1540 bool checkNullPointer(EvalInfo &Info,
const Expr *E,
1542 return checkNullPointerDiagnosingWith([&Info, E, CSK] {
1543 Info.CCEDiag(E, diag::note_constexpr_null_subobject) << CSK;
1547 bool checkNullPointerForFoldAccess(EvalInfo &Info,
const Expr *E,
1549 return checkNullPointerDiagnosingWith([&Info, E, AK] {
1550 if (AK == AccessKinds::AK_Dereference)
1551 Info.FFDiag(E, diag::note_constexpr_dereferencing_null);
1553 Info.FFDiag(E, diag::note_constexpr_access_null) << AK;
1561 Designator.checkSubobject(Info, E, CSK);
1564 void addDecl(EvalInfo &Info,
const Expr *E,
1565 const Decl *D,
bool Virtual =
false) {
1567 Designator.addDeclUnchecked(D,
Virtual);
1569 void addUnsizedArray(EvalInfo &Info,
const Expr *E, QualType ElemTy) {
1570 if (!Designator.Entries.empty()) {
1571 Info.CCEDiag(E, diag::note_constexpr_unsupported_unsized_array);
1572 Designator.setInvalid();
1576 assert(!Base ||
getType(Base).getNonReferenceType()->isPointerType() ||
1577 getType(Base).getNonReferenceType()->isArrayType());
1578 Designator.FirstEntryIsAnUnsizedArray =
true;
1579 Designator.addUnsizedArrayUnchecked(ElemTy);
1582 void addArray(EvalInfo &Info,
const Expr *E,
const ConstantArrayType *CAT) {
1584 Designator.addArrayUnchecked(CAT);
1586 void addComplex(EvalInfo &Info,
const Expr *E, QualType EltTy,
bool Imag) {
1588 Designator.addComplexUnchecked(EltTy, Imag);
1590 void addVectorElement(EvalInfo &Info,
const Expr *E, QualType EltTy,
1591 uint64_t Size, uint64_t Idx) {
1593 Designator.addVectorElementUnchecked(EltTy, Size, Idx);
1595 void clearIsNullPointer() {
1598 void adjustOffsetAndIndex(EvalInfo &Info,
const Expr *E,
1599 const APSInt &Index, CharUnits ElementSize) {
1610 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
1614 Designator.adjustIndex(Info, E, Index, *
this);
1615 clearIsNullPointer();
1617 void adjustOffset(CharUnits N) {
1620 clearIsNullPointer();
1626 explicit MemberPtr(
const ValueDecl *Decl)
1627 : DeclAndIsDerivedMember(
Decl,
false) {}
1631 const ValueDecl *getDecl()
const {
1632 return DeclAndIsDerivedMember.getPointer();
1635 bool isDerivedMember()
const {
1636 return DeclAndIsDerivedMember.getInt();
1639 const CXXRecordDecl *getContainingRecord()
const {
1641 DeclAndIsDerivedMember.getPointer()->getDeclContext());
1645 V =
APValue(getDecl(), isDerivedMember(), Path);
1648 assert(
V.isMemberPointer());
1649 DeclAndIsDerivedMember.setPointer(
V.getMemberPointerDecl());
1650 DeclAndIsDerivedMember.setInt(
V.isMemberPointerToDerivedMember());
1652 llvm::append_range(Path,
V.getMemberPointerPath());
1658 llvm::PointerIntPair<const ValueDecl*, 1, bool> DeclAndIsDerivedMember;
1661 SmallVector<const CXXRecordDecl*, 4> Path;
1665 bool castBack(
const CXXRecordDecl *
Class) {
1666 assert(!Path.empty());
1667 const CXXRecordDecl *Expected;
1668 if (Path.size() >= 2)
1669 Expected = Path[Path.size() - 2];
1671 Expected = getContainingRecord();
1685 bool castToDerived(
const CXXRecordDecl *Derived) {
1688 if (!isDerivedMember()) {
1689 Path.push_back(Derived);
1692 if (!castBack(Derived))
1695 DeclAndIsDerivedMember.setInt(
false);
1703 DeclAndIsDerivedMember.setInt(
true);
1704 if (isDerivedMember()) {
1705 Path.push_back(Base);
1708 return castBack(Base);
1713 static bool operator==(
const MemberPtr &LHS,
const MemberPtr &RHS) {
1714 if (!LHS.getDecl() || !RHS.getDecl())
1715 return !LHS.getDecl() && !RHS.getDecl();
1716 if (LHS.getDecl()->getCanonicalDecl() != RHS.getDecl()->getCanonicalDecl())
1718 return LHS.Path == RHS.Path;
1722void SubobjectDesignator::adjustIndex(EvalInfo &Info,
const Expr *E,
APSInt N,
1726 uint64_t TruncatedN = N.extOrTrunc(64).getZExtValue();
1727 if (isMostDerivedAnUnsizedArray()) {
1728 diagnoseUnsizedArrayPointerArithmetic(Info, E);
1733 PathEntry::ArrayIndex(Entries.back().getAsArrayIndex() + TruncatedN);
1741 MostDerivedPathLength == Entries.size() && MostDerivedIsArrayElement;
1743 IsArray ? Entries.back().getAsArrayIndex() : (
uint64_t)IsOnePastTheEnd;
1746 if (N < -(int64_t)ArrayIndex || N > ArraySize - ArrayIndex) {
1747 if (!Info.checkingPotentialConstantExpression() ||
1748 !LV.AllowConstexprUnknown) {
1751 N = N.extend(std::max<unsigned>(N.getBitWidth() + 1, 65));
1752 (llvm::APInt &)N += ArrayIndex;
1753 assert(N.ugt(ArraySize) &&
"bounds check failed for in-bounds index");
1754 diagnosePointerArithmetic(Info, E, N);
1760 ArrayIndex += TruncatedN;
1761 assert(ArrayIndex <= ArraySize &&
1762 "bounds check succeeded for out-of-bounds index");
1765 Entries.back() = PathEntry::ArrayIndex(ArrayIndex);
1767 IsOnePastTheEnd = (ArrayIndex != 0);
1772 const LValue &This,
const Expr *E,
1773 bool AllowNonLiteralTypes =
false);
1775 bool InvalidBaseOK =
false);
1777 bool InvalidBaseOK =
false);
1785static bool EvaluateComplex(
const Expr *E, ComplexValue &Res, EvalInfo &Info);
1790static std::optional<uint64_t>
1792 std::string *StringResult =
nullptr);
1809 if (Int.isUnsigned() || Int.isMinSignedValue()) {
1810 Int = Int.extend(Int.getBitWidth() + 1);
1811 Int.setIsSigned(
true);
1816template<
typename KeyT>
1817APValue &CallStackFrame::createTemporary(
const KeyT *Key, QualType
T,
1818 ScopeKind Scope, LValue &LV) {
1819 unsigned Version = getTempVersion();
1820 APValue::LValueBase
Base(Key, Index, Version);
1822 return createLocal(Base, Key,
T, Scope);
1826APValue &CallStackFrame::createParam(CallRef Args,
const ParmVarDecl *PVD,
1828 assert(Args.CallIndex == Index &&
"creating parameter in wrong frame");
1829 APValue::LValueBase
Base(PVD, Index, Args.Version);
1834 return createLocal(Base, PVD, PVD->
getType(), ScopeKind::Call);
1837APValue &CallStackFrame::createLocal(APValue::LValueBase Base,
const void *Key,
1838 QualType
T, ScopeKind Scope) {
1839 assert(
Base.getCallIndex() == Index &&
"lvalue for wrong frame");
1840 unsigned Version =
Base.getVersion();
1842 assert(
Result.isAbsent() &&
"local created multiple times");
1848 if (Index <= Info.SpeculativeEvaluationDepth) {
1849 if (
T.isDestructedType())
1850 Info.noteSideEffect();
1852 Info.CleanupStack.push_back(Cleanup(&
Result, Base,
T, Scope));
1857APValue *EvalInfo::createHeapAlloc(
const Expr *E, QualType
T, LValue &LV) {
1859 FFDiag(E, diag::note_constexpr_heap_alloc_limit_exceeded);
1863 DynamicAllocLValue DA(NumHeapAllocs++);
1865 auto Result = HeapAllocs.emplace(std::piecewise_construct,
1866 std::forward_as_tuple(DA), std::tuple<>());
1867 assert(
Result.second &&
"reused a heap alloc index?");
1868 Result.first->second.AllocExpr = E;
1869 return &
Result.first->second.Value;
1873void CallStackFrame::describe(raw_ostream &Out)
const {
1874 bool IsMemberCall =
false;
1875 bool ExplicitInstanceParam =
false;
1876 clang::PrintingPolicy PrintingPolicy = Info.Ctx.getPrintingPolicy();
1879 if (
const auto *MD = dyn_cast<CXXMethodDecl>(Callee)) {
1881 ExplicitInstanceParam = MD->isExplicitObjectMemberFunction();
1885 Callee->getNameForDiagnostic(Out, PrintingPolicy,
1888 if (This && IsMemberCall) {
1889 if (
const auto *MCE = dyn_cast_if_present<CXXMemberCallExpr>(CallExpr)) {
1890 const Expr *
Object = MCE->getImplicitObjectArgument();
1891 Object->printPretty(Out,
nullptr, PrintingPolicy,
1893 if (
Object->getType()->isPointerType())
1897 }
else if (
const auto *OCE =
1898 dyn_cast_if_present<CXXOperatorCallExpr>(CallExpr)) {
1899 OCE->getArg(0)->printPretty(Out,
nullptr, PrintingPolicy,
1904 This->moveInto(Val);
1907 Info.Ctx.getLValueReferenceType(
This->Designator.MostDerivedType));
1910 Callee->getNameForDiagnostic(Out, PrintingPolicy,
1916 llvm::ListSeparator
Comma;
1917 for (
const ParmVarDecl *Param :
1918 Callee->parameters().slice(ExplicitInstanceParam)) {
1920 const APValue *
V = Info.getParamSlot(Arguments, Param);
1922 V->printPretty(Out, Info.Ctx, Param->getType());
1938 return Info.noteSideEffect();
1945 return (
Builtin == Builtin::BI__builtin___CFStringMakeConstantString ||
1946 Builtin == Builtin::BI__builtin___NSStringMakeConstantString ||
1947 Builtin == Builtin::BI__builtin_ptrauth_sign_constant ||
1948 Builtin == Builtin::BI__builtin_function_start);
1952 const auto *BaseExpr =
1953 llvm::dyn_cast_if_present<CallExpr>(LVal.Base.
dyn_cast<
const Expr *>());
1968 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
1969 return VD->hasGlobalStorage();
1985 case Expr::CompoundLiteralExprClass: {
1989 case Expr::MaterializeTemporaryExprClass:
1994 case Expr::StringLiteralClass:
1995 case Expr::PredefinedExprClass:
1996 case Expr::ObjCStringLiteralClass:
1997 case Expr::ObjCEncodeExprClass:
1999 case Expr::ObjCBoxedExprClass:
2000 case Expr::ObjCArrayLiteralClass:
2001 case Expr::ObjCDictionaryLiteralClass:
2003 case Expr::CallExprClass:
2006 case Expr::AddrLabelExprClass:
2010 case Expr::BlockExprClass:
2014 case Expr::SourceLocExprClass:
2016 case Expr::ImplicitValueInitExprClass:
2041 const auto *BaseExpr = LVal.Base.
dyn_cast<
const Expr *>();
2046 if (
const auto *EE = dyn_cast<ObjCEncodeExpr>(BaseExpr)) {
2047 Info.Ctx.getObjCEncodingForType(EE->getEncodedType(),
2055 const auto *Lit = dyn_cast<StringLiteral>(BaseExpr);
2056 if (
const auto *PE = dyn_cast<PredefinedExpr>(BaseExpr))
2057 Lit = PE->getFunctionName();
2062 AsString.
Bytes = Lit->getBytes();
2063 AsString.
CharWidth = Lit->getCharByteWidth();
2083 const LValue &RHS) {
2092 CharUnits Offset = RHS.Offset - LHS.Offset;
2093 if (Offset.isNegative()) {
2094 if (LHSString.
Bytes.size() < (
size_t)-Offset.getQuantity())
2096 LHSString.
Bytes = LHSString.
Bytes.drop_front(-Offset.getQuantity());
2098 if (RHSString.
Bytes.size() < (
size_t)Offset.getQuantity())
2100 RHSString.
Bytes = RHSString.
Bytes.drop_front(Offset.getQuantity());
2103 bool LHSIsLonger = LHSString.
Bytes.size() > RHSString.
Bytes.size();
2104 StringRef Longer = LHSIsLonger ? LHSString.
Bytes : RHSString.
Bytes;
2105 StringRef Shorter = LHSIsLonger ? RHSString.
Bytes : LHSString.
Bytes;
2106 int ShorterCharWidth = (LHSIsLonger ? RHSString : LHSString).CharWidth;
2111 for (
int NullByte : llvm::seq(ShorterCharWidth)) {
2112 if (Shorter.size() + NullByte >= Longer.size())
2114 if (Longer[Shorter.size() + NullByte])
2120 return Shorter == Longer.take_front(Shorter.size());
2130 if (isa_and_nonnull<VarDecl>(
Decl)) {
2140 if (!A.getLValueBase())
2141 return !B.getLValueBase();
2142 if (!B.getLValueBase())
2145 if (A.getLValueBase().getOpaqueValue() !=
2146 B.getLValueBase().getOpaqueValue())
2149 return A.getLValueCallIndex() == B.getLValueCallIndex() &&
2150 A.getLValueVersion() == B.getLValueVersion();
2154 assert(
Base &&
"no location for a null lvalue");
2160 if (
auto *PVD = dyn_cast_or_null<ParmVarDecl>(VD)) {
2162 for (CallStackFrame *F = Info.CurrentCall; F; F = F->Caller) {
2163 if (F->Arguments.CallIndex ==
Base.getCallIndex() &&
2164 F->Arguments.Version ==
Base.getVersion() && F->Callee &&
2165 Idx < F->Callee->getNumParams()) {
2166 VD = F->Callee->getParamDecl(Idx);
2173 Info.Note(VD->
getLocation(), diag::note_declared_at);
2175 Info.Note(E->
getExprLoc(), diag::note_constexpr_temporary_here);
2178 if (std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA))
2179 Info.Note((*Alloc)->AllocExpr->getExprLoc(),
2180 diag::note_constexpr_dynamic_alloc_here);
2202 bool IsCompleteClass =
true);
2214 const SubobjectDesignator &
Designator = LVal.getLValueDesignator();
2222 if (isTemplateArgument(Kind)) {
2223 int InvalidBaseKind = -1;
2226 InvalidBaseKind = 0;
2227 else if (isa_and_nonnull<StringLiteral>(BaseE))
2228 InvalidBaseKind = 1;
2229 else if (isa_and_nonnull<MaterializeTemporaryExpr>(BaseE) ||
2230 isa_and_nonnull<LifetimeExtendedTemporaryDecl>(BaseVD))
2231 InvalidBaseKind = 2;
2232 else if (
auto *PE = dyn_cast_or_null<PredefinedExpr>(BaseE)) {
2233 InvalidBaseKind = 3;
2234 Ident = PE->getIdentKindName();
2237 if (InvalidBaseKind != -1) {
2238 Info.FFDiag(Loc, diag::note_constexpr_invalid_template_arg)
2239 << IsReferenceType << !
Designator.Entries.empty() << InvalidBaseKind
2245 if (
auto *FD = dyn_cast_or_null<FunctionDecl>(BaseVD);
2246 FD && FD->isImmediateFunction()) {
2247 Info.FFDiag(Loc, diag::note_consteval_address_accessible)
2249 Info.Note(FD->getLocation(), diag::note_declared_at);
2257 if (Info.getLangOpts().CPlusPlus11) {
2258 Info.FFDiag(Loc, diag::note_constexpr_non_global, 1)
2259 << IsReferenceType << !
Designator.Entries.empty() << !!BaseVD
2261 auto *VarD = dyn_cast_or_null<VarDecl>(BaseVD);
2262 if (VarD && VarD->isConstexpr()) {
2268 Info.Note(VarD->getLocation(), diag::note_constexpr_not_static)
2280 assert((Info.checkingPotentialConstantExpression() ||
2281 LVal.getLValueCallIndex() == 0) &&
2282 "have call index for global lvalue");
2284 if (LVal.allowConstexprUnknown()) {
2286 Info.FFDiag(Loc, diag::note_constexpr_var_init_non_constant, 1) << BaseVD;
2295 Info.FFDiag(Loc, diag::note_constexpr_dynamic_alloc)
2296 << IsReferenceType << !
Designator.Entries.empty();
2302 if (
const VarDecl *Var = dyn_cast<const VarDecl>(BaseVD)) {
2304 if (Var->getTLSKind())
2312 if (!isForManglingOnly(Kind) && Var->hasAttr<DLLImportAttr>() &&
2313 !Var->isStaticLocal())
2318 if (Info.getLangOpts().CUDA && Info.getLangOpts().CUDAIsDevice &&
2319 Info.Ctx.CUDAConstantEvalCtx.NoWrongSidedVars) {
2320 if ((!Var->hasAttr<CUDADeviceAttr>() &&
2321 !Var->hasAttr<CUDAConstantAttr>() &&
2322 !Var->getType()->isCUDADeviceBuiltinSurfaceType() &&
2323 !Var->getType()->isCUDADeviceBuiltinTextureType()) ||
2324 Var->hasAttr<HIPManagedAttr>())
2328 if (
const auto *FD = dyn_cast<const FunctionDecl>(BaseVD)) {
2339 if (Info.getLangOpts().CPlusPlus && !isForManglingOnly(Kind) &&
2340 FD->hasAttr<DLLImportAttr>())
2344 }
else if (
const auto *MTE =
2345 dyn_cast_or_null<MaterializeTemporaryExpr>(BaseE)) {
2346 if (CheckedTemps.insert(MTE).second) {
2349 Info.FFDiag(MTE->getExprLoc(),
2350 diag::note_constexpr_unsupported_temporary_nontrivial_dtor)
2355 APValue *
V = MTE->getOrCreateValue(
false);
2356 assert(
V &&
"evasluation result refers to uninitialised temporary");
2358 Info, MTE->getExprLoc(), TempType, *
V, Kind,
2359 nullptr, CheckedTemps))
2366 if (!IsReferenceType)
2378 Info.FFDiag(Loc, diag::note_constexpr_past_end, 1)
2379 << !
Designator.Entries.empty() << !!BaseVD << BaseVD;
2394 const auto *FD = dyn_cast_or_null<CXXMethodDecl>(
Member);
2397 if (FD->isImmediateFunction()) {
2398 Info.FFDiag(Loc, diag::note_consteval_address_accessible) << 0;
2399 Info.Note(FD->getLocation(), diag::note_declared_at);
2402 return isForManglingOnly(Kind) || FD->isVirtual() ||
2403 !FD->hasAttr<DLLImportAttr>();
2409 const LValue *
This =
nullptr) {
2411 if (Info.getLangOpts().CPlusPlus23)
2430 if (
This && Info.EvaluatingDecl ==
This->getLValueBase())
2434 if (Info.getLangOpts().CPlusPlus11)
2435 Info.FFDiag(E, diag::note_constexpr_nonliteral)
2438 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
2448 bool IsCompleteClass) {
2450 if (SubobjectDecl) {
2451 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
2452 << 1 << SubobjectDecl;
2454 diag::note_constexpr_subobject_declared_here);
2456 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
2465 Type = AT->getValueType();
2470 if (
Value.isArray()) {
2472 for (
unsigned I = 0, N =
Value.getArrayInitializedElts(); I != N; ++I) {
2474 Value.getArrayInitializedElt(I), Kind,
2475 SubobjectDecl, CheckedTemps))
2478 if (!
Value.hasArrayFiller())
2481 Value.getArrayFiller(), Kind, SubobjectDecl,
2484 if (
Value.isUnion() &&
Value.getUnionField()) {
2487 Value.getUnionValue(), Kind,
Value.getUnionField(), CheckedTemps);
2489 if (
Value.isStruct()) {
2491 if (
const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {
2492 unsigned BaseIndex = 0;
2496 const APValue &BaseValue =
Value.getStructBase(BaseIndex);
2499 Info.FFDiag(TypeBeginLoc, diag::note_constexpr_uninitialized_base)
2500 << BS.getType() <<
SourceRange(TypeBeginLoc, BS.getEndLoc());
2505 CheckedTemps,
false))
2510 for (
const auto *I : RD->fields()) {
2511 if (I->isUnnamedBitField())
2515 Value.getStructField(I->getFieldIndex()), Kind,
2520 if (IsCompleteClass) {
2521 if (
const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {
2522 unsigned BaseIndex = 0;
2524 assert(BS.isVirtual());
2525 const APValue &BaseValue =
Value.getStructVirtualBase(BaseIndex);
2528 Info.FFDiag(TypeBeginLoc, diag::note_constexpr_uninitialized_base)
2529 << BS.getType() <<
SourceRange(TypeBeginLoc, BS.getEndLoc());
2533 BaseValue, Kind,
nullptr,
2534 CheckedTemps,
false))
2542 if (
Value.isLValue() &&
2545 LVal.setFrom(Info.Ctx,
Value);
2550 if (
Value.isMemberPointer() &&
2571 nullptr, CheckedTemps);
2581 ConstantExprKind::Normal,
nullptr, CheckedTemps);
2587 if (!Info.HeapAllocs.empty()) {
2591 Info.CCEDiag(Info.HeapAllocs.begin()->second.AllocExpr,
2592 diag::note_constexpr_memory_leak)
2593 <<
unsigned(Info.HeapAllocs.size() - 1);
2601 if (!
Value.getLValueBase()) {
2654 llvm_unreachable(
"unknown APValue kind");
2660 assert(E->
isPRValue() &&
"missing lvalue-to-rvalue conv in bool condition");
2670 Info.CCEDiag(E, diag::note_constexpr_overflow) << SrcValue << DestType;
2671 if (
const auto *OBT = DestType->
getAs<OverflowBehaviorType>();
2672 OBT && OBT->isTrapKind()) {
2675 return Info.noteUndefinedBehavior();
2681 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
2687 if (
Value.convertToInteger(
Result, llvm::APFloat::rmTowardZero, &ignored)
2688 & APFloat::opInvalidOp)
2699 llvm::RoundingMode RM =
2701 if (RM == llvm::RoundingMode::Dynamic)
2702 RM = llvm::RoundingMode::NearestTiesToEven;
2711 APFloat::opStatus St) {
2714 if (Info.InConstantContext)
2718 if ((St & APFloat::opInexact) &&
2722 Info.FFDiag(E, diag::note_constexpr_dynamic_rounding);
2726 if ((St != APFloat::opOK) &&
2729 FPO.getAllowFEnvAccess())) {
2730 Info.FFDiag(E, diag::note_constexpr_float_arithmetic_strict);
2734 if ((St & APFloat::opStatus::opInvalidOp) &&
2755 "HandleFloatToFloatCast has been checked with only CastExpr, "
2756 "CompoundAssignOperator and ConvertVectorExpr. Please either validate "
2757 "the new expression or address the root cause of this usage.");
2759 APFloat::opStatus St;
2762 St =
Result.convert(Info.Ctx.getFloatTypeSemantics(DestType), RM, &ignored);
2769 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
2783 Result = APFloat(Info.Ctx.getFloatTypeSemantics(DestType), 1);
2785 APFloat::opStatus St =
Result.convertFromAPInt(
Value,
Value.isSigned(), RM);
2791 assert(FD->
isBitField() &&
"truncateBitfieldValue on non-bitfield");
2793 if (!
Value.isInt()) {
2797 assert(
Value.isLValue() &&
"integral value neither int nor lvalue?");
2803 unsigned OldBitWidth = Int.getBitWidth();
2805 if (NewBitWidth < OldBitWidth)
2806 Int = Int.trunc(NewBitWidth).extend(OldBitWidth);
2813template<
typename Operation>
2816 unsigned BitWidth, Operation Op,
2818 if (LHS.isUnsigned()) {
2823 APSInt Value(Op(LHS.extend(BitWidth), RHS.extend(BitWidth)),
false);
2826 if (Info.checkingForUndefinedBehavior())
2827 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
2828 diag::warn_integer_constant_overflow)
2841 bool HandleOverflowResult =
true;
2848 std::multiplies<APSInt>(),
Result);
2851 std::plus<APSInt>(),
Result);
2854 std::minus<APSInt>(),
Result);
2855 case BO_And:
Result = LHS & RHS;
return true;
2856 case BO_Xor:
Result = LHS ^ RHS;
return true;
2857 case BO_Or:
Result = LHS | RHS;
return true;
2861 Info.FFDiag(E, diag::note_expr_divide_by_zero)
2867 if (RHS.isNegative() && RHS.isAllOnes() && LHS.isSigned() &&
2868 LHS.isMinSignedValue())
2870 Info, E, -LHS.extend(LHS.getBitWidth() + 1), E->
getType());
2871 Result = (Opcode == BO_Rem ? LHS % RHS : LHS / RHS);
2872 return HandleOverflowResult;
2874 if (Info.getLangOpts().OpenCL)
2876 RHS &=
APSInt(llvm::APInt(RHS.getBitWidth(),
2877 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2879 else if (RHS.isSigned() && RHS.isNegative()) {
2882 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
2883 if (!Info.noteUndefinedBehavior())
2891 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
2893 Info.CCEDiag(E, diag::note_constexpr_large_shift)
2894 << RHS << E->
getType() << LHS.getBitWidth();
2895 if (!Info.noteUndefinedBehavior())
2897 }
else if (LHS.isSigned() && !Info.getLangOpts().CPlusPlus20) {
2902 if (LHS.isNegative()) {
2903 Info.CCEDiag(E, diag::note_constexpr_lshift_of_negative) << LHS;
2904 if (!Info.noteUndefinedBehavior())
2906 }
else if (LHS.countl_zero() < SA) {
2907 Info.CCEDiag(E, diag::note_constexpr_lshift_discards);
2908 if (!Info.noteUndefinedBehavior())
2916 if (Info.getLangOpts().OpenCL)
2918 RHS &=
APSInt(llvm::APInt(RHS.getBitWidth(),
2919 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2921 else if (RHS.isSigned() && RHS.isNegative()) {
2924 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
2925 if (!Info.noteUndefinedBehavior())
2933 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
2935 Info.CCEDiag(E, diag::note_constexpr_large_shift)
2936 << RHS << E->
getType() << LHS.getBitWidth();
2937 if (!Info.noteUndefinedBehavior())
2945 case BO_LT:
Result = LHS < RHS;
return true;
2946 case BO_GT:
Result = LHS > RHS;
return true;
2947 case BO_LE:
Result = LHS <= RHS;
return true;
2948 case BO_GE:
Result = LHS >= RHS;
return true;
2949 case BO_EQ:
Result = LHS == RHS;
return true;
2950 case BO_NE:
Result = LHS != RHS;
return true;
2952 llvm_unreachable(
"BO_Cmp should be handled elsewhere");
2959 const APFloat &RHS) {
2961 APFloat::opStatus St;
2967 St = LHS.multiply(RHS, RM);
2970 St = LHS.add(RHS, RM);
2973 St = LHS.subtract(RHS, RM);
2979 Info.CCEDiag(E, diag::note_expr_divide_by_zero);
2980 St = LHS.divide(RHS, RM);
2993 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << LHS.isNaN();
2994 return Info.noteUndefinedBehavior();
3002 const APInt &RHSValue, APInt &
Result) {
3003 bool LHS = (LHSValue != 0);
3004 bool RHS = (RHSValue != 0);
3006 if (Opcode == BO_LAnd)
3014 const APFloat &RHSValue, APInt &
Result) {
3015 bool LHS = !LHSValue.isZero();
3016 bool RHS = !RHSValue.isZero();
3018 if (Opcode == BO_LAnd)
3037template <
typename APTy>
3040 const APTy &RHSValue, APInt &
Result) {
3043 llvm_unreachable(
"unsupported binary operator");
3045 Result = (LHSValue == RHSValue);
3048 Result = (LHSValue != RHSValue);
3051 Result = (LHSValue < RHSValue);
3054 Result = (LHSValue > RHSValue);
3057 Result = (LHSValue <= RHSValue);
3060 Result = (LHSValue >= RHSValue);
3089 assert(Opcode != BO_PtrMemD && Opcode != BO_PtrMemI &&
3090 "Operation not supported on vector types");
3094 QualType EltTy = VT->getElementType();
3101 "A vector result that isn't a vector OR uncalculated LValue");
3107 RHSValue.
getVectorLength() == NumElements &&
"Different vector sizes");
3111 for (
unsigned EltNum = 0; EltNum < NumElements; ++EltNum) {
3116 APSInt EltResult{Info.Ctx.getIntWidth(EltTy),
3126 RHSElt.
getInt(), EltResult);
3132 ResultElements.emplace_back(EltResult);
3137 "Mismatched LHS/RHS/Result Type");
3138 APFloat LHSFloat = LHSElt.
getFloat();
3146 ResultElements.emplace_back(LHSFloat);
3150 LHSValue =
APValue(ResultElements.data(), ResultElements.size());
3158 unsigned TruncatedElements) {
3159 SubobjectDesignator &D =
Result.Designator;
3162 if (TruncatedElements == D.Entries.size())
3164 assert(TruncatedElements >= D.MostDerivedPathLength &&
3165 "not casting to a derived class");
3171 for (
unsigned I = TruncatedElements, N = D.Entries.size(); I != N; ++I) {
3175 if (isVirtualBaseClass(D.Entries[I]))
3181 D.Entries.resize(TruncatedElements);
3191 RL = &Info.Ctx.getASTRecordLayout(Derived);
3194 Obj.addDecl(Info, E,
Base,
false);
3195 Obj.getLValueOffset() += RL->getBaseClassOffset(
Base);
3207 RL = &Info.Ctx.getASTRecordLayout(Derived);
3210 Obj.addDecl(Info, E,
Base,
true);
3211 Obj.getLValueOffset() += RL->getVBaseClassOffset(
Base);
3220 if (!
Base->isVirtual())
3223 SubobjectDesignator &D = Obj.Designator;
3238 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(DerivedDecl);
3239 Obj.addDecl(Info, E, BaseDecl,
true);
3248 PathI != PathE; ++PathI) {
3252 Type = (*PathI)->getType();
3264 llvm_unreachable(
"Class must be derived from the passed in base class!");
3288 RL = &Info.Ctx.getASTRecordLayout(RD);
3292 LVal.addDecl(Info, E, FD);
3293 LVal.adjustOffset(Info.Ctx.toCharUnitsFromBits(RL->getFieldOffset(I)));
3301 for (
const auto *
C : IFD->
chain())
3335 Size = Info.Ctx.getTypeSizeInChars(
Type);
3337 Size = Info.Ctx.getTypeInfoDataSizeInChars(
Type).Width;
3354 LVal.adjustOffsetAndIndex(Info, E, Adjustment, SizeOfPointee);
3360 int64_t Adjustment) {
3362 APSInt::get(Adjustment));
3377 LVal.Offset += SizeOfComponent;
3379 LVal.addComplex(Info, E, EltTy, Imag);
3385 uint64_t Size, uint64_t Idx) {
3390 LVal.Offset += SizeOfElement * Idx;
3392 LVal.addVectorElement(Info, E, EltTy, Size, Idx);
3406 const VarDecl *VD, CallStackFrame *Frame,
3410 bool AllowConstexprUnknown =
3415 auto CheckUninitReference = [&](
bool IsLocalVariable) {
3427 if (!AllowConstexprUnknown || IsLocalVariable) {
3428 if (!Info.checkingPotentialConstantExpression())
3429 Info.FFDiag(E, diag::note_constexpr_use_uninit_reference);
3439 Result = Frame->getTemporary(VD, Version);
3441 return CheckUninitReference(
true);
3450 "missing value for local variable");
3451 if (Info.checkingPotentialConstantExpression())
3455 "A variable in a frame should either be a local or a parameter");
3461 if (Info.EvaluatingDecl ==
Base) {
3462 Result = Info.EvaluatingDeclValue;
3463 return CheckUninitReference(
false);
3471 if (AllowConstexprUnknown) {
3478 if (!Info.checkingPotentialConstantExpression() ||
3479 !Info.CurrentCall->Callee ||
3481 if (Info.getLangOpts().CPlusPlus11) {
3482 Info.FFDiag(E, diag::note_constexpr_function_param_value_unknown)
3503 if (!
Init && !AllowConstexprUnknown) {
3506 if (!Info.checkingPotentialConstantExpression()) {
3507 Info.FFDiag(E, diag::note_constexpr_var_init_unknown, 1)
3518 if (
Init &&
Init->isValueDependent()) {
3525 if (!Info.checkingPotentialConstantExpression()) {
3526 Info.FFDiag(E, Info.getLangOpts().CPlusPlus11
3527 ? diag::note_constexpr_ltor_non_constexpr
3528 : diag::note_constexpr_ltor_non_integral, 1)
3542 Info.FFDiag(E, diag::note_constexpr_var_init_non_constant, 1) << VD;
3558 !AllowConstexprUnknown) ||
3559 ((Info.getLangOpts().CPlusPlus || Info.getLangOpts().OpenCL) &&
3562 Info.CCEDiag(E, diag::note_constexpr_var_init_non_constant, 1) << VD;
3572 Info.FFDiag(E, diag::note_constexpr_var_init_weak) << VD;
3579 if (!
Result && !AllowConstexprUnknown)
3582 return CheckUninitReference(
false);
3605 llvm_unreachable(
"base class missing from derived class's bases list");
3612 "SourceLocExpr should have already been converted to a StringLiteral");
3615 if (
const auto *ObjCEnc = dyn_cast<ObjCEncodeExpr>(Lit)) {
3617 Info.Ctx.getObjCEncodingForType(ObjCEnc->getEncodedType(), Str);
3618 assert(Index <= Str.size() &&
"Index too large");
3619 return APSInt::getUnsigned(Str.c_str()[Index]);
3622 if (
auto PE = dyn_cast<PredefinedExpr>(Lit))
3623 Lit = PE->getFunctionName();
3626 Info.Ctx.getAsConstantArrayType(S->
getType());
3627 assert(CAT &&
"string literal isn't an array");
3629 assert(CharType->
isIntegerType() &&
"unexpected character type");
3632 if (Index < S->getLength())
3645 AllocType.isNull() ? S->
getType() : AllocType);
3646 assert(CAT &&
"string literal isn't an array");
3648 assert(CharType->
isIntegerType() &&
"unexpected character type");
3655 if (
Result.hasArrayFiller())
3657 for (
unsigned I = 0, N =
Result.getArrayInitializedElts(); I != N; ++I) {
3665 unsigned Size =
Array.getArraySize();
3666 assert(Index < Size);
3669 unsigned OldElts =
Array.getArrayInitializedElts();
3670 unsigned NewElts = std::max(Index+1, OldElts * 2);
3671 NewElts = std::min(Size, std::max(NewElts, 8u));
3675 for (
unsigned I = 0; I != OldElts; ++I)
3677 for (
unsigned I = OldElts; I != NewElts; ++I)
3681 Array.swap(NewValue);
3688 Vec =
APValue(Elts.data(), Elts.size());
3698 CXXRecordDecl *RD =
T->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
3709 for (
auto *Field : RD->
fields())
3710 if (!Field->isUnnamedBitField() &&
3714 for (
auto &BaseSpec : RD->
bases())
3725 CXXRecordDecl *RD =
T->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
3732 for (
auto *Field : RD->
fields()) {
3737 if (Field->isMutable() &&
3739 Info.FFDiag(E, diag::note_constexpr_access_mutable, 1) << AK << Field;
3740 Info.Note(Field->getLocation(), diag::note_declared_at);
3748 for (
auto &BaseSpec : RD->
bases())
3758 bool MutableSubobject =
false) {
3763 switch (Info.IsEvaluatingDecl) {
3764 case EvalInfo::EvaluatingDeclKind::None:
3767 case EvalInfo::EvaluatingDeclKind::Ctor:
3769 if (Info.EvaluatingDecl ==
Base)
3774 if (
auto *BaseE =
Base.dyn_cast<
const Expr *>())
3775 if (
auto *BaseMTE = dyn_cast<MaterializeTemporaryExpr>(BaseE))
3776 return Info.EvaluatingDecl == BaseMTE->getExtendingDecl();
3779 case EvalInfo::EvaluatingDeclKind::Dtor:
3784 if (MutableSubobject ||
Base != Info.EvaluatingDecl)
3790 return T.isConstQualified() ||
T->isReferenceType();
3793 llvm_unreachable(
"unknown evaluating decl kind");
3798 return Info.CheckArraySize(
3818 uint64_t IntResult = BoolResult;
3821 : Info.Ctx.getIntTypeForBitwidth(64,
false);
3822 Result =
APValue(Info.Ctx.MakeIntValue(IntResult, IntType));
3827 Info.Ctx.getIntTypeForBitwidth(64,
false),
3830 Result = std::move(Result2);
3838 DestTy,
Result.getFloat());
3844 uint64_t IntResult = BoolResult;
3863 uint64_t IntResult = BoolResult;
3870 DestTy,
Result.getInt());
3874 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
3887 {&
Result, ResultType, 0}};
3890 while (!WorkList.empty() && ElI < Elements.size()) {
3891 auto [Res,
Type, BitWidth] = WorkList.pop_back_val();
3907 APSInt &Int = Res->getInt();
3908 unsigned OldBitWidth = Int.getBitWidth();
3909 unsigned NewBitWidth = BitWidth;
3910 if (NewBitWidth < OldBitWidth)
3911 Int = Int.trunc(NewBitWidth).extend(OldBitWidth);
3920 for (
unsigned I = 0; I < NumEl; ++I) {
3926 *Res =
APValue(Vals.data(), NumEl);
3935 for (int64_t I = Size - 1; I > -1; --I)
3936 WorkList.emplace_back(&Res->getArrayInitializedElt(I), ElTy, 0u);
3942 unsigned NumBases = 0;
3943 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
3944 NumBases = CXXRD->getNumBases();
3951 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
3952 if (CXXRD->getNumBases() > 0) {
3953 assert(CXXRD->getNumBases() == 1);
3955 ReverseList.emplace_back(&Res->getStructBase(0), BS.
getType(), 0u);
3962 if (FD->isUnnamedBitField())
3964 if (FD->isBitField()) {
3965 FDBW = FD->getBitWidthValue();
3968 ReverseList.emplace_back(&Res->getStructField(FD->getFieldIndex()),
3969 FD->getType(), FDBW);
3972 std::reverse(ReverseList.begin(), ReverseList.end());
3973 llvm::append_range(WorkList, ReverseList);
3976 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
3989 assert((Elements.size() == SrcTypes.size()) &&
3990 (Elements.size() == DestTypes.size()));
3992 for (
unsigned I = 0, ESz = Elements.size(); I < ESz; ++I) {
3993 APValue Original = Elements[I];
3997 if (!
handleScalarCast(Info, FPO, E, SourceTy, DestTy, Original, Results[I]))
4008 while (!WorkList.empty()) {
4031 for (uint64_t I = 0; I < ArrSize; ++I) {
4032 WorkList.push_back(ElTy);
4040 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4041 if (CXXRD->getNumBases() > 0) {
4042 assert(CXXRD->getNumBases() == 1);
4044 WorkList.push_back(BS.
getType());
4050 if (FD->isUnnamedBitField())
4052 WorkList.push_back(FD->getType());
4069 "Not a valid HLSLAggregateSplatCast.");
4089 unsigned Populated = 0;
4090 while (!WorkList.empty() && Populated < Size) {
4091 auto [Work,
Type] = WorkList.pop_back_val();
4093 if (Work.isFloat() || Work.isInt()) {
4094 Elements.push_back(Work);
4095 Types.push_back(
Type);
4099 if (Work.isVector()) {
4102 for (
unsigned I = 0; I < Work.getVectorLength() && Populated < Size;
4104 Elements.push_back(Work.getVectorElt(I));
4105 Types.push_back(ElTy);
4110 if (Work.isMatrix()) {
4113 QualType ElTy = MT->getElementType();
4115 for (
unsigned Row = 0; Row < Work.getMatrixNumRows() && Populated < Size;
4117 for (
unsigned Col = 0;
4118 Col < Work.getMatrixNumColumns() && Populated < Size; Col++) {
4119 Elements.push_back(Work.getMatrixElt(Row, Col));
4120 Types.push_back(ElTy);
4126 if (Work.isArray()) {
4130 for (int64_t I = Work.getArraySize() - 1; I > -1; --I) {
4131 WorkList.emplace_back(Work.getArrayInitializedElt(I), ElTy);
4136 if (Work.isStruct()) {
4144 if (FD->isUnnamedBitField())
4146 ReverseList.emplace_back(Work.getStructField(FD->getFieldIndex()),
4150 std::reverse(ReverseList.begin(), ReverseList.end());
4151 llvm::append_range(WorkList, ReverseList);
4154 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4155 if (CXXRD->getNumBases() > 0) {
4156 assert(CXXRD->getNumBases() == 1);
4161 if (!
Base.isStruct())
4169 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
4178struct CompleteObject {
4180 APValue::LValueBase
Base;
4190 bool mayAccessMutableMembers(EvalInfo &Info,
AccessKinds AK)
const {
4201 if (!Info.getLangOpts().CPlusPlus14 &&
4202 AK != AccessKinds::AK_IsWithinLifetime)
4207 explicit operator bool()
const {
return !
Type.isNull(); }
4212 bool IsMutable =
false) {
4226template <
typename Sub
objectHandler>
4227static typename SubobjectHandler::result_type
4229 const SubobjectDesignator &Sub, SubobjectHandler &handler) {
4232 return handler.failed();
4233 if (Sub.isOnePastTheEnd() || Sub.isMostDerivedAnUnsizedArray()) {
4234 if (Info.getLangOpts().CPlusPlus11)
4235 Info.FFDiag(E, Sub.isOnePastTheEnd()
4236 ? diag::note_constexpr_access_past_end
4237 : diag::note_constexpr_access_unsized_array)
4238 << handler.AccessKind;
4241 return handler.failed();
4247 const FieldDecl *VolatileField =
nullptr;
4250 for (
unsigned I = 0, N = Sub.Entries.size(); ; ++I) {
4261 if (!Info.checkingPotentialConstantExpression()) {
4262 Info.FFDiag(E, diag::note_constexpr_access_uninit)
4267 return handler.failed();
4275 Info.isEvaluatingCtorDtor(
4276 Obj.Base,
ArrayRef(Sub.Entries.begin(), Sub.Entries.begin() + I)) !=
4277 ConstructionPhase::None) {
4278 ObjType = Info.Ctx.getCanonicalType(ObjType);
4287 if (Info.getLangOpts().CPlusPlus) {
4291 if (VolatileField) {
4294 Decl = VolatileField;
4297 Loc = VD->getLocation();
4304 Info.FFDiag(E, diag::note_constexpr_access_volatile_obj, 1)
4305 << handler.AccessKind << DiagKind <<
Decl;
4306 Info.Note(Loc, diag::note_constexpr_volatile_here) << DiagKind;
4308 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
4310 return handler.failed();
4318 !Obj.mayAccessMutableMembers(Info, handler.AccessKind) &&
4320 return handler.failed();
4324 if (!handler.found(*O, ObjType, Obj.Base))
4336 LastField =
nullptr;
4341 ObjType = Info.Ctx.getQualifiedType(AT->getValueType(),
4346 const ArrayType *AT = Info.Ctx.getAsArrayType(ObjType);
4348 "vla in literal type?");
4349 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4350 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT);
4351 CAT && CAT->
getSize().ule(Index)) {
4354 if (Info.getLangOpts().CPlusPlus11)
4355 Info.FFDiag(E, diag::note_constexpr_access_past_end)
4356 << handler.AccessKind;
4359 return handler.failed();
4366 else if (!
isRead(handler.AccessKind)) {
4367 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT);
4369 return handler.failed();
4377 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4379 if (Info.getLangOpts().CPlusPlus11)
4380 Info.FFDiag(E, diag::note_constexpr_access_past_end)
4381 << handler.AccessKind;
4384 return handler.failed();
4390 assert(I == N - 1 &&
"extracting subobject of scalar?");
4400 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4401 unsigned NumElements = VT->getNumElements();
4402 if (Index == NumElements) {
4403 if (Info.getLangOpts().CPlusPlus11)
4404 Info.FFDiag(E, diag::note_constexpr_access_past_end)
4405 << handler.AccessKind;
4408 return handler.failed();
4411 if (Index > NumElements) {
4412 Info.CCEDiag(E, diag::note_constexpr_array_index)
4413 << Index << 0 << NumElements;
4414 return handler.failed();
4417 ObjType = VT->getElementType();
4418 assert(I == N - 1 &&
"extracting subobject of scalar?");
4421 if (
isRead(handler.AccessKind)) {
4423 return handler.failed();
4427 assert(O->
isVector() &&
"unexpected object during vector element access");
4428 return handler.found(O->
getVectorElt(Index), ObjType, Obj.Base);
4429 }
else if (
const FieldDecl *Field = getAsField(Sub.Entries[I])) {
4430 if (Field->isMutable() &&
4431 !Obj.mayAccessMutableMembers(Info, handler.AccessKind)) {
4432 Info.FFDiag(E, diag::note_constexpr_access_mutable, 1)
4433 << handler.AccessKind << Field;
4434 Info.Note(Field->getLocation(), diag::note_declared_at);
4435 return handler.failed();
4444 if (I == N - 1 && handler.AccessKind ==
AK_Construct) {
4455 Info.FFDiag(E, diag::note_constexpr_access_inactive_union_member)
4456 << handler.AccessKind << Field << !UnionField << UnionField;
4457 return handler.failed();
4466 if (Field->getType().isVolatileQualified())
4467 VolatileField = Field;
4475 if (BaseIndex >= NumNonVirtualBases) {
4486struct ExtractSubobjectHandler {
4492 typedef bool result_type;
4493 bool failed() {
return false; }
4494 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
4504 bool found(APFloat &
Value, QualType SubobjType) {
4513 const CompleteObject &Obj,
4517 ExtractSubobjectHandler Handler = {Info, E,
Result, AK};
4522struct ModifySubobjectHandler {
4527 typedef bool result_type;
4530 bool checkConst(QualType QT) {
4533 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
4539 bool failed() {
return false; }
4540 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
4541 if (!checkConst(SubobjType))
4544 Subobj.
swap(NewVal);
4548 if (!checkConst(SubobjType))
4550 if (!NewVal.
isInt()) {
4558 bool found(APFloat &
Value, QualType SubobjType) {
4559 if (!checkConst(SubobjType))
4567const AccessKinds ModifySubobjectHandler::AccessKind;
4571 const CompleteObject &Obj,
4572 const SubobjectDesignator &Sub,
4574 ModifySubobjectHandler Handler = { Info, NewVal, E };
4581 const SubobjectDesignator &A,
4582 const SubobjectDesignator &B,
4583 bool &WasArrayIndex) {
4584 unsigned I = 0, N = std::min(A.Entries.size(), B.Entries.size());
4585 for (; I != N; ++I) {
4589 if (A.Entries[I].getAsArrayIndex() != B.Entries[I].getAsArrayIndex()) {
4590 WasArrayIndex =
true;
4598 if (A.Entries[I].getAsBaseOrMember() !=
4599 B.Entries[I].getAsBaseOrMember()) {
4600 WasArrayIndex =
false;
4603 if (
const FieldDecl *FD = getAsField(A.Entries[I]))
4605 ObjType = FD->getType();
4611 WasArrayIndex =
false;
4618 const SubobjectDesignator &A,
4619 const SubobjectDesignator &B) {
4620 if (A.Entries.size() != B.Entries.size())
4623 bool IsArray = A.MostDerivedIsArrayElement;
4624 if (IsArray && A.MostDerivedPathLength != A.Entries.size())
4633 return CommonLength >= A.Entries.size() - IsArray;
4640 if (LVal.InvalidBase) {
4642 return CompleteObject();
4647 Info.FFDiag(E, diag::note_constexpr_dereferencing_null);
4649 Info.FFDiag(E, diag::note_constexpr_access_null) << AK;
4650 return CompleteObject();
4653 CallStackFrame *Frame =
nullptr;
4655 if (LVal.getLValueCallIndex()) {
4656 std::tie(Frame, Depth) =
4657 Info.getCallFrameAndDepth(LVal.getLValueCallIndex());
4659 Info.FFDiag(E, diag::note_constexpr_access_uninit, 1)
4662 return CompleteObject();
4673 if (Info.getLangOpts().CPlusPlus)
4674 Info.FFDiag(E, diag::note_constexpr_access_volatile_type)
4678 return CompleteObject();
4685 if (Info.getLangOpts().CPlusPlus14 && LVal.Base == Info.EvaluatingDecl &&
4689 BaseVal = Info.EvaluatingDeclValue;
4692 if (
auto *GD = dyn_cast<MSGuidDecl>(D)) {
4695 Info.FFDiag(E, diag::note_constexpr_modify_global);
4696 return CompleteObject();
4700 Info.FFDiag(E, diag::note_constexpr_unsupported_layout)
4702 return CompleteObject();
4704 return CompleteObject(LVal.Base, &
V, GD->getType());
4708 if (
auto *GCD = dyn_cast<UnnamedGlobalConstantDecl>(D)) {
4710 Info.FFDiag(E, diag::note_constexpr_modify_global);
4711 return CompleteObject();
4713 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&GCD->getValue()),
4718 if (
auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
4720 Info.FFDiag(E, diag::note_constexpr_modify_global);
4721 return CompleteObject();
4723 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&TPO->getValue()),
4734 const VarDecl *VD = dyn_cast<VarDecl>(D);
4741 return CompleteObject();
4744 bool IsConstant = BaseType.isConstant(Info.Ctx);
4745 bool ConstexprVar =
false;
4746 if (
const auto *VD = dyn_cast_if_present<VarDecl>(
4758 }
else if (Info.getLangOpts().CPlusPlus14 &&
4765 Info.FFDiag(E, diag::note_constexpr_modify_global);
4766 return CompleteObject();
4769 }
else if (Info.getLangOpts().C23 && ConstexprVar) {
4771 return CompleteObject();
4772 }
else if (BaseType->isIntegralOrEnumerationType()) {
4775 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4776 if (Info.getLangOpts().CPlusPlus) {
4777 Info.FFDiag(E, diag::note_constexpr_ltor_non_const_int, 1) << VD;
4778 Info.Note(VD->
getLocation(), diag::note_declared_at);
4782 return CompleteObject();
4784 }
else if (!IsAccess) {
4785 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4786 }
else if ((IsConstant || BaseType->isReferenceType()) &&
4787 Info.checkingPotentialConstantExpression() &&
4788 BaseType->isLiteralType(Info.Ctx) && !VD->
hasDefinition()) {
4790 }
else if (IsConstant) {
4794 if (Info.getLangOpts().CPlusPlus) {
4795 Info.CCEDiag(E, Info.getLangOpts().CPlusPlus11
4796 ? diag::note_constexpr_ltor_non_constexpr
4797 : diag::note_constexpr_ltor_non_integral, 1)
4799 Info.Note(VD->
getLocation(), diag::note_declared_at);
4805 if (Info.getLangOpts().CPlusPlus) {
4806 Info.FFDiag(E, Info.getLangOpts().CPlusPlus11
4807 ? diag::note_constexpr_ltor_non_constexpr
4808 : diag::note_constexpr_ltor_non_integral, 1)
4810 Info.Note(VD->
getLocation(), diag::note_declared_at);
4814 return CompleteObject();
4823 return CompleteObject();
4828 if (!Info.checkingPotentialConstantExpression()) {
4829 Info.FFDiag(E, diag::note_constexpr_access_unknown_variable, 1)
4831 Info.Note(VD->getLocation(), diag::note_declared_at);
4833 return CompleteObject();
4836 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
4838 Info.FFDiag(E, diag::note_constexpr_access_deleted_object) << AK;
4839 return CompleteObject();
4841 return CompleteObject(LVal.Base, &(*Alloc)->Value,
4851 dyn_cast_or_null<MaterializeTemporaryExpr>(
Base)) {
4852 assert(MTE->getStorageDuration() ==
SD_Static &&
4853 "should have a frame for a non-global materialized temporary");
4880 if (!MTE->isUsableInConstantExpressions(Info.Ctx) &&
4883 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4884 Info.FFDiag(E, diag::note_constexpr_access_static_temporary, 1) << AK;
4885 Info.Note(MTE->getExprLoc(), diag::note_constexpr_temporary_here);
4886 return CompleteObject();
4889 BaseVal = MTE->getOrCreateValue(
false);
4890 assert(BaseVal &&
"got reference to unevaluated temporary");
4892 dyn_cast_or_null<CompoundLiteralExpr>(
Base)) {
4908 !CLETy.isConstant(Info.Ctx)) {
4910 Info.Note(CLE->getExprLoc(), diag::note_declared_at);
4911 return CompleteObject();
4914 BaseVal = &CLE->getStaticValue();
4917 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4920 Info.FFDiag(E, diag::note_constexpr_access_unreadable_object)
4923 Info.Ctx.getLValueReferenceType(LValType));
4925 return CompleteObject();
4929 assert(BaseVal &&
"missing value for temporary");
4940 unsigned VisibleDepth = Depth;
4941 if (llvm::isa_and_nonnull<ParmVarDecl>(
4944 if ((Frame && Info.getLangOpts().CPlusPlus14 &&
4945 Info.EvalStatus.HasSideEffects) ||
4946 (
isModification(AK) && VisibleDepth < Info.SpeculativeEvaluationDepth))
4947 return CompleteObject();
4949 return CompleteObject(LVal.getLValueBase(), BaseVal, BaseType);
4968 const LValue &LVal,
APValue &RVal,
4969 bool WantObjectRepresentation =
false) {
4970 if (LVal.Designator.Invalid)
4979 if (
Base && !LVal.getLValueCallIndex() && !
Type.isVolatileQualified()) {
4983 assert(LVal.Designator.Entries.size() <= 1 &&
4984 "Can only read characters from string literals");
4985 if (LVal.Designator.Entries.empty()) {
4992 if (LVal.Designator.isOnePastTheEnd()) {
4993 if (Info.getLangOpts().CPlusPlus11)
4994 Info.FFDiag(Conv, diag::note_constexpr_access_past_end) << AK;
4999 uint64_t CharIndex = LVal.Designator.Entries[0].getAsArrayIndex();
5006 return Obj &&
extractSubobject(Info, Conv, Obj, LVal.Designator, RVal, AK);
5020 LVal.setFrom(Info.Ctx, Val);
5036 if (LVal.Designator.Invalid)
5039 if (!Info.getLangOpts().CPlusPlus14) {
5049struct CompoundAssignSubobjectHandler {
5051 const CompoundAssignOperator *E;
5052 QualType PromotedLHSType;
5058 typedef bool result_type;
5060 bool checkConst(QualType QT) {
5063 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
5069 bool failed() {
return false; }
5070 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
5073 return found(Subobj.
getInt(), SubobjType);
5075 return found(Subobj.
getFloat(), SubobjType);
5082 return foundPointer(Subobj, SubobjType);
5084 return foundVector(Subobj, SubobjType);
5086 Info.FFDiag(E, diag::note_constexpr_access_uninit)
5098 bool foundVector(
APValue &
Value, QualType SubobjType) {
5099 if (!checkConst(SubobjType))
5110 if (!checkConst(SubobjType))
5129 Info.Ctx.getLangOpts());
5132 PromotedLHSType, FValue) &&
5141 bool found(APFloat &
Value, QualType SubobjType) {
5142 return checkConst(SubobjType) &&
5148 bool foundPointer(
APValue &Subobj, QualType SubobjType) {
5149 if (!checkConst(SubobjType))
5152 QualType PointeeType;
5153 if (
const PointerType *PT = SubobjType->
getAs<PointerType>())
5157 (Opcode != BO_Add && Opcode != BO_Sub)) {
5163 if (Opcode == BO_Sub)
5167 LVal.setFrom(Info.Ctx, Subobj);
5170 LVal.moveInto(Subobj);
5176const AccessKinds CompoundAssignSubobjectHandler::AccessKind;
5181 const LValue &LVal,
QualType LValType,
5185 if (LVal.Designator.Invalid)
5188 if (!Info.getLangOpts().CPlusPlus14) {
5194 CompoundAssignSubobjectHandler Handler = { Info, E, PromotedLValType, Opcode,
5196 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
5200struct IncDecSubobjectHandler {
5202 const UnaryOperator *E;
5206 typedef bool result_type;
5208 bool checkConst(QualType QT) {
5211 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
5217 bool failed() {
return false; }
5218 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
5228 return found(Subobj.
getInt(), SubobjType);
5230 return found(Subobj.
getFloat(), SubobjType);
5233 SubobjType->
castAs<ComplexType>()->getElementType()
5237 SubobjType->
castAs<ComplexType>()->getElementType()
5240 return foundPointer(Subobj, SubobjType);
5248 if (!checkConst(SubobjType))
5270 bool WasNegative =
Value.isNegative();
5284 unsigned BitWidth =
Value.getBitWidth();
5285 APSInt ActualValue(
Value.sext(BitWidth + 1),
false);
5286 ActualValue.setBit(BitWidth);
5292 bool found(APFloat &
Value, QualType SubobjType) {
5293 if (!checkConst(SubobjType))
5300 APFloat::opStatus St;
5302 St =
Value.add(One, RM);
5304 St =
Value.subtract(One, RM);
5307 bool foundPointer(
APValue &Subobj, QualType SubobjType) {
5308 if (!checkConst(SubobjType))
5311 QualType PointeeType;
5312 if (
const PointerType *PT = SubobjType->
getAs<PointerType>())
5320 LVal.setFrom(Info.Ctx, Subobj);
5324 LVal.moveInto(Subobj);
5333 if (LVal.Designator.Invalid)
5336 if (!Info.getLangOpts().CPlusPlus14) {
5344 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
5350 if (
Object->getType()->isPointerType() &&
Object->isPRValue())
5356 if (
Object->getType()->isLiteralType(Info.Ctx))
5359 if (
Object->getType()->isRecordType() &&
Object->isPRValue())
5362 Info.FFDiag(
Object, diag::note_constexpr_nonliteral) <<
Object->getType();
5381 bool IncludeMember =
true) {
5388 if (!MemPtr.getDecl()) {
5394 if (MemPtr.isDerivedMember()) {
5401 if (LV.Designator.MostDerivedPathLength + MemPtr.Path.size() >
5402 LV.Designator.Entries.size()) {
5406 unsigned PathLengthToMember =
5407 LV.Designator.Entries.size() - MemPtr.Path.size();
5408 for (
unsigned I = 0, N = MemPtr.Path.size(); I != N; ++I) {
5410 LV.Designator.Entries[PathLengthToMember + I]);
5427 (PathLengthToMember > LV.Designator.MostDerivedPathLength)
5428 ? getAsBaseClass(LV.Designator.Entries[PathLengthToMember - 1])
5430 const CXXRecordDecl *LastMPDecl = MemPtr.getContainingRecord();
5438 PathLengthToMember))
5440 }
else if (!MemPtr.Path.empty()) {
5442 LV.Designator.Entries.reserve(LV.Designator.Entries.size() +
5443 MemPtr.Path.size() + IncludeMember);
5449 assert(RD &&
"member pointer access on non-class-type expression");
5451 for (
unsigned I = 1, N = MemPtr.Path.size(); I != N; ++I) {
5459 MemPtr.getContainingRecord()))
5464 if (IncludeMember) {
5465 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(MemPtr.getDecl())) {
5469 dyn_cast<IndirectFieldDecl>(MemPtr.getDecl())) {
5473 llvm_unreachable(
"can't construct reference to bound member function");
5477 return MemPtr.getDecl();
5483 bool IncludeMember =
true) {
5487 if (Info.noteFailure()) {
5495 BO->
getRHS(), IncludeMember);
5502 SubobjectDesignator &D =
Result.Designator;
5510 auto InvalidCast = [&]() {
5511 if (!Info.checkingPotentialConstantExpression() ||
5512 !
Result.AllowConstexprUnknown) {
5513 Info.CCEDiag(E, diag::note_constexpr_invalid_downcast)
5514 << D.MostDerivedType << TargetQT;
5520 if (D.MostDerivedPathLength + E->
path_size() > D.Entries.size())
5521 return InvalidCast();
5525 unsigned NewEntriesSize = D.Entries.size() - E->
path_size();
5528 if (NewEntriesSize == D.MostDerivedPathLength)
5531 FinalType = getAsBaseClass(D.Entries[NewEntriesSize - 1]);
5533 return InvalidCast();
5542 bool IsCompleteClass =
true) {
5549 if (
auto *RD =
T->getAsCXXRecordDecl()) {
5550 if (RD->isInvalidDecl()) {
5554 if (RD->isUnion()) {
5560 unsigned NonVirtualBases = countNonVirtualBases(RD);
5563 IsCompleteClass ? RD->getNumVBases() : 0);
5574 for (
const auto *I : RD->fields()) {
5575 if (I->isUnnamedBitField())
5578 I->getType(),
Result.getStructField(I->getFieldIndex()));
5581 if (IsCompleteClass) {
5584 for (
const auto &B : RD->vbases()) {
5586 Result.getStructVirtualBase(Index),
5592 assert(
Result.getStructNumVirtualBases() == 0);
5599 dyn_cast_or_null<ConstantArrayType>(
T->getAsArrayTypeUnsafe())) {
5601 if (
Result.hasArrayFiller())
5612enum EvalStmtResult {
5641 if (!
Result.Designator.Invalid &&
Result.Designator.isOnePastTheEnd()) {
5659 APValue &Val = Info.CurrentCall->createTemporary(VD, VD->
getType(),
5660 ScopeKind::Block,
Result);
5665 return Info.noteSideEffect();
5686 const DecompositionDecl *DD);
5689 bool EvaluateConditionDecl =
false) {
5691 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
5695 EvaluateConditionDecl && DD)
5705 if (
auto *VD = BD->getHoldingVar())
5713 if (
auto *DD = dyn_cast_if_present<DecompositionDecl>(VD)) {
5722 if (Info.noteSideEffect())
5724 assert(E->
containsErrors() &&
"valid value-dependent expression should never "
5725 "reach invalid code path.");
5732 if (
Cond->isValueDependent())
5734 FullExpressionRAII
Scope(Info);
5741 return Scope.destroy();
5754struct TempVersionRAII {
5755 CallStackFrame &Frame;
5757 TempVersionRAII(CallStackFrame &Frame) : Frame(Frame) {
5758 Frame.pushTempVersion();
5761 ~TempVersionRAII() {
5762 Frame.popTempVersion();
5770 const SwitchCase *SC =
nullptr);
5776 const Stmt *LoopOrSwitch,
5778 EvalStmtResult &ESR) {
5782 if (!IsSwitch && ESR == ESR_Succeeded) {
5787 if (ESR != ESR_Break && ESR != ESR_Continue)
5791 bool CanBreakOrContinue = !IsSwitch || ESR == ESR_Break;
5792 const Stmt *StackTop = Info.BreakContinueStack.back();
5793 if (CanBreakOrContinue && (StackTop ==
nullptr || StackTop == LoopOrSwitch)) {
5794 Info.BreakContinueStack.pop_back();
5795 if (ESR == ESR_Break)
5796 ESR = ESR_Succeeded;
5801 for (BlockScopeRAII *S : Scopes) {
5802 if (!S->destroy()) {
5814 BlockScopeRAII
Scope(Info);
5817 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5826 BlockScopeRAII
Scope(Info);
5833 if (ESR != ESR_Succeeded) {
5834 if (ESR != ESR_Failed && !
Scope.destroy())
5840 FullExpressionRAII CondScope(Info);
5855 if (!CondScope.destroy())
5876 if (LHSValue <=
Value &&
Value <= RHSValue) {
5883 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5887 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5894 llvm_unreachable(
"Should have been converted to Succeeded");
5900 case ESR_CaseNotFound:
5903 Info.FFDiag(
Found->getBeginLoc(),
5904 diag::note_constexpr_stmt_expr_unsupported);
5907 llvm_unreachable(
"Invalid EvalStmtResult!");
5917 Info.CCEDiag(VD->
getLocation(), diag::note_constexpr_static_local)
5927 if (!Info.nextStep(S))
5934 case Stmt::CompoundStmtClass:
5938 case Stmt::LabelStmtClass:
5939 case Stmt::AttributedStmtClass:
5940 case Stmt::DoStmtClass:
5943 case Stmt::CaseStmtClass:
5944 case Stmt::DefaultStmtClass:
5949 case Stmt::IfStmtClass: {
5956 BlockScopeRAII
Scope(Info);
5962 if (ESR != ESR_CaseNotFound) {
5963 assert(ESR != ESR_Succeeded);
5974 if (ESR == ESR_Failed)
5976 if (ESR != ESR_CaseNotFound)
5977 return Scope.destroy() ? ESR : ESR_Failed;
5979 return ESR_CaseNotFound;
5982 if (ESR == ESR_Failed)
5984 if (ESR != ESR_CaseNotFound)
5985 return Scope.destroy() ? ESR : ESR_Failed;
5986 return ESR_CaseNotFound;
5989 case Stmt::WhileStmtClass: {
5990 EvalStmtResult ESR =
5994 if (ESR != ESR_Continue)
5999 case Stmt::ForStmtClass: {
6001 BlockScopeRAII
Scope(Info);
6007 if (ESR != ESR_CaseNotFound) {
6008 assert(ESR != ESR_Succeeded);
6013 EvalStmtResult ESR =
6017 if (ESR != ESR_Continue)
6019 if (
const auto *Inc = FS->
getInc()) {
6020 if (Inc->isValueDependent()) {
6024 FullExpressionRAII IncScope(Info);
6032 case Stmt::DeclStmtClass: {
6036 for (
const auto *D : DS->
decls()) {
6037 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
6040 if (VD->hasLocalStorage() && !VD->getInit())
6048 return ESR_CaseNotFound;
6052 return ESR_CaseNotFound;
6058 if (
const Expr *E = dyn_cast<Expr>(S)) {
6067 FullExpressionRAII
Scope(Info);
6071 return ESR_Succeeded;
6077 case Stmt::NullStmtClass:
6078 return ESR_Succeeded;
6080 case Stmt::DeclStmtClass: {
6082 for (
const auto *D : DS->
decls()) {
6083 const VarDecl *VD = dyn_cast_or_null<VarDecl>(D);
6087 if (
const auto *ESD = dyn_cast<CXXExpansionStmtDecl>(D)) {
6088 assert(ESD->getInstantiations() &&
"not expanded?");
6093 FullExpressionRAII
Scope(Info);
6095 !Info.noteFailure())
6097 if (!
Scope.destroy())
6100 return ESR_Succeeded;
6103 case Stmt::ReturnStmtClass: {
6105 FullExpressionRAII
Scope(Info);
6116 return Scope.destroy() ? ESR_Returned : ESR_Failed;
6119 case Stmt::CompoundStmtClass: {
6120 BlockScopeRAII
Scope(Info);
6123 for (
const auto *BI : CS->
body()) {
6125 if (ESR == ESR_Succeeded)
6127 else if (ESR != ESR_CaseNotFound) {
6128 if (ESR != ESR_Failed && !
Scope.destroy())
6134 return ESR_CaseNotFound;
6135 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
6138 case Stmt::IfStmtClass: {
6142 BlockScopeRAII
Scope(Info);
6145 if (ESR != ESR_Succeeded) {
6146 if (ESR != ESR_Failed && !
Scope.destroy())
6156 if (!Info.InConstantContext)
6164 if (ESR != ESR_Succeeded) {
6165 if (ESR != ESR_Failed && !
Scope.destroy())
6170 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
6173 case Stmt::WhileStmtClass: {
6176 BlockScopeRAII
Scope(Info);
6188 if (ESR != ESR_Continue) {
6189 if (ESR != ESR_Failed && !
Scope.destroy())
6193 if (!
Scope.destroy())
6196 return ESR_Succeeded;
6199 case Stmt::DoStmtClass: {
6206 if (ESR != ESR_Continue)
6215 FullExpressionRAII CondScope(Info);
6217 !CondScope.destroy())
6220 return ESR_Succeeded;
6223 case Stmt::ForStmtClass: {
6225 BlockScopeRAII ForScope(Info);
6228 if (ESR != ESR_Succeeded) {
6229 if (ESR != ESR_Failed && !ForScope.destroy())
6235 BlockScopeRAII IterScope(Info);
6236 bool Continue =
true;
6242 if (!IterScope.destroy())
6250 if (ESR != ESR_Continue) {
6251 if (ESR != ESR_Failed && (!IterScope.destroy() || !ForScope.destroy()))
6256 if (
const auto *Inc = FS->
getInc()) {
6257 if (Inc->isValueDependent()) {
6261 FullExpressionRAII IncScope(Info);
6267 if (!IterScope.destroy())
6270 return ForScope.destroy() ? ESR_Succeeded : ESR_Failed;
6273 case Stmt::CXXForRangeStmtClass: {
6275 BlockScopeRAII
Scope(Info);
6280 if (ESR != ESR_Succeeded) {
6281 if (ESR != ESR_Failed && !
Scope.destroy())
6289 if (ESR != ESR_Succeeded) {
6290 if (ESR != ESR_Failed && !
Scope.destroy())
6302 if (ESR != ESR_Succeeded) {
6303 if (ESR != ESR_Failed && !
Scope.destroy())
6308 if (ESR != ESR_Succeeded) {
6309 if (ESR != ESR_Failed && !
Scope.destroy())
6322 bool Continue =
true;
6323 FullExpressionRAII CondExpr(Info);
6331 BlockScopeRAII InnerScope(Info);
6333 if (ESR != ESR_Succeeded) {
6334 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
6343 if (ESR != ESR_Continue) {
6344 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
6357 if (!InnerScope.destroy())
6361 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
6364 case Stmt::CXXExpansionStmtInstantiationClass: {
6365 BlockScopeRAII
Scope(Info);
6367 for (
const Stmt *PreambleStmt : Expansion->getPreambleStmts()) {
6369 if (ESR != ESR_Succeeded) {
6370 if (ESR != ESR_Failed && !
Scope.destroy())
6378 EvalStmtResult ESR = ESR_Succeeded;
6379 for (
const Stmt *Instantiation : Expansion->getInstantiations()) {
6381 if (ESR == ESR_Failed ||
6384 if (ESR != ESR_Continue) {
6386 assert(ESR == ESR_Succeeded || ESR == ESR_Returned);
6392 if (ESR == ESR_Continue)
6393 ESR = ESR_Succeeded;
6395 return Scope.destroy() ? ESR : ESR_Failed;
6398 case Stmt::SwitchStmtClass:
6401 case Stmt::ContinueStmtClass:
6402 case Stmt::BreakStmtClass: {
6404 Info.BreakContinueStack.push_back(B->getNamedLoopOrSwitch());
6408 case Stmt::LabelStmtClass:
6411 case Stmt::AttributedStmtClass: {
6413 const auto *SS = AS->getSubStmt();
6414 MSConstexprContextRAII ConstexprContext(
6418 auto LO = Info.Ctx.getLangOpts();
6419 if (LO.CXXAssumptions && !LO.MSVCCompat) {
6420 for (
auto *
Attr : AS->getAttrs()) {
6421 auto *AA = dyn_cast<CXXAssumeAttr>(
Attr);
6425 auto *Assumption = AA->getAssumption();
6426 if (Assumption->isValueDependent())
6429 if (Assumption->HasSideEffects(Info.Ctx))
6436 Info.CCEDiag(Assumption->getExprLoc(),
6437 diag::note_constexpr_assumption_failed);
6446 case Stmt::CaseStmtClass:
6447 case Stmt::DefaultStmtClass:
6449 case Stmt::CXXTryStmtClass:
6461 bool IsValueInitialization) {
6468 if (!CD->
isConstexpr() && !IsValueInitialization) {
6469 if (Info.getLangOpts().CPlusPlus11) {
6472 Info.CCEDiag(Loc, diag::note_constexpr_invalid_function, 1)
6474 Info.Note(CD->
getLocation(), diag::note_declared_at);
6476 Info.CCEDiag(Loc, diag::note_invalid_subexpr_in_const_expr);
6490 if (Info.checkingPotentialConstantExpression() && !
Definition &&
6498 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6507 Info.CCEDiag(CallLoc, diag::note_constexpr_virtual_call);
6510 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6516 (
Definition->isConstexpr() || (Info.CurrentCall->CanEvalMSConstexpr &&
6526 StringRef Name = DiagDecl->
getName();
6528 Name ==
"__assert_rtn" || Name ==
"__assert_fail" || Name ==
"_wassert";
6530 Info.FFDiag(CallLoc, diag::note_constexpr_assert_failed);
6535 if (Info.getLangOpts().CPlusPlus11) {
6538 auto *CD = dyn_cast<CXXConstructorDecl>(DiagDecl);
6539 if (CD && CD->isInheritingConstructor()) {
6540 auto *Inherited = CD->getInheritedConstructor().getConstructor();
6541 if (!Inherited->isConstexpr())
6542 DiagDecl = CD = Inherited;
6548 if (CD && CD->isInheritingConstructor())
6549 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_inhctor, 1)
6550 << CD->getInheritedConstructor().getConstructor()->getParent();
6552 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_function, 1)
6554 Info.Note(DiagDecl->
getLocation(), diag::note_declared_at);
6556 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6562struct CheckDynamicTypeHandler {
6564 typedef bool result_type;
6565 bool failed() {
return false; }
6566 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
6569 bool found(
APSInt &
Value, QualType SubobjType) {
return true; }
6570 bool found(APFloat &
Value, QualType SubobjType) {
return true; }
6578 if (
This.Designator.Invalid)
6590 if (
This.Designator.isOnePastTheEnd() ||
6591 This.Designator.isMostDerivedAnUnsizedArray()) {
6592 Info.FFDiag(E,
This.Designator.isOnePastTheEnd()
6593 ? diag::note_constexpr_access_past_end
6594 : diag::note_constexpr_access_unsized_array)
6597 }
else if (Polymorphic) {
6600 if (!Info.checkingPotentialConstantExpression() ||
6601 !
This.AllowConstexprUnknown) {
6605 Info.Ctx.getLValueReferenceType(
This.Designator.getType(Info.Ctx));
6606 Info.FFDiag(E, diag::note_constexpr_polymorphic_unknown_dynamic_type)
6614 CheckDynamicTypeHandler Handler{AK};
6637 unsigned PathLength) {
6638 assert(PathLength >=
Designator.MostDerivedPathLength && PathLength <=
6639 Designator.Entries.size() &&
"invalid path length");
6640 return (PathLength ==
Designator.MostDerivedPathLength)
6641 ?
Designator.MostDerivedType->getAsCXXRecordDecl()
6642 : getAsBaseClass(
Designator.Entries[PathLength - 1]);
6655 return std::nullopt;
6657 if (
This.Designator.Invalid)
6658 return std::nullopt;
6664 This.Designator.MostDerivedType->getAsCXXRecordDecl();
6665 if (!Class || (!Info.getLangOpts().CPlusPlus26 && Class->getNumVBases())) {
6667 return std::nullopt;
6675 for (
unsigned PathLength =
This.Designator.MostDerivedPathLength;
6676 PathLength <= Path.size(); ++PathLength) {
6677 switch (Info.isEvaluatingCtorDtor(
This.getLValueBase(),
6678 Path.slice(0, PathLength))) {
6679 case ConstructionPhase::Bases:
6680 case ConstructionPhase::DestroyingBases:
6685 case ConstructionPhase::None:
6686 case ConstructionPhase::AfterBases:
6687 case ConstructionPhase::AfterFields:
6688 case ConstructionPhase::Destroying:
6700 return std::nullopt;
6718 unsigned PathLength = DynType->PathLength;
6719 for (; PathLength <=
This.Designator.Entries.size(); ++PathLength) {
6722 Found->getCorrespondingMethodDeclaredInClass(Class,
false);
6732 if (Callee->isPureVirtual()) {
6733 Info.FFDiag(E, diag::note_constexpr_pure_virtual_call, 1) << Callee;
6734 Info.Note(Callee->getLocation(), diag::note_declared_at);
6740 if (!Info.Ctx.hasSameUnqualifiedType(Callee->getReturnType(),
6741 Found->getReturnType())) {
6742 CovariantAdjustmentPath.push_back(Callee->getReturnType());
6743 for (
unsigned CovariantPathLength = PathLength + 1;
6744 CovariantPathLength !=
This.Designator.Entries.size();
6745 ++CovariantPathLength) {
6749 Found->getCorrespondingMethodDeclaredInClass(NextClass,
false);
6750 if (
Next && !Info.Ctx.hasSameUnqualifiedType(
6751 Next->getReturnType(), CovariantAdjustmentPath.back()))
6752 CovariantAdjustmentPath.push_back(
Next->getReturnType());
6754 if (!Info.Ctx.hasSameUnqualifiedType(
Found->getReturnType(),
6755 CovariantAdjustmentPath.back()))
6756 CovariantAdjustmentPath.push_back(
Found->getReturnType());
6772 assert(
Result.isLValue() &&
6773 "unexpected kind of APValue for covariant return");
6774 if (
Result.isNullPointer())
6778 LVal.setFrom(Info.Ctx,
Result);
6780 const CXXRecordDecl *OldClass = Path[0]->getPointeeCXXRecordDecl();
6781 for (
unsigned I = 1; I != Path.size(); ++I) {
6782 const CXXRecordDecl *NewClass = Path[I]->getPointeeCXXRecordDecl();
6783 assert(OldClass && NewClass &&
"unexpected kind of covariant return");
6784 if (OldClass != NewClass &&
6787 OldClass = NewClass;
6799 if (BaseSpec.isVirtual())
6801 auto *BaseClass = BaseSpec.getType()->getAsCXXRecordDecl();
6803 return BaseSpec.getAccessSpecifier() ==
AS_public;
6806 auto *BaseClass = BaseSpec.getType()->getAsCXXRecordDecl();
6808 return BaseSpec.getAccessSpecifier() ==
AS_public;
6811 llvm_unreachable(
"Base is not a direct base of Derived");
6821 SubobjectDesignator &D = Ptr.Designator;
6827 if (Ptr.isNullPointer() && !E->
isGLValue())
6833 std::optional<DynamicType> DynType =
6845 assert(
C &&
"dynamic_cast target is not void pointer nor class");
6853 Ptr.setNull(Info.Ctx, E->
getType());
6860 DynType->Type->isDerivedFrom(
C)))
6862 else if (!Paths || Paths->begin() == Paths->end())
6864 else if (Paths->isAmbiguous(CQT))
6867 assert(Paths->front().Access !=
AS_public &&
"why did the cast fail?");
6870 Info.FFDiag(E, diag::note_constexpr_dynamic_cast_to_reference_failed)
6871 << DiagKind << Ptr.Designator.getType(Info.Ctx)
6872 << Info.Ctx.getCanonicalTagType(DynType->Type)
6880 for (
int PathLength = Ptr.Designator.Entries.size();
6881 PathLength >= (
int)DynType->PathLength; --PathLength) {
6886 if (PathLength > (
int)DynType->PathLength &&
6889 return RuntimeCheckFailed(
nullptr);
6896 if (DynType->Type->isDerivedFrom(
C, Paths) && !Paths.
isAmbiguous(CQT) &&
6909 return RuntimeCheckFailed(&Paths);
6913struct StartLifetimeOfUnionMemberHandler {
6915 const Expr *LHSExpr;
6916 const FieldDecl *
Field;
6918 bool Failed =
false;
6921 typedef bool result_type;
6922 bool failed() {
return Failed; }
6923 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
6938 }
else if (DuringInit) {
6942 Info.FFDiag(LHSExpr,
6943 diag::note_constexpr_union_member_change_during_init);
6952 llvm_unreachable(
"wrong value kind for union object");
6954 bool found(APFloat &
Value, QualType SubobjType) {
6955 llvm_unreachable(
"wrong value kind for union object");
6960const AccessKinds StartLifetimeOfUnionMemberHandler::AccessKind;
6967 const Expr *LHSExpr,
6968 const LValue &LHS) {
6969 if (LHS.InvalidBase || LHS.Designator.Invalid)
6975 unsigned PathLength = LHS.Designator.Entries.size();
6976 for (
const Expr *E = LHSExpr; E !=
nullptr;) {
6978 if (
auto *ME = dyn_cast<MemberExpr>(E)) {
6979 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
6982 if (!FD || FD->getType()->isReferenceType())
6986 if (FD->getParent()->isUnion()) {
6991 FD->getType()->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
6992 if (!RD || RD->hasTrivialDefaultConstructor())
6993 UnionPathLengths.push_back({PathLength - 1, FD});
6999 LHS.Designator.Entries[PathLength]
7000 .getAsBaseOrMember().getPointer()));
7004 }
else if (
auto *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
7006 auto *
Base = ASE->getBase()->IgnoreImplicit();
7007 if (!
Base->getType()->isArrayType())
7013 }
else if (
auto *ICE = dyn_cast<ImplicitCastExpr>(E)) {
7016 if (ICE->getCastKind() == CK_NoOp)
7018 if (ICE->getCastKind() != CK_DerivedToBase &&
7019 ICE->getCastKind() != CK_UncheckedDerivedToBase)
7023 if (Elt->isVirtual()) {
7032 LHS.Designator.Entries[PathLength]
7033 .getAsBaseOrMember().getPointer()));
7043 if (UnionPathLengths.empty())
7048 CompleteObject Obj =
7052 for (std::pair<unsigned, const FieldDecl *> LengthAndField :
7053 llvm::reverse(UnionPathLengths)) {
7055 SubobjectDesignator D = LHS.Designator;
7056 D.truncate(Info.Ctx, LHS.Base, LengthAndField.first);
7058 bool DuringInit = Info.isEvaluatingCtorDtor(LHS.Base, D.Entries) ==
7059 ConstructionPhase::AfterBases;
7060 StartLifetimeOfUnionMemberHandler StartLifetime{
7061 Info, LHSExpr, LengthAndField.second, DuringInit};
7070 CallRef
Call, EvalInfo &Info,
bool NonNull =
false,
7071 APValue **EvaluatedArg =
nullptr) {
7078 APValue &
V = PVD ? Info.CurrentCall->createParam(
Call, PVD, LV)
7079 : Info.CurrentCall->createTemporary(Arg, Arg->
getType(),
7080 ScopeKind::Call, LV);
7086 if (
NonNull &&
V.isLValue() &&
V.isNullPointer()) {
7087 Info.CCEDiag(Arg, diag::note_non_null_attribute_failed);
7100 bool RightToLeft =
false,
7101 LValue *ObjectArg =
nullptr) {
7103 llvm::SmallBitVector ForbiddenNullArgs;
7104 if (Callee->hasAttr<NonNullAttr>()) {
7105 ForbiddenNullArgs.resize(Args.size());
7106 for (
const auto *
Attr : Callee->specific_attrs<NonNullAttr>()) {
7107 if (!
Attr->args_size()) {
7108 ForbiddenNullArgs.set();
7111 for (
auto Idx :
Attr->args()) {
7112 unsigned ASTIdx = Idx.getASTIndex();
7113 if (ASTIdx >= Args.size())
7115 ForbiddenNullArgs[ASTIdx] =
true;
7119 for (
unsigned I = 0; I < Args.size(); I++) {
7120 unsigned Idx = RightToLeft ? Args.size() - I - 1 : I;
7122 Idx < Callee->getNumParams() ? Callee->getParamDecl(Idx) :
nullptr;
7123 bool NonNull = !ForbiddenNullArgs.empty() && ForbiddenNullArgs[Idx];
7128 if (!Info.noteFailure())
7133 ObjectArg->setFrom(Info.Ctx, *That);
7142 bool CopyObjectRepresentation) {
7144 CallStackFrame *Frame = Info.CurrentCall;
7145 APValue *RefValue = Info.getParamSlot(Frame->Arguments, Param);
7153 RefLValue.setFrom(Info.Ctx, *RefValue);
7156 CopyObjectRepresentation);
7162 const LValue *ObjectArg,
const Expr *E,
7164 const Stmt *Body, EvalInfo &Info,
7166 if (!Info.CheckCallLimit(CallLoc))
7179 auto IsTrivialMemoryOperation = [&](
const CXXMethodDecl *MD) {
7189 if (IsTrivialMemoryOperation(MD)) {
7202 ObjectArg->moveInto(
Result);
7211 if (!Info.checkingPotentialConstantExpression())
7213 Frame.LambdaThisCaptureField);
7216 StmtResult Ret = {
Result, ResultSlot};
7218 if (ESR == ESR_Succeeded) {
7219 if (Callee->getReturnType()->isVoidType())
7221 Info.FFDiag(Callee->getEndLoc(), diag::note_constexpr_no_return);
7223 return ESR == ESR_Returned;
7230 bool IsCompleteClass =
true);
7236 bool IsCompleteClass =
true) {
7237 CallScopeRAII CallScope(Info);
7244 CallScope.destroy();
7252 bool IsCompleteClass) {
7255 if (!Info.CheckCallLimit(CallLoc))
7259 if (!Info.getLangOpts().CPlusPlus26 && RD->
getNumVBases()) {
7260 Info.FFDiag(CallLoc, diag::note_constexpr_virtual_base) << RD;
7264 EvalInfo::EvaluatingConstructorRAII EvalObj(
7266 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries},
7273 StmtResult Ret = {RetVal,
nullptr};
7278 if ((*I)->getInit()->isValueDependent()) {
7282 FullExpressionRAII InitScope(Info);
7284 !InitScope.destroy())
7307 if (!
Result.hasValue()) {
7309 unsigned NonVirtualBases = countNonVirtualBases(RD);
7321 BlockScopeRAII LifetimeExtendedScope(Info);
7324 unsigned BasesSeen = 0;
7325 unsigned VirtualBasesSeen = 0;
7326 unsigned NonVirtualBases = countNonVirtualBases(RD);
7329 auto SkipToField = [&](
FieldDecl *FD,
bool Indirect) {
7334 assert(Indirect &&
"fields out of order?");
7340 assert(FieldIt != RD->
field_end() &&
"missing field?");
7341 if (!FieldIt->isUnnamedBitField())
7344 Result.getStructField(FieldIt->getFieldIndex()));
7349 LValue Subobject =
This;
7350 LValue SubobjectParent =
This;
7355 if (I->isBaseInitializer()) {
7356 QualType BaseType(I->getBaseClass(), 0);
7357 if (I->isBaseVirtual()) {
7358 if (
This.pointsToCompleteClass(RD)) {
7360 BaseType->getAsCXXRecordDecl(),
7363 Value = &
Result.getStructVirtualBase(VirtualBasesSeen++);
7370 BaseType->getAsCXXRecordDecl(), &Layout))
7374 }
else if ((FD = I->getMember())) {
7381 SkipToField(FD,
false);
7387 auto IndirectFieldChain = IFD->chain();
7388 for (
auto *
C : IndirectFieldChain) {
7397 (
Value->isUnion() &&
7410 if (
C == IndirectFieldChain.back())
7411 SubobjectParent = Subobject;
7417 if (
C == IndirectFieldChain.front() && !RD->
isUnion())
7418 SkipToField(FD,
true);
7423 llvm_unreachable(
"unknown base initializer kind");
7430 if (
Init->isValueDependent()) {
7434 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &SubobjectParent,
7436 FullExpressionRAII InitScope(Info);
7442 if (!Info.noteFailure())
7451 if (!Info.noteFailure())
7459 if (I->isBaseInitializer() && BasesSeen == NonVirtualBases)
7460 EvalObj.finishedConstructingBases();
7465 for (; FieldIt != RD->
field_end(); ++FieldIt) {
7466 if (!FieldIt->isUnnamedBitField())
7469 Result.getStructField(FieldIt->getFieldIndex()));
7473 EvalObj.finishedConstructingFields();
7477 LifetimeExtendedScope.destroy();
7482 QualType T,
bool IsCompleteClass =
true) {
7487 if (
Value.isAbsent() && !
T->isNullPtrType()) {
7489 This.moveInto(Printable);
7491 diag::note_constexpr_destroy_out_of_lifetime)
7492 << Printable.
getAsString(Info.Ctx, Info.Ctx.getLValueReferenceType(
T));
7508 LValue ElemLV =
This;
7509 ElemLV.addArray(Info, &LocE, CAT);
7516 if (Size && Size >
Value.getArrayInitializedElts())
7521 for (Size =
Value.getArraySize(); Size != 0; --Size) {
7522 APValue &Elem =
Value.getArrayInitializedElt(Size - 1);
7535 if (
T.isDestructedType()) {
7537 diag::note_constexpr_unsupported_destruction)
7546 if (!Info.getLangOpts().CPlusPlus26 && RD->
getNumVBases()) {
7547 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_virtual_base) << RD;
7575 if (!Info.CheckCallLimit(CallRange.
getBegin()))
7584 CallStackFrame Frame(Info, CallRange,
Definition, &
This,
nullptr,
7588 EvalInfo::EvaluatingDestructorRAII EvalObj(
7590 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries});
7591 unsigned NonVirtualBases = countNonVirtualBases(RD);
7593 unsigned BasesLeft = NonVirtualBases;
7594 if (!EvalObj.DidInsert) {
7601 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_double_destroy);
7608 StmtResult Ret = {RetVal,
nullptr};
7621 for (
const FieldDecl *FD : llvm::reverse(Fields)) {
7622 if (FD->isUnnamedBitField())
7625 LValue Subobject =
This;
7629 APValue *SubobjectValue = &
Value.getStructField(FD->getFieldIndex());
7635 if (BasesLeft != 0 || NumVirtualBases != 0)
7636 EvalObj.startedDestroyingBases();
7640 if (
Base.isVirtual())
7645 LValue Subobject =
This;
7647 BaseType->getAsCXXRecordDecl(), &Layout))
7650 APValue *SubobjectValue = &
Value.getStructBase(BasesLeft);
7655 assert(BasesLeft == 0 &&
"NumBases was wrong?");
7658 if (IsCompleteClass) {
7659 unsigned VirtualBasesLeft = NumVirtualBases;
7664 LValue Subobject =
This;
7666 BaseType->getAsCXXRecordDecl(),
7670 APValue *SubobjectValue = &
Value.getStructVirtualBase(VirtualBasesLeft);
7675 assert(VirtualBasesLeft == 0 &&
"NumVirtualBases was wrong?");
7684struct DestroyObjectHandler {
7690 typedef bool result_type;
7691 bool failed() {
return false; }
7692 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
7697 Info.FFDiag(E, diag::note_constexpr_destroy_complex_elem);
7700 bool found(APFloat &
Value, QualType SubobjType) {
7701 Info.FFDiag(E, diag::note_constexpr_destroy_complex_elem);
7722 if (Info.EvalStatus.HasSideEffects)
7733 if (Info.checkingPotentialConstantExpression() ||
7734 Info.SpeculativeEvaluationDepth)
7738 auto Caller = Info.getStdAllocatorCaller(
"allocate");
7740 Info.FFDiag(E->
getExprLoc(), Info.getLangOpts().CPlusPlus20
7741 ? diag::note_constexpr_new_untyped
7742 : diag::note_constexpr_new);
7746 QualType ElemType = Caller.ElemType;
7749 diag::note_constexpr_new_not_complete_object_type)
7757 bool IsNothrow =
false;
7758 for (
unsigned I = 1, N = E->
getNumArgs(); I != N; ++I) {
7766 APInt Size, Remainder;
7767 APInt ElemSizeAP(ByteSize.getBitWidth(), ElemSize.
getQuantity());
7768 APInt::udivrem(ByteSize, ElemSizeAP, Size, Remainder);
7769 if (Remainder != 0) {
7771 Info.FFDiag(E->
getExprLoc(), diag::note_constexpr_operator_new_bad_size)
7772 << ByteSize <<
APSInt(ElemSizeAP,
true) << ElemType;
7776 if (!Info.CheckArraySize(E->
getBeginLoc(), ByteSize.getActiveBits(),
7777 Size.getZExtValue(), !IsNothrow)) {
7785 QualType AllocType = Info.Ctx.getConstantArrayType(
7787 APValue *Val = Info.createHeapAlloc(Caller.Call, AllocType,
Result);
7796 return DD->isVirtual();
7803 return DD->isVirtual() ? DD->getOperatorDelete() :
nullptr;
7814 DynAlloc::Kind DeallocKind) {
7815 auto PointerAsString = [&] {
7816 return Pointer.toString(Info.Ctx, Info.Ctx.VoidPtrTy);
7821 Info.FFDiag(E, diag::note_constexpr_delete_not_heap_alloc)
7822 << PointerAsString();
7825 return std::nullopt;
7828 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
7830 Info.FFDiag(E, diag::note_constexpr_double_delete);
7831 return std::nullopt;
7834 if (DeallocKind != (*Alloc)->getKind()) {
7836 Info.FFDiag(E, diag::note_constexpr_new_delete_mismatch)
7837 << DeallocKind << (*Alloc)->getKind() << AllocType;
7839 return std::nullopt;
7842 bool Subobject =
false;
7843 if (DeallocKind == DynAlloc::New) {
7844 Subobject =
Pointer.Designator.MostDerivedPathLength != 0 ||
7845 Pointer.Designator.isOnePastTheEnd();
7847 Subobject =
Pointer.Designator.Entries.size() != 1 ||
7848 Pointer.Designator.Entries[0].getAsArrayIndex() != 0;
7851 Info.FFDiag(E, diag::note_constexpr_delete_subobject)
7852 << PointerAsString() <<
Pointer.Designator.isOnePastTheEnd();
7853 return std::nullopt;
7861 if (Info.checkingPotentialConstantExpression() ||
7862 Info.SpeculativeEvaluationDepth)
7866 if (!Info.getStdAllocatorCaller(
"deallocate")) {
7874 for (
unsigned I = 1, N = E->
getNumArgs(); I != N; ++I)
7877 if (
Pointer.Designator.Invalid)
7882 if (
Pointer.isNullPointer()) {
7883 Info.CCEDiag(E->
getExprLoc(), diag::note_constexpr_deallocate_null);
7899class BitCastBuffer {
7905 SmallVector<std::optional<unsigned char>, 32> Bytes;
7907 static_assert(std::numeric_limits<unsigned char>::digits >= 8,
7908 "Need at least 8 bit unsigned char");
7910 bool TargetIsLittleEndian;
7913 BitCastBuffer(CharUnits Width,
bool TargetIsLittleEndian)
7914 : Bytes(Width.getQuantity()),
7915 TargetIsLittleEndian(TargetIsLittleEndian) {}
7917 [[nodiscard]]
bool readObject(CharUnits Offset, CharUnits Width,
7918 SmallVectorImpl<unsigned char> &Output)
const {
7919 for (CharUnits I = Offset, E = Offset + Width; I != E; ++I) {
7922 if (!Bytes[I.getQuantity()])
7924 Output.push_back(*Bytes[I.getQuantity()]);
7926 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
7927 std::reverse(Output.begin(), Output.end());
7931 void writeObject(CharUnits Offset, SmallVectorImpl<unsigned char> &Input) {
7932 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
7933 std::reverse(Input.begin(), Input.end());
7936 for (
unsigned char Byte : Input) {
7937 assert(!Bytes[Offset.
getQuantity() + Index] &&
"overwriting a byte?");
7943 size_t size() {
return Bytes.size(); }
7948class APValueToBufferConverter {
7950 BitCastBuffer Buffer;
7953 APValueToBufferConverter(EvalInfo &Info, CharUnits ObjectWidth,
7956 Buffer(ObjectWidth, Info.Ctx.getTargetInfo().isLittleEndian()),
7959 bool visit(
const APValue &Val, QualType Ty) {
7964 bool visit(
const APValue &Val, QualType Ty, CharUnits Offset) {
7965 assert((
size_t)Offset.
getQuantity() <= Buffer.size());
7978 return visitInt(Val.
getInt(), Ty, Offset);
7980 return visitFloat(Val.
getFloat(), Ty, Offset);
7982 return visitArray(Val, Ty, Offset);
7984 return visitRecord(Val, Ty, Offset);
7986 return visitVector(Val, Ty, Offset);
7990 return visitComplex(Val, Ty, Offset);
8000 diag::note_constexpr_bit_cast_unsupported_type)
8005 llvm_unreachable(
"Unhandled APValue::ValueKind");
8008 bool visitRecord(
const APValue &Val, QualType Ty, CharUnits Offset) {
8010 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD);
8013 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
8014 for (
size_t I = 0, E = CXXRD->getNumBases(); I != E; ++I) {
8015 const CXXBaseSpecifier &BS = CXXRD->bases_begin()[I];
8020 if (!
Base.isStruct())
8023 if (!visitRecord(Base, BS.
getType(),
8030 unsigned FieldIdx = 0;
8031 for (FieldDecl *FD : RD->
fields()) {
8032 if (FD->isBitField()) {
8034 diag::note_constexpr_bit_cast_unsupported_bitfield);
8040 assert(FieldOffsetBits % Info.Ctx.getCharWidth() == 0 &&
8041 "only bit-fields can have sub-char alignment");
8042 CharUnits FieldOffset =
8043 Info.Ctx.toCharUnitsFromBits(FieldOffsetBits) + Offset;
8044 QualType FieldTy = FD->getType();
8053 bool visitArray(
const APValue &Val, QualType Ty, CharUnits Offset) {
8059 CharUnits ElemWidth = Info.Ctx.getTypeSizeInChars(CAT->
getElementType());
8063 for (
unsigned I = 0; I != NumInitializedElts; ++I) {
8065 if (!visit(SubObj, CAT->
getElementType(), Offset + I * ElemWidth))
8072 for (
unsigned I = NumInitializedElts; I != ArraySize; ++I) {
8073 if (!visit(Filler, CAT->
getElementType(), Offset + I * ElemWidth))
8081 bool visitComplex(
const APValue &Val, QualType Ty, CharUnits Offset) {
8082 const ComplexType *ComplexTy = Ty->
castAs<ComplexType>();
8084 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
8089 Offset + (0 * EltSizeChars)))
8092 Offset + (1 * EltSizeChars)))
8096 Offset + (0 * EltSizeChars)))
8099 Offset + (1 * EltSizeChars)))
8106 bool visitVector(
const APValue &Val, QualType Ty, CharUnits Offset) {
8107 const VectorType *VTy = Ty->
castAs<VectorType>();
8120 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
8122 llvm::APInt Res = llvm::APInt::getZero(NElts);
8123 for (
unsigned I = 0; I < NElts; ++I) {
8125 assert(EltAsInt.isUnsigned() && EltAsInt.getBitWidth() == 1 &&
8126 "bool vector element must be 1-bit unsigned integer!");
8128 Res.insertBits(EltAsInt, BigEndian ? (NElts - I - 1) : I);
8131 SmallVector<uint8_t, 8> Bytes(NElts / 8);
8132 llvm::StoreIntToMemory(Res, &*Bytes.begin(), NElts / 8);
8133 Buffer.writeObject(Offset, Bytes);
8137 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
8138 for (
unsigned I = 0; I < NElts; ++I) {
8139 if (!visit(Val.
getVectorElt(I), EltTy, Offset + I * EltSizeChars))
8147 bool visitInt(
const APSInt &Val, QualType Ty, CharUnits Offset) {
8148 APSInt AdjustedVal = Val;
8149 unsigned Width = AdjustedVal.getBitWidth();
8151 Width = Info.Ctx.getTypeSize(Ty);
8152 AdjustedVal = AdjustedVal.extend(Width);
8155 SmallVector<uint8_t, 8> Bytes(Width / 8);
8156 llvm::StoreIntToMemory(AdjustedVal, &*Bytes.begin(), Width / 8);
8157 Buffer.writeObject(Offset, Bytes);
8161 bool visitFloat(
const APFloat &Val, QualType Ty, CharUnits Offset) {
8162 APSInt AsInt(Val.bitcastToAPInt());
8163 return visitInt(AsInt, Ty, Offset);
8167 static std::optional<BitCastBuffer>
8169 CharUnits DstSize = Info.Ctx.getTypeSizeInChars(BCE->
getType());
8170 APValueToBufferConverter Converter(Info, DstSize, BCE);
8172 return std::nullopt;
8173 return Converter.Buffer;
8178class BufferToAPValueConverter {
8180 const BitCastBuffer &Buffer;
8183 BufferToAPValueConverter(EvalInfo &Info,
const BitCastBuffer &Buffer,
8185 : Info(Info), Buffer(Buffer), BCE(BCE) {}
8190 std::nullopt_t unsupportedType(QualType Ty) {
8192 diag::note_constexpr_bit_cast_unsupported_type)
8194 return std::nullopt;
8197 std::nullopt_t unrepresentableValue(QualType Ty,
const APSInt &Val) {
8199 diag::note_constexpr_bit_cast_unrepresentable_value)
8201 return std::nullopt;
8204 std::optional<APValue> visit(
const BuiltinType *
T, CharUnits Offset,
8205 const EnumType *EnumSugar =
nullptr) {
8207 uint64_t NullValue = Info.Ctx.getTargetNullPointerValue(QualType(
T, 0));
8208 return APValue((Expr *)
nullptr,
8210 APValue::NoLValuePath{},
true);
8213 CharUnits
SizeOf = Info.Ctx.getTypeSizeInChars(
T);
8219 const llvm::fltSemantics &Semantics =
8220 Info.Ctx.getFloatTypeSemantics(QualType(
T, 0));
8221 unsigned NumBits = llvm::APFloatBase::getSizeInBits(Semantics);
8222 assert(NumBits % 8 == 0);
8228 SmallVector<uint8_t, 8> Bytes;
8229 if (!Buffer.readObject(Offset,
SizeOf, Bytes)) {
8232 bool IsStdByte = EnumSugar && EnumSugar->isStdByteType();
8236 if (!IsStdByte && !IsUChar) {
8237 QualType DisplayType(EnumSugar ? (
const Type *)EnumSugar :
T, 0);
8239 diag::note_constexpr_bit_cast_indet_dest)
8240 << DisplayType << Info.Ctx.getLangOpts().CharIsSigned;
8241 return std::nullopt;
8247 APSInt Val(
SizeOf.getQuantity() * Info.Ctx.getCharWidth(),
true);
8248 llvm::LoadIntFromMemory(Val, &*Bytes.begin(), Bytes.size());
8253 unsigned IntWidth = Info.Ctx.getIntWidth(QualType(
T, 0));
8254 if (IntWidth != Val.getBitWidth()) {
8255 APSInt Truncated = Val.trunc(IntWidth);
8256 if (Truncated.extend(Val.getBitWidth()) != Val)
8257 return unrepresentableValue(QualType(
T, 0), Val);
8265 const llvm::fltSemantics &Semantics =
8266 Info.Ctx.getFloatTypeSemantics(QualType(
T, 0));
8270 return unsupportedType(QualType(
T, 0));
8273 std::optional<APValue> visit(
const RecordType *RTy, CharUnits Offset) {
8274 const RecordDecl *RD = RTy->getAsRecordDecl();
8276 return std::nullopt;
8277 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD);
8279 unsigned NumBases = 0;
8280 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
8281 NumBases = CXXRD->getNumBases();
8286 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
8287 for (
size_t I = 0, E = CXXRD->getNumBases(); I != E; ++I) {
8288 const CXXBaseSpecifier &BS = CXXRD->bases_begin()[I];
8291 std::optional<APValue> SubObj = visitType(
8294 return std::nullopt;
8295 ResultVal.getStructBase(I) = *SubObj;
8300 unsigned FieldIdx = 0;
8301 for (FieldDecl *FD : RD->
fields()) {
8304 if (FD->isBitField()) {
8306 diag::note_constexpr_bit_cast_unsupported_bitfield);
8307 return std::nullopt;
8311 assert(FieldOffsetBits % Info.Ctx.getCharWidth() == 0);
8313 CharUnits FieldOffset =
8316 QualType FieldTy = FD->getType();
8317 std::optional<APValue> SubObj = visitType(FieldTy, FieldOffset);
8319 return std::nullopt;
8320 ResultVal.getStructField(FieldIdx) = *SubObj;
8327 std::optional<APValue> visit(
const EnumType *Ty, CharUnits Offset) {
8328 QualType RepresentationType =
8329 Ty->getDecl()->getDefinitionOrSelf()->getIntegerType();
8330 assert(!RepresentationType.
isNull() &&
8331 "enum forward decl should be caught by Sema");
8332 const auto *AsBuiltin =
8336 return visit(AsBuiltin, Offset, Ty);
8339 std::optional<APValue> visit(
const ConstantArrayType *Ty, CharUnits Offset) {
8341 CharUnits ElementWidth = Info.Ctx.getTypeSizeInChars(Ty->
getElementType());
8343 APValue ArrayValue(APValue::UninitArray(), Size, Size);
8344 for (
size_t I = 0; I !=
Size; ++I) {
8345 std::optional<APValue> ElementValue =
8348 return std::nullopt;
8349 ArrayValue.getArrayInitializedElt(I) = std::move(*ElementValue);
8355 std::optional<APValue> visit(
const ComplexType *Ty, CharUnits Offset) {
8357 CharUnits ElementWidth = Info.Ctx.getTypeSizeInChars(ElementType);
8360 std::optional<APValue> Values[2];
8361 for (
unsigned I = 0; I != 2; ++I) {
8362 Values[I] = visitType(Ty->
getElementType(), Offset + I * ElementWidth);
8364 return std::nullopt;
8368 return APValue(Values[0]->getInt(), Values[1]->getInt());
8369 return APValue(Values[0]->getFloat(), Values[1]->getFloat());
8372 std::optional<APValue> visit(
const VectorType *VTy, CharUnits Offset) {
8378 SmallVector<APValue, 4> Elts;
8379 Elts.reserve(NElts);
8389 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
8391 SmallVector<uint8_t, 8> Bytes;
8392 Bytes.reserve(NElts / 8);
8394 return std::nullopt;
8396 APSInt SValInt(NElts,
true);
8397 llvm::LoadIntFromMemory(SValInt, &*Bytes.begin(), Bytes.size());
8399 for (
unsigned I = 0; I < NElts; ++I) {
8401 SValInt.extractBits(1, (BigEndian ? NElts - I - 1 : I) * EltSize);
8408 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
8409 for (
unsigned I = 0; I < NElts; ++I) {
8410 std::optional<APValue> EltValue =
8411 visitType(EltTy, Offset + I * EltSizeChars);
8413 return std::nullopt;
8414 Elts.push_back(std::move(*EltValue));
8418 return APValue(Elts.data(), Elts.size());
8421 std::optional<APValue> visit(
const Type *Ty, CharUnits Offset) {
8422 return unsupportedType(QualType(Ty, 0));
8425 std::optional<APValue> visitType(QualType Ty, CharUnits Offset) {
8429#define TYPE(Class, Base) \
8431 return visit(cast<Class##Type>(Can.getTypePtr()), Offset);
8432#define ABSTRACT_TYPE(Class, Base)
8433#define NON_CANONICAL_TYPE(Class, Base) \
8435 llvm_unreachable("non-canonical type should be impossible!");
8436#define DEPENDENT_TYPE(Class, Base) \
8439 "dependent types aren't supported in the constant evaluator!");
8440#define NON_CANONICAL_UNLESS_DEPENDENT(Class, Base) \
8442 llvm_unreachable("either dependent or not canonical!");
8443#include "clang/AST/TypeNodes.inc"
8445 llvm_unreachable(
"Unhandled Type::TypeClass");
8450 static std::optional<APValue> convert(EvalInfo &Info, BitCastBuffer &Buffer,
8452 BufferToAPValueConverter Converter(Info, Buffer, BCE);
8457static bool checkBitCastConstexprEligibilityType(SourceLocation Loc,
8458 QualType Ty, EvalInfo *Info,
8459 const ASTContext &Ctx,
8460 bool CheckingDest) {
8463 auto diag = [&](
int Reason) {
8465 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_invalid_type)
8466 << CheckingDest << (Reason == 4) << Reason;
8469 auto note = [&](
int Construct, QualType NoteTy, SourceLocation NoteLoc) {
8471 Info->Note(NoteLoc, diag::note_constexpr_bit_cast_invalid_subtype)
8472 << NoteTy << Construct << Ty;
8486 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(
Record)) {
8487 for (CXXBaseSpecifier &BS : CXXRD->bases())
8488 if (!checkBitCastConstexprEligibilityType(Loc, BS.
getType(), Info, Ctx,
8492 for (FieldDecl *FD :
Record->fields()) {
8493 if (FD->getType()->isReferenceType())
8495 if (!checkBitCastConstexprEligibilityType(Loc, FD->getType(), Info, Ctx,
8497 return note(0, FD->getType(), FD->getBeginLoc());
8503 Info, Ctx, CheckingDest))
8506 if (
const auto *VTy = Ty->
getAs<VectorType>()) {
8518 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_invalid_vector)
8519 << QualType(VTy, 0) << EltSize << NElts << Ctx.
getCharWidth();
8529 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_unsupported_type)
8538static bool checkBitCastConstexprEligibility(EvalInfo *Info,
8539 const ASTContext &Ctx,
8541 bool DestOK = checkBitCastConstexprEligibilityType(
8543 bool SourceOK = DestOK && checkBitCastConstexprEligibilityType(
8549static bool handleRValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
8552 assert(
CHAR_BIT == 8 && Info.Ctx.getTargetInfo().getCharWidth() == 8 &&
8553 "no host or target supports non 8-bit chars");
8555 if (!checkBitCastConstexprEligibility(&Info, Info.Ctx, BCE))
8559 std::optional<BitCastBuffer> Buffer =
8560 APValueToBufferConverter::convert(Info, SourceRValue, BCE);
8565 std::optional<APValue> MaybeDestValue =
8566 BufferToAPValueConverter::convert(Info, *Buffer, BCE);
8567 if (!MaybeDestValue)
8570 DestValue = std::move(*MaybeDestValue);
8574static bool handleLValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
8577 assert(
CHAR_BIT == 8 && Info.Ctx.getTargetInfo().getCharWidth() == 8 &&
8578 "no host or target supports non 8-bit chars");
8580 "LValueToRValueBitcast requires an lvalue operand!");
8582 LValue SourceLValue;
8584 SourceLValue.setFrom(Info.Ctx, SourceValue);
8587 SourceRValue,
true))
8590 return handleRValueToRValueBitCast(Info, DestValue, SourceRValue, BCE);
8593template <
class Derived>
8594class ExprEvaluatorBase
8595 :
public ConstStmtVisitor<Derived, bool> {
8597 Derived &getDerived() {
return static_cast<Derived&
>(*this); }
8598 bool DerivedSuccess(
const APValue &
V,
const Expr *E) {
8599 return getDerived().Success(
V, E);
8601 bool DerivedZeroInitialization(
const Expr *E) {
8602 return getDerived().ZeroInitialization(E);
8608 template<
typename ConditionalOperator>
8609 void CheckPotentialConstantConditional(
const ConditionalOperator *E) {
8610 assert(Info.checkingPotentialConstantExpression());
8613 SmallVector<PartialDiagnosticAt, 8>
Diag;
8615 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
8622 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
8624 Info.EvalStatus.DiagEmitted =
false;
8630 Error(E, diag::note_constexpr_conditional_never_const);
8634 template<
typename ConditionalOperator>
8635 bool HandleConditionalOperator(
const ConditionalOperator *E) {
8638 if (Info.checkingPotentialConstantExpression() && Info.noteFailure()) {
8639 CheckPotentialConstantConditional(E);
8642 if (Info.noteFailure()) {
8650 return StmtVisitorTy::Visit(EvalExpr);
8655 typedef ConstStmtVisitor<Derived, bool> StmtVisitorTy;
8656 typedef ExprEvaluatorBase ExprEvaluatorBaseTy;
8658 OptionalDiagnostic CCEDiag(
const Expr *E,
diag::kind D) {
8659 return Info.CCEDiag(E, D);
8662 bool ZeroInitialization(
const Expr *E) {
return Error(E); }
8664 bool IsConstantEvaluatedBuiltinCall(
const CallExpr *E) {
8666 return BuiltinOp != 0 &&
8667 Info.Ctx.BuiltinInfo.isConstantEvaluated(BuiltinOp);
8671 ExprEvaluatorBase(EvalInfo &Info) : Info(Info) {}
8673 EvalInfo &getEvalInfo() {
return Info; }
8681 bool Error(
const Expr *E) {
8682 return Error(E, diag::note_invalid_subexpr_in_const_expr);
8685 bool VisitStmt(
const Stmt *) {
8686 llvm_unreachable(
"Expression evaluator should not be called on stmts");
8688 bool VisitExpr(
const Expr *E) {
8692 bool VisitEmbedExpr(
const EmbedExpr *E) {
8693 const auto It = E->
begin();
8694 return StmtVisitorTy::Visit(*It);
8697 bool VisitPredefinedExpr(
const PredefinedExpr *E) {
8700 bool VisitConstantExpr(
const ConstantExpr *E) {
8704 return StmtVisitorTy::Visit(E->
getSubExpr());
8707 bool VisitParenExpr(
const ParenExpr *E)
8708 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8709 bool VisitUnaryExtension(
const UnaryOperator *E)
8710 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8711 bool VisitUnaryPlus(
const UnaryOperator *E)
8712 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8713 bool VisitChooseExpr(
const ChooseExpr *E)
8715 bool VisitGenericSelectionExpr(
const GenericSelectionExpr *E)
8717 bool VisitSubstNonTypeTemplateParmExpr(
const SubstNonTypeTemplateParmExpr *E)
8719 bool VisitCXXDefaultArgExpr(
const CXXDefaultArgExpr *E) {
8720 TempVersionRAII RAII(*Info.CurrentCall);
8721 SourceLocExprScopeGuard Guard(E, Info.CurrentCall->CurSourceLocExprScope);
8722 return StmtVisitorTy::Visit(E->
getExpr());
8724 bool VisitCXXDefaultInitExpr(
const CXXDefaultInitExpr *E) {
8725 TempVersionRAII RAII(*Info.CurrentCall);
8729 SourceLocExprScopeGuard Guard(E, Info.CurrentCall->CurSourceLocExprScope);
8730 return StmtVisitorTy::Visit(E->
getExpr());
8733 bool VisitExprWithCleanups(
const ExprWithCleanups *E) {
8734 FullExpressionRAII Scope(Info);
8735 return StmtVisitorTy::Visit(E->
getSubExpr()) && Scope.destroy();
8740 bool VisitCXXBindTemporaryExpr(
const CXXBindTemporaryExpr *E) {
8741 return StmtVisitorTy::Visit(E->
getSubExpr());
8744 bool VisitCXXReinterpretCastExpr(
const CXXReinterpretCastExpr *E) {
8746 CCEDiag(E, diag::note_constexpr_invalid_cast)
8747 << diag::ConstexprInvalidCastKind::Reinterpret;
8748 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8750 bool VisitCXXDynamicCastExpr(
const CXXDynamicCastExpr *E) {
8751 if (!Info.Ctx.getLangOpts().CPlusPlus20)
8752 CCEDiag(E, diag::note_constexpr_invalid_cast)
8753 << diag::ConstexprInvalidCastKind::Dynamic;
8754 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8756 bool VisitBuiltinBitCastExpr(
const BuiltinBitCastExpr *E) {
8757 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8760 bool VisitBinaryOperator(
const BinaryOperator *E) {
8766 VisitIgnoredValue(E->
getLHS());
8767 return StmtVisitorTy::Visit(E->
getRHS());
8777 return DerivedSuccess(
Result, E);
8782 bool VisitCXXRewrittenBinaryOperator(
const CXXRewrittenBinaryOperator *E) {
8786 bool VisitBinaryConditionalOperator(
const BinaryConditionalOperator *E) {
8790 if (!
Evaluate(Info.CurrentCall->createTemporary(
8793 ScopeKind::FullExpression, CommonLV),
8797 return HandleConditionalOperator(E);
8800 bool VisitConditionalOperator(
const ConditionalOperator *E) {
8801 bool IsBcpCall =
false;
8806 if (
const CallExpr *CallCE =
8808 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
8815 if (Info.checkingPotentialConstantExpression() && IsBcpCall)
8818 FoldConstant Fold(Info, IsBcpCall);
8819 if (!HandleConditionalOperator(E)) {
8820 Fold.keepDiagnostics();
8827 bool VisitOpaqueValueExpr(
const OpaqueValueExpr *E) {
8828 if (
APValue *
Value = Info.CurrentCall->getCurrentTemporary(E);
8830 return DerivedSuccess(*
Value, E);
8836 assert(0 &&
"OpaqueValueExpr recursively refers to itself");
8839 return StmtVisitorTy::Visit(Source);
8842 bool VisitPseudoObjectExpr(
const PseudoObjectExpr *E) {
8843 for (
const Expr *SemE : E->
semantics()) {
8844 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
8853 if (OVE->isUnique())
8857 if (!
Evaluate(Info.CurrentCall->createTemporary(
8858 OVE, getStorageType(Info.Ctx, OVE),
8859 ScopeKind::FullExpression, LV),
8860 Info, OVE->getSourceExpr()))
8863 if (!StmtVisitorTy::Visit(SemE))
8873 bool VisitCallExpr(
const CallExpr *E) {
8875 if (!handleCallExpr(E,
Result,
nullptr))
8877 return DerivedSuccess(
Result, E);
8881 const LValue *ResultSlot) {
8882 CallScopeRAII CallScope(Info);
8885 QualType CalleeType =
Callee->getType();
8887 const FunctionDecl *FD =
nullptr;
8888 LValue *
This =
nullptr, ObjectArg;
8890 bool HasQualifier =
false;
8896 const CXXMethodDecl *
Member =
nullptr;
8897 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(Callee)) {
8901 Member = dyn_cast<CXXMethodDecl>(ME->getMemberDecl());
8903 return Error(Callee);
8905 HasQualifier = ME->hasQualifier();
8906 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(Callee)) {
8908 const ValueDecl *D =
8912 Member = dyn_cast<CXXMethodDecl>(D);
8914 return Error(Callee);
8916 }
else if (
const auto *PDE = dyn_cast<CXXPseudoDestructorExpr>(Callee)) {
8917 if (!Info.getLangOpts().CPlusPlus20)
8918 Info.CCEDiag(PDE, diag::note_constexpr_pseudo_destructor);
8922 return Error(Callee);
8929 if (!CalleeLV.getLValueOffset().isZero())
8930 return Error(Callee);
8931 if (CalleeLV.isNullPointer()) {
8932 Info.FFDiag(Callee, diag::note_constexpr_null_callee)
8933 <<
const_cast<Expr *
>(
Callee);
8936 FD = dyn_cast_or_null<FunctionDecl>(
8937 CalleeLV.getLValueBase().dyn_cast<
const ValueDecl *>());
8939 return Error(Callee);
8942 if (!Info.Ctx.hasSameFunctionTypeIgnoringExceptionSpec(
8949 auto *OCE = dyn_cast<CXXOperatorCallExpr>(E);
8950 if (OCE && OCE->isAssignmentOp()) {
8951 assert(Args.size() == 2 &&
"wrong number of arguments in assignment");
8952 Call = Info.CurrentCall->createCall(FD);
8953 bool HasThis =
false;
8954 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FD))
8955 HasThis = MD->isImplicitObjectMemberFunction();
8963 const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD);
8983 if (Info.getLangOpts().CPlusPlus20 && OCE &&
8984 OCE->getOperator() == OO_Equal && MD->
isTrivial() &&
8988 Args = Args.slice(1);
8994 const CXXRecordDecl *ClosureClass = MD->
getParent();
8996 ClosureClass->
captures().empty() &&
8997 "Number of captures must be zero for conversion to function-ptr");
8999 const CXXMethodDecl *LambdaCallOp =
9008 "A generic lambda's static-invoker function must be a "
9009 "template specialization");
9011 FunctionTemplateDecl *CallOpTemplate =
9013 void *InsertPos =
nullptr;
9014 FunctionDecl *CorrespondingCallOpSpecialization =
9016 assert(CorrespondingCallOpSpecialization &&
9017 "We must always have a function call operator specialization "
9018 "that corresponds to our static invoker specialization");
9020 FD = CorrespondingCallOpSpecialization;
9029 return CallScope.destroy();
9039 Call = Info.CurrentCall->createCall(FD);
9045 SmallVector<QualType, 4> CovariantAdjustmentPath;
9047 auto *NamedMember = dyn_cast<CXXMethodDecl>(FD);
9048 if (NamedMember && NamedMember->isVirtual() && !HasQualifier) {
9051 CovariantAdjustmentPath);
9054 }
else if (NamedMember && NamedMember->isImplicitObjectMemberFunction()) {
9064 if (
auto *DD = dyn_cast<CXXDestructorDecl>(FD)) {
9065 assert(This &&
"no 'this' pointer for destructor call");
9067 Info.Ctx.getCanonicalTagType(DD->getParent())) &&
9068 CallScope.destroy();
9085 if (!CovariantAdjustmentPath.empty() &&
9087 CovariantAdjustmentPath))
9090 return CallScope.destroy();
9093 bool VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E) {
9096 bool VisitInitListExpr(
const InitListExpr *E) {
9098 return DerivedZeroInitialization(E);
9100 return StmtVisitorTy::Visit(E->
getInit(0));
9103 bool VisitImplicitValueInitExpr(
const ImplicitValueInitExpr *E) {
9104 return DerivedZeroInitialization(E);
9106 bool VisitCXXScalarValueInitExpr(
const CXXScalarValueInitExpr *E) {
9107 return DerivedZeroInitialization(E);
9109 bool VisitCXXNullPtrLiteralExpr(
const CXXNullPtrLiteralExpr *E) {
9110 return DerivedZeroInitialization(E);
9114 bool VisitMemberExpr(
const MemberExpr *E) {
9115 assert(!Info.Ctx.getLangOpts().CPlusPlus11 &&
9116 "missing temporary materialization conversion");
9117 assert(!E->
isArrow() &&
"missing call to bound member function?");
9125 const FieldDecl *FD = dyn_cast<FieldDecl>(E->
getMemberDecl());
9126 if (!FD)
return Error(E);
9130 "record / field mismatch");
9135 CompleteObject Obj(APValue::LValueBase(), &Val, BaseTy);
9136 SubobjectDesignator Designator(BaseTy);
9137 Designator.addDeclUnchecked(FD);
9141 DerivedSuccess(
Result, E);
9144 bool VisitExtVectorElementExpr(
const ExtVectorElementExpr *E) {
9150 SmallVector<uint32_t, 4> Indices;
9152 if (Indices.size() == 1) {
9154 return DerivedSuccess(Val.
getVectorElt(Indices[0]), E);
9157 SmallVector<APValue, 4> Elts;
9158 for (
unsigned I = 0; I < Indices.size(); ++I) {
9161 APValue VecResult(Elts.data(), Indices.size());
9162 return DerivedSuccess(VecResult, E);
9169 bool VisitCastExpr(
const CastExpr *E) {
9174 case CK_AtomicToNonAtomic: {
9181 return DerivedSuccess(AtomicVal, E);
9185 case CK_UserDefinedConversion:
9186 return StmtVisitorTy::Visit(E->
getSubExpr());
9188 case CK_HLSLArrayRValue: {
9194 return DerivedSuccess(Val, E);
9205 return DerivedSuccess(RVal, E);
9207 case CK_LValueToRValue: {
9216 return DerivedSuccess(RVal, E);
9218 case CK_LValueToRValueBitCast: {
9219 APValue DestValue, SourceValue;
9222 if (!handleLValueToRValueBitCast(Info, DestValue, SourceValue, E))
9224 return DerivedSuccess(DestValue, E);
9227 case CK_AddressSpaceConversion: {
9231 return DerivedSuccess(
Value, E);
9238 bool VisitUnaryPostInc(
const UnaryOperator *UO) {
9239 return VisitUnaryPostIncDec(UO);
9241 bool VisitUnaryPostDec(
const UnaryOperator *UO) {
9242 return VisitUnaryPostIncDec(UO);
9244 bool VisitUnaryPostIncDec(
const UnaryOperator *UO) {
9245 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9255 return DerivedSuccess(RVal, UO);
9258 bool VisitStmtExpr(
const StmtExpr *E) {
9261 llvm::SaveAndRestore NotCheckingForUB(Info.CheckingForUndefinedBehavior,
9268 BlockScopeRAII Scope(Info);
9273 const Expr *FinalExpr = dyn_cast<Expr>(*BI);
9275 Info.FFDiag((*BI)->getBeginLoc(),
9276 diag::note_constexpr_stmt_expr_unsupported);
9279 return this->Visit(FinalExpr) && Scope.destroy();
9285 if (ESR != ESR_Succeeded) {
9289 if (ESR != ESR_Failed)
9290 Info.FFDiag((*BI)->getBeginLoc(),
9291 diag::note_constexpr_stmt_expr_unsupported);
9296 llvm_unreachable(
"Return from function from the loop above.");
9299 bool VisitPackIndexingExpr(
const PackIndexingExpr *E) {
9304 void VisitIgnoredValue(
const Expr *E) {
9309 void VisitIgnoredBaseExpression(
const Expr *E) {
9312 if (Info.getLangOpts().MSVCCompat && !E->
HasSideEffects(Info.Ctx))
9314 VisitIgnoredValue(E);
9324template<
class Derived>
9325class LValueExprEvaluatorBase
9326 :
public ExprEvaluatorBase<Derived> {
9330 typedef LValueExprEvaluatorBase LValueExprEvaluatorBaseTy;
9331 typedef ExprEvaluatorBase<Derived> ExprEvaluatorBaseTy;
9333 bool Success(APValue::LValueBase B) {
9338 bool evaluatePointer(
const Expr *E, LValue &
Result) {
9343 LValueExprEvaluatorBase(EvalInfo &Info, LValue &
Result,
bool InvalidBaseOK)
9345 InvalidBaseOK(InvalidBaseOK) {}
9348 Result.setFrom(this->Info.Ctx,
V);
9352 bool VisitMemberExpr(
const MemberExpr *E) {
9364 EvalOK = this->Visit(E->
getBase());
9375 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(E->
getMemberDecl())) {
9378 "record / field mismatch");
9382 }
else if (
const IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(MD)) {
9386 return this->
Error(E);
9398 bool VisitBinaryOperator(
const BinaryOperator *E) {
9401 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
9409 bool VisitCastExpr(
const CastExpr *E) {
9412 return ExprEvaluatorBaseTy::VisitCastExpr(E);
9414 case CK_DerivedToBase:
9415 case CK_UncheckedDerivedToBase:
9462class LValueExprEvaluator
9463 :
public LValueExprEvaluatorBase<LValueExprEvaluator> {
9465 LValueExprEvaluator(EvalInfo &Info, LValue &
Result,
bool InvalidBaseOK) :
9466 LValueExprEvaluatorBaseTy(Info,
Result, InvalidBaseOK) {}
9468 bool VisitVarDecl(
const Expr *E,
const VarDecl *VD);
9469 bool VisitUnaryPreIncDec(
const UnaryOperator *UO);
9471 bool VisitCallExpr(
const CallExpr *E);
9472 bool VisitDeclRefExpr(
const DeclRefExpr *E);
9473 bool VisitPredefinedExpr(
const PredefinedExpr *E) {
return Success(E); }
9474 bool VisitMaterializeTemporaryExpr(
const MaterializeTemporaryExpr *E);
9475 bool VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E);
9476 bool VisitMemberExpr(
const MemberExpr *E);
9477 bool VisitStringLiteral(
const StringLiteral *E) {
9479 APValue::LValueBase(E, 0, Info.Ctx.getNextStringLiteralVersion()));
9481 bool VisitObjCEncodeExpr(
const ObjCEncodeExpr *E) {
return Success(E); }
9482 bool VisitCXXTypeidExpr(
const CXXTypeidExpr *E);
9483 bool VisitCXXUuidofExpr(
const CXXUuidofExpr *E);
9484 bool VisitArraySubscriptExpr(
const ArraySubscriptExpr *E);
9485 bool VisitExtVectorElementExpr(
const ExtVectorElementExpr *E);
9486 bool VisitUnaryDeref(
const UnaryOperator *E);
9487 bool VisitUnaryReal(
const UnaryOperator *E);
9488 bool VisitUnaryImag(
const UnaryOperator *E);
9489 bool VisitUnaryPreInc(
const UnaryOperator *UO) {
9490 return VisitUnaryPreIncDec(UO);
9492 bool VisitUnaryPreDec(
const UnaryOperator *UO) {
9493 return VisitUnaryPreIncDec(UO);
9495 bool VisitBinAssign(
const BinaryOperator *BO);
9496 bool VisitCompoundAssignOperator(
const CompoundAssignOperator *CAO);
9498 bool VisitCastExpr(
const CastExpr *E) {
9501 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
9503 case CK_LValueBitCast:
9504 this->CCEDiag(E, diag::note_constexpr_invalid_cast)
9505 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
9509 Result.Designator.setInvalid();
9512 case CK_BaseToDerived:
9529 bool LValueToRValueConversion) {
9533 assert(Info.CurrentCall->This ==
nullptr &&
9534 "This should not be set for a static call operator");
9542 if (
Self->getType()->isReferenceType()) {
9543 APValue *RefValue = Info.getParamSlot(Info.CurrentCall->Arguments,
Self);
9545 Result.setFrom(Info.Ctx, *RefValue);
9547 const ParmVarDecl *VD = Info.CurrentCall->Arguments.getOrigParam(
Self);
9548 CallStackFrame *Frame =
9549 Info.getCallFrameAndDepth(Info.CurrentCall->Arguments.CallIndex)
9551 unsigned Version = Info.CurrentCall->Arguments.Version;
9552 Result.set({VD, Frame->Index, Version});
9555 Result = *Info.CurrentCall->This;
9565 if (LValueToRValueConversion) {
9569 Result.setFrom(Info.Ctx, RVal);
9580 bool InvalidBaseOK) {
9584 return LValueExprEvaluator(Info,
Result, InvalidBaseOK).Visit(E);
9587bool LValueExprEvaluator::VisitDeclRefExpr(
const DeclRefExpr *E) {
9588 const ValueDecl *D = E->
getDecl();
9600 if (Info.checkingPotentialConstantExpression())
9603 if (
auto *FD = Info.CurrentCall->LambdaCaptureFields.lookup(D)) {
9610 if (
isa<FunctionDecl, MSGuidDecl, TemplateParamObjectDecl,
9611 UnnamedGlobalConstantDecl>(D))
9613 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
9614 return VisitVarDecl(E, VD);
9615 if (
const BindingDecl *BD = dyn_cast<BindingDecl>(D))
9616 return Visit(BD->getBinding());
9620bool LValueExprEvaluator::VisitVarDecl(
const Expr *E,
const VarDecl *VD) {
9621 CallStackFrame *Frame =
nullptr;
9622 unsigned Version = 0;
9630 CallStackFrame *CurrFrame = Info.CurrentCall;
9635 if (
auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
9636 if (CurrFrame->Arguments) {
9637 VD = CurrFrame->Arguments.getOrigParam(PVD);
9639 Info.getCallFrameAndDepth(CurrFrame->Arguments.CallIndex).first;
9640 Version = CurrFrame->Arguments.Version;
9644 Version = CurrFrame->getCurrentTemporaryVersion(VD);
9651 Result.set({VD, Frame->Index, Version});
9657 if (!Info.getLangOpts().CPlusPlus11) {
9658 Info.CCEDiag(E, diag::note_constexpr_ltor_non_integral, 1)
9660 Info.Note(VD->
getLocation(), diag::note_declared_at);
9669 Result.AllowConstexprUnknown =
true;
9676bool LValueExprEvaluator::VisitCallExpr(
const CallExpr *E) {
9677 if (!IsConstantEvaluatedBuiltinCall(E))
9678 return ExprEvaluatorBaseTy::VisitCallExpr(E);
9683 case Builtin::BIas_const:
9684 case Builtin::BIforward:
9685 case Builtin::BIforward_like:
9686 case Builtin::BImove:
9687 case Builtin::BImove_if_noexcept:
9689 return Visit(E->
getArg(0));
9693 return ExprEvaluatorBaseTy::VisitCallExpr(E);
9696bool LValueExprEvaluator::VisitMaterializeTemporaryExpr(
9697 const MaterializeTemporaryExpr *E) {
9705 for (
const Expr *E : CommaLHSs)
9714 if (Info.EvalMode == EvaluationMode::ConstantFold)
9721 Value = &Info.CurrentCall->createTemporary(
9737 for (
unsigned I = Adjustments.size(); I != 0; ) {
9739 switch (Adjustments[I].Kind) {
9744 Type = Adjustments[I].DerivedToBase.BasePath->getType();
9750 Type = Adjustments[I].Field->getType();
9755 Adjustments[I].Ptr.RHS))
9757 Type = Adjustments[I].Ptr.MPT->getPointeeType();
9766LValueExprEvaluator::VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E) {
9767 assert((!Info.getLangOpts().CPlusPlus || E->
isFileScope()) &&
9768 "lvalue compound literal in c++?");
9780 assert(!Info.getLangOpts().CPlusPlus);
9782 ScopeKind::Block,
Result);
9794bool LValueExprEvaluator::VisitCXXTypeidExpr(
const CXXTypeidExpr *E) {
9795 TypeInfoLValue TypeInfo;
9803 if (!Info.Ctx.getLangOpts().CPlusPlus20) {
9804 Info.CCEDiag(E, diag::note_constexpr_typeid_polymorphic)
9812 std::optional<DynamicType> DynType =
9817 TypeInfo = TypeInfoLValue(
9818 Info.Ctx.getCanonicalTagType(DynType->Type).getTypePtr());
9824bool LValueExprEvaluator::VisitCXXUuidofExpr(
const CXXUuidofExpr *E) {
9828bool LValueExprEvaluator::VisitMemberExpr(
const MemberExpr *E) {
9830 if (
const VarDecl *VD = dyn_cast<VarDecl>(E->
getMemberDecl())) {
9831 VisitIgnoredBaseExpression(E->
getBase());
9832 return VisitVarDecl(E, VD);
9836 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(E->
getMemberDecl())) {
9837 if (MD->isStatic()) {
9838 VisitIgnoredBaseExpression(E->
getBase());
9844 return LValueExprEvaluatorBaseTy::VisitMemberExpr(E);
9847bool LValueExprEvaluator::VisitExtVectorElementExpr(
9848 const ExtVectorElementExpr *E) {
9853 if (!Info.noteFailure())
9861 if (Indices.size() > 1)
9865 Result.setFrom(Info.Ctx, Val);
9869 const auto *VT = BaseType->
castAs<VectorType>();
9871 VT->getNumElements(), Indices[0]);
9877bool LValueExprEvaluator::VisitArraySubscriptExpr(
const ArraySubscriptExpr *E) {
9887 if (!Info.noteFailure())
9893 if (!Info.noteFailure())
9899 Result.setFrom(Info.Ctx, Val);
9901 VT->getNumElements(), Index.getZExtValue());
9909 for (
const Expr *SubExpr : {E->
getLHS(), E->
getRHS()}) {
9910 if (SubExpr == E->
getBase() ? !evaluatePointer(SubExpr,
Result)
9912 if (!Info.noteFailure())
9922bool LValueExprEvaluator::VisitUnaryDeref(
const UnaryOperator *E) {
9933 Info.noteUndefinedBehavior();
9936bool LValueExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
9945bool LValueExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
9947 "lvalue __imag__ on scalar?");
9954bool LValueExprEvaluator::VisitUnaryPreIncDec(
const UnaryOperator *UO) {
9955 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9966bool LValueExprEvaluator::VisitCompoundAssignOperator(
9967 const CompoundAssignOperator *CAO) {
9968 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9976 if (!Info.noteFailure())
9991bool LValueExprEvaluator::VisitBinAssign(
const BinaryOperator *E) {
9992 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
10000 if (!Info.noteFailure())
10008 if (Info.getLangOpts().CPlusPlus20 &&
10023 const LValue &LVal,
10025 assert(isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
10026 "Can't get the size of a non alloc_size function");
10027 const auto *
Base = LVal.getLValueBase().get<
const Expr *>();
10029 std::optional<llvm::APInt> Size =
10030 CE->evaluateBytesReturnedByAllocSizeCall(Ctx);
10034 Result = std::move(*Size);
10053 dyn_cast_or_null<VarDecl>(
Base.dyn_cast<
const ValueDecl *>());
10058 if (!
Init ||
Init->getType().isNull())
10061 const Expr *E =
Init->IgnoreParens();
10062 if (!tryUnwrapAllocSizeCall(E))
10070 Result.addUnsizedArray(Info, E, Pointee);
10075class PointerExprEvaluator
10076 :
public ExprEvaluatorBase<PointerExprEvaluator> {
10078 bool InvalidBaseOK;
10080 bool Success(
const Expr *E) {
10085 bool evaluateLValue(
const Expr *E, LValue &
Result) {
10089 bool evaluatePointer(
const Expr *E, LValue &
Result) {
10093 bool visitNonBuiltinCallExpr(
const CallExpr *E);
10096 PointerExprEvaluator(EvalInfo &info, LValue &
Result,
bool InvalidBaseOK)
10098 InvalidBaseOK(InvalidBaseOK) {}
10104 bool ZeroInitialization(
const Expr *E) {
10109 bool VisitBinaryOperator(
const BinaryOperator *E);
10110 bool VisitCastExpr(
const CastExpr* E);
10111 bool VisitUnaryAddrOf(
const UnaryOperator *E);
10112 bool VisitObjCStringLiteral(
const ObjCStringLiteral *E)
10114 bool VisitObjCBoxedExpr(
const ObjCBoxedExpr *E) {
10117 if (Info.noteFailure())
10121 bool VisitObjCArrayLiteral(
const ObjCArrayLiteral *E) {
10124 bool VisitObjCDictionaryLiteral(
const ObjCDictionaryLiteral *E) {
10127 bool VisitAddrLabelExpr(
const AddrLabelExpr *E)
10129 bool VisitCallExpr(
const CallExpr *E);
10130 bool VisitBuiltinCallExpr(
const CallExpr *E,
unsigned BuiltinOp);
10131 bool VisitBlockExpr(
const BlockExpr *E) {
10136 bool VisitCXXThisExpr(
const CXXThisExpr *E) {
10137 auto DiagnoseInvalidUseOfThis = [&] {
10138 if (Info.getLangOpts().CPlusPlus11)
10139 Info.FFDiag(E, diag::note_constexpr_this) << E->
isImplicit();
10145 if (Info.checkingPotentialConstantExpression())
10148 bool IsExplicitLambda =
10150 if (!IsExplicitLambda) {
10151 if (!Info.CurrentCall->This) {
10152 DiagnoseInvalidUseOfThis();
10156 Result = *Info.CurrentCall->This;
10164 if (!Info.CurrentCall->LambdaThisCaptureField) {
10165 if (IsExplicitLambda && !Info.CurrentCall->This) {
10166 DiagnoseInvalidUseOfThis();
10175 Info, E,
Result, MD, Info.CurrentCall->LambdaThisCaptureField,
10181 bool VisitCXXNewExpr(
const CXXNewExpr *E);
10183 bool VisitSourceLocExpr(
const SourceLocExpr *E) {
10184 assert(!E->
isIntType() &&
"SourceLocExpr isn't a pointer type?");
10186 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.
getDefaultExpr());
10187 Result.setFrom(Info.Ctx, LValResult);
10191 bool VisitEmbedExpr(
const EmbedExpr *E) {
10192 llvm::report_fatal_error(
"Not yet implemented for ExprConstant.cpp");
10196 bool VisitSYCLUniqueStableNameExpr(
const SYCLUniqueStableNameExpr *E) {
10197 std::string ResultStr = E->
ComputeName(Info.Ctx);
10199 QualType CharTy = Info.Ctx.CharTy.withConst();
10200 APInt Size(Info.Ctx.getTypeSize(Info.Ctx.getSizeType()),
10201 ResultStr.size() + 1);
10202 QualType ArrayTy = Info.Ctx.getConstantArrayType(
10203 CharTy, Size,
nullptr, ArraySizeModifier::Normal, 0);
10205 StringLiteral *SL =
10206 StringLiteral::Create(Info.Ctx, ResultStr, StringLiteralKind::Ordinary,
10209 evaluateLValue(SL,
Result);
10219 bool InvalidBaseOK) {
10222 return PointerExprEvaluator(Info,
Result, InvalidBaseOK).Visit(E);
10225bool PointerExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
10228 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
10230 const Expr *PExp = E->
getLHS();
10231 const Expr *IExp = E->
getRHS();
10233 std::swap(PExp, IExp);
10235 bool EvalPtrOK = evaluatePointer(PExp,
Result);
10236 if (!EvalPtrOK && !Info.noteFailure())
10239 llvm::APSInt Offset;
10250bool PointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
10258 if (!Info.getLangOpts().CPlusPlus) {
10260 if (
const auto *Deref = dyn_cast<UnaryOperator>(Sub);
10261 Deref && Deref->getOpcode() == UO_Deref)
10262 return evaluatePointer(Deref->getSubExpr(),
Result);
10272 if (!FnII || !FnII->
isStr(
"current"))
10275 const auto *RD = dyn_cast<RecordDecl>(FD->
getParent());
10283bool PointerExprEvaluator::VisitCastExpr(
const CastExpr *E) {
10290 case CK_CPointerToObjCPointerCast:
10291 case CK_BlockPointerToObjCPointerCast:
10292 case CK_AnyPointerToBlockPointerCast:
10293 case CK_AddressSpaceConversion:
10294 if (!Visit(SubExpr))
10300 CCEDiag(E, diag::note_constexpr_invalid_cast)
10301 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
10302 << Info.Ctx.getLangOpts().CPlusPlus;
10303 Result.Designator.setInvalid();
10311 bool HasValidResult = !
Result.InvalidBase && !
Result.Designator.Invalid &&
10313 bool VoidPtrCastMaybeOK =
10316 Info.Ctx.hasSimilarType(
Result.Designator.getType(Info.Ctx),
10325 if (VoidPtrCastMaybeOK &&
10326 (Info.getStdAllocatorCaller(
"allocate") ||
10328 Info.getLangOpts().CPlusPlus26)) {
10332 Info.getLangOpts().CPlusPlus) {
10333 if (HasValidResult)
10334 CCEDiag(E, diag::note_constexpr_invalid_void_star_cast)
10335 << SubExpr->
getType() << Info.getLangOpts().CPlusPlus26
10336 <<
Result.Designator.getType(Info.Ctx).getCanonicalType()
10339 CCEDiag(E, diag::note_constexpr_invalid_cast)
10340 << diag::ConstexprInvalidCastKind::CastFrom
10343 CCEDiag(E, diag::note_constexpr_invalid_cast)
10344 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
10345 << Info.Ctx.getLangOpts().CPlusPlus;
10346 Result.Designator.setInvalid();
10350 ZeroInitialization(E);
10353 case CK_DerivedToBase:
10354 case CK_UncheckedDerivedToBase:
10366 case CK_BaseToDerived:
10378 case CK_NullToPointer:
10380 return ZeroInitialization(E);
10382 case CK_IntegralToPointer: {
10383 CCEDiag(E, diag::note_constexpr_invalid_cast)
10384 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
10385 << Info.Ctx.getLangOpts().CPlusPlus;
10391 if (
Value.isInt()) {
10392 unsigned Size = Info.Ctx.getTypeSize(E->
getType());
10393 uint64_t N =
Value.getInt().extOrTrunc(Size).getZExtValue();
10394 if (N == Info.Ctx.getTargetNullPointerValue(E->
getType())) {
10397 Result.Base = (Expr *)
nullptr;
10398 Result.InvalidBase =
false;
10400 Result.Designator.setInvalid();
10401 Result.IsNullPtr =
false;
10409 if (!
Value.isLValue())
10418 case CK_ArrayToPointerDecay: {
10420 if (!evaluateLValue(SubExpr,
Result))
10424 SubExpr, SubExpr->
getType(), ScopeKind::FullExpression,
Result);
10429 auto *AT = Info.Ctx.getAsArrayType(SubExpr->
getType());
10430 if (
auto *CAT = dyn_cast<ConstantArrayType>(AT))
10431 Result.addArray(Info, E, CAT);
10433 Result.addUnsizedArray(Info, E, AT->getElementType());
10437 case CK_FunctionToPointerDecay:
10438 return evaluateLValue(SubExpr,
Result);
10440 case CK_LValueToRValue: {
10449 return InvalidBaseOK &&
10455 return ExprEvaluatorBaseTy::VisitCastExpr(E);
10459 UnaryExprOrTypeTrait ExprKind) {
10463 T =
T.getNonReferenceType();
10465 if (
T.getQualifiers().hasUnaligned())
10468 const bool AlignOfReturnsPreferred =
10474 if (ExprKind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
10477 else if (ExprKind == UETT_AlignOf)
10480 llvm_unreachable(
"GetAlignOfType on a non-alignment ExprKind");
10495 unsigned BuiltinOp) {
10519 switch (OwningTarget->
getTriple().getArch()) {
10520 case llvm::Triple::x86:
10521 case llvm::Triple::x86_64:
10534 UnaryExprOrTypeTrait ExprKind) {
10543 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
10547 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(E))
10556 return Info.Ctx.getDeclAlign(VD);
10557 if (
const auto *E =
Value.Base.dyn_cast<
const Expr *>())
10565 EvalInfo &Info,
APSInt &Alignment) {
10568 if (Alignment < 0 || !Alignment.isPowerOf2()) {
10569 Info.FFDiag(E, diag::note_constexpr_invalid_alignment) << Alignment;
10572 unsigned SrcWidth = Info.Ctx.getIntWidth(ForType);
10573 APSInt MaxValue(APInt::getOneBitSet(SrcWidth, SrcWidth - 1));
10574 if (APSInt::compareValues(Alignment, MaxValue) > 0) {
10575 Info.FFDiag(E, diag::note_constexpr_alignment_too_big)
10576 << MaxValue << ForType << Alignment;
10582 APSInt(Alignment.zextOrTrunc(SrcWidth),
true);
10583 assert(APSInt::compareValues(Alignment, ExtAlignment) == 0 &&
10584 "Alignment should not be changed by ext/trunc");
10585 Alignment = ExtAlignment;
10586 assert(Alignment.getBitWidth() == SrcWidth);
10591bool PointerExprEvaluator::visitNonBuiltinCallExpr(
const CallExpr *E) {
10592 if (ExprEvaluatorBaseTy::VisitCallExpr(E))
10600 Result.addUnsizedArray(Info, E, PointeeTy);
10604bool PointerExprEvaluator::VisitCallExpr(
const CallExpr *E) {
10605 if (!IsConstantEvaluatedBuiltinCall(E))
10606 return visitNonBuiltinCallExpr(E);
10613 return T->isCharType() ||
T->isChar8Type();
10616bool PointerExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *E,
10617 unsigned BuiltinOp) {
10621 switch (BuiltinOp) {
10622 case Builtin::BIaddressof:
10623 case Builtin::BI__addressof:
10624 case Builtin::BI__builtin_addressof:
10626 case Builtin::BI__builtin_assume_aligned: {
10633 LValue OffsetResult(
Result);
10645 int64_t AdditionalOffset = -Offset.getZExtValue();
10650 if (OffsetResult.Base) {
10653 if (BaseAlignment < Align) {
10654 Result.Designator.setInvalid();
10655 CCEDiag(E->
getArg(0), diag::note_constexpr_baa_insufficient_alignment)
10662 if (OffsetResult.Offset.alignTo(Align) != OffsetResult.Offset) {
10663 Result.Designator.setInvalid();
10667 diag::note_constexpr_baa_insufficient_alignment)
10670 diag::note_constexpr_baa_value_insufficient_alignment))
10671 << OffsetResult.Offset.getQuantity() << Align.
getQuantity();
10677 case Builtin::BI__builtin_align_up:
10678 case Builtin::BI__builtin_align_down: {
10698 assert(Alignment.getBitWidth() <= 64 &&
10699 "Cannot handle > 64-bit address-space");
10700 uint64_t Alignment64 = Alignment.getZExtValue();
10702 BuiltinOp == Builtin::BI__builtin_align_down
10703 ? llvm::alignDown(
Result.Offset.getQuantity(), Alignment64)
10704 : llvm::alignTo(
Result.Offset.getQuantity(), Alignment64));
10710 Info.FFDiag(E->
getArg(0), diag::note_constexpr_alignment_adjust)
10714 case Builtin::BI__builtin_operator_new:
10716 case Builtin::BI__builtin_launder:
10718 case Builtin::BIstrchr:
10719 case Builtin::BIwcschr:
10720 case Builtin::BImemchr:
10721 case Builtin::BIwmemchr:
10722 if (Info.getLangOpts().CPlusPlus11)
10723 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
10725 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
10727 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
10729 case Builtin::BI__builtin_strchr:
10730 case Builtin::BI__builtin_wcschr:
10731 case Builtin::BI__builtin_memchr:
10732 case Builtin::BI__builtin_char_memchr:
10733 case Builtin::BI__builtin_wmemchr: {
10734 if (!Visit(E->
getArg(0)))
10740 if (BuiltinOp != Builtin::BIstrchr &&
10741 BuiltinOp != Builtin::BIwcschr &&
10742 BuiltinOp != Builtin::BI__builtin_strchr &&
10743 BuiltinOp != Builtin::BI__builtin_wcschr) {
10747 MaxLength = N.getZExtValue();
10750 if (MaxLength == 0u)
10751 return ZeroInitialization(E);
10752 if (!
Result.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
10753 Result.Designator.Invalid)
10755 QualType CharTy =
Result.Designator.getType(Info.Ctx);
10756 bool IsRawByte = BuiltinOp == Builtin::BImemchr ||
10757 BuiltinOp == Builtin::BI__builtin_memchr;
10758 assert(IsRawByte ||
10759 Info.Ctx.hasSameUnqualifiedType(
10763 Info.FFDiag(E, diag::note_constexpr_ltor_incomplete_type) << CharTy;
10769 Info.FFDiag(E, diag::note_constexpr_memchr_unsupported)
10770 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp) << CharTy;
10776 bool StopAtNull =
false;
10777 switch (BuiltinOp) {
10778 case Builtin::BIstrchr:
10779 case Builtin::BI__builtin_strchr:
10786 return ZeroInitialization(E);
10789 case Builtin::BImemchr:
10790 case Builtin::BI__builtin_memchr:
10791 case Builtin::BI__builtin_char_memchr:
10795 DesiredVal = Desired.trunc(Info.Ctx.getCharWidth()).getZExtValue();
10798 case Builtin::BIwcschr:
10799 case Builtin::BI__builtin_wcschr:
10802 case Builtin::BIwmemchr:
10803 case Builtin::BI__builtin_wmemchr:
10805 DesiredVal = Desired.getZExtValue();
10809 for (; MaxLength; --MaxLength) {
10814 if (Char.
getInt().getZExtValue() == DesiredVal)
10816 if (StopAtNull && !Char.
getInt())
10822 return ZeroInitialization(E);
10825 case Builtin::BImemcpy:
10826 case Builtin::BImemmove:
10827 case Builtin::BIwmemcpy:
10828 case Builtin::BIwmemmove:
10829 if (Info.getLangOpts().CPlusPlus11)
10830 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
10832 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
10834 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
10836 case Builtin::BI__builtin_memcpy:
10837 case Builtin::BI__builtin_memmove:
10838 case Builtin::BI__builtin_wmemcpy:
10839 case Builtin::BI__builtin_wmemmove: {
10840 bool WChar = BuiltinOp == Builtin::BIwmemcpy ||
10841 BuiltinOp == Builtin::BIwmemmove ||
10842 BuiltinOp == Builtin::BI__builtin_wmemcpy ||
10843 BuiltinOp == Builtin::BI__builtin_wmemmove;
10844 bool Move = BuiltinOp == Builtin::BImemmove ||
10845 BuiltinOp == Builtin::BIwmemmove ||
10846 BuiltinOp == Builtin::BI__builtin_memmove ||
10847 BuiltinOp == Builtin::BI__builtin_wmemmove;
10850 if (!Visit(E->
getArg(0)))
10861 assert(!N.isSigned() &&
"memcpy and friends take an unsigned size");
10871 if (!Src.Base || !Dest.Base) {
10873 (!Src.Base ? Src : Dest).moveInto(Val);
10874 Info.FFDiag(E, diag::note_constexpr_memcpy_null)
10875 <<
Move << WChar << !!Src.Base
10879 if (Src.Designator.Invalid || Dest.Designator.Invalid)
10885 QualType
T = Dest.Designator.getType(Info.Ctx);
10886 QualType SrcT = Src.Designator.getType(Info.Ctx);
10887 if (!Info.Ctx.hasSameUnqualifiedType(
T, SrcT)) {
10889 Info.FFDiag(E, diag::note_constexpr_memcpy_type_pun) <<
Move << SrcT <<
T;
10893 Info.FFDiag(E, diag::note_constexpr_memcpy_incomplete_type) <<
Move <<
T;
10896 if (!
T.isTriviallyCopyableType(Info.Ctx)) {
10897 Info.FFDiag(E, diag::note_constexpr_memcpy_nontrivial) <<
Move <<
T;
10902 uint64_t TSize = Info.Ctx.getTypeSizeInChars(
T).getQuantity();
10907 llvm::APInt OrigN = N;
10908 llvm::APInt::udivrem(OrigN, TSize, N, Remainder);
10910 Info.FFDiag(E, diag::note_constexpr_memcpy_unsupported)
10912 << (unsigned)TSize;
10920 uint64_t RemainingSrcSize = Src.Designator.validIndexAdjustments().second;
10921 uint64_t RemainingDestSize = Dest.Designator.validIndexAdjustments().second;
10922 if (N.ugt(RemainingSrcSize) || N.ugt(RemainingDestSize)) {
10923 Info.FFDiag(E, diag::note_constexpr_memcpy_unsupported)
10924 <<
Move << WChar << (N.ugt(RemainingSrcSize) ? 1 : 2) <<
T
10928 uint64_t NElems = N.getZExtValue();
10934 uint64_t SrcOffset = Src.getLValueOffset().getQuantity();
10935 uint64_t DestOffset = Dest.getLValueOffset().getQuantity();
10936 if (DestOffset >= SrcOffset && DestOffset - SrcOffset < NBytes) {
10939 Info.FFDiag(E, diag::note_constexpr_memcpy_overlap) << WChar;
10947 }
else if (!Move && SrcOffset >= DestOffset &&
10948 SrcOffset - DestOffset < NBytes) {
10950 Info.FFDiag(E, diag::note_constexpr_memcpy_overlap) << WChar;
10979 QualType AllocType);
10982 const CXXConstructExpr *CCE,
10983 QualType AllocType);
10985bool PointerExprEvaluator::VisitCXXNewExpr(
const CXXNewExpr *E) {
10986 if (!Info.getLangOpts().CPlusPlus20)
10987 Info.CCEDiag(E, diag::note_constexpr_new);
10990 if (Info.SpeculativeEvaluationDepth)
10995 QualType TargetType = AllocType;
10997 bool IsNothrow =
false;
10998 bool IsPlacement =
false;
11016 }
else if (OperatorNew->isReservedGlobalPlacementOperator()) {
11017 if (Info.CurrentCall->isStdFunction() || Info.getLangOpts().CPlusPlus26 ||
11018 (Info.CurrentCall->CanEvalMSConstexpr &&
11019 OperatorNew->hasAttr<MSConstexprAttr>())) {
11022 if (
Result.Designator.Invalid)
11025 IsPlacement =
true;
11027 Info.FFDiag(E, diag::note_constexpr_new_placement)
11032 Info.FFDiag(E, diag::note_constexpr_new_placement)
11035 }
else if (!OperatorNew
11036 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
11037 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
11043 const InitListExpr *ResizedArrayILE =
nullptr;
11044 const CXXConstructExpr *ResizedArrayCCE =
nullptr;
11045 bool ValueInit =
false;
11047 if (std::optional<const Expr *> ArraySize = E->
getArraySize()) {
11048 const Expr *Stripped = *ArraySize;
11049 for (;
auto *ICE = dyn_cast<ImplicitCastExpr>(Stripped);
11050 Stripped = ICE->getSubExpr())
11051 if (ICE->getCastKind() != CK_NoOp &&
11052 ICE->getCastKind() != CK_IntegralCast)
11065 return ZeroInitialization(E);
11067 Info.FFDiag(*ArraySize, diag::note_constexpr_new_negative)
11068 <<
ArrayBound << (*ArraySize)->getSourceRange();
11074 if (!Info.CheckArraySize(ArraySize.value()->getExprLoc(),
11079 return ZeroInitialization(E);
11091 }
else if (
auto *CCE = dyn_cast<CXXConstructExpr>(
Init)) {
11092 ResizedArrayCCE = CCE;
11094 auto *CAT = Info.Ctx.getAsConstantArrayType(
Init->getType());
11095 assert(CAT &&
"unexpected type for array initializer");
11099 llvm::APInt InitBound = CAT->
getSize().zext(Bits);
11100 llvm::APInt AllocBound =
ArrayBound.zext(Bits);
11101 if (InitBound.ugt(AllocBound)) {
11103 return ZeroInitialization(E);
11105 Info.FFDiag(*ArraySize, diag::note_constexpr_new_too_small)
11106 <<
toString(AllocBound, 10,
false)
11108 << (*ArraySize)->getSourceRange();
11114 if (InitBound != AllocBound)
11118 AllocType = Info.Ctx.getConstantArrayType(AllocType,
ArrayBound,
nullptr,
11119 ArraySizeModifier::Normal, 0);
11129 "array allocation with non-array new");
11135 struct FindObjectHandler {
11138 QualType AllocType;
11142 typedef bool result_type;
11143 bool failed() {
return false; }
11144 bool checkConst(QualType QT) {
11146 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
11151 bool found(
APValue &Subobj, QualType SubobjType,
11152 APValue::LValueBase Base) {
11153 if (!checkConst(SubobjType))
11157 if (!Info.Ctx.hasSimilarType(SubobjType, AllocType)) {
11158 Info.FFDiag(E, diag::note_constexpr_placement_new_wrong_type)
11159 << SubobjType << AllocType;
11166 Info.FFDiag(E, diag::note_constexpr_construct_complex_elem);
11169 bool found(APFloat &
Value, QualType SubobjType) {
11170 Info.FFDiag(E, diag::note_constexpr_construct_complex_elem);
11173 } Handler = {Info, E, AllocType, AK,
nullptr};
11176 Result.Designator.MostDerivedIsArrayElement &&
11177 Result.Designator.Entries.back().getAsArrayIndex() == 0) {
11182 QualType AllocElementType =
11183 Info.Ctx.getAsArrayType(AllocType)->getElementType();
11184 if (Info.Ctx.hasSimilarType(AllocElementType,
11185 Result.Designator.MostDerivedType)) {
11187 Result.Designator.MostDerivedPathLength - 1);
11195 Val = Handler.Value;
11204 Val = Info.createHeapAlloc(E, AllocType,
Result);
11210 ImplicitValueInitExpr VIE(AllocType);
11213 }
else if (ResizedArrayILE) {
11217 }
else if (ResizedArrayCCE) {
11240class MemberPointerExprEvaluator
11241 :
public ExprEvaluatorBase<MemberPointerExprEvaluator> {
11244 bool Success(
const ValueDecl *D) {
11250 MemberPointerExprEvaluator(EvalInfo &Info, MemberPtr &
Result)
11257 bool ZeroInitialization(
const Expr *E) {
11258 return Success((
const ValueDecl*)
nullptr);
11261 bool VisitCastExpr(
const CastExpr *E);
11262 bool VisitUnaryAddrOf(
const UnaryOperator *E);
11270 return MemberPointerExprEvaluator(Info,
Result).Visit(E);
11273bool MemberPointerExprEvaluator::VisitCastExpr(
const CastExpr *E) {
11276 return ExprEvaluatorBaseTy::VisitCastExpr(E);
11278 case CK_NullToMemberPointer:
11280 return ZeroInitialization(E);
11282 case CK_BaseToDerivedMemberPointer: {
11290 typedef std::reverse_iterator<CastExpr::path_const_iterator> ReverseIter;
11292 PathI != PathE; ++PathI) {
11293 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
11294 const CXXRecordDecl *Derived = (*PathI)->getType()->getAsCXXRecordDecl();
11295 if (!
Result.castToDerived(Derived))
11299 ->
castAs<MemberPointerType>()
11300 ->getMostRecentCXXRecordDecl()))
11305 case CK_DerivedToBaseMemberPointer:
11309 PathE = E->
path_end(); PathI != PathE; ++PathI) {
11310 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
11311 const CXXRecordDecl *
Base = (*PathI)->getType()->getAsCXXRecordDecl();
11312 if (!
Result.castToBase(Base))
11319bool MemberPointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
11330 class RecordExprEvaluator
11331 :
public ExprEvaluatorBase<RecordExprEvaluator> {
11332 const LValue &
This;
11336 RecordExprEvaluator(EvalInfo &info,
const LValue &This,
APValue &
Result)
11343 bool ZeroInitialization(
const Expr *E) {
11344 return ZeroInitialization(E, E->
getType());
11346 bool ZeroInitialization(
const Expr *E, QualType
T);
11348 bool VisitCallExpr(
const CallExpr *E) {
11349 return handleCallExpr(E,
Result, &This);
11351 bool VisitCastExpr(
const CastExpr *E);
11352 bool VisitInitListExpr(
const InitListExpr *E);
11353 bool VisitCXXConstructExpr(
const CXXConstructExpr *E) {
11354 return VisitCXXConstructExpr(E, E->
getType());
11357 bool VisitCXXInheritedCtorInitExpr(
const CXXInheritedCtorInitExpr *E);
11358 bool VisitCXXConstructExpr(
const CXXConstructExpr *E, QualType
T);
11359 bool VisitCXXStdInitializerListExpr(
const CXXStdInitializerListExpr *E);
11360 bool VisitBinCmp(
const BinaryOperator *E);
11361 bool VisitCXXParenListInitExpr(
const CXXParenListInitExpr *E);
11362 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
11363 ArrayRef<Expr *> Args);
11364 bool VisitDesignatedInitUpdateExpr(
const DesignatedInitUpdateExpr *E);
11378 bool IsCompleteClass =
true) {
11379 assert(!RD->
isUnion() &&
"Expected non-union class type");
11383 unsigned NonVirtualBases = countNonVirtualBases(CD);
11395 unsigned Index = 0;
11397 for (
const auto &B : CD->
bases()) {
11401 LValue Subobject =
This;
11405 Result.getStructBase(Index),
11412 for (
const auto *I : RD->
fields()) {
11414 if (I->isUnnamedBitField() || I->getType()->isReferenceType())
11417 LValue Subobject =
This;
11423 Result.getStructField(I->getFieldIndex()), Info, Subobject, &VIE))
11427 if (CD &&
This.pointsToCompleteClass(CD)) {
11428 unsigned Index = 0;
11429 for (
const auto &B : CD->
vbases()) {
11431 LValue Subobject =
This;
11435 Result.getStructVirtualBase(Index),
11445bool RecordExprEvaluator::ZeroInitialization(
const Expr *E, QualType
T) {
11452 while (I != RD->
field_end() && (*I)->isUnnamedBitField())
11459 LValue Subobject =
This;
11463 ImplicitValueInitExpr VIE(I->getType());
11467 if (!Info.getLangOpts().CPlusPlus26) {
11468 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
11469 CXXRD && CXXRD->getNumVBases()) {
11470 Info.FFDiag(E, diag::note_constexpr_virtual_base) << RD;
11478bool RecordExprEvaluator::VisitCastExpr(
const CastExpr *E) {
11481 return ExprEvaluatorBaseTy::VisitCastExpr(E);
11483 case CK_ConstructorConversion:
11486 case CK_DerivedToBase:
11487 case CK_UncheckedDerivedToBase: {
11498 PathE = E->
path_end(); PathI != PathE; ++PathI) {
11499 assert(!(*PathI)->isVirtual() &&
"record rvalue with virtual base");
11500 const CXXRecordDecl *
Base = (*PathI)->getType()->getAsCXXRecordDecl();
11507 case CK_HLSLAggregateSplatCast: {
11527 case CK_HLSLElementwiseCast: {
11545 LValue Subobject =
This;
11552 if (
Field->isBitField()) {
11562bool RecordExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
11565 return VisitCXXParenListOrInitListExpr(E, E->
inits());
11568bool RecordExprEvaluator::VisitCXXParenListOrInitListExpr(
11572 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD);
11573 auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
11575 EvalInfo::EvaluatingConstructorRAII EvalObj(
11577 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries},
11578 CXXRD && CXXRD->getNumBases());
11581 const FieldDecl *
Field;
11582 if (
auto *ILE = dyn_cast<InitListExpr>(ExprToVisit)) {
11583 Field = ILE->getInitializedFieldInUnion();
11584 }
else if (
auto *PLIE = dyn_cast<CXXParenListInitExpr>(ExprToVisit)) {
11585 Field = PLIE->getInitializedFieldInUnion();
11588 "Expression is neither an init list nor a C++ paren list");
11600 ImplicitValueInitExpr VIE(
Field->getType());
11601 const Expr *InitExpr = Args.empty() ? &VIE : Args[0];
11603 LValue Subobject =
This;
11608 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
11612 if (
Field->isBitField())
11622 Result =
APValue(APValue::UninitStruct(), CXXRD ? CXXRD->getNumBases() : 0,
11624 unsigned ElementNo = 0;
11628 if (CXXRD && CXXRD->getNumBases()) {
11629 for (
const auto &Base : CXXRD->bases()) {
11630 assert(ElementNo < Args.size() &&
"missing init for base class");
11631 const Expr *
Init = Args[ElementNo];
11633 LValue Subobject =
This;
11639 if (!Info.noteFailure())
11646 EvalObj.finishedConstructingBases();
11650 for (
const auto *Field : RD->
fields()) {
11653 if (
Field->isUnnamedBitField())
11656 LValue Subobject =
This;
11658 bool HaveInit = ElementNo < Args.size();
11663 Subobject, Field, &Layout))
11668 ImplicitValueInitExpr VIE(HaveInit ? Info.Ctx.IntTy :
Field->getType());
11669 const Expr *
Init = HaveInit ? Args[ElementNo++] : &VIE;
11676 if (
Field->getType()->isIncompleteArrayType()) {
11677 if (
auto *CAT = Info.Ctx.getAsConstantArrayType(
Init->getType())) {
11681 Info.FFDiag(
Init, diag::note_constexpr_unsupported_flexible_array);
11688 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
11692 if (
Field->getType()->isReferenceType()) {
11696 if (!Info.noteFailure())
11701 (
Field->isBitField() &&
11703 if (!Info.noteFailure())
11709 EvalObj.finishedConstructingFields();
11714bool RecordExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E,
11724 return ZeroInitialization(E,
T);
11742 const Expr *SrcObj = E->
getArg(0);
11744 assert(Info.Ctx.hasSameUnqualifiedType(E->
getType(), SrcObj->
getType()));
11745 if (
const MaterializeTemporaryExpr *ME =
11746 dyn_cast<MaterializeTemporaryExpr>(SrcObj))
11747 return Visit(ME->getSubExpr());
11750 if (ZeroInit && !ZeroInitialization(E,
T))
11759bool RecordExprEvaluator::VisitCXXInheritedCtorInitExpr(
11760 const CXXInheritedCtorInitExpr *E) {
11761 if (!Info.CurrentCall) {
11762 assert(Info.checkingPotentialConstantExpression());
11781bool RecordExprEvaluator::VisitCXXStdInitializerListExpr(
11782 const CXXStdInitializerListExpr *E) {
11783 const ConstantArrayType *ArrayType =
11790 assert(ArrayType &&
"unexpected type for array initializer");
11793 Array.addArray(Info, E, ArrayType);
11801 assert(Field !=
Record->field_end() &&
11802 Info.Ctx.hasSameType(
Field->getType()->getPointeeType(),
11804 "Expected std::initializer_list first field to be const E *");
11806 assert(Field !=
Record->field_end() &&
11807 "Expected std::initializer_list to have two fields");
11809 if (Info.Ctx.hasSameType(
Field->getType(), Info.Ctx.getSizeType())) {
11814 assert(Info.Ctx.hasSameType(
Field->getType()->getPointeeType(),
11816 "Expected std::initializer_list second field to be const E *");
11824 assert(++Field ==
Record->field_end() &&
11825 "Expected std::initializer_list to only have two fields");
11830bool RecordExprEvaluator::VisitLambdaExpr(
const LambdaExpr *E) {
11835 const size_t NumFields = ClosureClass->
getNumFields();
11839 "The number of lambda capture initializers should equal the number of "
11840 "fields within the closure type");
11847 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(ClosureClass);
11848 for (
const auto *Field : ClosureClass->
fields()) {
11851 Expr *
const CurFieldInit = *CaptureInitIt++;
11858 LValue Subobject =
This;
11865 if (!Info.keepEvaluatingAfterFailure())
11873bool RecordExprEvaluator::VisitDesignatedInitUpdateExpr(
11874 const DesignatedInitUpdateExpr *E) {
11884 "can't evaluate expression as a record rvalue");
11885 return RecordExprEvaluator(Info,
This,
Result).Visit(E);
11896class TemporaryExprEvaluator
11897 :
public LValueExprEvaluatorBase<TemporaryExprEvaluator> {
11899 TemporaryExprEvaluator(EvalInfo &Info, LValue &
Result) :
11900 LValueExprEvaluatorBaseTy(Info,
Result,
false) {}
11903 bool VisitConstructExpr(
const Expr *E) {
11909 bool VisitCastExpr(
const CastExpr *E) {
11912 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
11914 case CK_ConstructorConversion:
11918 bool VisitInitListExpr(
const InitListExpr *E) {
11919 return VisitConstructExpr(E);
11921 bool VisitCXXConstructExpr(
const CXXConstructExpr *E) {
11922 return VisitConstructExpr(E);
11924 bool VisitCallExpr(
const CallExpr *E) {
11925 return VisitConstructExpr(E);
11927 bool VisitCXXStdInitializerListExpr(
const CXXStdInitializerListExpr *E) {
11928 return VisitConstructExpr(E);
11931 return VisitConstructExpr(E);
11940 return TemporaryExprEvaluator(Info,
Result).Visit(E);
11948 class VectorExprEvaluator
11949 :
public ExprEvaluatorBase<VectorExprEvaluator> {
11956 bool Success(ArrayRef<APValue>
V,
const Expr *E) {
11957 assert(
V.size() == E->
getType()->
castAs<VectorType>()->getNumElements());
11963 assert(
V.isVector());
11967 bool ZeroInitialization(
const Expr *E);
11969 bool VisitUnaryReal(
const UnaryOperator *E)
11971 bool VisitCastExpr(
const CastExpr* E);
11972 bool VisitInitListExpr(
const InitListExpr *E);
11973 bool VisitUnaryImag(
const UnaryOperator *E);
11974 bool VisitBinaryOperator(
const BinaryOperator *E);
11975 bool VisitUnaryOperator(
const UnaryOperator *E);
11976 bool VisitCallExpr(
const CallExpr *E);
11977 bool VisitConvertVectorExpr(
const ConvertVectorExpr *E);
11978 bool VisitShuffleVectorExpr(
const ShuffleVectorExpr *E);
11987 "not a vector prvalue");
11988 return VectorExprEvaluator(Info,
Result).Visit(E);
11992 assert(Val.
isVector() &&
"expected vector APValue");
11996 llvm::APInt
Result(NumElts, 0);
11998 for (
unsigned I = 0; I < NumElts; ++I) {
12000 assert(Elt.
isInt() &&
"expected integer element in bool vector");
12002 if (Elt.
getInt().getBoolValue())
12009bool VectorExprEvaluator::VisitCastExpr(
const CastExpr *E) {
12010 const VectorType *VTy = E->
getType()->
castAs<VectorType>();
12014 QualType SETy = SE->
getType();
12017 case CK_VectorSplat: {
12023 Val =
APValue(std::move(IntResult));
12028 Val =
APValue(std::move(FloatResult));
12045 Info.FFDiag(E, diag::note_constexpr_invalid_cast)
12046 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
12047 << Info.Ctx.getLangOpts().CPlusPlus;
12051 if (!handleRValueToRValueBitCast(Info,
Result, SVal, E))
12056 case CK_HLSLVectorTruncation: {
12061 for (
unsigned I = 0; I < NElts; I++)
12065 case CK_HLSLMatrixTruncation: {
12071 for (
unsigned Row = 0;
12073 for (
unsigned Col = 0;
12078 case CK_HLSLAggregateSplatCast: {
12095 case CK_HLSLElementwiseCast: {
12108 return Success(ResultEls, E);
12110 case CK_IntegralToFloating:
12111 case CK_FloatingToIntegral:
12112 case CK_IntegralCast:
12113 case CK_FloatingCast:
12114 case CK_FloatingToBoolean:
12115 case CK_IntegralToBoolean: {
12117 assert(SETy->
isVectorType() &&
"expected vector source type");
12123 QualType SrcEltTy = SETy->
castAs<VectorType>()->getElementType();
12128 for (
unsigned I = 0; I < NElts; ++I) {
12133 return Success(ResultEls, E);
12136 return ExprEvaluatorBaseTy::VisitCastExpr(E);
12141VectorExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
12158 unsigned CountInits = 0, CountElts = 0;
12159 while (CountElts < NumElements) {
12161 if (CountInits < NumInits
12167 for (
unsigned j = 0; j < vlen; j++)
12171 llvm::APSInt sInt(32);
12172 if (CountInits < NumInits) {
12176 sInt = Info.Ctx.MakeIntValue(0, EltTy);
12177 Elements.push_back(
APValue(sInt));
12180 llvm::APFloat f(0.0);
12181 if (CountInits < NumInits) {
12185 f = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy));
12186 Elements.push_back(
APValue(f));
12195VectorExprEvaluator::ZeroInitialization(
const Expr *E) {
12199 if (EltTy->isIntegerType())
12200 ZeroElement =
APValue(Info.Ctx.MakeIntValue(0, EltTy));
12203 APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy)));
12209bool VectorExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
12211 return ZeroInitialization(E);
12214bool VectorExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
12216 assert(Op != BO_PtrMemD && Op != BO_PtrMemI && Op != BO_Cmp &&
12217 "Operation not supported on vector types");
12219 if (Op == BO_Comma)
12220 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
12222 Expr *LHS = E->
getLHS();
12223 Expr *RHS = E->
getRHS();
12226 "Must both be vector types");
12229 assert(LHS->
getType()->
castAs<VectorType>()->getNumElements() ==
12233 "All operands must be the same size.");
12237 bool LHSOK =
Evaluate(LHSValue, Info, LHS);
12238 if (!LHSOK && !Info.noteFailure())
12240 if (!
Evaluate(RHSValue, Info, RHS) || !LHSOK)
12262 "Vector can only be int or float type");
12270 "Vector operator ~ can only be int");
12271 Elt.
getInt().flipAllBits();
12281 "Vector can only be int or float type");
12287 EltResult.setAllBits();
12289 EltResult.clearAllBits();
12295 return std::nullopt;
12299bool VectorExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
12305 const QualType ResultEltTy = VD->getElementType();
12309 if (!
Evaluate(SubExprValue, Info, SubExpr))
12322 "Vector length doesn't match type?");
12325 for (
unsigned EltNum = 0; EltNum < VD->getNumElements(); ++EltNum) {
12327 Info.Ctx, ResultEltTy, Op, SubExprValue.
getVectorElt(EltNum));
12330 ResultElements.push_back(*Elt);
12332 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12343 DestTy,
Result.getFloat());
12359 DestTy,
Result.getInt());
12363 Info.FFDiag(E, diag::err_convertvector_constexpr_unsupported_vector_cast)
12364 << SourceTy << DestTy;
12369 llvm::function_ref<APInt(
const APSInt &)> PackFn) {
12378 assert(LHSVecLen != 0 && LHSVecLen == RHSVecLen &&
12379 "pack builtin LHSVecLen must equal to RHSVecLen");
12382 const unsigned SrcBits = Info.Ctx.getIntWidth(VT0->
getElementType());
12388 const unsigned SrcPerLane = 128 / SrcBits;
12389 const unsigned Lanes = LHSVecLen * SrcBits / 128;
12392 Out.reserve(LHSVecLen + RHSVecLen);
12394 for (
unsigned Lane = 0; Lane != Lanes; ++Lane) {
12395 unsigned base = Lane * SrcPerLane;
12396 for (
unsigned I = 0; I != SrcPerLane; ++I)
12399 for (
unsigned I = 0; I != SrcPerLane; ++I)
12410 llvm::function_ref<std::pair<unsigned, int>(
unsigned,
unsigned)>
12417 unsigned ShuffleMask = 0;
12419 bool IsVectorMask =
false;
12420 bool IsSingleOperand = (
Call->getNumArgs() == 2);
12422 if (IsSingleOperand) {
12425 IsVectorMask =
true;
12434 ShuffleMask =
static_cast<unsigned>(MaskImm.getZExtValue());
12444 IsVectorMask =
true;
12453 ShuffleMask =
static_cast<unsigned>(MaskImm.getZExtValue());
12464 ResultElements.reserve(NumElts);
12466 for (
unsigned DstIdx = 0; DstIdx != NumElts; ++DstIdx) {
12467 if (IsVectorMask) {
12468 ShuffleMask =
static_cast<unsigned>(
12469 MaskVector.getVectorElt(DstIdx).getInt().getZExtValue());
12471 auto [SrcVecIdx, SrcIdx] = GetSourceIndex(DstIdx, ShuffleMask);
12477 ResultElements.push_back(
12478 APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(ElemTy))));
12484 ResultElements.push_back(
APValue());
12487 const APValue &Src = (SrcVecIdx == 0) ? A : B;
12492 Out =
APValue(ResultElements.data(), ResultElements.size());
12498 if (OrigVal.isInfinity()) {
12499 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << 0;
12502 if (OrigVal.isNaN()) {
12503 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << 1;
12507 APFloat Val = OrigVal;
12508 bool LosesInfo =
false;
12509 APFloat::opStatus Status = Val.convert(
12510 APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven, &LosesInfo);
12512 if (LosesInfo || Val.isDenormal()) {
12513 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic_strict);
12517 if (Status != APFloat::opOK) {
12518 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
12527 llvm::function_ref<APInt(
const APInt &, uint64_t)> ShiftOp,
12528 llvm::function_ref<APInt(
const APInt &,
unsigned)> OverflowOp) {
12535 assert(
Call->getNumArgs() == 2);
12539 Call->getArg(1)->getType()->isVectorType());
12542 unsigned DestEltWidth = Source.getVectorElt(0).getInt().getBitWidth();
12543 unsigned DestLen = Source.getVectorLength();
12546 unsigned NumBitsInQWord = 64;
12547 unsigned NumCountElts = NumBitsInQWord / CountEltWidth;
12549 Result.reserve(DestLen);
12551 uint64_t CountLQWord = 0;
12552 for (
unsigned EltIdx = 0; EltIdx != NumCountElts; ++EltIdx) {
12554 CountLQWord |= (Elt << (EltIdx * CountEltWidth));
12557 for (
unsigned EltIdx = 0; EltIdx != DestLen; ++EltIdx) {
12558 APInt Elt = Source.getVectorElt(EltIdx).getInt();
12559 if (CountLQWord < DestEltWidth) {
12561 APValue(
APSInt(ShiftOp(Elt, CountLQWord), IsDestUnsigned)));
12564 APValue(
APSInt(OverflowOp(Elt, DestEltWidth), IsDestUnsigned)));
12572 std::optional<APSInt> RoundingMode,
12574 APSInt DefaultMode(APInt(32, 4),
true);
12575 if (RoundingMode.value_or(DefaultMode) != 4)
12576 return std::nullopt;
12577 if (A.isNaN() || A.isInfinity() || A.isDenormal() || B.isNaN() ||
12578 B.isInfinity() || B.isDenormal())
12579 return std::nullopt;
12580 if (A.isZero() && B.isZero())
12582 return IsMin ? llvm::minimum(A, B) : llvm::maximum(A, B);
12585bool VectorExprEvaluator::VisitCallExpr(
const CallExpr *E) {
12586 if (!IsConstantEvaluatedBuiltinCall(E))
12587 return ExprEvaluatorBaseTy::VisitCallExpr(E);
12591 auto EvaluateBinOpExpr =
12593 APValue SourceLHS, SourceRHS;
12599 QualType DestEltTy = DestTy->getElementType();
12600 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
12603 ResultElements.reserve(SourceLen);
12605 if (SourceRHS.
isInt()) {
12607 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12609 ResultElements.push_back(
12613 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12616 ResultElements.push_back(
12623 auto EvaluateFpBinOpExpr =
12624 [&](llvm::function_ref<std::optional<APFloat>(
12625 const APFloat &,
const APFloat &, std::optional<APSInt>)>
12627 bool IsScalar =
false) {
12637 std::optional<APSInt> RoundingMode;
12642 RoundingMode = Imm;
12647 ResultElements.reserve(NumElems);
12649 for (
unsigned EltNum = 0; EltNum < NumElems; ++EltNum) {
12650 if (IsScalar && EltNum > 0) {
12656 std::optional<APFloat>
Result =
Fn(EltA, EltB, RoundingMode);
12664 auto EvaluateScalarFpRoundMaskBinOp =
12665 [&](llvm::function_ref<std::optional<APFloat>(
12666 const APFloat &,
const APFloat &, std::optional<APSInt>)>
12670 APSInt MaskVal, Rounding;
12681 ResultElements.reserve(NumElems);
12683 if (MaskVal.getZExtValue() & 1) {
12686 std::optional<APFloat>
Result =
Fn(EltA, EltB, Rounding);
12694 for (
unsigned I = 1; I < NumElems; ++I)
12700 auto EvalSelectScalar = [&](
unsigned Len) ->
bool {
12708 bool TakeA0 = (Mask.getZExtValue() & 1u) != 0;
12712 for (
unsigned I = 1; I < Len; ++I)
12714 APValue V(Res.data(), Res.size());
12718 auto EvalVectorDotProduct = [&](
bool IsSaturating) ->
bool {
12719 APValue Source, OperandA, OperandB;
12728 unsigned ElemsPerLane = NumOperandElems / NumSrcElems;
12733 Result.reserve(NumSrcElems);
12734 for (
unsigned I = 0; I != NumSrcElems; ++I) {
12736 DotProduct = DotProduct.extend(64);
12737 for (
unsigned J = 0; J != ElemsPerLane; ++J) {
12744 DotProduct += OpA * OpB;
12746 if (IsSaturating) {
12747 DotProduct =
APSInt(DotProduct.truncSSat(32),
false);
12749 DotProduct =
APSInt(DotProduct.trunc(32),
false);
12757 switch (BuiltinOp) {
12760 case Builtin::BI__builtin_elementwise_popcount:
12761 case Builtin::BI__builtin_elementwise_bitreverse: {
12766 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12769 ResultElements.reserve(SourceLen);
12771 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12773 switch (BuiltinOp) {
12774 case Builtin::BI__builtin_elementwise_popcount:
12775 ResultElements.push_back(
APValue(
12776 APSInt(
APInt(Info.Ctx.getIntWidth(DestEltTy), Elt.popcount()),
12779 case Builtin::BI__builtin_elementwise_bitreverse:
12780 ResultElements.push_back(
12787 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12789 case Builtin::BI__builtin_elementwise_abs: {
12794 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12797 ResultElements.reserve(SourceLen);
12799 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12804 CurrentEle.getInt().
abs(),
12805 DestEltTy->isUnsignedIntegerOrEnumerationType()));
12806 ResultElements.push_back(Val);
12809 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12812 case Builtin::BI__builtin_elementwise_add_sat:
12813 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12814 return LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS);
12817 case Builtin::BI__builtin_elementwise_sub_sat:
12818 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12819 return LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
12822 case X86::BI__builtin_ia32_extract128i256:
12823 case X86::BI__builtin_ia32_vextractf128_pd256:
12824 case X86::BI__builtin_ia32_vextractf128_ps256:
12825 case X86::BI__builtin_ia32_vextractf128_si256: {
12826 APValue SourceVec, SourceImm;
12835 unsigned RetLen = RetVT->getNumElements();
12836 unsigned Idx = SourceImm.
getInt().getZExtValue() & 1;
12839 ResultElements.reserve(RetLen);
12841 for (
unsigned I = 0; I < RetLen; I++)
12842 ResultElements.push_back(SourceVec.
getVectorElt(Idx * RetLen + I));
12847 case clang::X86::BI__builtin_ia32_cvtmask2b128:
12848 case clang::X86::BI__builtin_ia32_cvtmask2b256:
12849 case clang::X86::BI__builtin_ia32_cvtmask2b512:
12850 case clang::X86::BI__builtin_ia32_cvtmask2w128:
12851 case clang::X86::BI__builtin_ia32_cvtmask2w256:
12852 case clang::X86::BI__builtin_ia32_cvtmask2w512:
12853 case clang::X86::BI__builtin_ia32_cvtmask2d128:
12854 case clang::X86::BI__builtin_ia32_cvtmask2d256:
12855 case clang::X86::BI__builtin_ia32_cvtmask2d512:
12856 case clang::X86::BI__builtin_ia32_cvtmask2q128:
12857 case clang::X86::BI__builtin_ia32_cvtmask2q256:
12858 case clang::X86::BI__builtin_ia32_cvtmask2q512: {
12864 QualType VecTy = E->
getType();
12865 const VectorType *VT = VecTy->
castAs<VectorType>();
12868 unsigned ElemWidth = Info.Ctx.getTypeSize(ElemTy);
12871 for (
unsigned I = 0; I != VectorLen; ++I) {
12872 bool BitSet = Mask[I];
12873 APSInt ElemVal(ElemWidth,
false);
12875 ElemVal.setAllBits();
12877 Elems.push_back(
APValue(ElemVal));
12882 case X86::BI__builtin_ia32_extracti32x4_256_mask:
12883 case X86::BI__builtin_ia32_extractf32x4_256_mask:
12884 case X86::BI__builtin_ia32_extracti32x4_mask:
12885 case X86::BI__builtin_ia32_extractf32x4_mask:
12886 case X86::BI__builtin_ia32_extracti32x8_mask:
12887 case X86::BI__builtin_ia32_extractf32x8_mask:
12888 case X86::BI__builtin_ia32_extracti64x2_256_mask:
12889 case X86::BI__builtin_ia32_extractf64x2_256_mask:
12890 case X86::BI__builtin_ia32_extracti64x2_512_mask:
12891 case X86::BI__builtin_ia32_extractf64x2_512_mask:
12892 case X86::BI__builtin_ia32_extracti64x4_mask:
12893 case X86::BI__builtin_ia32_extractf64x4_mask: {
12904 unsigned RetLen = RetVT->getNumElements();
12909 unsigned Lanes = SrcLen / RetLen;
12910 unsigned Lane =
static_cast<unsigned>(Imm.getZExtValue() % Lanes);
12911 unsigned Base = Lane * RetLen;
12914 ResultElements.reserve(RetLen);
12915 for (
unsigned I = 0; I < RetLen; ++I) {
12917 ResultElements.push_back(SourceVec.
getVectorElt(Base + I));
12921 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12924 case clang::X86::BI__builtin_ia32_pavgb128:
12925 case clang::X86::BI__builtin_ia32_pavgw128:
12926 case clang::X86::BI__builtin_ia32_pavgb256:
12927 case clang::X86::BI__builtin_ia32_pavgw256:
12928 case clang::X86::BI__builtin_ia32_pavgb512:
12929 case clang::X86::BI__builtin_ia32_pavgw512:
12930 return EvaluateBinOpExpr(llvm::APIntOps::avgCeilU);
12932 case clang::X86::BI__builtin_ia32_pmulhrsw128:
12933 case clang::X86::BI__builtin_ia32_pmulhrsw256:
12934 case clang::X86::BI__builtin_ia32_pmulhrsw512:
12935 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12936 return (llvm::APIntOps::mulsExtended(LHS, RHS).ashr(14) + 1)
12937 .extractBits(16, 1);
12940 case clang::X86::BI__builtin_ia32_psadbw128:
12941 case clang::X86::BI__builtin_ia32_psadbw256:
12942 case clang::X86::BI__builtin_ia32_psadbw512: {
12943 APValue SourceLHS, SourceRHS;
12951 assert((SourceLen % 8) == 0);
12954 QualType DestEltTy = DestTy->getElementType();
12955 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
12957 ResultElements.reserve(SourceLen / 8);
12959 for (
unsigned Lane = 0; Lane != SourceLen; Lane += 8) {
12961 for (
unsigned I = 0; I != 8; ++I) {
12964 Sum += llvm::APIntOps::abdu(LHS, RHS).zext(64);
12966 ResultElements.push_back(
APValue(
APSInt(Sum, DestUnsigned)));
12969 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12972 case clang::X86::BI__builtin_ia32_pmaddubsw128:
12973 case clang::X86::BI__builtin_ia32_pmaddubsw256:
12974 case clang::X86::BI__builtin_ia32_pmaddubsw512:
12975 case clang::X86::BI__builtin_ia32_pmaddwd128:
12976 case clang::X86::BI__builtin_ia32_pmaddwd256:
12977 case clang::X86::BI__builtin_ia32_pmaddwd512: {
12978 APValue SourceLHS, SourceRHS;
12984 QualType DestEltTy = DestTy->getElementType();
12986 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
12988 ResultElements.reserve(SourceLen / 2);
12990 for (
unsigned EltNum = 0; EltNum < SourceLen; EltNum += 2) {
12995 unsigned BitWidth = 2 * LoLHS.getBitWidth();
12997 switch (BuiltinOp) {
12998 case clang::X86::BI__builtin_ia32_pmaddubsw128:
12999 case clang::X86::BI__builtin_ia32_pmaddubsw256:
13000 case clang::X86::BI__builtin_ia32_pmaddubsw512:
13001 ResultElements.push_back(
APValue(
13002 APSInt((LoLHS.zext(BitWidth) * LoRHS.sext(BitWidth))
13003 .sadd_sat((HiLHS.zext(BitWidth) * HiRHS.sext(BitWidth))),
13006 case clang::X86::BI__builtin_ia32_pmaddwd128:
13007 case clang::X86::BI__builtin_ia32_pmaddwd256:
13008 case clang::X86::BI__builtin_ia32_pmaddwd512:
13009 ResultElements.push_back(
13010 APValue(
APSInt((LoLHS.sext(BitWidth) * LoRHS.sext(BitWidth)) +
13011 (HiLHS.sext(BitWidth) * HiRHS.sext(BitWidth)),
13017 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13020 case clang::X86::BI__builtin_ia32_bmacor16x16x16_v16hi:
13021 case clang::X86::BI__builtin_ia32_bmacor16x16x16_v32hi:
13022 case clang::X86::BI__builtin_ia32_bmacxor16x16x16_v16hi:
13023 case clang::X86::BI__builtin_ia32_bmacxor16x16x16_v32hi: {
13034 APValue SourceA, SourceB, SourceC;
13041 clang::X86::BI__builtin_ia32_bmacxor16x16x16_v16hi ||
13043 clang::X86::BI__builtin_ia32_bmacxor16x16x16_v32hi;
13046 assert(SourceLen % 16 == 0 &&
"BMM operates on 256-bit lanes of 16 x i16");
13048 QualType DestEltTy = DestTy->getElementType();
13049 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
13052 for (
unsigned Lane = 0; Lane != SourceLen; Lane += 16) {
13053 for (
unsigned I = 0; I != 16; ++I) {
13058 for (
unsigned J = 0; J != 16; ++J) {
13062 unsigned Bit = (Dst >> J) & 1u;
13063 for (
unsigned K = 0; K != 16; ++K) {
13067 unsigned Product = ((A >> K) & 1u) & ((B >> J) & 1u);
13068 Bit = IsXor ? (Bit ^ Product) : (Bit | Product);
13072 ResultElements[Lane + I] =
13076 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13079 case clang::X86::BI__builtin_ia32_dbpsadbw128:
13080 case clang::X86::BI__builtin_ia32_dbpsadbw256:
13081 case clang::X86::BI__builtin_ia32_dbpsadbw512: {
13082 APValue SourceA, SourceB, SourceImm;
13089 constexpr unsigned LaneSize = 16;
13090 unsigned Imm = SourceImm.
getInt().getZExtValue();
13093 QualType DestEltTy = DestTy->getElementType();
13094 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
13096 ResultElements.reserve(SourceLen / 2);
13102 for (
unsigned I = 0; I < SourceLen; I += LaneSize) {
13103 for (
unsigned J = 0; J < 4; ++J) {
13104 unsigned Part = (Imm >> (2 * J)) & 3;
13105 for (
unsigned K = 0; K < 4; ++K) {
13106 Shuffled[I + 4 * J + K] =
static_cast<uint8_t>(
13107 SourceB.
getVectorElt(I + 4 * Part + K).getInt().getZExtValue());
13115 unsigned Size = SourceLen / 2;
13116 for (
unsigned I = 0; I <
Size; I += 4) {
13117 unsigned Sad[4] = {0, 0, 0, 0};
13118 for (
unsigned J = 0; J < 4; ++J) {
13120 SourceA.
getVectorElt(2 * I + J).getInt().getZExtValue());
13122 SourceA.
getVectorElt(2 * I + J + 4).getInt().getZExtValue());
13123 uint8_t B0 = Shuffled[2 * I + J];
13124 uint8_t B1 = Shuffled[2 * I + J + 1];
13125 uint8_t B2 = Shuffled[2 * I + J + 2];
13126 uint8_t B3 = Shuffled[2 * I + J + 3];
13127 Sad[0] += (A1 > B0) ? (A1 - B0) : (B0 - A1);
13128 Sad[1] += (A1 > B1) ? (A1 - B1) : (B1 - A1);
13129 Sad[2] += (A2 > B2) ? (A2 - B2) : (B2 - A2);
13130 Sad[3] += (A2 > B3) ? (A2 - B3) : (B3 - A2);
13132 for (
unsigned R = 0;
R < 4; ++
R)
13133 ResultElements.push_back(
13137 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13140 case clang::X86::BI__builtin_ia32_mpsadbw128:
13141 case clang::X86::BI__builtin_ia32_mpsadbw256: {
13149 constexpr unsigned LaneSize = 16;
13150 assert((SourceLen == LaneSize || SourceLen == 2 * LaneSize) &&
13151 "MPSADBW operates on 128-bit or 256-bit vectors");
13152 unsigned NumLanes = SourceLen / LaneSize;
13153 unsigned Imm = SourceImm.getZExtValue();
13155 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13158 ResultElements.reserve(SourceLen / 2);
13160 for (
unsigned Lane = 0; Lane != NumLanes; ++Lane) {
13161 unsigned Ctrl = (Imm >> (3 * Lane)) & 0x7;
13162 unsigned AOff = ((Ctrl >> 2) & 1) * 4;
13163 unsigned BOff = (Ctrl & 3) * 4;
13164 for (
unsigned J = 0; J != 8; ++J) {
13166 for (
unsigned K = 0; K != 4; ++K) {
13175 Sad += (A > B) ? (A - B) : (B - A);
13180 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13183 case clang::X86::BI__builtin_ia32_pmulhuw128:
13184 case clang::X86::BI__builtin_ia32_pmulhuw256:
13185 case clang::X86::BI__builtin_ia32_pmulhuw512:
13186 return EvaluateBinOpExpr(llvm::APIntOps::mulhu);
13188 case clang::X86::BI__builtin_ia32_pmulhw128:
13189 case clang::X86::BI__builtin_ia32_pmulhw256:
13190 case clang::X86::BI__builtin_ia32_pmulhw512:
13191 return EvaluateBinOpExpr(llvm::APIntOps::mulhs);
13193 case clang::X86::BI__builtin_ia32_psllv2di:
13194 case clang::X86::BI__builtin_ia32_psllv4di:
13195 case clang::X86::BI__builtin_ia32_psllv4si:
13196 case clang::X86::BI__builtin_ia32_psllv8di:
13197 case clang::X86::BI__builtin_ia32_psllv8hi:
13198 case clang::X86::BI__builtin_ia32_psllv8si:
13199 case clang::X86::BI__builtin_ia32_psllv16hi:
13200 case clang::X86::BI__builtin_ia32_psllv16si:
13201 case clang::X86::BI__builtin_ia32_psllv32hi:
13202 case clang::X86::BI__builtin_ia32_psllwi128:
13203 case clang::X86::BI__builtin_ia32_pslldi128:
13204 case clang::X86::BI__builtin_ia32_psllqi128:
13205 case clang::X86::BI__builtin_ia32_psllwi256:
13206 case clang::X86::BI__builtin_ia32_pslldi256:
13207 case clang::X86::BI__builtin_ia32_psllqi256:
13208 case clang::X86::BI__builtin_ia32_psllwi512:
13209 case clang::X86::BI__builtin_ia32_pslldi512:
13210 case clang::X86::BI__builtin_ia32_psllqi512:
13211 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
13212 if (RHS.uge(LHS.getBitWidth())) {
13213 return APInt::getZero(LHS.getBitWidth());
13215 return LHS.shl(RHS.getZExtValue());
13218 case clang::X86::BI__builtin_ia32_psrav4si:
13219 case clang::X86::BI__builtin_ia32_psrav8di:
13220 case clang::X86::BI__builtin_ia32_psrav8hi:
13221 case clang::X86::BI__builtin_ia32_psrav8si:
13222 case clang::X86::BI__builtin_ia32_psrav16hi:
13223 case clang::X86::BI__builtin_ia32_psrav16si:
13224 case clang::X86::BI__builtin_ia32_psrav32hi:
13225 case clang::X86::BI__builtin_ia32_psravq128:
13226 case clang::X86::BI__builtin_ia32_psravq256:
13227 case clang::X86::BI__builtin_ia32_psrawi128:
13228 case clang::X86::BI__builtin_ia32_psradi128:
13229 case clang::X86::BI__builtin_ia32_psraqi128:
13230 case clang::X86::BI__builtin_ia32_psrawi256:
13231 case clang::X86::BI__builtin_ia32_psradi256:
13232 case clang::X86::BI__builtin_ia32_psraqi256:
13233 case clang::X86::BI__builtin_ia32_psrawi512:
13234 case clang::X86::BI__builtin_ia32_psradi512:
13235 case clang::X86::BI__builtin_ia32_psraqi512:
13236 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
13237 if (RHS.uge(LHS.getBitWidth())) {
13238 return LHS.ashr(LHS.getBitWidth() - 1);
13240 return LHS.ashr(RHS.getZExtValue());
13243 case clang::X86::BI__builtin_ia32_psrlv2di:
13244 case clang::X86::BI__builtin_ia32_psrlv4di:
13245 case clang::X86::BI__builtin_ia32_psrlv4si:
13246 case clang::X86::BI__builtin_ia32_psrlv8di:
13247 case clang::X86::BI__builtin_ia32_psrlv8hi:
13248 case clang::X86::BI__builtin_ia32_psrlv8si:
13249 case clang::X86::BI__builtin_ia32_psrlv16hi:
13250 case clang::X86::BI__builtin_ia32_psrlv16si:
13251 case clang::X86::BI__builtin_ia32_psrlv32hi:
13252 case clang::X86::BI__builtin_ia32_psrlwi128:
13253 case clang::X86::BI__builtin_ia32_psrldi128:
13254 case clang::X86::BI__builtin_ia32_psrlqi128:
13255 case clang::X86::BI__builtin_ia32_psrlwi256:
13256 case clang::X86::BI__builtin_ia32_psrldi256:
13257 case clang::X86::BI__builtin_ia32_psrlqi256:
13258 case clang::X86::BI__builtin_ia32_psrlwi512:
13259 case clang::X86::BI__builtin_ia32_psrldi512:
13260 case clang::X86::BI__builtin_ia32_psrlqi512:
13261 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
13262 if (RHS.uge(LHS.getBitWidth())) {
13263 return APInt::getZero(LHS.getBitWidth());
13265 return LHS.lshr(RHS.getZExtValue());
13267 case X86::BI__builtin_ia32_packsswb128:
13268 case X86::BI__builtin_ia32_packsswb256:
13269 case X86::BI__builtin_ia32_packsswb512:
13270 case X86::BI__builtin_ia32_packssdw128:
13271 case X86::BI__builtin_ia32_packssdw256:
13272 case X86::BI__builtin_ia32_packssdw512:
13274 return APSInt(Src).truncSSat(Src.getBitWidth() / 2);
13276 case X86::BI__builtin_ia32_packusdw128:
13277 case X86::BI__builtin_ia32_packusdw256:
13278 case X86::BI__builtin_ia32_packusdw512:
13279 case X86::BI__builtin_ia32_packuswb128:
13280 case X86::BI__builtin_ia32_packuswb256:
13281 case X86::BI__builtin_ia32_packuswb512:
13283 return APSInt(Src).truncSSatU(Src.getBitWidth() / 2);
13285 case clang::X86::BI__builtin_ia32_selectss_128:
13286 return EvalSelectScalar(4);
13287 case clang::X86::BI__builtin_ia32_selectsd_128:
13288 return EvalSelectScalar(2);
13289 case clang::X86::BI__builtin_ia32_selectsh_128:
13290 case clang::X86::BI__builtin_ia32_selectsbf_128:
13291 return EvalSelectScalar(8);
13292 case clang::X86::BI__builtin_ia32_pmuldq128:
13293 case clang::X86::BI__builtin_ia32_pmuldq256:
13294 case clang::X86::BI__builtin_ia32_pmuldq512:
13295 case clang::X86::BI__builtin_ia32_pmuludq128:
13296 case clang::X86::BI__builtin_ia32_pmuludq256:
13297 case clang::X86::BI__builtin_ia32_pmuludq512: {
13298 APValue SourceLHS, SourceRHS;
13305 ResultElements.reserve(SourceLen / 2);
13307 for (
unsigned EltNum = 0; EltNum < SourceLen; EltNum += 2) {
13311 switch (BuiltinOp) {
13312 case clang::X86::BI__builtin_ia32_pmuludq128:
13313 case clang::X86::BI__builtin_ia32_pmuludq256:
13314 case clang::X86::BI__builtin_ia32_pmuludq512:
13315 ResultElements.push_back(
13316 APValue(
APSInt(llvm::APIntOps::muluExtended(LHS, RHS),
true)));
13318 case clang::X86::BI__builtin_ia32_pmuldq128:
13319 case clang::X86::BI__builtin_ia32_pmuldq256:
13320 case clang::X86::BI__builtin_ia32_pmuldq512:
13321 ResultElements.push_back(
13322 APValue(
APSInt(llvm::APIntOps::mulsExtended(LHS, RHS),
false)));
13327 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13330 case X86::BI__builtin_ia32_vpmadd52luq128:
13331 case X86::BI__builtin_ia32_vpmadd52luq256:
13332 case X86::BI__builtin_ia32_vpmadd52luq512: {
13341 ResultElements.reserve(ALen);
13343 for (
unsigned EltNum = 0; EltNum < ALen; EltNum += 1) {
13346 APInt CElt =
C.getVectorElt(EltNum).getInt().trunc(52);
13347 APSInt ResElt(AElt + (BElt * CElt).zext(64),
false);
13348 ResultElements.push_back(
APValue(ResElt));
13351 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13353 case X86::BI__builtin_ia32_vpmadd52huq128:
13354 case X86::BI__builtin_ia32_vpmadd52huq256:
13355 case X86::BI__builtin_ia32_vpmadd52huq512: {
13364 ResultElements.reserve(ALen);
13366 for (
unsigned EltNum = 0; EltNum < ALen; EltNum += 1) {
13369 APInt CElt =
C.getVectorElt(EltNum).getInt().trunc(52);
13370 APSInt ResElt(AElt + llvm::APIntOps::mulhu(BElt, CElt).zext(64),
false);
13371 ResultElements.push_back(
APValue(ResElt));
13374 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13377 case clang::X86::BI__builtin_ia32_vprotbi:
13378 case clang::X86::BI__builtin_ia32_vprotdi:
13379 case clang::X86::BI__builtin_ia32_vprotqi:
13380 case clang::X86::BI__builtin_ia32_vprotwi:
13381 case clang::X86::BI__builtin_ia32_prold128:
13382 case clang::X86::BI__builtin_ia32_prold256:
13383 case clang::X86::BI__builtin_ia32_prold512:
13384 case clang::X86::BI__builtin_ia32_prolq128:
13385 case clang::X86::BI__builtin_ia32_prolq256:
13386 case clang::X86::BI__builtin_ia32_prolq512:
13387 return EvaluateBinOpExpr(
13388 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS.rotl(RHS); });
13390 case clang::X86::BI__builtin_ia32_prord128:
13391 case clang::X86::BI__builtin_ia32_prord256:
13392 case clang::X86::BI__builtin_ia32_prord512:
13393 case clang::X86::BI__builtin_ia32_prorq128:
13394 case clang::X86::BI__builtin_ia32_prorq256:
13395 case clang::X86::BI__builtin_ia32_prorq512:
13396 return EvaluateBinOpExpr(
13397 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS.rotr(RHS); });
13399 case Builtin::BI__builtin_elementwise_max:
13400 case Builtin::BI__builtin_elementwise_min: {
13401 APValue SourceLHS, SourceRHS;
13406 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13413 ResultElements.reserve(SourceLen);
13415 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13418 switch (BuiltinOp) {
13419 case Builtin::BI__builtin_elementwise_max:
13420 ResultElements.push_back(
13424 case Builtin::BI__builtin_elementwise_min:
13425 ResultElements.push_back(
13432 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13434 case X86::BI__builtin_ia32_vpshldd128:
13435 case X86::BI__builtin_ia32_vpshldd256:
13436 case X86::BI__builtin_ia32_vpshldd512:
13437 case X86::BI__builtin_ia32_vpshldq128:
13438 case X86::BI__builtin_ia32_vpshldq256:
13439 case X86::BI__builtin_ia32_vpshldq512:
13440 case X86::BI__builtin_ia32_vpshldw128:
13441 case X86::BI__builtin_ia32_vpshldw256:
13442 case X86::BI__builtin_ia32_vpshldw512: {
13443 APValue SourceHi, SourceLo, SourceAmt;
13449 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13452 ResultElements.reserve(SourceLen);
13455 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13458 APInt R = llvm::APIntOps::fshl(Hi, Lo, Amt);
13459 ResultElements.push_back(
13463 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13465 case X86::BI__builtin_ia32_vpshrdd128:
13466 case X86::BI__builtin_ia32_vpshrdd256:
13467 case X86::BI__builtin_ia32_vpshrdd512:
13468 case X86::BI__builtin_ia32_vpshrdq128:
13469 case X86::BI__builtin_ia32_vpshrdq256:
13470 case X86::BI__builtin_ia32_vpshrdq512:
13471 case X86::BI__builtin_ia32_vpshrdw128:
13472 case X86::BI__builtin_ia32_vpshrdw256:
13473 case X86::BI__builtin_ia32_vpshrdw512: {
13475 APValue SourceHi, SourceLo, SourceAmt;
13481 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13484 ResultElements.reserve(SourceLen);
13487 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13490 APInt R = llvm::APIntOps::fshr(Hi, Lo, Amt);
13491 ResultElements.push_back(
13495 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13497 case X86::BI__builtin_ia32_compressdf128_mask:
13498 case X86::BI__builtin_ia32_compressdf256_mask:
13499 case X86::BI__builtin_ia32_compressdf512_mask:
13500 case X86::BI__builtin_ia32_compressdi128_mask:
13501 case X86::BI__builtin_ia32_compressdi256_mask:
13502 case X86::BI__builtin_ia32_compressdi512_mask:
13503 case X86::BI__builtin_ia32_compresshi128_mask:
13504 case X86::BI__builtin_ia32_compresshi256_mask:
13505 case X86::BI__builtin_ia32_compresshi512_mask:
13506 case X86::BI__builtin_ia32_compressqi128_mask:
13507 case X86::BI__builtin_ia32_compressqi256_mask:
13508 case X86::BI__builtin_ia32_compressqi512_mask:
13509 case X86::BI__builtin_ia32_compresssf128_mask:
13510 case X86::BI__builtin_ia32_compresssf256_mask:
13511 case X86::BI__builtin_ia32_compresssf512_mask:
13512 case X86::BI__builtin_ia32_compresssi128_mask:
13513 case X86::BI__builtin_ia32_compresssi256_mask:
13514 case X86::BI__builtin_ia32_compresssi512_mask: {
13525 ResultElements.reserve(NumElts);
13527 for (
unsigned I = 0; I != NumElts; ++I) {
13531 for (
unsigned I = ResultElements.size(); I != NumElts; ++I) {
13535 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13537 case X86::BI__builtin_ia32_expanddf128_mask:
13538 case X86::BI__builtin_ia32_expanddf256_mask:
13539 case X86::BI__builtin_ia32_expanddf512_mask:
13540 case X86::BI__builtin_ia32_expanddi128_mask:
13541 case X86::BI__builtin_ia32_expanddi256_mask:
13542 case X86::BI__builtin_ia32_expanddi512_mask:
13543 case X86::BI__builtin_ia32_expandhi128_mask:
13544 case X86::BI__builtin_ia32_expandhi256_mask:
13545 case X86::BI__builtin_ia32_expandhi512_mask:
13546 case X86::BI__builtin_ia32_expandqi128_mask:
13547 case X86::BI__builtin_ia32_expandqi256_mask:
13548 case X86::BI__builtin_ia32_expandqi512_mask:
13549 case X86::BI__builtin_ia32_expandsf128_mask:
13550 case X86::BI__builtin_ia32_expandsf256_mask:
13551 case X86::BI__builtin_ia32_expandsf512_mask:
13552 case X86::BI__builtin_ia32_expandsi128_mask:
13553 case X86::BI__builtin_ia32_expandsi256_mask:
13554 case X86::BI__builtin_ia32_expandsi512_mask: {
13565 ResultElements.reserve(NumElts);
13567 unsigned SourceIdx = 0;
13568 for (
unsigned I = 0; I != NumElts; ++I) {
13570 ResultElements.push_back(Source.
getVectorElt(SourceIdx++));
13574 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13576 case X86::BI__builtin_ia32_vpconflictsi_128:
13577 case X86::BI__builtin_ia32_vpconflictsi_256:
13578 case X86::BI__builtin_ia32_vpconflictsi_512:
13579 case X86::BI__builtin_ia32_vpconflictdi_128:
13580 case X86::BI__builtin_ia32_vpconflictdi_256:
13581 case X86::BI__builtin_ia32_vpconflictdi_512: {
13589 ResultElements.reserve(SourceLen);
13592 bool DestUnsigned =
13593 VecT->getElementType()->isUnsignedIntegerOrEnumerationType();
13595 for (
unsigned I = 0; I != SourceLen; ++I) {
13598 APInt ConflictMask(EltI.
getInt().getBitWidth(), 0);
13599 for (
unsigned J = 0; J != I; ++J) {
13601 ConflictMask.setBitVal(J, EltI.
getInt() == EltJ.
getInt());
13603 ResultElements.push_back(
APValue(
APSInt(ConflictMask, DestUnsigned)));
13605 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13607 case X86::BI__builtin_ia32_blendpd:
13608 case X86::BI__builtin_ia32_blendpd256:
13609 case X86::BI__builtin_ia32_blendps:
13610 case X86::BI__builtin_ia32_blendps256:
13611 case X86::BI__builtin_ia32_pblendw128:
13612 case X86::BI__builtin_ia32_pblendw256:
13613 case X86::BI__builtin_ia32_pblendd128:
13614 case X86::BI__builtin_ia32_pblendd256: {
13615 APValue SourceF, SourceT, SourceC;
13624 ResultElements.reserve(SourceLen);
13625 for (
unsigned EltNum = 0; EltNum != SourceLen; ++EltNum) {
13628 ResultElements.push_back(
C[EltNum % 8] ?
T : F);
13631 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13634 case X86::BI__builtin_ia32_psignb128:
13635 case X86::BI__builtin_ia32_psignb256:
13636 case X86::BI__builtin_ia32_psignw128:
13637 case X86::BI__builtin_ia32_psignw256:
13638 case X86::BI__builtin_ia32_psignd128:
13639 case X86::BI__builtin_ia32_psignd256:
13640 return EvaluateBinOpExpr([](
const APInt &AElem,
const APInt &BElem) {
13641 if (BElem.isZero())
13642 return APInt::getZero(AElem.getBitWidth());
13643 if (BElem.isNegative())
13648 case X86::BI__builtin_ia32_blendvpd:
13649 case X86::BI__builtin_ia32_blendvpd256:
13650 case X86::BI__builtin_ia32_blendvps:
13651 case X86::BI__builtin_ia32_blendvps256:
13652 case X86::BI__builtin_ia32_pblendvb128:
13653 case X86::BI__builtin_ia32_pblendvb256: {
13655 APValue SourceF, SourceT, SourceC;
13663 ResultElements.reserve(SourceLen);
13665 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13669 APInt M =
C.isInt() ? (
APInt)
C.getInt() :
C.getFloat().bitcastToAPInt();
13670 ResultElements.push_back(M.isNegative() ?
T : F);
13673 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13675 case X86::BI__builtin_ia32_selectb_128:
13676 case X86::BI__builtin_ia32_selectb_256:
13677 case X86::BI__builtin_ia32_selectb_512:
13678 case X86::BI__builtin_ia32_selectw_128:
13679 case X86::BI__builtin_ia32_selectw_256:
13680 case X86::BI__builtin_ia32_selectw_512:
13681 case X86::BI__builtin_ia32_selectd_128:
13682 case X86::BI__builtin_ia32_selectd_256:
13683 case X86::BI__builtin_ia32_selectd_512:
13684 case X86::BI__builtin_ia32_selectq_128:
13685 case X86::BI__builtin_ia32_selectq_256:
13686 case X86::BI__builtin_ia32_selectq_512:
13687 case X86::BI__builtin_ia32_selectph_128:
13688 case X86::BI__builtin_ia32_selectph_256:
13689 case X86::BI__builtin_ia32_selectph_512:
13690 case X86::BI__builtin_ia32_selectpbf_128:
13691 case X86::BI__builtin_ia32_selectpbf_256:
13692 case X86::BI__builtin_ia32_selectpbf_512:
13693 case X86::BI__builtin_ia32_selectps_128:
13694 case X86::BI__builtin_ia32_selectps_256:
13695 case X86::BI__builtin_ia32_selectps_512:
13696 case X86::BI__builtin_ia32_selectpd_128:
13697 case X86::BI__builtin_ia32_selectpd_256:
13698 case X86::BI__builtin_ia32_selectpd_512: {
13700 APValue SourceMask, SourceLHS, SourceRHS;
13709 ResultElements.reserve(SourceLen);
13711 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13714 ResultElements.push_back(Mask[EltNum] ? LHS : RHS);
13717 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13720 case X86::BI__builtin_ia32_cvtsd2ss: {
13733 Elements.push_back(ResultVal);
13736 for (
unsigned I = 1; I < NumEltsA; ++I) {
13742 case X86::BI__builtin_ia32_cvtsd2ss_round_mask: {
13743 APValue VecA, VecB, VecSrc, MaskValue;
13751 unsigned Mask = MaskValue.
getInt().getZExtValue();
13759 Elements.push_back(ResultVal);
13765 for (
unsigned I = 1; I < NumEltsA; ++I) {
13771 case X86::BI__builtin_ia32_cvtpd2ps:
13772 case X86::BI__builtin_ia32_cvtpd2ps256:
13773 case X86::BI__builtin_ia32_cvtpd2ps_mask:
13774 case X86::BI__builtin_ia32_cvtpd2ps512_mask: {
13776 const auto BuiltinID = BuiltinOp;
13777 bool IsMasked = (BuiltinID == X86::BI__builtin_ia32_cvtpd2ps_mask ||
13778 BuiltinID == X86::BI__builtin_ia32_cvtpd2ps512_mask);
13785 unsigned Mask = 0xFFFFFFFF;
13786 bool NeedsMerge =
false;
13791 Mask = MaskValue.
getInt().getZExtValue();
13792 auto NumEltsResult = E->
getType()->
getAs<VectorType>()->getNumElements();
13793 for (
unsigned I = 0; I < NumEltsResult; ++I) {
13794 if (!((Mask >> I) & 1)) {
13805 unsigned NumEltsResult =
13809 for (
unsigned I = 0; I < NumEltsResult; ++I) {
13810 if (IsMasked && !((Mask >> I) & 1)) {
13818 if (I >= NumEltsInput) {
13819 Elements.push_back(
APValue(APFloat::getZero(APFloat::IEEEsingle())));
13828 Elements.push_back(ResultVal);
13833 case X86::BI__builtin_ia32_shufps:
13834 case X86::BI__builtin_ia32_shufps256:
13835 case X86::BI__builtin_ia32_shufps512: {
13839 [](
unsigned DstIdx,
13840 unsigned ShuffleMask) -> std::pair<unsigned, int> {
13841 constexpr unsigned LaneBits = 128u;
13842 unsigned NumElemPerLane = LaneBits / 32;
13843 unsigned NumSelectableElems = NumElemPerLane / 2;
13844 unsigned BitsPerElem = 2;
13845 unsigned IndexMask = (1u << BitsPerElem) - 1;
13846 unsigned MaskBits = 8;
13847 unsigned Lane = DstIdx / NumElemPerLane;
13848 unsigned ElemInLane = DstIdx % NumElemPerLane;
13849 unsigned LaneOffset = Lane * NumElemPerLane;
13850 unsigned BitIndex = (DstIdx * BitsPerElem) % MaskBits;
13851 unsigned SrcIdx = (ElemInLane < NumSelectableElems) ? 0 : 1;
13852 unsigned Index = (ShuffleMask >> BitIndex) & IndexMask;
13853 return {SrcIdx,
static_cast<int>(LaneOffset + Index)};
13858 case X86::BI__builtin_ia32_shufpd:
13859 case X86::BI__builtin_ia32_shufpd256:
13860 case X86::BI__builtin_ia32_shufpd512: {
13864 [](
unsigned DstIdx,
13865 unsigned ShuffleMask) -> std::pair<unsigned, int> {
13866 constexpr unsigned LaneBits = 128u;
13867 unsigned NumElemPerLane = LaneBits / 64;
13868 unsigned NumSelectableElems = NumElemPerLane / 2;
13869 unsigned BitsPerElem = 1;
13870 unsigned IndexMask = (1u << BitsPerElem) - 1;
13871 unsigned MaskBits = 8;
13872 unsigned Lane = DstIdx / NumElemPerLane;
13873 unsigned ElemInLane = DstIdx % NumElemPerLane;
13874 unsigned LaneOffset = Lane * NumElemPerLane;
13875 unsigned BitIndex = (DstIdx * BitsPerElem) % MaskBits;
13876 unsigned SrcIdx = (ElemInLane < NumSelectableElems) ? 0 : 1;
13877 unsigned Index = (ShuffleMask >> BitIndex) & IndexMask;
13878 return {SrcIdx,
static_cast<int>(LaneOffset + Index)};
13883 case X86::BI__builtin_ia32_insertps128: {
13887 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13889 if ((Mask & (1 << DstIdx)) != 0) {
13894 unsigned SrcElem = (Mask >> 6) & 0x3;
13895 unsigned DstElem = (Mask >> 4) & 0x3;
13896 if (DstIdx == DstElem) {
13898 return {1,
static_cast<int>(SrcElem)};
13901 return {0,
static_cast<int>(DstIdx)};
13907 case X86::BI__builtin_ia32_pshufb128:
13908 case X86::BI__builtin_ia32_pshufb256:
13909 case X86::BI__builtin_ia32_pshufb512: {
13913 [](
unsigned DstIdx,
13914 unsigned ShuffleMask) -> std::pair<unsigned, int> {
13917 return std::make_pair(0, -1);
13919 unsigned LaneBase = (DstIdx / 16) * 16;
13920 unsigned SrcOffset = Ctlb & 0x0F;
13921 unsigned SrcIdx = LaneBase + SrcOffset;
13922 return std::make_pair(0,
static_cast<int>(SrcIdx));
13928 case X86::BI__builtin_ia32_pshuflw:
13929 case X86::BI__builtin_ia32_pshuflw256:
13930 case X86::BI__builtin_ia32_pshuflw512: {
13934 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13935 constexpr unsigned LaneBits = 128u;
13936 constexpr unsigned ElemBits = 16u;
13937 constexpr unsigned LaneElts = LaneBits / ElemBits;
13938 constexpr unsigned HalfSize = 4;
13939 unsigned LaneBase = (DstIdx / LaneElts) * LaneElts;
13940 unsigned LaneIdx = DstIdx % LaneElts;
13941 if (LaneIdx < HalfSize) {
13942 unsigned Sel = (Mask >> (2 * LaneIdx)) & 0x3;
13943 return std::make_pair(0,
static_cast<int>(LaneBase + Sel));
13945 return std::make_pair(0,
static_cast<int>(DstIdx));
13951 case X86::BI__builtin_ia32_pshufhw:
13952 case X86::BI__builtin_ia32_pshufhw256:
13953 case X86::BI__builtin_ia32_pshufhw512: {
13957 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13958 constexpr unsigned LaneBits = 128u;
13959 constexpr unsigned ElemBits = 16u;
13960 constexpr unsigned LaneElts = LaneBits / ElemBits;
13961 constexpr unsigned HalfSize = 4;
13962 unsigned LaneBase = (DstIdx / LaneElts) * LaneElts;
13963 unsigned LaneIdx = DstIdx % LaneElts;
13964 if (LaneIdx >= HalfSize) {
13965 unsigned Rel = LaneIdx - HalfSize;
13966 unsigned Sel = (Mask >> (2 * Rel)) & 0x3;
13967 return std::make_pair(
13968 0,
static_cast<int>(LaneBase + HalfSize + Sel));
13970 return std::make_pair(0,
static_cast<int>(DstIdx));
13976 case X86::BI__builtin_ia32_pshufd:
13977 case X86::BI__builtin_ia32_pshufd256:
13978 case X86::BI__builtin_ia32_pshufd512:
13979 case X86::BI__builtin_ia32_vpermilps:
13980 case X86::BI__builtin_ia32_vpermilps256:
13981 case X86::BI__builtin_ia32_vpermilps512: {
13985 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13986 constexpr unsigned LaneBits = 128u;
13987 constexpr unsigned ElemBits = 32u;
13988 constexpr unsigned LaneElts = LaneBits / ElemBits;
13989 unsigned LaneBase = (DstIdx / LaneElts) * LaneElts;
13990 unsigned LaneIdx = DstIdx % LaneElts;
13991 unsigned Sel = (Mask >> (2 * LaneIdx)) & 0x3;
13992 return std::make_pair(0,
static_cast<int>(LaneBase + Sel));
13998 case X86::BI__builtin_ia32_vpermilvarpd:
13999 case X86::BI__builtin_ia32_vpermilvarpd256:
14000 case X86::BI__builtin_ia32_vpermilvarpd512: {
14004 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
14005 unsigned NumElemPerLane = 2;
14006 unsigned Lane = DstIdx / NumElemPerLane;
14007 unsigned Offset = Mask & 0b10 ? 1 : 0;
14008 return std::make_pair(
14009 0,
static_cast<int>(Lane * NumElemPerLane + Offset));
14015 case X86::BI__builtin_ia32_vpermilpd:
14016 case X86::BI__builtin_ia32_vpermilpd256:
14017 case X86::BI__builtin_ia32_vpermilpd512: {
14020 unsigned NumElemPerLane = 2;
14021 unsigned BitsPerElem = 1;
14022 unsigned MaskBits = 8;
14023 unsigned IndexMask = 0x1;
14024 unsigned Lane = DstIdx / NumElemPerLane;
14025 unsigned LaneOffset = Lane * NumElemPerLane;
14026 unsigned BitIndex = (DstIdx * BitsPerElem) % MaskBits;
14027 unsigned Index = (Control >> BitIndex) & IndexMask;
14028 return std::make_pair(0,
static_cast<int>(LaneOffset + Index));
14034 case X86::BI__builtin_ia32_permdf256:
14035 case X86::BI__builtin_ia32_permdi256: {
14040 unsigned Index = (Control >> (2 * DstIdx)) & 0x3;
14041 return std::make_pair(0,
static_cast<int>(Index));
14047 case X86::BI__builtin_ia32_vpermilvarps:
14048 case X86::BI__builtin_ia32_vpermilvarps256:
14049 case X86::BI__builtin_ia32_vpermilvarps512: {
14053 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
14054 unsigned NumElemPerLane = 4;
14055 unsigned Lane = DstIdx / NumElemPerLane;
14056 unsigned Offset = Mask & 0b11;
14057 return std::make_pair(
14058 0,
static_cast<int>(Lane * NumElemPerLane + Offset));
14064 case X86::BI__builtin_ia32_vpmultishiftqb128:
14065 case X86::BI__builtin_ia32_vpmultishiftqb256:
14066 case X86::BI__builtin_ia32_vpmultishiftqb512: {
14074 unsigned NumBytesInQWord = 8;
14075 unsigned NumBitsInByte = 8;
14077 unsigned NumQWords = NumBytes / NumBytesInQWord;
14079 Result.reserve(NumBytes);
14081 for (
unsigned QWordId = 0; QWordId != NumQWords; ++QWordId) {
14082 APInt BQWord(64, 0);
14083 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
14084 unsigned Idx = QWordId * NumBytesInQWord + ByteIdx;
14086 BQWord.insertBits(
APInt(8, Byte & 0xFF), ByteIdx * NumBitsInByte);
14089 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
14090 unsigned Idx = QWordId * NumBytesInQWord + ByteIdx;
14094 for (
unsigned BitIdx = 0; BitIdx != NumBitsInByte; ++BitIdx) {
14095 Byte.setBitVal(BitIdx, BQWord[(Ctrl + BitIdx) & 0x3F]);
14103 case X86::BI__builtin_ia32_phminposuw128: {
14110 unsigned ElemBitWidth = Info.Ctx.getTypeSize(ElemQT);
14112 APInt MinIndex(ElemBitWidth, 0);
14114 for (
unsigned I = 1; I != SourceLen; ++I) {
14116 if (MinVal.ugt(Val)) {
14125 ->isUnsignedIntegerOrEnumerationType();
14128 Result.reserve(SourceLen);
14130 Result.emplace_back(
APSInt(MinIndex, ResultUnsigned));
14131 for (
unsigned I = 0; I != SourceLen - 2; ++I) {
14137 case X86::BI__builtin_ia32_psraq128:
14138 case X86::BI__builtin_ia32_psraq256:
14139 case X86::BI__builtin_ia32_psraq512:
14140 case X86::BI__builtin_ia32_psrad128:
14141 case X86::BI__builtin_ia32_psrad256:
14142 case X86::BI__builtin_ia32_psrad512:
14143 case X86::BI__builtin_ia32_psraw128:
14144 case X86::BI__builtin_ia32_psraw256:
14145 case X86::BI__builtin_ia32_psraw512: {
14149 [](
const APInt &Elt, uint64_t Count) {
return Elt.ashr(Count); },
14150 [](
const APInt &Elt,
unsigned Width) {
14151 return Elt.ashr(Width - 1);
14157 case X86::BI__builtin_ia32_psllq128:
14158 case X86::BI__builtin_ia32_psllq256:
14159 case X86::BI__builtin_ia32_psllq512:
14160 case X86::BI__builtin_ia32_pslld128:
14161 case X86::BI__builtin_ia32_pslld256:
14162 case X86::BI__builtin_ia32_pslld512:
14163 case X86::BI__builtin_ia32_psllw128:
14164 case X86::BI__builtin_ia32_psllw256:
14165 case X86::BI__builtin_ia32_psllw512: {
14169 [](
const APInt &Elt, uint64_t Count) {
return Elt.shl(Count); },
14170 [](
const APInt &Elt,
unsigned Width) {
14171 return APInt::getZero(Width);
14177 case X86::BI__builtin_ia32_psrlq128:
14178 case X86::BI__builtin_ia32_psrlq256:
14179 case X86::BI__builtin_ia32_psrlq512:
14180 case X86::BI__builtin_ia32_psrld128:
14181 case X86::BI__builtin_ia32_psrld256:
14182 case X86::BI__builtin_ia32_psrld512:
14183 case X86::BI__builtin_ia32_psrlw128:
14184 case X86::BI__builtin_ia32_psrlw256:
14185 case X86::BI__builtin_ia32_psrlw512: {
14189 [](
const APInt &Elt, uint64_t Count) {
return Elt.lshr(Count); },
14190 [](
const APInt &Elt,
unsigned Width) {
14191 return APInt::getZero(Width);
14197 case X86::BI__builtin_ia32_pternlogd128_mask:
14198 case X86::BI__builtin_ia32_pternlogd256_mask:
14199 case X86::BI__builtin_ia32_pternlogd512_mask:
14200 case X86::BI__builtin_ia32_pternlogq128_mask:
14201 case X86::BI__builtin_ia32_pternlogq256_mask:
14202 case X86::BI__builtin_ia32_pternlogq512_mask: {
14203 APValue AValue, BValue, CValue, ImmValue, UValue;
14211 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14217 ResultElements.reserve(ResultLen);
14219 for (
unsigned EltNum = 0; EltNum < ResultLen; ++EltNum) {
14225 unsigned BitWidth = ALane.getBitWidth();
14226 APInt ResLane(BitWidth, 0);
14228 for (
unsigned Bit = 0; Bit < BitWidth; ++Bit) {
14229 unsigned ABit = ALane[Bit];
14230 unsigned BBit = BLane[Bit];
14231 unsigned CBit = CLane[Bit];
14233 unsigned Idx = (ABit << 2) | (BBit << 1) | CBit;
14234 ResLane.setBitVal(Bit, Imm[Idx]);
14236 ResultElements.push_back(
APValue(
APSInt(ResLane, DestUnsigned)));
14238 ResultElements.push_back(
APValue(
APSInt(ALane, DestUnsigned)));
14241 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14243 case X86::BI__builtin_ia32_pternlogd128_maskz:
14244 case X86::BI__builtin_ia32_pternlogd256_maskz:
14245 case X86::BI__builtin_ia32_pternlogd512_maskz:
14246 case X86::BI__builtin_ia32_pternlogq128_maskz:
14247 case X86::BI__builtin_ia32_pternlogq256_maskz:
14248 case X86::BI__builtin_ia32_pternlogq512_maskz: {
14249 APValue AValue, BValue, CValue, ImmValue, UValue;
14257 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14263 ResultElements.reserve(ResultLen);
14265 for (
unsigned EltNum = 0; EltNum < ResultLen; ++EltNum) {
14270 unsigned BitWidth = ALane.getBitWidth();
14271 APInt ResLane(BitWidth, 0);
14274 for (
unsigned Bit = 0; Bit < BitWidth; ++Bit) {
14275 unsigned ABit = ALane[Bit];
14276 unsigned BBit = BLane[Bit];
14277 unsigned CBit = CLane[Bit];
14279 unsigned Idx = (ABit << 2) | (BBit << 1) | CBit;
14280 ResLane.setBitVal(Bit, Imm[Idx]);
14283 ResultElements.push_back(
APValue(
APSInt(ResLane, DestUnsigned)));
14285 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14288 case Builtin::BI__builtin_elementwise_clzg:
14289 case Builtin::BI__builtin_elementwise_ctzg: {
14291 std::optional<APValue> Fallback;
14298 Fallback = FallbackTmp;
14301 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14304 ResultElements.reserve(SourceLen);
14306 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
14311 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
14313 Builtin::BI__builtin_elementwise_ctzg);
14316 ResultElements.push_back(Fallback->getVectorElt(EltNum));
14319 switch (BuiltinOp) {
14320 case Builtin::BI__builtin_elementwise_clzg:
14321 ResultElements.push_back(
APValue(
14322 APSInt(
APInt(Info.Ctx.getIntWidth(DestEltTy), LHS.countl_zero()),
14325 case Builtin::BI__builtin_elementwise_ctzg:
14326 ResultElements.push_back(
APValue(
14327 APSInt(
APInt(Info.Ctx.getIntWidth(DestEltTy), LHS.countr_zero()),
14333 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14336 case Builtin::BI__builtin_elementwise_fma: {
14337 APValue SourceX, SourceY, SourceZ;
14345 ResultElements.reserve(SourceLen);
14347 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
14352 (void)
Result.fusedMultiplyAdd(Y, Z, RM);
14355 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14358 case clang::X86::BI__builtin_ia32_phaddw128:
14359 case clang::X86::BI__builtin_ia32_phaddw256:
14360 case clang::X86::BI__builtin_ia32_phaddd128:
14361 case clang::X86::BI__builtin_ia32_phaddd256:
14362 case clang::X86::BI__builtin_ia32_phaddsw128:
14363 case clang::X86::BI__builtin_ia32_phaddsw256:
14365 case clang::X86::BI__builtin_ia32_phsubw128:
14366 case clang::X86::BI__builtin_ia32_phsubw256:
14367 case clang::X86::BI__builtin_ia32_phsubd128:
14368 case clang::X86::BI__builtin_ia32_phsubd256:
14369 case clang::X86::BI__builtin_ia32_phsubsw128:
14370 case clang::X86::BI__builtin_ia32_phsubsw256: {
14371 APValue SourceLHS, SourceRHS;
14375 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14379 unsigned EltBits = Info.Ctx.getIntWidth(DestEltTy);
14380 unsigned EltsPerLane = 128 / EltBits;
14382 ResultElements.reserve(NumElts);
14384 for (
unsigned LaneStart = 0; LaneStart != NumElts;
14385 LaneStart += EltsPerLane) {
14386 for (
unsigned I = 0; I != EltsPerLane; I += 2) {
14389 switch (BuiltinOp) {
14390 case clang::X86::BI__builtin_ia32_phaddw128:
14391 case clang::X86::BI__builtin_ia32_phaddw256:
14392 case clang::X86::BI__builtin_ia32_phaddd128:
14393 case clang::X86::BI__builtin_ia32_phaddd256: {
14394 APSInt Res(LHSA + LHSB, DestUnsigned);
14395 ResultElements.push_back(
APValue(Res));
14398 case clang::X86::BI__builtin_ia32_phaddsw128:
14399 case clang::X86::BI__builtin_ia32_phaddsw256: {
14400 APSInt Res(LHSA.sadd_sat(LHSB));
14401 ResultElements.push_back(
APValue(Res));
14404 case clang::X86::BI__builtin_ia32_phsubw128:
14405 case clang::X86::BI__builtin_ia32_phsubw256:
14406 case clang::X86::BI__builtin_ia32_phsubd128:
14407 case clang::X86::BI__builtin_ia32_phsubd256: {
14408 APSInt Res(LHSA - LHSB, DestUnsigned);
14409 ResultElements.push_back(
APValue(Res));
14412 case clang::X86::BI__builtin_ia32_phsubsw128:
14413 case clang::X86::BI__builtin_ia32_phsubsw256: {
14414 APSInt Res(LHSA.ssub_sat(LHSB));
14415 ResultElements.push_back(
APValue(Res));
14420 for (
unsigned I = 0; I != EltsPerLane; I += 2) {
14423 switch (BuiltinOp) {
14424 case clang::X86::BI__builtin_ia32_phaddw128:
14425 case clang::X86::BI__builtin_ia32_phaddw256:
14426 case clang::X86::BI__builtin_ia32_phaddd128:
14427 case clang::X86::BI__builtin_ia32_phaddd256: {
14428 APSInt Res(RHSA + RHSB, DestUnsigned);
14429 ResultElements.push_back(
APValue(Res));
14432 case clang::X86::BI__builtin_ia32_phaddsw128:
14433 case clang::X86::BI__builtin_ia32_phaddsw256: {
14434 APSInt Res(RHSA.sadd_sat(RHSB));
14435 ResultElements.push_back(
APValue(Res));
14438 case clang::X86::BI__builtin_ia32_phsubw128:
14439 case clang::X86::BI__builtin_ia32_phsubw256:
14440 case clang::X86::BI__builtin_ia32_phsubd128:
14441 case clang::X86::BI__builtin_ia32_phsubd256: {
14442 APSInt Res(RHSA - RHSB, DestUnsigned);
14443 ResultElements.push_back(
APValue(Res));
14446 case clang::X86::BI__builtin_ia32_phsubsw128:
14447 case clang::X86::BI__builtin_ia32_phsubsw256: {
14448 APSInt Res(RHSA.ssub_sat(RHSB));
14449 ResultElements.push_back(
APValue(Res));
14455 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14457 case clang::X86::BI__builtin_ia32_haddpd:
14458 case clang::X86::BI__builtin_ia32_haddps:
14459 case clang::X86::BI__builtin_ia32_haddps256:
14460 case clang::X86::BI__builtin_ia32_haddpd256:
14461 case clang::X86::BI__builtin_ia32_hsubpd:
14462 case clang::X86::BI__builtin_ia32_hsubps:
14463 case clang::X86::BI__builtin_ia32_hsubps256:
14464 case clang::X86::BI__builtin_ia32_hsubpd256: {
14465 APValue SourceLHS, SourceRHS;
14471 ResultElements.reserve(NumElts);
14473 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14474 unsigned EltBits = Info.Ctx.getTypeSize(DestEltTy);
14475 unsigned NumLanes = NumElts * EltBits / 128;
14476 unsigned NumElemsPerLane = NumElts / NumLanes;
14477 unsigned HalfElemsPerLane = NumElemsPerLane / 2;
14479 for (
unsigned L = 0; L != NumElts; L += NumElemsPerLane) {
14480 for (
unsigned I = 0; I != HalfElemsPerLane; ++I) {
14483 switch (BuiltinOp) {
14484 case clang::X86::BI__builtin_ia32_haddpd:
14485 case clang::X86::BI__builtin_ia32_haddps:
14486 case clang::X86::BI__builtin_ia32_haddps256:
14487 case clang::X86::BI__builtin_ia32_haddpd256:
14488 LHSA.add(LHSB, RM);
14490 case clang::X86::BI__builtin_ia32_hsubpd:
14491 case clang::X86::BI__builtin_ia32_hsubps:
14492 case clang::X86::BI__builtin_ia32_hsubps256:
14493 case clang::X86::BI__builtin_ia32_hsubpd256:
14494 LHSA.subtract(LHSB, RM);
14497 ResultElements.push_back(
APValue(LHSA));
14499 for (
unsigned I = 0; I != HalfElemsPerLane; ++I) {
14502 switch (BuiltinOp) {
14503 case clang::X86::BI__builtin_ia32_haddpd:
14504 case clang::X86::BI__builtin_ia32_haddps:
14505 case clang::X86::BI__builtin_ia32_haddps256:
14506 case clang::X86::BI__builtin_ia32_haddpd256:
14507 RHSA.add(RHSB, RM);
14509 case clang::X86::BI__builtin_ia32_hsubpd:
14510 case clang::X86::BI__builtin_ia32_hsubps:
14511 case clang::X86::BI__builtin_ia32_hsubps256:
14512 case clang::X86::BI__builtin_ia32_hsubpd256:
14513 RHSA.subtract(RHSB, RM);
14516 ResultElements.push_back(
APValue(RHSA));
14519 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14521 case clang::X86::BI__builtin_ia32_addsubpd:
14522 case clang::X86::BI__builtin_ia32_addsubps:
14523 case clang::X86::BI__builtin_ia32_addsubpd256:
14524 case clang::X86::BI__builtin_ia32_addsubps256: {
14527 APValue SourceLHS, SourceRHS;
14533 ResultElements.reserve(NumElems);
14536 for (
unsigned I = 0; I != NumElems; ++I) {
14541 LHS.subtract(RHS, RM);
14546 ResultElements.push_back(
APValue(LHS));
14548 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14550 case clang::X86::BI__builtin_ia32_pclmulqdq128:
14551 case clang::X86::BI__builtin_ia32_pclmulqdq256:
14552 case clang::X86::BI__builtin_ia32_pclmulqdq512: {
14556 APValue SourceLHS, SourceRHS;
14566 bool SelectUpperA = (Imm8 & 0x01) != 0;
14567 bool SelectUpperB = (Imm8 & 0x10) != 0;
14571 ResultElements.reserve(NumElems);
14572 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14576 for (
unsigned Lane = 0; Lane < NumElems; Lane += 2) {
14585 APInt A = SelectUpperA ? A1 : A0;
14586 APInt B = SelectUpperB ? B1 : B0;
14589 APInt A128 = A.zext(128);
14590 APInt B128 = B.zext(128);
14593 APInt Result = llvm::APIntOps::clmul(A128, B128);
14596 APSInt ResultLow(
Result.extractBits(64, 0), DestUnsigned);
14597 APSInt ResultHigh(
Result.extractBits(64, 64), DestUnsigned);
14599 ResultElements.push_back(
APValue(ResultLow));
14600 ResultElements.push_back(
APValue(ResultHigh));
14603 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14605 case Builtin::BI__builtin_elementwise_clmul:
14606 return EvaluateBinOpExpr(llvm::APIntOps::clmul);
14607 case Builtin::BI__builtin_elementwise_pext:
14608 return EvaluateBinOpExpr(llvm::APIntOps::pext);
14609 case Builtin::BI__builtin_elementwise_pdep:
14610 return EvaluateBinOpExpr(llvm::APIntOps::pdep);
14611 case Builtin::BI__builtin_elementwise_fshl:
14612 case Builtin::BI__builtin_elementwise_fshr: {
14613 APValue SourceHi, SourceLo, SourceShift;
14619 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14625 ResultElements.reserve(SourceLen);
14626 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
14630 switch (BuiltinOp) {
14631 case Builtin::BI__builtin_elementwise_fshl:
14632 ResultElements.push_back(
APValue(
14633 APSInt(llvm::APIntOps::fshl(Hi, Lo, Shift), Hi.isUnsigned())));
14635 case Builtin::BI__builtin_elementwise_fshr:
14636 ResultElements.push_back(
APValue(
14637 APSInt(llvm::APIntOps::fshr(Hi, Lo, Shift), Hi.isUnsigned())));
14642 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14645 case X86::BI__builtin_ia32_shuf_f32x4_256:
14646 case X86::BI__builtin_ia32_shuf_i32x4_256:
14647 case X86::BI__builtin_ia32_shuf_f64x2_256:
14648 case X86::BI__builtin_ia32_shuf_i64x2_256:
14649 case X86::BI__builtin_ia32_shuf_f32x4:
14650 case X86::BI__builtin_ia32_shuf_i32x4:
14651 case X86::BI__builtin_ia32_shuf_f64x2:
14652 case X86::BI__builtin_ia32_shuf_i64x2: {
14666 unsigned ElemBits = Info.Ctx.getTypeSize(ElemQT);
14667 unsigned LaneBits = 128u;
14668 unsigned NumLanes = (NumElems * ElemBits) / LaneBits;
14669 unsigned NumElemsPerLane = LaneBits / ElemBits;
14673 ResultElements.reserve(DstLen);
14678 [NumLanes, NumElemsPerLane](
unsigned DstIdx,
unsigned ShuffleMask)
14679 -> std::pair<unsigned, int> {
14681 unsigned BitsPerElem = NumLanes / 2;
14682 unsigned IndexMask = (1u << BitsPerElem) - 1;
14683 unsigned Lane = DstIdx / NumElemsPerLane;
14684 unsigned SrcIdx = (Lane < NumLanes / 2) ? 0 : 1;
14685 unsigned BitIdx = BitsPerElem * Lane;
14686 unsigned SrcLaneIdx = (ShuffleMask >> BitIdx) & IndexMask;
14687 unsigned ElemInLane = DstIdx % NumElemsPerLane;
14688 unsigned IdxToPick = SrcLaneIdx * NumElemsPerLane + ElemInLane;
14689 return {SrcIdx, IdxToPick};
14695 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v16qi:
14696 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v32qi:
14697 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v64qi:
14698 case X86::BI__builtin_ia32_vgf2p8affineqb_v16qi:
14699 case X86::BI__builtin_ia32_vgf2p8affineqb_v32qi:
14700 case X86::BI__builtin_ia32_vgf2p8affineqb_v64qi: {
14712 bool IsInverse =
false;
14713 switch (BuiltinOp) {
14714 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v16qi:
14715 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v32qi:
14716 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v64qi: {
14721 unsigned NumBitsInByte = 8;
14722 unsigned NumBytesInQWord = 8;
14723 unsigned NumBitsInQWord = 64;
14725 unsigned NumQWords = NumBytes / NumBytesInQWord;
14727 Result.reserve(NumBytes);
14730 for (
unsigned QWordIdx = 0; QWordIdx != NumQWords; ++QWordIdx) {
14732 APInt XQWord(NumBitsInQWord, 0);
14733 APInt AQWord(NumBitsInQWord, 0);
14734 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
14735 unsigned Idx = QWordIdx * NumBytesInQWord + ByteIdx;
14736 APInt XByte =
X.getVectorElt(Idx).getInt();
14738 XQWord.insertBits(XByte, ByteIdx * NumBitsInByte);
14739 AQWord.insertBits(AByte, ByteIdx * NumBitsInByte);
14742 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
14744 XQWord.lshr(ByteIdx * NumBitsInByte).getLoBits(8).getZExtValue();
14753 case X86::BI__builtin_ia32_vgf2p8mulb_v16qi:
14754 case X86::BI__builtin_ia32_vgf2p8mulb_v32qi:
14755 case X86::BI__builtin_ia32_vgf2p8mulb_v64qi: {
14766 Result.reserve(NumBytes);
14768 for (
unsigned ByteIdx = 0; ByteIdx != NumBytes; ++ByteIdx) {
14778 case X86::BI__builtin_ia32_insertf32x4_256:
14779 case X86::BI__builtin_ia32_inserti32x4_256:
14780 case X86::BI__builtin_ia32_insertf64x2_256:
14781 case X86::BI__builtin_ia32_inserti64x2_256:
14782 case X86::BI__builtin_ia32_insertf32x4:
14783 case X86::BI__builtin_ia32_inserti32x4:
14784 case X86::BI__builtin_ia32_insertf64x2_512:
14785 case X86::BI__builtin_ia32_inserti64x2_512:
14786 case X86::BI__builtin_ia32_insertf32x8:
14787 case X86::BI__builtin_ia32_inserti32x8:
14788 case X86::BI__builtin_ia32_insertf64x4:
14789 case X86::BI__builtin_ia32_inserti64x4:
14790 case X86::BI__builtin_ia32_vinsertf128_ps256:
14791 case X86::BI__builtin_ia32_vinsertf128_pd256:
14792 case X86::BI__builtin_ia32_vinsertf128_si256:
14793 case X86::BI__builtin_ia32_insert128i256: {
14794 APValue SourceDst, SourceSub;
14806 assert(SubLen != 0 && DstLen != 0 && (DstLen % SubLen) == 0);
14807 unsigned NumLanes = DstLen / SubLen;
14808 unsigned LaneIdx = (Imm.getZExtValue() % NumLanes) * SubLen;
14811 ResultElements.reserve(DstLen);
14813 for (
unsigned EltNum = 0; EltNum < DstLen; ++EltNum) {
14814 if (EltNum >= LaneIdx && EltNum < LaneIdx + SubLen)
14815 ResultElements.push_back(SourceSub.
getVectorElt(EltNum - LaneIdx));
14817 ResultElements.push_back(SourceDst.
getVectorElt(EltNum));
14820 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14823 case clang::X86::BI__builtin_ia32_vec_set_v4hi:
14824 case clang::X86::BI__builtin_ia32_vec_set_v16qi:
14825 case clang::X86::BI__builtin_ia32_vec_set_v8hi:
14826 case clang::X86::BI__builtin_ia32_vec_set_v4si:
14827 case clang::X86::BI__builtin_ia32_vec_set_v2di:
14828 case clang::X86::BI__builtin_ia32_vec_set_v32qi:
14829 case clang::X86::BI__builtin_ia32_vec_set_v16hi:
14830 case clang::X86::BI__builtin_ia32_vec_set_v8si:
14831 case clang::X86::BI__builtin_ia32_vec_set_v4di: {
14839 QualType ElemTy = E->
getType()->
castAs<VectorType>()->getElementType();
14840 unsigned ElemWidth = Info.Ctx.getIntWidth(ElemTy);
14842 Scalar.setIsUnsigned(ElemUnsigned);
14848 static_cast<unsigned>(IndexAPS.getZExtValue() & (NumElems - 1));
14851 Elems.reserve(NumElems);
14852 for (
unsigned ElemNum = 0; ElemNum != NumElems; ++ElemNum)
14853 Elems.push_back(ElemNum == Index ? ElemAV : VecVal.
getVectorElt(ElemNum));
14858 case X86::BI__builtin_ia32_pslldqi128_byteshift:
14859 case X86::BI__builtin_ia32_pslldqi256_byteshift:
14860 case X86::BI__builtin_ia32_pslldqi512_byteshift: {
14864 [](
unsigned DstIdx,
unsigned Shift) -> std::pair<unsigned, int> {
14865 unsigned LaneBase = (DstIdx / 16) * 16;
14866 unsigned LaneIdx = DstIdx % 16;
14867 if (LaneIdx < Shift)
14868 return std::make_pair(0, -1);
14870 return std::make_pair(
14871 0,
static_cast<int>(LaneBase + LaneIdx - Shift));
14877 case X86::BI__builtin_ia32_psrldqi128_byteshift:
14878 case X86::BI__builtin_ia32_psrldqi256_byteshift:
14879 case X86::BI__builtin_ia32_psrldqi512_byteshift: {
14883 [](
unsigned DstIdx,
unsigned Shift) -> std::pair<unsigned, int> {
14884 unsigned LaneBase = (DstIdx / 16) * 16;
14885 unsigned LaneIdx = DstIdx % 16;
14886 if (LaneIdx + Shift < 16)
14887 return std::make_pair(
14888 0,
static_cast<int>(LaneBase + LaneIdx + Shift));
14890 return std::make_pair(0, -1);
14896 case X86::BI__builtin_ia32_palignr128:
14897 case X86::BI__builtin_ia32_palignr256:
14898 case X86::BI__builtin_ia32_palignr512: {
14902 unsigned VecIdx = 1;
14905 int Lane = DstIdx / 16;
14906 int Offset = DstIdx % 16;
14909 unsigned ShiftedIdx = Offset + (
Shift & 0xFF);
14910 if (ShiftedIdx < 16) {
14911 ElemIdx = ShiftedIdx + (Lane * 16);
14912 }
else if (ShiftedIdx < 32) {
14914 ElemIdx = (ShiftedIdx - 16) + (Lane * 16);
14917 return std::pair<unsigned, int>{VecIdx, ElemIdx};
14922 case X86::BI__builtin_ia32_alignd128:
14923 case X86::BI__builtin_ia32_alignd256:
14924 case X86::BI__builtin_ia32_alignd512:
14925 case X86::BI__builtin_ia32_alignq128:
14926 case X86::BI__builtin_ia32_alignq256:
14927 case X86::BI__builtin_ia32_alignq512: {
14929 unsigned NumElems = E->
getType()->
castAs<VectorType>()->getNumElements();
14931 [NumElems](
unsigned DstIdx,
unsigned Shift) {
14932 unsigned Imm =
Shift & 0xFF;
14933 unsigned EffectiveShift = Imm & (NumElems - 1);
14934 unsigned SourcePos = DstIdx + EffectiveShift;
14935 unsigned VecIdx = SourcePos < NumElems ? 1 : 0;
14936 unsigned ElemIdx = SourcePos & (NumElems - 1);
14938 return std::pair<unsigned, int>{
14939 VecIdx,
static_cast<int>(ElemIdx)};
14944 case X86::BI__builtin_ia32_permvarsi256:
14945 case X86::BI__builtin_ia32_permvarsf256:
14946 case X86::BI__builtin_ia32_permvardf512:
14947 case X86::BI__builtin_ia32_permvardi512:
14948 case X86::BI__builtin_ia32_permvarhi128: {
14951 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14952 int Offset = ShuffleMask & 0x7;
14953 return std::pair<unsigned, int>{0, Offset};
14958 case X86::BI__builtin_ia32_permvarqi128:
14959 case X86::BI__builtin_ia32_permvarhi256:
14960 case X86::BI__builtin_ia32_permvarsi512:
14961 case X86::BI__builtin_ia32_permvarsf512: {
14964 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14965 int Offset = ShuffleMask & 0xF;
14966 return std::pair<unsigned, int>{0, Offset};
14971 case X86::BI__builtin_ia32_permvardi256:
14972 case X86::BI__builtin_ia32_permvardf256: {
14975 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14976 int Offset = ShuffleMask & 0x3;
14977 return std::pair<unsigned, int>{0, Offset};
14982 case X86::BI__builtin_ia32_permvarqi256:
14983 case X86::BI__builtin_ia32_permvarhi512: {
14986 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14987 int Offset = ShuffleMask & 0x1F;
14988 return std::pair<unsigned, int>{0, Offset};
14993 case X86::BI__builtin_ia32_permvarqi512: {
14996 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14997 int Offset = ShuffleMask & 0x3F;
14998 return std::pair<unsigned, int>{0, Offset};
15003 case X86::BI__builtin_ia32_vpermi2varq128:
15004 case X86::BI__builtin_ia32_vpermi2varpd128: {
15007 [](
unsigned DstIdx,
unsigned ShuffleMask) {
15008 int Offset = ShuffleMask & 0x1;
15009 unsigned SrcIdx = (ShuffleMask >> 1) & 0x1;
15010 return std::pair<unsigned, int>{SrcIdx, Offset};
15015 case X86::BI__builtin_ia32_vpermi2vard128:
15016 case X86::BI__builtin_ia32_vpermi2varps128:
15017 case X86::BI__builtin_ia32_vpermi2varq256:
15018 case X86::BI__builtin_ia32_vpermi2varpd256: {
15021 [](
unsigned DstIdx,
unsigned ShuffleMask) {
15022 int Offset = ShuffleMask & 0x3;
15023 unsigned SrcIdx = (ShuffleMask >> 2) & 0x1;
15024 return std::pair<unsigned, int>{SrcIdx, Offset};
15029 case X86::BI__builtin_ia32_vpermi2varhi128:
15030 case X86::BI__builtin_ia32_vpermi2vard256:
15031 case X86::BI__builtin_ia32_vpermi2varps256:
15032 case X86::BI__builtin_ia32_vpermi2varq512:
15033 case X86::BI__builtin_ia32_vpermi2varpd512: {
15036 [](
unsigned DstIdx,
unsigned ShuffleMask) {
15037 int Offset = ShuffleMask & 0x7;
15038 unsigned SrcIdx = (ShuffleMask >> 3) & 0x1;
15039 return std::pair<unsigned, int>{SrcIdx, Offset};
15044 case X86::BI__builtin_ia32_vpermi2varqi128:
15045 case X86::BI__builtin_ia32_vpermi2varhi256:
15046 case X86::BI__builtin_ia32_vpermi2vard512:
15047 case X86::BI__builtin_ia32_vpermi2varps512: {
15050 [](
unsigned DstIdx,
unsigned ShuffleMask) {
15051 int Offset = ShuffleMask & 0xF;
15052 unsigned SrcIdx = (ShuffleMask >> 4) & 0x1;
15053 return std::pair<unsigned, int>{SrcIdx, Offset};
15058 case X86::BI__builtin_ia32_vpermi2varqi256:
15059 case X86::BI__builtin_ia32_vpermi2varhi512: {
15062 [](
unsigned DstIdx,
unsigned ShuffleMask) {
15063 int Offset = ShuffleMask & 0x1F;
15064 unsigned SrcIdx = (ShuffleMask >> 5) & 0x1;
15065 return std::pair<unsigned, int>{SrcIdx, Offset};
15070 case X86::BI__builtin_ia32_vpermi2varqi512: {
15073 [](
unsigned DstIdx,
unsigned ShuffleMask) {
15074 int Offset = ShuffleMask & 0x3F;
15075 unsigned SrcIdx = (ShuffleMask >> 6) & 0x1;
15076 return std::pair<unsigned, int>{SrcIdx, Offset};
15082 case clang::X86::BI__builtin_ia32_minps:
15083 case clang::X86::BI__builtin_ia32_minpd:
15084 case clang::X86::BI__builtin_ia32_minps256:
15085 case clang::X86::BI__builtin_ia32_minpd256:
15086 case clang::X86::BI__builtin_ia32_minps512:
15087 case clang::X86::BI__builtin_ia32_minpd512:
15088 case clang::X86::BI__builtin_ia32_minph128:
15089 case clang::X86::BI__builtin_ia32_minph256:
15090 case clang::X86::BI__builtin_ia32_minph512:
15091 return EvaluateFpBinOpExpr(
15092 [](
const APFloat &A,
const APFloat &B,
15093 std::optional<APSInt>) -> std::optional<APFloat> {
15094 if (A.isNaN() || A.isInfinity() || A.isDenormal() || B.isNaN() ||
15095 B.isInfinity() || B.isDenormal())
15096 return std::nullopt;
15097 if (A.isZero() && B.isZero())
15099 return llvm::minimum(A, B);
15102 case clang::X86::BI__builtin_ia32_minss:
15103 case clang::X86::BI__builtin_ia32_minsd:
15104 return EvaluateFpBinOpExpr(
15105 [](
const APFloat &A,
const APFloat &B,
15106 std::optional<APSInt> RoundingMode) -> std::optional<APFloat> {
15111 case clang::X86::BI__builtin_ia32_minsd_round_mask:
15112 case clang::X86::BI__builtin_ia32_minss_round_mask:
15113 case clang::X86::BI__builtin_ia32_minsh_round_mask:
15114 case clang::X86::BI__builtin_ia32_maxsd_round_mask:
15115 case clang::X86::BI__builtin_ia32_maxss_round_mask:
15116 case clang::X86::BI__builtin_ia32_maxsh_round_mask: {
15117 bool IsMin = BuiltinOp == clang::X86::BI__builtin_ia32_minsd_round_mask ||
15118 BuiltinOp == clang::X86::BI__builtin_ia32_minss_round_mask ||
15119 BuiltinOp == clang::X86::BI__builtin_ia32_minsh_round_mask;
15120 return EvaluateScalarFpRoundMaskBinOp(
15121 [IsMin](
const APFloat &A,
const APFloat &B,
15122 std::optional<APSInt> RoundingMode) -> std::optional<APFloat> {
15127 case clang::X86::BI__builtin_ia32_maxps:
15128 case clang::X86::BI__builtin_ia32_maxpd:
15129 case clang::X86::BI__builtin_ia32_maxps256:
15130 case clang::X86::BI__builtin_ia32_maxpd256:
15131 case clang::X86::BI__builtin_ia32_maxps512:
15132 case clang::X86::BI__builtin_ia32_maxpd512:
15133 case clang::X86::BI__builtin_ia32_maxph128:
15134 case clang::X86::BI__builtin_ia32_maxph256:
15135 case clang::X86::BI__builtin_ia32_maxph512:
15136 return EvaluateFpBinOpExpr(
15137 [](
const APFloat &A,
const APFloat &B,
15138 std::optional<APSInt>) -> std::optional<APFloat> {
15139 if (A.isNaN() || A.isInfinity() || A.isDenormal() || B.isNaN() ||
15140 B.isInfinity() || B.isDenormal())
15141 return std::nullopt;
15142 if (A.isZero() && B.isZero())
15144 return llvm::maximum(A, B);
15147 case clang::X86::BI__builtin_ia32_maxss:
15148 case clang::X86::BI__builtin_ia32_maxsd:
15149 return EvaluateFpBinOpExpr(
15150 [](
const APFloat &A,
const APFloat &B,
15151 std::optional<APSInt> RoundingMode) -> std::optional<APFloat> {
15156 case clang::X86::BI__builtin_ia32_vcvtps2ph:
15157 case clang::X86::BI__builtin_ia32_vcvtps2ph256: {
15167 unsigned SrcNumElems = SrcVTy->getNumElements();
15169 unsigned DstNumElems = DstVTy->getNumElements();
15170 QualType DstElemTy = DstVTy->getElementType();
15172 const llvm::fltSemantics &HalfSem =
15173 Info.Ctx.getFloatTypeSemantics(Info.Ctx.HalfTy);
15175 int ImmVal = Imm.getZExtValue();
15176 bool UseMXCSR = (ImmVal & 4) != 0;
15177 bool IsFPConstrained =
15180 llvm::RoundingMode RM;
15182 switch (ImmVal & 3) {
15184 RM = llvm::RoundingMode::NearestTiesToEven;
15187 RM = llvm::RoundingMode::TowardNegative;
15190 RM = llvm::RoundingMode::TowardPositive;
15193 RM = llvm::RoundingMode::TowardZero;
15196 llvm_unreachable(
"Invalid immediate rounding mode");
15199 RM = llvm::RoundingMode::NearestTiesToEven;
15203 ResultElements.reserve(DstNumElems);
15205 for (
unsigned I = 0; I < SrcNumElems; ++I) {
15209 APFloat::opStatus St = SrcVal.convert(HalfSem, RM, &LostInfo);
15211 if (UseMXCSR && IsFPConstrained && St != APFloat::opOK) {
15212 Info.FFDiag(E, diag::note_constexpr_dynamic_rounding);
15216 APSInt DstInt(SrcVal.bitcastToAPInt(),
15218 ResultElements.push_back(
APValue(DstInt));
15221 if (DstNumElems > SrcNumElems) {
15222 APSInt Zero = Info.Ctx.MakeIntValue(0, DstElemTy);
15223 for (
unsigned I = SrcNumElems; I < DstNumElems; ++I) {
15228 return Success(ResultElements, E);
15230 case X86::BI__builtin_ia32_vperm2f128_pd256:
15231 case X86::BI__builtin_ia32_vperm2f128_ps256:
15232 case X86::BI__builtin_ia32_vperm2f128_si256:
15233 case X86::BI__builtin_ia32_permti256: {
15234 unsigned NumElements =
15236 unsigned PreservedBitsCnt = NumElements >> 2;
15240 [PreservedBitsCnt](
unsigned DstIdx,
unsigned ShuffleMask) {
15241 unsigned ControlBitsCnt = DstIdx >> PreservedBitsCnt << 2;
15242 unsigned ControlBits = ShuffleMask >> ControlBitsCnt;
15244 if (ControlBits & 0b1000)
15245 return std::make_pair(0u, -1);
15247 unsigned SrcVecIdx = (ControlBits & 0b10) >> 1;
15248 unsigned PreservedBitsMask = (1 << PreservedBitsCnt) - 1;
15249 int SrcIdx = ((ControlBits & 0b1) << PreservedBitsCnt) |
15250 (DstIdx & PreservedBitsMask);
15251 return std::make_pair(SrcVecIdx, SrcIdx);
15256 case X86::BI__builtin_ia32_vpdpwssd128:
15257 case X86::BI__builtin_ia32_vpdpwssd256:
15258 case X86::BI__builtin_ia32_vpdpwssd512:
15259 case X86::BI__builtin_ia32_vpdpbusd128:
15260 case X86::BI__builtin_ia32_vpdpbusd256:
15261 case X86::BI__builtin_ia32_vpdpbusd512:
15262 return EvalVectorDotProduct(
false);
15263 case X86::BI__builtin_ia32_vpdpwssds128:
15264 case X86::BI__builtin_ia32_vpdpwssds256:
15265 case X86::BI__builtin_ia32_vpdpwssds512:
15266 case X86::BI__builtin_ia32_vpdpbusds128:
15267 case X86::BI__builtin_ia32_vpdpbusds256:
15268 case X86::BI__builtin_ia32_vpdpbusds512:
15269 return EvalVectorDotProduct(
true);
15273bool VectorExprEvaluator::VisitConvertVectorExpr(
const ConvertVectorExpr *E) {
15279 QualType DestTy = E->
getType()->
castAs<VectorType>()->getElementType();
15280 QualType SourceTy = SourceVecType->
castAs<VectorType>()->getElementType();
15286 ResultElements.reserve(SourceLen);
15287 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
15292 ResultElements.push_back(std::move(Elt));
15295 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
15300 APValue const &VecVal2,
unsigned EltNum,
15302 unsigned const TotalElementsInInputVector1 = VecVal1.
getVectorLength();
15303 unsigned const TotalElementsInInputVector2 = VecVal2.
getVectorLength();
15306 int64_t
index = IndexVal.getExtValue();
15313 E, diag::err_shufflevector_minus_one_is_undefined_behavior_constexpr)
15319 index >= TotalElementsInInputVector1 + TotalElementsInInputVector2)
15320 llvm_unreachable(
"Out of bounds shuffle index");
15322 if (
index >= TotalElementsInInputVector1)
15329bool VectorExprEvaluator::VisitShuffleVectorExpr(
const ShuffleVectorExpr *E) {
15334 const Expr *Vec1 = E->
getExpr(0);
15338 const Expr *Vec2 = E->
getExpr(1);
15342 VectorType
const *DestVecTy = E->
getType()->
castAs<VectorType>();
15348 ResultElements.reserve(TotalElementsInOutputVector);
15349 for (
unsigned EltNum = 0; EltNum < TotalElementsInOutputVector; ++EltNum) {
15353 ResultElements.push_back(std::move(Elt));
15356 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
15364class MatrixExprEvaluator :
public ExprEvaluatorBase<MatrixExprEvaluator> {
15371 bool Success(ArrayRef<APValue> M,
const Expr *E) {
15373 assert(M.size() == CMTy->getNumElementsFlattened());
15375 Result =
APValue(M.data(), CMTy->getNumRows(), CMTy->getNumColumns());
15379 assert(M.
isMatrix() &&
"expected matrix");
15384 bool VisitCastExpr(
const CastExpr *E);
15385 bool VisitInitListExpr(
const InitListExpr *E);
15391 "not a matrix prvalue");
15392 return MatrixExprEvaluator(Info,
Result).Visit(E);
15395bool MatrixExprEvaluator::VisitCastExpr(
const CastExpr *E) {
15396 const auto *MT = E->
getType()->
castAs<ConstantMatrixType>();
15397 unsigned NumRows = MT->getNumRows();
15398 unsigned NumCols = MT->getNumColumns();
15399 unsigned NElts = NumRows * NumCols;
15400 QualType EltTy = MT->getElementType();
15404 case CK_HLSLAggregateSplatCast: {
15419 case CK_HLSLElementwiseCast: {
15432 return Success(ResultEls, E);
15435 return ExprEvaluatorBaseTy::VisitCastExpr(E);
15439bool MatrixExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
15440 const auto *MT = E->
getType()->
castAs<ConstantMatrixType>();
15441 QualType EltTy = MT->getElementType();
15443 assert(E->
getNumInits() == MT->getNumElementsFlattened() &&
15444 "Expected number of elements in initializer list to match the number "
15445 "of matrix elements");
15448 Elements.reserve(MT->getNumElementsFlattened());
15453 for (
unsigned I = 0, N = MT->getNumElementsFlattened(); I < N; ++I) {
15454 if (EltTy->isIntegerType()) {
15455 llvm::APSInt IntVal;
15458 Elements.push_back(
APValue(IntVal));
15460 llvm::APFloat FloatVal(0.0);
15463 Elements.push_back(
APValue(FloatVal));
15475 class ArrayExprEvaluator
15476 :
public ExprEvaluatorBase<ArrayExprEvaluator> {
15477 const LValue &
This;
15481 ArrayExprEvaluator(EvalInfo &Info,
const LValue &This,
APValue &
Result)
15485 assert(
V.isArray() &&
"expected array");
15490 bool ZeroInitialization(
const Expr *E) {
15491 const ConstantArrayType *CAT =
15492 Info.Ctx.getAsConstantArrayType(E->
getType());
15506 if (!
Result.hasArrayFiller())
15510 LValue Subobject =
This;
15511 Subobject.addArray(Info, E, CAT);
15516 bool VisitCallExpr(
const CallExpr *E) {
15517 return handleCallExpr(E,
Result, &This);
15519 bool VisitCastExpr(
const CastExpr *E);
15520 bool VisitInitListExpr(
const InitListExpr *E,
15521 QualType AllocType = QualType());
15522 bool VisitArrayInitLoopExpr(
const ArrayInitLoopExpr *E);
15523 bool VisitCXXConstructExpr(
const CXXConstructExpr *E);
15524 bool VisitCXXConstructExpr(
const CXXConstructExpr *E,
15525 const LValue &Subobject,
15527 bool VisitStringLiteral(
const StringLiteral *E,
15528 QualType AllocType = QualType()) {
15532 bool VisitCXXParenListInitExpr(
const CXXParenListInitExpr *E);
15533 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
15534 ArrayRef<Expr *> Args,
15535 const Expr *ArrayFiller,
15536 QualType AllocType = QualType());
15537 bool VisitDesignatedInitUpdateExpr(
const DesignatedInitUpdateExpr *E);
15545 "not an array prvalue");
15546 return ArrayExprEvaluator(Info,
This,
Result).Visit(E);
15554 "not an array prvalue");
15555 return ArrayExprEvaluator(Info,
This,
Result)
15556 .VisitInitListExpr(ILE, AllocType);
15565 "not an array prvalue");
15566 return ArrayExprEvaluator(Info,
This,
Result)
15567 .VisitCXXConstructExpr(CCE,
This, &
Result, AllocType);
15576 if (
const InitListExpr *ILE = dyn_cast<InitListExpr>(FillerExpr)) {
15577 for (
unsigned I = 0, E = ILE->
getNumInits(); I != E; ++I) {
15582 if (ILE->hasArrayFiller() &&
15591bool ArrayExprEvaluator::VisitCastExpr(
const CastExpr *E) {
15596 return ExprEvaluatorBaseTy::VisitCastExpr(E);
15597 case CK_HLSLAggregateSplatCast: {
15617 case CK_HLSLElementwiseCast: {
15634bool ArrayExprEvaluator::VisitInitListExpr(
const InitListExpr *E,
15635 QualType AllocType) {
15636 const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(
15649 return VisitStringLiteral(SL, AllocType);
15654 "transparent array list initialization is not string literal init?");
15660bool ArrayExprEvaluator::VisitCXXParenListOrInitListExpr(
15662 QualType AllocType) {
15663 const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(
15668 unsigned NumEltsToInit = Args.size();
15673 if (NumEltsToInit != NumElts &&
15675 NumEltsToInit = NumElts;
15678 for (
auto *
Init : Args) {
15679 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts()))
15680 NumEltsToInit += EmbedS->getDataElementCount() - 1;
15683 if (NumEltsToInit > NumElts)
15684 NumEltsToInit = NumElts;
15688 if (
Result.hasValue() && NumEltsToInit <
Result.getArrayInitializedElts())
15689 NumEltsToInit =
Result.getArrayInitializedElts();
15692 LLVM_DEBUG(llvm::dbgs() <<
"The number of elements to initialize: "
15693 << NumEltsToInit <<
".\n");
15695 if (!
Result.hasValue()) {
15696 Result =
APValue(APValue::UninitArray(), NumEltsToInit, NumElts);
15697 }
else if (
Result.getArrayInitializedElts() != NumEltsToInit) {
15708 APValue NewResult =
APValue(APValue::UninitArray(), NumEltsToInit, NumElts);
15710 unsigned NumOldElts =
Result.getArrayInitializedElts();
15711 for (
unsigned I = 0; I < NumOldElts; ++I) {
15713 std::move(
Result.getArrayInitializedElt(I));
15716 for (
unsigned I =
Result.getArrayInitializedElts(); I < NumEltsToInit; ++I)
15720 Result = std::move(NewResult);
15723 LValue Subobject =
This;
15724 Subobject.addArray(Info, ExprToVisit, CAT);
15725 auto Eval = [&](
const Expr *
Init,
unsigned ArrayIndex) {
15726 if (
Init->isValueDependent())
15735 Subobject,
Init) ||
15738 if (!Info.noteFailure())
15744 unsigned ArrayIndex = 0;
15747 for (
unsigned Index = 0; Index != NumEltsToInit; ++Index) {
15748 const Expr *
Init = Index < Args.size() ? Args[Index] : ArrayFiller;
15749 if (ArrayIndex >= NumEltsToInit)
15751 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
15752 StringLiteral *SL = EmbedS->getDataStringLiteral();
15753 for (
unsigned I = EmbedS->getStartingElementPos(),
15754 N = EmbedS->getDataElementCount();
15755 I != EmbedS->getStartingElementPos() + N; ++I) {
15761 const FPOptions FPO =
15762 Init->getFPFeaturesInEffect(Info.Ctx.getLangOpts());
15767 Result.getArrayInitializedElt(ArrayIndex) =
APValue(FValue);
15772 if (!Eval(
Init, ArrayIndex))
15778 if (!
Result.hasArrayFiller())
15783 assert(ArrayFiller &&
"no array filler for incomplete init list");
15789bool ArrayExprEvaluator::VisitArrayInitLoopExpr(
const ArrayInitLoopExpr *E) {
15792 !
Evaluate(Info.CurrentCall->createTemporary(
15795 ScopeKind::FullExpression, CommonLV),
15802 Result =
APValue(APValue::UninitArray(), Elements, Elements);
15804 LValue Subobject =
This;
15805 Subobject.addArray(Info, E, CAT);
15808 for (EvalInfo::ArrayInitLoopIndex Index(Info); Index != Elements; ++Index) {
15817 FullExpressionRAII Scope(Info);
15823 if (!Info.noteFailure())
15835bool ArrayExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E) {
15836 return VisitCXXConstructExpr(E, This, &
Result, E->
getType());
15839bool ArrayExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E,
15840 const LValue &Subobject,
15843 bool HadZeroInit =
Value->hasValue();
15845 if (
const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(
Type)) {
15850 HadZeroInit &&
Value->hasArrayFiller() ?
Value->getArrayFiller()
15853 *
Value =
APValue(APValue::UninitArray(), 0, FinalSize);
15854 if (FinalSize == 0)
15860 LValue ArrayElt = Subobject;
15861 ArrayElt.addArray(Info, E, CAT);
15867 for (
const unsigned N : {1u, FinalSize}) {
15868 unsigned OldElts =
Value->getArrayInitializedElts();
15873 APValue NewValue(APValue::UninitArray(), N, FinalSize);
15874 for (
unsigned I = 0; I < OldElts; ++I)
15875 NewValue.getArrayInitializedElt(I).swap(
15876 Value->getArrayInitializedElt(I));
15877 Value->swap(NewValue);
15880 for (
unsigned I = OldElts; I < N; ++I)
15881 Value->getArrayInitializedElt(I) = Filler;
15883 if (HasTrivialConstructor && N == FinalSize && FinalSize != 1) {
15886 APValue &FirstResult =
Value->getArrayInitializedElt(0);
15887 for (
unsigned I = OldElts; I < FinalSize; ++I)
15888 Value->getArrayInitializedElt(I) = FirstResult;
15890 for (
unsigned I = OldElts; I < N; ++I) {
15891 if (!VisitCXXConstructExpr(E, ArrayElt,
15892 &
Value->getArrayInitializedElt(I),
15899 if (Info.EvalStatus.Diag && !Info.EvalStatus.Diag->empty() &&
15900 !Info.keepEvaluatingAfterFailure())
15909 if (!
Type->isRecordType())
15912 return RecordExprEvaluator(Info, Subobject, *
Value)
15913 .VisitCXXConstructExpr(E,
Type);
15916bool ArrayExprEvaluator::VisitCXXParenListInitExpr(
15917 const CXXParenListInitExpr *E) {
15919 "Expression result is not a constant array type");
15921 return VisitCXXParenListOrInitListExpr(E, E->
getInitExprs(),
15925bool ArrayExprEvaluator::VisitDesignatedInitUpdateExpr(
15926 const DesignatedInitUpdateExpr *E) {
15941class IntExprEvaluator
15942 :
public ExprEvaluatorBase<IntExprEvaluator> {
15945 IntExprEvaluator(EvalInfo &info,
APValue &result)
15946 : ExprEvaluatorBaseTy(
info),
Result(result) {}
15950 "Invalid evaluation result.");
15952 "Invalid evaluation result.");
15953 assert(SI.getBitWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
15954 "Invalid evaluation result.");
15958 bool Success(
const llvm::APSInt &SI,
const Expr *E) {
15964 "Invalid evaluation result.");
15965 assert(I.getBitWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
15966 "Invalid evaluation result.");
15968 Result.getInt().setIsUnsigned(
15972 bool Success(
const llvm::APInt &I,
const Expr *E) {
15978 "Invalid evaluation result.");
15986 bool Success(CharUnits Size,
const Expr *E) {
15993 if (
V.isLValue() ||
V.isAddrLabelDiff() ||
V.isIndeterminate() ||
15994 V.allowConstexprUnknown()) {
16001 bool ZeroInitialization(
const Expr *E) {
return Success(0, E); }
16003 friend std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &,
16010 bool VisitIntegerLiteral(
const IntegerLiteral *E) {
16013 bool VisitCharacterLiteral(
const CharacterLiteral *E) {
16017 bool CheckReferencedDecl(
const Expr *E,
const Decl *D);
16018 bool VisitDeclRefExpr(
const DeclRefExpr *E) {
16019 if (CheckReferencedDecl(E, E->
getDecl()))
16022 return ExprEvaluatorBaseTy::VisitDeclRefExpr(E);
16024 bool VisitMemberExpr(
const MemberExpr *E) {
16026 VisitIgnoredBaseExpression(E->
getBase());
16030 return ExprEvaluatorBaseTy::VisitMemberExpr(E);
16033 bool VisitCallExpr(
const CallExpr *E);
16034 bool VisitBuiltinCallExpr(
const CallExpr *E,
unsigned BuiltinOp);
16035 bool VisitBinaryOperator(
const BinaryOperator *E);
16036 bool VisitOffsetOfExpr(
const OffsetOfExpr *E);
16037 bool VisitUnaryOperator(
const UnaryOperator *E);
16039 bool VisitCastExpr(
const CastExpr* E);
16040 bool VisitUnaryExprOrTypeTraitExpr(
const UnaryExprOrTypeTraitExpr *E);
16042 bool VisitCXXBoolLiteralExpr(
const CXXBoolLiteralExpr *E) {
16046 bool VisitObjCBoolLiteralExpr(
const ObjCBoolLiteralExpr *E) {
16050 bool VisitArrayInitIndexExpr(
const ArrayInitIndexExpr *E) {
16051 if (Info.ArrayInitIndex ==
uint64_t(-1)) {
16057 return Success(Info.ArrayInitIndex, E);
16061 bool VisitGNUNullExpr(
const GNUNullExpr *E) {
16062 return ZeroInitialization(E);
16065 bool VisitTypeTraitExpr(
const TypeTraitExpr *E) {
16074 bool VisitArrayTypeTraitExpr(
const ArrayTypeTraitExpr *E) {
16078 bool VisitExpressionTraitExpr(
const ExpressionTraitExpr *E) {
16082 bool VisitOpenACCAsteriskSizeExpr(
const OpenACCAsteriskSizeExpr *E) {
16089 bool VisitUnaryReal(
const UnaryOperator *E);
16090 bool VisitUnaryImag(
const UnaryOperator *E);
16092 bool VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E);
16093 bool VisitSizeOfPackExpr(
const SizeOfPackExpr *E);
16094 bool VisitSourceLocExpr(
const SourceLocExpr *E);
16095 bool VisitConceptSpecializationExpr(
const ConceptSpecializationExpr *E);
16100class FixedPointExprEvaluator
16101 :
public ExprEvaluatorBase<FixedPointExprEvaluator> {
16105 FixedPointExprEvaluator(EvalInfo &info,
APValue &result)
16106 : ExprEvaluatorBaseTy(
info),
Result(result) {}
16108 bool Success(
const llvm::APInt &I,
const Expr *E) {
16110 APFixedPoint(I, Info.Ctx.getFixedPointSemantics(E->
getType())), E);
16115 APFixedPoint(
Value, Info.Ctx.getFixedPointSemantics(E->
getType())), E);
16119 return Success(
V.getFixedPoint(), E);
16122 bool Success(
const APFixedPoint &
V,
const Expr *E) {
16124 assert(
V.getWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
16125 "Invalid evaluation result.");
16130 bool ZeroInitialization(
const Expr *E) {
16138 bool VisitFixedPointLiteral(
const FixedPointLiteral *E) {
16142 bool VisitCastExpr(
const CastExpr *E);
16143 bool VisitUnaryOperator(
const UnaryOperator *E);
16144 bool VisitBinaryOperator(
const BinaryOperator *E);
16160 return IntExprEvaluator(Info,
Result).Visit(E);
16168 if (!Val.
isInt()) {
16171 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
16178bool IntExprEvaluator::VisitSourceLocExpr(
const SourceLocExpr *E) {
16180 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.
getDefaultExpr());
16189 if (!FixedPointExprEvaluator(Info, Val).Visit(E))
16204 auto FXSema = Info.Ctx.getFixedPointSemantics(E->
getType());
16208 Result = APFixedPoint(Val, FXSema);
16219bool IntExprEvaluator::CheckReferencedDecl(
const Expr* E,
const Decl* D) {
16221 if (
const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(D)) {
16223 bool SameSign = (ECD->getInitVal().isSigned()
16225 bool SameWidth = (ECD->getInitVal().
getBitWidth()
16226 == Info.Ctx.getIntWidth(E->
getType()));
16227 if (SameSign && SameWidth)
16228 return Success(ECD->getInitVal(), E);
16232 llvm::APSInt Val = ECD->getInitVal();
16234 Val.setIsSigned(!ECD->getInitVal().isSigned());
16236 Val = Val.extOrTrunc(Info.Ctx.getIntWidth(E->
getType()));
16247 assert(!
T->isDependentType() &&
"unexpected dependent type");
16252#define TYPE(ID, BASE)
16253#define DEPENDENT_TYPE(ID, BASE) case Type::ID:
16254#define NON_CANONICAL_TYPE(ID, BASE) case Type::ID:
16255#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(ID, BASE) case Type::ID:
16256#include "clang/AST/TypeNodes.inc"
16258 case Type::DeducedTemplateSpecialization:
16259 llvm_unreachable(
"unexpected non-canonical or dependent type");
16261 case Type::Builtin:
16263#define BUILTIN_TYPE(ID, SINGLETON_ID)
16264#define SIGNED_TYPE(ID, SINGLETON_ID) \
16265 case BuiltinType::ID: return GCCTypeClass::Integer;
16266#define FLOATING_TYPE(ID, SINGLETON_ID) \
16267 case BuiltinType::ID: return GCCTypeClass::RealFloat;
16268#define PLACEHOLDER_TYPE(ID, SINGLETON_ID) \
16269 case BuiltinType::ID: break;
16270#include "clang/AST/BuiltinTypes.def"
16271 case BuiltinType::Void:
16274 case BuiltinType::Bool:
16277 case BuiltinType::Char_U:
16278 case BuiltinType::UChar:
16279 case BuiltinType::WChar_U:
16280 case BuiltinType::Char8:
16281 case BuiltinType::Char16:
16282 case BuiltinType::Char32:
16283 case BuiltinType::UShort:
16284 case BuiltinType::UInt:
16285 case BuiltinType::ULong:
16286 case BuiltinType::ULongLong:
16287 case BuiltinType::UInt128:
16290 case BuiltinType::UShortAccum:
16291 case BuiltinType::UAccum:
16292 case BuiltinType::ULongAccum:
16293 case BuiltinType::UShortFract:
16294 case BuiltinType::UFract:
16295 case BuiltinType::ULongFract:
16296 case BuiltinType::SatUShortAccum:
16297 case BuiltinType::SatUAccum:
16298 case BuiltinType::SatULongAccum:
16299 case BuiltinType::SatUShortFract:
16300 case BuiltinType::SatUFract:
16301 case BuiltinType::SatULongFract:
16304 case BuiltinType::NullPtr:
16306 case BuiltinType::ObjCId:
16307 case BuiltinType::ObjCClass:
16308 case BuiltinType::ObjCSel:
16309#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
16310 case BuiltinType::Id:
16311#include "clang/Basic/OpenCLImageTypes.def"
16312#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
16313 case BuiltinType::Id:
16314#include "clang/Basic/OpenCLExtensionTypes.def"
16315 case BuiltinType::OCLSampler:
16316 case BuiltinType::OCLEvent:
16317 case BuiltinType::OCLClkEvent:
16318 case BuiltinType::OCLQueue:
16319 case BuiltinType::OCLReserveID:
16320#define SVE_TYPE(Name, Id, SingletonId) \
16321 case BuiltinType::Id:
16322#include "clang/Basic/AArch64ACLETypes.def"
16323#define PPC_VECTOR_TYPE(Name, Id, Size) \
16324 case BuiltinType::Id:
16325#include "clang/Basic/PPCTypes.def"
16326#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
16327#include "clang/Basic/RISCVVTypes.def"
16328#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
16329#include "clang/Basic/WebAssemblyReferenceTypes.def"
16330#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
16331#include "clang/Basic/AMDGPUTypes.def"
16332#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
16333#include "clang/Basic/HLSLIntangibleTypes.def"
16334#define SPIRV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
16335#include "clang/Basic/SPIRVTypes.def"
16338 case BuiltinType::Dependent:
16339 llvm_unreachable(
"unexpected dependent type");
16341 llvm_unreachable(
"unexpected placeholder type");
16346 case Type::Pointer:
16347 case Type::ConstantArray:
16348 case Type::VariableArray:
16349 case Type::IncompleteArray:
16350 case Type::FunctionNoProto:
16351 case Type::FunctionProto:
16352 case Type::ArrayParameter:
16355 case Type::MemberPointer:
16360 case Type::Complex:
16373 case Type::ExtVector:
16376 case Type::BlockPointer:
16377 case Type::ConstantMatrix:
16378 case Type::ObjCObject:
16379 case Type::ObjCInterface:
16380 case Type::ObjCObjectPointer:
16382 case Type::HLSLAttributedResource:
16383 case Type::HLSLInlineSpirv:
16384 case Type::OverflowBehavior:
16392 case Type::LValueReference:
16393 case Type::RValueReference:
16394 llvm_unreachable(
"invalid type for expression");
16397 llvm_unreachable(
"unexpected type class");
16422 if (
Base.isNull()) {
16425 }
else if (
const Expr *E =
Base.dyn_cast<
const Expr *>()) {
16444 SpeculativeEvaluationRAII SpeculativeEval(Info);
16449 FoldConstant Fold(Info,
true);
16467 if (ArgType->isIntegralOrEnumerationType() || ArgType->isFloatingType() ||
16468 ArgType->isAnyComplexType() || ArgType->isPointerType() ||
16469 ArgType->isNullPtrType()) {
16472 Fold.keepDiagnostics();
16481 return V.hasValue();
16492 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
16516 const auto *Cast = dyn_cast<CastExpr>(NoParens);
16517 if (Cast ==
nullptr)
16522 auto CastKind = Cast->getCastKind();
16524 CastKind != CK_AddressSpaceConversion)
16527 const auto *SubExpr = Cast->getSubExpr();
16549 assert(!LVal.Designator.Invalid);
16551 auto IsLastOrInvalidFieldDecl = [&Ctx](
const FieldDecl *FD) {
16559 auto &
Base = LVal.getLValueBase();
16560 if (
auto *ME = dyn_cast_or_null<MemberExpr>(
Base.dyn_cast<
const Expr *>())) {
16561 if (
auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
16562 if (!IsLastOrInvalidFieldDecl(FD))
16564 }
else if (
auto *IFD = dyn_cast<IndirectFieldDecl>(ME->getMemberDecl())) {
16565 for (
auto *FD : IFD->chain()) {
16574 if (LVal.Designator.FirstEntryIsAnUnsizedArray) {
16578 if (BaseType->isIncompleteArrayType())
16584 for (
unsigned E = LVal.Designator.Entries.size(); I != E; ++I) {
16585 const auto &Entry = LVal.Designator.Entries[I];
16586 if (BaseType->isArrayType()) {
16592 uint64_t Index = Entry.getAsArrayIndex();
16596 }
else if (BaseType->isAnyComplexType()) {
16597 const auto *CT = BaseType->castAs<
ComplexType>();
16598 uint64_t Index = Entry.getAsArrayIndex();
16601 BaseType = CT->getElementType();
16602 }
else if (
auto *FD = getAsField(Entry)) {
16603 if (!IsLastOrInvalidFieldDecl(FD))
16607 assert(getAsBaseClass(Entry) &&
"Expecting cast to a base class");
16619 if (LVal.Designator.Invalid)
16622 if (!LVal.Designator.Entries.empty())
16623 return LVal.Designator.isMostDerivedAnUnsizedArray();
16625 if (!LVal.InvalidBase)
16637 const SubobjectDesignator &
Designator = LVal.Designator;
16649 auto isFlexibleArrayMember = [&] {
16651 FAMKind StrictFlexArraysLevel =
16654 if (
Designator.isMostDerivedAnUnsizedArray())
16657 if (StrictFlexArraysLevel == FAMKind::Default)
16660 if (
Designator.getMostDerivedArraySize() == 0 &&
16661 StrictFlexArraysLevel != FAMKind::IncompleteOnly)
16664 if (
Designator.getMostDerivedArraySize() == 1 &&
16665 StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete)
16671 return LVal.InvalidBase &&
16673 Designator.MostDerivedIsArrayElement && isFlexibleArrayMember() &&
16681 auto CharUnitsMax = std::numeric_limits<CharUnits::QuantityType>::max();
16682 if (Int.ugt(CharUnitsMax))
16692 if (!
T.isNull() &&
T->isStructureType() &&
16693 T->castAsRecordDecl()->hasFlexibleArrayMember())
16694 if (
const auto *
V = LV.getLValueBase().dyn_cast<
const ValueDecl *>())
16695 if (
const auto *VD = dyn_cast<VarDecl>(
V))
16707 unsigned Type,
const LValue &LVal,
16726 if (!(
Type & 1) || LVal.Designator.Invalid || DetermineForCompleteObject) {
16728 if (
Type == 3 && !DetermineForCompleteObject)
16731 llvm::APInt APEndOffset;
16732 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
16736 if (LVal.InvalidBase)
16740 const bool Ret = CheckedHandleSizeof(BaseTy, EndOffset);
16746 const SubobjectDesignator &
Designator = LVal.Designator;
16758 llvm::APInt APEndOffset;
16759 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
16771 if (!CheckedHandleSizeof(
Designator.MostDerivedType, BytesPerElem))
16777 int64_t ElemsRemaining;
16780 uint64_t ArraySize =
Designator.getMostDerivedArraySize();
16781 uint64_t ArrayIndex =
Designator.Entries.back().getAsArrayIndex();
16782 ElemsRemaining = ArraySize <= ArrayIndex ? 0 : ArraySize - ArrayIndex;
16784 ElemsRemaining =
Designator.isOnePastTheEnd() ? 0 : 1;
16787 EndOffset = LVal.getLValueOffset() + BytesPerElem * ElemsRemaining;
16797static std::optional<uint64_t>
16799 bool IsDynamic =
false) {
16807 SpeculativeEvaluationRAII SpeculativeEval(Info);
16808 IgnoreSideEffectsRAII Fold(Info);
16815 return std::nullopt;
16816 LVal.setFrom(Info.Ctx, RVal);
16819 return std::nullopt;
16824 if (LVal.getLValueOffset().isNegative())
16839 const auto *FD = ME ? dyn_cast<FieldDecl>(ME->getMemberDecl()) :
nullptr;
16841 return std::nullopt;
16846 return std::nullopt;
16850 if (EndOffset <= LVal.getLValueOffset())
16852 return (EndOffset - LVal.getLValueOffset()).
getQuantity();
16855bool IntExprEvaluator::VisitCallExpr(
const CallExpr *E) {
16856 if (!IsConstantEvaluatedBuiltinCall(E))
16857 return ExprEvaluatorBaseTy::VisitCallExpr(E);
16874 Info.FFDiag(E->
getArg(0));
16880 assert(SrcInt.getBitWidth() >= Alignment.getBitWidth() &&
16881 "Bit widths must be the same");
16888bool IntExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *E,
16889 unsigned BuiltinOp) {
16890 auto EvalTestOp = [&](llvm::function_ref<
bool(
const APInt &,
const APInt &)>
16892 APValue SourceLHS, SourceRHS;
16900 unsigned LaneWidth = Info.Ctx.getTypeSize(ElemQT);
16902 APInt AWide(LaneWidth * SourceLen, 0);
16903 APInt BWide(LaneWidth * SourceLen, 0);
16905 for (
unsigned I = 0; I != SourceLen; ++I) {
16908 if (ElemQT->isIntegerType()) {
16911 }
else if (ElemQT->isFloatingType()) {
16919 AWide.insertBits(ALane, I * LaneWidth);
16920 BWide.insertBits(BLane, I * LaneWidth);
16925 auto HandleMaskBinOp =
16938 auto HandleCRC32 = [&](
unsigned DataBytes) ->
bool {
16944 uint64_t CRCVal = CRC.getZExtValue();
16948 static const uint32_t CRC32C_POLY = 0x82F63B78;
16952 for (
unsigned I = 0; I != DataBytes; ++I) {
16953 uint8_t Byte =
static_cast<uint8_t>((DataVal >> (I * 8)) & 0xFF);
16955 for (
int J = 0; J != 8; ++J) {
16963 switch (BuiltinOp) {
16967 case X86::BI__builtin_ia32_crc32qi:
16968 return HandleCRC32(1);
16969 case X86::BI__builtin_ia32_crc32hi:
16970 return HandleCRC32(2);
16971 case X86::BI__builtin_ia32_crc32si:
16972 return HandleCRC32(4);
16973 case X86::BI__builtin_ia32_crc32di:
16974 return HandleCRC32(8);
16976 case Builtin::BI__builtin_dynamic_object_size:
16977 case Builtin::BI__builtin_object_size: {
16981 assert(
Type <= 3 &&
"unexpected type");
16983 bool IsDynamic = BuiltinOp == Builtin::BI__builtin_dynamic_object_size;
16984 if (std::optional<uint64_t> Size =
16993 switch (Info.EvalMode) {
16994 case EvaluationMode::ConstantExpression:
16995 case EvaluationMode::ConstantFold:
16996 case EvaluationMode::IgnoreSideEffects:
16999 case EvaluationMode::ConstantExpressionUnevaluated:
17004 llvm_unreachable(
"unexpected EvalMode");
17007 case Builtin::BI__builtin_os_log_format_buffer_size: {
17008 analyze_os_log::OSLogBufferLayout Layout;
17013 case Builtin::BI__builtin_is_aligned: {
17021 Ptr.setFrom(Info.Ctx, Src);
17027 assert(Alignment.isPowerOf2());
17040 Info.FFDiag(E->
getArg(0), diag::note_constexpr_alignment_compute)
17044 assert(Src.
isInt());
17045 return Success((Src.
getInt() & (Alignment - 1)) == 0 ? 1 : 0, E);
17047 case Builtin::BI__builtin_align_up: {
17055 APSInt((Src.
getInt() + (Alignment - 1)) & ~(Alignment - 1),
17056 Src.
getInt().isUnsigned());
17057 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
17058 return Success(AlignedVal, E);
17060 case Builtin::BI__builtin_align_down: {
17069 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
17070 return Success(AlignedVal, E);
17073 case Builtin::BI__builtin_bitreverseg:
17074 case Builtin::BI__builtin_bitreverse8:
17075 case Builtin::BI__builtin_bitreverse16:
17076 case Builtin::BI__builtin_bitreverse32:
17077 case Builtin::BI__builtin_bitreverse64:
17078 case Builtin::BI__builtin_elementwise_bitreverse: {
17083 return Success(Val.reverseBits(), E);
17085 case Builtin::BI__builtin_bswapg:
17086 case Builtin::BI__builtin_bswap16:
17087 case Builtin::BI__builtin_bswap32:
17088 case Builtin::BI__builtin_bswap64:
17089 case Builtin::BIstdc_memreverse8u8:
17090 case Builtin::BIstdc_memreverse8u16:
17091 case Builtin::BIstdc_memreverse8u32:
17092 case Builtin::BIstdc_memreverse8u64: {
17096 if (Val.getBitWidth() == 8 || Val.getBitWidth() == 1)
17099 return Success(Val.byteSwap(), E);
17102 case Builtin::BI__builtin_classify_type:
17105 case Builtin::BI__builtin_clrsb:
17106 case Builtin::BI__builtin_clrsbl:
17107 case Builtin::BI__builtin_clrsbll: {
17112 return Success(Val.getBitWidth() - Val.getSignificantBits(), E);
17115 case Builtin::BI__builtin_clz:
17116 case Builtin::BI__builtin_clzl:
17117 case Builtin::BI__builtin_clzll:
17118 case Builtin::BI__builtin_clzs:
17119 case Builtin::BI__builtin_clzg:
17120 case Builtin::BI__builtin_elementwise_clzg:
17121 case Builtin::BI__lzcnt16:
17122 case Builtin::BI__lzcnt:
17123 case Builtin::BI__lzcnt64: {
17134 std::optional<APSInt> Fallback;
17135 if ((BuiltinOp == Builtin::BI__builtin_clzg ||
17136 BuiltinOp == Builtin::BI__builtin_elementwise_clzg) &&
17141 Fallback = FallbackTemp;
17146 return Success(*Fallback, E);
17151 bool ZeroIsUndefined = BuiltinOp != Builtin::BI__lzcnt16 &&
17152 BuiltinOp != Builtin::BI__lzcnt &&
17153 BuiltinOp != Builtin::BI__lzcnt64;
17155 if (BuiltinOp == Builtin::BI__builtin_elementwise_clzg) {
17156 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
17160 if (ZeroIsUndefined)
17164 return Success(Val.countl_zero(), E);
17167 case Builtin::BI__builtin_constant_p: {
17168 const Expr *Arg = E->
getArg(0);
17177 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
17181 case Builtin::BI__noop:
17185 case Builtin::BI__builtin_is_constant_evaluated: {
17186 const auto *
Callee = Info.CurrentCall->getCallee();
17187 if (Info.InConstantContext && !Info.CheckingPotentialConstantExpression &&
17188 (Info.CallStackDepth == 1 ||
17189 (Info.CallStackDepth == 2 &&
Callee->isInStdNamespace() &&
17190 Callee->getIdentifier() &&
17191 Callee->getIdentifier()->isStr(
"is_constant_evaluated")))) {
17193 if (Info.EvalStatus.Diag)
17194 Info.report((Info.CallStackDepth == 1)
17196 : Info.CurrentCall->getCallRange().getBegin(),
17197 diag::warn_is_constant_evaluated_always_true_constexpr)
17198 << (Info.CallStackDepth == 1 ?
"__builtin_is_constant_evaluated"
17199 :
"std::is_constant_evaluated");
17202 return Success(Info.InConstantContext, E);
17205 case Builtin::BI__builtin_is_within_lifetime:
17206 if (
auto result = EvaluateBuiltinIsWithinLifetime(*
this, E))
17210 case Builtin::BI__builtin_ctz:
17211 case Builtin::BI__builtin_ctzl:
17212 case Builtin::BI__builtin_ctzll:
17213 case Builtin::BI__builtin_ctzs:
17214 case Builtin::BI__builtin_ctzg:
17215 case Builtin::BI__builtin_elementwise_ctzg: {
17226 std::optional<APSInt> Fallback;
17227 if ((BuiltinOp == Builtin::BI__builtin_ctzg ||
17228 BuiltinOp == Builtin::BI__builtin_elementwise_ctzg) &&
17233 Fallback = FallbackTemp;
17238 return Success(*Fallback, E);
17240 if (BuiltinOp == Builtin::BI__builtin_elementwise_ctzg) {
17241 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
17247 return Success(Val.countr_zero(), E);
17250 case Builtin::BI__builtin_eh_return_data_regno: {
17252 Operand = Info.Ctx.getTargetInfo().getEHDataRegisterNumber(Operand);
17256 case Builtin::BI__builtin_elementwise_abs: {
17261 return Success(Val.abs(), E);
17264 case Builtin::BI__builtin_expect:
17265 case Builtin::BI__builtin_expect_with_probability:
17266 return Visit(E->
getArg(0));
17268 case Builtin::BI__builtin_ptrauth_string_discriminator: {
17275 case Builtin::BI__builtin_infer_alloc_token: {
17281 E, diag::note_constexpr_infer_alloc_token_type_inference_failed);
17284 return Error(E, diag::note_constexpr_infer_alloc_token_no_metadata);
17286 Info.getLangOpts().AllocTokenMode.value_or(llvm::DefaultAllocTokenMode);
17287 uint64_t BitWidth = Info.Ctx.getTypeSize(Info.Ctx.getSizeType());
17288 auto MaxTokensOpt = Info.getLangOpts().AllocTokenMax;
17290 MaxTokensOpt.value_or(0) ? *MaxTokensOpt : (~0ULL >> (64 - BitWidth));
17291 auto MaybeToken = llvm::getAllocToken(Mode, *ATMD, MaxTokens);
17293 return Error(E, diag::note_constexpr_infer_alloc_token_stateful_mode);
17294 return Success(llvm::APInt(BitWidth, *MaybeToken), E);
17297 case Builtin::BI__builtin_ffs:
17298 case Builtin::BI__builtin_ffsl:
17299 case Builtin::BI__builtin_ffsll: {
17304 unsigned N = Val.countr_zero();
17305 return Success(N == Val.getBitWidth() ? 0 : N + 1, E);
17308 case Builtin::BI__builtin_fpclassify: {
17313 switch (Val.getCategory()) {
17314 case APFloat::fcNaN: Arg = 0;
break;
17315 case APFloat::fcInfinity: Arg = 1;
break;
17316 case APFloat::fcNormal: Arg = Val.isDenormal() ? 3 : 2;
break;
17317 case APFloat::fcZero: Arg = 4;
break;
17319 return Visit(E->
getArg(Arg));
17322 case Builtin::BI__builtin_isinf_sign: {
17325 Success(Val.isInfinity() ? (Val.isNegative() ? -1 : 1) : 0, E);
17328 case Builtin::BI__builtin_isinf: {
17331 Success(Val.isInfinity() ? 1 : 0, E);
17334 case Builtin::BI__builtin_isfinite: {
17337 Success(Val.isFinite() ? 1 : 0, E);
17340 case Builtin::BI__builtin_isnan: {
17343 Success(Val.isNaN() ? 1 : 0, E);
17346 case Builtin::BI__builtin_isnormal: {
17349 Success(Val.isNormal() ? 1 : 0, E);
17352 case Builtin::BI__builtin_issubnormal: {
17355 Success(Val.isDenormal() ? 1 : 0, E);
17358 case Builtin::BI__builtin_iszero: {
17361 Success(Val.isZero() ? 1 : 0, E);
17364 case Builtin::BI__builtin_signbit:
17365 case Builtin::BI__builtin_signbitf:
17366 case Builtin::BI__builtin_signbitl: {
17369 Success(Val.isNegative() ? 1 : 0, E);
17372 case Builtin::BI__builtin_isgreater:
17373 case Builtin::BI__builtin_isgreaterequal:
17374 case Builtin::BI__builtin_isless:
17375 case Builtin::BI__builtin_islessequal:
17376 case Builtin::BI__builtin_islessgreater:
17377 case Builtin::BI__builtin_isunordered: {
17386 switch (BuiltinOp) {
17387 case Builtin::BI__builtin_isgreater:
17389 case Builtin::BI__builtin_isgreaterequal:
17391 case Builtin::BI__builtin_isless:
17393 case Builtin::BI__builtin_islessequal:
17395 case Builtin::BI__builtin_islessgreater: {
17396 APFloat::cmpResult cmp = LHS.compare(RHS);
17397 return cmp == APFloat::cmpResult::cmpLessThan ||
17398 cmp == APFloat::cmpResult::cmpGreaterThan;
17400 case Builtin::BI__builtin_isunordered:
17401 return LHS.compare(RHS) == APFloat::cmpResult::cmpUnordered;
17403 llvm_unreachable(
"Unexpected builtin ID: Should be a floating "
17404 "point comparison function");
17412 case Builtin::BI__builtin_issignaling: {
17415 Success(Val.isSignaling() ? 1 : 0, E);
17418 case Builtin::BI__builtin_isfpclass: {
17422 unsigned Test =
static_cast<llvm::FPClassTest
>(MaskVal.getZExtValue());
17425 Success((Val.classify() & Test) ? 1 : 0, E);
17428 case Builtin::BI__builtin_parity:
17429 case Builtin::BI__builtin_parityl:
17430 case Builtin::BI__builtin_parityll: {
17435 return Success(Val.popcount() % 2, E);
17438 case Builtin::BI__builtin_abs:
17439 case Builtin::BI__builtin_labs:
17440 case Builtin::BI__builtin_llabs: {
17444 if (Val ==
APSInt(APInt::getSignedMinValue(Val.getBitWidth()),
17447 if (Val.isNegative())
17452 case Builtin::BI__builtin_popcount:
17453 case Builtin::BI__builtin_popcountl:
17454 case Builtin::BI__builtin_popcountll:
17455 case Builtin::BI__builtin_popcountg:
17456 case Builtin::BI__builtin_elementwise_popcount:
17457 case Builtin::BI__popcnt16:
17458 case Builtin::BI__popcnt:
17459 case Builtin::BI__popcnt64: {
17470 return Success(Val.popcount(), E);
17473 case Builtin::BI__builtin_rotateleft8:
17474 case Builtin::BI__builtin_rotateleft16:
17475 case Builtin::BI__builtin_rotateleft32:
17476 case Builtin::BI__builtin_rotateleft64:
17477 case Builtin::BI__builtin_rotateright8:
17478 case Builtin::BI__builtin_rotateright16:
17479 case Builtin::BI__builtin_rotateright32:
17480 case Builtin::BI__builtin_rotateright64:
17481 case Builtin::BI__builtin_stdc_rotate_left:
17482 case Builtin::BI__builtin_stdc_rotate_right:
17483 case Builtin::BIstdc_rotate_left_uc:
17484 case Builtin::BIstdc_rotate_left_us:
17485 case Builtin::BIstdc_rotate_left_ui:
17486 case Builtin::BIstdc_rotate_left_ul:
17487 case Builtin::BIstdc_rotate_left_ull:
17488 case Builtin::BIstdc_rotate_right_uc:
17489 case Builtin::BIstdc_rotate_right_us:
17490 case Builtin::BIstdc_rotate_right_ui:
17491 case Builtin::BIstdc_rotate_right_ul:
17492 case Builtin::BIstdc_rotate_right_ull:
17493 case Builtin::BI_rotl8:
17494 case Builtin::BI_rotl16:
17495 case Builtin::BI_rotl:
17496 case Builtin::BI_lrotl:
17497 case Builtin::BI_rotl64:
17498 case Builtin::BI_rotr8:
17499 case Builtin::BI_rotr16:
17500 case Builtin::BI_rotr:
17501 case Builtin::BI_lrotr:
17502 case Builtin::BI_rotr64: {
17510 switch (BuiltinOp) {
17511 case Builtin::BI__builtin_rotateright8:
17512 case Builtin::BI__builtin_rotateright16:
17513 case Builtin::BI__builtin_rotateright32:
17514 case Builtin::BI__builtin_rotateright64:
17515 case Builtin::BI__builtin_stdc_rotate_right:
17516 case Builtin::BIstdc_rotate_right_uc:
17517 case Builtin::BIstdc_rotate_right_us:
17518 case Builtin::BIstdc_rotate_right_ui:
17519 case Builtin::BIstdc_rotate_right_ul:
17520 case Builtin::BIstdc_rotate_right_ull:
17521 case Builtin::BI_rotr8:
17522 case Builtin::BI_rotr16:
17523 case Builtin::BI_rotr:
17524 case Builtin::BI_lrotr:
17525 case Builtin::BI_rotr64:
17534 case Builtin::BIstdc_leading_zeros_uc:
17535 case Builtin::BIstdc_leading_zeros_us:
17536 case Builtin::BIstdc_leading_zeros_ui:
17537 case Builtin::BIstdc_leading_zeros_ul:
17538 case Builtin::BIstdc_leading_zeros_ull:
17539 case Builtin::BIstdc_leading_ones_uc:
17540 case Builtin::BIstdc_leading_ones_us:
17541 case Builtin::BIstdc_leading_ones_ui:
17542 case Builtin::BIstdc_leading_ones_ul:
17543 case Builtin::BIstdc_leading_ones_ull:
17544 case Builtin::BIstdc_trailing_zeros_uc:
17545 case Builtin::BIstdc_trailing_zeros_us:
17546 case Builtin::BIstdc_trailing_zeros_ui:
17547 case Builtin::BIstdc_trailing_zeros_ul:
17548 case Builtin::BIstdc_trailing_zeros_ull:
17549 case Builtin::BIstdc_trailing_ones_uc:
17550 case Builtin::BIstdc_trailing_ones_us:
17551 case Builtin::BIstdc_trailing_ones_ui:
17552 case Builtin::BIstdc_trailing_ones_ul:
17553 case Builtin::BIstdc_trailing_ones_ull:
17554 case Builtin::BIstdc_first_leading_zero_uc:
17555 case Builtin::BIstdc_first_leading_zero_us:
17556 case Builtin::BIstdc_first_leading_zero_ui:
17557 case Builtin::BIstdc_first_leading_zero_ul:
17558 case Builtin::BIstdc_first_leading_zero_ull:
17559 case Builtin::BIstdc_first_leading_one_uc:
17560 case Builtin::BIstdc_first_leading_one_us:
17561 case Builtin::BIstdc_first_leading_one_ui:
17562 case Builtin::BIstdc_first_leading_one_ul:
17563 case Builtin::BIstdc_first_leading_one_ull:
17564 case Builtin::BIstdc_first_trailing_zero_uc:
17565 case Builtin::BIstdc_first_trailing_zero_us:
17566 case Builtin::BIstdc_first_trailing_zero_ui:
17567 case Builtin::BIstdc_first_trailing_zero_ul:
17568 case Builtin::BIstdc_first_trailing_zero_ull:
17569 case Builtin::BIstdc_first_trailing_one_uc:
17570 case Builtin::BIstdc_first_trailing_one_us:
17571 case Builtin::BIstdc_first_trailing_one_ui:
17572 case Builtin::BIstdc_first_trailing_one_ul:
17573 case Builtin::BIstdc_first_trailing_one_ull:
17574 case Builtin::BIstdc_count_zeros_uc:
17575 case Builtin::BIstdc_count_zeros_us:
17576 case Builtin::BIstdc_count_zeros_ui:
17577 case Builtin::BIstdc_count_zeros_ul:
17578 case Builtin::BIstdc_count_zeros_ull:
17579 case Builtin::BIstdc_count_ones_uc:
17580 case Builtin::BIstdc_count_ones_us:
17581 case Builtin::BIstdc_count_ones_ui:
17582 case Builtin::BIstdc_count_ones_ul:
17583 case Builtin::BIstdc_count_ones_ull:
17584 case Builtin::BIstdc_has_single_bit_uc:
17585 case Builtin::BIstdc_has_single_bit_us:
17586 case Builtin::BIstdc_has_single_bit_ui:
17587 case Builtin::BIstdc_has_single_bit_ul:
17588 case Builtin::BIstdc_has_single_bit_ull:
17589 case Builtin::BIstdc_bit_width_uc:
17590 case Builtin::BIstdc_bit_width_us:
17591 case Builtin::BIstdc_bit_width_ui:
17592 case Builtin::BIstdc_bit_width_ul:
17593 case Builtin::BIstdc_bit_width_ull:
17594 case Builtin::BIstdc_bit_floor_uc:
17595 case Builtin::BIstdc_bit_floor_us:
17596 case Builtin::BIstdc_bit_floor_ui:
17597 case Builtin::BIstdc_bit_floor_ul:
17598 case Builtin::BIstdc_bit_floor_ull:
17599 case Builtin::BIstdc_bit_ceil_uc:
17600 case Builtin::BIstdc_bit_ceil_us:
17601 case Builtin::BIstdc_bit_ceil_ui:
17602 case Builtin::BIstdc_bit_ceil_ul:
17603 case Builtin::BIstdc_bit_ceil_ull:
17604 case Builtin::BI__builtin_stdc_leading_zeros:
17605 case Builtin::BI__builtin_stdc_leading_ones:
17606 case Builtin::BI__builtin_stdc_trailing_zeros:
17607 case Builtin::BI__builtin_stdc_trailing_ones:
17608 case Builtin::BI__builtin_stdc_first_leading_zero:
17609 case Builtin::BI__builtin_stdc_first_leading_one:
17610 case Builtin::BI__builtin_stdc_first_trailing_zero:
17611 case Builtin::BI__builtin_stdc_first_trailing_one:
17612 case Builtin::BI__builtin_stdc_count_zeros:
17613 case Builtin::BI__builtin_stdc_count_ones:
17614 case Builtin::BI__builtin_stdc_has_single_bit:
17615 case Builtin::BI__builtin_stdc_bit_width:
17616 case Builtin::BI__builtin_stdc_bit_floor:
17617 case Builtin::BI__builtin_stdc_bit_ceil: {
17622 unsigned BitWidth = Val.getBitWidth();
17623 const unsigned ResBitWidth = Info.Ctx.getIntWidth(E->
getType());
17625 switch (BuiltinOp) {
17626 case Builtin::BIstdc_leading_zeros_uc:
17627 case Builtin::BIstdc_leading_zeros_us:
17628 case Builtin::BIstdc_leading_zeros_ui:
17629 case Builtin::BIstdc_leading_zeros_ul:
17630 case Builtin::BIstdc_leading_zeros_ull:
17631 case Builtin::BI__builtin_stdc_leading_zeros:
17632 return Success(
APInt(ResBitWidth, Val.countl_zero()), E);
17633 case Builtin::BIstdc_leading_ones_uc:
17634 case Builtin::BIstdc_leading_ones_us:
17635 case Builtin::BIstdc_leading_ones_ui:
17636 case Builtin::BIstdc_leading_ones_ul:
17637 case Builtin::BIstdc_leading_ones_ull:
17638 case Builtin::BI__builtin_stdc_leading_ones:
17639 return Success(
APInt(ResBitWidth, Val.countl_one()), E);
17640 case Builtin::BIstdc_trailing_zeros_uc:
17641 case Builtin::BIstdc_trailing_zeros_us:
17642 case Builtin::BIstdc_trailing_zeros_ui:
17643 case Builtin::BIstdc_trailing_zeros_ul:
17644 case Builtin::BIstdc_trailing_zeros_ull:
17645 case Builtin::BI__builtin_stdc_trailing_zeros:
17646 return Success(
APInt(ResBitWidth, Val.countr_zero()), E);
17647 case Builtin::BIstdc_trailing_ones_uc:
17648 case Builtin::BIstdc_trailing_ones_us:
17649 case Builtin::BIstdc_trailing_ones_ui:
17650 case Builtin::BIstdc_trailing_ones_ul:
17651 case Builtin::BIstdc_trailing_ones_ull:
17652 case Builtin::BI__builtin_stdc_trailing_ones:
17653 return Success(
APInt(ResBitWidth, Val.countr_one()), E);
17654 case Builtin::BIstdc_first_leading_zero_uc:
17655 case Builtin::BIstdc_first_leading_zero_us:
17656 case Builtin::BIstdc_first_leading_zero_ui:
17657 case Builtin::BIstdc_first_leading_zero_ul:
17658 case Builtin::BIstdc_first_leading_zero_ull:
17659 case Builtin::BI__builtin_stdc_first_leading_zero:
17661 APInt(ResBitWidth, Val.isAllOnes() ? 0 : Val.countl_one() + 1), E);
17662 case Builtin::BIstdc_first_leading_one_uc:
17663 case Builtin::BIstdc_first_leading_one_us:
17664 case Builtin::BIstdc_first_leading_one_ui:
17665 case Builtin::BIstdc_first_leading_one_ul:
17666 case Builtin::BIstdc_first_leading_one_ull:
17667 case Builtin::BI__builtin_stdc_first_leading_one:
17669 APInt(ResBitWidth, Val.isZero() ? 0 : Val.countl_zero() + 1), E);
17670 case Builtin::BIstdc_first_trailing_zero_uc:
17671 case Builtin::BIstdc_first_trailing_zero_us:
17672 case Builtin::BIstdc_first_trailing_zero_ui:
17673 case Builtin::BIstdc_first_trailing_zero_ul:
17674 case Builtin::BIstdc_first_trailing_zero_ull:
17675 case Builtin::BI__builtin_stdc_first_trailing_zero:
17677 APInt(ResBitWidth, Val.isAllOnes() ? 0 : Val.countr_one() + 1), E);
17678 case Builtin::BIstdc_first_trailing_one_uc:
17679 case Builtin::BIstdc_first_trailing_one_us:
17680 case Builtin::BIstdc_first_trailing_one_ui:
17681 case Builtin::BIstdc_first_trailing_one_ul:
17682 case Builtin::BIstdc_first_trailing_one_ull:
17683 case Builtin::BI__builtin_stdc_first_trailing_one:
17685 APInt(ResBitWidth, Val.isZero() ? 0 : Val.countr_zero() + 1), E);
17686 case Builtin::BIstdc_count_zeros_uc:
17687 case Builtin::BIstdc_count_zeros_us:
17688 case Builtin::BIstdc_count_zeros_ui:
17689 case Builtin::BIstdc_count_zeros_ul:
17690 case Builtin::BIstdc_count_zeros_ull:
17691 case Builtin::BI__builtin_stdc_count_zeros: {
17692 APInt Cnt(ResBitWidth, BitWidth - Val.popcount());
17695 case Builtin::BIstdc_count_ones_uc:
17696 case Builtin::BIstdc_count_ones_us:
17697 case Builtin::BIstdc_count_ones_ui:
17698 case Builtin::BIstdc_count_ones_ul:
17699 case Builtin::BIstdc_count_ones_ull:
17700 case Builtin::BI__builtin_stdc_count_ones: {
17701 APInt Cnt(ResBitWidth, Val.popcount());
17704 case Builtin::BIstdc_has_single_bit_uc:
17705 case Builtin::BIstdc_has_single_bit_us:
17706 case Builtin::BIstdc_has_single_bit_ui:
17707 case Builtin::BIstdc_has_single_bit_ul:
17708 case Builtin::BIstdc_has_single_bit_ull:
17709 case Builtin::BI__builtin_stdc_has_single_bit: {
17710 APInt Res(ResBitWidth, Val.popcount() == 1 ? 1 : 0);
17713 case Builtin::BIstdc_bit_width_uc:
17714 case Builtin::BIstdc_bit_width_us:
17715 case Builtin::BIstdc_bit_width_ui:
17716 case Builtin::BIstdc_bit_width_ul:
17717 case Builtin::BIstdc_bit_width_ull:
17718 case Builtin::BI__builtin_stdc_bit_width:
17719 return Success(
APInt(ResBitWidth, BitWidth - Val.countl_zero()), E);
17720 case Builtin::BIstdc_bit_floor_uc:
17721 case Builtin::BIstdc_bit_floor_us:
17722 case Builtin::BIstdc_bit_floor_ui:
17723 case Builtin::BIstdc_bit_floor_ul:
17724 case Builtin::BIstdc_bit_floor_ull:
17725 case Builtin::BI__builtin_stdc_bit_floor: {
17728 unsigned Exp = BitWidth - Val.countl_zero() - 1;
17730 APSInt(APInt::getOneBitSet(BitWidth, Exp),
true), E);
17732 case Builtin::BIstdc_bit_ceil_uc:
17733 case Builtin::BIstdc_bit_ceil_us:
17734 case Builtin::BIstdc_bit_ceil_ui:
17735 case Builtin::BIstdc_bit_ceil_ul:
17736 case Builtin::BIstdc_bit_ceil_ull:
17737 case Builtin::BI__builtin_stdc_bit_ceil: {
17740 APInt ValMinusOne = Val - 1;
17741 unsigned LZ = ValMinusOne.countl_zero();
17745 APInt Result = APInt::getOneBitSet(BitWidth, BitWidth - LZ);
17749 llvm_unreachable(
"Unknown stdc builtin");
17753 case Builtin::BI__builtin_elementwise_add_sat: {
17759 APInt Result = LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS);
17762 case Builtin::BI__builtin_elementwise_sub_sat: {
17768 APInt Result = LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
17771 case Builtin::BI__builtin_elementwise_max: {
17780 case Builtin::BI__builtin_elementwise_min: {
17789 case Builtin::BI__builtin_elementwise_clmul: {
17798 case Builtin::BI__builtin_elementwise_fshl:
17799 case Builtin::BI__builtin_elementwise_fshr: {
17806 switch (BuiltinOp) {
17807 case Builtin::BI__builtin_elementwise_fshl: {
17808 APSInt Result(llvm::APIntOps::fshl(Hi, Lo, Shift), Hi.isUnsigned());
17811 case Builtin::BI__builtin_elementwise_fshr: {
17812 APSInt Result(llvm::APIntOps::fshr(Hi, Lo, Shift), Hi.isUnsigned());
17816 llvm_unreachable(
"Fully covered switch above");
17818 case Builtin::BIstrlen:
17819 case Builtin::BIwcslen:
17821 if (Info.getLangOpts().CPlusPlus11)
17822 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
17824 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
17826 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
17828 case Builtin::BI__builtin_strlen:
17829 case Builtin::BI__builtin_wcslen: {
17832 if (std::optional<uint64_t> StrLen =
17838 case Builtin::BIstrcmp:
17839 case Builtin::BIwcscmp:
17840 case Builtin::BIstrncmp:
17841 case Builtin::BIwcsncmp:
17842 case Builtin::BImemcmp:
17843 case Builtin::BIbcmp:
17844 case Builtin::BIwmemcmp:
17846 if (Info.getLangOpts().CPlusPlus11)
17847 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
17849 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
17851 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
17853 case Builtin::BI__builtin_strcmp:
17854 case Builtin::BI__builtin_wcscmp:
17855 case Builtin::BI__builtin_strncmp:
17856 case Builtin::BI__builtin_wcsncmp:
17857 case Builtin::BI__builtin_memcmp:
17858 case Builtin::BI__builtin_bcmp:
17859 case Builtin::BI__builtin_wmemcmp: {
17860 LValue String1, String2;
17866 if (BuiltinOp != Builtin::BIstrcmp &&
17867 BuiltinOp != Builtin::BIwcscmp &&
17868 BuiltinOp != Builtin::BI__builtin_strcmp &&
17869 BuiltinOp != Builtin::BI__builtin_wcscmp) {
17873 MaxLength = N.getZExtValue();
17877 if (MaxLength == 0u)
17880 if (!String1.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
17881 !String2.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
17882 String1.Designator.Invalid || String2.Designator.Invalid)
17885 QualType CharTy1 = String1.Designator.getType(Info.Ctx);
17886 QualType CharTy2 = String2.Designator.getType(Info.Ctx);
17888 bool IsRawByte = BuiltinOp == Builtin::BImemcmp ||
17889 BuiltinOp == Builtin::BIbcmp ||
17890 BuiltinOp == Builtin::BI__builtin_memcmp ||
17891 BuiltinOp == Builtin::BI__builtin_bcmp;
17893 assert(IsRawByte ||
17894 (Info.Ctx.hasSameUnqualifiedType(
17896 Info.Ctx.hasSameUnqualifiedType(CharTy1, CharTy2)));
17903 Info.FFDiag(E, diag::note_constexpr_memcmp_unsupported)
17904 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp) << CharTy1
17909 const auto &ReadCurElems = [&](
APValue &Char1,
APValue &Char2) {
17912 Char1.
isInt() && Char2.isInt();
17914 const auto &AdvanceElems = [&] {
17920 (BuiltinOp != Builtin::BImemcmp && BuiltinOp != Builtin::BIbcmp &&
17921 BuiltinOp != Builtin::BIwmemcmp &&
17922 BuiltinOp != Builtin::BI__builtin_memcmp &&
17923 BuiltinOp != Builtin::BI__builtin_bcmp &&
17924 BuiltinOp != Builtin::BI__builtin_wmemcmp);
17925 bool IsWide = BuiltinOp == Builtin::BIwcscmp ||
17926 BuiltinOp == Builtin::BIwcsncmp ||
17927 BuiltinOp == Builtin::BIwmemcmp ||
17928 BuiltinOp == Builtin::BI__builtin_wcscmp ||
17929 BuiltinOp == Builtin::BI__builtin_wcsncmp ||
17930 BuiltinOp == Builtin::BI__builtin_wmemcmp;
17932 for (; MaxLength; --MaxLength) {
17934 if (!ReadCurElems(Char1, Char2))
17942 if (StopAtNull && !Char1.
getInt())
17944 assert(!(StopAtNull && !Char2.
getInt()));
17945 if (!AdvanceElems())
17952 case Builtin::BI__atomic_always_lock_free:
17953 case Builtin::BI__atomic_is_lock_free:
17954 case Builtin::BI__c11_atomic_is_lock_free: {
17970 if (
Size.isPowerOfTwo()) {
17972 unsigned InlineWidthBits =
17973 Info.Ctx.getTargetInfo().getMaxAtomicInlineWidth();
17974 if (Size <= Info.Ctx.toCharUnitsFromBits(InlineWidthBits)) {
17975 if (BuiltinOp == Builtin::BI__c11_atomic_is_lock_free ||
17981 const Expr *PtrArg = E->
getArg(1);
17987 IntResult.isAligned(
Size.getAsAlign()))
17991 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(PtrArg)) {
17994 if (ICE->getCastKind() == CK_BitCast)
17995 PtrArg = ICE->getSubExpr();
17998 if (
auto PtrTy = PtrArg->
getType()->
getAs<PointerType>()) {
18001 Info.Ctx.getTypeAlignInChars(PointeeType) >= Size) {
18009 return BuiltinOp == Builtin::BI__atomic_always_lock_free ?
18012 case Builtin::BI__builtin_addcb:
18013 case Builtin::BI__builtin_addcs:
18014 case Builtin::BI__builtin_addc:
18015 case Builtin::BI__builtin_addcl:
18016 case Builtin::BI__builtin_addcll:
18017 case Builtin::BI__builtin_subcb:
18018 case Builtin::BI__builtin_subcs:
18019 case Builtin::BI__builtin_subc:
18020 case Builtin::BI__builtin_subcl:
18021 case Builtin::BI__builtin_subcll: {
18022 LValue CarryOutLValue;
18034 bool FirstOverflowed =
false;
18035 bool SecondOverflowed =
false;
18036 switch (BuiltinOp) {
18038 llvm_unreachable(
"Invalid value for BuiltinOp");
18039 case Builtin::BI__builtin_addcb:
18040 case Builtin::BI__builtin_addcs:
18041 case Builtin::BI__builtin_addc:
18042 case Builtin::BI__builtin_addcl:
18043 case Builtin::BI__builtin_addcll:
18045 LHS.uadd_ov(RHS, FirstOverflowed).uadd_ov(CarryIn, SecondOverflowed);
18047 case Builtin::BI__builtin_subcb:
18048 case Builtin::BI__builtin_subcs:
18049 case Builtin::BI__builtin_subc:
18050 case Builtin::BI__builtin_subcl:
18051 case Builtin::BI__builtin_subcll:
18053 LHS.usub_ov(RHS, FirstOverflowed).usub_ov(CarryIn, SecondOverflowed);
18059 CarryOut = (
uint64_t)(FirstOverflowed | SecondOverflowed);
18065 case Builtin::BI__builtin_add_overflow:
18066 case Builtin::BI__builtin_sub_overflow:
18067 case Builtin::BI__builtin_mul_overflow:
18068 case Builtin::BI__builtin_sadd_overflow:
18069 case Builtin::BI__builtin_uadd_overflow:
18070 case Builtin::BI__builtin_uaddl_overflow:
18071 case Builtin::BI__builtin_uaddll_overflow:
18072 case Builtin::BI__builtin_usub_overflow:
18073 case Builtin::BI__builtin_usubl_overflow:
18074 case Builtin::BI__builtin_usubll_overflow:
18075 case Builtin::BI__builtin_umul_overflow:
18076 case Builtin::BI__builtin_umull_overflow:
18077 case Builtin::BI__builtin_umulll_overflow:
18078 case Builtin::BI__builtin_saddl_overflow:
18079 case Builtin::BI__builtin_saddll_overflow:
18080 case Builtin::BI__builtin_ssub_overflow:
18081 case Builtin::BI__builtin_ssubl_overflow:
18082 case Builtin::BI__builtin_ssubll_overflow:
18083 case Builtin::BI__builtin_smul_overflow:
18084 case Builtin::BI__builtin_smull_overflow:
18085 case Builtin::BI__builtin_smulll_overflow: {
18086 LValue ResultLValue;
18096 bool DidOverflow =
false;
18099 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
18100 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
18101 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
18102 bool IsSigned = LHS.isSigned() || RHS.isSigned() ||
18104 bool AllSigned = LHS.isSigned() && RHS.isSigned() &&
18106 uint64_t LHSSize = LHS.getBitWidth();
18107 uint64_t RHSSize = RHS.getBitWidth();
18108 uint64_t ResultSize = Info.Ctx.getIntWidth(ResultType);
18109 uint64_t MaxBits = std::max(std::max(LHSSize, RHSSize), ResultSize);
18115 if (IsSigned && !AllSigned)
18118 LHS =
APSInt(LHS.extOrTrunc(MaxBits), !IsSigned);
18119 RHS =
APSInt(RHS.extOrTrunc(MaxBits), !IsSigned);
18124 switch (BuiltinOp) {
18126 llvm_unreachable(
"Invalid value for BuiltinOp");
18127 case Builtin::BI__builtin_add_overflow:
18128 case Builtin::BI__builtin_sadd_overflow:
18129 case Builtin::BI__builtin_saddl_overflow:
18130 case Builtin::BI__builtin_saddll_overflow:
18131 case Builtin::BI__builtin_uadd_overflow:
18132 case Builtin::BI__builtin_uaddl_overflow:
18133 case Builtin::BI__builtin_uaddll_overflow:
18134 Result = LHS.isSigned() ? LHS.sadd_ov(RHS, DidOverflow)
18135 : LHS.uadd_ov(RHS, DidOverflow);
18137 case Builtin::BI__builtin_sub_overflow:
18138 case Builtin::BI__builtin_ssub_overflow:
18139 case Builtin::BI__builtin_ssubl_overflow:
18140 case Builtin::BI__builtin_ssubll_overflow:
18141 case Builtin::BI__builtin_usub_overflow:
18142 case Builtin::BI__builtin_usubl_overflow:
18143 case Builtin::BI__builtin_usubll_overflow:
18144 Result = LHS.isSigned() ? LHS.ssub_ov(RHS, DidOverflow)
18145 : LHS.usub_ov(RHS, DidOverflow);
18147 case Builtin::BI__builtin_mul_overflow:
18148 case Builtin::BI__builtin_smul_overflow:
18149 case Builtin::BI__builtin_smull_overflow:
18150 case Builtin::BI__builtin_smulll_overflow:
18151 case Builtin::BI__builtin_umul_overflow:
18152 case Builtin::BI__builtin_umull_overflow:
18153 case Builtin::BI__builtin_umulll_overflow:
18154 Result = LHS.isSigned() ? LHS.smul_ov(RHS, DidOverflow)
18155 : LHS.umul_ov(RHS, DidOverflow);
18164 APSInt Temp =
Result.extOrTrunc(Info.Ctx.getIntWidth(ResultType));
18169 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
18170 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
18171 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
18172 if (!APSInt::isSameValue(Temp,
Result))
18173 DidOverflow =
true;
18180 return Success(DidOverflow, E);
18183 case Builtin::BI__builtin_reduce_add:
18184 case Builtin::BI__builtin_reduce_mul:
18185 case Builtin::BI__builtin_reduce_and:
18186 case Builtin::BI__builtin_reduce_or:
18187 case Builtin::BI__builtin_reduce_xor:
18188 case Builtin::BI__builtin_reduce_min:
18189 case Builtin::BI__builtin_reduce_max: {
18196 for (
unsigned EltNum = 1; EltNum < SourceLen; ++EltNum) {
18197 switch (BuiltinOp) {
18200 case Builtin::BI__builtin_reduce_add: {
18203 Reduced.getBitWidth() + 1, std::plus<APSInt>(), Reduced))
18207 case Builtin::BI__builtin_reduce_mul: {
18210 Reduced.getBitWidth() * 2, std::multiplies<APSInt>(), Reduced))
18214 case Builtin::BI__builtin_reduce_and: {
18218 case Builtin::BI__builtin_reduce_or: {
18222 case Builtin::BI__builtin_reduce_xor: {
18226 case Builtin::BI__builtin_reduce_min: {
18230 case Builtin::BI__builtin_reduce_max: {
18240 case clang::X86::BI__builtin_ia32_addcarryx_u32:
18241 case clang::X86::BI__builtin_ia32_addcarryx_u64:
18242 case clang::X86::BI__builtin_ia32_subborrow_u32:
18243 case clang::X86::BI__builtin_ia32_subborrow_u64: {
18244 LValue ResultLValue;
18245 APSInt CarryIn, LHS, RHS;
18253 bool IsAdd = BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u32 ||
18254 BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u64;
18256 unsigned BitWidth = LHS.getBitWidth();
18257 unsigned CarryInBit = CarryIn.ugt(0) ? 1 : 0;
18260 ? (LHS.zext(BitWidth + 1) + (RHS.zext(BitWidth + 1) + CarryInBit))
18261 : (LHS.zext(BitWidth + 1) - (RHS.zext(BitWidth + 1) + CarryInBit));
18263 APInt Result = ExResult.extractBits(BitWidth, 0);
18264 uint64_t CarryOut = ExResult.extractBitsAsZExtValue(1, BitWidth);
18272 case clang::X86::BI__builtin_ia32_movmskps:
18273 case clang::X86::BI__builtin_ia32_movmskpd:
18274 case clang::X86::BI__builtin_ia32_pmovmskb128:
18275 case clang::X86::BI__builtin_ia32_pmovmskb256:
18276 case clang::X86::BI__builtin_ia32_movmskps256:
18277 case clang::X86::BI__builtin_ia32_movmskpd256: {
18284 unsigned ResultLen = Info.Ctx.getTypeSize(
18288 for (
unsigned I = 0; I != SourceLen; ++I) {
18290 if (ElemQT->isIntegerType()) {
18292 }
else if (ElemQT->isRealFloatingType()) {
18297 Result.setBitVal(I, Elem.isNegative());
18302 case clang::X86::BI__builtin_ia32_bextr_u32:
18303 case clang::X86::BI__builtin_ia32_bextr_u64:
18304 case clang::X86::BI__builtin_ia32_bextri_u32:
18305 case clang::X86::BI__builtin_ia32_bextri_u64: {
18311 unsigned BitWidth = Val.getBitWidth();
18313 uint64_t Length = Idx.extractBitsAsZExtValue(8, 8);
18314 Length = Length > BitWidth ? BitWidth : Length;
18317 if (Length == 0 || Shift >= BitWidth)
18321 Result &= llvm::maskTrailingOnes<uint64_t>(Length);
18325 case clang::X86::BI__builtin_ia32_bzhi_si:
18326 case clang::X86::BI__builtin_ia32_bzhi_di: {
18332 unsigned BitWidth = Val.getBitWidth();
18333 unsigned Index = Idx.extractBitsAsZExtValue(8, 0);
18334 if (Index < BitWidth)
18335 Val.clearHighBits(BitWidth - Index);
18339 case clang::X86::BI__builtin_ia32_ktestcqi:
18340 case clang::X86::BI__builtin_ia32_ktestchi:
18341 case clang::X86::BI__builtin_ia32_ktestcsi:
18342 case clang::X86::BI__builtin_ia32_ktestcdi: {
18348 return Success((~A & B) == 0, E);
18351 case clang::X86::BI__builtin_ia32_ktestzqi:
18352 case clang::X86::BI__builtin_ia32_ktestzhi:
18353 case clang::X86::BI__builtin_ia32_ktestzsi:
18354 case clang::X86::BI__builtin_ia32_ktestzdi: {
18360 return Success((A & B) == 0, E);
18363 case clang::X86::BI__builtin_ia32_kortestcqi:
18364 case clang::X86::BI__builtin_ia32_kortestchi:
18365 case clang::X86::BI__builtin_ia32_kortestcsi:
18366 case clang::X86::BI__builtin_ia32_kortestcdi: {
18372 return Success(~(A | B) == 0, E);
18375 case clang::X86::BI__builtin_ia32_kortestzqi:
18376 case clang::X86::BI__builtin_ia32_kortestzhi:
18377 case clang::X86::BI__builtin_ia32_kortestzsi:
18378 case clang::X86::BI__builtin_ia32_kortestzdi: {
18384 return Success((A | B) == 0, E);
18387 case clang::X86::BI__builtin_ia32_kunpckhi:
18388 case clang::X86::BI__builtin_ia32_kunpckdi:
18389 case clang::X86::BI__builtin_ia32_kunpcksi: {
18397 unsigned BW = A.getBitWidth();
18398 APSInt Result(A.trunc(BW / 2).concat(B.trunc(BW / 2)), A.isUnsigned());
18402 case clang::X86::BI__builtin_ia32_lzcnt_u16:
18403 case clang::X86::BI__builtin_ia32_lzcnt_u32:
18404 case clang::X86::BI__builtin_ia32_lzcnt_u64: {
18408 return Success(Val.countLeadingZeros(), E);
18411 case clang::X86::BI__builtin_ia32_tzcnt_u16:
18412 case clang::X86::BI__builtin_ia32_tzcnt_u32:
18413 case clang::X86::BI__builtin_ia32_tzcnt_u64: {
18417 return Success(Val.countTrailingZeros(), E);
18420 case clang::X86::BI__builtin_ia32_pdep_si:
18421 case clang::X86::BI__builtin_ia32_pdep_di:
18422 case Builtin::BI__builtin_elementwise_pdep: {
18427 return Success(llvm::APIntOps::pdep(Val, Msk), E);
18430 case clang::X86::BI__builtin_ia32_pext_si:
18431 case clang::X86::BI__builtin_ia32_pext_di:
18432 case Builtin::BI__builtin_elementwise_pext: {
18437 return Success(llvm::APIntOps::pext(Val, Msk), E);
18439 case X86::BI__builtin_ia32_ptestz128:
18440 case X86::BI__builtin_ia32_ptestz256:
18441 case X86::BI__builtin_ia32_vtestzps:
18442 case X86::BI__builtin_ia32_vtestzps256:
18443 case X86::BI__builtin_ia32_vtestzpd:
18444 case X86::BI__builtin_ia32_vtestzpd256: {
18446 [](
const APInt &A,
const APInt &B) {
return (A & B) == 0; });
18448 case X86::BI__builtin_ia32_ptestc128:
18449 case X86::BI__builtin_ia32_ptestc256:
18450 case X86::BI__builtin_ia32_vtestcps:
18451 case X86::BI__builtin_ia32_vtestcps256:
18452 case X86::BI__builtin_ia32_vtestcpd:
18453 case X86::BI__builtin_ia32_vtestcpd256: {
18455 [](
const APInt &A,
const APInt &B) {
return (~A & B) == 0; });
18457 case X86::BI__builtin_ia32_ptestnzc128:
18458 case X86::BI__builtin_ia32_ptestnzc256:
18459 case X86::BI__builtin_ia32_vtestnzcps:
18460 case X86::BI__builtin_ia32_vtestnzcps256:
18461 case X86::BI__builtin_ia32_vtestnzcpd:
18462 case X86::BI__builtin_ia32_vtestnzcpd256: {
18463 return EvalTestOp([](
const APInt &A,
const APInt &B) {
18464 return ((A & B) != 0) && ((~A & B) != 0);
18467 case X86::BI__builtin_ia32_kandqi:
18468 case X86::BI__builtin_ia32_kandhi:
18469 case X86::BI__builtin_ia32_kandsi:
18470 case X86::BI__builtin_ia32_kanddi: {
18471 return HandleMaskBinOp(
18472 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS & RHS; });
18475 case X86::BI__builtin_ia32_kandnqi:
18476 case X86::BI__builtin_ia32_kandnhi:
18477 case X86::BI__builtin_ia32_kandnsi:
18478 case X86::BI__builtin_ia32_kandndi: {
18479 return HandleMaskBinOp(
18480 [](
const APSInt &LHS,
const APSInt &RHS) {
return ~LHS & RHS; });
18483 case X86::BI__builtin_ia32_korqi:
18484 case X86::BI__builtin_ia32_korhi:
18485 case X86::BI__builtin_ia32_korsi:
18486 case X86::BI__builtin_ia32_kordi: {
18487 return HandleMaskBinOp(
18488 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS | RHS; });
18491 case X86::BI__builtin_ia32_kxnorqi:
18492 case X86::BI__builtin_ia32_kxnorhi:
18493 case X86::BI__builtin_ia32_kxnorsi:
18494 case X86::BI__builtin_ia32_kxnordi: {
18495 return HandleMaskBinOp(
18496 [](
const APSInt &LHS,
const APSInt &RHS) {
return ~(LHS ^ RHS); });
18499 case X86::BI__builtin_ia32_kxorqi:
18500 case X86::BI__builtin_ia32_kxorhi:
18501 case X86::BI__builtin_ia32_kxorsi:
18502 case X86::BI__builtin_ia32_kxordi: {
18503 return HandleMaskBinOp(
18504 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS ^ RHS; });
18507 case X86::BI__builtin_ia32_knotqi:
18508 case X86::BI__builtin_ia32_knothi:
18509 case X86::BI__builtin_ia32_knotsi:
18510 case X86::BI__builtin_ia32_knotdi: {
18518 case X86::BI__builtin_ia32_kaddqi:
18519 case X86::BI__builtin_ia32_kaddhi:
18520 case X86::BI__builtin_ia32_kaddsi:
18521 case X86::BI__builtin_ia32_kadddi: {
18522 return HandleMaskBinOp(
18523 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS + RHS; });
18526 case X86::BI__builtin_ia32_kmovb:
18527 case X86::BI__builtin_ia32_kmovw:
18528 case X86::BI__builtin_ia32_kmovd:
18529 case X86::BI__builtin_ia32_kmovq: {
18536 case X86::BI__builtin_ia32_kshiftliqi:
18537 case X86::BI__builtin_ia32_kshiftlihi:
18538 case X86::BI__builtin_ia32_kshiftlisi:
18539 case X86::BI__builtin_ia32_kshiftlidi: {
18540 return HandleMaskBinOp([](
const APSInt &LHS,
const APSInt &RHS) {
18541 unsigned Amt = RHS.getZExtValue() & 0xFF;
18542 if (Amt >= LHS.getBitWidth())
18543 return APSInt(APInt::getZero(LHS.getBitWidth()), LHS.isUnsigned());
18544 return APSInt(LHS.shl(Amt), LHS.isUnsigned());
18548 case X86::BI__builtin_ia32_kshiftriqi:
18549 case X86::BI__builtin_ia32_kshiftrihi:
18550 case X86::BI__builtin_ia32_kshiftrisi:
18551 case X86::BI__builtin_ia32_kshiftridi: {
18552 return HandleMaskBinOp([](
const APSInt &LHS,
const APSInt &RHS) {
18553 unsigned Amt = RHS.getZExtValue() & 0xFF;
18554 if (Amt >= LHS.getBitWidth())
18555 return APSInt(APInt::getZero(LHS.getBitWidth()), LHS.isUnsigned());
18556 return APSInt(LHS.lshr(Amt), LHS.isUnsigned());
18560 case clang::X86::BI__builtin_ia32_vec_ext_v4hi:
18561 case clang::X86::BI__builtin_ia32_vec_ext_v16qi:
18562 case clang::X86::BI__builtin_ia32_vec_ext_v8hi:
18563 case clang::X86::BI__builtin_ia32_vec_ext_v4si:
18564 case clang::X86::BI__builtin_ia32_vec_ext_v2di:
18565 case clang::X86::BI__builtin_ia32_vec_ext_v32qi:
18566 case clang::X86::BI__builtin_ia32_vec_ext_v16hi:
18567 case clang::X86::BI__builtin_ia32_vec_ext_v8si:
18568 case clang::X86::BI__builtin_ia32_vec_ext_v4di: {
18575 unsigned Idx =
static_cast<unsigned>(IdxAPS.getZExtValue() & (N - 1));
18579 case clang::X86::BI__builtin_ia32_cvtb2mask128:
18580 case clang::X86::BI__builtin_ia32_cvtb2mask256:
18581 case clang::X86::BI__builtin_ia32_cvtb2mask512:
18582 case clang::X86::BI__builtin_ia32_cvtw2mask128:
18583 case clang::X86::BI__builtin_ia32_cvtw2mask256:
18584 case clang::X86::BI__builtin_ia32_cvtw2mask512:
18585 case clang::X86::BI__builtin_ia32_cvtd2mask128:
18586 case clang::X86::BI__builtin_ia32_cvtd2mask256:
18587 case clang::X86::BI__builtin_ia32_cvtd2mask512:
18588 case clang::X86::BI__builtin_ia32_cvtq2mask128:
18589 case clang::X86::BI__builtin_ia32_cvtq2mask256:
18590 case clang::X86::BI__builtin_ia32_cvtq2mask512: {
18597 unsigned RetWidth = Info.Ctx.getIntWidth(E->
getType());
18598 llvm::APInt Bits(RetWidth, 0);
18600 for (
unsigned ElemNum = 0; ElemNum != VectorLen; ++ElemNum) {
18602 unsigned MSB = A[A.getBitWidth() - 1];
18603 Bits.setBitVal(ElemNum, MSB);
18606 APSInt RetMask(Bits,
true);
18610 case clang::X86::BI__builtin_ia32_cmpb128_mask:
18611 case clang::X86::BI__builtin_ia32_cmpw128_mask:
18612 case clang::X86::BI__builtin_ia32_cmpd128_mask:
18613 case clang::X86::BI__builtin_ia32_cmpq128_mask:
18614 case clang::X86::BI__builtin_ia32_cmpb256_mask:
18615 case clang::X86::BI__builtin_ia32_cmpw256_mask:
18616 case clang::X86::BI__builtin_ia32_cmpd256_mask:
18617 case clang::X86::BI__builtin_ia32_cmpq256_mask:
18618 case clang::X86::BI__builtin_ia32_cmpb512_mask:
18619 case clang::X86::BI__builtin_ia32_cmpw512_mask:
18620 case clang::X86::BI__builtin_ia32_cmpd512_mask:
18621 case clang::X86::BI__builtin_ia32_cmpq512_mask:
18622 case clang::X86::BI__builtin_ia32_ucmpb128_mask:
18623 case clang::X86::BI__builtin_ia32_ucmpw128_mask:
18624 case clang::X86::BI__builtin_ia32_ucmpd128_mask:
18625 case clang::X86::BI__builtin_ia32_ucmpq128_mask:
18626 case clang::X86::BI__builtin_ia32_ucmpb256_mask:
18627 case clang::X86::BI__builtin_ia32_ucmpw256_mask:
18628 case clang::X86::BI__builtin_ia32_ucmpd256_mask:
18629 case clang::X86::BI__builtin_ia32_ucmpq256_mask:
18630 case clang::X86::BI__builtin_ia32_ucmpb512_mask:
18631 case clang::X86::BI__builtin_ia32_ucmpw512_mask:
18632 case clang::X86::BI__builtin_ia32_ucmpd512_mask:
18633 case clang::X86::BI__builtin_ia32_ucmpq512_mask: {
18637 (BuiltinOp >= clang::X86::BI__builtin_ia32_ucmpb128_mask &&
18638 BuiltinOp <= clang::X86::BI__builtin_ia32_ucmpw512_mask);
18651 unsigned RetWidth = Mask.getBitWidth();
18653 APSInt RetMask(llvm::APInt(RetWidth, 0),
true);
18655 for (
unsigned ElemNum = 0; ElemNum < VectorLen; ++ElemNum) {
18660 switch (
Opcode.getExtValue() & 0x7) {
18665 Result = IsUnsigned ? A.ult(B) : A.slt(B);
18668 Result = IsUnsigned ? A.ule(B) : A.sle(B);
18677 Result = IsUnsigned ? A.uge(B) : A.sge(B);
18680 Result = IsUnsigned ? A.ugt(B) : A.sgt(B);
18687 RetMask.setBitVal(ElemNum, Mask[ElemNum] &&
Result);
18692 case X86::BI__builtin_ia32_vpshufbitqmb128_mask:
18693 case X86::BI__builtin_ia32_vpshufbitqmb256_mask:
18694 case X86::BI__builtin_ia32_vpshufbitqmb512_mask: {
18707 unsigned NumBytesInQWord = 8;
18708 unsigned NumBitsInByte = 8;
18710 unsigned NumQWords = NumBytes / NumBytesInQWord;
18711 unsigned RetWidth = ZeroMask.getBitWidth();
18712 APSInt RetMask(llvm::APInt(RetWidth, 0),
true);
18714 for (
unsigned QWordId = 0; QWordId != NumQWords; ++QWordId) {
18715 APInt SourceQWord(64, 0);
18716 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
18720 SourceQWord.insertBits(
APInt(8, Byte & 0xFF), ByteIdx * NumBitsInByte);
18723 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
18724 unsigned SelIdx = QWordId * NumBytesInQWord + ByteIdx;
18727 if (ZeroMask[SelIdx]) {
18728 RetMask.setBitVal(SelIdx, SourceQWord[M]);
18740 const LValue &LV) {
18743 if (!LV.getLValueBase())
18748 if (!LV.getLValueDesignator().Invalid &&
18749 !LV.getLValueDesignator().isOnePastTheEnd())
18759 if (LV.getLValueDesignator().Invalid)
18765 return LV.getLValueOffset() == Size;
18775class DataRecursiveIntBinOpEvaluator {
18776 struct EvalResult {
18778 bool Failed =
false;
18780 EvalResult() =
default;
18782 void swap(EvalResult &RHS) {
18784 Failed = RHS.Failed;
18785 RHS.Failed =
false;
18791 EvalResult LHSResult;
18792 enum { AnyExprKind, BinOpKind, BinOpVisitedLHSKind }
Kind;
18795 Job(Job &&) =
default;
18797 void startSpeculativeEval(EvalInfo &Info) {
18798 SpecEvalRAII = SpeculativeEvaluationRAII(Info);
18802 SpeculativeEvaluationRAII SpecEvalRAII;
18805 SmallVector<Job, 16> Queue;
18807 IntExprEvaluator &IntEval;
18812 DataRecursiveIntBinOpEvaluator(IntExprEvaluator &IntEval,
APValue &
Result)
18813 : IntEval(IntEval), Info(IntEval.getEvalInfo()), FinalResult(
Result) { }
18819 static bool shouldEnqueue(
const BinaryOperator *E) {
18826 bool Traverse(
const BinaryOperator *E) {
18828 EvalResult PrevResult;
18829 while (!Queue.empty())
18830 process(PrevResult);
18832 if (PrevResult.Failed)
return false;
18834 FinalResult.
swap(PrevResult.Val);
18845 bool Error(
const Expr *E) {
18846 return IntEval.Error(E);
18849 return IntEval.Error(E, D);
18852 OptionalDiagnostic CCEDiag(
const Expr *E,
diag::kind D) {
18853 return Info.CCEDiag(E, D);
18857 bool VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
18858 bool &SuppressRHSDiags);
18860 bool VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
18863 void EvaluateExpr(
const Expr *E, EvalResult &
Result) {
18869 void process(EvalResult &
Result);
18871 void enqueue(
const Expr *E) {
18873 Queue.resize(Queue.size()+1);
18874 Queue.back().E = E;
18875 Queue.back().Kind = Job::AnyExprKind;
18881bool DataRecursiveIntBinOpEvaluator::
18882 VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
18883 bool &SuppressRHSDiags) {
18886 if (LHSResult.Failed)
18887 return Info.noteSideEffect();
18896 if (LHSAsBool == (E->
getOpcode() == BO_LOr)) {
18897 Success(LHSAsBool, E, LHSResult.Val);
18901 LHSResult.Failed =
true;
18905 if (!Info.noteSideEffect())
18911 SuppressRHSDiags =
true;
18920 if (LHSResult.Failed && !Info.noteFailure())
18931 assert(!LVal.
hasLValuePath() &&
"have designator for integer lvalue");
18933 uint64_t Offset64 = Offset.getQuantity();
18934 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
18936 : Offset64 + Index64);
18939bool DataRecursiveIntBinOpEvaluator::
18940 VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
18943 if (RHSResult.Failed)
18950 bool lhsResult, rhsResult;
18965 if (rhsResult == (E->
getOpcode() == BO_LOr))
18976 if (LHSResult.Failed || RHSResult.Failed)
18979 const APValue &LHSVal = LHSResult.Val;
18980 const APValue &RHSVal = RHSResult.Val;
19004 if (!LHSExpr || !RHSExpr)
19006 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
19007 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
19008 if (!LHSAddrExpr || !RHSAddrExpr)
19033void DataRecursiveIntBinOpEvaluator::process(EvalResult &
Result) {
19034 Job &job = Queue.back();
19036 switch (job.Kind) {
19037 case Job::AnyExprKind: {
19038 if (
const BinaryOperator *Bop = dyn_cast<BinaryOperator>(job.E)) {
19039 if (shouldEnqueue(Bop)) {
19040 job.Kind = Job::BinOpKind;
19041 enqueue(Bop->getLHS());
19046 EvaluateExpr(job.E,
Result);
19051 case Job::BinOpKind: {
19053 bool SuppressRHSDiags =
false;
19054 if (!VisitBinOpLHSOnly(
Result, Bop, SuppressRHSDiags)) {
19058 if (SuppressRHSDiags)
19059 job.startSpeculativeEval(Info);
19060 job.LHSResult.swap(
Result);
19061 job.Kind = Job::BinOpVisitedLHSKind;
19066 case Job::BinOpVisitedLHSKind: {
19070 Result.Failed = !VisitBinOp(job.LHSResult, RHS, Bop,
Result.Val);
19076 llvm_unreachable(
"Invalid Job::Kind!");
19080enum class CmpResult {
19089template <
class SuccessCB,
class AfterCB>
19092 SuccessCB &&
Success, AfterCB &&DoAfter) {
19097 "unsupported binary expression evaluation");
19099 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
19113 if (!LHSOK && !Info.noteFailure())
19118 return Success(CmpResult::Less, E);
19120 return Success(CmpResult::Greater, E);
19121 return Success(CmpResult::Equal, E);
19125 APFixedPoint LHSFX(Info.Ctx.getFixedPointSemantics(LHSTy));
19126 APFixedPoint RHSFX(Info.Ctx.getFixedPointSemantics(RHSTy));
19129 if (!LHSOK && !Info.noteFailure())
19134 return Success(CmpResult::Less, E);
19136 return Success(CmpResult::Greater, E);
19137 return Success(CmpResult::Equal, E);
19141 ComplexValue LHS, RHS;
19150 LHS.makeComplexFloat();
19151 LHS.FloatImag = APFloat(LHS.FloatReal.getSemantics());
19156 if (!LHSOK && !Info.noteFailure())
19162 RHS.makeComplexFloat();
19163 RHS.FloatImag = APFloat(RHS.FloatReal.getSemantics());
19167 if (LHS.isComplexFloat()) {
19168 APFloat::cmpResult CR_r =
19169 LHS.getComplexFloatReal().compare(RHS.getComplexFloatReal());
19170 APFloat::cmpResult CR_i =
19171 LHS.getComplexFloatImag().compare(RHS.getComplexFloatImag());
19172 bool IsEqual = CR_r == APFloat::cmpEqual && CR_i == APFloat::cmpEqual;
19173 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal, E);
19175 assert(IsEquality &&
"invalid complex comparison");
19176 bool IsEqual = LHS.getComplexIntReal() == RHS.getComplexIntReal() &&
19177 LHS.getComplexIntImag() == RHS.getComplexIntImag();
19178 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal, E);
19184 APFloat RHS(0.0), LHS(0.0);
19187 if (!LHSOK && !Info.noteFailure())
19194 llvm::APFloatBase::cmpResult APFloatCmpResult = LHS.compare(RHS);
19195 if (!Info.InConstantContext &&
19196 APFloatCmpResult == APFloat::cmpUnordered &&
19199 Info.FFDiag(E, diag::note_constexpr_float_arithmetic_strict);
19202 auto GetCmpRes = [&]() {
19203 switch (APFloatCmpResult) {
19204 case APFloat::cmpEqual:
19205 return CmpResult::Equal;
19206 case APFloat::cmpLessThan:
19207 return CmpResult::Less;
19208 case APFloat::cmpGreaterThan:
19209 return CmpResult::Greater;
19210 case APFloat::cmpUnordered:
19211 return CmpResult::Unordered;
19213 llvm_unreachable(
"Unrecognised APFloat::cmpResult enum");
19215 return Success(GetCmpRes(), E);
19219 LValue LHSValue, RHSValue;
19222 if (!LHSOK && !Info.noteFailure())
19233 if (Info.checkingPotentialConstantExpression() &&
19234 (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown))
19236 auto DiagComparison = [&] (
unsigned DiagID,
bool Reversed =
false) {
19237 std::string LHS = LHSValue.toString(Info.Ctx, E->
getLHS()->
getType());
19238 std::string RHS = RHSValue.toString(Info.Ctx, E->
getRHS()->
getType());
19239 Info.FFDiag(E, DiagID)
19246 return DiagComparison(
19247 diag::note_constexpr_pointer_comparison_unspecified);
19253 if ((!LHSValue.Base && !LHSValue.Offset.
isZero()) ||
19254 (!RHSValue.Base && !RHSValue.Offset.
isZero()))
19255 return DiagComparison(diag::note_constexpr_pointer_constant_comparison,
19269 return DiagComparison(diag::note_constexpr_literal_comparison);
19271 return DiagComparison(diag::note_constexpr_opaque_call_comparison,
19276 return DiagComparison(diag::note_constexpr_pointer_weak_comparison,
19280 if (LHSValue.Base && LHSValue.Offset.
isZero() &&
19282 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
19284 if (RHSValue.Base && RHSValue.Offset.
isZero() &&
19286 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
19292 return DiagComparison(
19293 diag::note_constexpr_pointer_comparison_zero_sized);
19294 if (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown)
19295 return DiagComparison(
19296 diag::note_constexpr_pointer_comparison_unspecified);
19298 return Success(CmpResult::Unequal, E);
19301 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
19302 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
19304 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
19305 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
19315 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid && IsRelational) {
19316 bool WasArrayIndex;
19319 :
getType(LHSValue.Base).getNonReferenceType(),
19320 LHSDesignator, RHSDesignator, WasArrayIndex);
19327 if (!WasArrayIndex && Mismatch < LHSDesignator.Entries.size() &&
19328 Mismatch < RHSDesignator.Entries.size()) {
19329 const FieldDecl *LF = getAsField(LHSDesignator.Entries[Mismatch]);
19330 const FieldDecl *RF = getAsField(RHSDesignator.Entries[Mismatch]);
19332 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_classes);
19334 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
19335 << getAsBaseClass(LHSDesignator.Entries[Mismatch])
19338 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
19339 << getAsBaseClass(RHSDesignator.Entries[Mismatch])
19344 diag::note_constexpr_pointer_comparison_differing_access)
19352 unsigned PtrSize = Info.Ctx.getTypeSize(LHSTy);
19355 assert(PtrSize <= 64 &&
"Unexpected pointer width");
19356 uint64_t Mask = ~0ULL >> (64 - PtrSize);
19357 CompareLHS &= Mask;
19358 CompareRHS &= Mask;
19363 if (!LHSValue.Base.
isNull() && IsRelational) {
19367 CharUnits Size = Info.Ctx.getTypeSizeInChars(BaseTy);
19368 uint64_t OffsetLimit = Size.getQuantity();
19369 if (CompareLHS > OffsetLimit || CompareRHS > OffsetLimit)
19373 if (CompareLHS < CompareRHS)
19374 return Success(CmpResult::Less, E);
19375 if (CompareLHS > CompareRHS)
19376 return Success(CmpResult::Greater, E);
19377 return Success(CmpResult::Equal, E);
19381 assert(IsEquality &&
"unexpected member pointer operation");
19384 MemberPtr LHSValue, RHSValue;
19387 if (!LHSOK && !Info.noteFailure())
19395 if (LHSValue.getDecl() && LHSValue.getDecl()->isWeak()) {
19396 Info.FFDiag(E, diag::note_constexpr_mem_pointer_weak_comparison)
19397 << LHSValue.getDecl();
19400 if (RHSValue.getDecl() && RHSValue.getDecl()->isWeak()) {
19401 Info.FFDiag(E, diag::note_constexpr_mem_pointer_weak_comparison)
19402 << RHSValue.getDecl();
19409 if (!LHSValue.getDecl() || !RHSValue.getDecl()) {
19410 bool Equal = !LHSValue.getDecl() && !RHSValue.getDecl();
19411 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal, E);
19416 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(LHSValue.getDecl()))
19417 if (MD->isVirtual())
19418 Info.CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
19419 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(RHSValue.getDecl()))
19420 if (MD->isVirtual())
19421 Info.CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
19427 bool Equal = LHSValue == RHSValue;
19428 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal, E);
19433 assert(RHSTy->
isNullPtrType() &&
"missing pointer conversion");
19441 return Success(CmpResult::Equal, E);
19447bool RecordExprEvaluator::VisitBinCmp(
const BinaryOperator *E) {
19451 auto OnSuccess = [&](CmpResult CR,
const BinaryOperator *E) {
19454 case CmpResult::Unequal:
19455 llvm_unreachable(
"should never produce Unequal for three-way comparison");
19456 case CmpResult::Less:
19457 CCR = ComparisonCategoryResult::Less;
19459 case CmpResult::Equal:
19460 CCR = ComparisonCategoryResult::Equal;
19462 case CmpResult::Greater:
19463 CCR = ComparisonCategoryResult::Greater;
19465 case CmpResult::Unordered:
19466 CCR = ComparisonCategoryResult::Unordered;
19471 const ComparisonCategoryInfo &CmpInfo =
19472 Info.Ctx.CompCategories.getInfoForType(E->
getType());
19480 ConstantExprKind::Normal);
19483 return ExprEvaluatorBaseTy::VisitBinCmp(E);
19487bool RecordExprEvaluator::VisitCXXParenListInitExpr(
19488 const CXXParenListInitExpr *E) {
19489 return VisitCXXParenListOrInitListExpr(E, E->
getInitExprs());
19492bool IntExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
19497 if (!Info.noteFailure())
19501 if (DataRecursiveIntBinOpEvaluator::shouldEnqueue(E))
19502 return DataRecursiveIntBinOpEvaluator(*
this,
Result).Traverse(E);
19506 "DataRecursiveIntBinOpEvaluator should have handled integral types");
19511 auto OnSuccess = [&](CmpResult CR,
const BinaryOperator *E) {
19512 assert((CR != CmpResult::Unequal || E->
isEqualityOp()) &&
19513 "should only produce Unequal for equality comparisons");
19514 bool IsEqual = CR == CmpResult::Equal,
19515 IsLess = CR == CmpResult::Less,
19516 IsGreater = CR == CmpResult::Greater;
19520 llvm_unreachable(
"unsupported binary operator");
19523 return Success(IsEqual == (Op == BO_EQ), E);
19527 return Success(IsGreater, E);
19529 return Success(IsEqual || IsLess, E);
19531 return Success(IsEqual || IsGreater, E);
19535 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
19544 LValue LHSValue, RHSValue;
19547 if (!LHSOK && !Info.noteFailure())
19556 if (Info.checkingPotentialConstantExpression() &&
19557 (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown))
19560 const Expr *LHSExpr = LHSValue.Base.
dyn_cast<
const Expr *>();
19561 const Expr *RHSExpr = RHSValue.Base.
dyn_cast<
const Expr *>();
19563 auto DiagArith = [&](
unsigned DiagID) {
19564 std::string LHS = LHSValue.toString(Info.Ctx, E->
getLHS()->
getType());
19565 std::string RHS = RHSValue.toString(Info.Ctx, E->
getRHS()->
getType());
19566 Info.FFDiag(E, DiagID) << LHS << RHS;
19567 if (LHSExpr && LHSExpr == RHSExpr)
19569 diag::note_constexpr_repeated_literal_eval)
19574 if (!LHSExpr || !RHSExpr)
19575 return DiagArith(diag::note_constexpr_pointer_arith_unspecified);
19578 return DiagArith(diag::note_constexpr_literal_arith);
19580 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
19581 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
19582 if (!LHSAddrExpr || !RHSAddrExpr)
19590 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
19591 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
19593 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
19594 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
19600 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid &&
19603 Info.CCEDiag(E, diag::note_constexpr_pointer_subtraction_not_same_array);
19608 CharUnits ElementSize;
19615 if (ElementSize.
isZero()) {
19616 Info.FFDiag(E, diag::note_constexpr_pointer_subtraction_zero_size)
19633 APSInt TrueResult = (LHS - RHS) / ElemSize;
19636 if (
Result.extend(65) != TrueResult &&
19642 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
19647bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr(
19648 const UnaryExprOrTypeTraitExpr *E) {
19650 case UETT_PreferredAlignOf:
19651 case UETT_AlignOf: {
19660 case UETT_PtrAuthTypeDiscriminator: {
19666 case UETT_VecStep: {
19670 unsigned n = Ty->
castAs<VectorType>()->getNumElements();
19682 case UETT_DataSizeOf:
19683 case UETT_SizeOf: {
19687 if (
const ReferenceType *Ref = SrcTy->
getAs<ReferenceType>())
19698 case UETT_OpenMPRequiredSimdAlign:
19701 Info.Ctx.toCharUnitsFromBits(
19705 case UETT_VectorElements: {
19709 if (
const auto *VT = Ty->
getAs<VectorType>())
19713 if (Info.InConstantContext)
19714 Info.CCEDiag(E, diag::note_constexpr_non_const_vectorelements)
19719 case UETT_CountOf: {
19725 if (
const auto *CAT =
19735 const auto *VAT = Info.Ctx.getAsVariableArrayType(Ty);
19737 if (VAT->getElementType()->isArrayType()) {
19740 if (!VAT->getSizeExpr()) {
19745 std::optional<APSInt> Res =
19746 VAT->getSizeExpr()->getIntegerConstantExpr(Info.Ctx);
19751 static_cast<unsigned>(Info.Ctx.getTypeSize(Info.Ctx.getSizeType())),
19752 Res->getZExtValue()};
19764 llvm_unreachable(
"unknown expr/type trait");
19767bool IntExprEvaluator::VisitOffsetOfExpr(
const OffsetOfExpr *OOE) {
19768 Info.Ctx.recordOffsetOfEvaluation(OOE);
19774 for (
unsigned i = 0; i != n; ++i) {
19782 const ArrayType *AT = Info.Ctx.getAsArrayType(CurrentType);
19786 CharUnits ElementSize = Info.Ctx.getTypeSizeInChars(CurrentType);
19789 if (IdxResult.isNegative() || IdxResult.getActiveBits() > 63)
19791 int64_t IdxVal = IdxResult.getExtValue();
19794 ElemSize > std::numeric_limits<int64_t>::max() / IdxVal)
19795 return Error(OOE, diag::note_constexpr_offsetof_overflow);
19796 int64_t Offset = IdxVal * ElemSize;
19797 if (
Result.getQuantity() > std::numeric_limits<int64_t>::max() - Offset)
19798 return Error(OOE, diag::note_constexpr_offsetof_overflow);
19804 FieldDecl *MemberDecl = ON.
getField();
19809 const ASTRecordLayout &RL = Info.Ctx.getASTRecordLayout(RD);
19811 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
19818 llvm_unreachable(
"dependent __builtin_offsetof");
19821 CXXBaseSpecifier *BaseSpec = ON.
getBase();
19830 const ASTRecordLayout &RL = Info.Ctx.getASTRecordLayout(RD);
19833 CurrentType = BaseSpec->
getType();
19847bool IntExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
19867 if (Info.checkingForUndefinedBehavior())
19868 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
19869 diag::warn_integer_constant_overflow)
19897bool IntExprEvaluator::VisitCastExpr(
const CastExpr *E) {
19899 QualType DestType = E->
getType();
19900 QualType SrcType = SubExpr->
getType();
19903 case CK_BaseToDerived:
19904 case CK_DerivedToBase:
19905 case CK_UncheckedDerivedToBase:
19908 case CK_ArrayToPointerDecay:
19909 case CK_FunctionToPointerDecay:
19910 case CK_NullToPointer:
19911 case CK_NullToMemberPointer:
19912 case CK_BaseToDerivedMemberPointer:
19913 case CK_DerivedToBaseMemberPointer:
19914 case CK_ReinterpretMemberPointer:
19915 case CK_ConstructorConversion:
19916 case CK_IntegralToPointer:
19918 case CK_VectorSplat:
19919 case CK_IntegralToFloating:
19920 case CK_FloatingCast:
19921 case CK_CPointerToObjCPointerCast:
19922 case CK_BlockPointerToObjCPointerCast:
19923 case CK_AnyPointerToBlockPointerCast:
19924 case CK_ObjCObjectLValueCast:
19925 case CK_FloatingRealToComplex:
19926 case CK_FloatingComplexToReal:
19927 case CK_FloatingComplexCast:
19928 case CK_FloatingComplexToIntegralComplex:
19929 case CK_IntegralRealToComplex:
19930 case CK_IntegralComplexCast:
19931 case CK_IntegralComplexToFloatingComplex:
19932 case CK_BuiltinFnToFnPtr:
19933 case CK_ZeroToOCLOpaqueType:
19934 case CK_NonAtomicToAtomic:
19935 case CK_AddressSpaceConversion:
19936 case CK_IntToOCLSampler:
19937 case CK_FloatingToFixedPoint:
19938 case CK_FixedPointToFloating:
19939 case CK_FixedPointCast:
19940 case CK_IntegralToFixedPoint:
19941 case CK_MatrixCast:
19942 case CK_HLSLAggregateSplatCast:
19943 llvm_unreachable(
"invalid cast kind for integral value");
19947 case CK_LValueBitCast:
19948 case CK_ARCProduceObject:
19949 case CK_ARCConsumeObject:
19950 case CK_ARCReclaimReturnedObject:
19951 case CK_ARCExtendBlockObject:
19952 case CK_CopyAndAutoreleaseBlockObject:
19955 case CK_UserDefinedConversion:
19956 case CK_LValueToRValue:
19957 case CK_AtomicToNonAtomic:
19959 case CK_LValueToRValueBitCast:
19960 case CK_HLSLArrayRValue:
19961 return ExprEvaluatorBaseTy::VisitCastExpr(E);
19963 case CK_MemberPointerToBoolean:
19964 case CK_PointerToBoolean:
19965 case CK_IntegralToBoolean:
19966 case CK_FloatingToBoolean:
19967 case CK_BooleanToSignedIntegral:
19968 case CK_FloatingComplexToBoolean:
19969 case CK_IntegralComplexToBoolean: {
19974 if (BoolResult && E->
getCastKind() == CK_BooleanToSignedIntegral)
19976 return Success(IntResult, E);
19979 case CK_FixedPointToIntegral: {
19980 APFixedPoint Src(Info.Ctx.getFixedPointSemantics(SrcType));
19984 llvm::APSInt
Result = Src.convertToInt(
19985 Info.Ctx.getIntWidth(DestType),
19992 case CK_FixedPointToBoolean: {
19995 if (!
Evaluate(Val, Info, SubExpr))
20000 case CK_IntegralCast: {
20001 if (!Visit(SubExpr))
20011 if (
Result.isAddrLabelDiff()) {
20012 unsigned DestBits = Info.Ctx.getTypeSize(DestType);
20013 return DestBits >= 32 && DestBits <= Info.Ctx.getTypeSize(SrcType);
20016 return Info.Ctx.getTypeSize(DestType) == Info.Ctx.getTypeSize(SrcType);
20019 if (Info.Ctx.getLangOpts().CPlusPlus && DestType->
isEnumeralType()) {
20031 if (!ED->isFixed()) {
20035 ED->getValueRange(
Max,
Min);
20038 if (ED->getNumNegativeBits() &&
20039 (
Max.slt(
Result.getInt().getSExtValue()) ||
20040 Min.sgt(
Result.getInt().getSExtValue())))
20041 Info.CCEDiag(E, diag::note_constexpr_unscoped_enum_out_of_range)
20042 << llvm::toString(
Result.getInt(), 10) <<
Min.getSExtValue()
20043 <<
Max.getSExtValue() << ED;
20044 else if (!ED->getNumNegativeBits() &&
20045 Max.ult(
Result.getInt().getZExtValue()))
20046 Info.CCEDiag(E, diag::note_constexpr_unscoped_enum_out_of_range)
20047 << llvm::toString(
Result.getInt(), 10) <<
Min.getZExtValue()
20048 <<
Max.getZExtValue() << ED;
20056 case CK_PointerToIntegral: {
20057 CCEDiag(E, diag::note_constexpr_invalid_cast_ptrtoint)
20058 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
20065 if (LV.getLValueBase()) {
20066 CCEDiag(E, diag::note_constexpr_has_lvalue) << E->
getSourceRange();
20071 if (Info.Ctx.getTypeSize(DestType) != Info.Ctx.getTypeSize(SrcType))
20074 LV.Designator.setInvalid();
20082 if (!
V.toIntegralConstant(AsInt, SrcType, Info.Ctx))
20083 llvm_unreachable(
"Can't cast this!");
20088 case CK_IntegralComplexToReal: {
20092 return Success(
C.getComplexIntReal(), E);
20095 case CK_FloatingToIntegral: {
20105 case CK_HLSLVectorTruncation: {
20111 case CK_HLSLMatrixTruncation: {
20117 case CK_HLSLElementwiseCast: {
20130 return Success(ResultVal, E);
20134 llvm_unreachable(
"unknown cast resulting in integral value");
20137bool IntExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
20142 if (!LV.isComplexInt())
20144 return Success(LV.getComplexIntReal(), E);
20150bool IntExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
20155 if (!LV.isComplexInt())
20157 return Success(LV.getComplexIntImag(), E);
20164bool IntExprEvaluator::VisitSizeOfPackExpr(
const SizeOfPackExpr *E) {
20168bool IntExprEvaluator::VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E) {
20172bool IntExprEvaluator::VisitConceptSpecializationExpr(
20173 const ConceptSpecializationExpr *E) {
20177bool IntExprEvaluator::VisitRequiresExpr(
const RequiresExpr *E) {
20181bool FixedPointExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
20191 if (!
Result.isFixedPoint())
20194 APFixedPoint Negated =
Result.getFixedPoint().negate(&Overflowed);
20208bool FixedPointExprEvaluator::VisitCastExpr(
const CastExpr *E) {
20210 QualType DestType = E->
getType();
20212 "Expected destination type to be a fixed point type");
20213 auto DestFXSema = Info.Ctx.getFixedPointSemantics(DestType);
20216 case CK_FixedPointCast: {
20217 APFixedPoint Src(Info.Ctx.getFixedPointSemantics(SubExpr->
getType()));
20221 APFixedPoint
Result = Src.convert(DestFXSema, &Overflowed);
20223 if (Info.checkingForUndefinedBehavior())
20224 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
20225 diag::warn_fixedpoint_constant_overflow)
20232 case CK_IntegralToFixedPoint: {
20238 APFixedPoint IntResult = APFixedPoint::getFromIntValue(
20239 Src, Info.Ctx.getFixedPointSemantics(DestType), &Overflowed);
20242 if (Info.checkingForUndefinedBehavior())
20243 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
20244 diag::warn_fixedpoint_constant_overflow)
20245 << IntResult.toString() << E->
getType();
20250 return Success(IntResult, E);
20252 case CK_FloatingToFixedPoint: {
20258 APFixedPoint
Result = APFixedPoint::getFromFloatValue(
20259 Src, Info.Ctx.getFixedPointSemantics(DestType), &Overflowed);
20262 if (Info.checkingForUndefinedBehavior())
20263 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
20264 diag::warn_fixedpoint_constant_overflow)
20273 case CK_LValueToRValue:
20274 return ExprEvaluatorBaseTy::VisitCastExpr(E);
20280bool FixedPointExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
20282 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
20284 const Expr *LHS = E->
getLHS();
20285 const Expr *RHS = E->
getRHS();
20287 Info.Ctx.getFixedPointSemantics(E->
getType());
20289 APFixedPoint LHSFX(Info.Ctx.getFixedPointSemantics(LHS->
getType()));
20292 APFixedPoint RHSFX(Info.Ctx.getFixedPointSemantics(RHS->
getType()));
20296 bool OpOverflow =
false, ConversionOverflow =
false;
20297 APFixedPoint
Result(LHSFX.getSemantics());
20300 Result = LHSFX.add(RHSFX, &OpOverflow)
20301 .convert(ResultFXSema, &ConversionOverflow);
20305 Result = LHSFX.sub(RHSFX, &OpOverflow)
20306 .convert(ResultFXSema, &ConversionOverflow);
20310 Result = LHSFX.mul(RHSFX, &OpOverflow)
20311 .convert(ResultFXSema, &ConversionOverflow);
20315 if (RHSFX.getValue() == 0) {
20316 Info.FFDiag(E, diag::note_expr_divide_by_zero);
20319 Result = LHSFX.div(RHSFX, &OpOverflow)
20320 .convert(ResultFXSema, &ConversionOverflow);
20326 llvm::APSInt RHSVal = RHSFX.getValue();
20329 LHSSema.getWidth() - (unsigned)LHSSema.hasUnsignedPadding();
20330 unsigned Amt = RHSVal.getLimitedValue(ShiftBW - 1);
20334 if (RHSVal.isNegative())
20335 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHSVal;
20336 else if (Amt != RHSVal)
20337 Info.CCEDiag(E, diag::note_constexpr_large_shift)
20338 << RHSVal << E->
getType() << ShiftBW;
20341 Result = LHSFX.shl(Amt, &OpOverflow);
20343 Result = LHSFX.shr(Amt, &OpOverflow);
20349 if (OpOverflow || ConversionOverflow) {
20350 if (Info.checkingForUndefinedBehavior())
20351 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
20352 diag::warn_fixedpoint_constant_overflow)
20365class FloatExprEvaluator
20366 :
public ExprEvaluatorBase<FloatExprEvaluator> {
20369 FloatExprEvaluator(EvalInfo &info, APFloat &result)
20370 : ExprEvaluatorBaseTy(
info),
Result(result) {}
20377 bool ZeroInitialization(
const Expr *E) {
20378 Result = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(E->
getType()));
20382 bool VisitCallExpr(
const CallExpr *E);
20384 bool VisitUnaryOperator(
const UnaryOperator *E);
20385 bool VisitBinaryOperator(
const BinaryOperator *E);
20386 bool VisitFloatingLiteral(
const FloatingLiteral *E);
20387 bool VisitCastExpr(
const CastExpr *E);
20389 bool VisitUnaryReal(
const UnaryOperator *E);
20390 bool VisitUnaryImag(
const UnaryOperator *E);
20399 return FloatExprEvaluator(Info,
Result).Visit(E);
20406 llvm::APFloat &
Result) {
20411 const llvm::fltSemantics &Sem = Context.getFloatTypeSemantics(ResultTy);
20417 fill = llvm::APInt(32, 0);
20418 else if (S->
getString().getAsInteger(0, fill))
20421 if (Context.getTargetInfo().isNan2008()) {
20423 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
20425 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
20433 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
20435 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
20441bool FloatExprEvaluator::VisitCallExpr(
const CallExpr *E) {
20442 if (!IsConstantEvaluatedBuiltinCall(E))
20443 return ExprEvaluatorBaseTy::VisitCallExpr(E);
20447 switch (BuiltinOp) {
20451 case Builtin::BI__builtin_huge_val:
20452 case Builtin::BI__builtin_huge_valf:
20453 case Builtin::BI__builtin_huge_vall:
20454 case Builtin::BI__builtin_huge_valf16:
20455 case Builtin::BI__builtin_huge_valf128:
20456 case Builtin::BI__builtin_inf:
20457 case Builtin::BI__builtin_inff:
20458 case Builtin::BI__builtin_infl:
20459 case Builtin::BI__builtin_inff16:
20460 case Builtin::BI__builtin_inff128: {
20461 const llvm::fltSemantics &Sem =
20462 Info.Ctx.getFloatTypeSemantics(E->
getType());
20463 Result = llvm::APFloat::getInf(Sem);
20467 case Builtin::BI__builtin_nans:
20468 case Builtin::BI__builtin_nansf:
20469 case Builtin::BI__builtin_nansl:
20470 case Builtin::BI__builtin_nansf16:
20471 case Builtin::BI__builtin_nansf128:
20477 case Builtin::BI__builtin_nan:
20478 case Builtin::BI__builtin_nanf:
20479 case Builtin::BI__builtin_nanl:
20480 case Builtin::BI__builtin_nanf16:
20481 case Builtin::BI__builtin_nanf128:
20489 case Builtin::BI__builtin_elementwise_abs:
20490 case Builtin::BI__builtin_fabs:
20491 case Builtin::BI__builtin_fabsf:
20492 case Builtin::BI__builtin_fabsl:
20493 case Builtin::BI__builtin_fabsf128:
20502 if (
Result.isNegative())
20506 case Builtin::BI__arithmetic_fence:
20513 case Builtin::BI__builtin_copysign:
20514 case Builtin::BI__builtin_copysignf:
20515 case Builtin::BI__builtin_copysignl:
20516 case Builtin::BI__builtin_copysignf128: {
20525 case Builtin::BI__builtin_fmax:
20526 case Builtin::BI__builtin_fmaxf:
20527 case Builtin::BI__builtin_fmaxl:
20528 case Builtin::BI__builtin_fmaxf16:
20529 case Builtin::BI__builtin_fmaxf128: {
20538 case Builtin::BI__builtin_fmin:
20539 case Builtin::BI__builtin_fminf:
20540 case Builtin::BI__builtin_fminl:
20541 case Builtin::BI__builtin_fminf16:
20542 case Builtin::BI__builtin_fminf128: {
20551 case Builtin::BI__builtin_fmaximum_num:
20552 case Builtin::BI__builtin_fmaximum_numf:
20553 case Builtin::BI__builtin_fmaximum_numl:
20554 case Builtin::BI__builtin_fmaximum_numf16:
20555 case Builtin::BI__builtin_fmaximum_numf128: {
20564 case Builtin::BI__builtin_fminimum_num:
20565 case Builtin::BI__builtin_fminimum_numf:
20566 case Builtin::BI__builtin_fminimum_numl:
20567 case Builtin::BI__builtin_fminimum_numf16:
20568 case Builtin::BI__builtin_fminimum_numf128: {
20577 case Builtin::BI__builtin_elementwise_fma: {
20582 APFloat SourceY(0.), SourceZ(0.);
20588 (void)
Result.fusedMultiplyAdd(SourceY, SourceZ, RM);
20592 case clang::X86::BI__builtin_ia32_vec_ext_v4sf: {
20599 unsigned Idx =
static_cast<unsigned>(IdxAPS.getZExtValue() & (N - 1));
20605bool FloatExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
20617bool FloatExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
20627 const llvm::fltSemantics &Sem = Info.Ctx.getFloatTypeSemantics(E->
getType());
20628 Result = llvm::APFloat::getZero(Sem);
20632bool FloatExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
20634 default:
return Error(E);
20648bool FloatExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
20650 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
20654 if (!LHSOK && !Info.noteFailure())
20660bool FloatExprEvaluator::VisitFloatingLiteral(
const FloatingLiteral *E) {
20665bool FloatExprEvaluator::VisitCastExpr(
const CastExpr *E) {
20670 return ExprEvaluatorBaseTy::VisitCastExpr(E);
20672 case CK_HLSLAggregateSplatCast:
20673 llvm_unreachable(
"invalid cast kind for floating value");
20675 case CK_IntegralToFloating: {
20678 Info.Ctx.getLangOpts());
20684 case CK_FixedPointToFloating: {
20685 APFixedPoint FixResult(Info.Ctx.getFixedPointSemantics(SubExpr->
getType()));
20689 FixResult.convertToFloat(Info.Ctx.getFloatTypeSemantics(E->
getType()));
20693 case CK_FloatingCast: {
20694 if (!Visit(SubExpr))
20700 case CK_FloatingComplexToReal: {
20704 Result =
V.getComplexFloatReal();
20707 case CK_HLSLVectorTruncation: {
20713 case CK_HLSLMatrixTruncation: {
20719 case CK_HLSLElementwiseCast: {
20734 return Success(ResultVal, E);
20744class ComplexExprEvaluator
20745 :
public ExprEvaluatorBase<ComplexExprEvaluator> {
20749 ComplexExprEvaluator(EvalInfo &info, ComplexValue &
Result)
20757 bool ZeroInitialization(
const Expr *E);
20763 bool VisitImaginaryLiteral(
const ImaginaryLiteral *E);
20764 bool VisitCastExpr(
const CastExpr *E);
20765 bool VisitBinaryOperator(
const BinaryOperator *E);
20766 bool VisitUnaryOperator(
const UnaryOperator *E);
20767 bool VisitInitListExpr(
const InitListExpr *E);
20768 bool VisitCallExpr(
const CallExpr *E);
20776 return ComplexExprEvaluator(Info,
Result).Visit(E);
20779bool ComplexExprEvaluator::ZeroInitialization(
const Expr *E) {
20780 QualType ElemTy = E->
getType()->
castAs<ComplexType>()->getElementType();
20782 Result.makeComplexFloat();
20783 APFloat Zero = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(ElemTy));
20787 Result.makeComplexInt();
20788 APSInt Zero = Info.Ctx.MakeIntValue(0, ElemTy);
20795bool ComplexExprEvaluator::VisitImaginaryLiteral(
const ImaginaryLiteral *E) {
20799 Result.makeComplexFloat();
20808 "Unexpected imaginary literal.");
20810 Result.makeComplexInt();
20815 Result.IntReal =
APSInt(Imag.getBitWidth(), !Imag.isSigned());
20820bool ComplexExprEvaluator::VisitCastExpr(
const CastExpr *E) {
20824 case CK_BaseToDerived:
20825 case CK_DerivedToBase:
20826 case CK_UncheckedDerivedToBase:
20829 case CK_ArrayToPointerDecay:
20830 case CK_FunctionToPointerDecay:
20831 case CK_NullToPointer:
20832 case CK_NullToMemberPointer:
20833 case CK_BaseToDerivedMemberPointer:
20834 case CK_DerivedToBaseMemberPointer:
20835 case CK_MemberPointerToBoolean:
20836 case CK_ReinterpretMemberPointer:
20837 case CK_ConstructorConversion:
20838 case CK_IntegralToPointer:
20839 case CK_PointerToIntegral:
20840 case CK_PointerToBoolean:
20842 case CK_VectorSplat:
20843 case CK_IntegralCast:
20844 case CK_BooleanToSignedIntegral:
20845 case CK_IntegralToBoolean:
20846 case CK_IntegralToFloating:
20847 case CK_FloatingToIntegral:
20848 case CK_FloatingToBoolean:
20849 case CK_FloatingCast:
20850 case CK_CPointerToObjCPointerCast:
20851 case CK_BlockPointerToObjCPointerCast:
20852 case CK_AnyPointerToBlockPointerCast:
20853 case CK_ObjCObjectLValueCast:
20854 case CK_FloatingComplexToReal:
20855 case CK_FloatingComplexToBoolean:
20856 case CK_IntegralComplexToReal:
20857 case CK_IntegralComplexToBoolean:
20858 case CK_ARCProduceObject:
20859 case CK_ARCConsumeObject:
20860 case CK_ARCReclaimReturnedObject:
20861 case CK_ARCExtendBlockObject:
20862 case CK_CopyAndAutoreleaseBlockObject:
20863 case CK_BuiltinFnToFnPtr:
20864 case CK_ZeroToOCLOpaqueType:
20865 case CK_NonAtomicToAtomic:
20866 case CK_AddressSpaceConversion:
20867 case CK_IntToOCLSampler:
20868 case CK_FloatingToFixedPoint:
20869 case CK_FixedPointToFloating:
20870 case CK_FixedPointCast:
20871 case CK_FixedPointToBoolean:
20872 case CK_FixedPointToIntegral:
20873 case CK_IntegralToFixedPoint:
20874 case CK_MatrixCast:
20875 case CK_HLSLVectorTruncation:
20876 case CK_HLSLMatrixTruncation:
20877 case CK_HLSLElementwiseCast:
20878 case CK_HLSLAggregateSplatCast:
20879 llvm_unreachable(
"invalid cast kind for complex value");
20881 case CK_LValueToRValue:
20882 case CK_AtomicToNonAtomic:
20884 case CK_LValueToRValueBitCast:
20885 case CK_HLSLArrayRValue:
20886 return ExprEvaluatorBaseTy::VisitCastExpr(E);
20889 case CK_LValueBitCast:
20890 case CK_UserDefinedConversion:
20893 case CK_FloatingRealToComplex: {
20898 Result.makeComplexFloat();
20903 case CK_FloatingComplexCast: {
20907 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
20915 case CK_FloatingComplexToIntegralComplex: {
20919 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
20922 Result.makeComplexInt();
20929 case CK_IntegralRealToComplex: {
20934 Result.makeComplexInt();
20935 Result.IntImag =
APSInt(Real.getBitWidth(), !Real.isSigned());
20939 case CK_IntegralComplexCast: {
20943 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
20952 case CK_IntegralComplexToFloatingComplex: {
20957 Info.Ctx.getLangOpts());
20958 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
20961 Result.makeComplexFloat();
20963 To,
Result.FloatReal) &&
20969 llvm_unreachable(
"unknown cast resulting in complex value");
20975 0x00, 0x01, 0x8d, 0xf6, 0xcb, 0x52, 0x7b, 0xd1, 0xe8, 0x4f, 0x29, 0xc0,
20976 0xb0, 0xe1, 0xe5, 0xc7, 0x74, 0xb4, 0xaa, 0x4b, 0x99, 0x2b, 0x60, 0x5f,
20977 0x58, 0x3f, 0xfd, 0xcc, 0xff, 0x40, 0xee, 0xb2, 0x3a, 0x6e, 0x5a, 0xf1,
20978 0x55, 0x4d, 0xa8, 0xc9, 0xc1, 0x0a, 0x98, 0x15, 0x30, 0x44, 0xa2, 0xc2,
20979 0x2c, 0x45, 0x92, 0x6c, 0xf3, 0x39, 0x66, 0x42, 0xf2, 0x35, 0x20, 0x6f,
20980 0x77, 0xbb, 0x59, 0x19, 0x1d, 0xfe, 0x37, 0x67, 0x2d, 0x31, 0xf5, 0x69,
20981 0xa7, 0x64, 0xab, 0x13, 0x54, 0x25, 0xe9, 0x09, 0xed, 0x5c, 0x05, 0xca,
20982 0x4c, 0x24, 0x87, 0xbf, 0x18, 0x3e, 0x22, 0xf0, 0x51, 0xec, 0x61, 0x17,
20983 0x16, 0x5e, 0xaf, 0xd3, 0x49, 0xa6, 0x36, 0x43, 0xf4, 0x47, 0x91, 0xdf,
20984 0x33, 0x93, 0x21, 0x3b, 0x79, 0xb7, 0x97, 0x85, 0x10, 0xb5, 0xba, 0x3c,
20985 0xb6, 0x70, 0xd0, 0x06, 0xa1, 0xfa, 0x81, 0x82, 0x83, 0x7e, 0x7f, 0x80,
20986 0x96, 0x73, 0xbe, 0x56, 0x9b, 0x9e, 0x95, 0xd9, 0xf7, 0x02, 0xb9, 0xa4,
20987 0xde, 0x6a, 0x32, 0x6d, 0xd8, 0x8a, 0x84, 0x72, 0x2a, 0x14, 0x9f, 0x88,
20988 0xf9, 0xdc, 0x89, 0x9a, 0xfb, 0x7c, 0x2e, 0xc3, 0x8f, 0xb8, 0x65, 0x48,
20989 0x26, 0xc8, 0x12, 0x4a, 0xce, 0xe7, 0xd2, 0x62, 0x0c, 0xe0, 0x1f, 0xef,
20990 0x11, 0x75, 0x78, 0x71, 0xa5, 0x8e, 0x76, 0x3d, 0xbd, 0xbc, 0x86, 0x57,
20991 0x0b, 0x28, 0x2f, 0xa3, 0xda, 0xd4, 0xe4, 0x0f, 0xa9, 0x27, 0x53, 0x04,
20992 0x1b, 0xfc, 0xac, 0xe6, 0x7a, 0x07, 0xae, 0x63, 0xc5, 0xdb, 0xe2, 0xea,
20993 0x94, 0x8b, 0xc4, 0xd5, 0x9d, 0xf8, 0x90, 0x6b, 0xb1, 0x0d, 0xd6, 0xeb,
20994 0xc6, 0x0e, 0xcf, 0xad, 0x08, 0x4e, 0xd7, 0xe3, 0x5d, 0x50, 0x1e, 0xb3,
20995 0x5b, 0x23, 0x38, 0x34, 0x68, 0x46, 0x03, 0x8c, 0xdd, 0x9c, 0x7d, 0xa0,
20996 0xcd, 0x1a, 0x41, 0x1c};
20998 return GFInv[Byte];
21003 unsigned NumBitsInByte = 8;
21006 for (
uint32_t BitIdx = 0; BitIdx != NumBitsInByte; ++BitIdx) {
21008 AQword.lshr((7 -
static_cast<int32_t>(BitIdx)) * NumBitsInByte)
21015 Product = AByte & XByte;
21020 for (
unsigned PBitIdx = 0; PBitIdx != NumBitsInByte; ++PBitIdx) {
21021 Parity = Parity ^ ((Product >> PBitIdx) & 0x1);
21024 uint8_t Temp = Imm[BitIdx] ? 1 : 0;
21025 RetByte |= (Temp ^ Parity) << BitIdx;
21035 unsigned NumBitsInByte = 8;
21036 for (
unsigned BitIdx = 0; BitIdx != NumBitsInByte; ++BitIdx) {
21037 if ((BByte >> BitIdx) & 0x1) {
21038 TWord = TWord ^ (AByte << BitIdx);
21046 for (
int32_t BitIdx = 14; BitIdx > 7; --BitIdx) {
21047 if ((TWord >> BitIdx) & 0x1) {
21048 TWord = TWord ^ (0x11B << (BitIdx - 8));
21051 return (TWord & 0xFF);
21055 APFloat &ResR, APFloat &ResI) {
21061 APFloat AC = A *
C;
21062 APFloat BD = B * D;
21063 APFloat AD = A * D;
21064 APFloat BC = B *
C;
21067 if (ResR.isNaN() && ResI.isNaN()) {
21068 bool Recalc =
false;
21069 if (A.isInfinity() || B.isInfinity()) {
21070 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
21072 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
21075 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
21077 D = APFloat::copySign(APFloat(D.getSemantics()), D);
21080 if (
C.isInfinity() || D.isInfinity()) {
21081 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
21083 D = APFloat::copySign(APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0),
21086 A = APFloat::copySign(APFloat(A.getSemantics()), A);
21088 B = APFloat::copySign(APFloat(B.getSemantics()), B);
21091 if (!Recalc && (AC.isInfinity() || BD.isInfinity() || AD.isInfinity() ||
21092 BC.isInfinity())) {
21094 A = APFloat::copySign(APFloat(A.getSemantics()), A);
21096 B = APFloat::copySign(APFloat(B.getSemantics()), B);
21098 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
21100 D = APFloat::copySign(APFloat(D.getSemantics()), D);
21104 ResR = APFloat::getInf(A.getSemantics()) * (A *
C - B * D);
21105 ResI = APFloat::getInf(A.getSemantics()) * (A * D + B *
C);
21111 APFloat &ResR, APFloat &ResI) {
21118 APFloat MaxCD = maxnum(
abs(
C),
abs(D));
21119 if (MaxCD.isFinite()) {
21120 DenomLogB =
ilogb(MaxCD);
21121 C =
scalbn(
C, -DenomLogB, APFloat::rmNearestTiesToEven);
21122 D =
scalbn(D, -DenomLogB, APFloat::rmNearestTiesToEven);
21124 APFloat Denom =
C *
C + D * D;
21126 scalbn((A *
C + B * D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
21128 scalbn((B *
C - A * D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
21129 if (ResR.isNaN() && ResI.isNaN()) {
21130 if (Denom.isPosZero() && (!A.isNaN() || !B.isNaN())) {
21131 ResR = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * A;
21132 ResI = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * B;
21133 }
else if ((A.isInfinity() || B.isInfinity()) &&
C.isFinite() &&
21135 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
21137 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
21139 ResR = APFloat::getInf(ResR.getSemantics()) * (A *
C + B * D);
21140 ResI = APFloat::getInf(ResI.getSemantics()) * (B *
C - A * D);
21141 }
else if (MaxCD.isInfinity() && A.isFinite() && B.isFinite()) {
21142 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
21144 D = APFloat::copySign(APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0),
21146 ResR = APFloat::getZero(ResR.getSemantics()) * (A *
C + B * D);
21147 ResI = APFloat::getZero(ResI.getSemantics()) * (B *
C - A * D);
21154 APSInt NormAmt = Amount;
21155 unsigned BitWidth =
Value.getBitWidth();
21156 unsigned AmtBitWidth = NormAmt.getBitWidth();
21157 if (BitWidth == 1) {
21159 NormAmt =
APSInt(APInt(AmtBitWidth, 0), NormAmt.isUnsigned());
21160 }
else if (BitWidth == 2) {
21165 APSInt(APInt(AmtBitWidth, NormAmt[0] ? 1 : 0), NormAmt.isUnsigned());
21168 if (AmtBitWidth > BitWidth) {
21169 Divisor = llvm::APInt(AmtBitWidth, BitWidth);
21171 Divisor = llvm::APInt(BitWidth, BitWidth);
21172 if (AmtBitWidth < BitWidth) {
21173 NormAmt = NormAmt.extend(BitWidth);
21178 if (NormAmt.isSigned()) {
21179 NormAmt =
APSInt(NormAmt.srem(Divisor),
false);
21180 if (NormAmt.isNegative()) {
21181 APSInt SignedDivisor(Divisor,
false);
21182 NormAmt += SignedDivisor;
21185 NormAmt =
APSInt(NormAmt.urem(Divisor),
true);
21192bool ComplexExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
21194 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
21198 bool LHSReal =
false, RHSReal =
false;
21206 Result.makeComplexFloat();
21210 LHSOK = Visit(E->
getLHS());
21212 if (!LHSOK && !Info.noteFailure())
21218 APFloat &Real = RHS.FloatReal;
21221 RHS.makeComplexFloat();
21222 RHS.FloatImag =
APFloat(Real.getSemantics());
21226 assert(!(LHSReal && RHSReal) &&
21227 "Cannot have both operands of a complex operation be real.");
21229 default:
return Error(E);
21231 if (
Result.isComplexFloat()) {
21232 Result.getComplexFloatReal().add(RHS.getComplexFloatReal(),
21233 APFloat::rmNearestTiesToEven);
21235 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
21237 Result.getComplexFloatImag().add(RHS.getComplexFloatImag(),
21238 APFloat::rmNearestTiesToEven);
21240 Result.getComplexIntReal() += RHS.getComplexIntReal();
21241 Result.getComplexIntImag() += RHS.getComplexIntImag();
21245 if (
Result.isComplexFloat()) {
21246 Result.getComplexFloatReal().subtract(RHS.getComplexFloatReal(),
21247 APFloat::rmNearestTiesToEven);
21249 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
21250 Result.getComplexFloatImag().changeSign();
21251 }
else if (!RHSReal) {
21252 Result.getComplexFloatImag().subtract(RHS.getComplexFloatImag(),
21253 APFloat::rmNearestTiesToEven);
21256 Result.getComplexIntReal() -= RHS.getComplexIntReal();
21257 Result.getComplexIntImag() -= RHS.getComplexIntImag();
21261 if (
Result.isComplexFloat()) {
21266 ComplexValue LHS =
Result;
21267 APFloat &A = LHS.getComplexFloatReal();
21268 APFloat &B = LHS.getComplexFloatImag();
21269 APFloat &
C = RHS.getComplexFloatReal();
21270 APFloat &D = RHS.getComplexFloatImag();
21274 assert(!RHSReal &&
"Cannot have two real operands for a complex op!");
21282 }
else if (RHSReal) {
21294 ComplexValue LHS =
Result;
21295 Result.getComplexIntReal() =
21296 (LHS.getComplexIntReal() * RHS.getComplexIntReal() -
21297 LHS.getComplexIntImag() * RHS.getComplexIntImag());
21298 Result.getComplexIntImag() =
21299 (LHS.getComplexIntReal() * RHS.getComplexIntImag() +
21300 LHS.getComplexIntImag() * RHS.getComplexIntReal());
21304 if (
Result.isComplexFloat()) {
21309 ComplexValue LHS =
Result;
21310 APFloat &A = LHS.getComplexFloatReal();
21311 APFloat &B = LHS.getComplexFloatImag();
21312 APFloat &
C = RHS.getComplexFloatReal();
21313 APFloat &D = RHS.getComplexFloatImag();
21327 B = APFloat::getZero(A.getSemantics());
21332 ComplexValue LHS =
Result;
21333 APSInt Den = RHS.getComplexIntReal() * RHS.getComplexIntReal() +
21334 RHS.getComplexIntImag() * RHS.getComplexIntImag();
21336 return Error(E, diag::note_expr_divide_by_zero);
21338 Result.getComplexIntReal() =
21339 (LHS.getComplexIntReal() * RHS.getComplexIntReal() +
21340 LHS.getComplexIntImag() * RHS.getComplexIntImag()) / Den;
21341 Result.getComplexIntImag() =
21342 (LHS.getComplexIntImag() * RHS.getComplexIntReal() -
21343 LHS.getComplexIntReal() * RHS.getComplexIntImag()) / Den;
21351bool ComplexExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
21365 if (
Result.isComplexFloat()) {
21366 Result.getComplexFloatReal().changeSign();
21367 Result.getComplexFloatImag().changeSign();
21370 Result.getComplexIntReal() = -
Result.getComplexIntReal();
21371 Result.getComplexIntImag() = -
Result.getComplexIntImag();
21375 if (
Result.isComplexFloat())
21376 Result.getComplexFloatImag().changeSign();
21378 Result.getComplexIntImag() = -
Result.getComplexIntImag();
21383bool ComplexExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
21386 Result.makeComplexFloat();
21392 Result.makeComplexInt();
21400 return ExprEvaluatorBaseTy::VisitInitListExpr(E);
21403bool ComplexExprEvaluator::VisitCallExpr(
const CallExpr *E) {
21404 if (!IsConstantEvaluatedBuiltinCall(E))
21405 return ExprEvaluatorBaseTy::VisitCallExpr(E);
21408 case Builtin::BI__builtin_complex:
21409 Result.makeComplexFloat();
21427class AtomicExprEvaluator :
21428 public ExprEvaluatorBase<AtomicExprEvaluator> {
21429 const LValue *
This;
21432 AtomicExprEvaluator(EvalInfo &Info,
const LValue *This,
APValue &
Result)
21440 bool ZeroInitialization(
const Expr *E) {
21441 ImplicitValueInitExpr VIE(
21449 bool VisitCastExpr(
const CastExpr *E) {
21452 return ExprEvaluatorBaseTy::VisitCastExpr(E);
21453 case CK_NullToPointer:
21455 return ZeroInitialization(E);
21456 case CK_NonAtomicToAtomic:
21468 return AtomicExprEvaluator(Info,
This,
Result).Visit(E);
21477class VoidExprEvaluator
21478 :
public ExprEvaluatorBase<VoidExprEvaluator> {
21480 VoidExprEvaluator(EvalInfo &Info) : ExprEvaluatorBaseTy(Info) {}
21484 bool ZeroInitialization(
const Expr *E) {
return true; }
21486 bool VisitCastExpr(
const CastExpr *E) {
21489 return ExprEvaluatorBaseTy::VisitCastExpr(E);
21496 bool VisitCallExpr(
const CallExpr *E) {
21497 if (!IsConstantEvaluatedBuiltinCall(E))
21498 return ExprEvaluatorBaseTy::VisitCallExpr(E);
21501 case Builtin::BI__assume:
21502 case Builtin::BI__builtin_assume:
21506 case Builtin::BI__builtin_operator_delete:
21514 bool VisitCXXDeleteExpr(
const CXXDeleteExpr *E);
21518bool VoidExprEvaluator::VisitCXXDeleteExpr(
const CXXDeleteExpr *E) {
21520 if (Info.SpeculativeEvaluationDepth)
21524 if (!OperatorDelete
21525 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
21526 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
21536 if (
Pointer.Designator.Invalid)
21540 if (
Pointer.isNullPointer()) {
21544 if (!Info.getLangOpts().CPlusPlus20)
21545 Info.CCEDiag(E, diag::note_constexpr_new);
21553 QualType AllocType =
Pointer.Base.getDynamicAllocType();
21559 Info.FFDiag(E, diag::note_constexpr_delete_base_nonvirt_dtor)
21568 if (VirtualDelete &&
21570 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
21571 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
21578 (*Alloc)->Value, AllocType))
21581 if (!Info.HeapAllocs.erase(
Pointer.Base.dyn_cast<DynamicAllocLValue>())) {
21586 Info.FFDiag(E, diag::note_constexpr_double_delete);
21596 return VoidExprEvaluator(Info).Visit(E);
21608 if (E->
isGLValue() ||
T->isFunctionType()) {
21613 }
else if (
T->isVectorType()) {
21616 }
else if (
T->isConstantMatrixType()) {
21619 }
else if (
T->isIntegralOrEnumerationType()) {
21620 if (!IntExprEvaluator(Info,
Result).Visit(E))
21622 }
else if (
T->hasPointerRepresentation()) {
21627 }
else if (
T->isRealFloatingType()) {
21628 llvm::APFloat F(0.0);
21632 }
else if (
T->isAnyComplexType()) {
21637 }
else if (
T->isFixedPointType()) {
21638 if (!FixedPointExprEvaluator(Info,
Result).Visit(E))
return false;
21639 }
else if (
T->isMemberPointerType()) {
21645 }
else if (
T->isArrayType()) {
21648 Info.CurrentCall->createTemporary(E,
T, ScopeKind::FullExpression, LV);
21652 }
else if (
T->isRecordType()) {
21655 Info.CurrentCall->createTemporary(E,
T, ScopeKind::FullExpression, LV);
21659 }
else if (
T->isVoidType()) {
21660 if (!Info.getLangOpts().CPlusPlus11)
21661 Info.CCEDiag(E, diag::note_constexpr_nonliteral)
21665 }
else if (
T->isAtomicType()) {
21666 QualType Unqual =
T.getAtomicUnqualifiedType();
21670 E, Unqual, ScopeKind::FullExpression, LV);
21678 }
else if (Info.getLangOpts().CPlusPlus11) {
21679 Info.FFDiag(E, diag::note_constexpr_nonliteral) << E->
getType();
21682 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
21693 const Expr *E,
bool AllowNonLiteralTypes) {
21709 if (
T->isArrayType())
21711 else if (
T->isRecordType())
21713 else if (
T->isAtomicType()) {
21714 QualType Unqual =
T.getAtomicUnqualifiedType();
21735 if (Info.EnableNewConstInterp) {
21736 if (!Info.Ctx.getInterpContext().evaluateAsRValue(Info, E,
Result))
21739 ConstantExprKind::Normal);
21748 LV.setFrom(Info.Ctx,
Result);
21755 ConstantExprKind::Normal) &&
21763 if (
const auto *L = dyn_cast<IntegerLiteral>(Exp)) {
21765 APValue(
APSInt(L->getValue(), L->getType()->isUnsignedIntegerType()));
21770 if (
const auto *L = dyn_cast<CXXBoolLiteralExpr>(Exp)) {
21776 if (
const auto *FL = dyn_cast<FloatingLiteral>(Exp)) {
21782 if (
const auto *L = dyn_cast<CharacterLiteral>(Exp)) {
21788 if (
const auto *CE = dyn_cast<ConstantExpr>(Exp)) {
21789 if (CE->hasAPValueResult()) {
21790 APValue APV = CE->getAPValueResult();
21792 Result = std::move(APV);
21868 bool InConstantContext)
const {
21870 "Expression evaluator can't be called on a dependent expression.");
21871 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsRValue");
21873 Info.InConstantContext = InConstantContext;
21874 return ::EvaluateAsRValue(
this,
Result, Ctx, Info);
21878 bool InConstantContext)
const {
21880 "Expression evaluator can't be called on a dependent expression.");
21881 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsBooleanCondition");
21889 bool InConstantContext)
const {
21891 "Expression evaluator can't be called on a dependent expression.");
21892 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsInt");
21894 Info.InConstantContext = InConstantContext;
21895 return ::EvaluateAsInt(
this,
Result, Ctx, AllowSideEffects, Info);
21900 bool InConstantContext)
const {
21902 "Expression evaluator can't be called on a dependent expression.");
21903 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFixedPoint");
21905 Info.InConstantContext = InConstantContext;
21906 return ::EvaluateAsFixedPoint(
this,
Result, Ctx, AllowSideEffects, Info);
21911 bool InConstantContext)
const {
21913 "Expression evaluator can't be called on a dependent expression.");
21915 if (!
getType()->isRealFloatingType())
21918 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFloat");
21930 bool InConstantContext)
const {
21932 "Expression evaluator can't be called on a dependent expression.");
21934 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsLValue");
21936 Info.InConstantContext = InConstantContext;
21940 if (Info.EnableNewConstInterp) {
21941 if (!Info.Ctx.getInterpContext().evaluate(Info,
this,
Result.Val,
21942 ConstantExprKind::Normal))
21945 LV.setFrom(Ctx,
Result.Val);
21948 ConstantExprKind::Normal, CheckedTemps);
21951 if (!
EvaluateLValue(
this, LV, Info) || !Info.discardCleanups() ||
21952 Result.HasSideEffects ||
21955 ConstantExprKind::Normal, CheckedTemps))
21958 LV.moveInto(
Result.Val);
21965 bool IsConstantDestruction) {
21966 EvalInfo Info(Ctx, EStatus,
21969 Info.setEvaluatingDecl(
Base, DestroyedValue,
21970 EvalInfo::EvaluatingDeclKind::Dtor);
21971 Info.InConstantContext = IsConstantDestruction;
21980 if (!Info.discardCleanups())
21981 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
21989 "Expression evaluator can't be called on a dependent expression.");
21995 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsConstantExpr");
21997 EvalInfo Info(Ctx,
Result, EM);
21998 Info.InConstantContext =
true;
22000 if (Info.EnableNewConstInterp) {
22001 if (!Info.Ctx.getInterpContext().evaluate(Info,
this,
Result.Val, Kind))
22004 getStorageType(Ctx,
this),
Result.Val, Kind);
22009 if (Kind == ConstantExprKind::ClassTemplateArgument)
22025 FullExpressionRAII
Scope(Info);
22030 if (!Info.discardCleanups())
22031 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
22041 if (Kind == ConstantExprKind::ClassTemplateArgument &&
22044 Result.HasSideEffects)) {
22054 bool IsConstantInitialization)
const {
22056 "Expression evaluator can't be called on a dependent expression.");
22057 assert(VD &&
"Need a valid VarDecl");
22059 llvm::TimeTraceScope TimeScope(
"EvaluateAsInitializer", [&] {
22061 llvm::raw_string_ostream OS(Name);
22066 EvalInfo Info(Ctx, EStatus,
22067 (IsConstantInitialization &&
22071 Info.setEvaluatingDecl(VD, EStatus.
Val);
22072 Info.InConstantContext = IsConstantInitialization;
22077 if (Info.EnableNewConstInterp) {
22079 if (!InterpCtx.evaluateAsInitializer(Info, VD,
this, EStatus.
Val))
22083 ConstantExprKind::Normal);
22098 FullExpressionRAII
Scope(Info);
22107 Info.performLifetimeExtension();
22109 if (!Info.discardCleanups())
22110 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
22114 ConstantExprKind::Normal) &&
22134 EStatus.
Diag = &Notes;
22151 EvalInfo Info(Ctx, EStatus,
22154 Info.InConstantContext = IsConstantDestruction;
22156 std::move(DestroyedValue)))
22163 getLocation(), EStatus, IsConstantDestruction) ||
22175 "Expression evaluator can't be called on a dependent expression.");
22184 "Expression evaluator can't be called on a dependent expression.");
22186 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstInt");
22189 Info.InConstantContext =
true;
22193 assert(
Result &&
"Could not evaluate expression");
22194 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
22196 return EVResult.Val.getInt();
22202 "Expression evaluator can't be called on a dependent expression.");
22204 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstIntCheckOverflow");
22206 EVResult.Diag =
Diag;
22208 Info.InConstantContext =
true;
22209 Info.CheckingForUndefinedBehavior =
true;
22213 assert(
Result &&
"Could not evaluate expression");
22214 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
22216 return EVResult.Val.getInt();
22221 "Expression evaluator can't be called on a dependent expression.");
22223 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateForOverflow");
22228 Info.CheckingForUndefinedBehavior =
true;
22234 assert(
Val.isLValue());
22260 IK_ICEIfUnevaluated,
22276static ICEDiag
Worst(ICEDiag A, ICEDiag B) {
return A.Kind >= B.Kind ? A : B; }
22283 Info.InConstantContext =
true;
22292 assert(!E->
isValueDependent() &&
"Should not see value dependent exprs!");
22297#define ABSTRACT_STMT(Node)
22298#define STMT(Node, Base) case Expr::Node##Class:
22299#define EXPR(Node, Base)
22300#include "clang/AST/StmtNodes.inc"
22301 case Expr::PredefinedExprClass:
22302 case Expr::FloatingLiteralClass:
22303 case Expr::ImaginaryLiteralClass:
22304 case Expr::StringLiteralClass:
22305 case Expr::ArraySubscriptExprClass:
22306 case Expr::MatrixSingleSubscriptExprClass:
22307 case Expr::MatrixSubscriptExprClass:
22308 case Expr::ArraySectionExprClass:
22309 case Expr::OMPArrayShapingExprClass:
22310 case Expr::OMPIteratorExprClass:
22311 case Expr::CompoundAssignOperatorClass:
22312 case Expr::CompoundLiteralExprClass:
22313 case Expr::ExtVectorElementExprClass:
22314 case Expr::MatrixElementExprClass:
22315 case Expr::DesignatedInitExprClass:
22316 case Expr::ArrayInitLoopExprClass:
22317 case Expr::ArrayInitIndexExprClass:
22318 case Expr::NoInitExprClass:
22319 case Expr::DesignatedInitUpdateExprClass:
22320 case Expr::ImplicitValueInitExprClass:
22321 case Expr::ParenListExprClass:
22322 case Expr::VAArgExprClass:
22323 case Expr::AddrLabelExprClass:
22324 case Expr::StmtExprClass:
22325 case Expr::CXXMemberCallExprClass:
22326 case Expr::CUDAKernelCallExprClass:
22327 case Expr::CXXAddrspaceCastExprClass:
22328 case Expr::CXXDynamicCastExprClass:
22329 case Expr::CXXTypeidExprClass:
22330 case Expr::CXXUuidofExprClass:
22331 case Expr::MSPropertyRefExprClass:
22332 case Expr::MSPropertySubscriptExprClass:
22333 case Expr::CXXNullPtrLiteralExprClass:
22334 case Expr::UserDefinedLiteralClass:
22335 case Expr::CXXThisExprClass:
22336 case Expr::CXXThrowExprClass:
22337 case Expr::CXXNewExprClass:
22338 case Expr::CXXDeleteExprClass:
22339 case Expr::CXXPseudoDestructorExprClass:
22340 case Expr::UnresolvedLookupExprClass:
22341 case Expr::RecoveryExprClass:
22342 case Expr::DependentScopeDeclRefExprClass:
22343 case Expr::CXXConstructExprClass:
22344 case Expr::CXXInheritedCtorInitExprClass:
22345 case Expr::CXXStdInitializerListExprClass:
22346 case Expr::CXXBindTemporaryExprClass:
22347 case Expr::ExprWithCleanupsClass:
22348 case Expr::CXXTemporaryObjectExprClass:
22349 case Expr::CXXUnresolvedConstructExprClass:
22350 case Expr::CXXDependentScopeMemberExprClass:
22351 case Expr::UnresolvedMemberExprClass:
22352 case Expr::ObjCStringLiteralClass:
22353 case Expr::ObjCBoxedExprClass:
22354 case Expr::ObjCArrayLiteralClass:
22355 case Expr::ObjCDictionaryLiteralClass:
22356 case Expr::ObjCEncodeExprClass:
22357 case Expr::ObjCMessageExprClass:
22358 case Expr::ObjCSelectorExprClass:
22359 case Expr::ObjCProtocolExprClass:
22360 case Expr::ObjCIvarRefExprClass:
22361 case Expr::ObjCPropertyRefExprClass:
22362 case Expr::ObjCSubscriptRefExprClass:
22363 case Expr::ObjCIsaExprClass:
22364 case Expr::ObjCAvailabilityCheckExprClass:
22365 case Expr::ShuffleVectorExprClass:
22366 case Expr::ConvertVectorExprClass:
22367 case Expr::BlockExprClass:
22369 case Expr::OpaqueValueExprClass:
22370 case Expr::PackExpansionExprClass:
22371 case Expr::SubstNonTypeTemplateParmPackExprClass:
22372 case Expr::FunctionParmPackExprClass:
22373 case Expr::AsTypeExprClass:
22374 case Expr::ObjCIndirectCopyRestoreExprClass:
22375 case Expr::MaterializeTemporaryExprClass:
22376 case Expr::PseudoObjectExprClass:
22377 case Expr::AtomicExprClass:
22378 case Expr::LambdaExprClass:
22379 case Expr::CXXFoldExprClass:
22380 case Expr::CoawaitExprClass:
22381 case Expr::DependentCoawaitExprClass:
22382 case Expr::CoyieldExprClass:
22383 case Expr::SYCLUniqueStableNameExprClass:
22384 case Expr::CXXParenListInitExprClass:
22385 case Expr::HLSLOutArgExprClass:
22386 case Expr::CXXExpansionSelectExprClass:
22389 case Expr::MemberExprClass: {
22392 while (
const auto *M = dyn_cast<MemberExpr>(ME)) {
22395 ME = M->getBase()->IgnoreParenImpCasts();
22397 const auto *DRE = dyn_cast<DeclRefExpr>(ME);
22399 if (
const auto *VD = dyn_cast<VarDecl>(DRE->getDecl());
22407 case Expr::InitListExprClass: {
22418 case Expr::SizeOfPackExprClass:
22419 case Expr::GNUNullExprClass:
22420 case Expr::SourceLocExprClass:
22421 case Expr::EmbedExprClass:
22422 case Expr::OpenACCAsteriskSizeExprClass:
22425 case Expr::PackIndexingExprClass:
22428 case Expr::SubstNonTypeTemplateParmExprClass:
22432 case Expr::ConstantExprClass:
22435 case Expr::ParenExprClass:
22437 case Expr::GenericSelectionExprClass:
22439 case Expr::IntegerLiteralClass:
22440 case Expr::FixedPointLiteralClass:
22441 case Expr::CharacterLiteralClass:
22442 case Expr::ObjCBoolLiteralExprClass:
22443 case Expr::CXXBoolLiteralExprClass:
22444 case Expr::CXXScalarValueInitExprClass:
22445 case Expr::TypeTraitExprClass:
22446 case Expr::ConceptSpecializationExprClass:
22447 case Expr::RequiresExprClass:
22448 case Expr::ArrayTypeTraitExprClass:
22449 case Expr::ExpressionTraitExprClass:
22450 case Expr::CXXNoexceptExprClass:
22451 case Expr::CXXReflectExprClass:
22453 case Expr::CallExprClass:
22454 case Expr::CXXOperatorCallExprClass: {
22463 case Expr::CXXRewrittenBinaryOperatorClass:
22466 case Expr::DeclRefExprClass: {
22480 const VarDecl *VD = dyn_cast<VarDecl>(D);
22487 case Expr::UnaryOperatorClass: {
22510 llvm_unreachable(
"invalid unary operator class");
22512 case Expr::OffsetOfExprClass: {
22521 case Expr::UnaryExprOrTypeTraitExprClass: {
22523 if ((Exp->
getKind() == UETT_SizeOf) &&
22526 if (Exp->
getKind() == UETT_CountOf) {
22533 if (VAT->getElementType()->isArrayType())
22545 case Expr::BinaryOperatorClass: {
22590 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE) {
22593 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
22594 if (REval.isSigned() && REval.isAllOnes()) {
22596 if (LEval.isMinSignedValue())
22597 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
22605 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE)
22606 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
22612 return Worst(LHSResult, RHSResult);
22618 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICEIfUnevaluated) {
22628 return Worst(LHSResult, RHSResult);
22631 llvm_unreachable(
"invalid binary operator kind");
22633 case Expr::ImplicitCastExprClass:
22634 case Expr::CStyleCastExprClass:
22635 case Expr::CXXFunctionalCastExprClass:
22636 case Expr::CXXStaticCastExprClass:
22637 case Expr::CXXReinterpretCastExprClass:
22638 case Expr::CXXConstCastExprClass:
22639 case Expr::ObjCBridgedCastExprClass: {
22646 APSInt IgnoredVal(DestWidth, !DestSigned);
22651 if (FL->getValue().convertToInteger(IgnoredVal,
22652 llvm::APFloat::rmTowardZero,
22653 &Ignored) & APFloat::opInvalidOp)
22659 case CK_LValueToRValue:
22660 case CK_AtomicToNonAtomic:
22661 case CK_NonAtomicToAtomic:
22663 case CK_IntegralToBoolean:
22664 case CK_IntegralCast:
22670 case Expr::BinaryConditionalOperatorClass: {
22673 if (CommonResult.Kind == IK_NotICE)
return CommonResult;
22675 if (FalseResult.Kind == IK_NotICE)
return FalseResult;
22676 if (CommonResult.Kind == IK_ICEIfUnevaluated)
return CommonResult;
22677 if (FalseResult.Kind == IK_ICEIfUnevaluated &&
22679 return FalseResult;
22681 case Expr::ConditionalOperatorClass: {
22689 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
22692 if (CondResult.Kind == IK_NotICE)
22698 if (TrueResult.Kind == IK_NotICE)
22700 if (FalseResult.Kind == IK_NotICE)
22701 return FalseResult;
22702 if (CondResult.Kind == IK_ICEIfUnevaluated)
22704 if (TrueResult.Kind == IK_ICE && FalseResult.Kind == IK_ICE)
22710 return FalseResult;
22713 case Expr::CXXDefaultArgExprClass:
22715 case Expr::CXXDefaultInitExprClass:
22717 case Expr::ChooseExprClass: {
22720 case Expr::BuiltinBitCastExprClass: {
22721 if (!checkBitCastConstexprEligibility(
nullptr, Ctx,
cast<CastExpr>(E)))
22727 llvm_unreachable(
"Invalid StmtClass!");
22733 llvm::APSInt *
Value,
22734 bool AllowRelaxedEval =
false) {
22751 "Expression evaluator can't be called on a dependent expression.");
22753 ExprTimeTraceScope TimeScope(
this, Ctx,
"isIntegerConstantExpr");
22759 if (D.Kind != IK_ICE)
22764std::optional<llvm::APSInt>
22766 bool AllowRelaxedEval)
const {
22769 return std::nullopt;
22777 return std::nullopt;
22781 return std::nullopt;
22790 Info.InConstantContext =
true;
22793 llvm_unreachable(
"ICE cannot be evaluated!");
22800 "Expression evaluator can't be called on a dependent expression.");
22802 return CheckICE(
this, Ctx).Kind == IK_ICE;
22806 bool AllowRelaxedEval)
const {
22808 "Expression evaluator can't be called on a dependent expression.");
22818 *
Result = std::move(Scratch);
22826 Status.ExtendedDiag = AllowRelaxedEval ? &MSRelaxedDiag :
nullptr;
22832 Info.discardCleanups() && !Status.HasSideEffects;
22834 return IsConstExpr && !Status.DiagEmitted;
22842 "Expression evaluator can't be called on a dependent expression.");
22844 llvm::TimeTraceScope TimeScope(
"EvaluateWithSubstitution", [&] {
22846 llvm::raw_string_ostream OS(Name);
22854 Info.InConstantContext =
true;
22856 if (Info.EnableNewConstInterp) {
22857 if (std::optional<bool> BoolResult =
22858 Info.Ctx.getInterpContext().evaluateWithSubstitution(
22859 Info, Callee, Args,
This,
this)) {
22867 const LValue *ThisPtr =
nullptr;
22870 auto *MD = dyn_cast<CXXMethodDecl>(Callee);
22871 assert(MD &&
"Don't provide `this` for non-methods.");
22872 assert(MD->isImplicitObjectMemberFunction() &&
22873 "Don't provide `this` for methods without an implicit object.");
22875 if (!
This->isValueDependent() &&
22877 !Info.EvalStatus.HasSideEffects)
22878 ThisPtr = &ThisVal;
22882 Info.EvalStatus.HasSideEffects =
false;
22885 CallRef
Call = Info.CurrentCall->createCall(Callee);
22888 unsigned Idx = I - Args.begin();
22889 if (Idx >= Callee->getNumParams())
22891 const ParmVarDecl *PVD = Callee->getParamDecl(Idx);
22892 if ((*I)->isValueDependent() ||
22894 Info.EvalStatus.HasSideEffects) {
22896 if (
APValue *Slot = Info.getParamSlot(
Call, PVD))
22902 Info.EvalStatus.HasSideEffects =
false;
22907 Info.discardCleanups();
22908 Info.EvalStatus.HasSideEffects =
false;
22911 CallStackFrame Frame(Info, Callee->getLocation(), Callee, ThisPtr,
This,
22914 FullExpressionRAII
Scope(Info);
22916 !Info.EvalStatus.HasSideEffects;
22928 llvm::TimeTraceScope TimeScope(
"isPotentialConstantExpr", [&] {
22930 llvm::raw_string_ostream OS(Name);
22937 Status.
Diag = &Diags;
22941 Info.InConstantContext =
true;
22942 Info.CheckingPotentialConstantExpression =
true;
22945 if (Info.EnableNewConstInterp) {
22946 Info.Ctx.getInterpContext().isPotentialConstantExpr(Info, FD);
22947 return Diags.empty();
22958 This.set({&VIE, Info.CurrentCall->Index});
22966 Info.setEvaluatingDecl(
This.getLValueBase(), Scratch);
22972 &VIE, Args, CallRef(), FD->
getBody(), Info, Scratch,
22976 return Diags.empty();
22984 "Expression evaluator can't be called on a dependent expression.");
22987 Status.
Diag = &Diags;
22991 Info.InConstantContext =
true;
22992 Info.CheckingPotentialConstantExpression =
true;
22994 if (Info.EnableNewConstInterp) {
22995 Info.Ctx.getInterpContext().isPotentialConstantExprUnevaluated(Info, E, FD);
22996 return Diags.empty();
23001 nullptr, CallRef());
23005 return Diags.empty();
23009 unsigned Type)
const {
23010 if (!
getType()->isPointerType())
23011 return std::nullopt;
23015 if (Info.EnableNewConstInterp)
23016 return Info.Ctx.getInterpContext().tryEvaluateObjectSize(Info,
this,
Type);
23020static std::optional<uint64_t>
23022 std::string *StringResult) {
23024 return std::nullopt;
23029 return std::nullopt;
23034 if (
const StringLiteral *S = dyn_cast_or_null<StringLiteral>(
23035 String.getLValueBase().dyn_cast<
const Expr *>())) {
23038 if (
Off >= 0 && (uint64_t)
Off <= (uint64_t)Str.size() &&
23041 Info.Ctx.hasSameUnqualifiedType(CharTy, Info.Ctx.CharTy)) {
23042 Str = Str.substr(
Off);
23044 StringRef::size_type Pos = Str.find(0);
23045 if (Pos != StringRef::npos)
23046 Str = Str.substr(0, Pos);
23049 *StringResult = Str;
23057 for (uint64_t Strlen = 0; ; ++Strlen) {
23061 return std::nullopt;
23064 else if (StringResult)
23065 StringResult->push_back(Char.
getInt().getExtValue());
23067 return std::nullopt;
23074 std::string StringResult;
23076 if (Info.EnableNewConstInterp) {
23077 if (!Info.Ctx.getInterpContext().evaluateString(Info,
this, StringResult))
23078 return std::nullopt;
23079 return StringResult;
23083 return StringResult;
23084 return std::nullopt;
23087template <
typename T>
23089 const Expr *SizeExpression,
23090 const Expr *PtrExpression,
23094 Info.InConstantContext =
true;
23096 if (Info.EnableNewConstInterp)
23097 return Info.Ctx.getInterpContext().evaluateCharRange(Info, SizeExpression,
23101 FullExpressionRAII
Scope(Info);
23106 uint64_t Size = SizeValue.getZExtValue();
23109 if constexpr (std::is_same_v<APValue, T>)
23112 if (Size <
Result.max_size())
23119 for (uint64_t I = 0; I < Size; ++I) {
23125 if constexpr (std::is_same_v<APValue, T>) {
23126 Result.getArrayInitializedElt(I) = std::move(Char);
23130 assert(
C.getBitWidth() <= 8 &&
23131 "string element not representable in char");
23133 Result.push_back(
static_cast<char>(
C.getExtValue()));
23144 const Expr *SizeExpression,
23148 PtrExpression, Ctx, Status);
23152 const Expr *SizeExpression,
23156 PtrExpression, Ctx, Status);
23163 if (Info.EnableNewConstInterp)
23164 return Info.Ctx.getInterpContext().evaluateStrlen(Info,
this);
23169struct IsWithinLifetimeHandler {
23172 using result_type = std::optional<bool>;
23173 std::optional<bool> failed() {
return std::nullopt; }
23174 template <
typename T>
23175 std::optional<bool> found(
T &Subobj,
QualType SubobjType,
23179 template <
typename T>
23180 std::optional<bool> found(
T &Subobj, QualType SubobjType) {
23185std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &IEE,
23186 const CallExpr *E) {
23187 EvalInfo &Info = IEE.Info;
23192 if (!Info.InConstantContext)
23193 return std::nullopt;
23195 const Expr *Arg = E->
getArg(0);
23197 return std::nullopt;
23200 return std::nullopt;
23202 if (Val.allowConstexprUnknown())
23206 bool CalledFromStd =
false;
23207 const auto *
Callee = Info.CurrentCall->getCallee();
23208 if (Callee &&
Callee->isInStdNamespace()) {
23209 const IdentifierInfo *Identifier =
Callee->getIdentifier();
23210 CalledFromStd = Identifier && Identifier->
isStr(
"is_within_lifetime");
23212 Info.CCEDiag(CalledFromStd ? Info.CurrentCall->getCallRange().getBegin()
23214 diag::err_invalid_is_within_lifetime)
23215 << (CalledFromStd ?
"std::is_within_lifetime"
23216 :
"__builtin_is_within_lifetime")
23218 return std::nullopt;
23228 if (Val.isNullPointer() || Val.getLValueBase().isNull())
23230 QualType
T = Val.getLValueBase().getType();
23232 "Pointers to functions should have been typed as function pointers "
23233 "which would have been rejected earlier");
23236 if (Val.getLValueDesignator().isOnePastTheEnd())
23238 assert(Val.getLValueDesignator().isValidSubobject() &&
23239 "Unchecked case for valid subobject");
23243 CompleteObject CO =
23247 if (Info.EvaluatingDeclValue && CO.Value == Info.EvaluatingDeclValue)
23252 IsWithinLifetimeHandler handler{Info};
23253 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 bool CheckEvaluationResult(CheckEvaluationResultKind CERK, EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value, ConstantExprKind Kind, const FieldDecl *SubobjectDecl, CheckedTemporaries &CheckedTemps, bool IsCompleteClass=true)
static const CXXMethodDecl * HandleVirtualDispatch(EvalInfo &Info, const Expr *E, LValue &This, const CXXMethodDecl *Found, llvm::SmallVectorImpl< QualType > &CovariantAdjustmentPath)
Perform virtual dispatch.
static bool EvaluateVarDecl(EvalInfo &Info, const VarDecl *VD)
static bool HandleLValueComplexElement(EvalInfo &Info, const Expr *E, LValue &LVal, QualType EltTy, bool Imag)
Update an lvalue to refer to a component of a complex number.
static bool evalPackBuiltin(const CallExpr *E, EvalInfo &Info, APValue &Result, llvm::function_ref< APInt(const APSInt &)> PackFn)
static bool HandleSizeof(EvalInfo &Info, SourceLocation Loc, QualType Type, CharUnits &Size, SizeOfType SOT=SizeOfType::SizeOf)
Get the size of the given type in char units.
static bool hlslElementwiseCastHelper(EvalInfo &Info, const Expr *E, QualType DestTy, SmallVectorImpl< APValue > &SrcVals, SmallVectorImpl< QualType > &SrcTypes)
static bool ShouldPropagateBreakContinue(EvalInfo &Info, const Stmt *LoopOrSwitch, ArrayRef< BlockScopeRAII * > Scopes, EvalStmtResult &ESR)
Helper to implement named break/continue.
static EvalStmtResult EvaluateLoopBody(StmtResult &Result, EvalInfo &Info, const Stmt *Body, const SwitchCase *Case=nullptr)
Evaluate the body of a loop, and translate the result as appropriate.
static bool EvaluatePointer(const Expr *E, LValue &Result, EvalInfo &Info, bool InvalidBaseOK=false)
static bool CheckTrivialDefaultConstructor(EvalInfo &Info, SourceLocation Loc, const CXXConstructorDecl *CD, bool IsValueInitialization)
CheckTrivialDefaultConstructor - Check whether a constructor is a trivial default constructor.
static bool EvaluateVector(const Expr *E, APValue &Result, EvalInfo &Info)
static const ValueDecl * GetLValueBaseDecl(const LValue &LVal)
static bool TryEvaluateBuiltinNaN(const ASTContext &Context, QualType ResultTy, const Expr *Arg, bool SNaN, llvm::APFloat &Result)
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 EvaluateComplex(const Expr *E, ComplexValue &Res, EvalInfo &Info)
std::optional< APFloat > EvalScalarMinMaxFp(const APFloat &A, const APFloat &B, std::optional< APSInt > RoundingMode, bool IsMin)
static bool CheckMemoryLeaks(EvalInfo &Info)
Enforce C++2a [expr.const]/4.17, which disallows new-expressions unless "the allocated storage is dea...
static bool handleScalarCast(EvalInfo &Info, const FPOptions FPO, const Expr *E, QualType SourceTy, QualType DestTy, APValue const &Original, APValue &Result)
static ICEDiag CheckEvalInICE(const Expr *E, const ASTContext &Ctx)
static llvm::APInt ConvertBoolVectorToInt(const APValue &Val)
static bool flattenAPValue(EvalInfo &Info, const Expr *E, APValue Value, QualType BaseTy, SmallVectorImpl< APValue > &Elements, SmallVectorImpl< QualType > &Types, unsigned Size)
static bool hlslAggSplatHelper(EvalInfo &Info, const Expr *E, APValue &SrcVal, QualType &SrcTy)
static bool isBaseClassPublic(const CXXRecordDecl *Derived, const CXXRecordDecl *Base)
Determine whether Base, which is known to be a direct base class of Derived, is a public base class.
static bool hasVirtualDestructor(QualType T)
static bool HandleOverflow(EvalInfo &Info, const Expr *E, const T &SrcValue, QualType DestType)
static CharUnits getBaseAlignment(EvalInfo &Info, const LValue &Value)
static bool HandleLValueIndirectMember(EvalInfo &Info, const Expr *E, LValue &LVal, const IndirectFieldDecl *IFD)
Update LVal to refer to the given indirect field.
unsigned ConvertBuiltinIDToX86BuiltinID(const ASTContext &Ctx, unsigned BuiltinOp)
Convert a builtin ID to the canonical x86 builtin ID the constant evaluators dispatch on in their x86...
static bool ConvertDoubleToFloatStrict(EvalInfo &Info, const Expr *E, APFloat OrigVal, APValue &Result)
static ICEDiag Worst(ICEDiag A, ICEDiag B)
static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E, const VarDecl *VD, CallStackFrame *Frame, unsigned Version, APValue *&Result)
Try to evaluate the initializer for a variable declaration.
static bool HandleLValueVectorElement(EvalInfo &Info, const Expr *E, LValue &LVal, QualType EltTy, uint64_t Size, uint64_t Idx)
static bool checkFloatingPointResultForConstantFolding(EvalInfo &Info, const Expr *E, APFloat::opStatus St)
Check if the given floating-point evaluation result is allowed for compile-time constant folding duri...
static void NoteLValueLocation(EvalInfo &Info, APValue::LValueBase Base)
static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc, QualType Type, const LValue &LVal, ConstantExprKind Kind, CheckedTemporaries &CheckedTemps)
Check that this reference or pointer core constant expression is a valid value for an address or refe...
static bool CheckedIntArithmetic(EvalInfo &Info, const Expr *E, const APSInt &LHS, const APSInt &RHS, unsigned BitWidth, Operation Op, APSInt &Result)
Perform the given integer operation, which is known to need at most BitWidth bits,...
static bool EvaluateTemporary(const Expr *E, LValue &Result, EvalInfo &Info)
Evaluate an expression of record type as a temporary.
static bool EvaluateArray(const Expr *E, const LValue &This, APValue &Result, EvalInfo &Info)
static bool truncateBitfieldValue(EvalInfo &Info, const Expr *E, APValue &Value, const FieldDecl *FD)
static bool handleVectorShuffle(EvalInfo &Info, const ShuffleVectorExpr *E, QualType ElemType, APValue const &VecVal1, APValue const &VecVal2, unsigned EltNum, APValue &Result)
static bool handleVectorElementCast(EvalInfo &Info, const FPOptions FPO, const Expr *E, QualType SourceTy, QualType DestTy, APValue const &Original, APValue &Result)
static const ValueDecl * HandleMemberPointerAccess(EvalInfo &Info, QualType LVType, LValue &LV, const Expr *RHS, bool IncludeMember=true)
HandleMemberPointerAccess - Evaluate a member access operation and build an lvalue referring to the r...
static bool HandleBaseToDerivedCast(EvalInfo &Info, const CastExpr *E, LValue &Result)
HandleBaseToDerivedCast - Apply the given base-to-derived cast operation on the provided lvalue,...
static bool EvaluateFloat(const Expr *E, APFloat &Result, EvalInfo &Info)
static bool IsOpaqueConstantCall(const CallExpr *E)
Should this call expression be treated as forming an opaque constant?
static bool CheckMemberPointerConstantExpression(EvalInfo &Info, SourceLocation Loc, QualType Type, const APValue &Value, ConstantExprKind Kind)
Member pointers are constant expressions unless they point to a non-virtual dllimport member function...
static bool EvaluateAsInt(const Expr *E, Expr::EvalResult &ExprResult, const ASTContext &Ctx, Expr::SideEffectsKind AllowSideEffects, EvalInfo &Info)
static bool handleLValueToRValueConversion(EvalInfo &Info, const Expr *Conv, QualType Type, const LValue &LVal, APValue &RVal, bool WantObjectRepresentation=false)
Perform an lvalue-to-rvalue conversion on the given glvalue.
static bool handleElementwiseCast(EvalInfo &Info, const Expr *E, const FPOptions FPO, SmallVectorImpl< APValue > &Elements, SmallVectorImpl< QualType > &SrcTypes, SmallVectorImpl< QualType > &DestTypes, SmallVectorImpl< APValue > &Results)
static bool refersToCompleteObject(const LValue &LVal)
Tests to see if the LValue has a user-specified designator (that isn't necessarily valid)....
static bool AreElementsOfSameArray(QualType ObjType, const SubobjectDesignator &A, const SubobjectDesignator &B)
Determine whether the given subobject designators refer to elements of the same array object.
static bool EvaluateDecompositionDeclInit(EvalInfo &Info, const DecompositionDecl *DD)
static bool IsWeakLValue(const LValue &Value)
static bool EvaluateArrayNewConstructExpr(EvalInfo &Info, LValue &This, APValue &Result, const CXXConstructExpr *CCE, QualType AllocType)
static bool EvaluateRecord(const Expr *E, const LValue &This, APValue &Result, EvalInfo &Info)
static bool handleAssignment(EvalInfo &Info, const Expr *E, const LValue &LVal, QualType LValType, APValue &Val)
Perform an assignment of Val to LVal. Takes ownership of Val.
static bool CastToDerivedClass(EvalInfo &Info, const Expr *E, LValue &Result, const RecordDecl *TruncatedType, unsigned TruncatedElements)
Cast an lvalue referring to a base subobject to a derived class, by truncating the lvalue's path to t...
static bool EvaluateIgnoredValue(EvalInfo &Info, const Expr *E)
Evaluate an expression to see if it had side-effects, and discard its result.
static bool constructAggregate(EvalInfo &Info, const FPOptions FPO, const Expr *E, APValue &Result, QualType ResultType, SmallVectorImpl< APValue > &Elements, SmallVectorImpl< QualType > &ElTypes)
static void addFlexibleArrayMemberInitSize(EvalInfo &Info, const QualType &T, const LValue &LV, CharUnits &Size)
If we're evaluating the object size of an instance of a struct that contains a flexible array member,...
static bool HandleLValueBasePath(EvalInfo &Info, const CastExpr *E, QualType Type, LValue &Result)
static bool evalShuffleGeneric(EvalInfo &Info, const CallExpr *Call, APValue &Out, llvm::function_ref< std::pair< unsigned, int >(unsigned, unsigned)> GetSourceIndex)
static QualType getSubobjectType(QualType ObjType, QualType SubobjType, bool IsMutable=false)
static bool EvaluateFixedPointOrInteger(const Expr *E, APFixedPoint &Result, EvalInfo &Info)
Evaluate an integer or fixed point expression into an APResult.
static bool HandleIntToFloatCast(EvalInfo &Info, const Expr *E, const FPOptions FPO, QualType SrcType, const APSInt &Value, QualType DestType, APFloat &Result)
static const CXXRecordDecl * getBaseClassType(SubobjectDesignator &Designator, unsigned PathLength)
static bool CastToBaseClass(EvalInfo &Info, const Expr *E, LValue &Result, const CXXRecordDecl *DerivedRD, const CXXRecordDecl *BaseRD)
Cast an lvalue referring to a derived class to a known base subobject.
static bool HandleLValueBase(EvalInfo &Info, const Expr *E, LValue &Obj, const CXXRecordDecl *DerivedDecl, const CXXBaseSpecifier *Base)
static bool HandleLValueDirectVirtualBase(EvalInfo &Info, const Expr *E, LValue &Obj, const CXXRecordDecl *Derived, const CXXRecordDecl *Base, const ASTRecordLayout *RL=nullptr)
static bool HandleConversionToBool(const APValue &Val, bool &Result)
static void expandVector(APValue &Vec, unsigned NumElements)
CharUnits GetAlignOfExpr(const ASTContext &Ctx, const Expr *E, UnaryExprOrTypeTrait ExprKind)
static bool handleCompareOpForVector(const APValue &LHSValue, BinaryOperatorKind Opcode, const APValue &RHSValue, APInt &Result)
static bool MaybeElementDependentArrayFiller(const Expr *FillerExpr)
static bool EvaluateObjectArgument(EvalInfo &Info, const Expr *Object, LValue &This)
Build an lvalue for the object argument of a member function call.
static bool CheckLiteralType(EvalInfo &Info, const Expr *E, const LValue *This=nullptr)
Check that this core constant expression is of literal type, and if not, produce an appropriate diagn...
static bool EvaluateInteger(const Expr *E, APSInt &Result, EvalInfo &Info)
CheckEvaluationResultKind
static bool isZeroSized(const LValue &Value)
static APSInt extractStringLiteralCharacter(EvalInfo &Info, const Expr *Lit, uint64_t Index)
Extract the value of a character from a string literal.
static bool modifySubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, const SubobjectDesignator &Sub, APValue &NewVal)
Update the designated sub-object of an rvalue to the given value.
static CharUnits GetAlignOfType(const ASTContext &Ctx, QualType T, UnaryExprOrTypeTrait ExprKind)
static bool getBuiltinAlignArguments(const CallExpr *E, EvalInfo &Info, APValue &Val, APSInt &Alignment)
static bool HandleLValueArrayAdjustment(EvalInfo &Info, const Expr *E, LValue &LVal, QualType EltTy, APSInt Adjustment)
Update a pointer value to model pointer arithmetic.
static bool extractSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, const SubobjectDesignator &Sub, APValue &Result, AccessKinds AK=AK_Read)
Extract the designated sub-object of an rvalue.
static bool HandleLValueMember(EvalInfo &Info, const Expr *E, LValue &LVal, const FieldDecl *FD, const ASTRecordLayout *RL=nullptr)
Update LVal to refer to the given field, which must be a member of the type currently described by LV...
static void addOrSubLValueAsInteger(APValue &LVal, const APSInt &Index, bool IsSub)
static bool IsDeclSourceLocationCurrent(const FunctionDecl *FD)
static std::optional< uint64_t > EvaluateBuiltinStrLen(const Expr *E, EvalInfo &Info, std::string *StringResult=nullptr)
void HandleComplexComplexDiv(APFloat A, APFloat B, APFloat C, APFloat D, APFloat &ResR, APFloat &ResI)
static bool handleTrivialCopy(EvalInfo &Info, const ParmVarDecl *Param, const Expr *E, APValue &Result, bool CopyObjectRepresentation)
Perform a trivial copy from Param, which is the parameter of a copy or move constructor or assignment...
static bool EvaluateBuiltinConstantPForLValue(const APValue &LV)
EvaluateBuiltinConstantPForLValue - Determine the result of __builtin_constant_p when applied to the ...
static bool EvaluateBuiltinConstantP(EvalInfo &Info, const Expr *Arg)
EvaluateBuiltinConstantP - Evaluate __builtin_constant_p as similarly to GCC as we can manage.
static bool checkNonVirtualMemberCallThisPointer(EvalInfo &Info, const Expr *E, const LValue &This, const CXXMethodDecl *NamedMember)
Check that the pointee of the 'this' pointer in a member function call is either within its lifetime ...
static bool CheckConstantExpression(EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value, ConstantExprKind Kind)
Check that this core constant expression value is a valid value for a constant expression.
static bool EvaluateAsBooleanCondition(const Expr *E, bool &Result, EvalInfo &Info)
static std::optional< DynamicType > ComputeDynamicType(EvalInfo &Info, const Expr *E, LValue &This, AccessKinds AK)
Determine the dynamic type of an object.
static bool EvaluateDecl(EvalInfo &Info, const Decl *D, bool EvaluateConditionDecl=false)
static void expandArray(APValue &Array, unsigned Index)
static bool handleLogicalOpForVector(const APInt &LHSValue, BinaryOperatorKind Opcode, const APInt &RHSValue, APInt &Result)
static unsigned FindDesignatorMismatch(QualType ObjType, const SubobjectDesignator &A, const SubobjectDesignator &B, bool &WasArrayIndex)
Find the position where two subobject designators diverge, or equivalently the length of the common i...
static bool isOnePastTheEndOfCompleteObject(const ASTContext &Ctx, const LValue &LV)
Determine whether this is a pointer past the end of the complete object referred to by the lvalue.
static unsigned getBaseIndex(const CXXRecordDecl *Derived, const CXXRecordDecl *Base)
Get the base index of the given base class within an APValue representing the given derived class.
static bool EvaluateFixedPoint(const Expr *E, APFixedPoint &Result, EvalInfo &Info)
Evaluate only a fixed point expression into an APResult.
void HandleComplexComplexMul(APFloat A, APFloat B, APFloat C, APFloat D, APFloat &ResR, APFloat &ResI)
static bool HandleDestructionImpl(EvalInfo &Info, SourceRange CallRange, const LValue &This, APValue &Value, QualType T, bool IsCompleteClass=true)
static bool EvalPointerValueAsBool(const APValue &Value, bool &Result)
static bool handleVectorVectorBinOp(EvalInfo &Info, const BinaryOperator *E, BinaryOperatorKind Opcode, APValue &LHSValue, const APValue &RHSValue)
static bool 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 HandleClassZeroInitialization(EvalInfo &Info, const Expr *E, const RecordDecl *RD, const LValue &This, APValue &Result, bool IsCompleteClass=true)
Perform zero-initialization on an object of non-union class type. C++11 [dcl.init]p5: To zero-initial...
static bool EvaluateCPlusPlus11IntegralConstantExpr(const ASTContext &Ctx, const Expr *E, llvm::APSInt *Value, bool AllowRelaxedEval=false)
Evaluate an expression as a C++11 integral constant expression.
static bool EvaluateLValue(const Expr *E, LValue &Result, EvalInfo &Info, bool InvalidBaseOK=false)
Evaluate an expression as an lvalue. This can be legitimately called on expressions which are not glv...
static bool HandleConstructorCall(const Expr *E, const LValue &This, CallRef Call, const CXXConstructorDecl *Definition, EvalInfo &Info, APValue &Result, bool IsCompleteClass=true)
Evaluate a constructor call.
static bool FastEvaluateAsRValue(const Expr *Exp, APValue &Result, const ASTContext &Ctx, bool &IsConst)
static bool HandleCovariantReturnAdjustment(EvalInfo &Info, const Expr *E, APValue &Result, ArrayRef< QualType > Path)
Perform the adjustment from a value returned by a virtual function to a value of the statically expec...
static bool evalShiftWithCount(EvalInfo &Info, const CallExpr *Call, APValue &Out, llvm::function_ref< APInt(const APInt &, uint64_t)> ShiftOp, llvm::function_ref< APInt(const APInt &, unsigned)> OverflowOp)
static EvalStmtResult EvaluateSwitch(StmtResult &Result, EvalInfo &Info, const SwitchStmt *SS)
Evaluate a switch statement.
static void expandStringLiteral(EvalInfo &Info, const StringLiteral *S, APValue &Result, QualType AllocType=QualType())
static bool EvaluateArgs(ArrayRef< const Expr * > Args, CallRef Call, EvalInfo &Info, const FunctionDecl *Callee, bool RightToLeft=false, LValue *ObjectArg=nullptr)
Evaluate the arguments to a function call.
static bool EvaluateAtomic(const Expr *E, const LValue *This, APValue &Result, EvalInfo &Info)
static bool getBytesReturnedByAllocSizeCall(const ASTContext &Ctx, const LValue &LVal, llvm::APInt &Result)
Convenience function. LVal's base must be a call to an alloc_size function.
static bool handleIntIntBinOp(EvalInfo &Info, const BinaryOperator *E, const APSInt &LHS, BinaryOperatorKind Opcode, APSInt RHS, APSInt &Result)
Perform the given binary integer operation.
static bool EvaluateInitForDeclOfReferenceType(EvalInfo &Info, const ValueDecl *D, const Expr *Init, LValue &Result, APValue &Val)
Evaluates the initializer of a reference.
static bool checkDynamicType(EvalInfo &Info, const Expr *E, const LValue &This, AccessKinds AK, bool Polymorphic)
Check that we can access the notional vptr of an object / determine its dynamic type.
static bool HandleFloatToIntCast(EvalInfo &Info, const Expr *E, QualType SrcType, const APFloat &Value, QualType DestType, APSInt &Result)
static bool getAlignmentArgument(const Expr *E, QualType ForType, EvalInfo &Info, APSInt &Alignment)
Evaluate the value of the alignment argument to __builtin_align_{up,down}, __builtin_is_aligned and _...
static bool CheckFullyInitialized(EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value)
Check that this evaluated value is fully-initialized and can be loaded by an lvalue-to-rvalue convers...
static SubobjectHandler::result_type findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, const SubobjectDesignator &Sub, SubobjectHandler &handler)
Find the designated sub-object of an rvalue.
static bool determineEndOffset(EvalInfo &Info, SourceLocation ExprLoc, unsigned Type, const LValue &LVal, CharUnits &EndOffset)
Helper for tryEvaluateBuiltinObjectSize – Given an LValue, this will determine how many bytes exist f...
static bool convertUnsignedAPIntToCharUnits(const llvm::APInt &Int, CharUnits &Result)
Converts the given APInt to CharUnits, assuming the APInt is unsigned. Fails if the conversion would ...
static bool EvaluateCallArg(const ParmVarDecl *PVD, const Expr *Arg, CallRef Call, EvalInfo &Info, bool NonNull=false, APValue **EvaluatedArg=nullptr)
llvm::SmallPtrSet< const MaterializeTemporaryExpr *, 8 > CheckedTemporaries
Materialized temporaries that we've already checked to determine if they're initializsed by a constan...
GCCTypeClass EvaluateBuiltinClassifyType(QualType T, const LangOptions &LangOpts)
EvaluateBuiltinClassifyType - Evaluate __builtin_classify_type the same way as GCC.
static bool EvaluateDependentExpr(const Expr *E, EvalInfo &Info)
static bool MaybeEvaluateDeferredVarDeclInit(EvalInfo &Info, const VarDecl *VD)
static APSInt HandleIntToIntCast(EvalInfo &Info, const Expr *E, QualType DestType, QualType SrcType, const APSInt &Value)
static std::optional< APValue > handleVectorUnaryOperator(ASTContext &Ctx, QualType ResultTy, UnaryOperatorKind Op, APValue Elt)
static bool lifetimeStartedInEvaluation(EvalInfo &Info, APValue::LValueBase Base, bool MutableSubobject=false)
static bool isOneByteCharacterType(QualType T)
static bool HandleLambdaCapture(EvalInfo &Info, const Expr *E, LValue &Result, const CXXMethodDecl *MD, const FieldDecl *FD, bool LValueToRValueConversion)
Get an lvalue to a field of a lambda's closure type.
static bool EvaluateCond(EvalInfo &Info, const VarDecl *CondDecl, const Expr *Cond, bool &Result)
Evaluate a condition (either a variable declaration or an expression).
static bool EvaluateAsFixedPoint(const Expr *E, Expr::EvalResult &ExprResult, const ASTContext &Ctx, Expr::SideEffectsKind AllowSideEffects, EvalInfo &Info)
static bool EvaluateAsRValue(EvalInfo &Info, const Expr *E, APValue &Result)
EvaluateAsRValue - Try to evaluate this expression, performing an implicit lvalue-to-rvalue cast if i...
static bool diagnoseMutableFields(EvalInfo &Info, const Expr *E, AccessKinds AK, QualType T)
Diagnose an attempt to read from any unreadable field within the specified type, which might be a cla...
static ICEDiag CheckICE(const Expr *E, const ASTContext &Ctx)
static bool CheckConstexprFunction(EvalInfo &Info, SourceLocation CallLoc, const FunctionDecl *Declaration, const FunctionDecl *Definition, const Stmt *Body)
CheckConstexprFunction - Check that a function can be called in a constant expression.
static bool EvaluateDestruction(const ASTContext &Ctx, APValue::LValueBase Base, APValue DestroyedValue, QualType Type, SourceLocation Loc, Expr::EvalStatus &EStatus, bool IsConstantDestruction)
static bool handleDefaultInitValue(QualType T, APValue &Result, bool IsCompleteClass=true)
Get the value to use for a default-initialized object of type T.
static EvalStmtResult EvaluateStmt(StmtResult &Result, EvalInfo &Info, const Stmt *S, const SwitchCase *SC=nullptr)
static bool EvaluateArrayNewInitList(EvalInfo &Info, LValue &This, APValue &Result, const InitListExpr *ILE, QualType AllocType)
static bool HasSameBase(const LValue &A, const LValue &B)
static bool CheckLocalVariableDeclaration(EvalInfo &Info, const VarDecl *VD)
static bool HandleLValueDirectBase(EvalInfo &Info, const Expr *E, LValue &Obj, const CXXRecordDecl *Derived, const CXXRecordDecl *Base, const ASTRecordLayout *RL=nullptr)
static bool IsGlobalLValue(APValue::LValueBase B)
static llvm::RoundingMode getActiveRoundingMode(EvalInfo &Info, const Expr *E)
Get rounding mode to use in evaluation of the specified expression.
static QualType getObjectType(APValue::LValueBase B)
Retrieves the "underlying object type" of the given expression, as used by __builtin_object_size.
static bool handleCompareOpForVectorHelper(const APTy &LHSValue, BinaryOperatorKind Opcode, const APTy &RHSValue, APInt &Result)
static std::optional< uint64_t > tryEvaluateBuiltinObjectSize(const Expr *E, unsigned Type, EvalInfo &Info, bool IsDynamic=false)
Tries to evaluate the __builtin_object_size for E.
static bool Evaluate(APValue &Result, EvalInfo &Info, const Expr *E)
static 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 ArePotentiallyOverlappingStringLiterals(const EvalInfo &Info, const LValue &LHS, const LValue &RHS)
uint8_t GFNIMultiplicativeInverse(uint8_t Byte)
uint8_t GFNIAffine(uint8_t XByte, const APInt &AQword, const APSInt &Imm, bool Inverse)
APSInt NormalizeRotateAmount(const APSInt &Value, const APSInt &Amount)
Result
Implement __builtin_bit_cast and related operations.
static bool isModification(AccessKinds AK)
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
llvm::MachO::Record Record
Implements a partial diagnostic which may not be emitted.
llvm::DenseMap< Stmt *, Stmt * > MapTy
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
Expr * getExpr()
Get 'expr' part of the associated expression/statement.
static QualType getPointeeType(const MemRegion *R)
Enumerates target-specific builtins in their own namespaces within namespace clang.
Defines the clang::TypeLoc interface and its subclasses.
C Language Family Type Representation.
__DEVICE__ long long abs(long long __n)
a trap message and trap category.
llvm::APInt getValue() const
unsigned getVersion() const
QualType getDynamicAllocType() const
QualType getTypeInfoType() const
static LValueBase getTypeInfo(TypeInfoLValue LV, QualType TypeInfo)
static LValueBase getDynamicAlloc(DynamicAllocLValue LV, QualType Type)
A non-discriminated union of a base, field, or array index.
BaseOrMemberType getAsBaseOrMember() const
static LValuePathEntry ArrayIndex(uint64_t Index)
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
bool hasArrayFiller() const
const LValueBase getLValueBase() const
APValue & getArrayInitializedElt(unsigned I)
void swap(APValue &RHS)
Swaps the contents of this and the given APValue.
APValue & getStructField(unsigned i)
unsigned getMatrixNumColumns() const
const FieldDecl * getUnionField() const
APSInt & getComplexIntImag()
bool isComplexInt() const
llvm::PointerIntPair< const Decl *, 1, bool > BaseOrMemberType
A FieldDecl or CXXRecordDecl, along with a flag indicating whether we mean a virtual or non-virtual b...
ValueKind getKind() const
APValue & getStructVirtualBase(unsigned i)
unsigned getArrayInitializedElts() const
static APValue IndeterminateValue()
unsigned getStructNumBases() const
APFixedPoint & getFixedPoint()
bool hasLValuePath() const
const ValueDecl * getMemberPointerDecl() const
APValue & getUnionValue()
CharUnits & getLValueOffset()
void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const
bool isComplexFloat() const
APValue & getVectorElt(unsigned I)
APValue & getArrayFiller()
unsigned getVectorLength() const
void setUnion(const FieldDecl *Field, const APValue &Value)
bool isIndeterminate() const
unsigned getMatrixNumRows() const
unsigned getArraySize() const
bool allowConstexprUnknown() const
std::string getAsString(const ASTContext &Ctx, QualType Ty) const
bool isFixedPoint() const
APValue & getMatrixElt(unsigned Idx)
@ Indeterminate
This object has an indeterminate value (C++ [basic.indet]).
@ None
There is no such object (it's outside its lifetime).
APSInt & getComplexIntReal()
APFloat & getComplexFloatImag()
APFloat & getComplexFloatReal()
APValue & getStructBase(unsigned i)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
SourceManager & getSourceManager()
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
unsigned getIntWidth(QualType T) const
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
uint64_t getTargetNullPointerValue(QualType QT) const
Get target-dependent integer value for null pointer which is used for constant folding.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
unsigned getPreferredTypeAlign(QualType T) const
Return the "preferred" alignment of the specified type T for the current target, in bits.
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
Builtin::Context & BuiltinInfo
const LangOptions & getLangOpts() const
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
const TargetInfo * getAuxTargetInfo() const
interp::Context & getInterpContext() const
Returns the clang bytecode interpreter context.
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
const clang::PrintingPolicy & getPrintingPolicy() const
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
llvm::APSInt MakeIntValue(uint64_t Value, QualType Type) const
Make an APSInt of the appropriate width and signedness for the given Value and integer Type.
const VariableArrayType * getAsVariableArrayType(QualType T) const
const TargetInfo & getTargetInfo() const
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
CanQualType getCanonicalTagType(const TagDecl *TD) const
uint64_t getCharWidth() const
Return the size of the character type, in bits.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
unsigned getFieldCount() const
getFieldCount - Get the number of fields in the layout.
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - Get the offset, in chars, for the given base class.
LabelDecl * getLabel() const
OpaqueValueExpr * getCommonExpr() const
Get the common subexpression shared by all initializations (the source array).
Expr * getSubExpr() const
Get the initializer to use for each array element.
Expr * getLHS()
An array access can be written A[4] or 4[A] (both are equivalent).
uint64_t getValue() const
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
QualType getValueType() const
Gets the type contained by this atomic type, i.e.
Attr - This represents one attribute.
BinaryConditionalOperator - The GNU extension to the conditional operator which allows the middle ope...
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression which will be evaluated if the condition evaluates to false; ...
OpaqueValueExpr * getOpaqueValue() const
getOpaqueValue - Return the opaque value placeholder.
Expr * getCommon() const
getCommon - Return the common expression, written to the left of the condition.
A builtin binary operation expression such as "x + y" or "x <= y".
static bool isLogicalOp(Opcode Opc)
static bool isRelationalOp(Opcode Opc)
static bool isComparisonOp(Opcode Opc)
static Opcode getOpForCompoundAssignment(Opcode Opc)
SourceLocation getExprLoc() const
static bool isAdditiveOp(Opcode Opc)
static bool isPtrMemOp(Opcode Opc)
predicates to categorize the respective opcodes.
static bool isAssignmentOp(Opcode Opc)
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
static bool isEqualityOp(Opcode Opc)
bool hasCaptures() const
True if this block (or its nested blocks) captures anything of local storage from its enclosing scope...
const BlockDecl * getBlockDecl() const
bool isAuxBuiltinID(unsigned ID) const
Return true if the builtin ID belongs exclusively to the AuxTarget, and false if it belongs to both p...
unsigned getAuxBuiltinID(unsigned ID) const
Return real builtin ID (i.e.
AccessSpecifier Access
The access along this inheritance path.
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
bool isAmbiguous(CanQualType BaseType) const
Determine whether the path from the most-derived type to the given base type is ambiguous (i....
Represents a base class of a C++ class.
SourceLocation getBeginLoc() const LLVM_READONLY
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
QualType getType() const
Retrieves the type of the base class.
const Expr * getSubExpr() const
Represents a call to a C++ constructor.
bool isElidable() const
Whether this construction is elidable.
Expr * getArg(unsigned Arg)
Return the specified argument.
bool requiresZeroInitialization() const
Whether this construction first requires zero-initialization before the initializer is called.
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
unsigned getNumArgs() const
Return the number of arguments to the constructor call.
Represents a C++ constructor within a class.
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
CXXCtorInitializer *const * init_const_iterator
Iterates through the member/base initializer list.
Expr * getExpr()
Get the initialization expression that will be used.
FunctionDecl * getOperatorDelete() const
bool isGlobalDelete() const
Represents a C++ destructor within a class.
CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for statement, represented as 'for (ra...
DeclStmt * getBeginStmt()
DeclStmt * getLoopVarStmt()
DeclStmt * getRangeStmt()
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will call.
Represents a static or instance method of a struct/union/class.
bool isExplicitObjectMemberFunction() const
[C++2b][dcl.fct]/p7 An explicit object member function is a non-static member function with an explic...
bool isImplicitObjectMemberFunction() const
[C++2b][dcl.fct]/p7 An implicit object member function is a non-static member function without an exp...
QualType getFunctionObjectParameterReferenceType() const
Return the type of the object pointed by this.
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
bool isMoveAssignmentOperator() const
Determine whether this is a move assignment operator.
bool isCopyAssignmentOperator() const
Determine whether this is a copy-assignment operator, regardless of whether it was declared implicitl...
bool isLambdaStaticInvoker() const
Determine whether this is a lambda closure type's static member function that is used for the result ...
QualType getAllocatedType() const
std::optional< Expr * > getArraySize()
This might return std::nullopt even if isArray() returns true, since there might not be an array size...
Expr * getPlacementArg(unsigned I)
unsigned getNumPlacementArgs() const
SourceRange getSourceRange() const
FunctionDecl * getOperatorNew() const
Expr * getInitializer()
The initializer of this new-expression.
MutableArrayRef< Expr * > getInitExprs()
Represents a C++ struct/union/class.
bool hasMutableFields() const
Determine whether this class, or any of its class subobjects, contains a mutable field.
bool isGenericLambda() const
Determine whether this class describes a generic lambda function object (i.e.
bool hasTrivialDestructor() const
Determine whether this class has a trivial destructor (C++ [class.dtor]p3)
void getCaptureFields(llvm::DenseMap< const ValueDecl *, FieldDecl * > &Captures, FieldDecl *&ThisCapture) const
For a closure type, retrieve the mapping from captured variables and this to the non-static data memb...
unsigned getNumBases() const
Retrieves the number of base classes of this class.
base_class_range vbases()
capture_const_range captures() const
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
CXXMethodDecl * getLambdaCallOperator() const
Retrieve the lambda call operator of the closure type if this is a closure type.
CXXRecordDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
bool isDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is derived from the class Base.
Expr * getSemanticForm()
Get an equivalent semantic form for this expression.
bool isTypeOperand() const
QualType getTypeOperand(const ASTContext &Context) const
Retrieves the type operand of this typeid() expression after various required adjustments (removing r...
Expr * getExprOperand() const
bool isPotentiallyEvaluated() const
Determine whether this typeid has a type operand which is potentially evaluated, per C++11 [expr....
MSGuidDecl * getGuidDecl() const
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
SourceLocation getBeginLoc() const
const AllocSizeAttr * getCalleeAllocSizeAttr() const
Try to get the alloc_size attribute of the callee. May return null.
unsigned getBuiltinCallee() const
getBuiltinCallee - If this is a call to a builtin, return the builtin ID of the callee.
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
Expr ** getArgs()
Retrieve the call arguments.
QualType getCallReturnType(const ASTContext &Ctx) const
getCallReturnType - Get the return type of the call expr.
CaseStmt - Represent a case statement.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
path_iterator path_begin()
unsigned path_size() const
CastKind getCastKind() const
const FieldDecl * getTargetUnionField() const
const CXXBaseSpecifier *const * path_const_iterator
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operation.
CharUnits - This is an opaque type for sizes expressed in character units.
bool isPowerOfTwo() const
isPowerOfTwo - Test whether the quantity is a power of two.
CharUnits alignmentAtOffset(CharUnits offset) const
Given that this is a non-zero alignment value, what is the alignment at the given offset?
bool isZero() const
isZero - Test whether the quantity equals zero.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
unsigned getValue() const
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
const ValueInfo * getValueInfo(ComparisonCategoryResult ValueKind) const
ComparisonCategoryResult makeWeakResult(ComparisonCategoryResult Res) const
Converts the specified result kind into the correct result kind for this category.
Complex values, per C99 6.2.5p11.
QualType getElementType() const
CompoundAssignOperator - For compound assignments (e.g.
QualType getComputationLHSType() const
CompoundLiteralExpr - [C99 6.5.2.5].
bool hasStaticStorage() const
APValue & getOrCreateStaticValue(ASTContext &Ctx) const
const Expr * getInitializer() const
CompoundStmt - This represents a group of statements like { stmt stmt }.
Stmt *const * const_body_iterator
body_iterator body_begin()
bool isSatisfied() const
Whether or not the concept with the given arguments was satisfied when the expression was created.
ConditionalOperator - The ?
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
Expr * getCond() const
getCond - Return the expression representing the condition for the ?
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
Represents the canonical version of C arrays with a specified constant size.
unsigned getSizeBitWidth() const
Return the bit width of the size type.
static unsigned getNumAddressingBits(const ASTContext &Context, QualType ElementType, const llvm::APInt &NumElements)
Determine the number of bits required to address a member of.
static unsigned getMaxSizeBits(const ASTContext &Context)
Determine the maximum number of active bits that an array's size can require, which limits the maximu...
uint64_t getLimitedSize() const
Return the size zero-extended to uint64_t or UINT64_MAX if the value is larger than UINT64_MAX.
bool isZeroSize() const
Return true if the size is zero.
const Expr * getSizeExpr() const
Return a pointer to the size expression.
llvm::APInt getSize() const
Return the constant array size as an APInt.
uint64_t getZExtSize() const
Return the size zero-extended as a uint64_t.
APValue getAPValueResult() const
bool hasAPValueResult() const
Represents a concrete matrix type with constant number of rows and columns.
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
Represents the current source location and context used to determine the value of the source location...
const Expr * getDefaultExpr() const
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool Equals(const DeclContext *DC) const
Determine whether this declaration context is equivalent to the declaration context DC.
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
A reference to a declared variable, function, enum, etc.
bool refersToEnclosingVariableOrCapture() const
Does this DeclRefExpr refer to an enclosing local or a captured variable?
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Decl - This represents one declaration (or definition), e.g.
bool isInStdNamespace() const
ASTContext & getASTContext() const LLVM_READONLY
bool isInvalidDecl() const
SourceLocation getLocation() const
DeclContext * getDeclContext()
AccessSpecifier getAccess() const
bool isAnyOperatorNew() const
A decomposition declaration.
auto flat_bindings() const
InitListExpr * getUpdater() const
Designator - A designator in a C99 designated initializer.
DoStmt - This represents a 'do/while' stmt.
Symbolic representation of a dynamic allocation.
static unsigned getMaxIndex()
const Expr * getBase() const
ChildElementIter< false > begin()
ExplicitCastExpr - An explicit cast written in the source code.
QualType getTypeAsWritten() const
getTypeAsWritten - Returns the type that this expression is casting to, as written in the source code...
This represents one expression.
const Expr * skipRValueSubobjectAdjustments(SmallVectorImpl< const Expr * > &CommaLHS, SmallVectorImpl< SubobjectAdjustment > &Adjustments) const
Walk outwards from an expression we want to bind a reference to and find the expression whose lifetim...
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
static bool isPotentialConstantExpr(const FunctionDecl *FD, SmallVectorImpl< PartialDiagnosticAt > &Diags)
isPotentialConstantExpr - Return true if this function's definition might be usable in a constant exp...
bool isIntegerConstantExpr(const ASTContext &Ctx) const
static bool isPotentialConstantExprUnevaluated(Expr *E, const FunctionDecl *FD, SmallVectorImpl< PartialDiagnosticAt > &Diags)
isPotentialConstantExprUnevaluated - Return true if this expression might be usable in a constant exp...
@ SE_AllowSideEffects
Allow any unmodeled side effect.
@ SE_AllowUndefinedBehavior
Allow UB that we can give a value, but not arbitrary unmodeled side effects.
bool EvaluateCharRangeAsString(std::string &Result, const Expr *SizeExpression, const Expr *PtrExpression, ASTContext &Ctx, EvalResult &Status) const
llvm::APSInt EvaluateKnownConstIntCheckOverflow(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
bool isValueDependent() const
Determines whether the value of this expression depends on.
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Returns the set of floating point options that apply to this expression.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
bool containsErrors() const
Whether this expression contains subexpressions which had errors.
bool EvaluateAsFloat(llvm::APFloat &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsFloat - Return true if this is a constant which we can fold and convert to a floating point...
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsLValue - Evaluate an expression to see if we can fold it to an lvalue with link time known ...
bool EvaluateAsInitializer(const ASTContext &Ctx, const VarDecl *VD, EvalResult &Result, bool IsConstantInitializer) const
EvaluateAsInitializer - Evaluate an expression as if it were the initializer of the given declaration...
bool EvaluateAsFixedPoint(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsFixedPoint - Return true if this is a constant which we can fold and convert to a fixed poi...
bool isEvaluatable(const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
isEvaluatable - Call EvaluateAsRValue to see if this expression can be constant folded without side-e...
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language.
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...
std::optional< uint64_t > tryEvaluateStrLen(const ASTContext &Ctx) const
If the current Expr is a pointer, this will try to statically determine the strlen of the string poin...
bool HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects=true) const
HasSideEffects - This routine returns true for all those expressions which have any effect other than...
bool EvaluateAsConstantExpr(EvalResult &Result, const ASTContext &Ctx, ConstantExprKind Kind=ConstantExprKind::Normal) const
Evaluate an expression that is required to be a constant expression.
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx, bool AllowRelaxedEval=false) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
std::optional< std::string > tryEvaluateString(ASTContext &Ctx) const
If the current Expr can be evaluated to a pointer to a null-terminated constant string,...
bool EvaluateAsBooleanCondition(bool &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsBooleanCondition - Return true if this is a constant which we can fold and convert to a boo...
bool isTemporaryObject(ASTContext &Ctx, const CXXRecordDecl *TempTy) const
Determine whether the result of this expression is a temporary object of the given class type.
std::optional< uint64_t > tryEvaluateObjectSize(const ASTContext &Ctx, unsigned Type) const
If the current Expr is a pointer, this will try to statically determine the number of bytes available...
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
bool isCXX98IntegralConstantExpr(const ASTContext &Ctx) const
isCXX98IntegralConstantExpr - Return true if this expression is an integral constant expression in C+...
bool EvaluateWithSubstitution(APValue &Value, ASTContext &Ctx, const FunctionDecl *Callee, ArrayRef< const Expr * > Args, const Expr *This=nullptr) const
EvaluateWithSubstitution - Evaluate an expression as if from the context of a call to the given funct...
bool isCXX11ConstantExpr(const ASTContext &Ctx, APValue *Result=nullptr, bool AllowRelaxedEval=false) const
isCXX11ConstantExpr - Return true if this expression is a constant expression in C++11.
void EvaluateForOverflow(const ASTContext &Ctx) const
bool isArrow() const
isArrow - Return true if the base expression is a pointer to vector, return false if the base express...
void getEncodedElementAccess(SmallVectorImpl< uint32_t > &Elts) const
getEncodedElementAccess - Encode the elements accessed into an llvm aggregate Constant of ConstantInt...
bool isFPConstrained() const
LangOptions::FPExceptionModeKind getExceptionMode() const
RoundingMode getRoundingMode() const
Represents a member of a struct/union/class.
bool isBitField() const
Determines whether this field is a bitfield.
unsigned getBitWidthValue() const
Computes the bit width of this field, if this is a bit field.
unsigned getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
FieldDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this field.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
llvm::APInt getValue() const
Returns an internal integer representation of the literal.
llvm::APFloat getValue() const
ForStmt - This represents a 'for (init;cond;inc)' stmt.
VarDecl * getConditionVariable() const
Retrieve the variable declared in this "for" statement, if any.
const Expr * getSubExpr() const
Represents a function declaration or definition.
const ParmVarDecl * getParamDecl(unsigned i) const
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
bool isFunctionTemplateSpecialization() const
Determine whether this function is a function template specialization.
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
bool hasCXXExplicitFunctionObjectParameter() const
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
bool isConstexpr() const
Whether this is a (C++11) constexpr function or constexpr constructor.
bool isUsableAsGlobalAllocationFunctionInConstantEvaluation(UnsignedOrNone *AlignmentParam=nullptr, bool *IsNothrow=nullptr) const
Determines whether this function is one of the replaceable global allocation functions described in i...
bool isDefaulted() const
Whether this function is defaulted.
void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override
Appends a human-readable name for this declaration into the given stream.
FunctionDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
Expr * getResultExpr()
Return the result expression of this controlling expression.
One of these records is kept for each identifier that is lexed.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
IfStmt - This represents an if/then/else.
bool isNonNegatedConsteval() const
VarDecl * getConditionVariable()
Retrieve the variable declared in this "if" statement, if any.
const Expr * getSubExpr() const
Represents an implicitly-generated value initialization of an object of a given type.
Represents a field injected from an anonymous union/struct into the parent scope.
ArrayRef< NamedDecl * > chain() const
Describes an C or C++ initializer list.
bool isTransparent() const
Is this a transparent initializer list (that is, an InitListExpr that is purely syntactic,...
bool isStringLiteralInit() const
Is this an initializer for an array of characters, initialized by a string literal or an @encode?
unsigned getNumInits() const
Expr * getArrayFiller()
If this initializer list initializes an array with more elements than there are initializers in the l...
const Expr * getInit(unsigned Init) const
ArrayRef< Expr * > inits() const
capture_init_iterator capture_init_end()
Retrieve the iterator pointing one past the last initialization argument for this lambda expression.
capture_init_iterator capture_init_begin()
Retrieve the first initialization argument for this lambda expression (which initializes the first ca...
CXXRecordDecl * getLambdaClass() const
Retrieve the class that corresponds to the lambda.
StrictFlexArraysLevelKind
@ FPE_Ignore
Assume that floating-point exceptions are masked.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
bool isCompatibleWith(ClangABI Version) const
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
StorageDuration getStorageDuration() const
Retrieve the storage duration for the materialized temporary.
Expr * getSubExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue.
APValue * getOrCreateValue(bool MayCreate) const
Get the storage for the constant value of a materialized temporary of static storage duration.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
void printQualifiedName(raw_ostream &OS) const
Returns a human-readable qualified name for this declaration, like A::B::i, for i being member of nam...
bool isExpressibleAsConstantInitializer() const
Expr * getIndexExpr(unsigned Idx)
const OffsetOfNode & getComponent(unsigned Idx) const
TypeSourceInfo * getTypeSourceInfo() const
unsigned getNumComponents() const
unsigned getArrayExprIndex() const
For an array element node, returns the index into the array of expressions.
FieldDecl * getField() const
For a field offsetof node, returns the field.
@ Array
An index into an array.
@ Identifier
A field in a dependent type, known only by its name.
@ Base
An implicit indirection through a C++ base class, when the field found is in a base class.
Kind getKind() const
Determine what kind of offsetof node this is.
CXXBaseSpecifier * getBase() const
For a base class node, returns the base specifier.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
Expr * getSelectedExpr() const
const Expr * getSubExpr() const
Represents a parameter to a function.
unsigned getFunctionScopeIndex() const
Returns the index of this parameter in its prototype or method scope.
bool isExplicitObjectParameter() const
PointerType - C99 6.7.5.1 - Pointer Declarators.
StringLiteral * getFunctionName()
Expr * getResultExpr()
Return the result-bearing expression, or null if there is none.
ArrayRef< Expr * > semantics()
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
QualType withConst() const
void addConst()
Add the const type qualifier to this QualType.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
void removeLocalVolatile()
void addVolatile()
Add the volatile type qualifier to this QualType.
bool isConstQualified() const
Determine whether this type is const-qualified.
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()
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
TagDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Exposes information about the current target.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
unsigned size() const
Retrieve the number of template arguments in this template argument list.
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
@ Type
The template argument is a type.
Symbolic representation of typeid(T) for some type T.
QualType getType() const
Return the type wrapped by this type source info.
bool getBoolValue() const
const APValue & getAPValue() const
bool isStoredAsBoolean() const
The base class of the type hierarchy.
bool isBooleanType() const
bool isFunctionReferenceType() const
bool isMFloat8Type() const
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
bool isPackedVectorBoolType(const ASTContext &ctx) const
bool isLiteralType(const ASTContext &Ctx) const
Return true if this is a literal type (C++11 [basic.types]p10)
bool isIncompleteArrayType() const
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
bool isComplexType() const
isComplexType() does not include complex integers (a GCC extension).
const ArrayType * castAsArrayTypeUnsafe() const
A variant of castAs<> for array type which silently discards qualifiers from the outermost type.
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
bool isIntegralOrUnscopedEnumerationType() const
Determine whether this type is an integral or unscoped enumeration type.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isConstantArrayType() const
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isVoidPointerType() const
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6....
bool isFunctionPointerType() const
bool isCountAttributedType() const
bool isConstantMatrixType() const
bool isPointerType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isEnumeralType() const
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
bool isVariableArrayType() const
bool isSveVLSBuiltinType() const
Determines if this is a sizeless type supported by the 'arm_sve_vector_bits' type attribute,...
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
bool isExtVectorBoolType() const
bool isMemberDataPointerType() const
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
RecordDecl * castAsRecordDecl() const
bool isAnyComplexType() const
bool isFixedPointType() const
Return true if this is a fixed point type according to ISO/IEC JTC1 SC22 WG14 N1169.
bool isMemberPointerType() const
bool isAtomicType() const
bool isComplexIntegerType() const
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isObjectType() const
Determine whether this type is an object type.
EnumDecl * getAsEnumDecl() const
Retrieves the EnumDecl this type refers to.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
bool isFunctionType() const
bool isVectorType() const
bool isRealFloatingType() const
Floating point categories.
bool isFloatingType() const
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
const T * castAsCanonical() const
Return this type's canonical type cast to the specified type.
bool isAnyPointerType() const
TypeClass getTypeClass() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isNullPtrType() const
bool isRecordType() const
bool isSizelessVectorType() const
Returns true for all scalable vector types.
bool hasPointerRepresentation() const
Whether this type is represented natively as a pointer.
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
QualType getArgumentType() const
SourceLocation getBeginLoc() const LLVM_READONLY
QualType getTypeOfArgument() const
Gets the argument type, or the type of the argument expression, whichever is appropriate.
bool isArgumentType() const
UnaryExprOrTypeTrait getKind() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
SourceLocation getExprLoc() const
Expr * getSubExpr() const
static bool isIncrementOp(Opcode Op)
bool canOverflow() const
Returns true if the unary operator can cause an overflow.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
bool isWeak() const
Determine whether this symbol is weakly-imported, or declared with the weak or weak-ref attr.
Represents a variable declaration or definition.
bool isConstexpr() const
Whether this variable is (C++11) constexpr.
bool hasICEInitializer(const ASTContext &Context) const
Determine whether the initializer of this variable is an integer constant expression.
bool isInitCapture() const
Whether this variable is the implicit variable for a lambda init-capture.
const APValue * getEvaluatedValue() const
Return the already-evaluated value of this variable's initializer, or nullptr if the value is not yet...
CharUnits getFlexibleArrayInitChars(const ASTContext &Ctx) const
If hasFlexibleArrayInit is true, compute the number of additional bytes necessary to store those elem...
bool hasConstantInitialization() const
Determine whether this variable has constant initialization.
VarDecl * getDefinition(ASTContext &)
Get the real (not just tentative) definition for this declaration.
bool mightBeUsableInConstantExpressions(const ASTContext &C) const
Determine whether this variable's value might be usable in a constant expression, according to the re...
EvaluatedStmt * ensureEvaluatedStmt() const
Convert the initializer for this declaration to the elaborated EvaluatedStmt form,...
bool evaluateDestruction(SmallVectorImpl< PartialDiagnosticAt > &Notes) const
Evaluate the destruction of this variable to determine if it constitutes constant destruction.
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
ThreadStorageClassSpecifier getTSCSpec() const
const Expr * getInit() const
const APValue * evaluateValue() const
Attempt to evaluate the value of the initializer attached to this declaration, and produce notes expl...
bool hasLocalStorage() const
Returns true if a variable with function scope is a non-static local variable.
DefinitionKind hasDefinition(ASTContext &) const
Check whether this variable is defined in this translation unit.
bool isLocalVarDecl() const
Returns true for local variable declarations other than parameters.
bool isUsableInConstantExpressions(const ASTContext &C) const
Determine whether this variable's value can be used in a constant expression, according to the releva...
const Expr * getAnyInitializer() const
Get the initializer for this variable, no matter which declaration it is attached to.
Expr * getSizeExpr() const
Represents a GCC generic vector type.
unsigned getNumElements() const
QualType getElementType() const
WhileStmt - This represents a 'while' stmt.
VarDecl * getConditionVariable()
Retrieve the variable declared in this "while" statement, if any.
bool evaluateDestruction(State &Parent, const VarDecl *VD, APValue Value)
Evaluates the destruction of a variable.
Base class for stack frames, shared between VM and walker.
Interface for the VM to interact with the AST walker's context.
Defines the clang::TargetInfo interface.
bool computeOSLogBufferLayout(clang::ASTContext &Ctx, const clang::CallExpr *E, OSLogBufferLayout &layout)
static const FunctionDecl * getCallee(const CXXConstructExpr &D)
uint32_t Literal
Literals are represented as positive integers.
unsigned kind
All of the diagnostics that can be emitted by the frontend.
std::optional< llvm::AllocTokenMetadata > getAllocTokenMetadata(QualType T, const ASTContext &Ctx)
Get the information required for construction of an allocation token ID.
QualType inferPossibleType(const CallExpr *E, const ASTContext &Ctx, const CastExpr *CastE)
Infer the possible allocated type from an allocation call expression.
bool Sub(InterpState &S, CodePtr OpPC)
bool NE(InterpState &S, CodePtr OpPC)
llvm::FixedPointSemantics FixedPointSemantics
bool This(InterpState &S, CodePtr OpPC)
bool Alloc(InterpState &S, CodePtr OpPC, const Descriptor *Desc)
std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl
All declarations that can appear in a module declaration.
void info(bool Verbose, unsigned Level, const char *Fmt, Ts &&...Args)
Prints an indented note to stderr when Verbose is set.
AccessKind
This enum distinguishes between different ways to access (read or write) a variable.
Top level wrappers for InstallAPI frontend operations.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
bool isa(CodeGen::Address addr)
const Expr * findStructFieldAccess(const Expr *E, const Expr **OutArrayIndex=nullptr, QualType *OutArrayElementTy=nullptr)
Walk E through parens, implicit casts, unary &/*, array subscripts and comma operators to find the he...
bool hasSpecificAttr(const Container &container)
@ NonNull
Values of this type can never be null.
@ Success
Annotation was successful.
Expr::ConstantExprKind ConstantExprKind
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
bool operator==(const CallGraphNode::CallRecord &LHS, const CallGraphNode::CallRecord &RHS)
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
bool isLambdaCallWithExplicitObjectParameter(const DeclContext *DC)
ComparisonCategoryResult
An enumeration representing the possible results of a three-way comparison.
CheckSubobjectKind
The order of this enum is important for diagnostics.
@ SD_Static
Static storage duration.
@ SD_FullExpression
Full-expression storage duration (for temporaries).
bool isLambdaCallOperator(const CXXMethodDecl *MD)
@ Result
The result type of a method or function.
AccessKinds
Kinds of access we can perform on an object, for diagnostics.
@ AK_ReadObjectRepresentation
const FunctionProtoType * T
@ Off
Never emit colors regardless of the output stream.
@ Type
The name was classified as a type.
CastKind
CastKind - The kind of operation required for a conversion.
llvm::hash_code hash_value(const CustomizableOptional< T > &O)
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs.
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
@ ConstantFold
Fold the expression to a constant.
@ ConstantExpressionUnevaluated
Evaluate as a constant expression.
@ ConstantExpression
Evaluate as a constant expression.
@ IgnoreSideEffects
Evaluate in any way we know how.
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
U cast(CodeGen::Address addr)
@ None
The alignment was not explicit in code.
@ ArrayBound
Array bound in array declarator or new-expression.
@ Class
The "class" keyword introduces the elaborated-type-specifier.
ActionResult< Expr * > ExprResult
@ Other
Other implicit parameter.
ActionResult< Stmt * > StmtResult
Diagnostic wrappers for TextAPI types for error reporting.
hash_code hash_value(const clang::dependencies::ModuleID &ID)
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 int32_t
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 uint8_t
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 __packed_splat4 uint16_t
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 __packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 uint32_t
unsigned PathLength
The corresponding path length in the lvalue.
const CXXRecordDecl * Type
The dynamic class type of the object.
std::string ObjCEncodeStorage
Represents an element in a path from a derived class to a base class.
EvalResult is a struct with detailed info about an evaluated expression.
APValue Val
Val - This is the value the expression can be folded to.
bool isGlobalLValue() const
Return true if the evaluated lvalue expression is global.
EvalStatus is a struct with detailed info about an evaluation in progress.
SmallVectorImpl< PartialDiagnosticAt > * Diag
Diag - If this is non-null, it will be filled in with a stack of notes indicating why evaluation fail...
bool HasSideEffects
Whether the evaluated expression has side effects.
unsigned SuppressLambdaBody
Whether to suppress printing the body of a lambda.
@ DerivedToBaseAdjustment
@ MemberPointerAdjustment
DenseMapInfo< APValue::LValueBase > Base
static unsigned getHashValue(const ObjectUnderConstruction &Object)
static bool isEqual(const ObjectUnderConstruction &LHS, const ObjectUnderConstruction &RHS)