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;
2708 APFloat::opStatus St) {
2711 if (Info.InConstantContext)
2715 if ((St & APFloat::opInexact) &&
2719 Info.FFDiag(E, diag::note_constexpr_dynamic_rounding);
2723 if ((St != APFloat::opOK) &&
2726 FPO.getAllowFEnvAccess())) {
2727 Info.FFDiag(E, diag::note_constexpr_float_arithmetic_strict);
2731 if ((St & APFloat::opStatus::opInvalidOp) &&
2752 "HandleFloatToFloatCast has been checked with only CastExpr, "
2753 "CompoundAssignOperator and ConvertVectorExpr. Please either validate "
2754 "the new expression or address the root cause of this usage.");
2756 APFloat::opStatus St;
2759 St =
Result.convert(Info.Ctx.getFloatTypeSemantics(DestType), RM, &ignored);
2766 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
2780 Result = APFloat(Info.Ctx.getFloatTypeSemantics(DestType), 1);
2782 APFloat::opStatus St =
Result.convertFromAPInt(
Value,
Value.isSigned(), RM);
2788 assert(FD->
isBitField() &&
"truncateBitfieldValue on non-bitfield");
2790 if (!
Value.isInt()) {
2794 assert(
Value.isLValue() &&
"integral value neither int nor lvalue?");
2800 unsigned OldBitWidth = Int.getBitWidth();
2802 if (NewBitWidth < OldBitWidth)
2803 Int = Int.trunc(NewBitWidth).extend(OldBitWidth);
2810template<
typename Operation>
2813 unsigned BitWidth, Operation Op,
2815 if (LHS.isUnsigned()) {
2820 APSInt Value(Op(LHS.extend(BitWidth), RHS.extend(BitWidth)),
false);
2823 if (Info.checkingForUndefinedBehavior())
2824 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
2825 diag::warn_integer_constant_overflow)
2838 bool HandleOverflowResult =
true;
2845 std::multiplies<APSInt>(),
Result);
2848 std::plus<APSInt>(),
Result);
2851 std::minus<APSInt>(),
Result);
2852 case BO_And:
Result = LHS & RHS;
return true;
2853 case BO_Xor:
Result = LHS ^ RHS;
return true;
2854 case BO_Or:
Result = LHS | RHS;
return true;
2858 Info.FFDiag(E, diag::note_expr_divide_by_zero)
2864 if (RHS.isNegative() && RHS.isAllOnes() && LHS.isSigned() &&
2865 LHS.isMinSignedValue())
2867 Info, E, -LHS.extend(LHS.getBitWidth() + 1), E->
getType());
2868 Result = (Opcode == BO_Rem ? LHS % RHS : LHS / RHS);
2869 return HandleOverflowResult;
2871 if (Info.getLangOpts().OpenCL)
2873 RHS &=
APSInt(llvm::APInt(RHS.getBitWidth(),
2874 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2876 else if (RHS.isSigned() && RHS.isNegative()) {
2879 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
2880 if (!Info.noteUndefinedBehavior())
2888 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
2890 Info.CCEDiag(E, diag::note_constexpr_large_shift)
2891 << RHS << E->
getType() << LHS.getBitWidth();
2892 if (!Info.noteUndefinedBehavior())
2894 }
else if (LHS.isSigned() && !Info.getLangOpts().CPlusPlus20) {
2899 if (LHS.isNegative()) {
2900 Info.CCEDiag(E, diag::note_constexpr_lshift_of_negative) << LHS;
2901 if (!Info.noteUndefinedBehavior())
2903 }
else if (LHS.countl_zero() < SA) {
2904 Info.CCEDiag(E, diag::note_constexpr_lshift_discards);
2905 if (!Info.noteUndefinedBehavior())
2913 if (Info.getLangOpts().OpenCL)
2915 RHS &=
APSInt(llvm::APInt(RHS.getBitWidth(),
2916 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2918 else if (RHS.isSigned() && RHS.isNegative()) {
2921 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
2922 if (!Info.noteUndefinedBehavior())
2930 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
2932 Info.CCEDiag(E, diag::note_constexpr_large_shift)
2933 << RHS << E->
getType() << LHS.getBitWidth();
2934 if (!Info.noteUndefinedBehavior())
2942 case BO_LT:
Result = LHS < RHS;
return true;
2943 case BO_GT:
Result = LHS > RHS;
return true;
2944 case BO_LE:
Result = LHS <= RHS;
return true;
2945 case BO_GE:
Result = LHS >= RHS;
return true;
2946 case BO_EQ:
Result = LHS == RHS;
return true;
2947 case BO_NE:
Result = LHS != RHS;
return true;
2949 llvm_unreachable(
"BO_Cmp should be handled elsewhere");
2956 const APFloat &RHS) {
2958 APFloat::opStatus St;
2964 St = LHS.multiply(RHS, RM);
2967 St = LHS.add(RHS, RM);
2970 St = LHS.subtract(RHS, RM);
2976 Info.CCEDiag(E, diag::note_expr_divide_by_zero);
2977 St = LHS.divide(RHS, RM);
2986 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << LHS.isNaN();
2987 return Info.noteUndefinedBehavior();
2995 const APInt &RHSValue, APInt &
Result) {
2996 bool LHS = (LHSValue != 0);
2997 bool RHS = (RHSValue != 0);
2999 if (Opcode == BO_LAnd)
3007 const APFloat &RHSValue, APInt &
Result) {
3008 bool LHS = !LHSValue.isZero();
3009 bool RHS = !RHSValue.isZero();
3011 if (Opcode == BO_LAnd)
3030template <
typename APTy>
3033 const APTy &RHSValue, APInt &
Result) {
3036 llvm_unreachable(
"unsupported binary operator");
3038 Result = (LHSValue == RHSValue);
3041 Result = (LHSValue != RHSValue);
3044 Result = (LHSValue < RHSValue);
3047 Result = (LHSValue > RHSValue);
3050 Result = (LHSValue <= RHSValue);
3053 Result = (LHSValue >= RHSValue);
3082 assert(Opcode != BO_PtrMemD && Opcode != BO_PtrMemI &&
3083 "Operation not supported on vector types");
3087 QualType EltTy = VT->getElementType();
3094 "A vector result that isn't a vector OR uncalculated LValue");
3100 RHSValue.
getVectorLength() == NumElements &&
"Different vector sizes");
3104 for (
unsigned EltNum = 0; EltNum < NumElements; ++EltNum) {
3109 APSInt EltResult{Info.Ctx.getIntWidth(EltTy),
3119 RHSElt.
getInt(), EltResult);
3125 ResultElements.emplace_back(EltResult);
3130 "Mismatched LHS/RHS/Result Type");
3131 APFloat LHSFloat = LHSElt.
getFloat();
3139 ResultElements.emplace_back(LHSFloat);
3143 LHSValue =
APValue(ResultElements.data(), ResultElements.size());
3151 unsigned TruncatedElements) {
3152 SubobjectDesignator &D =
Result.Designator;
3155 if (TruncatedElements == D.Entries.size())
3157 assert(TruncatedElements >= D.MostDerivedPathLength &&
3158 "not casting to a derived class");
3164 for (
unsigned I = TruncatedElements, N = D.Entries.size(); I != N; ++I) {
3168 if (isVirtualBaseClass(D.Entries[I]))
3174 D.Entries.resize(TruncatedElements);
3184 RL = &Info.Ctx.getASTRecordLayout(Derived);
3187 Obj.addDecl(Info, E,
Base,
false);
3188 Obj.getLValueOffset() += RL->getBaseClassOffset(
Base);
3200 RL = &Info.Ctx.getASTRecordLayout(Derived);
3203 Obj.addDecl(Info, E,
Base,
true);
3204 Obj.getLValueOffset() += RL->getVBaseClassOffset(
Base);
3213 if (!
Base->isVirtual())
3216 SubobjectDesignator &D = Obj.Designator;
3231 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(DerivedDecl);
3232 Obj.addDecl(Info, E, BaseDecl,
true);
3241 PathI != PathE; ++PathI) {
3245 Type = (*PathI)->getType();
3257 llvm_unreachable(
"Class must be derived from the passed in base class!");
3281 RL = &Info.Ctx.getASTRecordLayout(RD);
3285 LVal.addDecl(Info, E, FD);
3286 LVal.adjustOffset(Info.Ctx.toCharUnitsFromBits(RL->getFieldOffset(I)));
3294 for (
const auto *
C : IFD->
chain())
3328 Size = Info.Ctx.getTypeSizeInChars(
Type);
3330 Size = Info.Ctx.getTypeInfoDataSizeInChars(
Type).Width;
3347 LVal.adjustOffsetAndIndex(Info, E, Adjustment, SizeOfPointee);
3353 int64_t Adjustment) {
3355 APSInt::get(Adjustment));
3370 LVal.Offset += SizeOfComponent;
3372 LVal.addComplex(Info, E, EltTy, Imag);
3378 uint64_t Size, uint64_t Idx) {
3383 LVal.Offset += SizeOfElement * Idx;
3385 LVal.addVectorElement(Info, E, EltTy, Size, Idx);
3399 const VarDecl *VD, CallStackFrame *Frame,
3403 bool AllowConstexprUnknown =
3408 auto CheckUninitReference = [&](
bool IsLocalVariable) {
3420 if (!AllowConstexprUnknown || IsLocalVariable) {
3421 if (!Info.checkingPotentialConstantExpression())
3422 Info.FFDiag(E, diag::note_constexpr_use_uninit_reference);
3432 Result = Frame->getTemporary(VD, Version);
3434 return CheckUninitReference(
true);
3443 "missing value for local variable");
3444 if (Info.checkingPotentialConstantExpression())
3448 "A variable in a frame should either be a local or a parameter");
3454 if (Info.EvaluatingDecl ==
Base) {
3455 Result = Info.EvaluatingDeclValue;
3456 return CheckUninitReference(
false);
3464 if (AllowConstexprUnknown) {
3471 if (!Info.checkingPotentialConstantExpression() ||
3472 !Info.CurrentCall->Callee ||
3474 if (Info.getLangOpts().CPlusPlus11) {
3475 Info.FFDiag(E, diag::note_constexpr_function_param_value_unknown)
3496 if (!
Init && !AllowConstexprUnknown) {
3499 if (!Info.checkingPotentialConstantExpression()) {
3500 Info.FFDiag(E, diag::note_constexpr_var_init_unknown, 1)
3511 if (
Init &&
Init->isValueDependent()) {
3518 if (!Info.checkingPotentialConstantExpression()) {
3519 Info.FFDiag(E, Info.getLangOpts().CPlusPlus11
3520 ? diag::note_constexpr_ltor_non_constexpr
3521 : diag::note_constexpr_ltor_non_integral, 1)
3535 Info.FFDiag(E, diag::note_constexpr_var_init_non_constant, 1) << VD;
3551 !AllowConstexprUnknown) ||
3552 ((Info.getLangOpts().CPlusPlus || Info.getLangOpts().OpenCL) &&
3555 Info.CCEDiag(E, diag::note_constexpr_var_init_non_constant, 1) << VD;
3565 Info.FFDiag(E, diag::note_constexpr_var_init_weak) << VD;
3572 if (!
Result && !AllowConstexprUnknown)
3575 return CheckUninitReference(
false);
3598 llvm_unreachable(
"base class missing from derived class's bases list");
3605 "SourceLocExpr should have already been converted to a StringLiteral");
3608 if (
const auto *ObjCEnc = dyn_cast<ObjCEncodeExpr>(Lit)) {
3610 Info.Ctx.getObjCEncodingForType(ObjCEnc->getEncodedType(), Str);
3611 assert(Index <= Str.size() &&
"Index too large");
3612 return APSInt::getUnsigned(Str.c_str()[Index]);
3615 if (
auto PE = dyn_cast<PredefinedExpr>(Lit))
3616 Lit = PE->getFunctionName();
3619 Info.Ctx.getAsConstantArrayType(S->
getType());
3620 assert(CAT &&
"string literal isn't an array");
3622 assert(CharType->
isIntegerType() &&
"unexpected character type");
3625 if (Index < S->getLength())
3638 AllocType.isNull() ? S->
getType() : AllocType);
3639 assert(CAT &&
"string literal isn't an array");
3641 assert(CharType->
isIntegerType() &&
"unexpected character type");
3648 if (
Result.hasArrayFiller())
3650 for (
unsigned I = 0, N =
Result.getArrayInitializedElts(); I != N; ++I) {
3658 unsigned Size =
Array.getArraySize();
3659 assert(Index < Size);
3662 unsigned OldElts =
Array.getArrayInitializedElts();
3663 unsigned NewElts = std::max(Index+1, OldElts * 2);
3664 NewElts = std::min(Size, std::max(NewElts, 8u));
3668 for (
unsigned I = 0; I != OldElts; ++I)
3670 for (
unsigned I = OldElts; I != NewElts; ++I)
3674 Array.swap(NewValue);
3681 Vec =
APValue(Elts.data(), Elts.size());
3691 CXXRecordDecl *RD =
T->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
3702 for (
auto *Field : RD->
fields())
3703 if (!Field->isUnnamedBitField() &&
3707 for (
auto &BaseSpec : RD->
bases())
3718 CXXRecordDecl *RD =
T->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
3725 for (
auto *Field : RD->
fields()) {
3730 if (Field->isMutable() &&
3732 Info.FFDiag(E, diag::note_constexpr_access_mutable, 1) << AK << Field;
3733 Info.Note(Field->getLocation(), diag::note_declared_at);
3741 for (
auto &BaseSpec : RD->
bases())
3751 bool MutableSubobject =
false) {
3756 switch (Info.IsEvaluatingDecl) {
3757 case EvalInfo::EvaluatingDeclKind::None:
3760 case EvalInfo::EvaluatingDeclKind::Ctor:
3762 if (Info.EvaluatingDecl ==
Base)
3767 if (
auto *BaseE =
Base.dyn_cast<
const Expr *>())
3768 if (
auto *BaseMTE = dyn_cast<MaterializeTemporaryExpr>(BaseE))
3769 return Info.EvaluatingDecl == BaseMTE->getExtendingDecl();
3772 case EvalInfo::EvaluatingDeclKind::Dtor:
3777 if (MutableSubobject ||
Base != Info.EvaluatingDecl)
3783 return T.isConstQualified() ||
T->isReferenceType();
3786 llvm_unreachable(
"unknown evaluating decl kind");
3791 return Info.CheckArraySize(
3811 uint64_t IntResult = BoolResult;
3814 : Info.Ctx.getIntTypeForBitwidth(64,
false);
3815 Result =
APValue(Info.Ctx.MakeIntValue(IntResult, IntType));
3820 Info.Ctx.getIntTypeForBitwidth(64,
false),
3823 Result = std::move(Result2);
3831 DestTy,
Result.getFloat());
3837 uint64_t IntResult = BoolResult;
3856 uint64_t IntResult = BoolResult;
3863 DestTy,
Result.getInt());
3867 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
3880 {&
Result, ResultType, 0}};
3883 while (!WorkList.empty() && ElI < Elements.size()) {
3884 auto [Res,
Type, BitWidth] = WorkList.pop_back_val();
3900 APSInt &Int = Res->getInt();
3901 unsigned OldBitWidth = Int.getBitWidth();
3902 unsigned NewBitWidth = BitWidth;
3903 if (NewBitWidth < OldBitWidth)
3904 Int = Int.trunc(NewBitWidth).extend(OldBitWidth);
3913 for (
unsigned I = 0; I < NumEl; ++I) {
3919 *Res =
APValue(Vals.data(), NumEl);
3928 for (int64_t I = Size - 1; I > -1; --I)
3929 WorkList.emplace_back(&Res->getArrayInitializedElt(I), ElTy, 0u);
3935 unsigned NumBases = 0;
3936 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
3937 NumBases = CXXRD->getNumBases();
3944 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
3945 if (CXXRD->getNumBases() > 0) {
3946 assert(CXXRD->getNumBases() == 1);
3948 ReverseList.emplace_back(&Res->getStructBase(0), BS.
getType(), 0u);
3955 if (FD->isUnnamedBitField())
3957 if (FD->isBitField()) {
3958 FDBW = FD->getBitWidthValue();
3961 ReverseList.emplace_back(&Res->getStructField(FD->getFieldIndex()),
3962 FD->getType(), FDBW);
3965 std::reverse(ReverseList.begin(), ReverseList.end());
3966 llvm::append_range(WorkList, ReverseList);
3969 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
3982 assert((Elements.size() == SrcTypes.size()) &&
3983 (Elements.size() == DestTypes.size()));
3985 for (
unsigned I = 0, ESz = Elements.size(); I < ESz; ++I) {
3986 APValue Original = Elements[I];
3990 if (!
handleScalarCast(Info, FPO, E, SourceTy, DestTy, Original, Results[I]))
4001 while (!WorkList.empty()) {
4024 for (uint64_t I = 0; I < ArrSize; ++I) {
4025 WorkList.push_back(ElTy);
4033 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4034 if (CXXRD->getNumBases() > 0) {
4035 assert(CXXRD->getNumBases() == 1);
4037 WorkList.push_back(BS.
getType());
4043 if (FD->isUnnamedBitField())
4045 WorkList.push_back(FD->getType());
4062 "Not a valid HLSLAggregateSplatCast.");
4082 unsigned Populated = 0;
4083 while (!WorkList.empty() && Populated < Size) {
4084 auto [Work,
Type] = WorkList.pop_back_val();
4086 if (Work.isFloat() || Work.isInt()) {
4087 Elements.push_back(Work);
4088 Types.push_back(
Type);
4092 if (Work.isVector()) {
4095 for (
unsigned I = 0; I < Work.getVectorLength() && Populated < Size;
4097 Elements.push_back(Work.getVectorElt(I));
4098 Types.push_back(ElTy);
4103 if (Work.isMatrix()) {
4106 QualType ElTy = MT->getElementType();
4108 for (
unsigned Row = 0; Row < Work.getMatrixNumRows() && Populated < Size;
4110 for (
unsigned Col = 0;
4111 Col < Work.getMatrixNumColumns() && Populated < Size; Col++) {
4112 Elements.push_back(Work.getMatrixElt(Row, Col));
4113 Types.push_back(ElTy);
4119 if (Work.isArray()) {
4123 for (int64_t I = Work.getArraySize() - 1; I > -1; --I) {
4124 WorkList.emplace_back(Work.getArrayInitializedElt(I), ElTy);
4129 if (Work.isStruct()) {
4137 if (FD->isUnnamedBitField())
4139 ReverseList.emplace_back(Work.getStructField(FD->getFieldIndex()),
4143 std::reverse(ReverseList.begin(), ReverseList.end());
4144 llvm::append_range(WorkList, ReverseList);
4147 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4148 if (CXXRD->getNumBases() > 0) {
4149 assert(CXXRD->getNumBases() == 1);
4154 if (!
Base.isStruct())
4162 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
4171struct CompleteObject {
4173 APValue::LValueBase
Base;
4183 bool mayAccessMutableMembers(EvalInfo &Info,
AccessKinds AK)
const {
4194 if (!Info.getLangOpts().CPlusPlus14 &&
4195 AK != AccessKinds::AK_IsWithinLifetime)
4200 explicit operator bool()
const {
return !
Type.isNull(); }
4205 bool IsMutable =
false) {
4219template <
typename Sub
objectHandler>
4220static typename SubobjectHandler::result_type
4222 const SubobjectDesignator &Sub, SubobjectHandler &handler) {
4225 return handler.failed();
4226 if (Sub.isOnePastTheEnd() || Sub.isMostDerivedAnUnsizedArray()) {
4227 if (Info.getLangOpts().CPlusPlus11)
4228 Info.FFDiag(E, Sub.isOnePastTheEnd()
4229 ? diag::note_constexpr_access_past_end
4230 : diag::note_constexpr_access_unsized_array)
4231 << handler.AccessKind;
4234 return handler.failed();
4240 const FieldDecl *VolatileField =
nullptr;
4243 for (
unsigned I = 0, N = Sub.Entries.size(); ; ++I) {
4254 if (!Info.checkingPotentialConstantExpression()) {
4255 Info.FFDiag(E, diag::note_constexpr_access_uninit)
4260 return handler.failed();
4268 Info.isEvaluatingCtorDtor(
4269 Obj.Base,
ArrayRef(Sub.Entries.begin(), Sub.Entries.begin() + I)) !=
4270 ConstructionPhase::None) {
4271 ObjType = Info.Ctx.getCanonicalType(ObjType);
4280 if (Info.getLangOpts().CPlusPlus) {
4284 if (VolatileField) {
4287 Decl = VolatileField;
4290 Loc = VD->getLocation();
4297 Info.FFDiag(E, diag::note_constexpr_access_volatile_obj, 1)
4298 << handler.AccessKind << DiagKind <<
Decl;
4299 Info.Note(Loc, diag::note_constexpr_volatile_here) << DiagKind;
4301 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
4303 return handler.failed();
4311 !Obj.mayAccessMutableMembers(Info, handler.AccessKind) &&
4313 return handler.failed();
4317 if (!handler.found(*O, ObjType, Obj.Base))
4329 LastField =
nullptr;
4334 ObjType = Info.Ctx.getQualifiedType(AT->getValueType(),
4339 const ArrayType *AT = Info.Ctx.getAsArrayType(ObjType);
4341 "vla in literal type?");
4342 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4343 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT);
4344 CAT && CAT->
getSize().ule(Index)) {
4347 if (Info.getLangOpts().CPlusPlus11)
4348 Info.FFDiag(E, diag::note_constexpr_access_past_end)
4349 << handler.AccessKind;
4352 return handler.failed();
4359 else if (!
isRead(handler.AccessKind)) {
4360 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT);
4362 return handler.failed();
4370 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4372 if (Info.getLangOpts().CPlusPlus11)
4373 Info.FFDiag(E, diag::note_constexpr_access_past_end)
4374 << handler.AccessKind;
4377 return handler.failed();
4383 assert(I == N - 1 &&
"extracting subobject of scalar?");
4393 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4394 unsigned NumElements = VT->getNumElements();
4395 if (Index == NumElements) {
4396 if (Info.getLangOpts().CPlusPlus11)
4397 Info.FFDiag(E, diag::note_constexpr_access_past_end)
4398 << handler.AccessKind;
4401 return handler.failed();
4404 if (Index > NumElements) {
4405 Info.CCEDiag(E, diag::note_constexpr_array_index)
4406 << Index << 0 << NumElements;
4407 return handler.failed();
4410 ObjType = VT->getElementType();
4411 assert(I == N - 1 &&
"extracting subobject of scalar?");
4414 if (
isRead(handler.AccessKind)) {
4416 return handler.failed();
4420 assert(O->
isVector() &&
"unexpected object during vector element access");
4421 return handler.found(O->
getVectorElt(Index), ObjType, Obj.Base);
4422 }
else if (
const FieldDecl *Field = getAsField(Sub.Entries[I])) {
4423 if (Field->isMutable() &&
4424 !Obj.mayAccessMutableMembers(Info, handler.AccessKind)) {
4425 Info.FFDiag(E, diag::note_constexpr_access_mutable, 1)
4426 << handler.AccessKind << Field;
4427 Info.Note(Field->getLocation(), diag::note_declared_at);
4428 return handler.failed();
4437 if (I == N - 1 && handler.AccessKind ==
AK_Construct) {
4448 Info.FFDiag(E, diag::note_constexpr_access_inactive_union_member)
4449 << handler.AccessKind << Field << !UnionField << UnionField;
4450 return handler.failed();
4459 if (Field->getType().isVolatileQualified())
4460 VolatileField = Field;
4468 if (BaseIndex >= NumNonVirtualBases) {
4479struct ExtractSubobjectHandler {
4485 typedef bool result_type;
4486 bool failed() {
return false; }
4487 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
4497 bool found(APFloat &
Value, QualType SubobjType) {
4506 const CompleteObject &Obj,
4510 ExtractSubobjectHandler Handler = {Info, E,
Result, AK};
4515struct ModifySubobjectHandler {
4520 typedef bool result_type;
4523 bool checkConst(QualType QT) {
4526 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
4532 bool failed() {
return false; }
4533 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
4534 if (!checkConst(SubobjType))
4537 Subobj.
swap(NewVal);
4541 if (!checkConst(SubobjType))
4543 if (!NewVal.
isInt()) {
4551 bool found(APFloat &
Value, QualType SubobjType) {
4552 if (!checkConst(SubobjType))
4560const AccessKinds ModifySubobjectHandler::AccessKind;
4564 const CompleteObject &Obj,
4565 const SubobjectDesignator &Sub,
4567 ModifySubobjectHandler Handler = { Info, NewVal, E };
4574 const SubobjectDesignator &A,
4575 const SubobjectDesignator &B,
4576 bool &WasArrayIndex) {
4577 unsigned I = 0, N = std::min(A.Entries.size(), B.Entries.size());
4578 for (; I != N; ++I) {
4582 if (A.Entries[I].getAsArrayIndex() != B.Entries[I].getAsArrayIndex()) {
4583 WasArrayIndex =
true;
4591 if (A.Entries[I].getAsBaseOrMember() !=
4592 B.Entries[I].getAsBaseOrMember()) {
4593 WasArrayIndex =
false;
4596 if (
const FieldDecl *FD = getAsField(A.Entries[I]))
4598 ObjType = FD->getType();
4604 WasArrayIndex =
false;
4611 const SubobjectDesignator &A,
4612 const SubobjectDesignator &B) {
4613 if (A.Entries.size() != B.Entries.size())
4616 bool IsArray = A.MostDerivedIsArrayElement;
4617 if (IsArray && A.MostDerivedPathLength != A.Entries.size())
4626 return CommonLength >= A.Entries.size() - IsArray;
4633 if (LVal.InvalidBase) {
4635 return CompleteObject();
4640 Info.FFDiag(E, diag::note_constexpr_dereferencing_null);
4642 Info.FFDiag(E, diag::note_constexpr_access_null) << AK;
4643 return CompleteObject();
4646 CallStackFrame *Frame =
nullptr;
4648 if (LVal.getLValueCallIndex()) {
4649 std::tie(Frame, Depth) =
4650 Info.getCallFrameAndDepth(LVal.getLValueCallIndex());
4652 Info.FFDiag(E, diag::note_constexpr_access_uninit, 1)
4655 return CompleteObject();
4666 if (Info.getLangOpts().CPlusPlus)
4667 Info.FFDiag(E, diag::note_constexpr_access_volatile_type)
4671 return CompleteObject();
4678 if (Info.getLangOpts().CPlusPlus14 && LVal.Base == Info.EvaluatingDecl &&
4682 BaseVal = Info.EvaluatingDeclValue;
4685 if (
auto *GD = dyn_cast<MSGuidDecl>(D)) {
4688 Info.FFDiag(E, diag::note_constexpr_modify_global);
4689 return CompleteObject();
4693 Info.FFDiag(E, diag::note_constexpr_unsupported_layout)
4695 return CompleteObject();
4697 return CompleteObject(LVal.Base, &
V, GD->getType());
4701 if (
auto *GCD = dyn_cast<UnnamedGlobalConstantDecl>(D)) {
4703 Info.FFDiag(E, diag::note_constexpr_modify_global);
4704 return CompleteObject();
4706 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&GCD->getValue()),
4711 if (
auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
4713 Info.FFDiag(E, diag::note_constexpr_modify_global);
4714 return CompleteObject();
4716 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&TPO->getValue()),
4727 const VarDecl *VD = dyn_cast<VarDecl>(D);
4734 return CompleteObject();
4737 bool IsConstant = BaseType.isConstant(Info.Ctx);
4738 bool ConstexprVar =
false;
4739 if (
const auto *VD = dyn_cast_if_present<VarDecl>(
4751 }
else if (Info.getLangOpts().CPlusPlus14 &&
4758 Info.FFDiag(E, diag::note_constexpr_modify_global);
4759 return CompleteObject();
4762 }
else if (Info.getLangOpts().C23 && ConstexprVar) {
4764 return CompleteObject();
4765 }
else if (BaseType->isIntegralOrEnumerationType()) {
4768 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4769 if (Info.getLangOpts().CPlusPlus) {
4770 Info.FFDiag(E, diag::note_constexpr_ltor_non_const_int, 1) << VD;
4771 Info.Note(VD->
getLocation(), diag::note_declared_at);
4775 return CompleteObject();
4777 }
else if (!IsAccess) {
4778 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4779 }
else if ((IsConstant || BaseType->isReferenceType()) &&
4780 Info.checkingPotentialConstantExpression() &&
4781 BaseType->isLiteralType(Info.Ctx) && !VD->
hasDefinition()) {
4783 }
else if (IsConstant) {
4787 if (Info.getLangOpts().CPlusPlus) {
4788 Info.CCEDiag(E, Info.getLangOpts().CPlusPlus11
4789 ? diag::note_constexpr_ltor_non_constexpr
4790 : diag::note_constexpr_ltor_non_integral, 1)
4792 Info.Note(VD->
getLocation(), diag::note_declared_at);
4798 if (Info.getLangOpts().CPlusPlus) {
4799 Info.FFDiag(E, Info.getLangOpts().CPlusPlus11
4800 ? diag::note_constexpr_ltor_non_constexpr
4801 : diag::note_constexpr_ltor_non_integral, 1)
4803 Info.Note(VD->
getLocation(), diag::note_declared_at);
4807 return CompleteObject();
4816 return CompleteObject();
4821 if (!Info.checkingPotentialConstantExpression()) {
4822 Info.FFDiag(E, diag::note_constexpr_access_unknown_variable, 1)
4824 Info.Note(VD->getLocation(), diag::note_declared_at);
4826 return CompleteObject();
4829 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
4831 Info.FFDiag(E, diag::note_constexpr_access_deleted_object) << AK;
4832 return CompleteObject();
4834 return CompleteObject(LVal.Base, &(*Alloc)->Value,
4844 dyn_cast_or_null<MaterializeTemporaryExpr>(
Base)) {
4845 assert(MTE->getStorageDuration() ==
SD_Static &&
4846 "should have a frame for a non-global materialized temporary");
4873 if (!MTE->isUsableInConstantExpressions(Info.Ctx) &&
4876 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4877 Info.FFDiag(E, diag::note_constexpr_access_static_temporary, 1) << AK;
4878 Info.Note(MTE->getExprLoc(), diag::note_constexpr_temporary_here);
4879 return CompleteObject();
4882 BaseVal = MTE->getOrCreateValue(
false);
4883 assert(BaseVal &&
"got reference to unevaluated temporary");
4885 dyn_cast_or_null<CompoundLiteralExpr>(
Base)) {
4901 !CLETy.isConstant(Info.Ctx)) {
4903 Info.Note(CLE->getExprLoc(), diag::note_declared_at);
4904 return CompleteObject();
4907 BaseVal = &CLE->getStaticValue();
4910 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4913 Info.FFDiag(E, diag::note_constexpr_access_unreadable_object)
4916 Info.Ctx.getLValueReferenceType(LValType));
4918 return CompleteObject();
4922 assert(BaseVal &&
"missing value for temporary");
4933 unsigned VisibleDepth = Depth;
4934 if (llvm::isa_and_nonnull<ParmVarDecl>(
4937 if ((Frame && Info.getLangOpts().CPlusPlus14 &&
4938 Info.EvalStatus.HasSideEffects) ||
4939 (
isModification(AK) && VisibleDepth < Info.SpeculativeEvaluationDepth))
4940 return CompleteObject();
4942 return CompleteObject(LVal.getLValueBase(), BaseVal, BaseType);
4961 const LValue &LVal,
APValue &RVal,
4962 bool WantObjectRepresentation =
false) {
4963 if (LVal.Designator.Invalid)
4972 if (
Base && !LVal.getLValueCallIndex() && !
Type.isVolatileQualified()) {
4976 assert(LVal.Designator.Entries.size() <= 1 &&
4977 "Can only read characters from string literals");
4978 if (LVal.Designator.Entries.empty()) {
4985 if (LVal.Designator.isOnePastTheEnd()) {
4986 if (Info.getLangOpts().CPlusPlus11)
4987 Info.FFDiag(Conv, diag::note_constexpr_access_past_end) << AK;
4992 uint64_t CharIndex = LVal.Designator.Entries[0].getAsArrayIndex();
4999 return Obj &&
extractSubobject(Info, Conv, Obj, LVal.Designator, RVal, AK);
5013 LVal.setFrom(Info.Ctx, Val);
5029 if (LVal.Designator.Invalid)
5032 if (!Info.getLangOpts().CPlusPlus14) {
5042struct CompoundAssignSubobjectHandler {
5044 const CompoundAssignOperator *E;
5045 QualType PromotedLHSType;
5051 typedef bool result_type;
5053 bool checkConst(QualType QT) {
5056 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
5062 bool failed() {
return false; }
5063 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
5066 return found(Subobj.
getInt(), SubobjType);
5068 return found(Subobj.
getFloat(), SubobjType);
5075 return foundPointer(Subobj, SubobjType);
5077 return foundVector(Subobj, SubobjType);
5079 Info.FFDiag(E, diag::note_constexpr_access_uninit)
5091 bool foundVector(
APValue &
Value, QualType SubobjType) {
5092 if (!checkConst(SubobjType))
5103 if (!checkConst(SubobjType))
5122 Info.Ctx.getLangOpts());
5125 PromotedLHSType, FValue) &&
5134 bool found(APFloat &
Value, QualType SubobjType) {
5135 return checkConst(SubobjType) &&
5141 bool foundPointer(
APValue &Subobj, QualType SubobjType) {
5142 if (!checkConst(SubobjType))
5145 QualType PointeeType;
5146 if (
const PointerType *PT = SubobjType->
getAs<PointerType>())
5150 (Opcode != BO_Add && Opcode != BO_Sub)) {
5156 if (Opcode == BO_Sub)
5160 LVal.setFrom(Info.Ctx, Subobj);
5163 LVal.moveInto(Subobj);
5169const AccessKinds CompoundAssignSubobjectHandler::AccessKind;
5174 const LValue &LVal,
QualType LValType,
5178 if (LVal.Designator.Invalid)
5181 if (!Info.getLangOpts().CPlusPlus14) {
5187 CompoundAssignSubobjectHandler Handler = { Info, E, PromotedLValType, Opcode,
5189 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
5193struct IncDecSubobjectHandler {
5195 const UnaryOperator *E;
5199 typedef bool result_type;
5201 bool checkConst(QualType QT) {
5204 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
5210 bool failed() {
return false; }
5211 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
5221 return found(Subobj.
getInt(), SubobjType);
5223 return found(Subobj.
getFloat(), SubobjType);
5226 SubobjType->
castAs<ComplexType>()->getElementType()
5230 SubobjType->
castAs<ComplexType>()->getElementType()
5233 return foundPointer(Subobj, SubobjType);
5241 if (!checkConst(SubobjType))
5263 bool WasNegative =
Value.isNegative();
5277 unsigned BitWidth =
Value.getBitWidth();
5278 APSInt ActualValue(
Value.sext(BitWidth + 1),
false);
5279 ActualValue.setBit(BitWidth);
5285 bool found(APFloat &
Value, QualType SubobjType) {
5286 if (!checkConst(SubobjType))
5293 APFloat::opStatus St;
5295 St =
Value.add(One, RM);
5297 St =
Value.subtract(One, RM);
5300 bool foundPointer(
APValue &Subobj, QualType SubobjType) {
5301 if (!checkConst(SubobjType))
5304 QualType PointeeType;
5305 if (
const PointerType *PT = SubobjType->
getAs<PointerType>())
5313 LVal.setFrom(Info.Ctx, Subobj);
5317 LVal.moveInto(Subobj);
5326 if (LVal.Designator.Invalid)
5329 if (!Info.getLangOpts().CPlusPlus14) {
5337 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
5343 if (
Object->getType()->isPointerType() &&
Object->isPRValue())
5349 if (
Object->getType()->isLiteralType(Info.Ctx))
5352 if (
Object->getType()->isRecordType() &&
Object->isPRValue())
5355 Info.FFDiag(
Object, diag::note_constexpr_nonliteral) <<
Object->getType();
5374 bool IncludeMember =
true) {
5381 if (!MemPtr.getDecl()) {
5387 if (MemPtr.isDerivedMember()) {
5394 if (LV.Designator.MostDerivedPathLength + MemPtr.Path.size() >
5395 LV.Designator.Entries.size()) {
5399 unsigned PathLengthToMember =
5400 LV.Designator.Entries.size() - MemPtr.Path.size();
5401 for (
unsigned I = 0, N = MemPtr.Path.size(); I != N; ++I) {
5403 LV.Designator.Entries[PathLengthToMember + I]);
5420 (PathLengthToMember > LV.Designator.MostDerivedPathLength)
5421 ? getAsBaseClass(LV.Designator.Entries[PathLengthToMember - 1])
5423 const CXXRecordDecl *LastMPDecl = MemPtr.getContainingRecord();
5431 PathLengthToMember))
5433 }
else if (!MemPtr.Path.empty()) {
5435 LV.Designator.Entries.reserve(LV.Designator.Entries.size() +
5436 MemPtr.Path.size() + IncludeMember);
5442 assert(RD &&
"member pointer access on non-class-type expression");
5444 for (
unsigned I = 1, N = MemPtr.Path.size(); I != N; ++I) {
5452 MemPtr.getContainingRecord()))
5457 if (IncludeMember) {
5458 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(MemPtr.getDecl())) {
5462 dyn_cast<IndirectFieldDecl>(MemPtr.getDecl())) {
5466 llvm_unreachable(
"can't construct reference to bound member function");
5470 return MemPtr.getDecl();
5476 bool IncludeMember =
true) {
5480 if (Info.noteFailure()) {
5488 BO->
getRHS(), IncludeMember);
5495 SubobjectDesignator &D =
Result.Designator;
5503 auto InvalidCast = [&]() {
5504 if (!Info.checkingPotentialConstantExpression() ||
5505 !
Result.AllowConstexprUnknown) {
5506 Info.CCEDiag(E, diag::note_constexpr_invalid_downcast)
5507 << D.MostDerivedType << TargetQT;
5513 if (D.MostDerivedPathLength + E->
path_size() > D.Entries.size())
5514 return InvalidCast();
5518 unsigned NewEntriesSize = D.Entries.size() - E->
path_size();
5521 if (NewEntriesSize == D.MostDerivedPathLength)
5524 FinalType = getAsBaseClass(D.Entries[NewEntriesSize - 1]);
5526 return InvalidCast();
5535 bool IsCompleteClass =
true) {
5542 if (
auto *RD =
T->getAsCXXRecordDecl()) {
5543 if (RD->isInvalidDecl()) {
5547 if (RD->isUnion()) {
5553 unsigned NonVirtualBases = countNonVirtualBases(RD);
5556 IsCompleteClass ? RD->getNumVBases() : 0);
5567 for (
const auto *I : RD->fields()) {
5568 if (I->isUnnamedBitField())
5571 I->getType(),
Result.getStructField(I->getFieldIndex()));
5574 if (IsCompleteClass) {
5577 for (
const auto &B : RD->vbases()) {
5579 Result.getStructVirtualBase(Index),
5585 assert(
Result.getStructNumVirtualBases() == 0);
5592 dyn_cast_or_null<ConstantArrayType>(
T->getAsArrayTypeUnsafe())) {
5594 if (
Result.hasArrayFiller())
5605enum EvalStmtResult {
5634 if (!
Result.Designator.Invalid &&
Result.Designator.isOnePastTheEnd()) {
5652 APValue &Val = Info.CurrentCall->createTemporary(VD, VD->
getType(),
5653 ScopeKind::Block,
Result);
5658 return Info.noteSideEffect();
5679 const DecompositionDecl *DD);
5682 bool EvaluateConditionDecl =
false) {
5684 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
5688 EvaluateConditionDecl && DD)
5698 if (
auto *VD = BD->getHoldingVar())
5706 if (
auto *DD = dyn_cast_if_present<DecompositionDecl>(VD)) {
5715 if (Info.noteSideEffect())
5717 assert(E->
containsErrors() &&
"valid value-dependent expression should never "
5718 "reach invalid code path.");
5725 if (
Cond->isValueDependent())
5727 FullExpressionRAII
Scope(Info);
5734 return Scope.destroy();
5747struct TempVersionRAII {
5748 CallStackFrame &Frame;
5750 TempVersionRAII(CallStackFrame &Frame) : Frame(Frame) {
5751 Frame.pushTempVersion();
5754 ~TempVersionRAII() {
5755 Frame.popTempVersion();
5763 const SwitchCase *SC =
nullptr);
5769 const Stmt *LoopOrSwitch,
5771 EvalStmtResult &ESR) {
5775 if (!IsSwitch && ESR == ESR_Succeeded) {
5780 if (ESR != ESR_Break && ESR != ESR_Continue)
5784 bool CanBreakOrContinue = !IsSwitch || ESR == ESR_Break;
5785 const Stmt *StackTop = Info.BreakContinueStack.back();
5786 if (CanBreakOrContinue && (StackTop ==
nullptr || StackTop == LoopOrSwitch)) {
5787 Info.BreakContinueStack.pop_back();
5788 if (ESR == ESR_Break)
5789 ESR = ESR_Succeeded;
5794 for (BlockScopeRAII *S : Scopes) {
5795 if (!S->destroy()) {
5807 BlockScopeRAII
Scope(Info);
5810 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5819 BlockScopeRAII
Scope(Info);
5826 if (ESR != ESR_Succeeded) {
5827 if (ESR != ESR_Failed && !
Scope.destroy())
5833 FullExpressionRAII CondScope(Info);
5848 if (!CondScope.destroy())
5869 if (LHSValue <=
Value &&
Value <= RHSValue) {
5876 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5880 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5887 llvm_unreachable(
"Should have been converted to Succeeded");
5893 case ESR_CaseNotFound:
5896 Info.FFDiag(
Found->getBeginLoc(),
5897 diag::note_constexpr_stmt_expr_unsupported);
5900 llvm_unreachable(
"Invalid EvalStmtResult!");
5910 Info.CCEDiag(VD->
getLocation(), diag::note_constexpr_static_local)
5920 if (!Info.nextStep(S))
5927 case Stmt::CompoundStmtClass:
5931 case Stmt::LabelStmtClass:
5932 case Stmt::AttributedStmtClass:
5933 case Stmt::DoStmtClass:
5936 case Stmt::CaseStmtClass:
5937 case Stmt::DefaultStmtClass:
5942 case Stmt::IfStmtClass: {
5949 BlockScopeRAII
Scope(Info);
5955 if (ESR != ESR_CaseNotFound) {
5956 assert(ESR != ESR_Succeeded);
5967 if (ESR == ESR_Failed)
5969 if (ESR != ESR_CaseNotFound)
5970 return Scope.destroy() ? ESR : ESR_Failed;
5972 return ESR_CaseNotFound;
5975 if (ESR == ESR_Failed)
5977 if (ESR != ESR_CaseNotFound)
5978 return Scope.destroy() ? ESR : ESR_Failed;
5979 return ESR_CaseNotFound;
5982 case Stmt::WhileStmtClass: {
5983 EvalStmtResult ESR =
5987 if (ESR != ESR_Continue)
5992 case Stmt::ForStmtClass: {
5994 BlockScopeRAII
Scope(Info);
6000 if (ESR != ESR_CaseNotFound) {
6001 assert(ESR != ESR_Succeeded);
6006 EvalStmtResult ESR =
6010 if (ESR != ESR_Continue)
6012 if (
const auto *Inc = FS->
getInc()) {
6013 if (Inc->isValueDependent()) {
6017 FullExpressionRAII IncScope(Info);
6025 case Stmt::DeclStmtClass: {
6029 for (
const auto *D : DS->
decls()) {
6030 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
6033 if (VD->hasLocalStorage() && !VD->getInit())
6041 return ESR_CaseNotFound;
6045 return ESR_CaseNotFound;
6051 if (
const Expr *E = dyn_cast<Expr>(S)) {
6060 FullExpressionRAII
Scope(Info);
6064 return ESR_Succeeded;
6070 case Stmt::NullStmtClass:
6071 return ESR_Succeeded;
6073 case Stmt::DeclStmtClass: {
6075 for (
const auto *D : DS->
decls()) {
6076 const VarDecl *VD = dyn_cast_or_null<VarDecl>(D);
6080 if (
const auto *ESD = dyn_cast<CXXExpansionStmtDecl>(D)) {
6081 assert(ESD->getInstantiations() &&
"not expanded?");
6086 FullExpressionRAII
Scope(Info);
6088 !Info.noteFailure())
6090 if (!
Scope.destroy())
6093 return ESR_Succeeded;
6096 case Stmt::ReturnStmtClass: {
6098 FullExpressionRAII
Scope(Info);
6109 return Scope.destroy() ? ESR_Returned : ESR_Failed;
6112 case Stmt::CompoundStmtClass: {
6113 BlockScopeRAII
Scope(Info);
6116 for (
const auto *BI : CS->
body()) {
6118 if (ESR == ESR_Succeeded)
6120 else if (ESR != ESR_CaseNotFound) {
6121 if (ESR != ESR_Failed && !
Scope.destroy())
6127 return ESR_CaseNotFound;
6128 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
6131 case Stmt::IfStmtClass: {
6135 BlockScopeRAII
Scope(Info);
6138 if (ESR != ESR_Succeeded) {
6139 if (ESR != ESR_Failed && !
Scope.destroy())
6149 if (!Info.InConstantContext)
6157 if (ESR != ESR_Succeeded) {
6158 if (ESR != ESR_Failed && !
Scope.destroy())
6163 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
6166 case Stmt::WhileStmtClass: {
6169 BlockScopeRAII
Scope(Info);
6181 if (ESR != ESR_Continue) {
6182 if (ESR != ESR_Failed && !
Scope.destroy())
6186 if (!
Scope.destroy())
6189 return ESR_Succeeded;
6192 case Stmt::DoStmtClass: {
6199 if (ESR != ESR_Continue)
6208 FullExpressionRAII CondScope(Info);
6210 !CondScope.destroy())
6213 return ESR_Succeeded;
6216 case Stmt::ForStmtClass: {
6218 BlockScopeRAII ForScope(Info);
6221 if (ESR != ESR_Succeeded) {
6222 if (ESR != ESR_Failed && !ForScope.destroy())
6228 BlockScopeRAII IterScope(Info);
6229 bool Continue =
true;
6235 if (!IterScope.destroy())
6243 if (ESR != ESR_Continue) {
6244 if (ESR != ESR_Failed && (!IterScope.destroy() || !ForScope.destroy()))
6249 if (
const auto *Inc = FS->
getInc()) {
6250 if (Inc->isValueDependent()) {
6254 FullExpressionRAII IncScope(Info);
6260 if (!IterScope.destroy())
6263 return ForScope.destroy() ? ESR_Succeeded : ESR_Failed;
6266 case Stmt::CXXForRangeStmtClass: {
6268 BlockScopeRAII
Scope(Info);
6273 if (ESR != ESR_Succeeded) {
6274 if (ESR != ESR_Failed && !
Scope.destroy())
6282 if (ESR != ESR_Succeeded) {
6283 if (ESR != ESR_Failed && !
Scope.destroy())
6295 if (ESR != ESR_Succeeded) {
6296 if (ESR != ESR_Failed && !
Scope.destroy())
6301 if (ESR != ESR_Succeeded) {
6302 if (ESR != ESR_Failed && !
Scope.destroy())
6315 bool Continue =
true;
6316 FullExpressionRAII CondExpr(Info);
6324 BlockScopeRAII InnerScope(Info);
6326 if (ESR != ESR_Succeeded) {
6327 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
6336 if (ESR != ESR_Continue) {
6337 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
6350 if (!InnerScope.destroy())
6354 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
6357 case Stmt::CXXExpansionStmtInstantiationClass: {
6358 BlockScopeRAII
Scope(Info);
6360 for (
const Stmt *PreambleStmt : Expansion->getPreambleStmts()) {
6362 if (ESR != ESR_Succeeded) {
6363 if (ESR != ESR_Failed && !
Scope.destroy())
6371 EvalStmtResult ESR = ESR_Succeeded;
6372 for (
const Stmt *Instantiation : Expansion->getInstantiations()) {
6374 if (ESR == ESR_Failed ||
6377 if (ESR != ESR_Continue) {
6379 assert(ESR == ESR_Succeeded || ESR == ESR_Returned);
6385 if (ESR == ESR_Continue)
6386 ESR = ESR_Succeeded;
6388 return Scope.destroy() ? ESR : ESR_Failed;
6391 case Stmt::SwitchStmtClass:
6394 case Stmt::ContinueStmtClass:
6395 case Stmt::BreakStmtClass: {
6397 Info.BreakContinueStack.push_back(B->getNamedLoopOrSwitch());
6401 case Stmt::LabelStmtClass:
6404 case Stmt::AttributedStmtClass: {
6406 const auto *SS = AS->getSubStmt();
6407 MSConstexprContextRAII ConstexprContext(
6411 auto LO = Info.Ctx.getLangOpts();
6412 if (LO.CXXAssumptions && !LO.MSVCCompat) {
6413 for (
auto *
Attr : AS->getAttrs()) {
6414 auto *AA = dyn_cast<CXXAssumeAttr>(
Attr);
6418 auto *Assumption = AA->getAssumption();
6419 if (Assumption->isValueDependent())
6422 if (Assumption->HasSideEffects(Info.Ctx))
6429 Info.CCEDiag(Assumption->getExprLoc(),
6430 diag::note_constexpr_assumption_failed);
6439 case Stmt::CaseStmtClass:
6440 case Stmt::DefaultStmtClass:
6442 case Stmt::CXXTryStmtClass:
6454 bool IsValueInitialization) {
6461 if (!CD->
isConstexpr() && !IsValueInitialization) {
6462 if (Info.getLangOpts().CPlusPlus11) {
6465 Info.CCEDiag(Loc, diag::note_constexpr_invalid_function, 1)
6467 Info.Note(CD->
getLocation(), diag::note_declared_at);
6469 Info.CCEDiag(Loc, diag::note_invalid_subexpr_in_const_expr);
6483 if (Info.checkingPotentialConstantExpression() && !
Definition &&
6491 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6500 Info.CCEDiag(CallLoc, diag::note_constexpr_virtual_call);
6503 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6509 (
Definition->isConstexpr() || (Info.CurrentCall->CanEvalMSConstexpr &&
6519 StringRef Name = DiagDecl->
getName();
6521 Name ==
"__assert_rtn" || Name ==
"__assert_fail" || Name ==
"_wassert";
6523 Info.FFDiag(CallLoc, diag::note_constexpr_assert_failed);
6528 if (Info.getLangOpts().CPlusPlus11) {
6531 auto *CD = dyn_cast<CXXConstructorDecl>(DiagDecl);
6532 if (CD && CD->isInheritingConstructor()) {
6533 auto *Inherited = CD->getInheritedConstructor().getConstructor();
6534 if (!Inherited->isConstexpr())
6535 DiagDecl = CD = Inherited;
6541 if (CD && CD->isInheritingConstructor())
6542 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_inhctor, 1)
6543 << CD->getInheritedConstructor().getConstructor()->getParent();
6545 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_function, 1)
6547 Info.Note(DiagDecl->
getLocation(), diag::note_declared_at);
6549 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6555struct CheckDynamicTypeHandler {
6557 typedef bool result_type;
6558 bool failed() {
return false; }
6559 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
6562 bool found(
APSInt &
Value, QualType SubobjType) {
return true; }
6563 bool found(APFloat &
Value, QualType SubobjType) {
return true; }
6571 if (
This.Designator.Invalid)
6583 if (
This.Designator.isOnePastTheEnd() ||
6584 This.Designator.isMostDerivedAnUnsizedArray()) {
6585 Info.FFDiag(E,
This.Designator.isOnePastTheEnd()
6586 ? diag::note_constexpr_access_past_end
6587 : diag::note_constexpr_access_unsized_array)
6590 }
else if (Polymorphic) {
6593 if (!Info.checkingPotentialConstantExpression() ||
6594 !
This.AllowConstexprUnknown) {
6598 Info.Ctx.getLValueReferenceType(
This.Designator.getType(Info.Ctx));
6599 Info.FFDiag(E, diag::note_constexpr_polymorphic_unknown_dynamic_type)
6607 CheckDynamicTypeHandler Handler{AK};
6630 unsigned PathLength) {
6631 assert(PathLength >=
Designator.MostDerivedPathLength && PathLength <=
6632 Designator.Entries.size() &&
"invalid path length");
6633 return (PathLength ==
Designator.MostDerivedPathLength)
6634 ?
Designator.MostDerivedType->getAsCXXRecordDecl()
6635 : getAsBaseClass(
Designator.Entries[PathLength - 1]);
6648 return std::nullopt;
6650 if (
This.Designator.Invalid)
6651 return std::nullopt;
6657 This.Designator.MostDerivedType->getAsCXXRecordDecl();
6658 if (!Class || (!Info.getLangOpts().CPlusPlus26 && Class->getNumVBases())) {
6660 return std::nullopt;
6668 for (
unsigned PathLength =
This.Designator.MostDerivedPathLength;
6669 PathLength <= Path.size(); ++PathLength) {
6670 switch (Info.isEvaluatingCtorDtor(
This.getLValueBase(),
6671 Path.slice(0, PathLength))) {
6672 case ConstructionPhase::Bases:
6673 case ConstructionPhase::DestroyingBases:
6678 case ConstructionPhase::None:
6679 case ConstructionPhase::AfterBases:
6680 case ConstructionPhase::AfterFields:
6681 case ConstructionPhase::Destroying:
6693 return std::nullopt;
6711 unsigned PathLength = DynType->PathLength;
6712 for (; PathLength <=
This.Designator.Entries.size(); ++PathLength) {
6715 Found->getCorrespondingMethodDeclaredInClass(Class,
false);
6725 if (Callee->isPureVirtual()) {
6726 Info.FFDiag(E, diag::note_constexpr_pure_virtual_call, 1) << Callee;
6727 Info.Note(Callee->getLocation(), diag::note_declared_at);
6733 if (!Info.Ctx.hasSameUnqualifiedType(Callee->getReturnType(),
6734 Found->getReturnType())) {
6735 CovariantAdjustmentPath.push_back(Callee->getReturnType());
6736 for (
unsigned CovariantPathLength = PathLength + 1;
6737 CovariantPathLength !=
This.Designator.Entries.size();
6738 ++CovariantPathLength) {
6742 Found->getCorrespondingMethodDeclaredInClass(NextClass,
false);
6743 if (
Next && !Info.Ctx.hasSameUnqualifiedType(
6744 Next->getReturnType(), CovariantAdjustmentPath.back()))
6745 CovariantAdjustmentPath.push_back(
Next->getReturnType());
6747 if (!Info.Ctx.hasSameUnqualifiedType(
Found->getReturnType(),
6748 CovariantAdjustmentPath.back()))
6749 CovariantAdjustmentPath.push_back(
Found->getReturnType());
6765 assert(
Result.isLValue() &&
6766 "unexpected kind of APValue for covariant return");
6767 if (
Result.isNullPointer())
6771 LVal.setFrom(Info.Ctx,
Result);
6773 const CXXRecordDecl *OldClass = Path[0]->getPointeeCXXRecordDecl();
6774 for (
unsigned I = 1; I != Path.size(); ++I) {
6775 const CXXRecordDecl *NewClass = Path[I]->getPointeeCXXRecordDecl();
6776 assert(OldClass && NewClass &&
"unexpected kind of covariant return");
6777 if (OldClass != NewClass &&
6780 OldClass = NewClass;
6792 if (BaseSpec.isVirtual())
6794 auto *BaseClass = BaseSpec.getType()->getAsCXXRecordDecl();
6796 return BaseSpec.getAccessSpecifier() ==
AS_public;
6799 auto *BaseClass = BaseSpec.getType()->getAsCXXRecordDecl();
6801 return BaseSpec.getAccessSpecifier() ==
AS_public;
6804 llvm_unreachable(
"Base is not a direct base of Derived");
6814 SubobjectDesignator &D = Ptr.Designator;
6820 if (Ptr.isNullPointer() && !E->
isGLValue())
6826 std::optional<DynamicType> DynType =
6838 assert(
C &&
"dynamic_cast target is not void pointer nor class");
6846 Ptr.setNull(Info.Ctx, E->
getType());
6853 DynType->Type->isDerivedFrom(
C)))
6855 else if (!Paths || Paths->begin() == Paths->end())
6857 else if (Paths->isAmbiguous(CQT))
6860 assert(Paths->front().Access !=
AS_public &&
"why did the cast fail?");
6863 Info.FFDiag(E, diag::note_constexpr_dynamic_cast_to_reference_failed)
6864 << DiagKind << Ptr.Designator.getType(Info.Ctx)
6865 << Info.Ctx.getCanonicalTagType(DynType->Type)
6873 for (
int PathLength = Ptr.Designator.Entries.size();
6874 PathLength >= (
int)DynType->PathLength; --PathLength) {
6879 if (PathLength > (
int)DynType->PathLength &&
6882 return RuntimeCheckFailed(
nullptr);
6889 if (DynType->Type->isDerivedFrom(
C, Paths) && !Paths.
isAmbiguous(CQT) &&
6902 return RuntimeCheckFailed(&Paths);
6906struct StartLifetimeOfUnionMemberHandler {
6908 const Expr *LHSExpr;
6909 const FieldDecl *
Field;
6911 bool Failed =
false;
6914 typedef bool result_type;
6915 bool failed() {
return Failed; }
6916 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
6931 }
else if (DuringInit) {
6935 Info.FFDiag(LHSExpr,
6936 diag::note_constexpr_union_member_change_during_init);
6945 llvm_unreachable(
"wrong value kind for union object");
6947 bool found(APFloat &
Value, QualType SubobjType) {
6948 llvm_unreachable(
"wrong value kind for union object");
6953const AccessKinds StartLifetimeOfUnionMemberHandler::AccessKind;
6960 const Expr *LHSExpr,
6961 const LValue &LHS) {
6962 if (LHS.InvalidBase || LHS.Designator.Invalid)
6968 unsigned PathLength = LHS.Designator.Entries.size();
6969 for (
const Expr *E = LHSExpr; E !=
nullptr;) {
6971 if (
auto *ME = dyn_cast<MemberExpr>(E)) {
6972 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
6975 if (!FD || FD->getType()->isReferenceType())
6979 if (FD->getParent()->isUnion()) {
6984 FD->getType()->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
6985 if (!RD || RD->hasTrivialDefaultConstructor())
6986 UnionPathLengths.push_back({PathLength - 1, FD});
6992 LHS.Designator.Entries[PathLength]
6993 .getAsBaseOrMember().getPointer()));
6997 }
else if (
auto *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
6999 auto *
Base = ASE->getBase()->IgnoreImplicit();
7000 if (!
Base->getType()->isArrayType())
7006 }
else if (
auto *ICE = dyn_cast<ImplicitCastExpr>(E)) {
7009 if (ICE->getCastKind() == CK_NoOp)
7011 if (ICE->getCastKind() != CK_DerivedToBase &&
7012 ICE->getCastKind() != CK_UncheckedDerivedToBase)
7016 if (Elt->isVirtual()) {
7025 LHS.Designator.Entries[PathLength]
7026 .getAsBaseOrMember().getPointer()));
7036 if (UnionPathLengths.empty())
7041 CompleteObject Obj =
7045 for (std::pair<unsigned, const FieldDecl *> LengthAndField :
7046 llvm::reverse(UnionPathLengths)) {
7048 SubobjectDesignator D = LHS.Designator;
7049 D.truncate(Info.Ctx, LHS.Base, LengthAndField.first);
7051 bool DuringInit = Info.isEvaluatingCtorDtor(LHS.Base, D.Entries) ==
7052 ConstructionPhase::AfterBases;
7053 StartLifetimeOfUnionMemberHandler StartLifetime{
7054 Info, LHSExpr, LengthAndField.second, DuringInit};
7063 CallRef
Call, EvalInfo &Info,
bool NonNull =
false,
7064 APValue **EvaluatedArg =
nullptr) {
7071 APValue &
V = PVD ? Info.CurrentCall->createParam(
Call, PVD, LV)
7072 : Info.CurrentCall->createTemporary(Arg, Arg->
getType(),
7073 ScopeKind::Call, LV);
7079 if (
NonNull &&
V.isLValue() &&
V.isNullPointer()) {
7080 Info.CCEDiag(Arg, diag::note_non_null_attribute_failed);
7093 bool RightToLeft =
false,
7094 LValue *ObjectArg =
nullptr) {
7096 llvm::SmallBitVector ForbiddenNullArgs;
7097 if (Callee->hasAttr<NonNullAttr>()) {
7098 ForbiddenNullArgs.resize(Args.size());
7099 for (
const auto *
Attr : Callee->specific_attrs<NonNullAttr>()) {
7100 if (!
Attr->args_size()) {
7101 ForbiddenNullArgs.set();
7104 for (
auto Idx :
Attr->args()) {
7105 unsigned ASTIdx = Idx.getASTIndex();
7106 if (ASTIdx >= Args.size())
7108 ForbiddenNullArgs[ASTIdx] =
true;
7112 for (
unsigned I = 0; I < Args.size(); I++) {
7113 unsigned Idx = RightToLeft ? Args.size() - I - 1 : I;
7115 Idx < Callee->getNumParams() ? Callee->getParamDecl(Idx) :
nullptr;
7116 bool NonNull = !ForbiddenNullArgs.empty() && ForbiddenNullArgs[Idx];
7121 if (!Info.noteFailure())
7126 ObjectArg->setFrom(Info.Ctx, *That);
7135 bool CopyObjectRepresentation) {
7137 CallStackFrame *Frame = Info.CurrentCall;
7138 APValue *RefValue = Info.getParamSlot(Frame->Arguments, Param);
7146 RefLValue.setFrom(Info.Ctx, *RefValue);
7149 CopyObjectRepresentation);
7155 const LValue *ObjectArg,
const Expr *E,
7157 const Stmt *Body, EvalInfo &Info,
7159 if (!Info.CheckCallLimit(CallLoc))
7172 auto IsTrivialMemoryOperation = [&](
const CXXMethodDecl *MD) {
7182 if (IsTrivialMemoryOperation(MD)) {
7195 ObjectArg->moveInto(
Result);
7204 if (!Info.checkingPotentialConstantExpression())
7206 Frame.LambdaThisCaptureField);
7209 StmtResult Ret = {
Result, ResultSlot};
7211 if (ESR == ESR_Succeeded) {
7212 if (Callee->getReturnType()->isVoidType())
7214 Info.FFDiag(Callee->getEndLoc(), diag::note_constexpr_no_return);
7216 return ESR == ESR_Returned;
7223 bool IsCompleteClass =
true);
7229 bool IsCompleteClass =
true) {
7230 CallScopeRAII CallScope(Info);
7237 CallScope.destroy();
7245 bool IsCompleteClass) {
7248 if (!Info.CheckCallLimit(CallLoc))
7252 if (!Info.getLangOpts().CPlusPlus26 && RD->
getNumVBases()) {
7253 Info.FFDiag(CallLoc, diag::note_constexpr_virtual_base) << RD;
7257 EvalInfo::EvaluatingConstructorRAII EvalObj(
7259 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries},
7266 StmtResult Ret = {RetVal,
nullptr};
7271 if ((*I)->getInit()->isValueDependent()) {
7275 FullExpressionRAII InitScope(Info);
7277 !InitScope.destroy())
7300 if (!
Result.hasValue()) {
7302 unsigned NonVirtualBases = countNonVirtualBases(RD);
7314 BlockScopeRAII LifetimeExtendedScope(Info);
7317 unsigned BasesSeen = 0;
7318 unsigned VirtualBasesSeen = 0;
7319 unsigned NonVirtualBases = countNonVirtualBases(RD);
7322 auto SkipToField = [&](
FieldDecl *FD,
bool Indirect) {
7327 assert(Indirect &&
"fields out of order?");
7333 assert(FieldIt != RD->
field_end() &&
"missing field?");
7334 if (!FieldIt->isUnnamedBitField())
7337 Result.getStructField(FieldIt->getFieldIndex()));
7342 LValue Subobject =
This;
7343 LValue SubobjectParent =
This;
7348 if (I->isBaseInitializer()) {
7349 QualType BaseType(I->getBaseClass(), 0);
7350 if (I->isBaseVirtual()) {
7351 if (
This.pointsToCompleteClass(RD)) {
7353 BaseType->getAsCXXRecordDecl(),
7356 Value = &
Result.getStructVirtualBase(VirtualBasesSeen++);
7363 BaseType->getAsCXXRecordDecl(), &Layout))
7367 }
else if ((FD = I->getMember())) {
7374 SkipToField(FD,
false);
7380 auto IndirectFieldChain = IFD->chain();
7381 for (
auto *
C : IndirectFieldChain) {
7390 (
Value->isUnion() &&
7403 if (
C == IndirectFieldChain.back())
7404 SubobjectParent = Subobject;
7410 if (
C == IndirectFieldChain.front() && !RD->
isUnion())
7411 SkipToField(FD,
true);
7416 llvm_unreachable(
"unknown base initializer kind");
7423 if (
Init->isValueDependent()) {
7427 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &SubobjectParent,
7429 FullExpressionRAII InitScope(Info);
7435 if (!Info.noteFailure())
7444 if (!Info.noteFailure())
7452 if (I->isBaseInitializer() && BasesSeen == NonVirtualBases)
7453 EvalObj.finishedConstructingBases();
7458 for (; FieldIt != RD->
field_end(); ++FieldIt) {
7459 if (!FieldIt->isUnnamedBitField())
7462 Result.getStructField(FieldIt->getFieldIndex()));
7466 EvalObj.finishedConstructingFields();
7470 LifetimeExtendedScope.destroy();
7475 QualType T,
bool IsCompleteClass =
true) {
7480 if (
Value.isAbsent() && !
T->isNullPtrType()) {
7482 This.moveInto(Printable);
7484 diag::note_constexpr_destroy_out_of_lifetime)
7485 << Printable.
getAsString(Info.Ctx, Info.Ctx.getLValueReferenceType(
T));
7501 LValue ElemLV =
This;
7502 ElemLV.addArray(Info, &LocE, CAT);
7509 if (Size && Size >
Value.getArrayInitializedElts())
7514 for (Size =
Value.getArraySize(); Size != 0; --Size) {
7515 APValue &Elem =
Value.getArrayInitializedElt(Size - 1);
7528 if (
T.isDestructedType()) {
7530 diag::note_constexpr_unsupported_destruction)
7539 if (!Info.getLangOpts().CPlusPlus26 && RD->
getNumVBases()) {
7540 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_virtual_base) << RD;
7568 if (!Info.CheckCallLimit(CallRange.
getBegin()))
7577 CallStackFrame Frame(Info, CallRange,
Definition, &
This,
nullptr,
7581 EvalInfo::EvaluatingDestructorRAII EvalObj(
7583 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries});
7584 unsigned NonVirtualBases = countNonVirtualBases(RD);
7586 unsigned BasesLeft = NonVirtualBases;
7587 if (!EvalObj.DidInsert) {
7594 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_double_destroy);
7601 StmtResult Ret = {RetVal,
nullptr};
7614 for (
const FieldDecl *FD : llvm::reverse(Fields)) {
7615 if (FD->isUnnamedBitField())
7618 LValue Subobject =
This;
7622 APValue *SubobjectValue = &
Value.getStructField(FD->getFieldIndex());
7628 if (BasesLeft != 0 || NumVirtualBases != 0)
7629 EvalObj.startedDestroyingBases();
7633 if (
Base.isVirtual())
7638 LValue Subobject =
This;
7640 BaseType->getAsCXXRecordDecl(), &Layout))
7643 APValue *SubobjectValue = &
Value.getStructBase(BasesLeft);
7648 assert(BasesLeft == 0 &&
"NumBases was wrong?");
7651 if (IsCompleteClass) {
7652 unsigned VirtualBasesLeft = NumVirtualBases;
7657 LValue Subobject =
This;
7659 BaseType->getAsCXXRecordDecl(),
7663 APValue *SubobjectValue = &
Value.getStructVirtualBase(VirtualBasesLeft);
7668 assert(VirtualBasesLeft == 0 &&
"NumVirtualBases was wrong?");
7677struct DestroyObjectHandler {
7683 typedef bool result_type;
7684 bool failed() {
return false; }
7685 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
7690 Info.FFDiag(E, diag::note_constexpr_destroy_complex_elem);
7693 bool found(APFloat &
Value, QualType SubobjType) {
7694 Info.FFDiag(E, diag::note_constexpr_destroy_complex_elem);
7715 if (Info.EvalStatus.HasSideEffects)
7726 if (Info.checkingPotentialConstantExpression() ||
7727 Info.SpeculativeEvaluationDepth)
7731 auto Caller = Info.getStdAllocatorCaller(
"allocate");
7733 Info.FFDiag(E->
getExprLoc(), Info.getLangOpts().CPlusPlus20
7734 ? diag::note_constexpr_new_untyped
7735 : diag::note_constexpr_new);
7739 QualType ElemType = Caller.ElemType;
7742 diag::note_constexpr_new_not_complete_object_type)
7750 bool IsNothrow =
false;
7751 for (
unsigned I = 1, N = E->
getNumArgs(); I != N; ++I) {
7759 APInt Size, Remainder;
7760 APInt ElemSizeAP(ByteSize.getBitWidth(), ElemSize.
getQuantity());
7761 APInt::udivrem(ByteSize, ElemSizeAP, Size, Remainder);
7762 if (Remainder != 0) {
7764 Info.FFDiag(E->
getExprLoc(), diag::note_constexpr_operator_new_bad_size)
7765 << ByteSize <<
APSInt(ElemSizeAP,
true) << ElemType;
7769 if (!Info.CheckArraySize(E->
getBeginLoc(), ByteSize.getActiveBits(),
7770 Size.getZExtValue(), !IsNothrow)) {
7778 QualType AllocType = Info.Ctx.getConstantArrayType(
7780 APValue *Val = Info.createHeapAlloc(Caller.Call, AllocType,
Result);
7789 return DD->isVirtual();
7796 return DD->isVirtual() ? DD->getOperatorDelete() :
nullptr;
7807 DynAlloc::Kind DeallocKind) {
7808 auto PointerAsString = [&] {
7809 return Pointer.toString(Info.Ctx, Info.Ctx.VoidPtrTy);
7814 Info.FFDiag(E, diag::note_constexpr_delete_not_heap_alloc)
7815 << PointerAsString();
7818 return std::nullopt;
7821 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
7823 Info.FFDiag(E, diag::note_constexpr_double_delete);
7824 return std::nullopt;
7827 if (DeallocKind != (*Alloc)->getKind()) {
7829 Info.FFDiag(E, diag::note_constexpr_new_delete_mismatch)
7830 << DeallocKind << (*Alloc)->getKind() << AllocType;
7832 return std::nullopt;
7835 bool Subobject =
false;
7836 if (DeallocKind == DynAlloc::New) {
7837 Subobject =
Pointer.Designator.MostDerivedPathLength != 0 ||
7838 Pointer.Designator.isOnePastTheEnd();
7840 Subobject =
Pointer.Designator.Entries.size() != 1 ||
7841 Pointer.Designator.Entries[0].getAsArrayIndex() != 0;
7844 Info.FFDiag(E, diag::note_constexpr_delete_subobject)
7845 << PointerAsString() <<
Pointer.Designator.isOnePastTheEnd();
7846 return std::nullopt;
7854 if (Info.checkingPotentialConstantExpression() ||
7855 Info.SpeculativeEvaluationDepth)
7859 if (!Info.getStdAllocatorCaller(
"deallocate")) {
7867 for (
unsigned I = 1, N = E->
getNumArgs(); I != N; ++I)
7870 if (
Pointer.Designator.Invalid)
7875 if (
Pointer.isNullPointer()) {
7876 Info.CCEDiag(E->
getExprLoc(), diag::note_constexpr_deallocate_null);
7892class BitCastBuffer {
7898 SmallVector<std::optional<unsigned char>, 32> Bytes;
7900 static_assert(std::numeric_limits<unsigned char>::digits >= 8,
7901 "Need at least 8 bit unsigned char");
7903 bool TargetIsLittleEndian;
7906 BitCastBuffer(CharUnits Width,
bool TargetIsLittleEndian)
7907 : Bytes(Width.getQuantity()),
7908 TargetIsLittleEndian(TargetIsLittleEndian) {}
7910 [[nodiscard]]
bool readObject(CharUnits Offset, CharUnits Width,
7911 SmallVectorImpl<unsigned char> &Output)
const {
7912 for (CharUnits I = Offset, E = Offset + Width; I != E; ++I) {
7915 if (!Bytes[I.getQuantity()])
7917 Output.push_back(*Bytes[I.getQuantity()]);
7919 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
7920 std::reverse(Output.begin(), Output.end());
7924 void writeObject(CharUnits Offset, SmallVectorImpl<unsigned char> &Input) {
7925 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
7926 std::reverse(Input.begin(), Input.end());
7929 for (
unsigned char Byte : Input) {
7930 assert(!Bytes[Offset.
getQuantity() + Index] &&
"overwriting a byte?");
7936 size_t size() {
return Bytes.size(); }
7941class APValueToBufferConverter {
7943 BitCastBuffer Buffer;
7946 APValueToBufferConverter(EvalInfo &Info, CharUnits ObjectWidth,
7949 Buffer(ObjectWidth, Info.Ctx.getTargetInfo().isLittleEndian()),
7952 bool visit(
const APValue &Val, QualType Ty) {
7957 bool visit(
const APValue &Val, QualType Ty, CharUnits Offset) {
7958 assert((
size_t)Offset.
getQuantity() <= Buffer.size());
7971 return visitInt(Val.
getInt(), Ty, Offset);
7973 return visitFloat(Val.
getFloat(), Ty, Offset);
7975 return visitArray(Val, Ty, Offset);
7977 return visitRecord(Val, Ty, Offset);
7979 return visitVector(Val, Ty, Offset);
7983 return visitComplex(Val, Ty, Offset);
7993 diag::note_constexpr_bit_cast_unsupported_type)
7998 llvm_unreachable(
"Unhandled APValue::ValueKind");
8001 bool visitRecord(
const APValue &Val, QualType Ty, CharUnits Offset) {
8003 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD);
8006 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
8007 for (
size_t I = 0, E = CXXRD->getNumBases(); I != E; ++I) {
8008 const CXXBaseSpecifier &BS = CXXRD->bases_begin()[I];
8013 if (!
Base.isStruct())
8016 if (!visitRecord(Base, BS.
getType(),
8023 unsigned FieldIdx = 0;
8024 for (FieldDecl *FD : RD->
fields()) {
8025 if (FD->isBitField()) {
8027 diag::note_constexpr_bit_cast_unsupported_bitfield);
8033 assert(FieldOffsetBits % Info.Ctx.getCharWidth() == 0 &&
8034 "only bit-fields can have sub-char alignment");
8035 CharUnits FieldOffset =
8036 Info.Ctx.toCharUnitsFromBits(FieldOffsetBits) + Offset;
8037 QualType FieldTy = FD->getType();
8046 bool visitArray(
const APValue &Val, QualType Ty, CharUnits Offset) {
8052 CharUnits ElemWidth = Info.Ctx.getTypeSizeInChars(CAT->
getElementType());
8056 for (
unsigned I = 0; I != NumInitializedElts; ++I) {
8058 if (!visit(SubObj, CAT->
getElementType(), Offset + I * ElemWidth))
8065 for (
unsigned I = NumInitializedElts; I != ArraySize; ++I) {
8066 if (!visit(Filler, CAT->
getElementType(), Offset + I * ElemWidth))
8074 bool visitComplex(
const APValue &Val, QualType Ty, CharUnits Offset) {
8075 const ComplexType *ComplexTy = Ty->
castAs<ComplexType>();
8077 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
8082 Offset + (0 * EltSizeChars)))
8085 Offset + (1 * EltSizeChars)))
8089 Offset + (0 * EltSizeChars)))
8092 Offset + (1 * EltSizeChars)))
8099 bool visitVector(
const APValue &Val, QualType Ty, CharUnits Offset) {
8100 const VectorType *VTy = Ty->
castAs<VectorType>();
8113 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
8115 llvm::APInt Res = llvm::APInt::getZero(NElts);
8116 for (
unsigned I = 0; I < NElts; ++I) {
8118 assert(EltAsInt.isUnsigned() && EltAsInt.getBitWidth() == 1 &&
8119 "bool vector element must be 1-bit unsigned integer!");
8121 Res.insertBits(EltAsInt, BigEndian ? (NElts - I - 1) : I);
8124 SmallVector<uint8_t, 8> Bytes(NElts / 8);
8125 llvm::StoreIntToMemory(Res, &*Bytes.begin(), NElts / 8);
8126 Buffer.writeObject(Offset, Bytes);
8130 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
8131 for (
unsigned I = 0; I < NElts; ++I) {
8132 if (!visit(Val.
getVectorElt(I), EltTy, Offset + I * EltSizeChars))
8140 bool visitInt(
const APSInt &Val, QualType Ty, CharUnits Offset) {
8141 APSInt AdjustedVal = Val;
8142 unsigned Width = AdjustedVal.getBitWidth();
8144 Width = Info.Ctx.getTypeSize(Ty);
8145 AdjustedVal = AdjustedVal.extend(Width);
8148 SmallVector<uint8_t, 8> Bytes(Width / 8);
8149 llvm::StoreIntToMemory(AdjustedVal, &*Bytes.begin(), Width / 8);
8150 Buffer.writeObject(Offset, Bytes);
8154 bool visitFloat(
const APFloat &Val, QualType Ty, CharUnits Offset) {
8155 APSInt AsInt(Val.bitcastToAPInt());
8156 return visitInt(AsInt, Ty, Offset);
8160 static std::optional<BitCastBuffer>
8162 CharUnits DstSize = Info.Ctx.getTypeSizeInChars(BCE->
getType());
8163 APValueToBufferConverter Converter(Info, DstSize, BCE);
8165 return std::nullopt;
8166 return Converter.Buffer;
8171class BufferToAPValueConverter {
8173 const BitCastBuffer &Buffer;
8176 BufferToAPValueConverter(EvalInfo &Info,
const BitCastBuffer &Buffer,
8178 : Info(Info), Buffer(Buffer), BCE(BCE) {}
8183 std::nullopt_t unsupportedType(QualType Ty) {
8185 diag::note_constexpr_bit_cast_unsupported_type)
8187 return std::nullopt;
8190 std::nullopt_t unrepresentableValue(QualType Ty,
const APSInt &Val) {
8192 diag::note_constexpr_bit_cast_unrepresentable_value)
8194 return std::nullopt;
8197 std::optional<APValue> visit(
const BuiltinType *
T, CharUnits Offset,
8198 const EnumType *EnumSugar =
nullptr) {
8200 uint64_t NullValue = Info.Ctx.getTargetNullPointerValue(QualType(
T, 0));
8201 return APValue((Expr *)
nullptr,
8203 APValue::NoLValuePath{},
true);
8206 CharUnits
SizeOf = Info.Ctx.getTypeSizeInChars(
T);
8212 const llvm::fltSemantics &Semantics =
8213 Info.Ctx.getFloatTypeSemantics(QualType(
T, 0));
8214 unsigned NumBits = llvm::APFloatBase::getSizeInBits(Semantics);
8215 assert(NumBits % 8 == 0);
8221 SmallVector<uint8_t, 8> Bytes;
8222 if (!Buffer.readObject(Offset,
SizeOf, Bytes)) {
8225 bool IsStdByte = EnumSugar && EnumSugar->isStdByteType();
8229 if (!IsStdByte && !IsUChar) {
8230 QualType DisplayType(EnumSugar ? (
const Type *)EnumSugar :
T, 0);
8232 diag::note_constexpr_bit_cast_indet_dest)
8233 << DisplayType << Info.Ctx.getLangOpts().CharIsSigned;
8234 return std::nullopt;
8240 APSInt Val(
SizeOf.getQuantity() * Info.Ctx.getCharWidth(),
true);
8241 llvm::LoadIntFromMemory(Val, &*Bytes.begin(), Bytes.size());
8246 unsigned IntWidth = Info.Ctx.getIntWidth(QualType(
T, 0));
8247 if (IntWidth != Val.getBitWidth()) {
8248 APSInt Truncated = Val.trunc(IntWidth);
8249 if (Truncated.extend(Val.getBitWidth()) != Val)
8250 return unrepresentableValue(QualType(
T, 0), Val);
8258 const llvm::fltSemantics &Semantics =
8259 Info.Ctx.getFloatTypeSemantics(QualType(
T, 0));
8263 return unsupportedType(QualType(
T, 0));
8266 std::optional<APValue> visit(
const RecordType *RTy, CharUnits Offset) {
8267 const RecordDecl *RD = RTy->getAsRecordDecl();
8269 return std::nullopt;
8270 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD);
8272 unsigned NumBases = 0;
8273 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
8274 NumBases = CXXRD->getNumBases();
8279 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
8280 for (
size_t I = 0, E = CXXRD->getNumBases(); I != E; ++I) {
8281 const CXXBaseSpecifier &BS = CXXRD->bases_begin()[I];
8284 std::optional<APValue> SubObj = visitType(
8287 return std::nullopt;
8288 ResultVal.getStructBase(I) = *SubObj;
8293 unsigned FieldIdx = 0;
8294 for (FieldDecl *FD : RD->
fields()) {
8297 if (FD->isBitField()) {
8299 diag::note_constexpr_bit_cast_unsupported_bitfield);
8300 return std::nullopt;
8304 assert(FieldOffsetBits % Info.Ctx.getCharWidth() == 0);
8306 CharUnits FieldOffset =
8309 QualType FieldTy = FD->getType();
8310 std::optional<APValue> SubObj = visitType(FieldTy, FieldOffset);
8312 return std::nullopt;
8313 ResultVal.getStructField(FieldIdx) = *SubObj;
8320 std::optional<APValue> visit(
const EnumType *Ty, CharUnits Offset) {
8321 QualType RepresentationType =
8322 Ty->getDecl()->getDefinitionOrSelf()->getIntegerType();
8323 assert(!RepresentationType.
isNull() &&
8324 "enum forward decl should be caught by Sema");
8325 const auto *AsBuiltin =
8329 return visit(AsBuiltin, Offset, Ty);
8332 std::optional<APValue> visit(
const ConstantArrayType *Ty, CharUnits Offset) {
8334 CharUnits ElementWidth = Info.Ctx.getTypeSizeInChars(Ty->
getElementType());
8336 APValue ArrayValue(APValue::UninitArray(), Size, Size);
8337 for (
size_t I = 0; I !=
Size; ++I) {
8338 std::optional<APValue> ElementValue =
8341 return std::nullopt;
8342 ArrayValue.getArrayInitializedElt(I) = std::move(*ElementValue);
8348 std::optional<APValue> visit(
const ComplexType *Ty, CharUnits Offset) {
8350 CharUnits ElementWidth = Info.Ctx.getTypeSizeInChars(ElementType);
8353 std::optional<APValue> Values[2];
8354 for (
unsigned I = 0; I != 2; ++I) {
8355 Values[I] = visitType(Ty->
getElementType(), Offset + I * ElementWidth);
8357 return std::nullopt;
8361 return APValue(Values[0]->getInt(), Values[1]->getInt());
8362 return APValue(Values[0]->getFloat(), Values[1]->getFloat());
8365 std::optional<APValue> visit(
const VectorType *VTy, CharUnits Offset) {
8371 SmallVector<APValue, 4> Elts;
8372 Elts.reserve(NElts);
8382 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
8384 SmallVector<uint8_t, 8> Bytes;
8385 Bytes.reserve(NElts / 8);
8387 return std::nullopt;
8389 APSInt SValInt(NElts,
true);
8390 llvm::LoadIntFromMemory(SValInt, &*Bytes.begin(), Bytes.size());
8392 for (
unsigned I = 0; I < NElts; ++I) {
8394 SValInt.extractBits(1, (BigEndian ? NElts - I - 1 : I) * EltSize);
8401 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
8402 for (
unsigned I = 0; I < NElts; ++I) {
8403 std::optional<APValue> EltValue =
8404 visitType(EltTy, Offset + I * EltSizeChars);
8406 return std::nullopt;
8407 Elts.push_back(std::move(*EltValue));
8411 return APValue(Elts.data(), Elts.size());
8414 std::optional<APValue> visit(
const Type *Ty, CharUnits Offset) {
8415 return unsupportedType(QualType(Ty, 0));
8418 std::optional<APValue> visitType(QualType Ty, CharUnits Offset) {
8422#define TYPE(Class, Base) \
8424 return visit(cast<Class##Type>(Can.getTypePtr()), Offset);
8425#define ABSTRACT_TYPE(Class, Base)
8426#define NON_CANONICAL_TYPE(Class, Base) \
8428 llvm_unreachable("non-canonical type should be impossible!");
8429#define DEPENDENT_TYPE(Class, Base) \
8432 "dependent types aren't supported in the constant evaluator!");
8433#define NON_CANONICAL_UNLESS_DEPENDENT(Class, Base) \
8435 llvm_unreachable("either dependent or not canonical!");
8436#include "clang/AST/TypeNodes.inc"
8438 llvm_unreachable(
"Unhandled Type::TypeClass");
8443 static std::optional<APValue> convert(EvalInfo &Info, BitCastBuffer &Buffer,
8445 BufferToAPValueConverter Converter(Info, Buffer, BCE);
8450static bool checkBitCastConstexprEligibilityType(SourceLocation Loc,
8451 QualType Ty, EvalInfo *Info,
8452 const ASTContext &Ctx,
8453 bool CheckingDest) {
8456 auto diag = [&](
int Reason) {
8458 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_invalid_type)
8459 << CheckingDest << (Reason == 4) << Reason;
8462 auto note = [&](
int Construct, QualType NoteTy, SourceLocation NoteLoc) {
8464 Info->Note(NoteLoc, diag::note_constexpr_bit_cast_invalid_subtype)
8465 << NoteTy << Construct << Ty;
8479 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(
Record)) {
8480 for (CXXBaseSpecifier &BS : CXXRD->bases())
8481 if (!checkBitCastConstexprEligibilityType(Loc, BS.
getType(), Info, Ctx,
8485 for (FieldDecl *FD :
Record->fields()) {
8486 if (FD->getType()->isReferenceType())
8488 if (!checkBitCastConstexprEligibilityType(Loc, FD->getType(), Info, Ctx,
8490 return note(0, FD->getType(), FD->getBeginLoc());
8496 Info, Ctx, CheckingDest))
8499 if (
const auto *VTy = Ty->
getAs<VectorType>()) {
8511 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_invalid_vector)
8512 << QualType(VTy, 0) << EltSize << NElts << Ctx.
getCharWidth();
8522 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_unsupported_type)
8531static bool checkBitCastConstexprEligibility(EvalInfo *Info,
8532 const ASTContext &Ctx,
8534 bool DestOK = checkBitCastConstexprEligibilityType(
8536 bool SourceOK = DestOK && checkBitCastConstexprEligibilityType(
8542static bool handleRValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
8545 assert(
CHAR_BIT == 8 && Info.Ctx.getTargetInfo().getCharWidth() == 8 &&
8546 "no host or target supports non 8-bit chars");
8548 if (!checkBitCastConstexprEligibility(&Info, Info.Ctx, BCE))
8552 std::optional<BitCastBuffer> Buffer =
8553 APValueToBufferConverter::convert(Info, SourceRValue, BCE);
8558 std::optional<APValue> MaybeDestValue =
8559 BufferToAPValueConverter::convert(Info, *Buffer, BCE);
8560 if (!MaybeDestValue)
8563 DestValue = std::move(*MaybeDestValue);
8567static bool handleLValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
8570 assert(
CHAR_BIT == 8 && Info.Ctx.getTargetInfo().getCharWidth() == 8 &&
8571 "no host or target supports non 8-bit chars");
8573 "LValueToRValueBitcast requires an lvalue operand!");
8575 LValue SourceLValue;
8577 SourceLValue.setFrom(Info.Ctx, SourceValue);
8580 SourceRValue,
true))
8583 return handleRValueToRValueBitCast(Info, DestValue, SourceRValue, BCE);
8586template <
class Derived>
8587class ExprEvaluatorBase
8588 :
public ConstStmtVisitor<Derived, bool> {
8590 Derived &getDerived() {
return static_cast<Derived&
>(*this); }
8591 bool DerivedSuccess(
const APValue &
V,
const Expr *E) {
8592 return getDerived().Success(
V, E);
8594 bool DerivedZeroInitialization(
const Expr *E) {
8595 return getDerived().ZeroInitialization(E);
8601 template<
typename ConditionalOperator>
8602 void CheckPotentialConstantConditional(
const ConditionalOperator *E) {
8603 assert(Info.checkingPotentialConstantExpression());
8606 SmallVector<PartialDiagnosticAt, 8>
Diag;
8608 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
8615 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
8617 Info.EvalStatus.DiagEmitted =
false;
8623 Error(E, diag::note_constexpr_conditional_never_const);
8627 template<
typename ConditionalOperator>
8628 bool HandleConditionalOperator(
const ConditionalOperator *E) {
8631 if (Info.checkingPotentialConstantExpression() && Info.noteFailure()) {
8632 CheckPotentialConstantConditional(E);
8635 if (Info.noteFailure()) {
8643 return StmtVisitorTy::Visit(EvalExpr);
8648 typedef ConstStmtVisitor<Derived, bool> StmtVisitorTy;
8649 typedef ExprEvaluatorBase ExprEvaluatorBaseTy;
8651 OptionalDiagnostic CCEDiag(
const Expr *E,
diag::kind D) {
8652 return Info.CCEDiag(E, D);
8655 bool ZeroInitialization(
const Expr *E) {
return Error(E); }
8657 bool IsConstantEvaluatedBuiltinCall(
const CallExpr *E) {
8659 return BuiltinOp != 0 &&
8660 Info.Ctx.BuiltinInfo.isConstantEvaluated(BuiltinOp);
8664 ExprEvaluatorBase(EvalInfo &Info) : Info(Info) {}
8666 EvalInfo &getEvalInfo() {
return Info; }
8674 bool Error(
const Expr *E) {
8675 return Error(E, diag::note_invalid_subexpr_in_const_expr);
8678 bool VisitStmt(
const Stmt *) {
8679 llvm_unreachable(
"Expression evaluator should not be called on stmts");
8681 bool VisitExpr(
const Expr *E) {
8685 bool VisitEmbedExpr(
const EmbedExpr *E) {
8686 const auto It = E->
begin();
8687 return StmtVisitorTy::Visit(*It);
8690 bool VisitPredefinedExpr(
const PredefinedExpr *E) {
8693 bool VisitConstantExpr(
const ConstantExpr *E) {
8697 return StmtVisitorTy::Visit(E->
getSubExpr());
8700 bool VisitParenExpr(
const ParenExpr *E)
8701 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8702 bool VisitUnaryExtension(
const UnaryOperator *E)
8703 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8704 bool VisitUnaryPlus(
const UnaryOperator *E)
8705 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8706 bool VisitChooseExpr(
const ChooseExpr *E)
8708 bool VisitGenericSelectionExpr(
const GenericSelectionExpr *E)
8710 bool VisitSubstNonTypeTemplateParmExpr(
const SubstNonTypeTemplateParmExpr *E)
8712 bool VisitCXXDefaultArgExpr(
const CXXDefaultArgExpr *E) {
8713 TempVersionRAII RAII(*Info.CurrentCall);
8714 SourceLocExprScopeGuard Guard(E, Info.CurrentCall->CurSourceLocExprScope);
8715 return StmtVisitorTy::Visit(E->
getExpr());
8717 bool VisitCXXDefaultInitExpr(
const CXXDefaultInitExpr *E) {
8718 TempVersionRAII RAII(*Info.CurrentCall);
8722 SourceLocExprScopeGuard Guard(E, Info.CurrentCall->CurSourceLocExprScope);
8723 return StmtVisitorTy::Visit(E->
getExpr());
8726 bool VisitExprWithCleanups(
const ExprWithCleanups *E) {
8727 FullExpressionRAII Scope(Info);
8728 return StmtVisitorTy::Visit(E->
getSubExpr()) && Scope.destroy();
8733 bool VisitCXXBindTemporaryExpr(
const CXXBindTemporaryExpr *E) {
8734 return StmtVisitorTy::Visit(E->
getSubExpr());
8737 bool VisitCXXReinterpretCastExpr(
const CXXReinterpretCastExpr *E) {
8738 CCEDiag(E, diag::note_constexpr_invalid_cast)
8739 << diag::ConstexprInvalidCastKind::Reinterpret;
8740 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8742 bool VisitCXXDynamicCastExpr(
const CXXDynamicCastExpr *E) {
8743 if (!Info.Ctx.getLangOpts().CPlusPlus20)
8744 CCEDiag(E, diag::note_constexpr_invalid_cast)
8745 << diag::ConstexprInvalidCastKind::Dynamic;
8746 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8748 bool VisitBuiltinBitCastExpr(
const BuiltinBitCastExpr *E) {
8749 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8752 bool VisitBinaryOperator(
const BinaryOperator *E) {
8758 VisitIgnoredValue(E->
getLHS());
8759 return StmtVisitorTy::Visit(E->
getRHS());
8769 return DerivedSuccess(
Result, E);
8774 bool VisitCXXRewrittenBinaryOperator(
const CXXRewrittenBinaryOperator *E) {
8778 bool VisitBinaryConditionalOperator(
const BinaryConditionalOperator *E) {
8782 if (!
Evaluate(Info.CurrentCall->createTemporary(
8785 ScopeKind::FullExpression, CommonLV),
8789 return HandleConditionalOperator(E);
8792 bool VisitConditionalOperator(
const ConditionalOperator *E) {
8793 bool IsBcpCall =
false;
8798 if (
const CallExpr *CallCE =
8800 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
8807 if (Info.checkingPotentialConstantExpression() && IsBcpCall)
8810 FoldConstant Fold(Info, IsBcpCall);
8811 if (!HandleConditionalOperator(E)) {
8812 Fold.keepDiagnostics();
8819 bool VisitOpaqueValueExpr(
const OpaqueValueExpr *E) {
8820 if (
APValue *
Value = Info.CurrentCall->getCurrentTemporary(E);
8822 return DerivedSuccess(*
Value, E);
8828 assert(0 &&
"OpaqueValueExpr recursively refers to itself");
8831 return StmtVisitorTy::Visit(Source);
8834 bool VisitPseudoObjectExpr(
const PseudoObjectExpr *E) {
8835 for (
const Expr *SemE : E->
semantics()) {
8836 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
8845 if (OVE->isUnique())
8849 if (!
Evaluate(Info.CurrentCall->createTemporary(
8850 OVE, getStorageType(Info.Ctx, OVE),
8851 ScopeKind::FullExpression, LV),
8852 Info, OVE->getSourceExpr()))
8855 if (!StmtVisitorTy::Visit(SemE))
8865 bool VisitCallExpr(
const CallExpr *E) {
8867 if (!handleCallExpr(E,
Result,
nullptr))
8869 return DerivedSuccess(
Result, E);
8873 const LValue *ResultSlot) {
8874 CallScopeRAII CallScope(Info);
8877 QualType CalleeType =
Callee->getType();
8879 const FunctionDecl *FD =
nullptr;
8880 LValue *
This =
nullptr, ObjectArg;
8882 bool HasQualifier =
false;
8888 const CXXMethodDecl *
Member =
nullptr;
8889 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(Callee)) {
8893 Member = dyn_cast<CXXMethodDecl>(ME->getMemberDecl());
8895 return Error(Callee);
8897 HasQualifier = ME->hasQualifier();
8898 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(Callee)) {
8900 const ValueDecl *D =
8904 Member = dyn_cast<CXXMethodDecl>(D);
8906 return Error(Callee);
8908 }
else if (
const auto *PDE = dyn_cast<CXXPseudoDestructorExpr>(Callee)) {
8909 if (!Info.getLangOpts().CPlusPlus20)
8910 Info.CCEDiag(PDE, diag::note_constexpr_pseudo_destructor);
8914 return Error(Callee);
8921 if (!CalleeLV.getLValueOffset().isZero())
8922 return Error(Callee);
8923 if (CalleeLV.isNullPointer()) {
8924 Info.FFDiag(Callee, diag::note_constexpr_null_callee)
8925 <<
const_cast<Expr *
>(
Callee);
8928 FD = dyn_cast_or_null<FunctionDecl>(
8929 CalleeLV.getLValueBase().dyn_cast<
const ValueDecl *>());
8931 return Error(Callee);
8934 if (!Info.Ctx.hasSameFunctionTypeIgnoringExceptionSpec(
8941 auto *OCE = dyn_cast<CXXOperatorCallExpr>(E);
8942 if (OCE && OCE->isAssignmentOp()) {
8943 assert(Args.size() == 2 &&
"wrong number of arguments in assignment");
8944 Call = Info.CurrentCall->createCall(FD);
8945 bool HasThis =
false;
8946 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FD))
8947 HasThis = MD->isImplicitObjectMemberFunction();
8955 const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD);
8975 if (Info.getLangOpts().CPlusPlus20 && OCE &&
8976 OCE->getOperator() == OO_Equal && MD->
isTrivial() &&
8980 Args = Args.slice(1);
8986 const CXXRecordDecl *ClosureClass = MD->
getParent();
8988 ClosureClass->
captures().empty() &&
8989 "Number of captures must be zero for conversion to function-ptr");
8991 const CXXMethodDecl *LambdaCallOp =
9000 "A generic lambda's static-invoker function must be a "
9001 "template specialization");
9003 FunctionTemplateDecl *CallOpTemplate =
9005 void *InsertPos =
nullptr;
9006 FunctionDecl *CorrespondingCallOpSpecialization =
9008 assert(CorrespondingCallOpSpecialization &&
9009 "We must always have a function call operator specialization "
9010 "that corresponds to our static invoker specialization");
9012 FD = CorrespondingCallOpSpecialization;
9021 return CallScope.destroy();
9031 Call = Info.CurrentCall->createCall(FD);
9037 SmallVector<QualType, 4> CovariantAdjustmentPath;
9039 auto *NamedMember = dyn_cast<CXXMethodDecl>(FD);
9040 if (NamedMember && NamedMember->isVirtual() && !HasQualifier) {
9043 CovariantAdjustmentPath);
9046 }
else if (NamedMember && NamedMember->isImplicitObjectMemberFunction()) {
9056 if (
auto *DD = dyn_cast<CXXDestructorDecl>(FD)) {
9057 assert(This &&
"no 'this' pointer for destructor call");
9059 Info.Ctx.getCanonicalTagType(DD->getParent())) &&
9060 CallScope.destroy();
9077 if (!CovariantAdjustmentPath.empty() &&
9079 CovariantAdjustmentPath))
9082 return CallScope.destroy();
9085 bool VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E) {
9088 bool VisitInitListExpr(
const InitListExpr *E) {
9090 return DerivedZeroInitialization(E);
9092 return StmtVisitorTy::Visit(E->
getInit(0));
9095 bool VisitImplicitValueInitExpr(
const ImplicitValueInitExpr *E) {
9096 return DerivedZeroInitialization(E);
9098 bool VisitCXXScalarValueInitExpr(
const CXXScalarValueInitExpr *E) {
9099 return DerivedZeroInitialization(E);
9101 bool VisitCXXNullPtrLiteralExpr(
const CXXNullPtrLiteralExpr *E) {
9102 return DerivedZeroInitialization(E);
9106 bool VisitMemberExpr(
const MemberExpr *E) {
9107 assert(!Info.Ctx.getLangOpts().CPlusPlus11 &&
9108 "missing temporary materialization conversion");
9109 assert(!E->
isArrow() &&
"missing call to bound member function?");
9117 const FieldDecl *FD = dyn_cast<FieldDecl>(E->
getMemberDecl());
9118 if (!FD)
return Error(E);
9122 "record / field mismatch");
9127 CompleteObject Obj(APValue::LValueBase(), &Val, BaseTy);
9128 SubobjectDesignator Designator(BaseTy);
9129 Designator.addDeclUnchecked(FD);
9133 DerivedSuccess(
Result, E);
9136 bool VisitExtVectorElementExpr(
const ExtVectorElementExpr *E) {
9142 SmallVector<uint32_t, 4> Indices;
9144 if (Indices.size() == 1) {
9146 return DerivedSuccess(Val.
getVectorElt(Indices[0]), E);
9149 SmallVector<APValue, 4> Elts;
9150 for (
unsigned I = 0; I < Indices.size(); ++I) {
9153 APValue VecResult(Elts.data(), Indices.size());
9154 return DerivedSuccess(VecResult, E);
9161 bool VisitCastExpr(
const CastExpr *E) {
9166 case CK_AtomicToNonAtomic: {
9173 return DerivedSuccess(AtomicVal, E);
9177 case CK_UserDefinedConversion:
9178 return StmtVisitorTy::Visit(E->
getSubExpr());
9180 case CK_HLSLArrayRValue: {
9186 return DerivedSuccess(Val, E);
9197 return DerivedSuccess(RVal, E);
9199 case CK_LValueToRValue: {
9208 return DerivedSuccess(RVal, E);
9210 case CK_LValueToRValueBitCast: {
9211 APValue DestValue, SourceValue;
9214 if (!handleLValueToRValueBitCast(Info, DestValue, SourceValue, E))
9216 return DerivedSuccess(DestValue, E);
9219 case CK_AddressSpaceConversion: {
9223 return DerivedSuccess(
Value, E);
9230 bool VisitUnaryPostInc(
const UnaryOperator *UO) {
9231 return VisitUnaryPostIncDec(UO);
9233 bool VisitUnaryPostDec(
const UnaryOperator *UO) {
9234 return VisitUnaryPostIncDec(UO);
9236 bool VisitUnaryPostIncDec(
const UnaryOperator *UO) {
9237 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9247 return DerivedSuccess(RVal, UO);
9250 bool VisitStmtExpr(
const StmtExpr *E) {
9253 llvm::SaveAndRestore NotCheckingForUB(Info.CheckingForUndefinedBehavior,
9260 BlockScopeRAII Scope(Info);
9265 const Expr *FinalExpr = dyn_cast<Expr>(*BI);
9267 Info.FFDiag((*BI)->getBeginLoc(),
9268 diag::note_constexpr_stmt_expr_unsupported);
9271 return this->Visit(FinalExpr) && Scope.destroy();
9277 if (ESR != ESR_Succeeded) {
9281 if (ESR != ESR_Failed)
9282 Info.FFDiag((*BI)->getBeginLoc(),
9283 diag::note_constexpr_stmt_expr_unsupported);
9288 llvm_unreachable(
"Return from function from the loop above.");
9291 bool VisitPackIndexingExpr(
const PackIndexingExpr *E) {
9296 void VisitIgnoredValue(
const Expr *E) {
9301 void VisitIgnoredBaseExpression(
const Expr *E) {
9304 if (Info.getLangOpts().MSVCCompat && !E->
HasSideEffects(Info.Ctx))
9306 VisitIgnoredValue(E);
9316template<
class Derived>
9317class LValueExprEvaluatorBase
9318 :
public ExprEvaluatorBase<Derived> {
9322 typedef LValueExprEvaluatorBase LValueExprEvaluatorBaseTy;
9323 typedef ExprEvaluatorBase<Derived> ExprEvaluatorBaseTy;
9325 bool Success(APValue::LValueBase B) {
9330 bool evaluatePointer(
const Expr *E, LValue &
Result) {
9335 LValueExprEvaluatorBase(EvalInfo &Info, LValue &
Result,
bool InvalidBaseOK)
9337 InvalidBaseOK(InvalidBaseOK) {}
9340 Result.setFrom(this->Info.Ctx,
V);
9344 bool VisitMemberExpr(
const MemberExpr *E) {
9356 EvalOK = this->Visit(E->
getBase());
9367 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(E->
getMemberDecl())) {
9370 "record / field mismatch");
9374 }
else if (
const IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(MD)) {
9378 return this->
Error(E);
9390 bool VisitBinaryOperator(
const BinaryOperator *E) {
9393 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
9401 bool VisitCastExpr(
const CastExpr *E) {
9404 return ExprEvaluatorBaseTy::VisitCastExpr(E);
9406 case CK_DerivedToBase:
9407 case CK_UncheckedDerivedToBase:
9454class LValueExprEvaluator
9455 :
public LValueExprEvaluatorBase<LValueExprEvaluator> {
9457 LValueExprEvaluator(EvalInfo &Info, LValue &
Result,
bool InvalidBaseOK) :
9458 LValueExprEvaluatorBaseTy(Info,
Result, InvalidBaseOK) {}
9460 bool VisitVarDecl(
const Expr *E,
const VarDecl *VD);
9461 bool VisitUnaryPreIncDec(
const UnaryOperator *UO);
9463 bool VisitCallExpr(
const CallExpr *E);
9464 bool VisitDeclRefExpr(
const DeclRefExpr *E);
9465 bool VisitPredefinedExpr(
const PredefinedExpr *E) {
return Success(E); }
9466 bool VisitMaterializeTemporaryExpr(
const MaterializeTemporaryExpr *E);
9467 bool VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E);
9468 bool VisitMemberExpr(
const MemberExpr *E);
9469 bool VisitStringLiteral(
const StringLiteral *E) {
9471 APValue::LValueBase(E, 0, Info.Ctx.getNextStringLiteralVersion()));
9473 bool VisitObjCEncodeExpr(
const ObjCEncodeExpr *E) {
return Success(E); }
9474 bool VisitCXXTypeidExpr(
const CXXTypeidExpr *E);
9475 bool VisitCXXUuidofExpr(
const CXXUuidofExpr *E);
9476 bool VisitArraySubscriptExpr(
const ArraySubscriptExpr *E);
9477 bool VisitExtVectorElementExpr(
const ExtVectorElementExpr *E);
9478 bool VisitUnaryDeref(
const UnaryOperator *E);
9479 bool VisitUnaryReal(
const UnaryOperator *E);
9480 bool VisitUnaryImag(
const UnaryOperator *E);
9481 bool VisitUnaryPreInc(
const UnaryOperator *UO) {
9482 return VisitUnaryPreIncDec(UO);
9484 bool VisitUnaryPreDec(
const UnaryOperator *UO) {
9485 return VisitUnaryPreIncDec(UO);
9487 bool VisitBinAssign(
const BinaryOperator *BO);
9488 bool VisitCompoundAssignOperator(
const CompoundAssignOperator *CAO);
9490 bool VisitCastExpr(
const CastExpr *E) {
9493 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
9495 case CK_LValueBitCast:
9496 this->CCEDiag(E, diag::note_constexpr_invalid_cast)
9497 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
9501 Result.Designator.setInvalid();
9504 case CK_BaseToDerived:
9521 bool LValueToRValueConversion) {
9525 assert(Info.CurrentCall->This ==
nullptr &&
9526 "This should not be set for a static call operator");
9534 if (
Self->getType()->isReferenceType()) {
9535 APValue *RefValue = Info.getParamSlot(Info.CurrentCall->Arguments,
Self);
9537 Result.setFrom(Info.Ctx, *RefValue);
9539 const ParmVarDecl *VD = Info.CurrentCall->Arguments.getOrigParam(
Self);
9540 CallStackFrame *Frame =
9541 Info.getCallFrameAndDepth(Info.CurrentCall->Arguments.CallIndex)
9543 unsigned Version = Info.CurrentCall->Arguments.Version;
9544 Result.set({VD, Frame->Index, Version});
9547 Result = *Info.CurrentCall->This;
9557 if (LValueToRValueConversion) {
9561 Result.setFrom(Info.Ctx, RVal);
9572 bool InvalidBaseOK) {
9576 return LValueExprEvaluator(Info,
Result, InvalidBaseOK).Visit(E);
9579bool LValueExprEvaluator::VisitDeclRefExpr(
const DeclRefExpr *E) {
9580 const ValueDecl *D = E->
getDecl();
9592 if (Info.checkingPotentialConstantExpression())
9595 if (
auto *FD = Info.CurrentCall->LambdaCaptureFields.lookup(D)) {
9602 if (
isa<FunctionDecl, MSGuidDecl, TemplateParamObjectDecl,
9603 UnnamedGlobalConstantDecl>(D))
9605 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
9606 return VisitVarDecl(E, VD);
9607 if (
const BindingDecl *BD = dyn_cast<BindingDecl>(D))
9608 return Visit(BD->getBinding());
9612bool LValueExprEvaluator::VisitVarDecl(
const Expr *E,
const VarDecl *VD) {
9613 CallStackFrame *Frame =
nullptr;
9614 unsigned Version = 0;
9622 CallStackFrame *CurrFrame = Info.CurrentCall;
9627 if (
auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
9628 if (CurrFrame->Arguments) {
9629 VD = CurrFrame->Arguments.getOrigParam(PVD);
9631 Info.getCallFrameAndDepth(CurrFrame->Arguments.CallIndex).first;
9632 Version = CurrFrame->Arguments.Version;
9636 Version = CurrFrame->getCurrentTemporaryVersion(VD);
9643 Result.set({VD, Frame->Index, Version});
9649 if (!Info.getLangOpts().CPlusPlus11) {
9650 Info.CCEDiag(E, diag::note_constexpr_ltor_non_integral, 1)
9652 Info.Note(VD->
getLocation(), diag::note_declared_at);
9661 Result.AllowConstexprUnknown =
true;
9668bool LValueExprEvaluator::VisitCallExpr(
const CallExpr *E) {
9669 if (!IsConstantEvaluatedBuiltinCall(E))
9670 return ExprEvaluatorBaseTy::VisitCallExpr(E);
9675 case Builtin::BIas_const:
9676 case Builtin::BIforward:
9677 case Builtin::BIforward_like:
9678 case Builtin::BImove:
9679 case Builtin::BImove_if_noexcept:
9681 return Visit(E->
getArg(0));
9685 return ExprEvaluatorBaseTy::VisitCallExpr(E);
9688bool LValueExprEvaluator::VisitMaterializeTemporaryExpr(
9689 const MaterializeTemporaryExpr *E) {
9697 for (
const Expr *E : CommaLHSs)
9706 if (Info.EvalMode == EvaluationMode::ConstantFold)
9713 Value = &Info.CurrentCall->createTemporary(
9729 for (
unsigned I = Adjustments.size(); I != 0; ) {
9731 switch (Adjustments[I].Kind) {
9736 Type = Adjustments[I].DerivedToBase.BasePath->getType();
9742 Type = Adjustments[I].Field->getType();
9747 Adjustments[I].Ptr.RHS))
9749 Type = Adjustments[I].Ptr.MPT->getPointeeType();
9758LValueExprEvaluator::VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E) {
9759 assert((!Info.getLangOpts().CPlusPlus || E->
isFileScope()) &&
9760 "lvalue compound literal in c++?");
9772 assert(!Info.getLangOpts().CPlusPlus);
9774 ScopeKind::Block,
Result);
9786bool LValueExprEvaluator::VisitCXXTypeidExpr(
const CXXTypeidExpr *E) {
9787 TypeInfoLValue TypeInfo;
9795 if (!Info.Ctx.getLangOpts().CPlusPlus20) {
9796 Info.CCEDiag(E, diag::note_constexpr_typeid_polymorphic)
9804 std::optional<DynamicType> DynType =
9809 TypeInfo = TypeInfoLValue(
9810 Info.Ctx.getCanonicalTagType(DynType->Type).getTypePtr());
9816bool LValueExprEvaluator::VisitCXXUuidofExpr(
const CXXUuidofExpr *E) {
9820bool LValueExprEvaluator::VisitMemberExpr(
const MemberExpr *E) {
9822 if (
const VarDecl *VD = dyn_cast<VarDecl>(E->
getMemberDecl())) {
9823 VisitIgnoredBaseExpression(E->
getBase());
9824 return VisitVarDecl(E, VD);
9828 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(E->
getMemberDecl())) {
9829 if (MD->isStatic()) {
9830 VisitIgnoredBaseExpression(E->
getBase());
9836 return LValueExprEvaluatorBaseTy::VisitMemberExpr(E);
9839bool LValueExprEvaluator::VisitExtVectorElementExpr(
9840 const ExtVectorElementExpr *E) {
9845 if (!Info.noteFailure())
9853 if (Indices.size() > 1)
9857 Result.setFrom(Info.Ctx, Val);
9861 const auto *VT = BaseType->
castAs<VectorType>();
9863 VT->getNumElements(), Indices[0]);
9869bool LValueExprEvaluator::VisitArraySubscriptExpr(
const ArraySubscriptExpr *E) {
9879 if (!Info.noteFailure())
9885 if (!Info.noteFailure())
9891 Result.setFrom(Info.Ctx, Val);
9893 VT->getNumElements(), Index.getZExtValue());
9901 for (
const Expr *SubExpr : {E->
getLHS(), E->
getRHS()}) {
9902 if (SubExpr == E->
getBase() ? !evaluatePointer(SubExpr,
Result)
9904 if (!Info.noteFailure())
9914bool LValueExprEvaluator::VisitUnaryDeref(
const UnaryOperator *E) {
9925 Info.noteUndefinedBehavior();
9928bool LValueExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
9937bool LValueExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
9939 "lvalue __imag__ on scalar?");
9946bool LValueExprEvaluator::VisitUnaryPreIncDec(
const UnaryOperator *UO) {
9947 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9958bool LValueExprEvaluator::VisitCompoundAssignOperator(
9959 const CompoundAssignOperator *CAO) {
9960 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9968 if (!Info.noteFailure())
9983bool LValueExprEvaluator::VisitBinAssign(
const BinaryOperator *E) {
9984 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9992 if (!Info.noteFailure())
10000 if (Info.getLangOpts().CPlusPlus20 &&
10015 const LValue &LVal,
10017 assert(isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
10018 "Can't get the size of a non alloc_size function");
10019 const auto *
Base = LVal.getLValueBase().get<
const Expr *>();
10021 std::optional<llvm::APInt> Size =
10022 CE->evaluateBytesReturnedByAllocSizeCall(Ctx);
10026 Result = std::move(*Size);
10045 dyn_cast_or_null<VarDecl>(
Base.dyn_cast<
const ValueDecl *>());
10050 if (!
Init ||
Init->getType().isNull())
10053 const Expr *E =
Init->IgnoreParens();
10054 if (!tryUnwrapAllocSizeCall(E))
10062 Result.addUnsizedArray(Info, E, Pointee);
10067class PointerExprEvaluator
10068 :
public ExprEvaluatorBase<PointerExprEvaluator> {
10070 bool InvalidBaseOK;
10072 bool Success(
const Expr *E) {
10077 bool evaluateLValue(
const Expr *E, LValue &
Result) {
10081 bool evaluatePointer(
const Expr *E, LValue &
Result) {
10085 bool visitNonBuiltinCallExpr(
const CallExpr *E);
10088 PointerExprEvaluator(EvalInfo &info, LValue &
Result,
bool InvalidBaseOK)
10090 InvalidBaseOK(InvalidBaseOK) {}
10096 bool ZeroInitialization(
const Expr *E) {
10101 bool VisitBinaryOperator(
const BinaryOperator *E);
10102 bool VisitCastExpr(
const CastExpr* E);
10103 bool VisitUnaryAddrOf(
const UnaryOperator *E);
10104 bool VisitObjCStringLiteral(
const ObjCStringLiteral *E)
10106 bool VisitObjCBoxedExpr(
const ObjCBoxedExpr *E) {
10109 if (Info.noteFailure())
10113 bool VisitObjCArrayLiteral(
const ObjCArrayLiteral *E) {
10116 bool VisitObjCDictionaryLiteral(
const ObjCDictionaryLiteral *E) {
10119 bool VisitAddrLabelExpr(
const AddrLabelExpr *E)
10121 bool VisitCallExpr(
const CallExpr *E);
10122 bool VisitBuiltinCallExpr(
const CallExpr *E,
unsigned BuiltinOp);
10123 bool VisitBlockExpr(
const BlockExpr *E) {
10128 bool VisitCXXThisExpr(
const CXXThisExpr *E) {
10129 auto DiagnoseInvalidUseOfThis = [&] {
10130 if (Info.getLangOpts().CPlusPlus11)
10131 Info.FFDiag(E, diag::note_constexpr_this) << E->
isImplicit();
10137 if (Info.checkingPotentialConstantExpression())
10140 bool IsExplicitLambda =
10142 if (!IsExplicitLambda) {
10143 if (!Info.CurrentCall->This) {
10144 DiagnoseInvalidUseOfThis();
10148 Result = *Info.CurrentCall->This;
10156 if (!Info.CurrentCall->LambdaThisCaptureField) {
10157 if (IsExplicitLambda && !Info.CurrentCall->This) {
10158 DiagnoseInvalidUseOfThis();
10167 Info, E,
Result, MD, Info.CurrentCall->LambdaThisCaptureField,
10173 bool VisitCXXNewExpr(
const CXXNewExpr *E);
10175 bool VisitSourceLocExpr(
const SourceLocExpr *E) {
10176 assert(!E->
isIntType() &&
"SourceLocExpr isn't a pointer type?");
10178 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.
getDefaultExpr());
10179 Result.setFrom(Info.Ctx, LValResult);
10183 bool VisitEmbedExpr(
const EmbedExpr *E) {
10184 llvm::report_fatal_error(
"Not yet implemented for ExprConstant.cpp");
10188 bool VisitSYCLUniqueStableNameExpr(
const SYCLUniqueStableNameExpr *E) {
10189 std::string ResultStr = E->
ComputeName(Info.Ctx);
10191 QualType CharTy = Info.Ctx.CharTy.withConst();
10192 APInt Size(Info.Ctx.getTypeSize(Info.Ctx.getSizeType()),
10193 ResultStr.size() + 1);
10194 QualType ArrayTy = Info.Ctx.getConstantArrayType(
10195 CharTy, Size,
nullptr, ArraySizeModifier::Normal, 0);
10197 StringLiteral *SL =
10198 StringLiteral::Create(Info.Ctx, ResultStr, StringLiteralKind::Ordinary,
10201 evaluateLValue(SL,
Result);
10211 bool InvalidBaseOK) {
10214 return PointerExprEvaluator(Info,
Result, InvalidBaseOK).Visit(E);
10217bool PointerExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
10220 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
10222 const Expr *PExp = E->
getLHS();
10223 const Expr *IExp = E->
getRHS();
10225 std::swap(PExp, IExp);
10227 bool EvalPtrOK = evaluatePointer(PExp,
Result);
10228 if (!EvalPtrOK && !Info.noteFailure())
10231 llvm::APSInt Offset;
10242bool PointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
10250 if (!Info.getLangOpts().CPlusPlus) {
10252 if (
const auto *Deref = dyn_cast<UnaryOperator>(Sub);
10253 Deref && Deref->getOpcode() == UO_Deref)
10254 return evaluatePointer(Deref->getSubExpr(),
Result);
10264 if (!FnII || !FnII->
isStr(
"current"))
10267 const auto *RD = dyn_cast<RecordDecl>(FD->
getParent());
10275bool PointerExprEvaluator::VisitCastExpr(
const CastExpr *E) {
10282 case CK_CPointerToObjCPointerCast:
10283 case CK_BlockPointerToObjCPointerCast:
10284 case CK_AnyPointerToBlockPointerCast:
10285 case CK_AddressSpaceConversion:
10286 if (!Visit(SubExpr))
10292 CCEDiag(E, diag::note_constexpr_invalid_cast)
10293 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
10294 << Info.Ctx.getLangOpts().CPlusPlus;
10295 Result.Designator.setInvalid();
10303 bool HasValidResult = !
Result.InvalidBase && !
Result.Designator.Invalid &&
10305 bool VoidPtrCastMaybeOK =
10308 Info.Ctx.hasSimilarType(
Result.Designator.getType(Info.Ctx),
10317 if (VoidPtrCastMaybeOK &&
10318 (Info.getStdAllocatorCaller(
"allocate") ||
10320 Info.getLangOpts().CPlusPlus26)) {
10324 Info.getLangOpts().CPlusPlus) {
10325 if (HasValidResult)
10326 CCEDiag(E, diag::note_constexpr_invalid_void_star_cast)
10327 << SubExpr->
getType() << Info.getLangOpts().CPlusPlus26
10328 <<
Result.Designator.getType(Info.Ctx).getCanonicalType()
10331 CCEDiag(E, diag::note_constexpr_invalid_cast)
10332 << diag::ConstexprInvalidCastKind::CastFrom
10335 CCEDiag(E, diag::note_constexpr_invalid_cast)
10336 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
10337 << Info.Ctx.getLangOpts().CPlusPlus;
10338 Result.Designator.setInvalid();
10342 ZeroInitialization(E);
10345 case CK_DerivedToBase:
10346 case CK_UncheckedDerivedToBase:
10358 case CK_BaseToDerived:
10370 case CK_NullToPointer:
10372 return ZeroInitialization(E);
10374 case CK_IntegralToPointer: {
10375 CCEDiag(E, diag::note_constexpr_invalid_cast)
10376 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
10377 << Info.Ctx.getLangOpts().CPlusPlus;
10383 if (
Value.isInt()) {
10384 unsigned Size = Info.Ctx.getTypeSize(E->
getType());
10385 uint64_t N =
Value.getInt().extOrTrunc(Size).getZExtValue();
10386 if (N == Info.Ctx.getTargetNullPointerValue(E->
getType())) {
10389 Result.Base = (Expr *)
nullptr;
10390 Result.InvalidBase =
false;
10392 Result.Designator.setInvalid();
10393 Result.IsNullPtr =
false;
10401 if (!
Value.isLValue())
10410 case CK_ArrayToPointerDecay: {
10412 if (!evaluateLValue(SubExpr,
Result))
10416 SubExpr, SubExpr->
getType(), ScopeKind::FullExpression,
Result);
10421 auto *AT = Info.Ctx.getAsArrayType(SubExpr->
getType());
10422 if (
auto *CAT = dyn_cast<ConstantArrayType>(AT))
10423 Result.addArray(Info, E, CAT);
10425 Result.addUnsizedArray(Info, E, AT->getElementType());
10429 case CK_FunctionToPointerDecay:
10430 return evaluateLValue(SubExpr,
Result);
10432 case CK_LValueToRValue: {
10441 return InvalidBaseOK &&
10447 return ExprEvaluatorBaseTy::VisitCastExpr(E);
10451 UnaryExprOrTypeTrait ExprKind) {
10455 T =
T.getNonReferenceType();
10457 if (
T.getQualifiers().hasUnaligned())
10460 const bool AlignOfReturnsPreferred =
10466 if (ExprKind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
10469 else if (ExprKind == UETT_AlignOf)
10472 llvm_unreachable(
"GetAlignOfType on a non-alignment ExprKind");
10487 unsigned BuiltinOp) {
10511 switch (OwningTarget->
getTriple().getArch()) {
10512 case llvm::Triple::x86:
10513 case llvm::Triple::x86_64:
10526 UnaryExprOrTypeTrait ExprKind) {
10535 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
10539 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(E))
10548 return Info.Ctx.getDeclAlign(VD);
10549 if (
const auto *E =
Value.Base.dyn_cast<
const Expr *>())
10557 EvalInfo &Info,
APSInt &Alignment) {
10560 if (Alignment < 0 || !Alignment.isPowerOf2()) {
10561 Info.FFDiag(E, diag::note_constexpr_invalid_alignment) << Alignment;
10564 unsigned SrcWidth = Info.Ctx.getIntWidth(ForType);
10565 APSInt MaxValue(APInt::getOneBitSet(SrcWidth, SrcWidth - 1));
10566 if (APSInt::compareValues(Alignment, MaxValue) > 0) {
10567 Info.FFDiag(E, diag::note_constexpr_alignment_too_big)
10568 << MaxValue << ForType << Alignment;
10574 APSInt(Alignment.zextOrTrunc(SrcWidth),
true);
10575 assert(APSInt::compareValues(Alignment, ExtAlignment) == 0 &&
10576 "Alignment should not be changed by ext/trunc");
10577 Alignment = ExtAlignment;
10578 assert(Alignment.getBitWidth() == SrcWidth);
10583bool PointerExprEvaluator::visitNonBuiltinCallExpr(
const CallExpr *E) {
10584 if (ExprEvaluatorBaseTy::VisitCallExpr(E))
10592 Result.addUnsizedArray(Info, E, PointeeTy);
10596bool PointerExprEvaluator::VisitCallExpr(
const CallExpr *E) {
10597 if (!IsConstantEvaluatedBuiltinCall(E))
10598 return visitNonBuiltinCallExpr(E);
10605 return T->isCharType() ||
T->isChar8Type();
10608bool PointerExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *E,
10609 unsigned BuiltinOp) {
10613 switch (BuiltinOp) {
10614 case Builtin::BIaddressof:
10615 case Builtin::BI__addressof:
10616 case Builtin::BI__builtin_addressof:
10618 case Builtin::BI__builtin_assume_aligned: {
10625 LValue OffsetResult(
Result);
10637 int64_t AdditionalOffset = -Offset.getZExtValue();
10642 if (OffsetResult.Base) {
10645 if (BaseAlignment < Align) {
10646 Result.Designator.setInvalid();
10647 CCEDiag(E->
getArg(0), diag::note_constexpr_baa_insufficient_alignment)
10654 if (OffsetResult.Offset.alignTo(Align) != OffsetResult.Offset) {
10655 Result.Designator.setInvalid();
10659 diag::note_constexpr_baa_insufficient_alignment)
10662 diag::note_constexpr_baa_value_insufficient_alignment))
10663 << OffsetResult.Offset.getQuantity() << Align.
getQuantity();
10669 case Builtin::BI__builtin_align_up:
10670 case Builtin::BI__builtin_align_down: {
10690 assert(Alignment.getBitWidth() <= 64 &&
10691 "Cannot handle > 64-bit address-space");
10692 uint64_t Alignment64 = Alignment.getZExtValue();
10694 BuiltinOp == Builtin::BI__builtin_align_down
10695 ? llvm::alignDown(
Result.Offset.getQuantity(), Alignment64)
10696 : llvm::alignTo(
Result.Offset.getQuantity(), Alignment64));
10702 Info.FFDiag(E->
getArg(0), diag::note_constexpr_alignment_adjust)
10706 case Builtin::BI__builtin_operator_new:
10708 case Builtin::BI__builtin_launder:
10710 case Builtin::BIstrchr:
10711 case Builtin::BIwcschr:
10712 case Builtin::BImemchr:
10713 case Builtin::BIwmemchr:
10714 if (Info.getLangOpts().CPlusPlus11)
10715 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
10717 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
10719 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
10721 case Builtin::BI__builtin_strchr:
10722 case Builtin::BI__builtin_wcschr:
10723 case Builtin::BI__builtin_memchr:
10724 case Builtin::BI__builtin_char_memchr:
10725 case Builtin::BI__builtin_wmemchr: {
10726 if (!Visit(E->
getArg(0)))
10732 if (BuiltinOp != Builtin::BIstrchr &&
10733 BuiltinOp != Builtin::BIwcschr &&
10734 BuiltinOp != Builtin::BI__builtin_strchr &&
10735 BuiltinOp != Builtin::BI__builtin_wcschr) {
10739 MaxLength = N.getZExtValue();
10742 if (MaxLength == 0u)
10743 return ZeroInitialization(E);
10744 if (!
Result.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
10745 Result.Designator.Invalid)
10747 QualType CharTy =
Result.Designator.getType(Info.Ctx);
10748 bool IsRawByte = BuiltinOp == Builtin::BImemchr ||
10749 BuiltinOp == Builtin::BI__builtin_memchr;
10750 assert(IsRawByte ||
10751 Info.Ctx.hasSameUnqualifiedType(
10755 Info.FFDiag(E, diag::note_constexpr_ltor_incomplete_type) << CharTy;
10761 Info.FFDiag(E, diag::note_constexpr_memchr_unsupported)
10762 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp) << CharTy;
10768 bool StopAtNull =
false;
10769 switch (BuiltinOp) {
10770 case Builtin::BIstrchr:
10771 case Builtin::BI__builtin_strchr:
10778 return ZeroInitialization(E);
10781 case Builtin::BImemchr:
10782 case Builtin::BI__builtin_memchr:
10783 case Builtin::BI__builtin_char_memchr:
10787 DesiredVal = Desired.trunc(Info.Ctx.getCharWidth()).getZExtValue();
10790 case Builtin::BIwcschr:
10791 case Builtin::BI__builtin_wcschr:
10794 case Builtin::BIwmemchr:
10795 case Builtin::BI__builtin_wmemchr:
10797 DesiredVal = Desired.getZExtValue();
10801 for (; MaxLength; --MaxLength) {
10806 if (Char.
getInt().getZExtValue() == DesiredVal)
10808 if (StopAtNull && !Char.
getInt())
10814 return ZeroInitialization(E);
10817 case Builtin::BImemcpy:
10818 case Builtin::BImemmove:
10819 case Builtin::BIwmemcpy:
10820 case Builtin::BIwmemmove:
10821 if (Info.getLangOpts().CPlusPlus11)
10822 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
10824 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
10826 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
10828 case Builtin::BI__builtin_memcpy:
10829 case Builtin::BI__builtin_memmove:
10830 case Builtin::BI__builtin_wmemcpy:
10831 case Builtin::BI__builtin_wmemmove: {
10832 bool WChar = BuiltinOp == Builtin::BIwmemcpy ||
10833 BuiltinOp == Builtin::BIwmemmove ||
10834 BuiltinOp == Builtin::BI__builtin_wmemcpy ||
10835 BuiltinOp == Builtin::BI__builtin_wmemmove;
10836 bool Move = BuiltinOp == Builtin::BImemmove ||
10837 BuiltinOp == Builtin::BIwmemmove ||
10838 BuiltinOp == Builtin::BI__builtin_memmove ||
10839 BuiltinOp == Builtin::BI__builtin_wmemmove;
10842 if (!Visit(E->
getArg(0)))
10853 assert(!N.isSigned() &&
"memcpy and friends take an unsigned size");
10863 if (!Src.Base || !Dest.Base) {
10865 (!Src.Base ? Src : Dest).moveInto(Val);
10866 Info.FFDiag(E, diag::note_constexpr_memcpy_null)
10867 <<
Move << WChar << !!Src.Base
10871 if (Src.Designator.Invalid || Dest.Designator.Invalid)
10877 QualType
T = Dest.Designator.getType(Info.Ctx);
10878 QualType SrcT = Src.Designator.getType(Info.Ctx);
10879 if (!Info.Ctx.hasSameUnqualifiedType(
T, SrcT)) {
10881 Info.FFDiag(E, diag::note_constexpr_memcpy_type_pun) <<
Move << SrcT <<
T;
10885 Info.FFDiag(E, diag::note_constexpr_memcpy_incomplete_type) <<
Move <<
T;
10888 if (!
T.isTriviallyCopyableType(Info.Ctx)) {
10889 Info.FFDiag(E, diag::note_constexpr_memcpy_nontrivial) <<
Move <<
T;
10894 uint64_t TSize = Info.Ctx.getTypeSizeInChars(
T).getQuantity();
10899 llvm::APInt OrigN = N;
10900 llvm::APInt::udivrem(OrigN, TSize, N, Remainder);
10902 Info.FFDiag(E, diag::note_constexpr_memcpy_unsupported)
10904 << (unsigned)TSize;
10912 uint64_t RemainingSrcSize = Src.Designator.validIndexAdjustments().second;
10913 uint64_t RemainingDestSize = Dest.Designator.validIndexAdjustments().second;
10914 if (N.ugt(RemainingSrcSize) || N.ugt(RemainingDestSize)) {
10915 Info.FFDiag(E, diag::note_constexpr_memcpy_unsupported)
10916 <<
Move << WChar << (N.ugt(RemainingSrcSize) ? 1 : 2) <<
T
10920 uint64_t NElems = N.getZExtValue();
10926 uint64_t SrcOffset = Src.getLValueOffset().getQuantity();
10927 uint64_t DestOffset = Dest.getLValueOffset().getQuantity();
10928 if (DestOffset >= SrcOffset && DestOffset - SrcOffset < NBytes) {
10931 Info.FFDiag(E, diag::note_constexpr_memcpy_overlap) << WChar;
10939 }
else if (!Move && SrcOffset >= DestOffset &&
10940 SrcOffset - DestOffset < NBytes) {
10942 Info.FFDiag(E, diag::note_constexpr_memcpy_overlap) << WChar;
10971 QualType AllocType);
10974 const CXXConstructExpr *CCE,
10975 QualType AllocType);
10977bool PointerExprEvaluator::VisitCXXNewExpr(
const CXXNewExpr *E) {
10978 if (!Info.getLangOpts().CPlusPlus20)
10979 Info.CCEDiag(E, diag::note_constexpr_new);
10982 if (Info.SpeculativeEvaluationDepth)
10987 QualType TargetType = AllocType;
10989 bool IsNothrow =
false;
10990 bool IsPlacement =
false;
11008 }
else if (OperatorNew->isReservedGlobalPlacementOperator()) {
11009 if (Info.CurrentCall->isStdFunction() || Info.getLangOpts().CPlusPlus26 ||
11010 (Info.CurrentCall->CanEvalMSConstexpr &&
11011 OperatorNew->hasAttr<MSConstexprAttr>())) {
11014 if (
Result.Designator.Invalid)
11017 IsPlacement =
true;
11019 Info.FFDiag(E, diag::note_constexpr_new_placement)
11024 Info.FFDiag(E, diag::note_constexpr_new_placement)
11027 }
else if (!OperatorNew
11028 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
11029 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
11035 const InitListExpr *ResizedArrayILE =
nullptr;
11036 const CXXConstructExpr *ResizedArrayCCE =
nullptr;
11037 bool ValueInit =
false;
11039 if (std::optional<const Expr *> ArraySize = E->
getArraySize()) {
11040 const Expr *Stripped = *ArraySize;
11041 for (;
auto *ICE = dyn_cast<ImplicitCastExpr>(Stripped);
11042 Stripped = ICE->getSubExpr())
11043 if (ICE->getCastKind() != CK_NoOp &&
11044 ICE->getCastKind() != CK_IntegralCast)
11057 return ZeroInitialization(E);
11059 Info.FFDiag(*ArraySize, diag::note_constexpr_new_negative)
11060 <<
ArrayBound << (*ArraySize)->getSourceRange();
11066 if (!Info.CheckArraySize(ArraySize.value()->getExprLoc(),
11071 return ZeroInitialization(E);
11083 }
else if (
auto *CCE = dyn_cast<CXXConstructExpr>(
Init)) {
11084 ResizedArrayCCE = CCE;
11086 auto *CAT = Info.Ctx.getAsConstantArrayType(
Init->getType());
11087 assert(CAT &&
"unexpected type for array initializer");
11091 llvm::APInt InitBound = CAT->
getSize().zext(Bits);
11092 llvm::APInt AllocBound =
ArrayBound.zext(Bits);
11093 if (InitBound.ugt(AllocBound)) {
11095 return ZeroInitialization(E);
11097 Info.FFDiag(*ArraySize, diag::note_constexpr_new_too_small)
11098 <<
toString(AllocBound, 10,
false)
11100 << (*ArraySize)->getSourceRange();
11106 if (InitBound != AllocBound)
11110 AllocType = Info.Ctx.getConstantArrayType(AllocType,
ArrayBound,
nullptr,
11111 ArraySizeModifier::Normal, 0);
11121 "array allocation with non-array new");
11127 struct FindObjectHandler {
11130 QualType AllocType;
11134 typedef bool result_type;
11135 bool failed() {
return false; }
11136 bool checkConst(QualType QT) {
11138 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
11143 bool found(
APValue &Subobj, QualType SubobjType,
11144 APValue::LValueBase Base) {
11145 if (!checkConst(SubobjType))
11149 if (!Info.Ctx.hasSimilarType(SubobjType, AllocType)) {
11150 Info.FFDiag(E, diag::note_constexpr_placement_new_wrong_type)
11151 << SubobjType << AllocType;
11158 Info.FFDiag(E, diag::note_constexpr_construct_complex_elem);
11161 bool found(APFloat &
Value, QualType SubobjType) {
11162 Info.FFDiag(E, diag::note_constexpr_construct_complex_elem);
11165 } Handler = {Info, E, AllocType, AK,
nullptr};
11168 Result.Designator.MostDerivedIsArrayElement &&
11169 Result.Designator.Entries.back().getAsArrayIndex() == 0) {
11174 QualType AllocElementType =
11175 Info.Ctx.getAsArrayType(AllocType)->getElementType();
11176 if (Info.Ctx.hasSimilarType(AllocElementType,
11177 Result.Designator.MostDerivedType)) {
11179 Result.Designator.MostDerivedPathLength - 1);
11187 Val = Handler.Value;
11196 Val = Info.createHeapAlloc(E, AllocType,
Result);
11202 ImplicitValueInitExpr VIE(AllocType);
11205 }
else if (ResizedArrayILE) {
11209 }
else if (ResizedArrayCCE) {
11232class MemberPointerExprEvaluator
11233 :
public ExprEvaluatorBase<MemberPointerExprEvaluator> {
11236 bool Success(
const ValueDecl *D) {
11242 MemberPointerExprEvaluator(EvalInfo &Info, MemberPtr &
Result)
11249 bool ZeroInitialization(
const Expr *E) {
11250 return Success((
const ValueDecl*)
nullptr);
11253 bool VisitCastExpr(
const CastExpr *E);
11254 bool VisitUnaryAddrOf(
const UnaryOperator *E);
11262 return MemberPointerExprEvaluator(Info,
Result).Visit(E);
11265bool MemberPointerExprEvaluator::VisitCastExpr(
const CastExpr *E) {
11268 return ExprEvaluatorBaseTy::VisitCastExpr(E);
11270 case CK_NullToMemberPointer:
11272 return ZeroInitialization(E);
11274 case CK_BaseToDerivedMemberPointer: {
11282 typedef std::reverse_iterator<CastExpr::path_const_iterator> ReverseIter;
11284 PathI != PathE; ++PathI) {
11285 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
11286 const CXXRecordDecl *Derived = (*PathI)->getType()->getAsCXXRecordDecl();
11287 if (!
Result.castToDerived(Derived))
11291 ->
castAs<MemberPointerType>()
11292 ->getMostRecentCXXRecordDecl()))
11297 case CK_DerivedToBaseMemberPointer:
11301 PathE = E->
path_end(); PathI != PathE; ++PathI) {
11302 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
11303 const CXXRecordDecl *
Base = (*PathI)->getType()->getAsCXXRecordDecl();
11304 if (!
Result.castToBase(Base))
11311bool MemberPointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
11322 class RecordExprEvaluator
11323 :
public ExprEvaluatorBase<RecordExprEvaluator> {
11324 const LValue &
This;
11328 RecordExprEvaluator(EvalInfo &info,
const LValue &This,
APValue &
Result)
11335 bool ZeroInitialization(
const Expr *E) {
11336 return ZeroInitialization(E, E->
getType());
11338 bool ZeroInitialization(
const Expr *E, QualType
T);
11340 bool VisitCallExpr(
const CallExpr *E) {
11341 return handleCallExpr(E,
Result, &This);
11343 bool VisitCastExpr(
const CastExpr *E);
11344 bool VisitInitListExpr(
const InitListExpr *E);
11345 bool VisitCXXConstructExpr(
const CXXConstructExpr *E) {
11346 return VisitCXXConstructExpr(E, E->
getType());
11349 bool VisitCXXInheritedCtorInitExpr(
const CXXInheritedCtorInitExpr *E);
11350 bool VisitCXXConstructExpr(
const CXXConstructExpr *E, QualType
T);
11351 bool VisitCXXStdInitializerListExpr(
const CXXStdInitializerListExpr *E);
11352 bool VisitBinCmp(
const BinaryOperator *E);
11353 bool VisitCXXParenListInitExpr(
const CXXParenListInitExpr *E);
11354 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
11355 ArrayRef<Expr *> Args);
11356 bool VisitDesignatedInitUpdateExpr(
const DesignatedInitUpdateExpr *E);
11370 bool IsCompleteClass =
true) {
11371 assert(!RD->
isUnion() &&
"Expected non-union class type");
11375 unsigned NonVirtualBases = countNonVirtualBases(CD);
11387 unsigned Index = 0;
11389 for (
const auto &B : CD->
bases()) {
11393 LValue Subobject =
This;
11397 Result.getStructBase(Index),
11404 for (
const auto *I : RD->
fields()) {
11406 if (I->isUnnamedBitField() || I->getType()->isReferenceType())
11409 LValue Subobject =
This;
11415 Result.getStructField(I->getFieldIndex()), Info, Subobject, &VIE))
11419 if (CD &&
This.pointsToCompleteClass(CD)) {
11420 unsigned Index = 0;
11421 for (
const auto &B : CD->
vbases()) {
11423 LValue Subobject =
This;
11427 Result.getStructVirtualBase(Index),
11437bool RecordExprEvaluator::ZeroInitialization(
const Expr *E, QualType
T) {
11444 while (I != RD->
field_end() && (*I)->isUnnamedBitField())
11451 LValue Subobject =
This;
11455 ImplicitValueInitExpr VIE(I->getType());
11459 if (!Info.getLangOpts().CPlusPlus26) {
11460 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
11461 CXXRD && CXXRD->getNumVBases()) {
11462 Info.FFDiag(E, diag::note_constexpr_virtual_base) << RD;
11470bool RecordExprEvaluator::VisitCastExpr(
const CastExpr *E) {
11473 return ExprEvaluatorBaseTy::VisitCastExpr(E);
11475 case CK_ConstructorConversion:
11478 case CK_DerivedToBase:
11479 case CK_UncheckedDerivedToBase: {
11490 PathE = E->
path_end(); PathI != PathE; ++PathI) {
11491 assert(!(*PathI)->isVirtual() &&
"record rvalue with virtual base");
11492 const CXXRecordDecl *
Base = (*PathI)->getType()->getAsCXXRecordDecl();
11499 case CK_HLSLAggregateSplatCast: {
11519 case CK_HLSLElementwiseCast: {
11537 LValue Subobject =
This;
11544 if (
Field->isBitField()) {
11554bool RecordExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
11557 return VisitCXXParenListOrInitListExpr(E, E->
inits());
11560bool RecordExprEvaluator::VisitCXXParenListOrInitListExpr(
11564 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD);
11565 auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
11567 EvalInfo::EvaluatingConstructorRAII EvalObj(
11569 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries},
11570 CXXRD && CXXRD->getNumBases());
11573 const FieldDecl *
Field;
11574 if (
auto *ILE = dyn_cast<InitListExpr>(ExprToVisit)) {
11575 Field = ILE->getInitializedFieldInUnion();
11576 }
else if (
auto *PLIE = dyn_cast<CXXParenListInitExpr>(ExprToVisit)) {
11577 Field = PLIE->getInitializedFieldInUnion();
11580 "Expression is neither an init list nor a C++ paren list");
11592 ImplicitValueInitExpr VIE(
Field->getType());
11593 const Expr *InitExpr = Args.empty() ? &VIE : Args[0];
11595 LValue Subobject =
This;
11600 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
11604 if (
Field->isBitField())
11614 Result =
APValue(APValue::UninitStruct(), CXXRD ? CXXRD->getNumBases() : 0,
11616 unsigned ElementNo = 0;
11620 if (CXXRD && CXXRD->getNumBases()) {
11621 for (
const auto &Base : CXXRD->bases()) {
11622 assert(ElementNo < Args.size() &&
"missing init for base class");
11623 const Expr *
Init = Args[ElementNo];
11625 LValue Subobject =
This;
11631 if (!Info.noteFailure())
11638 EvalObj.finishedConstructingBases();
11642 for (
const auto *Field : RD->
fields()) {
11645 if (
Field->isUnnamedBitField())
11648 LValue Subobject =
This;
11650 bool HaveInit = ElementNo < Args.size();
11655 Subobject, Field, &Layout))
11660 ImplicitValueInitExpr VIE(HaveInit ? Info.Ctx.IntTy :
Field->getType());
11661 const Expr *
Init = HaveInit ? Args[ElementNo++] : &VIE;
11668 if (
Field->getType()->isIncompleteArrayType()) {
11669 if (
auto *CAT = Info.Ctx.getAsConstantArrayType(
Init->getType())) {
11673 Info.FFDiag(
Init, diag::note_constexpr_unsupported_flexible_array);
11680 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
11684 if (
Field->getType()->isReferenceType()) {
11688 if (!Info.noteFailure())
11693 (
Field->isBitField() &&
11695 if (!Info.noteFailure())
11701 EvalObj.finishedConstructingFields();
11706bool RecordExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E,
11716 return ZeroInitialization(E,
T);
11734 const Expr *SrcObj = E->
getArg(0);
11736 assert(Info.Ctx.hasSameUnqualifiedType(E->
getType(), SrcObj->
getType()));
11737 if (
const MaterializeTemporaryExpr *ME =
11738 dyn_cast<MaterializeTemporaryExpr>(SrcObj))
11739 return Visit(ME->getSubExpr());
11742 if (ZeroInit && !ZeroInitialization(E,
T))
11751bool RecordExprEvaluator::VisitCXXInheritedCtorInitExpr(
11752 const CXXInheritedCtorInitExpr *E) {
11753 if (!Info.CurrentCall) {
11754 assert(Info.checkingPotentialConstantExpression());
11773bool RecordExprEvaluator::VisitCXXStdInitializerListExpr(
11774 const CXXStdInitializerListExpr *E) {
11775 const ConstantArrayType *ArrayType =
11782 assert(ArrayType &&
"unexpected type for array initializer");
11785 Array.addArray(Info, E, ArrayType);
11793 assert(Field !=
Record->field_end() &&
11794 Info.Ctx.hasSameType(
Field->getType()->getPointeeType(),
11796 "Expected std::initializer_list first field to be const E *");
11798 assert(Field !=
Record->field_end() &&
11799 "Expected std::initializer_list to have two fields");
11801 if (Info.Ctx.hasSameType(
Field->getType(), Info.Ctx.getSizeType())) {
11806 assert(Info.Ctx.hasSameType(
Field->getType()->getPointeeType(),
11808 "Expected std::initializer_list second field to be const E *");
11816 assert(++Field ==
Record->field_end() &&
11817 "Expected std::initializer_list to only have two fields");
11822bool RecordExprEvaluator::VisitLambdaExpr(
const LambdaExpr *E) {
11827 const size_t NumFields = ClosureClass->
getNumFields();
11831 "The number of lambda capture initializers should equal the number of "
11832 "fields within the closure type");
11839 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(ClosureClass);
11840 for (
const auto *Field : ClosureClass->
fields()) {
11843 Expr *
const CurFieldInit = *CaptureInitIt++;
11850 LValue Subobject =
This;
11857 if (!Info.keepEvaluatingAfterFailure())
11865bool RecordExprEvaluator::VisitDesignatedInitUpdateExpr(
11866 const DesignatedInitUpdateExpr *E) {
11876 "can't evaluate expression as a record rvalue");
11877 return RecordExprEvaluator(Info,
This,
Result).Visit(E);
11888class TemporaryExprEvaluator
11889 :
public LValueExprEvaluatorBase<TemporaryExprEvaluator> {
11891 TemporaryExprEvaluator(EvalInfo &Info, LValue &
Result) :
11892 LValueExprEvaluatorBaseTy(Info,
Result,
false) {}
11895 bool VisitConstructExpr(
const Expr *E) {
11901 bool VisitCastExpr(
const CastExpr *E) {
11904 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
11906 case CK_ConstructorConversion:
11910 bool VisitInitListExpr(
const InitListExpr *E) {
11911 return VisitConstructExpr(E);
11913 bool VisitCXXConstructExpr(
const CXXConstructExpr *E) {
11914 return VisitConstructExpr(E);
11916 bool VisitCallExpr(
const CallExpr *E) {
11917 return VisitConstructExpr(E);
11919 bool VisitCXXStdInitializerListExpr(
const CXXStdInitializerListExpr *E) {
11920 return VisitConstructExpr(E);
11923 return VisitConstructExpr(E);
11932 return TemporaryExprEvaluator(Info,
Result).Visit(E);
11940 class VectorExprEvaluator
11941 :
public ExprEvaluatorBase<VectorExprEvaluator> {
11948 bool Success(ArrayRef<APValue>
V,
const Expr *E) {
11949 assert(
V.size() == E->
getType()->
castAs<VectorType>()->getNumElements());
11955 assert(
V.isVector());
11959 bool ZeroInitialization(
const Expr *E);
11961 bool VisitUnaryReal(
const UnaryOperator *E)
11963 bool VisitCastExpr(
const CastExpr* E);
11964 bool VisitInitListExpr(
const InitListExpr *E);
11965 bool VisitUnaryImag(
const UnaryOperator *E);
11966 bool VisitBinaryOperator(
const BinaryOperator *E);
11967 bool VisitUnaryOperator(
const UnaryOperator *E);
11968 bool VisitCallExpr(
const CallExpr *E);
11969 bool VisitConvertVectorExpr(
const ConvertVectorExpr *E);
11970 bool VisitShuffleVectorExpr(
const ShuffleVectorExpr *E);
11979 "not a vector prvalue");
11980 return VectorExprEvaluator(Info,
Result).Visit(E);
11984 assert(Val.
isVector() &&
"expected vector APValue");
11988 llvm::APInt
Result(NumElts, 0);
11990 for (
unsigned I = 0; I < NumElts; ++I) {
11992 assert(Elt.
isInt() &&
"expected integer element in bool vector");
11994 if (Elt.
getInt().getBoolValue())
12001bool VectorExprEvaluator::VisitCastExpr(
const CastExpr *E) {
12002 const VectorType *VTy = E->
getType()->
castAs<VectorType>();
12006 QualType SETy = SE->
getType();
12009 case CK_VectorSplat: {
12015 Val =
APValue(std::move(IntResult));
12020 Val =
APValue(std::move(FloatResult));
12037 Info.FFDiag(E, diag::note_constexpr_invalid_cast)
12038 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
12039 << Info.Ctx.getLangOpts().CPlusPlus;
12043 if (!handleRValueToRValueBitCast(Info,
Result, SVal, E))
12048 case CK_HLSLVectorTruncation: {
12053 for (
unsigned I = 0; I < NElts; I++)
12057 case CK_HLSLMatrixTruncation: {
12063 for (
unsigned Row = 0;
12065 for (
unsigned Col = 0;
12070 case CK_HLSLAggregateSplatCast: {
12087 case CK_HLSLElementwiseCast: {
12100 return Success(ResultEls, E);
12102 case CK_IntegralToFloating:
12103 case CK_FloatingToIntegral:
12104 case CK_IntegralCast:
12105 case CK_FloatingCast:
12106 case CK_FloatingToBoolean:
12107 case CK_IntegralToBoolean: {
12109 assert(SETy->
isVectorType() &&
"expected vector source type");
12115 QualType SrcEltTy = SETy->
castAs<VectorType>()->getElementType();
12120 for (
unsigned I = 0; I < NElts; ++I) {
12125 return Success(ResultEls, E);
12128 return ExprEvaluatorBaseTy::VisitCastExpr(E);
12133VectorExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
12150 unsigned CountInits = 0, CountElts = 0;
12151 while (CountElts < NumElements) {
12153 if (CountInits < NumInits
12159 for (
unsigned j = 0; j < vlen; j++)
12163 llvm::APSInt sInt(32);
12164 if (CountInits < NumInits) {
12168 sInt = Info.Ctx.MakeIntValue(0, EltTy);
12169 Elements.push_back(
APValue(sInt));
12172 llvm::APFloat f(0.0);
12173 if (CountInits < NumInits) {
12177 f = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy));
12178 Elements.push_back(
APValue(f));
12187VectorExprEvaluator::ZeroInitialization(
const Expr *E) {
12191 if (EltTy->isIntegerType())
12192 ZeroElement =
APValue(Info.Ctx.MakeIntValue(0, EltTy));
12195 APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy)));
12201bool VectorExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
12203 return ZeroInitialization(E);
12206bool VectorExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
12208 assert(Op != BO_PtrMemD && Op != BO_PtrMemI && Op != BO_Cmp &&
12209 "Operation not supported on vector types");
12211 if (Op == BO_Comma)
12212 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
12214 Expr *LHS = E->
getLHS();
12215 Expr *RHS = E->
getRHS();
12218 "Must both be vector types");
12221 assert(LHS->
getType()->
castAs<VectorType>()->getNumElements() ==
12225 "All operands must be the same size.");
12229 bool LHSOK =
Evaluate(LHSValue, Info, LHS);
12230 if (!LHSOK && !Info.noteFailure())
12232 if (!
Evaluate(RHSValue, Info, RHS) || !LHSOK)
12254 "Vector can only be int or float type");
12262 "Vector operator ~ can only be int");
12263 Elt.
getInt().flipAllBits();
12273 "Vector can only be int or float type");
12279 EltResult.setAllBits();
12281 EltResult.clearAllBits();
12287 return std::nullopt;
12291bool VectorExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
12297 const QualType ResultEltTy = VD->getElementType();
12301 if (!
Evaluate(SubExprValue, Info, SubExpr))
12314 "Vector length doesn't match type?");
12317 for (
unsigned EltNum = 0; EltNum < VD->getNumElements(); ++EltNum) {
12319 Info.Ctx, ResultEltTy, Op, SubExprValue.
getVectorElt(EltNum));
12322 ResultElements.push_back(*Elt);
12324 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12335 DestTy,
Result.getFloat());
12351 DestTy,
Result.getInt());
12355 Info.FFDiag(E, diag::err_convertvector_constexpr_unsupported_vector_cast)
12356 << SourceTy << DestTy;
12361 llvm::function_ref<APInt(
const APSInt &)> PackFn) {
12370 assert(LHSVecLen != 0 && LHSVecLen == RHSVecLen &&
12371 "pack builtin LHSVecLen must equal to RHSVecLen");
12374 const unsigned SrcBits = Info.Ctx.getIntWidth(VT0->
getElementType());
12380 const unsigned SrcPerLane = 128 / SrcBits;
12381 const unsigned Lanes = LHSVecLen * SrcBits / 128;
12384 Out.reserve(LHSVecLen + RHSVecLen);
12386 for (
unsigned Lane = 0; Lane != Lanes; ++Lane) {
12387 unsigned base = Lane * SrcPerLane;
12388 for (
unsigned I = 0; I != SrcPerLane; ++I)
12391 for (
unsigned I = 0; I != SrcPerLane; ++I)
12402 llvm::function_ref<std::pair<unsigned, int>(
unsigned,
unsigned)>
12409 unsigned ShuffleMask = 0;
12411 bool IsVectorMask =
false;
12412 bool IsSingleOperand = (
Call->getNumArgs() == 2);
12414 if (IsSingleOperand) {
12417 IsVectorMask =
true;
12426 ShuffleMask =
static_cast<unsigned>(MaskImm.getZExtValue());
12436 IsVectorMask =
true;
12445 ShuffleMask =
static_cast<unsigned>(MaskImm.getZExtValue());
12456 ResultElements.reserve(NumElts);
12458 for (
unsigned DstIdx = 0; DstIdx != NumElts; ++DstIdx) {
12459 if (IsVectorMask) {
12460 ShuffleMask =
static_cast<unsigned>(
12461 MaskVector.getVectorElt(DstIdx).getInt().getZExtValue());
12463 auto [SrcVecIdx, SrcIdx] = GetSourceIndex(DstIdx, ShuffleMask);
12469 ResultElements.push_back(
12470 APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(ElemTy))));
12476 ResultElements.push_back(
APValue());
12479 const APValue &Src = (SrcVecIdx == 0) ? A : B;
12484 Out =
APValue(ResultElements.data(), ResultElements.size());
12490 if (OrigVal.isInfinity()) {
12491 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << 0;
12494 if (OrigVal.isNaN()) {
12495 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << 1;
12499 APFloat Val = OrigVal;
12500 bool LosesInfo =
false;
12501 APFloat::opStatus Status = Val.convert(
12502 APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven, &LosesInfo);
12504 if (LosesInfo || Val.isDenormal()) {
12505 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic_strict);
12509 if (Status != APFloat::opOK) {
12510 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
12519 llvm::function_ref<APInt(
const APInt &, uint64_t)> ShiftOp,
12520 llvm::function_ref<APInt(
const APInt &,
unsigned)> OverflowOp) {
12527 assert(
Call->getNumArgs() == 2);
12531 Call->getArg(1)->getType()->isVectorType());
12534 unsigned DestEltWidth = Source.getVectorElt(0).getInt().getBitWidth();
12535 unsigned DestLen = Source.getVectorLength();
12538 unsigned NumBitsInQWord = 64;
12539 unsigned NumCountElts = NumBitsInQWord / CountEltWidth;
12541 Result.reserve(DestLen);
12543 uint64_t CountLQWord = 0;
12544 for (
unsigned EltIdx = 0; EltIdx != NumCountElts; ++EltIdx) {
12546 CountLQWord |= (Elt << (EltIdx * CountEltWidth));
12549 for (
unsigned EltIdx = 0; EltIdx != DestLen; ++EltIdx) {
12550 APInt Elt = Source.getVectorElt(EltIdx).getInt();
12551 if (CountLQWord < DestEltWidth) {
12553 APValue(
APSInt(ShiftOp(Elt, CountLQWord), IsDestUnsigned)));
12556 APValue(
APSInt(OverflowOp(Elt, DestEltWidth), IsDestUnsigned)));
12564 std::optional<APSInt> RoundingMode,
12566 APSInt DefaultMode(APInt(32, 4),
true);
12567 if (RoundingMode.value_or(DefaultMode) != 4)
12568 return std::nullopt;
12569 if (A.isNaN() || A.isInfinity() || A.isDenormal() || B.isNaN() ||
12570 B.isInfinity() || B.isDenormal())
12571 return std::nullopt;
12572 if (A.isZero() && B.isZero())
12574 return IsMin ? llvm::minimum(A, B) : llvm::maximum(A, B);
12577bool VectorExprEvaluator::VisitCallExpr(
const CallExpr *E) {
12578 if (!IsConstantEvaluatedBuiltinCall(E))
12579 return ExprEvaluatorBaseTy::VisitCallExpr(E);
12583 auto EvaluateBinOpExpr =
12585 APValue SourceLHS, SourceRHS;
12591 QualType DestEltTy = DestTy->getElementType();
12592 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
12595 ResultElements.reserve(SourceLen);
12597 if (SourceRHS.
isInt()) {
12599 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12601 ResultElements.push_back(
12605 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12608 ResultElements.push_back(
12615 auto EvaluateFpBinOpExpr =
12616 [&](llvm::function_ref<std::optional<APFloat>(
12617 const APFloat &,
const APFloat &, std::optional<APSInt>)>
12619 bool IsScalar =
false) {
12629 std::optional<APSInt> RoundingMode;
12634 RoundingMode = Imm;
12639 ResultElements.reserve(NumElems);
12641 for (
unsigned EltNum = 0; EltNum < NumElems; ++EltNum) {
12642 if (IsScalar && EltNum > 0) {
12648 std::optional<APFloat>
Result =
Fn(EltA, EltB, RoundingMode);
12656 auto EvaluateScalarFpRoundMaskBinOp =
12657 [&](llvm::function_ref<std::optional<APFloat>(
12658 const APFloat &,
const APFloat &, std::optional<APSInt>)>
12662 APSInt MaskVal, Rounding;
12673 ResultElements.reserve(NumElems);
12675 if (MaskVal.getZExtValue() & 1) {
12678 std::optional<APFloat>
Result =
Fn(EltA, EltB, Rounding);
12686 for (
unsigned I = 1; I < NumElems; ++I)
12692 auto EvalSelectScalar = [&](
unsigned Len) ->
bool {
12700 bool TakeA0 = (Mask.getZExtValue() & 1u) != 0;
12704 for (
unsigned I = 1; I < Len; ++I)
12706 APValue V(Res.data(), Res.size());
12710 auto EvalVectorDotProduct = [&](
bool IsSaturating) ->
bool {
12711 APValue Source, OperandA, OperandB;
12720 unsigned ElemsPerLane = NumOperandElems / NumSrcElems;
12725 Result.reserve(NumSrcElems);
12726 for (
unsigned I = 0; I != NumSrcElems; ++I) {
12728 DotProduct = DotProduct.extend(64);
12729 for (
unsigned J = 0; J != ElemsPerLane; ++J) {
12736 DotProduct += OpA * OpB;
12738 if (IsSaturating) {
12739 DotProduct =
APSInt(DotProduct.truncSSat(32),
false);
12741 DotProduct =
APSInt(DotProduct.trunc(32),
false);
12749 switch (BuiltinOp) {
12752 case Builtin::BI__builtin_elementwise_popcount:
12753 case Builtin::BI__builtin_elementwise_bitreverse: {
12758 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12761 ResultElements.reserve(SourceLen);
12763 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12765 switch (BuiltinOp) {
12766 case Builtin::BI__builtin_elementwise_popcount:
12767 ResultElements.push_back(
APValue(
12768 APSInt(
APInt(Info.Ctx.getIntWidth(DestEltTy), Elt.popcount()),
12771 case Builtin::BI__builtin_elementwise_bitreverse:
12772 ResultElements.push_back(
12779 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12781 case Builtin::BI__builtin_elementwise_abs: {
12786 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12789 ResultElements.reserve(SourceLen);
12791 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12796 CurrentEle.getInt().
abs(),
12797 DestEltTy->isUnsignedIntegerOrEnumerationType()));
12798 ResultElements.push_back(Val);
12801 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12804 case Builtin::BI__builtin_elementwise_add_sat:
12805 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12806 return LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS);
12809 case Builtin::BI__builtin_elementwise_sub_sat:
12810 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12811 return LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
12814 case X86::BI__builtin_ia32_extract128i256:
12815 case X86::BI__builtin_ia32_vextractf128_pd256:
12816 case X86::BI__builtin_ia32_vextractf128_ps256:
12817 case X86::BI__builtin_ia32_vextractf128_si256: {
12818 APValue SourceVec, SourceImm;
12827 unsigned RetLen = RetVT->getNumElements();
12828 unsigned Idx = SourceImm.
getInt().getZExtValue() & 1;
12831 ResultElements.reserve(RetLen);
12833 for (
unsigned I = 0; I < RetLen; I++)
12834 ResultElements.push_back(SourceVec.
getVectorElt(Idx * RetLen + I));
12839 case clang::X86::BI__builtin_ia32_cvtmask2b128:
12840 case clang::X86::BI__builtin_ia32_cvtmask2b256:
12841 case clang::X86::BI__builtin_ia32_cvtmask2b512:
12842 case clang::X86::BI__builtin_ia32_cvtmask2w128:
12843 case clang::X86::BI__builtin_ia32_cvtmask2w256:
12844 case clang::X86::BI__builtin_ia32_cvtmask2w512:
12845 case clang::X86::BI__builtin_ia32_cvtmask2d128:
12846 case clang::X86::BI__builtin_ia32_cvtmask2d256:
12847 case clang::X86::BI__builtin_ia32_cvtmask2d512:
12848 case clang::X86::BI__builtin_ia32_cvtmask2q128:
12849 case clang::X86::BI__builtin_ia32_cvtmask2q256:
12850 case clang::X86::BI__builtin_ia32_cvtmask2q512: {
12856 QualType VecTy = E->
getType();
12857 const VectorType *VT = VecTy->
castAs<VectorType>();
12860 unsigned ElemWidth = Info.Ctx.getTypeSize(ElemTy);
12863 for (
unsigned I = 0; I != VectorLen; ++I) {
12864 bool BitSet = Mask[I];
12865 APSInt ElemVal(ElemWidth,
false);
12867 ElemVal.setAllBits();
12869 Elems.push_back(
APValue(ElemVal));
12874 case X86::BI__builtin_ia32_extracti32x4_256_mask:
12875 case X86::BI__builtin_ia32_extractf32x4_256_mask:
12876 case X86::BI__builtin_ia32_extracti32x4_mask:
12877 case X86::BI__builtin_ia32_extractf32x4_mask:
12878 case X86::BI__builtin_ia32_extracti32x8_mask:
12879 case X86::BI__builtin_ia32_extractf32x8_mask:
12880 case X86::BI__builtin_ia32_extracti64x2_256_mask:
12881 case X86::BI__builtin_ia32_extractf64x2_256_mask:
12882 case X86::BI__builtin_ia32_extracti64x2_512_mask:
12883 case X86::BI__builtin_ia32_extractf64x2_512_mask:
12884 case X86::BI__builtin_ia32_extracti64x4_mask:
12885 case X86::BI__builtin_ia32_extractf64x4_mask: {
12896 unsigned RetLen = RetVT->getNumElements();
12901 unsigned Lanes = SrcLen / RetLen;
12902 unsigned Lane =
static_cast<unsigned>(Imm.getZExtValue() % Lanes);
12903 unsigned Base = Lane * RetLen;
12906 ResultElements.reserve(RetLen);
12907 for (
unsigned I = 0; I < RetLen; ++I) {
12909 ResultElements.push_back(SourceVec.
getVectorElt(Base + I));
12913 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12916 case clang::X86::BI__builtin_ia32_pavgb128:
12917 case clang::X86::BI__builtin_ia32_pavgw128:
12918 case clang::X86::BI__builtin_ia32_pavgb256:
12919 case clang::X86::BI__builtin_ia32_pavgw256:
12920 case clang::X86::BI__builtin_ia32_pavgb512:
12921 case clang::X86::BI__builtin_ia32_pavgw512:
12922 return EvaluateBinOpExpr(llvm::APIntOps::avgCeilU);
12924 case clang::X86::BI__builtin_ia32_pmulhrsw128:
12925 case clang::X86::BI__builtin_ia32_pmulhrsw256:
12926 case clang::X86::BI__builtin_ia32_pmulhrsw512:
12927 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12928 return (llvm::APIntOps::mulsExtended(LHS, RHS).ashr(14) + 1)
12929 .extractBits(16, 1);
12932 case clang::X86::BI__builtin_ia32_psadbw128:
12933 case clang::X86::BI__builtin_ia32_psadbw256:
12934 case clang::X86::BI__builtin_ia32_psadbw512: {
12935 APValue SourceLHS, SourceRHS;
12943 assert((SourceLen % 8) == 0);
12946 QualType DestEltTy = DestTy->getElementType();
12947 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
12949 ResultElements.reserve(SourceLen / 8);
12951 for (
unsigned Lane = 0; Lane != SourceLen; Lane += 8) {
12953 for (
unsigned I = 0; I != 8; ++I) {
12956 Sum += llvm::APIntOps::abdu(LHS, RHS).zext(64);
12958 ResultElements.push_back(
APValue(
APSInt(Sum, DestUnsigned)));
12961 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12964 case clang::X86::BI__builtin_ia32_pmaddubsw128:
12965 case clang::X86::BI__builtin_ia32_pmaddubsw256:
12966 case clang::X86::BI__builtin_ia32_pmaddubsw512:
12967 case clang::X86::BI__builtin_ia32_pmaddwd128:
12968 case clang::X86::BI__builtin_ia32_pmaddwd256:
12969 case clang::X86::BI__builtin_ia32_pmaddwd512: {
12970 APValue SourceLHS, SourceRHS;
12976 QualType DestEltTy = DestTy->getElementType();
12978 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
12980 ResultElements.reserve(SourceLen / 2);
12982 for (
unsigned EltNum = 0; EltNum < SourceLen; EltNum += 2) {
12987 unsigned BitWidth = 2 * LoLHS.getBitWidth();
12989 switch (BuiltinOp) {
12990 case clang::X86::BI__builtin_ia32_pmaddubsw128:
12991 case clang::X86::BI__builtin_ia32_pmaddubsw256:
12992 case clang::X86::BI__builtin_ia32_pmaddubsw512:
12993 ResultElements.push_back(
APValue(
12994 APSInt((LoLHS.zext(BitWidth) * LoRHS.sext(BitWidth))
12995 .sadd_sat((HiLHS.zext(BitWidth) * HiRHS.sext(BitWidth))),
12998 case clang::X86::BI__builtin_ia32_pmaddwd128:
12999 case clang::X86::BI__builtin_ia32_pmaddwd256:
13000 case clang::X86::BI__builtin_ia32_pmaddwd512:
13001 ResultElements.push_back(
13002 APValue(
APSInt((LoLHS.sext(BitWidth) * LoRHS.sext(BitWidth)) +
13003 (HiLHS.sext(BitWidth) * HiRHS.sext(BitWidth)),
13009 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13012 case clang::X86::BI__builtin_ia32_bmacor16x16x16_v16hi:
13013 case clang::X86::BI__builtin_ia32_bmacor16x16x16_v32hi:
13014 case clang::X86::BI__builtin_ia32_bmacxor16x16x16_v16hi:
13015 case clang::X86::BI__builtin_ia32_bmacxor16x16x16_v32hi: {
13026 APValue SourceA, SourceB, SourceC;
13033 clang::X86::BI__builtin_ia32_bmacxor16x16x16_v16hi ||
13035 clang::X86::BI__builtin_ia32_bmacxor16x16x16_v32hi;
13038 assert(SourceLen % 16 == 0 &&
"BMM operates on 256-bit lanes of 16 x i16");
13040 QualType DestEltTy = DestTy->getElementType();
13041 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
13044 for (
unsigned Lane = 0; Lane != SourceLen; Lane += 16) {
13045 for (
unsigned I = 0; I != 16; ++I) {
13050 for (
unsigned J = 0; J != 16; ++J) {
13054 unsigned Bit = (Dst >> J) & 1u;
13055 for (
unsigned K = 0; K != 16; ++K) {
13059 unsigned Product = ((A >> K) & 1u) & ((B >> J) & 1u);
13060 Bit = IsXor ? (Bit ^ Product) : (Bit | Product);
13064 ResultElements[Lane + I] =
13068 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13071 case clang::X86::BI__builtin_ia32_dbpsadbw128:
13072 case clang::X86::BI__builtin_ia32_dbpsadbw256:
13073 case clang::X86::BI__builtin_ia32_dbpsadbw512: {
13074 APValue SourceA, SourceB, SourceImm;
13081 constexpr unsigned LaneSize = 16;
13082 unsigned Imm = SourceImm.
getInt().getZExtValue();
13085 QualType DestEltTy = DestTy->getElementType();
13086 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
13088 ResultElements.reserve(SourceLen / 2);
13094 for (
unsigned I = 0; I < SourceLen; I += LaneSize) {
13095 for (
unsigned J = 0; J < 4; ++J) {
13096 unsigned Part = (Imm >> (2 * J)) & 3;
13097 for (
unsigned K = 0; K < 4; ++K) {
13098 Shuffled[I + 4 * J + K] =
static_cast<uint8_t>(
13099 SourceB.
getVectorElt(I + 4 * Part + K).getInt().getZExtValue());
13107 unsigned Size = SourceLen / 2;
13108 for (
unsigned I = 0; I <
Size; I += 4) {
13109 unsigned Sad[4] = {0, 0, 0, 0};
13110 for (
unsigned J = 0; J < 4; ++J) {
13112 SourceA.
getVectorElt(2 * I + J).getInt().getZExtValue());
13114 SourceA.
getVectorElt(2 * I + J + 4).getInt().getZExtValue());
13115 uint8_t B0 = Shuffled[2 * I + J];
13116 uint8_t B1 = Shuffled[2 * I + J + 1];
13117 uint8_t B2 = Shuffled[2 * I + J + 2];
13118 uint8_t B3 = Shuffled[2 * I + J + 3];
13119 Sad[0] += (A1 > B0) ? (A1 - B0) : (B0 - A1);
13120 Sad[1] += (A1 > B1) ? (A1 - B1) : (B1 - A1);
13121 Sad[2] += (A2 > B2) ? (A2 - B2) : (B2 - A2);
13122 Sad[3] += (A2 > B3) ? (A2 - B3) : (B3 - A2);
13124 for (
unsigned R = 0;
R < 4; ++
R)
13125 ResultElements.push_back(
13129 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13132 case clang::X86::BI__builtin_ia32_mpsadbw128:
13133 case clang::X86::BI__builtin_ia32_mpsadbw256: {
13141 constexpr unsigned LaneSize = 16;
13142 assert((SourceLen == LaneSize || SourceLen == 2 * LaneSize) &&
13143 "MPSADBW operates on 128-bit or 256-bit vectors");
13144 unsigned NumLanes = SourceLen / LaneSize;
13145 unsigned Imm = SourceImm.getZExtValue();
13147 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13150 ResultElements.reserve(SourceLen / 2);
13152 for (
unsigned Lane = 0; Lane != NumLanes; ++Lane) {
13153 unsigned Ctrl = (Imm >> (3 * Lane)) & 0x7;
13154 unsigned AOff = ((Ctrl >> 2) & 1) * 4;
13155 unsigned BOff = (Ctrl & 3) * 4;
13156 for (
unsigned J = 0; J != 8; ++J) {
13158 for (
unsigned K = 0; K != 4; ++K) {
13167 Sad += (A > B) ? (A - B) : (B - A);
13172 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13175 case clang::X86::BI__builtin_ia32_pmulhuw128:
13176 case clang::X86::BI__builtin_ia32_pmulhuw256:
13177 case clang::X86::BI__builtin_ia32_pmulhuw512:
13178 return EvaluateBinOpExpr(llvm::APIntOps::mulhu);
13180 case clang::X86::BI__builtin_ia32_pmulhw128:
13181 case clang::X86::BI__builtin_ia32_pmulhw256:
13182 case clang::X86::BI__builtin_ia32_pmulhw512:
13183 return EvaluateBinOpExpr(llvm::APIntOps::mulhs);
13185 case clang::X86::BI__builtin_ia32_psllv2di:
13186 case clang::X86::BI__builtin_ia32_psllv4di:
13187 case clang::X86::BI__builtin_ia32_psllv4si:
13188 case clang::X86::BI__builtin_ia32_psllv8di:
13189 case clang::X86::BI__builtin_ia32_psllv8hi:
13190 case clang::X86::BI__builtin_ia32_psllv8si:
13191 case clang::X86::BI__builtin_ia32_psllv16hi:
13192 case clang::X86::BI__builtin_ia32_psllv16si:
13193 case clang::X86::BI__builtin_ia32_psllv32hi:
13194 case clang::X86::BI__builtin_ia32_psllwi128:
13195 case clang::X86::BI__builtin_ia32_pslldi128:
13196 case clang::X86::BI__builtin_ia32_psllqi128:
13197 case clang::X86::BI__builtin_ia32_psllwi256:
13198 case clang::X86::BI__builtin_ia32_pslldi256:
13199 case clang::X86::BI__builtin_ia32_psllqi256:
13200 case clang::X86::BI__builtin_ia32_psllwi512:
13201 case clang::X86::BI__builtin_ia32_pslldi512:
13202 case clang::X86::BI__builtin_ia32_psllqi512:
13203 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
13204 if (RHS.uge(LHS.getBitWidth())) {
13205 return APInt::getZero(LHS.getBitWidth());
13207 return LHS.shl(RHS.getZExtValue());
13210 case clang::X86::BI__builtin_ia32_psrav4si:
13211 case clang::X86::BI__builtin_ia32_psrav8di:
13212 case clang::X86::BI__builtin_ia32_psrav8hi:
13213 case clang::X86::BI__builtin_ia32_psrav8si:
13214 case clang::X86::BI__builtin_ia32_psrav16hi:
13215 case clang::X86::BI__builtin_ia32_psrav16si:
13216 case clang::X86::BI__builtin_ia32_psrav32hi:
13217 case clang::X86::BI__builtin_ia32_psravq128:
13218 case clang::X86::BI__builtin_ia32_psravq256:
13219 case clang::X86::BI__builtin_ia32_psrawi128:
13220 case clang::X86::BI__builtin_ia32_psradi128:
13221 case clang::X86::BI__builtin_ia32_psraqi128:
13222 case clang::X86::BI__builtin_ia32_psrawi256:
13223 case clang::X86::BI__builtin_ia32_psradi256:
13224 case clang::X86::BI__builtin_ia32_psraqi256:
13225 case clang::X86::BI__builtin_ia32_psrawi512:
13226 case clang::X86::BI__builtin_ia32_psradi512:
13227 case clang::X86::BI__builtin_ia32_psraqi512:
13228 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
13229 if (RHS.uge(LHS.getBitWidth())) {
13230 return LHS.ashr(LHS.getBitWidth() - 1);
13232 return LHS.ashr(RHS.getZExtValue());
13235 case clang::X86::BI__builtin_ia32_psrlv2di:
13236 case clang::X86::BI__builtin_ia32_psrlv4di:
13237 case clang::X86::BI__builtin_ia32_psrlv4si:
13238 case clang::X86::BI__builtin_ia32_psrlv8di:
13239 case clang::X86::BI__builtin_ia32_psrlv8hi:
13240 case clang::X86::BI__builtin_ia32_psrlv8si:
13241 case clang::X86::BI__builtin_ia32_psrlv16hi:
13242 case clang::X86::BI__builtin_ia32_psrlv16si:
13243 case clang::X86::BI__builtin_ia32_psrlv32hi:
13244 case clang::X86::BI__builtin_ia32_psrlwi128:
13245 case clang::X86::BI__builtin_ia32_psrldi128:
13246 case clang::X86::BI__builtin_ia32_psrlqi128:
13247 case clang::X86::BI__builtin_ia32_psrlwi256:
13248 case clang::X86::BI__builtin_ia32_psrldi256:
13249 case clang::X86::BI__builtin_ia32_psrlqi256:
13250 case clang::X86::BI__builtin_ia32_psrlwi512:
13251 case clang::X86::BI__builtin_ia32_psrldi512:
13252 case clang::X86::BI__builtin_ia32_psrlqi512:
13253 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
13254 if (RHS.uge(LHS.getBitWidth())) {
13255 return APInt::getZero(LHS.getBitWidth());
13257 return LHS.lshr(RHS.getZExtValue());
13259 case X86::BI__builtin_ia32_packsswb128:
13260 case X86::BI__builtin_ia32_packsswb256:
13261 case X86::BI__builtin_ia32_packsswb512:
13262 case X86::BI__builtin_ia32_packssdw128:
13263 case X86::BI__builtin_ia32_packssdw256:
13264 case X86::BI__builtin_ia32_packssdw512:
13266 return APSInt(Src).truncSSat(Src.getBitWidth() / 2);
13268 case X86::BI__builtin_ia32_packusdw128:
13269 case X86::BI__builtin_ia32_packusdw256:
13270 case X86::BI__builtin_ia32_packusdw512:
13271 case X86::BI__builtin_ia32_packuswb128:
13272 case X86::BI__builtin_ia32_packuswb256:
13273 case X86::BI__builtin_ia32_packuswb512:
13275 return APSInt(Src).truncSSatU(Src.getBitWidth() / 2);
13277 case clang::X86::BI__builtin_ia32_selectss_128:
13278 return EvalSelectScalar(4);
13279 case clang::X86::BI__builtin_ia32_selectsd_128:
13280 return EvalSelectScalar(2);
13281 case clang::X86::BI__builtin_ia32_selectsh_128:
13282 case clang::X86::BI__builtin_ia32_selectsbf_128:
13283 return EvalSelectScalar(8);
13284 case clang::X86::BI__builtin_ia32_pmuldq128:
13285 case clang::X86::BI__builtin_ia32_pmuldq256:
13286 case clang::X86::BI__builtin_ia32_pmuldq512:
13287 case clang::X86::BI__builtin_ia32_pmuludq128:
13288 case clang::X86::BI__builtin_ia32_pmuludq256:
13289 case clang::X86::BI__builtin_ia32_pmuludq512: {
13290 APValue SourceLHS, SourceRHS;
13297 ResultElements.reserve(SourceLen / 2);
13299 for (
unsigned EltNum = 0; EltNum < SourceLen; EltNum += 2) {
13303 switch (BuiltinOp) {
13304 case clang::X86::BI__builtin_ia32_pmuludq128:
13305 case clang::X86::BI__builtin_ia32_pmuludq256:
13306 case clang::X86::BI__builtin_ia32_pmuludq512:
13307 ResultElements.push_back(
13308 APValue(
APSInt(llvm::APIntOps::muluExtended(LHS, RHS),
true)));
13310 case clang::X86::BI__builtin_ia32_pmuldq128:
13311 case clang::X86::BI__builtin_ia32_pmuldq256:
13312 case clang::X86::BI__builtin_ia32_pmuldq512:
13313 ResultElements.push_back(
13314 APValue(
APSInt(llvm::APIntOps::mulsExtended(LHS, RHS),
false)));
13319 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13322 case X86::BI__builtin_ia32_vpmadd52luq128:
13323 case X86::BI__builtin_ia32_vpmadd52luq256:
13324 case X86::BI__builtin_ia32_vpmadd52luq512: {
13333 ResultElements.reserve(ALen);
13335 for (
unsigned EltNum = 0; EltNum < ALen; EltNum += 1) {
13338 APInt CElt =
C.getVectorElt(EltNum).getInt().trunc(52);
13339 APSInt ResElt(AElt + (BElt * CElt).zext(64),
false);
13340 ResultElements.push_back(
APValue(ResElt));
13343 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13345 case X86::BI__builtin_ia32_vpmadd52huq128:
13346 case X86::BI__builtin_ia32_vpmadd52huq256:
13347 case X86::BI__builtin_ia32_vpmadd52huq512: {
13356 ResultElements.reserve(ALen);
13358 for (
unsigned EltNum = 0; EltNum < ALen; EltNum += 1) {
13361 APInt CElt =
C.getVectorElt(EltNum).getInt().trunc(52);
13362 APSInt ResElt(AElt + llvm::APIntOps::mulhu(BElt, CElt).zext(64),
false);
13363 ResultElements.push_back(
APValue(ResElt));
13366 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13369 case clang::X86::BI__builtin_ia32_vprotbi:
13370 case clang::X86::BI__builtin_ia32_vprotdi:
13371 case clang::X86::BI__builtin_ia32_vprotqi:
13372 case clang::X86::BI__builtin_ia32_vprotwi:
13373 case clang::X86::BI__builtin_ia32_prold128:
13374 case clang::X86::BI__builtin_ia32_prold256:
13375 case clang::X86::BI__builtin_ia32_prold512:
13376 case clang::X86::BI__builtin_ia32_prolq128:
13377 case clang::X86::BI__builtin_ia32_prolq256:
13378 case clang::X86::BI__builtin_ia32_prolq512:
13379 return EvaluateBinOpExpr(
13380 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS.rotl(RHS); });
13382 case clang::X86::BI__builtin_ia32_prord128:
13383 case clang::X86::BI__builtin_ia32_prord256:
13384 case clang::X86::BI__builtin_ia32_prord512:
13385 case clang::X86::BI__builtin_ia32_prorq128:
13386 case clang::X86::BI__builtin_ia32_prorq256:
13387 case clang::X86::BI__builtin_ia32_prorq512:
13388 return EvaluateBinOpExpr(
13389 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS.rotr(RHS); });
13391 case Builtin::BI__builtin_elementwise_max:
13392 case Builtin::BI__builtin_elementwise_min: {
13393 APValue SourceLHS, SourceRHS;
13398 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13405 ResultElements.reserve(SourceLen);
13407 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13410 switch (BuiltinOp) {
13411 case Builtin::BI__builtin_elementwise_max:
13412 ResultElements.push_back(
13416 case Builtin::BI__builtin_elementwise_min:
13417 ResultElements.push_back(
13424 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13426 case X86::BI__builtin_ia32_vpshldd128:
13427 case X86::BI__builtin_ia32_vpshldd256:
13428 case X86::BI__builtin_ia32_vpshldd512:
13429 case X86::BI__builtin_ia32_vpshldq128:
13430 case X86::BI__builtin_ia32_vpshldq256:
13431 case X86::BI__builtin_ia32_vpshldq512:
13432 case X86::BI__builtin_ia32_vpshldw128:
13433 case X86::BI__builtin_ia32_vpshldw256:
13434 case X86::BI__builtin_ia32_vpshldw512: {
13435 APValue SourceHi, SourceLo, SourceAmt;
13441 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13444 ResultElements.reserve(SourceLen);
13447 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13450 APInt R = llvm::APIntOps::fshl(Hi, Lo, Amt);
13451 ResultElements.push_back(
13455 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13457 case X86::BI__builtin_ia32_vpshrdd128:
13458 case X86::BI__builtin_ia32_vpshrdd256:
13459 case X86::BI__builtin_ia32_vpshrdd512:
13460 case X86::BI__builtin_ia32_vpshrdq128:
13461 case X86::BI__builtin_ia32_vpshrdq256:
13462 case X86::BI__builtin_ia32_vpshrdq512:
13463 case X86::BI__builtin_ia32_vpshrdw128:
13464 case X86::BI__builtin_ia32_vpshrdw256:
13465 case X86::BI__builtin_ia32_vpshrdw512: {
13467 APValue SourceHi, SourceLo, SourceAmt;
13473 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13476 ResultElements.reserve(SourceLen);
13479 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13482 APInt R = llvm::APIntOps::fshr(Hi, Lo, Amt);
13483 ResultElements.push_back(
13487 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13489 case X86::BI__builtin_ia32_compressdf128_mask:
13490 case X86::BI__builtin_ia32_compressdf256_mask:
13491 case X86::BI__builtin_ia32_compressdf512_mask:
13492 case X86::BI__builtin_ia32_compressdi128_mask:
13493 case X86::BI__builtin_ia32_compressdi256_mask:
13494 case X86::BI__builtin_ia32_compressdi512_mask:
13495 case X86::BI__builtin_ia32_compresshi128_mask:
13496 case X86::BI__builtin_ia32_compresshi256_mask:
13497 case X86::BI__builtin_ia32_compresshi512_mask:
13498 case X86::BI__builtin_ia32_compressqi128_mask:
13499 case X86::BI__builtin_ia32_compressqi256_mask:
13500 case X86::BI__builtin_ia32_compressqi512_mask:
13501 case X86::BI__builtin_ia32_compresssf128_mask:
13502 case X86::BI__builtin_ia32_compresssf256_mask:
13503 case X86::BI__builtin_ia32_compresssf512_mask:
13504 case X86::BI__builtin_ia32_compresssi128_mask:
13505 case X86::BI__builtin_ia32_compresssi256_mask:
13506 case X86::BI__builtin_ia32_compresssi512_mask: {
13517 ResultElements.reserve(NumElts);
13519 for (
unsigned I = 0; I != NumElts; ++I) {
13523 for (
unsigned I = ResultElements.size(); I != NumElts; ++I) {
13527 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13529 case X86::BI__builtin_ia32_expanddf128_mask:
13530 case X86::BI__builtin_ia32_expanddf256_mask:
13531 case X86::BI__builtin_ia32_expanddf512_mask:
13532 case X86::BI__builtin_ia32_expanddi128_mask:
13533 case X86::BI__builtin_ia32_expanddi256_mask:
13534 case X86::BI__builtin_ia32_expanddi512_mask:
13535 case X86::BI__builtin_ia32_expandhi128_mask:
13536 case X86::BI__builtin_ia32_expandhi256_mask:
13537 case X86::BI__builtin_ia32_expandhi512_mask:
13538 case X86::BI__builtin_ia32_expandqi128_mask:
13539 case X86::BI__builtin_ia32_expandqi256_mask:
13540 case X86::BI__builtin_ia32_expandqi512_mask:
13541 case X86::BI__builtin_ia32_expandsf128_mask:
13542 case X86::BI__builtin_ia32_expandsf256_mask:
13543 case X86::BI__builtin_ia32_expandsf512_mask:
13544 case X86::BI__builtin_ia32_expandsi128_mask:
13545 case X86::BI__builtin_ia32_expandsi256_mask:
13546 case X86::BI__builtin_ia32_expandsi512_mask: {
13557 ResultElements.reserve(NumElts);
13559 unsigned SourceIdx = 0;
13560 for (
unsigned I = 0; I != NumElts; ++I) {
13562 ResultElements.push_back(Source.
getVectorElt(SourceIdx++));
13566 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13568 case X86::BI__builtin_ia32_vpconflictsi_128:
13569 case X86::BI__builtin_ia32_vpconflictsi_256:
13570 case X86::BI__builtin_ia32_vpconflictsi_512:
13571 case X86::BI__builtin_ia32_vpconflictdi_128:
13572 case X86::BI__builtin_ia32_vpconflictdi_256:
13573 case X86::BI__builtin_ia32_vpconflictdi_512: {
13581 ResultElements.reserve(SourceLen);
13584 bool DestUnsigned =
13585 VecT->getElementType()->isUnsignedIntegerOrEnumerationType();
13587 for (
unsigned I = 0; I != SourceLen; ++I) {
13590 APInt ConflictMask(EltI.
getInt().getBitWidth(), 0);
13591 for (
unsigned J = 0; J != I; ++J) {
13593 ConflictMask.setBitVal(J, EltI.
getInt() == EltJ.
getInt());
13595 ResultElements.push_back(
APValue(
APSInt(ConflictMask, DestUnsigned)));
13597 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13599 case X86::BI__builtin_ia32_blendpd:
13600 case X86::BI__builtin_ia32_blendpd256:
13601 case X86::BI__builtin_ia32_blendps:
13602 case X86::BI__builtin_ia32_blendps256:
13603 case X86::BI__builtin_ia32_pblendw128:
13604 case X86::BI__builtin_ia32_pblendw256:
13605 case X86::BI__builtin_ia32_pblendd128:
13606 case X86::BI__builtin_ia32_pblendd256: {
13607 APValue SourceF, SourceT, SourceC;
13616 ResultElements.reserve(SourceLen);
13617 for (
unsigned EltNum = 0; EltNum != SourceLen; ++EltNum) {
13620 ResultElements.push_back(
C[EltNum % 8] ?
T : F);
13623 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13626 case X86::BI__builtin_ia32_psignb128:
13627 case X86::BI__builtin_ia32_psignb256:
13628 case X86::BI__builtin_ia32_psignw128:
13629 case X86::BI__builtin_ia32_psignw256:
13630 case X86::BI__builtin_ia32_psignd128:
13631 case X86::BI__builtin_ia32_psignd256:
13632 return EvaluateBinOpExpr([](
const APInt &AElem,
const APInt &BElem) {
13633 if (BElem.isZero())
13634 return APInt::getZero(AElem.getBitWidth());
13635 if (BElem.isNegative())
13640 case X86::BI__builtin_ia32_blendvpd:
13641 case X86::BI__builtin_ia32_blendvpd256:
13642 case X86::BI__builtin_ia32_blendvps:
13643 case X86::BI__builtin_ia32_blendvps256:
13644 case X86::BI__builtin_ia32_pblendvb128:
13645 case X86::BI__builtin_ia32_pblendvb256: {
13647 APValue SourceF, SourceT, SourceC;
13655 ResultElements.reserve(SourceLen);
13657 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13661 APInt M =
C.isInt() ? (
APInt)
C.getInt() :
C.getFloat().bitcastToAPInt();
13662 ResultElements.push_back(M.isNegative() ?
T : F);
13665 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13667 case X86::BI__builtin_ia32_selectb_128:
13668 case X86::BI__builtin_ia32_selectb_256:
13669 case X86::BI__builtin_ia32_selectb_512:
13670 case X86::BI__builtin_ia32_selectw_128:
13671 case X86::BI__builtin_ia32_selectw_256:
13672 case X86::BI__builtin_ia32_selectw_512:
13673 case X86::BI__builtin_ia32_selectd_128:
13674 case X86::BI__builtin_ia32_selectd_256:
13675 case X86::BI__builtin_ia32_selectd_512:
13676 case X86::BI__builtin_ia32_selectq_128:
13677 case X86::BI__builtin_ia32_selectq_256:
13678 case X86::BI__builtin_ia32_selectq_512:
13679 case X86::BI__builtin_ia32_selectph_128:
13680 case X86::BI__builtin_ia32_selectph_256:
13681 case X86::BI__builtin_ia32_selectph_512:
13682 case X86::BI__builtin_ia32_selectpbf_128:
13683 case X86::BI__builtin_ia32_selectpbf_256:
13684 case X86::BI__builtin_ia32_selectpbf_512:
13685 case X86::BI__builtin_ia32_selectps_128:
13686 case X86::BI__builtin_ia32_selectps_256:
13687 case X86::BI__builtin_ia32_selectps_512:
13688 case X86::BI__builtin_ia32_selectpd_128:
13689 case X86::BI__builtin_ia32_selectpd_256:
13690 case X86::BI__builtin_ia32_selectpd_512: {
13692 APValue SourceMask, SourceLHS, SourceRHS;
13701 ResultElements.reserve(SourceLen);
13703 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13706 ResultElements.push_back(Mask[EltNum] ? LHS : RHS);
13709 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13712 case X86::BI__builtin_ia32_cvtsd2ss: {
13725 Elements.push_back(ResultVal);
13728 for (
unsigned I = 1; I < NumEltsA; ++I) {
13734 case X86::BI__builtin_ia32_cvtsd2ss_round_mask: {
13735 APValue VecA, VecB, VecSrc, MaskValue;
13743 unsigned Mask = MaskValue.
getInt().getZExtValue();
13751 Elements.push_back(ResultVal);
13757 for (
unsigned I = 1; I < NumEltsA; ++I) {
13763 case X86::BI__builtin_ia32_cvtpd2ps:
13764 case X86::BI__builtin_ia32_cvtpd2ps256:
13765 case X86::BI__builtin_ia32_cvtpd2ps_mask:
13766 case X86::BI__builtin_ia32_cvtpd2ps512_mask: {
13768 const auto BuiltinID = BuiltinOp;
13769 bool IsMasked = (BuiltinID == X86::BI__builtin_ia32_cvtpd2ps_mask ||
13770 BuiltinID == X86::BI__builtin_ia32_cvtpd2ps512_mask);
13777 unsigned Mask = 0xFFFFFFFF;
13778 bool NeedsMerge =
false;
13783 Mask = MaskValue.
getInt().getZExtValue();
13784 auto NumEltsResult = E->
getType()->
getAs<VectorType>()->getNumElements();
13785 for (
unsigned I = 0; I < NumEltsResult; ++I) {
13786 if (!((Mask >> I) & 1)) {
13797 unsigned NumEltsResult =
13801 for (
unsigned I = 0; I < NumEltsResult; ++I) {
13802 if (IsMasked && !((Mask >> I) & 1)) {
13810 if (I >= NumEltsInput) {
13811 Elements.push_back(
APValue(APFloat::getZero(APFloat::IEEEsingle())));
13820 Elements.push_back(ResultVal);
13825 case X86::BI__builtin_ia32_shufps:
13826 case X86::BI__builtin_ia32_shufps256:
13827 case X86::BI__builtin_ia32_shufps512: {
13831 [](
unsigned DstIdx,
13832 unsigned ShuffleMask) -> std::pair<unsigned, int> {
13833 constexpr unsigned LaneBits = 128u;
13834 unsigned NumElemPerLane = LaneBits / 32;
13835 unsigned NumSelectableElems = NumElemPerLane / 2;
13836 unsigned BitsPerElem = 2;
13837 unsigned IndexMask = (1u << BitsPerElem) - 1;
13838 unsigned MaskBits = 8;
13839 unsigned Lane = DstIdx / NumElemPerLane;
13840 unsigned ElemInLane = DstIdx % NumElemPerLane;
13841 unsigned LaneOffset = Lane * NumElemPerLane;
13842 unsigned BitIndex = (DstIdx * BitsPerElem) % MaskBits;
13843 unsigned SrcIdx = (ElemInLane < NumSelectableElems) ? 0 : 1;
13844 unsigned Index = (ShuffleMask >> BitIndex) & IndexMask;
13845 return {SrcIdx,
static_cast<int>(LaneOffset + Index)};
13850 case X86::BI__builtin_ia32_shufpd:
13851 case X86::BI__builtin_ia32_shufpd256:
13852 case X86::BI__builtin_ia32_shufpd512: {
13856 [](
unsigned DstIdx,
13857 unsigned ShuffleMask) -> std::pair<unsigned, int> {
13858 constexpr unsigned LaneBits = 128u;
13859 unsigned NumElemPerLane = LaneBits / 64;
13860 unsigned NumSelectableElems = NumElemPerLane / 2;
13861 unsigned BitsPerElem = 1;
13862 unsigned IndexMask = (1u << BitsPerElem) - 1;
13863 unsigned MaskBits = 8;
13864 unsigned Lane = DstIdx / NumElemPerLane;
13865 unsigned ElemInLane = DstIdx % NumElemPerLane;
13866 unsigned LaneOffset = Lane * NumElemPerLane;
13867 unsigned BitIndex = (DstIdx * BitsPerElem) % MaskBits;
13868 unsigned SrcIdx = (ElemInLane < NumSelectableElems) ? 0 : 1;
13869 unsigned Index = (ShuffleMask >> BitIndex) & IndexMask;
13870 return {SrcIdx,
static_cast<int>(LaneOffset + Index)};
13875 case X86::BI__builtin_ia32_insertps128: {
13879 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13881 if ((Mask & (1 << DstIdx)) != 0) {
13886 unsigned SrcElem = (Mask >> 6) & 0x3;
13887 unsigned DstElem = (Mask >> 4) & 0x3;
13888 if (DstIdx == DstElem) {
13890 return {1,
static_cast<int>(SrcElem)};
13893 return {0,
static_cast<int>(DstIdx)};
13899 case X86::BI__builtin_ia32_pshufb128:
13900 case X86::BI__builtin_ia32_pshufb256:
13901 case X86::BI__builtin_ia32_pshufb512: {
13905 [](
unsigned DstIdx,
13906 unsigned ShuffleMask) -> std::pair<unsigned, int> {
13909 return std::make_pair(0, -1);
13911 unsigned LaneBase = (DstIdx / 16) * 16;
13912 unsigned SrcOffset = Ctlb & 0x0F;
13913 unsigned SrcIdx = LaneBase + SrcOffset;
13914 return std::make_pair(0,
static_cast<int>(SrcIdx));
13920 case X86::BI__builtin_ia32_pshuflw:
13921 case X86::BI__builtin_ia32_pshuflw256:
13922 case X86::BI__builtin_ia32_pshuflw512: {
13926 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13927 constexpr unsigned LaneBits = 128u;
13928 constexpr unsigned ElemBits = 16u;
13929 constexpr unsigned LaneElts = LaneBits / ElemBits;
13930 constexpr unsigned HalfSize = 4;
13931 unsigned LaneBase = (DstIdx / LaneElts) * LaneElts;
13932 unsigned LaneIdx = DstIdx % LaneElts;
13933 if (LaneIdx < HalfSize) {
13934 unsigned Sel = (Mask >> (2 * LaneIdx)) & 0x3;
13935 return std::make_pair(0,
static_cast<int>(LaneBase + Sel));
13937 return std::make_pair(0,
static_cast<int>(DstIdx));
13943 case X86::BI__builtin_ia32_pshufhw:
13944 case X86::BI__builtin_ia32_pshufhw256:
13945 case X86::BI__builtin_ia32_pshufhw512: {
13949 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13950 constexpr unsigned LaneBits = 128u;
13951 constexpr unsigned ElemBits = 16u;
13952 constexpr unsigned LaneElts = LaneBits / ElemBits;
13953 constexpr unsigned HalfSize = 4;
13954 unsigned LaneBase = (DstIdx / LaneElts) * LaneElts;
13955 unsigned LaneIdx = DstIdx % LaneElts;
13956 if (LaneIdx >= HalfSize) {
13957 unsigned Rel = LaneIdx - HalfSize;
13958 unsigned Sel = (Mask >> (2 * Rel)) & 0x3;
13959 return std::make_pair(
13960 0,
static_cast<int>(LaneBase + HalfSize + Sel));
13962 return std::make_pair(0,
static_cast<int>(DstIdx));
13968 case X86::BI__builtin_ia32_pshufd:
13969 case X86::BI__builtin_ia32_pshufd256:
13970 case X86::BI__builtin_ia32_pshufd512:
13971 case X86::BI__builtin_ia32_vpermilps:
13972 case X86::BI__builtin_ia32_vpermilps256:
13973 case X86::BI__builtin_ia32_vpermilps512: {
13977 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13978 constexpr unsigned LaneBits = 128u;
13979 constexpr unsigned ElemBits = 32u;
13980 constexpr unsigned LaneElts = LaneBits / ElemBits;
13981 unsigned LaneBase = (DstIdx / LaneElts) * LaneElts;
13982 unsigned LaneIdx = DstIdx % LaneElts;
13983 unsigned Sel = (Mask >> (2 * LaneIdx)) & 0x3;
13984 return std::make_pair(0,
static_cast<int>(LaneBase + Sel));
13990 case X86::BI__builtin_ia32_vpermilvarpd:
13991 case X86::BI__builtin_ia32_vpermilvarpd256:
13992 case X86::BI__builtin_ia32_vpermilvarpd512: {
13996 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13997 unsigned NumElemPerLane = 2;
13998 unsigned Lane = DstIdx / NumElemPerLane;
13999 unsigned Offset = Mask & 0b10 ? 1 : 0;
14000 return std::make_pair(
14001 0,
static_cast<int>(Lane * NumElemPerLane + Offset));
14007 case X86::BI__builtin_ia32_vpermilpd:
14008 case X86::BI__builtin_ia32_vpermilpd256:
14009 case X86::BI__builtin_ia32_vpermilpd512: {
14012 unsigned NumElemPerLane = 2;
14013 unsigned BitsPerElem = 1;
14014 unsigned MaskBits = 8;
14015 unsigned IndexMask = 0x1;
14016 unsigned Lane = DstIdx / NumElemPerLane;
14017 unsigned LaneOffset = Lane * NumElemPerLane;
14018 unsigned BitIndex = (DstIdx * BitsPerElem) % MaskBits;
14019 unsigned Index = (Control >> BitIndex) & IndexMask;
14020 return std::make_pair(0,
static_cast<int>(LaneOffset + Index));
14026 case X86::BI__builtin_ia32_permdf256:
14027 case X86::BI__builtin_ia32_permdi256: {
14032 unsigned Index = (Control >> (2 * DstIdx)) & 0x3;
14033 return std::make_pair(0,
static_cast<int>(Index));
14039 case X86::BI__builtin_ia32_vpermilvarps:
14040 case X86::BI__builtin_ia32_vpermilvarps256:
14041 case X86::BI__builtin_ia32_vpermilvarps512: {
14045 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
14046 unsigned NumElemPerLane = 4;
14047 unsigned Lane = DstIdx / NumElemPerLane;
14048 unsigned Offset = Mask & 0b11;
14049 return std::make_pair(
14050 0,
static_cast<int>(Lane * NumElemPerLane + Offset));
14056 case X86::BI__builtin_ia32_vpmultishiftqb128:
14057 case X86::BI__builtin_ia32_vpmultishiftqb256:
14058 case X86::BI__builtin_ia32_vpmultishiftqb512: {
14066 unsigned NumBytesInQWord = 8;
14067 unsigned NumBitsInByte = 8;
14069 unsigned NumQWords = NumBytes / NumBytesInQWord;
14071 Result.reserve(NumBytes);
14073 for (
unsigned QWordId = 0; QWordId != NumQWords; ++QWordId) {
14074 APInt BQWord(64, 0);
14075 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
14076 unsigned Idx = QWordId * NumBytesInQWord + ByteIdx;
14078 BQWord.insertBits(
APInt(8, Byte & 0xFF), ByteIdx * NumBitsInByte);
14081 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
14082 unsigned Idx = QWordId * NumBytesInQWord + ByteIdx;
14086 for (
unsigned BitIdx = 0; BitIdx != NumBitsInByte; ++BitIdx) {
14087 Byte.setBitVal(BitIdx, BQWord[(Ctrl + BitIdx) & 0x3F]);
14095 case X86::BI__builtin_ia32_phminposuw128: {
14102 unsigned ElemBitWidth = Info.Ctx.getTypeSize(ElemQT);
14104 APInt MinIndex(ElemBitWidth, 0);
14106 for (
unsigned I = 1; I != SourceLen; ++I) {
14108 if (MinVal.ugt(Val)) {
14117 ->isUnsignedIntegerOrEnumerationType();
14120 Result.reserve(SourceLen);
14122 Result.emplace_back(
APSInt(MinIndex, ResultUnsigned));
14123 for (
unsigned I = 0; I != SourceLen - 2; ++I) {
14129 case X86::BI__builtin_ia32_psraq128:
14130 case X86::BI__builtin_ia32_psraq256:
14131 case X86::BI__builtin_ia32_psraq512:
14132 case X86::BI__builtin_ia32_psrad128:
14133 case X86::BI__builtin_ia32_psrad256:
14134 case X86::BI__builtin_ia32_psrad512:
14135 case X86::BI__builtin_ia32_psraw128:
14136 case X86::BI__builtin_ia32_psraw256:
14137 case X86::BI__builtin_ia32_psraw512: {
14141 [](
const APInt &Elt, uint64_t Count) {
return Elt.ashr(Count); },
14142 [](
const APInt &Elt,
unsigned Width) {
14143 return Elt.ashr(Width - 1);
14149 case X86::BI__builtin_ia32_psllq128:
14150 case X86::BI__builtin_ia32_psllq256:
14151 case X86::BI__builtin_ia32_psllq512:
14152 case X86::BI__builtin_ia32_pslld128:
14153 case X86::BI__builtin_ia32_pslld256:
14154 case X86::BI__builtin_ia32_pslld512:
14155 case X86::BI__builtin_ia32_psllw128:
14156 case X86::BI__builtin_ia32_psllw256:
14157 case X86::BI__builtin_ia32_psllw512: {
14161 [](
const APInt &Elt, uint64_t Count) {
return Elt.shl(Count); },
14162 [](
const APInt &Elt,
unsigned Width) {
14163 return APInt::getZero(Width);
14169 case X86::BI__builtin_ia32_psrlq128:
14170 case X86::BI__builtin_ia32_psrlq256:
14171 case X86::BI__builtin_ia32_psrlq512:
14172 case X86::BI__builtin_ia32_psrld128:
14173 case X86::BI__builtin_ia32_psrld256:
14174 case X86::BI__builtin_ia32_psrld512:
14175 case X86::BI__builtin_ia32_psrlw128:
14176 case X86::BI__builtin_ia32_psrlw256:
14177 case X86::BI__builtin_ia32_psrlw512: {
14181 [](
const APInt &Elt, uint64_t Count) {
return Elt.lshr(Count); },
14182 [](
const APInt &Elt,
unsigned Width) {
14183 return APInt::getZero(Width);
14189 case X86::BI__builtin_ia32_pternlogd128_mask:
14190 case X86::BI__builtin_ia32_pternlogd256_mask:
14191 case X86::BI__builtin_ia32_pternlogd512_mask:
14192 case X86::BI__builtin_ia32_pternlogq128_mask:
14193 case X86::BI__builtin_ia32_pternlogq256_mask:
14194 case X86::BI__builtin_ia32_pternlogq512_mask: {
14195 APValue AValue, BValue, CValue, ImmValue, UValue;
14203 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14209 ResultElements.reserve(ResultLen);
14211 for (
unsigned EltNum = 0; EltNum < ResultLen; ++EltNum) {
14217 unsigned BitWidth = ALane.getBitWidth();
14218 APInt ResLane(BitWidth, 0);
14220 for (
unsigned Bit = 0; Bit < BitWidth; ++Bit) {
14221 unsigned ABit = ALane[Bit];
14222 unsigned BBit = BLane[Bit];
14223 unsigned CBit = CLane[Bit];
14225 unsigned Idx = (ABit << 2) | (BBit << 1) | CBit;
14226 ResLane.setBitVal(Bit, Imm[Idx]);
14228 ResultElements.push_back(
APValue(
APSInt(ResLane, DestUnsigned)));
14230 ResultElements.push_back(
APValue(
APSInt(ALane, DestUnsigned)));
14233 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14235 case X86::BI__builtin_ia32_pternlogd128_maskz:
14236 case X86::BI__builtin_ia32_pternlogd256_maskz:
14237 case X86::BI__builtin_ia32_pternlogd512_maskz:
14238 case X86::BI__builtin_ia32_pternlogq128_maskz:
14239 case X86::BI__builtin_ia32_pternlogq256_maskz:
14240 case X86::BI__builtin_ia32_pternlogq512_maskz: {
14241 APValue AValue, BValue, CValue, ImmValue, UValue;
14249 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14255 ResultElements.reserve(ResultLen);
14257 for (
unsigned EltNum = 0; EltNum < ResultLen; ++EltNum) {
14262 unsigned BitWidth = ALane.getBitWidth();
14263 APInt ResLane(BitWidth, 0);
14266 for (
unsigned Bit = 0; Bit < BitWidth; ++Bit) {
14267 unsigned ABit = ALane[Bit];
14268 unsigned BBit = BLane[Bit];
14269 unsigned CBit = CLane[Bit];
14271 unsigned Idx = (ABit << 2) | (BBit << 1) | CBit;
14272 ResLane.setBitVal(Bit, Imm[Idx]);
14275 ResultElements.push_back(
APValue(
APSInt(ResLane, DestUnsigned)));
14277 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14280 case Builtin::BI__builtin_elementwise_clzg:
14281 case Builtin::BI__builtin_elementwise_ctzg: {
14283 std::optional<APValue> Fallback;
14290 Fallback = FallbackTmp;
14293 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14296 ResultElements.reserve(SourceLen);
14298 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
14303 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
14305 Builtin::BI__builtin_elementwise_ctzg);
14308 ResultElements.push_back(Fallback->getVectorElt(EltNum));
14311 switch (BuiltinOp) {
14312 case Builtin::BI__builtin_elementwise_clzg:
14313 ResultElements.push_back(
APValue(
14314 APSInt(
APInt(Info.Ctx.getIntWidth(DestEltTy), LHS.countl_zero()),
14317 case Builtin::BI__builtin_elementwise_ctzg:
14318 ResultElements.push_back(
APValue(
14319 APSInt(
APInt(Info.Ctx.getIntWidth(DestEltTy), LHS.countr_zero()),
14325 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14328 case Builtin::BI__builtin_elementwise_fma: {
14329 APValue SourceX, SourceY, SourceZ;
14337 ResultElements.reserve(SourceLen);
14339 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
14344 (void)
Result.fusedMultiplyAdd(Y, Z, RM);
14347 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14350 case clang::X86::BI__builtin_ia32_phaddw128:
14351 case clang::X86::BI__builtin_ia32_phaddw256:
14352 case clang::X86::BI__builtin_ia32_phaddd128:
14353 case clang::X86::BI__builtin_ia32_phaddd256:
14354 case clang::X86::BI__builtin_ia32_phaddsw128:
14355 case clang::X86::BI__builtin_ia32_phaddsw256:
14357 case clang::X86::BI__builtin_ia32_phsubw128:
14358 case clang::X86::BI__builtin_ia32_phsubw256:
14359 case clang::X86::BI__builtin_ia32_phsubd128:
14360 case clang::X86::BI__builtin_ia32_phsubd256:
14361 case clang::X86::BI__builtin_ia32_phsubsw128:
14362 case clang::X86::BI__builtin_ia32_phsubsw256: {
14363 APValue SourceLHS, SourceRHS;
14367 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14371 unsigned EltBits = Info.Ctx.getIntWidth(DestEltTy);
14372 unsigned EltsPerLane = 128 / EltBits;
14374 ResultElements.reserve(NumElts);
14376 for (
unsigned LaneStart = 0; LaneStart != NumElts;
14377 LaneStart += EltsPerLane) {
14378 for (
unsigned I = 0; I != EltsPerLane; I += 2) {
14381 switch (BuiltinOp) {
14382 case clang::X86::BI__builtin_ia32_phaddw128:
14383 case clang::X86::BI__builtin_ia32_phaddw256:
14384 case clang::X86::BI__builtin_ia32_phaddd128:
14385 case clang::X86::BI__builtin_ia32_phaddd256: {
14386 APSInt Res(LHSA + LHSB, DestUnsigned);
14387 ResultElements.push_back(
APValue(Res));
14390 case clang::X86::BI__builtin_ia32_phaddsw128:
14391 case clang::X86::BI__builtin_ia32_phaddsw256: {
14392 APSInt Res(LHSA.sadd_sat(LHSB));
14393 ResultElements.push_back(
APValue(Res));
14396 case clang::X86::BI__builtin_ia32_phsubw128:
14397 case clang::X86::BI__builtin_ia32_phsubw256:
14398 case clang::X86::BI__builtin_ia32_phsubd128:
14399 case clang::X86::BI__builtin_ia32_phsubd256: {
14400 APSInt Res(LHSA - LHSB, DestUnsigned);
14401 ResultElements.push_back(
APValue(Res));
14404 case clang::X86::BI__builtin_ia32_phsubsw128:
14405 case clang::X86::BI__builtin_ia32_phsubsw256: {
14406 APSInt Res(LHSA.ssub_sat(LHSB));
14407 ResultElements.push_back(
APValue(Res));
14412 for (
unsigned I = 0; I != EltsPerLane; I += 2) {
14415 switch (BuiltinOp) {
14416 case clang::X86::BI__builtin_ia32_phaddw128:
14417 case clang::X86::BI__builtin_ia32_phaddw256:
14418 case clang::X86::BI__builtin_ia32_phaddd128:
14419 case clang::X86::BI__builtin_ia32_phaddd256: {
14420 APSInt Res(RHSA + RHSB, DestUnsigned);
14421 ResultElements.push_back(
APValue(Res));
14424 case clang::X86::BI__builtin_ia32_phaddsw128:
14425 case clang::X86::BI__builtin_ia32_phaddsw256: {
14426 APSInt Res(RHSA.sadd_sat(RHSB));
14427 ResultElements.push_back(
APValue(Res));
14430 case clang::X86::BI__builtin_ia32_phsubw128:
14431 case clang::X86::BI__builtin_ia32_phsubw256:
14432 case clang::X86::BI__builtin_ia32_phsubd128:
14433 case clang::X86::BI__builtin_ia32_phsubd256: {
14434 APSInt Res(RHSA - RHSB, DestUnsigned);
14435 ResultElements.push_back(
APValue(Res));
14438 case clang::X86::BI__builtin_ia32_phsubsw128:
14439 case clang::X86::BI__builtin_ia32_phsubsw256: {
14440 APSInt Res(RHSA.ssub_sat(RHSB));
14441 ResultElements.push_back(
APValue(Res));
14447 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14449 case clang::X86::BI__builtin_ia32_haddpd:
14450 case clang::X86::BI__builtin_ia32_haddps:
14451 case clang::X86::BI__builtin_ia32_haddps256:
14452 case clang::X86::BI__builtin_ia32_haddpd256:
14453 case clang::X86::BI__builtin_ia32_hsubpd:
14454 case clang::X86::BI__builtin_ia32_hsubps:
14455 case clang::X86::BI__builtin_ia32_hsubps256:
14456 case clang::X86::BI__builtin_ia32_hsubpd256: {
14457 APValue SourceLHS, SourceRHS;
14463 ResultElements.reserve(NumElts);
14465 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14466 unsigned EltBits = Info.Ctx.getTypeSize(DestEltTy);
14467 unsigned NumLanes = NumElts * EltBits / 128;
14468 unsigned NumElemsPerLane = NumElts / NumLanes;
14469 unsigned HalfElemsPerLane = NumElemsPerLane / 2;
14471 for (
unsigned L = 0; L != NumElts; L += NumElemsPerLane) {
14472 for (
unsigned I = 0; I != HalfElemsPerLane; ++I) {
14475 switch (BuiltinOp) {
14476 case clang::X86::BI__builtin_ia32_haddpd:
14477 case clang::X86::BI__builtin_ia32_haddps:
14478 case clang::X86::BI__builtin_ia32_haddps256:
14479 case clang::X86::BI__builtin_ia32_haddpd256:
14480 LHSA.add(LHSB, RM);
14482 case clang::X86::BI__builtin_ia32_hsubpd:
14483 case clang::X86::BI__builtin_ia32_hsubps:
14484 case clang::X86::BI__builtin_ia32_hsubps256:
14485 case clang::X86::BI__builtin_ia32_hsubpd256:
14486 LHSA.subtract(LHSB, RM);
14489 ResultElements.push_back(
APValue(LHSA));
14491 for (
unsigned I = 0; I != HalfElemsPerLane; ++I) {
14494 switch (BuiltinOp) {
14495 case clang::X86::BI__builtin_ia32_haddpd:
14496 case clang::X86::BI__builtin_ia32_haddps:
14497 case clang::X86::BI__builtin_ia32_haddps256:
14498 case clang::X86::BI__builtin_ia32_haddpd256:
14499 RHSA.add(RHSB, RM);
14501 case clang::X86::BI__builtin_ia32_hsubpd:
14502 case clang::X86::BI__builtin_ia32_hsubps:
14503 case clang::X86::BI__builtin_ia32_hsubps256:
14504 case clang::X86::BI__builtin_ia32_hsubpd256:
14505 RHSA.subtract(RHSB, RM);
14508 ResultElements.push_back(
APValue(RHSA));
14511 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14513 case clang::X86::BI__builtin_ia32_addsubpd:
14514 case clang::X86::BI__builtin_ia32_addsubps:
14515 case clang::X86::BI__builtin_ia32_addsubpd256:
14516 case clang::X86::BI__builtin_ia32_addsubps256: {
14519 APValue SourceLHS, SourceRHS;
14525 ResultElements.reserve(NumElems);
14528 for (
unsigned I = 0; I != NumElems; ++I) {
14533 LHS.subtract(RHS, RM);
14538 ResultElements.push_back(
APValue(LHS));
14540 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14542 case clang::X86::BI__builtin_ia32_pclmulqdq128:
14543 case clang::X86::BI__builtin_ia32_pclmulqdq256:
14544 case clang::X86::BI__builtin_ia32_pclmulqdq512: {
14548 APValue SourceLHS, SourceRHS;
14558 bool SelectUpperA = (Imm8 & 0x01) != 0;
14559 bool SelectUpperB = (Imm8 & 0x10) != 0;
14563 ResultElements.reserve(NumElems);
14564 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14568 for (
unsigned Lane = 0; Lane < NumElems; Lane += 2) {
14577 APInt A = SelectUpperA ? A1 : A0;
14578 APInt B = SelectUpperB ? B1 : B0;
14581 APInt A128 = A.zext(128);
14582 APInt B128 = B.zext(128);
14585 APInt Result = llvm::APIntOps::clmul(A128, B128);
14588 APSInt ResultLow(
Result.extractBits(64, 0), DestUnsigned);
14589 APSInt ResultHigh(
Result.extractBits(64, 64), DestUnsigned);
14591 ResultElements.push_back(
APValue(ResultLow));
14592 ResultElements.push_back(
APValue(ResultHigh));
14595 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14597 case Builtin::BI__builtin_elementwise_clmul:
14598 return EvaluateBinOpExpr(llvm::APIntOps::clmul);
14599 case Builtin::BI__builtin_elementwise_pext:
14600 return EvaluateBinOpExpr(llvm::APIntOps::pext);
14601 case Builtin::BI__builtin_elementwise_pdep:
14602 return EvaluateBinOpExpr(llvm::APIntOps::pdep);
14603 case Builtin::BI__builtin_elementwise_fshl:
14604 case Builtin::BI__builtin_elementwise_fshr: {
14605 APValue SourceHi, SourceLo, SourceShift;
14611 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14617 ResultElements.reserve(SourceLen);
14618 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
14622 switch (BuiltinOp) {
14623 case Builtin::BI__builtin_elementwise_fshl:
14624 ResultElements.push_back(
APValue(
14625 APSInt(llvm::APIntOps::fshl(Hi, Lo, Shift), Hi.isUnsigned())));
14627 case Builtin::BI__builtin_elementwise_fshr:
14628 ResultElements.push_back(
APValue(
14629 APSInt(llvm::APIntOps::fshr(Hi, Lo, Shift), Hi.isUnsigned())));
14634 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14637 case X86::BI__builtin_ia32_shuf_f32x4_256:
14638 case X86::BI__builtin_ia32_shuf_i32x4_256:
14639 case X86::BI__builtin_ia32_shuf_f64x2_256:
14640 case X86::BI__builtin_ia32_shuf_i64x2_256:
14641 case X86::BI__builtin_ia32_shuf_f32x4:
14642 case X86::BI__builtin_ia32_shuf_i32x4:
14643 case X86::BI__builtin_ia32_shuf_f64x2:
14644 case X86::BI__builtin_ia32_shuf_i64x2: {
14658 unsigned ElemBits = Info.Ctx.getTypeSize(ElemQT);
14659 unsigned LaneBits = 128u;
14660 unsigned NumLanes = (NumElems * ElemBits) / LaneBits;
14661 unsigned NumElemsPerLane = LaneBits / ElemBits;
14665 ResultElements.reserve(DstLen);
14670 [NumLanes, NumElemsPerLane](
unsigned DstIdx,
unsigned ShuffleMask)
14671 -> std::pair<unsigned, int> {
14673 unsigned BitsPerElem = NumLanes / 2;
14674 unsigned IndexMask = (1u << BitsPerElem) - 1;
14675 unsigned Lane = DstIdx / NumElemsPerLane;
14676 unsigned SrcIdx = (Lane < NumLanes / 2) ? 0 : 1;
14677 unsigned BitIdx = BitsPerElem * Lane;
14678 unsigned SrcLaneIdx = (ShuffleMask >> BitIdx) & IndexMask;
14679 unsigned ElemInLane = DstIdx % NumElemsPerLane;
14680 unsigned IdxToPick = SrcLaneIdx * NumElemsPerLane + ElemInLane;
14681 return {SrcIdx, IdxToPick};
14687 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v16qi:
14688 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v32qi:
14689 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v64qi:
14690 case X86::BI__builtin_ia32_vgf2p8affineqb_v16qi:
14691 case X86::BI__builtin_ia32_vgf2p8affineqb_v32qi:
14692 case X86::BI__builtin_ia32_vgf2p8affineqb_v64qi: {
14704 bool IsInverse =
false;
14705 switch (BuiltinOp) {
14706 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v16qi:
14707 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v32qi:
14708 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v64qi: {
14713 unsigned NumBitsInByte = 8;
14714 unsigned NumBytesInQWord = 8;
14715 unsigned NumBitsInQWord = 64;
14717 unsigned NumQWords = NumBytes / NumBytesInQWord;
14719 Result.reserve(NumBytes);
14722 for (
unsigned QWordIdx = 0; QWordIdx != NumQWords; ++QWordIdx) {
14724 APInt XQWord(NumBitsInQWord, 0);
14725 APInt AQWord(NumBitsInQWord, 0);
14726 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
14727 unsigned Idx = QWordIdx * NumBytesInQWord + ByteIdx;
14728 APInt XByte =
X.getVectorElt(Idx).getInt();
14730 XQWord.insertBits(XByte, ByteIdx * NumBitsInByte);
14731 AQWord.insertBits(AByte, ByteIdx * NumBitsInByte);
14734 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
14736 XQWord.lshr(ByteIdx * NumBitsInByte).getLoBits(8).getZExtValue();
14745 case X86::BI__builtin_ia32_vgf2p8mulb_v16qi:
14746 case X86::BI__builtin_ia32_vgf2p8mulb_v32qi:
14747 case X86::BI__builtin_ia32_vgf2p8mulb_v64qi: {
14758 Result.reserve(NumBytes);
14760 for (
unsigned ByteIdx = 0; ByteIdx != NumBytes; ++ByteIdx) {
14770 case X86::BI__builtin_ia32_insertf32x4_256:
14771 case X86::BI__builtin_ia32_inserti32x4_256:
14772 case X86::BI__builtin_ia32_insertf64x2_256:
14773 case X86::BI__builtin_ia32_inserti64x2_256:
14774 case X86::BI__builtin_ia32_insertf32x4:
14775 case X86::BI__builtin_ia32_inserti32x4:
14776 case X86::BI__builtin_ia32_insertf64x2_512:
14777 case X86::BI__builtin_ia32_inserti64x2_512:
14778 case X86::BI__builtin_ia32_insertf32x8:
14779 case X86::BI__builtin_ia32_inserti32x8:
14780 case X86::BI__builtin_ia32_insertf64x4:
14781 case X86::BI__builtin_ia32_inserti64x4:
14782 case X86::BI__builtin_ia32_vinsertf128_ps256:
14783 case X86::BI__builtin_ia32_vinsertf128_pd256:
14784 case X86::BI__builtin_ia32_vinsertf128_si256:
14785 case X86::BI__builtin_ia32_insert128i256: {
14786 APValue SourceDst, SourceSub;
14798 assert(SubLen != 0 && DstLen != 0 && (DstLen % SubLen) == 0);
14799 unsigned NumLanes = DstLen / SubLen;
14800 unsigned LaneIdx = (Imm.getZExtValue() % NumLanes) * SubLen;
14803 ResultElements.reserve(DstLen);
14805 for (
unsigned EltNum = 0; EltNum < DstLen; ++EltNum) {
14806 if (EltNum >= LaneIdx && EltNum < LaneIdx + SubLen)
14807 ResultElements.push_back(SourceSub.
getVectorElt(EltNum - LaneIdx));
14809 ResultElements.push_back(SourceDst.
getVectorElt(EltNum));
14812 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14815 case clang::X86::BI__builtin_ia32_vec_set_v4hi:
14816 case clang::X86::BI__builtin_ia32_vec_set_v16qi:
14817 case clang::X86::BI__builtin_ia32_vec_set_v8hi:
14818 case clang::X86::BI__builtin_ia32_vec_set_v4si:
14819 case clang::X86::BI__builtin_ia32_vec_set_v2di:
14820 case clang::X86::BI__builtin_ia32_vec_set_v32qi:
14821 case clang::X86::BI__builtin_ia32_vec_set_v16hi:
14822 case clang::X86::BI__builtin_ia32_vec_set_v8si:
14823 case clang::X86::BI__builtin_ia32_vec_set_v4di: {
14831 QualType ElemTy = E->
getType()->
castAs<VectorType>()->getElementType();
14832 unsigned ElemWidth = Info.Ctx.getIntWidth(ElemTy);
14834 Scalar.setIsUnsigned(ElemUnsigned);
14840 static_cast<unsigned>(IndexAPS.getZExtValue() & (NumElems - 1));
14843 Elems.reserve(NumElems);
14844 for (
unsigned ElemNum = 0; ElemNum != NumElems; ++ElemNum)
14845 Elems.push_back(ElemNum == Index ? ElemAV : VecVal.
getVectorElt(ElemNum));
14850 case X86::BI__builtin_ia32_pslldqi128_byteshift:
14851 case X86::BI__builtin_ia32_pslldqi256_byteshift:
14852 case X86::BI__builtin_ia32_pslldqi512_byteshift: {
14856 [](
unsigned DstIdx,
unsigned Shift) -> std::pair<unsigned, int> {
14857 unsigned LaneBase = (DstIdx / 16) * 16;
14858 unsigned LaneIdx = DstIdx % 16;
14859 if (LaneIdx < Shift)
14860 return std::make_pair(0, -1);
14862 return std::make_pair(
14863 0,
static_cast<int>(LaneBase + LaneIdx - Shift));
14869 case X86::BI__builtin_ia32_psrldqi128_byteshift:
14870 case X86::BI__builtin_ia32_psrldqi256_byteshift:
14871 case X86::BI__builtin_ia32_psrldqi512_byteshift: {
14875 [](
unsigned DstIdx,
unsigned Shift) -> std::pair<unsigned, int> {
14876 unsigned LaneBase = (DstIdx / 16) * 16;
14877 unsigned LaneIdx = DstIdx % 16;
14878 if (LaneIdx + Shift < 16)
14879 return std::make_pair(
14880 0,
static_cast<int>(LaneBase + LaneIdx + Shift));
14882 return std::make_pair(0, -1);
14888 case X86::BI__builtin_ia32_palignr128:
14889 case X86::BI__builtin_ia32_palignr256:
14890 case X86::BI__builtin_ia32_palignr512: {
14894 unsigned VecIdx = 1;
14897 int Lane = DstIdx / 16;
14898 int Offset = DstIdx % 16;
14901 unsigned ShiftedIdx = Offset + (
Shift & 0xFF);
14902 if (ShiftedIdx < 16) {
14903 ElemIdx = ShiftedIdx + (Lane * 16);
14904 }
else if (ShiftedIdx < 32) {
14906 ElemIdx = (ShiftedIdx - 16) + (Lane * 16);
14909 return std::pair<unsigned, int>{VecIdx, ElemIdx};
14914 case X86::BI__builtin_ia32_alignd128:
14915 case X86::BI__builtin_ia32_alignd256:
14916 case X86::BI__builtin_ia32_alignd512:
14917 case X86::BI__builtin_ia32_alignq128:
14918 case X86::BI__builtin_ia32_alignq256:
14919 case X86::BI__builtin_ia32_alignq512: {
14921 unsigned NumElems = E->
getType()->
castAs<VectorType>()->getNumElements();
14923 [NumElems](
unsigned DstIdx,
unsigned Shift) {
14924 unsigned Imm =
Shift & 0xFF;
14925 unsigned EffectiveShift = Imm & (NumElems - 1);
14926 unsigned SourcePos = DstIdx + EffectiveShift;
14927 unsigned VecIdx = SourcePos < NumElems ? 1 : 0;
14928 unsigned ElemIdx = SourcePos & (NumElems - 1);
14930 return std::pair<unsigned, int>{
14931 VecIdx,
static_cast<int>(ElemIdx)};
14936 case X86::BI__builtin_ia32_permvarsi256:
14937 case X86::BI__builtin_ia32_permvarsf256:
14938 case X86::BI__builtin_ia32_permvardf512:
14939 case X86::BI__builtin_ia32_permvardi512:
14940 case X86::BI__builtin_ia32_permvarhi128: {
14943 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14944 int Offset = ShuffleMask & 0x7;
14945 return std::pair<unsigned, int>{0, Offset};
14950 case X86::BI__builtin_ia32_permvarqi128:
14951 case X86::BI__builtin_ia32_permvarhi256:
14952 case X86::BI__builtin_ia32_permvarsi512:
14953 case X86::BI__builtin_ia32_permvarsf512: {
14956 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14957 int Offset = ShuffleMask & 0xF;
14958 return std::pair<unsigned, int>{0, Offset};
14963 case X86::BI__builtin_ia32_permvardi256:
14964 case X86::BI__builtin_ia32_permvardf256: {
14967 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14968 int Offset = ShuffleMask & 0x3;
14969 return std::pair<unsigned, int>{0, Offset};
14974 case X86::BI__builtin_ia32_permvarqi256:
14975 case X86::BI__builtin_ia32_permvarhi512: {
14978 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14979 int Offset = ShuffleMask & 0x1F;
14980 return std::pair<unsigned, int>{0, Offset};
14985 case X86::BI__builtin_ia32_permvarqi512: {
14988 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14989 int Offset = ShuffleMask & 0x3F;
14990 return std::pair<unsigned, int>{0, Offset};
14995 case X86::BI__builtin_ia32_vpermi2varq128:
14996 case X86::BI__builtin_ia32_vpermi2varpd128: {
14999 [](
unsigned DstIdx,
unsigned ShuffleMask) {
15000 int Offset = ShuffleMask & 0x1;
15001 unsigned SrcIdx = (ShuffleMask >> 1) & 0x1;
15002 return std::pair<unsigned, int>{SrcIdx, Offset};
15007 case X86::BI__builtin_ia32_vpermi2vard128:
15008 case X86::BI__builtin_ia32_vpermi2varps128:
15009 case X86::BI__builtin_ia32_vpermi2varq256:
15010 case X86::BI__builtin_ia32_vpermi2varpd256: {
15013 [](
unsigned DstIdx,
unsigned ShuffleMask) {
15014 int Offset = ShuffleMask & 0x3;
15015 unsigned SrcIdx = (ShuffleMask >> 2) & 0x1;
15016 return std::pair<unsigned, int>{SrcIdx, Offset};
15021 case X86::BI__builtin_ia32_vpermi2varhi128:
15022 case X86::BI__builtin_ia32_vpermi2vard256:
15023 case X86::BI__builtin_ia32_vpermi2varps256:
15024 case X86::BI__builtin_ia32_vpermi2varq512:
15025 case X86::BI__builtin_ia32_vpermi2varpd512: {
15028 [](
unsigned DstIdx,
unsigned ShuffleMask) {
15029 int Offset = ShuffleMask & 0x7;
15030 unsigned SrcIdx = (ShuffleMask >> 3) & 0x1;
15031 return std::pair<unsigned, int>{SrcIdx, Offset};
15036 case X86::BI__builtin_ia32_vpermi2varqi128:
15037 case X86::BI__builtin_ia32_vpermi2varhi256:
15038 case X86::BI__builtin_ia32_vpermi2vard512:
15039 case X86::BI__builtin_ia32_vpermi2varps512: {
15042 [](
unsigned DstIdx,
unsigned ShuffleMask) {
15043 int Offset = ShuffleMask & 0xF;
15044 unsigned SrcIdx = (ShuffleMask >> 4) & 0x1;
15045 return std::pair<unsigned, int>{SrcIdx, Offset};
15050 case X86::BI__builtin_ia32_vpermi2varqi256:
15051 case X86::BI__builtin_ia32_vpermi2varhi512: {
15054 [](
unsigned DstIdx,
unsigned ShuffleMask) {
15055 int Offset = ShuffleMask & 0x1F;
15056 unsigned SrcIdx = (ShuffleMask >> 5) & 0x1;
15057 return std::pair<unsigned, int>{SrcIdx, Offset};
15062 case X86::BI__builtin_ia32_vpermi2varqi512: {
15065 [](
unsigned DstIdx,
unsigned ShuffleMask) {
15066 int Offset = ShuffleMask & 0x3F;
15067 unsigned SrcIdx = (ShuffleMask >> 6) & 0x1;
15068 return std::pair<unsigned, int>{SrcIdx, Offset};
15074 case clang::X86::BI__builtin_ia32_minps:
15075 case clang::X86::BI__builtin_ia32_minpd:
15076 case clang::X86::BI__builtin_ia32_minps256:
15077 case clang::X86::BI__builtin_ia32_minpd256:
15078 case clang::X86::BI__builtin_ia32_minps512:
15079 case clang::X86::BI__builtin_ia32_minpd512:
15080 case clang::X86::BI__builtin_ia32_minph128:
15081 case clang::X86::BI__builtin_ia32_minph256:
15082 case clang::X86::BI__builtin_ia32_minph512:
15083 return EvaluateFpBinOpExpr(
15084 [](
const APFloat &A,
const APFloat &B,
15085 std::optional<APSInt>) -> std::optional<APFloat> {
15086 if (A.isNaN() || A.isInfinity() || A.isDenormal() || B.isNaN() ||
15087 B.isInfinity() || B.isDenormal())
15088 return std::nullopt;
15089 if (A.isZero() && B.isZero())
15091 return llvm::minimum(A, B);
15094 case clang::X86::BI__builtin_ia32_minss:
15095 case clang::X86::BI__builtin_ia32_minsd:
15096 return EvaluateFpBinOpExpr(
15097 [](
const APFloat &A,
const APFloat &B,
15098 std::optional<APSInt> RoundingMode) -> std::optional<APFloat> {
15103 case clang::X86::BI__builtin_ia32_minsd_round_mask:
15104 case clang::X86::BI__builtin_ia32_minss_round_mask:
15105 case clang::X86::BI__builtin_ia32_minsh_round_mask:
15106 case clang::X86::BI__builtin_ia32_maxsd_round_mask:
15107 case clang::X86::BI__builtin_ia32_maxss_round_mask:
15108 case clang::X86::BI__builtin_ia32_maxsh_round_mask: {
15109 bool IsMin = BuiltinOp == clang::X86::BI__builtin_ia32_minsd_round_mask ||
15110 BuiltinOp == clang::X86::BI__builtin_ia32_minss_round_mask ||
15111 BuiltinOp == clang::X86::BI__builtin_ia32_minsh_round_mask;
15112 return EvaluateScalarFpRoundMaskBinOp(
15113 [IsMin](
const APFloat &A,
const APFloat &B,
15114 std::optional<APSInt> RoundingMode) -> std::optional<APFloat> {
15119 case clang::X86::BI__builtin_ia32_maxps:
15120 case clang::X86::BI__builtin_ia32_maxpd:
15121 case clang::X86::BI__builtin_ia32_maxps256:
15122 case clang::X86::BI__builtin_ia32_maxpd256:
15123 case clang::X86::BI__builtin_ia32_maxps512:
15124 case clang::X86::BI__builtin_ia32_maxpd512:
15125 case clang::X86::BI__builtin_ia32_maxph128:
15126 case clang::X86::BI__builtin_ia32_maxph256:
15127 case clang::X86::BI__builtin_ia32_maxph512:
15128 return EvaluateFpBinOpExpr(
15129 [](
const APFloat &A,
const APFloat &B,
15130 std::optional<APSInt>) -> std::optional<APFloat> {
15131 if (A.isNaN() || A.isInfinity() || A.isDenormal() || B.isNaN() ||
15132 B.isInfinity() || B.isDenormal())
15133 return std::nullopt;
15134 if (A.isZero() && B.isZero())
15136 return llvm::maximum(A, B);
15139 case clang::X86::BI__builtin_ia32_maxss:
15140 case clang::X86::BI__builtin_ia32_maxsd:
15141 return EvaluateFpBinOpExpr(
15142 [](
const APFloat &A,
const APFloat &B,
15143 std::optional<APSInt> RoundingMode) -> std::optional<APFloat> {
15148 case clang::X86::BI__builtin_ia32_vcvtps2ph:
15149 case clang::X86::BI__builtin_ia32_vcvtps2ph256: {
15159 unsigned SrcNumElems = SrcVTy->getNumElements();
15161 unsigned DstNumElems = DstVTy->getNumElements();
15162 QualType DstElemTy = DstVTy->getElementType();
15164 const llvm::fltSemantics &HalfSem =
15165 Info.Ctx.getFloatTypeSemantics(Info.Ctx.HalfTy);
15167 int ImmVal = Imm.getZExtValue();
15168 bool UseMXCSR = (ImmVal & 4) != 0;
15169 bool IsFPConstrained =
15172 llvm::RoundingMode RM;
15174 switch (ImmVal & 3) {
15176 RM = llvm::RoundingMode::NearestTiesToEven;
15179 RM = llvm::RoundingMode::TowardNegative;
15182 RM = llvm::RoundingMode::TowardPositive;
15185 RM = llvm::RoundingMode::TowardZero;
15188 llvm_unreachable(
"Invalid immediate rounding mode");
15191 RM = llvm::RoundingMode::NearestTiesToEven;
15195 ResultElements.reserve(DstNumElems);
15197 for (
unsigned I = 0; I < SrcNumElems; ++I) {
15201 APFloat::opStatus St = SrcVal.convert(HalfSem, RM, &LostInfo);
15203 if (UseMXCSR && IsFPConstrained && St != APFloat::opOK) {
15204 Info.FFDiag(E, diag::note_constexpr_dynamic_rounding);
15208 APSInt DstInt(SrcVal.bitcastToAPInt(),
15210 ResultElements.push_back(
APValue(DstInt));
15213 if (DstNumElems > SrcNumElems) {
15214 APSInt Zero = Info.Ctx.MakeIntValue(0, DstElemTy);
15215 for (
unsigned I = SrcNumElems; I < DstNumElems; ++I) {
15220 return Success(ResultElements, E);
15222 case X86::BI__builtin_ia32_vperm2f128_pd256:
15223 case X86::BI__builtin_ia32_vperm2f128_ps256:
15224 case X86::BI__builtin_ia32_vperm2f128_si256:
15225 case X86::BI__builtin_ia32_permti256: {
15226 unsigned NumElements =
15228 unsigned PreservedBitsCnt = NumElements >> 2;
15232 [PreservedBitsCnt](
unsigned DstIdx,
unsigned ShuffleMask) {
15233 unsigned ControlBitsCnt = DstIdx >> PreservedBitsCnt << 2;
15234 unsigned ControlBits = ShuffleMask >> ControlBitsCnt;
15236 if (ControlBits & 0b1000)
15237 return std::make_pair(0u, -1);
15239 unsigned SrcVecIdx = (ControlBits & 0b10) >> 1;
15240 unsigned PreservedBitsMask = (1 << PreservedBitsCnt) - 1;
15241 int SrcIdx = ((ControlBits & 0b1) << PreservedBitsCnt) |
15242 (DstIdx & PreservedBitsMask);
15243 return std::make_pair(SrcVecIdx, SrcIdx);
15248 case X86::BI__builtin_ia32_vpdpwssd128:
15249 case X86::BI__builtin_ia32_vpdpwssd256:
15250 case X86::BI__builtin_ia32_vpdpwssd512:
15251 case X86::BI__builtin_ia32_vpdpbusd128:
15252 case X86::BI__builtin_ia32_vpdpbusd256:
15253 case X86::BI__builtin_ia32_vpdpbusd512:
15254 return EvalVectorDotProduct(
false);
15255 case X86::BI__builtin_ia32_vpdpwssds128:
15256 case X86::BI__builtin_ia32_vpdpwssds256:
15257 case X86::BI__builtin_ia32_vpdpwssds512:
15258 case X86::BI__builtin_ia32_vpdpbusds128:
15259 case X86::BI__builtin_ia32_vpdpbusds256:
15260 case X86::BI__builtin_ia32_vpdpbusds512:
15261 return EvalVectorDotProduct(
true);
15265bool VectorExprEvaluator::VisitConvertVectorExpr(
const ConvertVectorExpr *E) {
15271 QualType DestTy = E->
getType()->
castAs<VectorType>()->getElementType();
15272 QualType SourceTy = SourceVecType->
castAs<VectorType>()->getElementType();
15278 ResultElements.reserve(SourceLen);
15279 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
15284 ResultElements.push_back(std::move(Elt));
15287 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
15292 APValue const &VecVal2,
unsigned EltNum,
15294 unsigned const TotalElementsInInputVector1 = VecVal1.
getVectorLength();
15295 unsigned const TotalElementsInInputVector2 = VecVal2.
getVectorLength();
15298 int64_t
index = IndexVal.getExtValue();
15305 E, diag::err_shufflevector_minus_one_is_undefined_behavior_constexpr)
15311 index >= TotalElementsInInputVector1 + TotalElementsInInputVector2)
15312 llvm_unreachable(
"Out of bounds shuffle index");
15314 if (
index >= TotalElementsInInputVector1)
15321bool VectorExprEvaluator::VisitShuffleVectorExpr(
const ShuffleVectorExpr *E) {
15326 const Expr *Vec1 = E->
getExpr(0);
15330 const Expr *Vec2 = E->
getExpr(1);
15334 VectorType
const *DestVecTy = E->
getType()->
castAs<VectorType>();
15340 ResultElements.reserve(TotalElementsInOutputVector);
15341 for (
unsigned EltNum = 0; EltNum < TotalElementsInOutputVector; ++EltNum) {
15345 ResultElements.push_back(std::move(Elt));
15348 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
15356class MatrixExprEvaluator :
public ExprEvaluatorBase<MatrixExprEvaluator> {
15363 bool Success(ArrayRef<APValue> M,
const Expr *E) {
15365 assert(M.size() == CMTy->getNumElementsFlattened());
15367 Result =
APValue(M.data(), CMTy->getNumRows(), CMTy->getNumColumns());
15371 assert(M.
isMatrix() &&
"expected matrix");
15376 bool VisitCastExpr(
const CastExpr *E);
15377 bool VisitInitListExpr(
const InitListExpr *E);
15383 "not a matrix prvalue");
15384 return MatrixExprEvaluator(Info,
Result).Visit(E);
15387bool MatrixExprEvaluator::VisitCastExpr(
const CastExpr *E) {
15388 const auto *MT = E->
getType()->
castAs<ConstantMatrixType>();
15389 unsigned NumRows = MT->getNumRows();
15390 unsigned NumCols = MT->getNumColumns();
15391 unsigned NElts = NumRows * NumCols;
15392 QualType EltTy = MT->getElementType();
15396 case CK_HLSLAggregateSplatCast: {
15411 case CK_HLSLElementwiseCast: {
15424 return Success(ResultEls, E);
15427 return ExprEvaluatorBaseTy::VisitCastExpr(E);
15431bool MatrixExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
15432 const auto *MT = E->
getType()->
castAs<ConstantMatrixType>();
15433 QualType EltTy = MT->getElementType();
15435 assert(E->
getNumInits() == MT->getNumElementsFlattened() &&
15436 "Expected number of elements in initializer list to match the number "
15437 "of matrix elements");
15440 Elements.reserve(MT->getNumElementsFlattened());
15445 for (
unsigned I = 0, N = MT->getNumElementsFlattened(); I < N; ++I) {
15446 if (EltTy->isIntegerType()) {
15447 llvm::APSInt IntVal;
15450 Elements.push_back(
APValue(IntVal));
15452 llvm::APFloat FloatVal(0.0);
15455 Elements.push_back(
APValue(FloatVal));
15467 class ArrayExprEvaluator
15468 :
public ExprEvaluatorBase<ArrayExprEvaluator> {
15469 const LValue &
This;
15473 ArrayExprEvaluator(EvalInfo &Info,
const LValue &This,
APValue &
Result)
15477 assert(
V.isArray() &&
"expected array");
15482 bool ZeroInitialization(
const Expr *E) {
15483 const ConstantArrayType *CAT =
15484 Info.Ctx.getAsConstantArrayType(E->
getType());
15498 if (!
Result.hasArrayFiller())
15502 LValue Subobject =
This;
15503 Subobject.addArray(Info, E, CAT);
15508 bool VisitCallExpr(
const CallExpr *E) {
15509 return handleCallExpr(E,
Result, &This);
15511 bool VisitCastExpr(
const CastExpr *E);
15512 bool VisitInitListExpr(
const InitListExpr *E,
15513 QualType AllocType = QualType());
15514 bool VisitArrayInitLoopExpr(
const ArrayInitLoopExpr *E);
15515 bool VisitCXXConstructExpr(
const CXXConstructExpr *E);
15516 bool VisitCXXConstructExpr(
const CXXConstructExpr *E,
15517 const LValue &Subobject,
15519 bool VisitStringLiteral(
const StringLiteral *E,
15520 QualType AllocType = QualType()) {
15524 bool VisitCXXParenListInitExpr(
const CXXParenListInitExpr *E);
15525 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
15526 ArrayRef<Expr *> Args,
15527 const Expr *ArrayFiller,
15528 QualType AllocType = QualType());
15529 bool VisitDesignatedInitUpdateExpr(
const DesignatedInitUpdateExpr *E);
15537 "not an array prvalue");
15538 return ArrayExprEvaluator(Info,
This,
Result).Visit(E);
15546 "not an array prvalue");
15547 return ArrayExprEvaluator(Info,
This,
Result)
15548 .VisitInitListExpr(ILE, AllocType);
15557 "not an array prvalue");
15558 return ArrayExprEvaluator(Info,
This,
Result)
15559 .VisitCXXConstructExpr(CCE,
This, &
Result, AllocType);
15568 if (
const InitListExpr *ILE = dyn_cast<InitListExpr>(FillerExpr)) {
15569 for (
unsigned I = 0, E = ILE->
getNumInits(); I != E; ++I) {
15574 if (ILE->hasArrayFiller() &&
15583bool ArrayExprEvaluator::VisitCastExpr(
const CastExpr *E) {
15588 return ExprEvaluatorBaseTy::VisitCastExpr(E);
15589 case CK_HLSLAggregateSplatCast: {
15609 case CK_HLSLElementwiseCast: {
15626bool ArrayExprEvaluator::VisitInitListExpr(
const InitListExpr *E,
15627 QualType AllocType) {
15628 const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(
15641 return VisitStringLiteral(SL, AllocType);
15646 "transparent array list initialization is not string literal init?");
15652bool ArrayExprEvaluator::VisitCXXParenListOrInitListExpr(
15654 QualType AllocType) {
15655 const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(
15660 unsigned NumEltsToInit = Args.size();
15665 if (NumEltsToInit != NumElts &&
15667 NumEltsToInit = NumElts;
15670 for (
auto *
Init : Args) {
15671 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts()))
15672 NumEltsToInit += EmbedS->getDataElementCount() - 1;
15675 if (NumEltsToInit > NumElts)
15676 NumEltsToInit = NumElts;
15680 if (
Result.hasValue() && NumEltsToInit <
Result.getArrayInitializedElts())
15681 NumEltsToInit =
Result.getArrayInitializedElts();
15684 LLVM_DEBUG(llvm::dbgs() <<
"The number of elements to initialize: "
15685 << NumEltsToInit <<
".\n");
15687 if (!
Result.hasValue()) {
15688 Result =
APValue(APValue::UninitArray(), NumEltsToInit, NumElts);
15689 }
else if (
Result.getArrayInitializedElts() != NumEltsToInit) {
15700 APValue NewResult =
APValue(APValue::UninitArray(), NumEltsToInit, NumElts);
15702 unsigned NumOldElts =
Result.getArrayInitializedElts();
15703 for (
unsigned I = 0; I < NumOldElts; ++I) {
15705 std::move(
Result.getArrayInitializedElt(I));
15708 for (
unsigned I =
Result.getArrayInitializedElts(); I < NumEltsToInit; ++I)
15712 Result = std::move(NewResult);
15715 LValue Subobject =
This;
15716 Subobject.addArray(Info, ExprToVisit, CAT);
15717 auto Eval = [&](
const Expr *
Init,
unsigned ArrayIndex) {
15718 if (
Init->isValueDependent())
15727 Subobject,
Init) ||
15730 if (!Info.noteFailure())
15736 unsigned ArrayIndex = 0;
15739 for (
unsigned Index = 0; Index != NumEltsToInit; ++Index) {
15740 const Expr *
Init = Index < Args.size() ? Args[Index] : ArrayFiller;
15741 if (ArrayIndex >= NumEltsToInit)
15743 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
15744 StringLiteral *SL = EmbedS->getDataStringLiteral();
15745 for (
unsigned I = EmbedS->getStartingElementPos(),
15746 N = EmbedS->getDataElementCount();
15747 I != EmbedS->getStartingElementPos() + N; ++I) {
15753 const FPOptions FPO =
15754 Init->getFPFeaturesInEffect(Info.Ctx.getLangOpts());
15759 Result.getArrayInitializedElt(ArrayIndex) =
APValue(FValue);
15764 if (!Eval(
Init, ArrayIndex))
15770 if (!
Result.hasArrayFiller())
15775 assert(ArrayFiller &&
"no array filler for incomplete init list");
15781bool ArrayExprEvaluator::VisitArrayInitLoopExpr(
const ArrayInitLoopExpr *E) {
15784 !
Evaluate(Info.CurrentCall->createTemporary(
15787 ScopeKind::FullExpression, CommonLV),
15794 Result =
APValue(APValue::UninitArray(), Elements, Elements);
15796 LValue Subobject =
This;
15797 Subobject.addArray(Info, E, CAT);
15800 for (EvalInfo::ArrayInitLoopIndex Index(Info); Index != Elements; ++Index) {
15809 FullExpressionRAII Scope(Info);
15815 if (!Info.noteFailure())
15827bool ArrayExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E) {
15828 return VisitCXXConstructExpr(E, This, &
Result, E->
getType());
15831bool ArrayExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E,
15832 const LValue &Subobject,
15835 bool HadZeroInit =
Value->hasValue();
15837 if (
const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(
Type)) {
15842 HadZeroInit &&
Value->hasArrayFiller() ?
Value->getArrayFiller()
15845 *
Value =
APValue(APValue::UninitArray(), 0, FinalSize);
15846 if (FinalSize == 0)
15852 LValue ArrayElt = Subobject;
15853 ArrayElt.addArray(Info, E, CAT);
15859 for (
const unsigned N : {1u, FinalSize}) {
15860 unsigned OldElts =
Value->getArrayInitializedElts();
15865 APValue NewValue(APValue::UninitArray(), N, FinalSize);
15866 for (
unsigned I = 0; I < OldElts; ++I)
15867 NewValue.getArrayInitializedElt(I).swap(
15868 Value->getArrayInitializedElt(I));
15869 Value->swap(NewValue);
15872 for (
unsigned I = OldElts; I < N; ++I)
15873 Value->getArrayInitializedElt(I) = Filler;
15875 if (HasTrivialConstructor && N == FinalSize && FinalSize != 1) {
15878 APValue &FirstResult =
Value->getArrayInitializedElt(0);
15879 for (
unsigned I = OldElts; I < FinalSize; ++I)
15880 Value->getArrayInitializedElt(I) = FirstResult;
15882 for (
unsigned I = OldElts; I < N; ++I) {
15883 if (!VisitCXXConstructExpr(E, ArrayElt,
15884 &
Value->getArrayInitializedElt(I),
15891 if (Info.EvalStatus.Diag && !Info.EvalStatus.Diag->empty() &&
15892 !Info.keepEvaluatingAfterFailure())
15901 if (!
Type->isRecordType())
15904 return RecordExprEvaluator(Info, Subobject, *
Value)
15905 .VisitCXXConstructExpr(E,
Type);
15908bool ArrayExprEvaluator::VisitCXXParenListInitExpr(
15909 const CXXParenListInitExpr *E) {
15911 "Expression result is not a constant array type");
15913 return VisitCXXParenListOrInitListExpr(E, E->
getInitExprs(),
15917bool ArrayExprEvaluator::VisitDesignatedInitUpdateExpr(
15918 const DesignatedInitUpdateExpr *E) {
15933class IntExprEvaluator
15934 :
public ExprEvaluatorBase<IntExprEvaluator> {
15937 IntExprEvaluator(EvalInfo &info,
APValue &result)
15938 : ExprEvaluatorBaseTy(info),
Result(result) {}
15942 "Invalid evaluation result.");
15944 "Invalid evaluation result.");
15945 assert(SI.getBitWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
15946 "Invalid evaluation result.");
15950 bool Success(
const llvm::APSInt &SI,
const Expr *E) {
15956 "Invalid evaluation result.");
15957 assert(I.getBitWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
15958 "Invalid evaluation result.");
15960 Result.getInt().setIsUnsigned(
15964 bool Success(
const llvm::APInt &I,
const Expr *E) {
15970 "Invalid evaluation result.");
15978 bool Success(CharUnits Size,
const Expr *E) {
15985 if (
V.isLValue() ||
V.isAddrLabelDiff() ||
V.isIndeterminate() ||
15986 V.allowConstexprUnknown()) {
15993 bool ZeroInitialization(
const Expr *E) {
return Success(0, E); }
15995 friend std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &,
16002 bool VisitIntegerLiteral(
const IntegerLiteral *E) {
16005 bool VisitCharacterLiteral(
const CharacterLiteral *E) {
16009 bool CheckReferencedDecl(
const Expr *E,
const Decl *D);
16010 bool VisitDeclRefExpr(
const DeclRefExpr *E) {
16011 if (CheckReferencedDecl(E, E->
getDecl()))
16014 return ExprEvaluatorBaseTy::VisitDeclRefExpr(E);
16016 bool VisitMemberExpr(
const MemberExpr *E) {
16018 VisitIgnoredBaseExpression(E->
getBase());
16022 return ExprEvaluatorBaseTy::VisitMemberExpr(E);
16025 bool VisitCallExpr(
const CallExpr *E);
16026 bool VisitBuiltinCallExpr(
const CallExpr *E,
unsigned BuiltinOp);
16027 bool VisitBinaryOperator(
const BinaryOperator *E);
16028 bool VisitOffsetOfExpr(
const OffsetOfExpr *E);
16029 bool VisitUnaryOperator(
const UnaryOperator *E);
16031 bool VisitCastExpr(
const CastExpr* E);
16032 bool VisitUnaryExprOrTypeTraitExpr(
const UnaryExprOrTypeTraitExpr *E);
16034 bool VisitCXXBoolLiteralExpr(
const CXXBoolLiteralExpr *E) {
16038 bool VisitObjCBoolLiteralExpr(
const ObjCBoolLiteralExpr *E) {
16042 bool VisitArrayInitIndexExpr(
const ArrayInitIndexExpr *E) {
16043 if (Info.ArrayInitIndex ==
uint64_t(-1)) {
16049 return Success(Info.ArrayInitIndex, E);
16053 bool VisitGNUNullExpr(
const GNUNullExpr *E) {
16054 return ZeroInitialization(E);
16057 bool VisitTypeTraitExpr(
const TypeTraitExpr *E) {
16066 bool VisitArrayTypeTraitExpr(
const ArrayTypeTraitExpr *E) {
16070 bool VisitExpressionTraitExpr(
const ExpressionTraitExpr *E) {
16074 bool VisitOpenACCAsteriskSizeExpr(
const OpenACCAsteriskSizeExpr *E) {
16081 bool VisitUnaryReal(
const UnaryOperator *E);
16082 bool VisitUnaryImag(
const UnaryOperator *E);
16084 bool VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E);
16085 bool VisitSizeOfPackExpr(
const SizeOfPackExpr *E);
16086 bool VisitSourceLocExpr(
const SourceLocExpr *E);
16087 bool VisitConceptSpecializationExpr(
const ConceptSpecializationExpr *E);
16092class FixedPointExprEvaluator
16093 :
public ExprEvaluatorBase<FixedPointExprEvaluator> {
16097 FixedPointExprEvaluator(EvalInfo &info,
APValue &result)
16098 : ExprEvaluatorBaseTy(info),
Result(result) {}
16100 bool Success(
const llvm::APInt &I,
const Expr *E) {
16102 APFixedPoint(I, Info.Ctx.getFixedPointSemantics(E->
getType())), E);
16107 APFixedPoint(
Value, Info.Ctx.getFixedPointSemantics(E->
getType())), E);
16111 return Success(
V.getFixedPoint(), E);
16114 bool Success(
const APFixedPoint &
V,
const Expr *E) {
16116 assert(
V.getWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
16117 "Invalid evaluation result.");
16122 bool ZeroInitialization(
const Expr *E) {
16130 bool VisitFixedPointLiteral(
const FixedPointLiteral *E) {
16134 bool VisitCastExpr(
const CastExpr *E);
16135 bool VisitUnaryOperator(
const UnaryOperator *E);
16136 bool VisitBinaryOperator(
const BinaryOperator *E);
16152 return IntExprEvaluator(Info,
Result).Visit(E);
16160 if (!Val.
isInt()) {
16163 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
16170bool IntExprEvaluator::VisitSourceLocExpr(
const SourceLocExpr *E) {
16172 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.
getDefaultExpr());
16181 if (!FixedPointExprEvaluator(Info, Val).Visit(E))
16196 auto FXSema = Info.Ctx.getFixedPointSemantics(E->
getType());
16200 Result = APFixedPoint(Val, FXSema);
16211bool IntExprEvaluator::CheckReferencedDecl(
const Expr* E,
const Decl* D) {
16213 if (
const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(D)) {
16215 bool SameSign = (ECD->getInitVal().isSigned()
16217 bool SameWidth = (ECD->getInitVal().
getBitWidth()
16218 == Info.Ctx.getIntWidth(E->
getType()));
16219 if (SameSign && SameWidth)
16220 return Success(ECD->getInitVal(), E);
16224 llvm::APSInt Val = ECD->getInitVal();
16226 Val.setIsSigned(!ECD->getInitVal().isSigned());
16228 Val = Val.extOrTrunc(Info.Ctx.getIntWidth(E->
getType()));
16239 assert(!
T->isDependentType() &&
"unexpected dependent type");
16244#define TYPE(ID, BASE)
16245#define DEPENDENT_TYPE(ID, BASE) case Type::ID:
16246#define NON_CANONICAL_TYPE(ID, BASE) case Type::ID:
16247#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(ID, BASE) case Type::ID:
16248#include "clang/AST/TypeNodes.inc"
16250 case Type::DeducedTemplateSpecialization:
16251 llvm_unreachable(
"unexpected non-canonical or dependent type");
16253 case Type::Builtin:
16255#define BUILTIN_TYPE(ID, SINGLETON_ID)
16256#define SIGNED_TYPE(ID, SINGLETON_ID) \
16257 case BuiltinType::ID: return GCCTypeClass::Integer;
16258#define FLOATING_TYPE(ID, SINGLETON_ID) \
16259 case BuiltinType::ID: return GCCTypeClass::RealFloat;
16260#define PLACEHOLDER_TYPE(ID, SINGLETON_ID) \
16261 case BuiltinType::ID: break;
16262#include "clang/AST/BuiltinTypes.def"
16263 case BuiltinType::Void:
16266 case BuiltinType::Bool:
16269 case BuiltinType::Char_U:
16270 case BuiltinType::UChar:
16271 case BuiltinType::WChar_U:
16272 case BuiltinType::Char8:
16273 case BuiltinType::Char16:
16274 case BuiltinType::Char32:
16275 case BuiltinType::UShort:
16276 case BuiltinType::UInt:
16277 case BuiltinType::ULong:
16278 case BuiltinType::ULongLong:
16279 case BuiltinType::UInt128:
16282 case BuiltinType::UShortAccum:
16283 case BuiltinType::UAccum:
16284 case BuiltinType::ULongAccum:
16285 case BuiltinType::UShortFract:
16286 case BuiltinType::UFract:
16287 case BuiltinType::ULongFract:
16288 case BuiltinType::SatUShortAccum:
16289 case BuiltinType::SatUAccum:
16290 case BuiltinType::SatULongAccum:
16291 case BuiltinType::SatUShortFract:
16292 case BuiltinType::SatUFract:
16293 case BuiltinType::SatULongFract:
16296 case BuiltinType::NullPtr:
16298 case BuiltinType::ObjCId:
16299 case BuiltinType::ObjCClass:
16300 case BuiltinType::ObjCSel:
16301#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
16302 case BuiltinType::Id:
16303#include "clang/Basic/OpenCLImageTypes.def"
16304#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
16305 case BuiltinType::Id:
16306#include "clang/Basic/OpenCLExtensionTypes.def"
16307 case BuiltinType::OCLSampler:
16308 case BuiltinType::OCLEvent:
16309 case BuiltinType::OCLClkEvent:
16310 case BuiltinType::OCLQueue:
16311 case BuiltinType::OCLReserveID:
16312#define SVE_TYPE(Name, Id, SingletonId) \
16313 case BuiltinType::Id:
16314#include "clang/Basic/AArch64ACLETypes.def"
16315#define PPC_VECTOR_TYPE(Name, Id, Size) \
16316 case BuiltinType::Id:
16317#include "clang/Basic/PPCTypes.def"
16318#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
16319#include "clang/Basic/RISCVVTypes.def"
16320#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
16321#include "clang/Basic/WebAssemblyReferenceTypes.def"
16322#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
16323#include "clang/Basic/AMDGPUTypes.def"
16324#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
16325#include "clang/Basic/HLSLIntangibleTypes.def"
16328 case BuiltinType::Dependent:
16329 llvm_unreachable(
"unexpected dependent type");
16331 llvm_unreachable(
"unexpected placeholder type");
16336 case Type::Pointer:
16337 case Type::ConstantArray:
16338 case Type::VariableArray:
16339 case Type::IncompleteArray:
16340 case Type::FunctionNoProto:
16341 case Type::FunctionProto:
16342 case Type::ArrayParameter:
16345 case Type::MemberPointer:
16350 case Type::Complex:
16363 case Type::ExtVector:
16366 case Type::BlockPointer:
16367 case Type::ConstantMatrix:
16368 case Type::ObjCObject:
16369 case Type::ObjCInterface:
16370 case Type::ObjCObjectPointer:
16372 case Type::HLSLAttributedResource:
16373 case Type::HLSLInlineSpirv:
16374 case Type::OverflowBehavior:
16382 case Type::LValueReference:
16383 case Type::RValueReference:
16384 llvm_unreachable(
"invalid type for expression");
16387 llvm_unreachable(
"unexpected type class");
16412 if (
Base.isNull()) {
16415 }
else if (
const Expr *E =
Base.dyn_cast<
const Expr *>()) {
16434 SpeculativeEvaluationRAII SpeculativeEval(Info);
16439 FoldConstant Fold(Info,
true);
16457 if (ArgType->isIntegralOrEnumerationType() || ArgType->isFloatingType() ||
16458 ArgType->isAnyComplexType() || ArgType->isPointerType() ||
16459 ArgType->isNullPtrType()) {
16462 Fold.keepDiagnostics();
16471 return V.hasValue();
16482 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
16506 const auto *Cast = dyn_cast<CastExpr>(NoParens);
16507 if (Cast ==
nullptr)
16512 auto CastKind = Cast->getCastKind();
16514 CastKind != CK_AddressSpaceConversion)
16517 const auto *SubExpr = Cast->getSubExpr();
16539 assert(!LVal.Designator.Invalid);
16541 auto IsLastOrInvalidFieldDecl = [&Ctx](
const FieldDecl *FD) {
16549 auto &
Base = LVal.getLValueBase();
16550 if (
auto *ME = dyn_cast_or_null<MemberExpr>(
Base.dyn_cast<
const Expr *>())) {
16551 if (
auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
16552 if (!IsLastOrInvalidFieldDecl(FD))
16554 }
else if (
auto *IFD = dyn_cast<IndirectFieldDecl>(ME->getMemberDecl())) {
16555 for (
auto *FD : IFD->chain()) {
16564 if (LVal.Designator.FirstEntryIsAnUnsizedArray) {
16568 if (BaseType->isIncompleteArrayType())
16574 for (
unsigned E = LVal.Designator.Entries.size(); I != E; ++I) {
16575 const auto &Entry = LVal.Designator.Entries[I];
16576 if (BaseType->isArrayType()) {
16582 uint64_t Index = Entry.getAsArrayIndex();
16586 }
else if (BaseType->isAnyComplexType()) {
16587 const auto *CT = BaseType->castAs<
ComplexType>();
16588 uint64_t Index = Entry.getAsArrayIndex();
16591 BaseType = CT->getElementType();
16592 }
else if (
auto *FD = getAsField(Entry)) {
16593 if (!IsLastOrInvalidFieldDecl(FD))
16597 assert(getAsBaseClass(Entry) &&
"Expecting cast to a base class");
16609 if (LVal.Designator.Invalid)
16612 if (!LVal.Designator.Entries.empty())
16613 return LVal.Designator.isMostDerivedAnUnsizedArray();
16615 if (!LVal.InvalidBase)
16627 const SubobjectDesignator &
Designator = LVal.Designator;
16639 auto isFlexibleArrayMember = [&] {
16641 FAMKind StrictFlexArraysLevel =
16644 if (
Designator.isMostDerivedAnUnsizedArray())
16647 if (StrictFlexArraysLevel == FAMKind::Default)
16650 if (
Designator.getMostDerivedArraySize() == 0 &&
16651 StrictFlexArraysLevel != FAMKind::IncompleteOnly)
16654 if (
Designator.getMostDerivedArraySize() == 1 &&
16655 StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete)
16661 return LVal.InvalidBase &&
16663 Designator.MostDerivedIsArrayElement && isFlexibleArrayMember() &&
16671 auto CharUnitsMax = std::numeric_limits<CharUnits::QuantityType>::max();
16672 if (Int.ugt(CharUnitsMax))
16682 if (!
T.isNull() &&
T->isStructureType() &&
16683 T->castAsRecordDecl()->hasFlexibleArrayMember())
16684 if (
const auto *
V = LV.getLValueBase().dyn_cast<
const ValueDecl *>())
16685 if (
const auto *VD = dyn_cast<VarDecl>(
V))
16697 unsigned Type,
const LValue &LVal,
16716 if (!(
Type & 1) || LVal.Designator.Invalid || DetermineForCompleteObject) {
16718 if (
Type == 3 && !DetermineForCompleteObject)
16721 llvm::APInt APEndOffset;
16722 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
16726 if (LVal.InvalidBase)
16730 const bool Ret = CheckedHandleSizeof(BaseTy, EndOffset);
16736 const SubobjectDesignator &
Designator = LVal.Designator;
16748 llvm::APInt APEndOffset;
16749 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
16761 if (!CheckedHandleSizeof(
Designator.MostDerivedType, BytesPerElem))
16767 int64_t ElemsRemaining;
16770 uint64_t ArraySize =
Designator.getMostDerivedArraySize();
16771 uint64_t ArrayIndex =
Designator.Entries.back().getAsArrayIndex();
16772 ElemsRemaining = ArraySize <= ArrayIndex ? 0 : ArraySize - ArrayIndex;
16774 ElemsRemaining =
Designator.isOnePastTheEnd() ? 0 : 1;
16777 EndOffset = LVal.getLValueOffset() + BytesPerElem * ElemsRemaining;
16791static std::optional<uint64_t>
16793 bool IsDynamic =
false) {
16801 SpeculativeEvaluationRAII SpeculativeEval(Info);
16802 IgnoreSideEffectsRAII Fold(Info);
16809 return std::nullopt;
16810 LVal.setFrom(Info.Ctx, RVal);
16813 return std::nullopt;
16818 if (LVal.getLValueOffset().isNegative())
16833 const auto *FD = ME ? dyn_cast<FieldDecl>(ME->getMemberDecl()) :
nullptr;
16835 return std::nullopt;
16840 return std::nullopt;
16844 if (EndOffset <= LVal.getLValueOffset())
16846 return (EndOffset - LVal.getLValueOffset()).
getQuantity();
16849bool IntExprEvaluator::VisitCallExpr(
const CallExpr *E) {
16850 if (!IsConstantEvaluatedBuiltinCall(E))
16851 return ExprEvaluatorBaseTy::VisitCallExpr(E);
16868 Info.FFDiag(E->
getArg(0));
16874 assert(SrcInt.getBitWidth() >= Alignment.getBitWidth() &&
16875 "Bit widths must be the same");
16882bool IntExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *E,
16883 unsigned BuiltinOp) {
16884 auto EvalTestOp = [&](llvm::function_ref<
bool(
const APInt &,
const APInt &)>
16886 APValue SourceLHS, SourceRHS;
16894 unsigned LaneWidth = Info.Ctx.getTypeSize(ElemQT);
16896 APInt AWide(LaneWidth * SourceLen, 0);
16897 APInt BWide(LaneWidth * SourceLen, 0);
16899 for (
unsigned I = 0; I != SourceLen; ++I) {
16902 if (ElemQT->isIntegerType()) {
16905 }
else if (ElemQT->isFloatingType()) {
16913 AWide.insertBits(ALane, I * LaneWidth);
16914 BWide.insertBits(BLane, I * LaneWidth);
16919 auto HandleMaskBinOp =
16932 auto HandleCRC32 = [&](
unsigned DataBytes) ->
bool {
16938 uint64_t CRCVal = CRC.getZExtValue();
16942 static const uint32_t CRC32C_POLY = 0x82F63B78;
16946 for (
unsigned I = 0; I != DataBytes; ++I) {
16947 uint8_t Byte =
static_cast<uint8_t>((DataVal >> (I * 8)) & 0xFF);
16949 for (
int J = 0; J != 8; ++J) {
16957 switch (BuiltinOp) {
16961 case X86::BI__builtin_ia32_crc32qi:
16962 return HandleCRC32(1);
16963 case X86::BI__builtin_ia32_crc32hi:
16964 return HandleCRC32(2);
16965 case X86::BI__builtin_ia32_crc32si:
16966 return HandleCRC32(4);
16967 case X86::BI__builtin_ia32_crc32di:
16968 return HandleCRC32(8);
16970 case Builtin::BI__builtin_dynamic_object_size:
16971 case Builtin::BI__builtin_object_size: {
16975 assert(
Type <= 3 &&
"unexpected type");
16977 bool IsDynamic = BuiltinOp == Builtin::BI__builtin_dynamic_object_size;
16978 if (std::optional<uint64_t> Size =
16987 switch (Info.EvalMode) {
16988 case EvaluationMode::ConstantExpression:
16989 case EvaluationMode::ConstantFold:
16990 case EvaluationMode::IgnoreSideEffects:
16993 case EvaluationMode::ConstantExpressionUnevaluated:
16998 llvm_unreachable(
"unexpected EvalMode");
17001 case Builtin::BI__builtin_os_log_format_buffer_size: {
17002 analyze_os_log::OSLogBufferLayout Layout;
17007 case Builtin::BI__builtin_is_aligned: {
17015 Ptr.setFrom(Info.Ctx, Src);
17021 assert(Alignment.isPowerOf2());
17034 Info.FFDiag(E->
getArg(0), diag::note_constexpr_alignment_compute)
17038 assert(Src.
isInt());
17039 return Success((Src.
getInt() & (Alignment - 1)) == 0 ? 1 : 0, E);
17041 case Builtin::BI__builtin_align_up: {
17049 APSInt((Src.
getInt() + (Alignment - 1)) & ~(Alignment - 1),
17050 Src.
getInt().isUnsigned());
17051 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
17052 return Success(AlignedVal, E);
17054 case Builtin::BI__builtin_align_down: {
17063 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
17064 return Success(AlignedVal, E);
17067 case Builtin::BI__builtin_bitreverseg:
17068 case Builtin::BI__builtin_bitreverse8:
17069 case Builtin::BI__builtin_bitreverse16:
17070 case Builtin::BI__builtin_bitreverse32:
17071 case Builtin::BI__builtin_bitreverse64:
17072 case Builtin::BI__builtin_elementwise_bitreverse: {
17077 return Success(Val.reverseBits(), E);
17079 case Builtin::BI__builtin_bswapg:
17080 case Builtin::BI__builtin_bswap16:
17081 case Builtin::BI__builtin_bswap32:
17082 case Builtin::BI__builtin_bswap64:
17083 case Builtin::BIstdc_memreverse8u8:
17084 case Builtin::BIstdc_memreverse8u16:
17085 case Builtin::BIstdc_memreverse8u32:
17086 case Builtin::BIstdc_memreverse8u64: {
17090 if (Val.getBitWidth() == 8 || Val.getBitWidth() == 1)
17093 return Success(Val.byteSwap(), E);
17096 case Builtin::BI__builtin_classify_type:
17099 case Builtin::BI__builtin_clrsb:
17100 case Builtin::BI__builtin_clrsbl:
17101 case Builtin::BI__builtin_clrsbll: {
17106 return Success(Val.getBitWidth() - Val.getSignificantBits(), E);
17109 case Builtin::BI__builtin_clz:
17110 case Builtin::BI__builtin_clzl:
17111 case Builtin::BI__builtin_clzll:
17112 case Builtin::BI__builtin_clzs:
17113 case Builtin::BI__builtin_clzg:
17114 case Builtin::BI__builtin_elementwise_clzg:
17115 case Builtin::BI__lzcnt16:
17116 case Builtin::BI__lzcnt:
17117 case Builtin::BI__lzcnt64: {
17128 std::optional<APSInt> Fallback;
17129 if ((BuiltinOp == Builtin::BI__builtin_clzg ||
17130 BuiltinOp == Builtin::BI__builtin_elementwise_clzg) &&
17135 Fallback = FallbackTemp;
17140 return Success(*Fallback, E);
17145 bool ZeroIsUndefined = BuiltinOp != Builtin::BI__lzcnt16 &&
17146 BuiltinOp != Builtin::BI__lzcnt &&
17147 BuiltinOp != Builtin::BI__lzcnt64;
17149 if (BuiltinOp == Builtin::BI__builtin_elementwise_clzg) {
17150 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
17154 if (ZeroIsUndefined)
17158 return Success(Val.countl_zero(), E);
17161 case Builtin::BI__builtin_constant_p: {
17162 const Expr *Arg = E->
getArg(0);
17171 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
17175 case Builtin::BI__noop:
17179 case Builtin::BI__builtin_is_constant_evaluated: {
17180 const auto *
Callee = Info.CurrentCall->getCallee();
17181 if (Info.InConstantContext && !Info.CheckingPotentialConstantExpression &&
17182 (Info.CallStackDepth == 1 ||
17183 (Info.CallStackDepth == 2 &&
Callee->isInStdNamespace() &&
17184 Callee->getIdentifier() &&
17185 Callee->getIdentifier()->isStr(
"is_constant_evaluated")))) {
17187 if (Info.EvalStatus.Diag)
17188 Info.report((Info.CallStackDepth == 1)
17190 : Info.CurrentCall->getCallRange().getBegin(),
17191 diag::warn_is_constant_evaluated_always_true_constexpr)
17192 << (Info.CallStackDepth == 1 ?
"__builtin_is_constant_evaluated"
17193 :
"std::is_constant_evaluated");
17196 return Success(Info.InConstantContext, E);
17199 case Builtin::BI__builtin_is_within_lifetime:
17200 if (
auto result = EvaluateBuiltinIsWithinLifetime(*
this, E))
17204 case Builtin::BI__builtin_ctz:
17205 case Builtin::BI__builtin_ctzl:
17206 case Builtin::BI__builtin_ctzll:
17207 case Builtin::BI__builtin_ctzs:
17208 case Builtin::BI__builtin_ctzg:
17209 case Builtin::BI__builtin_elementwise_ctzg: {
17220 std::optional<APSInt> Fallback;
17221 if ((BuiltinOp == Builtin::BI__builtin_ctzg ||
17222 BuiltinOp == Builtin::BI__builtin_elementwise_ctzg) &&
17227 Fallback = FallbackTemp;
17232 return Success(*Fallback, E);
17234 if (BuiltinOp == Builtin::BI__builtin_elementwise_ctzg) {
17235 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
17241 return Success(Val.countr_zero(), E);
17244 case Builtin::BI__builtin_eh_return_data_regno: {
17246 Operand = Info.Ctx.getTargetInfo().getEHDataRegisterNumber(Operand);
17250 case Builtin::BI__builtin_elementwise_abs: {
17255 return Success(Val.abs(), E);
17258 case Builtin::BI__builtin_expect:
17259 case Builtin::BI__builtin_expect_with_probability:
17260 return Visit(E->
getArg(0));
17262 case Builtin::BI__builtin_ptrauth_string_discriminator: {
17269 case Builtin::BI__builtin_infer_alloc_token: {
17275 E, diag::note_constexpr_infer_alloc_token_type_inference_failed);
17278 return Error(E, diag::note_constexpr_infer_alloc_token_no_metadata);
17280 Info.getLangOpts().AllocTokenMode.value_or(llvm::DefaultAllocTokenMode);
17281 uint64_t BitWidth = Info.Ctx.getTypeSize(Info.Ctx.getSizeType());
17282 auto MaxTokensOpt = Info.getLangOpts().AllocTokenMax;
17284 MaxTokensOpt.value_or(0) ? *MaxTokensOpt : (~0ULL >> (64 - BitWidth));
17285 auto MaybeToken = llvm::getAllocToken(Mode, *ATMD, MaxTokens);
17287 return Error(E, diag::note_constexpr_infer_alloc_token_stateful_mode);
17288 return Success(llvm::APInt(BitWidth, *MaybeToken), E);
17291 case Builtin::BI__builtin_ffs:
17292 case Builtin::BI__builtin_ffsl:
17293 case Builtin::BI__builtin_ffsll: {
17298 unsigned N = Val.countr_zero();
17299 return Success(N == Val.getBitWidth() ? 0 : N + 1, E);
17302 case Builtin::BI__builtin_fpclassify: {
17307 switch (Val.getCategory()) {
17308 case APFloat::fcNaN: Arg = 0;
break;
17309 case APFloat::fcInfinity: Arg = 1;
break;
17310 case APFloat::fcNormal: Arg = Val.isDenormal() ? 3 : 2;
break;
17311 case APFloat::fcZero: Arg = 4;
break;
17313 return Visit(E->
getArg(Arg));
17316 case Builtin::BI__builtin_isinf_sign: {
17319 Success(Val.isInfinity() ? (Val.isNegative() ? -1 : 1) : 0, E);
17322 case Builtin::BI__builtin_isinf: {
17325 Success(Val.isInfinity() ? 1 : 0, E);
17328 case Builtin::BI__builtin_isfinite: {
17331 Success(Val.isFinite() ? 1 : 0, E);
17334 case Builtin::BI__builtin_isnan: {
17337 Success(Val.isNaN() ? 1 : 0, E);
17340 case Builtin::BI__builtin_isnormal: {
17343 Success(Val.isNormal() ? 1 : 0, E);
17346 case Builtin::BI__builtin_issubnormal: {
17349 Success(Val.isDenormal() ? 1 : 0, E);
17352 case Builtin::BI__builtin_iszero: {
17355 Success(Val.isZero() ? 1 : 0, E);
17358 case Builtin::BI__builtin_signbit:
17359 case Builtin::BI__builtin_signbitf:
17360 case Builtin::BI__builtin_signbitl: {
17363 Success(Val.isNegative() ? 1 : 0, E);
17366 case Builtin::BI__builtin_isgreater:
17367 case Builtin::BI__builtin_isgreaterequal:
17368 case Builtin::BI__builtin_isless:
17369 case Builtin::BI__builtin_islessequal:
17370 case Builtin::BI__builtin_islessgreater:
17371 case Builtin::BI__builtin_isunordered: {
17380 switch (BuiltinOp) {
17381 case Builtin::BI__builtin_isgreater:
17383 case Builtin::BI__builtin_isgreaterequal:
17385 case Builtin::BI__builtin_isless:
17387 case Builtin::BI__builtin_islessequal:
17389 case Builtin::BI__builtin_islessgreater: {
17390 APFloat::cmpResult cmp = LHS.compare(RHS);
17391 return cmp == APFloat::cmpResult::cmpLessThan ||
17392 cmp == APFloat::cmpResult::cmpGreaterThan;
17394 case Builtin::BI__builtin_isunordered:
17395 return LHS.compare(RHS) == APFloat::cmpResult::cmpUnordered;
17397 llvm_unreachable(
"Unexpected builtin ID: Should be a floating "
17398 "point comparison function");
17406 case Builtin::BI__builtin_issignaling: {
17409 Success(Val.isSignaling() ? 1 : 0, E);
17412 case Builtin::BI__builtin_isfpclass: {
17416 unsigned Test =
static_cast<llvm::FPClassTest
>(MaskVal.getZExtValue());
17419 Success((Val.classify() & Test) ? 1 : 0, E);
17422 case Builtin::BI__builtin_parity:
17423 case Builtin::BI__builtin_parityl:
17424 case Builtin::BI__builtin_parityll: {
17429 return Success(Val.popcount() % 2, E);
17432 case Builtin::BI__builtin_abs:
17433 case Builtin::BI__builtin_labs:
17434 case Builtin::BI__builtin_llabs: {
17438 if (Val ==
APSInt(APInt::getSignedMinValue(Val.getBitWidth()),
17441 if (Val.isNegative())
17446 case Builtin::BI__builtin_popcount:
17447 case Builtin::BI__builtin_popcountl:
17448 case Builtin::BI__builtin_popcountll:
17449 case Builtin::BI__builtin_popcountg:
17450 case Builtin::BI__builtin_elementwise_popcount:
17451 case Builtin::BI__popcnt16:
17452 case Builtin::BI__popcnt:
17453 case Builtin::BI__popcnt64: {
17464 return Success(Val.popcount(), E);
17467 case Builtin::BI__builtin_rotateleft8:
17468 case Builtin::BI__builtin_rotateleft16:
17469 case Builtin::BI__builtin_rotateleft32:
17470 case Builtin::BI__builtin_rotateleft64:
17471 case Builtin::BI__builtin_rotateright8:
17472 case Builtin::BI__builtin_rotateright16:
17473 case Builtin::BI__builtin_rotateright32:
17474 case Builtin::BI__builtin_rotateright64:
17475 case Builtin::BI__builtin_stdc_rotate_left:
17476 case Builtin::BI__builtin_stdc_rotate_right:
17477 case Builtin::BIstdc_rotate_left_uc:
17478 case Builtin::BIstdc_rotate_left_us:
17479 case Builtin::BIstdc_rotate_left_ui:
17480 case Builtin::BIstdc_rotate_left_ul:
17481 case Builtin::BIstdc_rotate_left_ull:
17482 case Builtin::BIstdc_rotate_right_uc:
17483 case Builtin::BIstdc_rotate_right_us:
17484 case Builtin::BIstdc_rotate_right_ui:
17485 case Builtin::BIstdc_rotate_right_ul:
17486 case Builtin::BIstdc_rotate_right_ull:
17487 case Builtin::BI_rotl8:
17488 case Builtin::BI_rotl16:
17489 case Builtin::BI_rotl:
17490 case Builtin::BI_lrotl:
17491 case Builtin::BI_rotl64:
17492 case Builtin::BI_rotr8:
17493 case Builtin::BI_rotr16:
17494 case Builtin::BI_rotr:
17495 case Builtin::BI_lrotr:
17496 case Builtin::BI_rotr64: {
17504 switch (BuiltinOp) {
17505 case Builtin::BI__builtin_rotateright8:
17506 case Builtin::BI__builtin_rotateright16:
17507 case Builtin::BI__builtin_rotateright32:
17508 case Builtin::BI__builtin_rotateright64:
17509 case Builtin::BI__builtin_stdc_rotate_right:
17510 case Builtin::BIstdc_rotate_right_uc:
17511 case Builtin::BIstdc_rotate_right_us:
17512 case Builtin::BIstdc_rotate_right_ui:
17513 case Builtin::BIstdc_rotate_right_ul:
17514 case Builtin::BIstdc_rotate_right_ull:
17515 case Builtin::BI_rotr8:
17516 case Builtin::BI_rotr16:
17517 case Builtin::BI_rotr:
17518 case Builtin::BI_lrotr:
17519 case Builtin::BI_rotr64:
17528 case Builtin::BIstdc_leading_zeros_uc:
17529 case Builtin::BIstdc_leading_zeros_us:
17530 case Builtin::BIstdc_leading_zeros_ui:
17531 case Builtin::BIstdc_leading_zeros_ul:
17532 case Builtin::BIstdc_leading_zeros_ull:
17533 case Builtin::BIstdc_leading_ones_uc:
17534 case Builtin::BIstdc_leading_ones_us:
17535 case Builtin::BIstdc_leading_ones_ui:
17536 case Builtin::BIstdc_leading_ones_ul:
17537 case Builtin::BIstdc_leading_ones_ull:
17538 case Builtin::BIstdc_trailing_zeros_uc:
17539 case Builtin::BIstdc_trailing_zeros_us:
17540 case Builtin::BIstdc_trailing_zeros_ui:
17541 case Builtin::BIstdc_trailing_zeros_ul:
17542 case Builtin::BIstdc_trailing_zeros_ull:
17543 case Builtin::BIstdc_trailing_ones_uc:
17544 case Builtin::BIstdc_trailing_ones_us:
17545 case Builtin::BIstdc_trailing_ones_ui:
17546 case Builtin::BIstdc_trailing_ones_ul:
17547 case Builtin::BIstdc_trailing_ones_ull:
17548 case Builtin::BIstdc_first_leading_zero_uc:
17549 case Builtin::BIstdc_first_leading_zero_us:
17550 case Builtin::BIstdc_first_leading_zero_ui:
17551 case Builtin::BIstdc_first_leading_zero_ul:
17552 case Builtin::BIstdc_first_leading_zero_ull:
17553 case Builtin::BIstdc_first_leading_one_uc:
17554 case Builtin::BIstdc_first_leading_one_us:
17555 case Builtin::BIstdc_first_leading_one_ui:
17556 case Builtin::BIstdc_first_leading_one_ul:
17557 case Builtin::BIstdc_first_leading_one_ull:
17558 case Builtin::BIstdc_first_trailing_zero_uc:
17559 case Builtin::BIstdc_first_trailing_zero_us:
17560 case Builtin::BIstdc_first_trailing_zero_ui:
17561 case Builtin::BIstdc_first_trailing_zero_ul:
17562 case Builtin::BIstdc_first_trailing_zero_ull:
17563 case Builtin::BIstdc_first_trailing_one_uc:
17564 case Builtin::BIstdc_first_trailing_one_us:
17565 case Builtin::BIstdc_first_trailing_one_ui:
17566 case Builtin::BIstdc_first_trailing_one_ul:
17567 case Builtin::BIstdc_first_trailing_one_ull:
17568 case Builtin::BIstdc_count_zeros_uc:
17569 case Builtin::BIstdc_count_zeros_us:
17570 case Builtin::BIstdc_count_zeros_ui:
17571 case Builtin::BIstdc_count_zeros_ul:
17572 case Builtin::BIstdc_count_zeros_ull:
17573 case Builtin::BIstdc_count_ones_uc:
17574 case Builtin::BIstdc_count_ones_us:
17575 case Builtin::BIstdc_count_ones_ui:
17576 case Builtin::BIstdc_count_ones_ul:
17577 case Builtin::BIstdc_count_ones_ull:
17578 case Builtin::BIstdc_has_single_bit_uc:
17579 case Builtin::BIstdc_has_single_bit_us:
17580 case Builtin::BIstdc_has_single_bit_ui:
17581 case Builtin::BIstdc_has_single_bit_ul:
17582 case Builtin::BIstdc_has_single_bit_ull:
17583 case Builtin::BIstdc_bit_width_uc:
17584 case Builtin::BIstdc_bit_width_us:
17585 case Builtin::BIstdc_bit_width_ui:
17586 case Builtin::BIstdc_bit_width_ul:
17587 case Builtin::BIstdc_bit_width_ull:
17588 case Builtin::BIstdc_bit_floor_uc:
17589 case Builtin::BIstdc_bit_floor_us:
17590 case Builtin::BIstdc_bit_floor_ui:
17591 case Builtin::BIstdc_bit_floor_ul:
17592 case Builtin::BIstdc_bit_floor_ull:
17593 case Builtin::BIstdc_bit_ceil_uc:
17594 case Builtin::BIstdc_bit_ceil_us:
17595 case Builtin::BIstdc_bit_ceil_ui:
17596 case Builtin::BIstdc_bit_ceil_ul:
17597 case Builtin::BIstdc_bit_ceil_ull:
17598 case Builtin::BI__builtin_stdc_leading_zeros:
17599 case Builtin::BI__builtin_stdc_leading_ones:
17600 case Builtin::BI__builtin_stdc_trailing_zeros:
17601 case Builtin::BI__builtin_stdc_trailing_ones:
17602 case Builtin::BI__builtin_stdc_first_leading_zero:
17603 case Builtin::BI__builtin_stdc_first_leading_one:
17604 case Builtin::BI__builtin_stdc_first_trailing_zero:
17605 case Builtin::BI__builtin_stdc_first_trailing_one:
17606 case Builtin::BI__builtin_stdc_count_zeros:
17607 case Builtin::BI__builtin_stdc_count_ones:
17608 case Builtin::BI__builtin_stdc_has_single_bit:
17609 case Builtin::BI__builtin_stdc_bit_width:
17610 case Builtin::BI__builtin_stdc_bit_floor:
17611 case Builtin::BI__builtin_stdc_bit_ceil: {
17616 unsigned BitWidth = Val.getBitWidth();
17617 const unsigned ResBitWidth = Info.Ctx.getIntWidth(E->
getType());
17619 switch (BuiltinOp) {
17620 case Builtin::BIstdc_leading_zeros_uc:
17621 case Builtin::BIstdc_leading_zeros_us:
17622 case Builtin::BIstdc_leading_zeros_ui:
17623 case Builtin::BIstdc_leading_zeros_ul:
17624 case Builtin::BIstdc_leading_zeros_ull:
17625 case Builtin::BI__builtin_stdc_leading_zeros:
17626 return Success(
APInt(ResBitWidth, Val.countl_zero()), E);
17627 case Builtin::BIstdc_leading_ones_uc:
17628 case Builtin::BIstdc_leading_ones_us:
17629 case Builtin::BIstdc_leading_ones_ui:
17630 case Builtin::BIstdc_leading_ones_ul:
17631 case Builtin::BIstdc_leading_ones_ull:
17632 case Builtin::BI__builtin_stdc_leading_ones:
17633 return Success(
APInt(ResBitWidth, Val.countl_one()), E);
17634 case Builtin::BIstdc_trailing_zeros_uc:
17635 case Builtin::BIstdc_trailing_zeros_us:
17636 case Builtin::BIstdc_trailing_zeros_ui:
17637 case Builtin::BIstdc_trailing_zeros_ul:
17638 case Builtin::BIstdc_trailing_zeros_ull:
17639 case Builtin::BI__builtin_stdc_trailing_zeros:
17640 return Success(
APInt(ResBitWidth, Val.countr_zero()), E);
17641 case Builtin::BIstdc_trailing_ones_uc:
17642 case Builtin::BIstdc_trailing_ones_us:
17643 case Builtin::BIstdc_trailing_ones_ui:
17644 case Builtin::BIstdc_trailing_ones_ul:
17645 case Builtin::BIstdc_trailing_ones_ull:
17646 case Builtin::BI__builtin_stdc_trailing_ones:
17647 return Success(
APInt(ResBitWidth, Val.countr_one()), E);
17648 case Builtin::BIstdc_first_leading_zero_uc:
17649 case Builtin::BIstdc_first_leading_zero_us:
17650 case Builtin::BIstdc_first_leading_zero_ui:
17651 case Builtin::BIstdc_first_leading_zero_ul:
17652 case Builtin::BIstdc_first_leading_zero_ull:
17653 case Builtin::BI__builtin_stdc_first_leading_zero:
17655 APInt(ResBitWidth, Val.isAllOnes() ? 0 : Val.countl_one() + 1), E);
17656 case Builtin::BIstdc_first_leading_one_uc:
17657 case Builtin::BIstdc_first_leading_one_us:
17658 case Builtin::BIstdc_first_leading_one_ui:
17659 case Builtin::BIstdc_first_leading_one_ul:
17660 case Builtin::BIstdc_first_leading_one_ull:
17661 case Builtin::BI__builtin_stdc_first_leading_one:
17663 APInt(ResBitWidth, Val.isZero() ? 0 : Val.countl_zero() + 1), E);
17664 case Builtin::BIstdc_first_trailing_zero_uc:
17665 case Builtin::BIstdc_first_trailing_zero_us:
17666 case Builtin::BIstdc_first_trailing_zero_ui:
17667 case Builtin::BIstdc_first_trailing_zero_ul:
17668 case Builtin::BIstdc_first_trailing_zero_ull:
17669 case Builtin::BI__builtin_stdc_first_trailing_zero:
17671 APInt(ResBitWidth, Val.isAllOnes() ? 0 : Val.countr_one() + 1), E);
17672 case Builtin::BIstdc_first_trailing_one_uc:
17673 case Builtin::BIstdc_first_trailing_one_us:
17674 case Builtin::BIstdc_first_trailing_one_ui:
17675 case Builtin::BIstdc_first_trailing_one_ul:
17676 case Builtin::BIstdc_first_trailing_one_ull:
17677 case Builtin::BI__builtin_stdc_first_trailing_one:
17679 APInt(ResBitWidth, Val.isZero() ? 0 : Val.countr_zero() + 1), E);
17680 case Builtin::BIstdc_count_zeros_uc:
17681 case Builtin::BIstdc_count_zeros_us:
17682 case Builtin::BIstdc_count_zeros_ui:
17683 case Builtin::BIstdc_count_zeros_ul:
17684 case Builtin::BIstdc_count_zeros_ull:
17685 case Builtin::BI__builtin_stdc_count_zeros: {
17686 APInt Cnt(ResBitWidth, BitWidth - Val.popcount());
17689 case Builtin::BIstdc_count_ones_uc:
17690 case Builtin::BIstdc_count_ones_us:
17691 case Builtin::BIstdc_count_ones_ui:
17692 case Builtin::BIstdc_count_ones_ul:
17693 case Builtin::BIstdc_count_ones_ull:
17694 case Builtin::BI__builtin_stdc_count_ones: {
17695 APInt Cnt(ResBitWidth, Val.popcount());
17698 case Builtin::BIstdc_has_single_bit_uc:
17699 case Builtin::BIstdc_has_single_bit_us:
17700 case Builtin::BIstdc_has_single_bit_ui:
17701 case Builtin::BIstdc_has_single_bit_ul:
17702 case Builtin::BIstdc_has_single_bit_ull:
17703 case Builtin::BI__builtin_stdc_has_single_bit: {
17704 APInt Res(ResBitWidth, Val.popcount() == 1 ? 1 : 0);
17707 case Builtin::BIstdc_bit_width_uc:
17708 case Builtin::BIstdc_bit_width_us:
17709 case Builtin::BIstdc_bit_width_ui:
17710 case Builtin::BIstdc_bit_width_ul:
17711 case Builtin::BIstdc_bit_width_ull:
17712 case Builtin::BI__builtin_stdc_bit_width:
17713 return Success(
APInt(ResBitWidth, BitWidth - Val.countl_zero()), E);
17714 case Builtin::BIstdc_bit_floor_uc:
17715 case Builtin::BIstdc_bit_floor_us:
17716 case Builtin::BIstdc_bit_floor_ui:
17717 case Builtin::BIstdc_bit_floor_ul:
17718 case Builtin::BIstdc_bit_floor_ull:
17719 case Builtin::BI__builtin_stdc_bit_floor: {
17722 unsigned Exp = BitWidth - Val.countl_zero() - 1;
17724 APSInt(APInt::getOneBitSet(BitWidth, Exp),
true), E);
17726 case Builtin::BIstdc_bit_ceil_uc:
17727 case Builtin::BIstdc_bit_ceil_us:
17728 case Builtin::BIstdc_bit_ceil_ui:
17729 case Builtin::BIstdc_bit_ceil_ul:
17730 case Builtin::BIstdc_bit_ceil_ull:
17731 case Builtin::BI__builtin_stdc_bit_ceil: {
17734 APInt ValMinusOne = Val - 1;
17735 unsigned LZ = ValMinusOne.countl_zero();
17739 APInt Result = APInt::getOneBitSet(BitWidth, BitWidth - LZ);
17743 llvm_unreachable(
"Unknown stdc builtin");
17747 case Builtin::BI__builtin_elementwise_add_sat: {
17753 APInt Result = LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS);
17756 case Builtin::BI__builtin_elementwise_sub_sat: {
17762 APInt Result = LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
17765 case Builtin::BI__builtin_elementwise_max: {
17774 case Builtin::BI__builtin_elementwise_min: {
17783 case Builtin::BI__builtin_elementwise_clmul: {
17792 case Builtin::BI__builtin_elementwise_fshl:
17793 case Builtin::BI__builtin_elementwise_fshr: {
17800 switch (BuiltinOp) {
17801 case Builtin::BI__builtin_elementwise_fshl: {
17802 APSInt Result(llvm::APIntOps::fshl(Hi, Lo, Shift), Hi.isUnsigned());
17805 case Builtin::BI__builtin_elementwise_fshr: {
17806 APSInt Result(llvm::APIntOps::fshr(Hi, Lo, Shift), Hi.isUnsigned());
17810 llvm_unreachable(
"Fully covered switch above");
17812 case Builtin::BIstrlen:
17813 case Builtin::BIwcslen:
17815 if (Info.getLangOpts().CPlusPlus11)
17816 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
17818 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
17820 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
17822 case Builtin::BI__builtin_strlen:
17823 case Builtin::BI__builtin_wcslen: {
17826 if (std::optional<uint64_t> StrLen =
17832 case Builtin::BIstrcmp:
17833 case Builtin::BIwcscmp:
17834 case Builtin::BIstrncmp:
17835 case Builtin::BIwcsncmp:
17836 case Builtin::BImemcmp:
17837 case Builtin::BIbcmp:
17838 case Builtin::BIwmemcmp:
17840 if (Info.getLangOpts().CPlusPlus11)
17841 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
17843 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
17845 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
17847 case Builtin::BI__builtin_strcmp:
17848 case Builtin::BI__builtin_wcscmp:
17849 case Builtin::BI__builtin_strncmp:
17850 case Builtin::BI__builtin_wcsncmp:
17851 case Builtin::BI__builtin_memcmp:
17852 case Builtin::BI__builtin_bcmp:
17853 case Builtin::BI__builtin_wmemcmp: {
17854 LValue String1, String2;
17860 if (BuiltinOp != Builtin::BIstrcmp &&
17861 BuiltinOp != Builtin::BIwcscmp &&
17862 BuiltinOp != Builtin::BI__builtin_strcmp &&
17863 BuiltinOp != Builtin::BI__builtin_wcscmp) {
17867 MaxLength = N.getZExtValue();
17871 if (MaxLength == 0u)
17874 if (!String1.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
17875 !String2.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
17876 String1.Designator.Invalid || String2.Designator.Invalid)
17879 QualType CharTy1 = String1.Designator.getType(Info.Ctx);
17880 QualType CharTy2 = String2.Designator.getType(Info.Ctx);
17882 bool IsRawByte = BuiltinOp == Builtin::BImemcmp ||
17883 BuiltinOp == Builtin::BIbcmp ||
17884 BuiltinOp == Builtin::BI__builtin_memcmp ||
17885 BuiltinOp == Builtin::BI__builtin_bcmp;
17887 assert(IsRawByte ||
17888 (Info.Ctx.hasSameUnqualifiedType(
17890 Info.Ctx.hasSameUnqualifiedType(CharTy1, CharTy2)));
17897 Info.FFDiag(E, diag::note_constexpr_memcmp_unsupported)
17898 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp) << CharTy1
17903 const auto &ReadCurElems = [&](
APValue &Char1,
APValue &Char2) {
17906 Char1.
isInt() && Char2.isInt();
17908 const auto &AdvanceElems = [&] {
17914 (BuiltinOp != Builtin::BImemcmp && BuiltinOp != Builtin::BIbcmp &&
17915 BuiltinOp != Builtin::BIwmemcmp &&
17916 BuiltinOp != Builtin::BI__builtin_memcmp &&
17917 BuiltinOp != Builtin::BI__builtin_bcmp &&
17918 BuiltinOp != Builtin::BI__builtin_wmemcmp);
17919 bool IsWide = BuiltinOp == Builtin::BIwcscmp ||
17920 BuiltinOp == Builtin::BIwcsncmp ||
17921 BuiltinOp == Builtin::BIwmemcmp ||
17922 BuiltinOp == Builtin::BI__builtin_wcscmp ||
17923 BuiltinOp == Builtin::BI__builtin_wcsncmp ||
17924 BuiltinOp == Builtin::BI__builtin_wmemcmp;
17926 for (; MaxLength; --MaxLength) {
17928 if (!ReadCurElems(Char1, Char2))
17936 if (StopAtNull && !Char1.
getInt())
17938 assert(!(StopAtNull && !Char2.
getInt()));
17939 if (!AdvanceElems())
17946 case Builtin::BI__atomic_always_lock_free:
17947 case Builtin::BI__atomic_is_lock_free:
17948 case Builtin::BI__c11_atomic_is_lock_free: {
17964 if (
Size.isPowerOfTwo()) {
17966 unsigned InlineWidthBits =
17967 Info.Ctx.getTargetInfo().getMaxAtomicInlineWidth();
17968 if (Size <= Info.Ctx.toCharUnitsFromBits(InlineWidthBits)) {
17969 if (BuiltinOp == Builtin::BI__c11_atomic_is_lock_free ||
17975 const Expr *PtrArg = E->
getArg(1);
17981 IntResult.isAligned(
Size.getAsAlign()))
17985 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(PtrArg)) {
17988 if (ICE->getCastKind() == CK_BitCast)
17989 PtrArg = ICE->getSubExpr();
17992 if (
auto PtrTy = PtrArg->
getType()->
getAs<PointerType>()) {
17995 Info.Ctx.getTypeAlignInChars(PointeeType) >= Size) {
18003 return BuiltinOp == Builtin::BI__atomic_always_lock_free ?
18006 case Builtin::BI__builtin_addcb:
18007 case Builtin::BI__builtin_addcs:
18008 case Builtin::BI__builtin_addc:
18009 case Builtin::BI__builtin_addcl:
18010 case Builtin::BI__builtin_addcll:
18011 case Builtin::BI__builtin_subcb:
18012 case Builtin::BI__builtin_subcs:
18013 case Builtin::BI__builtin_subc:
18014 case Builtin::BI__builtin_subcl:
18015 case Builtin::BI__builtin_subcll: {
18016 LValue CarryOutLValue;
18028 bool FirstOverflowed =
false;
18029 bool SecondOverflowed =
false;
18030 switch (BuiltinOp) {
18032 llvm_unreachable(
"Invalid value for BuiltinOp");
18033 case Builtin::BI__builtin_addcb:
18034 case Builtin::BI__builtin_addcs:
18035 case Builtin::BI__builtin_addc:
18036 case Builtin::BI__builtin_addcl:
18037 case Builtin::BI__builtin_addcll:
18039 LHS.uadd_ov(RHS, FirstOverflowed).uadd_ov(CarryIn, SecondOverflowed);
18041 case Builtin::BI__builtin_subcb:
18042 case Builtin::BI__builtin_subcs:
18043 case Builtin::BI__builtin_subc:
18044 case Builtin::BI__builtin_subcl:
18045 case Builtin::BI__builtin_subcll:
18047 LHS.usub_ov(RHS, FirstOverflowed).usub_ov(CarryIn, SecondOverflowed);
18053 CarryOut = (
uint64_t)(FirstOverflowed | SecondOverflowed);
18059 case Builtin::BI__builtin_add_overflow:
18060 case Builtin::BI__builtin_sub_overflow:
18061 case Builtin::BI__builtin_mul_overflow:
18062 case Builtin::BI__builtin_sadd_overflow:
18063 case Builtin::BI__builtin_uadd_overflow:
18064 case Builtin::BI__builtin_uaddl_overflow:
18065 case Builtin::BI__builtin_uaddll_overflow:
18066 case Builtin::BI__builtin_usub_overflow:
18067 case Builtin::BI__builtin_usubl_overflow:
18068 case Builtin::BI__builtin_usubll_overflow:
18069 case Builtin::BI__builtin_umul_overflow:
18070 case Builtin::BI__builtin_umull_overflow:
18071 case Builtin::BI__builtin_umulll_overflow:
18072 case Builtin::BI__builtin_saddl_overflow:
18073 case Builtin::BI__builtin_saddll_overflow:
18074 case Builtin::BI__builtin_ssub_overflow:
18075 case Builtin::BI__builtin_ssubl_overflow:
18076 case Builtin::BI__builtin_ssubll_overflow:
18077 case Builtin::BI__builtin_smul_overflow:
18078 case Builtin::BI__builtin_smull_overflow:
18079 case Builtin::BI__builtin_smulll_overflow: {
18080 LValue ResultLValue;
18090 bool DidOverflow =
false;
18093 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
18094 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
18095 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
18096 bool IsSigned = LHS.isSigned() || RHS.isSigned() ||
18098 bool AllSigned = LHS.isSigned() && RHS.isSigned() &&
18100 uint64_t LHSSize = LHS.getBitWidth();
18101 uint64_t RHSSize = RHS.getBitWidth();
18102 uint64_t ResultSize = Info.Ctx.getIntWidth(ResultType);
18103 uint64_t MaxBits = std::max(std::max(LHSSize, RHSSize), ResultSize);
18109 if (IsSigned && !AllSigned)
18112 LHS =
APSInt(LHS.extOrTrunc(MaxBits), !IsSigned);
18113 RHS =
APSInt(RHS.extOrTrunc(MaxBits), !IsSigned);
18118 switch (BuiltinOp) {
18120 llvm_unreachable(
"Invalid value for BuiltinOp");
18121 case Builtin::BI__builtin_add_overflow:
18122 case Builtin::BI__builtin_sadd_overflow:
18123 case Builtin::BI__builtin_saddl_overflow:
18124 case Builtin::BI__builtin_saddll_overflow:
18125 case Builtin::BI__builtin_uadd_overflow:
18126 case Builtin::BI__builtin_uaddl_overflow:
18127 case Builtin::BI__builtin_uaddll_overflow:
18128 Result = LHS.isSigned() ? LHS.sadd_ov(RHS, DidOverflow)
18129 : LHS.uadd_ov(RHS, DidOverflow);
18131 case Builtin::BI__builtin_sub_overflow:
18132 case Builtin::BI__builtin_ssub_overflow:
18133 case Builtin::BI__builtin_ssubl_overflow:
18134 case Builtin::BI__builtin_ssubll_overflow:
18135 case Builtin::BI__builtin_usub_overflow:
18136 case Builtin::BI__builtin_usubl_overflow:
18137 case Builtin::BI__builtin_usubll_overflow:
18138 Result = LHS.isSigned() ? LHS.ssub_ov(RHS, DidOverflow)
18139 : LHS.usub_ov(RHS, DidOverflow);
18141 case Builtin::BI__builtin_mul_overflow:
18142 case Builtin::BI__builtin_smul_overflow:
18143 case Builtin::BI__builtin_smull_overflow:
18144 case Builtin::BI__builtin_smulll_overflow:
18145 case Builtin::BI__builtin_umul_overflow:
18146 case Builtin::BI__builtin_umull_overflow:
18147 case Builtin::BI__builtin_umulll_overflow:
18148 Result = LHS.isSigned() ? LHS.smul_ov(RHS, DidOverflow)
18149 : LHS.umul_ov(RHS, DidOverflow);
18158 APSInt Temp =
Result.extOrTrunc(Info.Ctx.getIntWidth(ResultType));
18163 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
18164 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
18165 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
18166 if (!APSInt::isSameValue(Temp,
Result))
18167 DidOverflow =
true;
18174 return Success(DidOverflow, E);
18177 case Builtin::BI__builtin_reduce_add:
18178 case Builtin::BI__builtin_reduce_mul:
18179 case Builtin::BI__builtin_reduce_and:
18180 case Builtin::BI__builtin_reduce_or:
18181 case Builtin::BI__builtin_reduce_xor:
18182 case Builtin::BI__builtin_reduce_min:
18183 case Builtin::BI__builtin_reduce_max: {
18190 for (
unsigned EltNum = 1; EltNum < SourceLen; ++EltNum) {
18191 switch (BuiltinOp) {
18194 case Builtin::BI__builtin_reduce_add: {
18197 Reduced.getBitWidth() + 1, std::plus<APSInt>(), Reduced))
18201 case Builtin::BI__builtin_reduce_mul: {
18204 Reduced.getBitWidth() * 2, std::multiplies<APSInt>(), Reduced))
18208 case Builtin::BI__builtin_reduce_and: {
18212 case Builtin::BI__builtin_reduce_or: {
18216 case Builtin::BI__builtin_reduce_xor: {
18220 case Builtin::BI__builtin_reduce_min: {
18224 case Builtin::BI__builtin_reduce_max: {
18234 case clang::X86::BI__builtin_ia32_addcarryx_u32:
18235 case clang::X86::BI__builtin_ia32_addcarryx_u64:
18236 case clang::X86::BI__builtin_ia32_subborrow_u32:
18237 case clang::X86::BI__builtin_ia32_subborrow_u64: {
18238 LValue ResultLValue;
18239 APSInt CarryIn, LHS, RHS;
18247 bool IsAdd = BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u32 ||
18248 BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u64;
18250 unsigned BitWidth = LHS.getBitWidth();
18251 unsigned CarryInBit = CarryIn.ugt(0) ? 1 : 0;
18254 ? (LHS.zext(BitWidth + 1) + (RHS.zext(BitWidth + 1) + CarryInBit))
18255 : (LHS.zext(BitWidth + 1) - (RHS.zext(BitWidth + 1) + CarryInBit));
18257 APInt Result = ExResult.extractBits(BitWidth, 0);
18258 uint64_t CarryOut = ExResult.extractBitsAsZExtValue(1, BitWidth);
18266 case clang::X86::BI__builtin_ia32_movmskps:
18267 case clang::X86::BI__builtin_ia32_movmskpd:
18268 case clang::X86::BI__builtin_ia32_pmovmskb128:
18269 case clang::X86::BI__builtin_ia32_pmovmskb256:
18270 case clang::X86::BI__builtin_ia32_movmskps256:
18271 case clang::X86::BI__builtin_ia32_movmskpd256: {
18278 unsigned ResultLen = Info.Ctx.getTypeSize(
18282 for (
unsigned I = 0; I != SourceLen; ++I) {
18284 if (ElemQT->isIntegerType()) {
18286 }
else if (ElemQT->isRealFloatingType()) {
18291 Result.setBitVal(I, Elem.isNegative());
18296 case clang::X86::BI__builtin_ia32_bextr_u32:
18297 case clang::X86::BI__builtin_ia32_bextr_u64:
18298 case clang::X86::BI__builtin_ia32_bextri_u32:
18299 case clang::X86::BI__builtin_ia32_bextri_u64: {
18305 unsigned BitWidth = Val.getBitWidth();
18307 uint64_t Length = Idx.extractBitsAsZExtValue(8, 8);
18308 Length = Length > BitWidth ? BitWidth : Length;
18311 if (Length == 0 || Shift >= BitWidth)
18315 Result &= llvm::maskTrailingOnes<uint64_t>(Length);
18319 case clang::X86::BI__builtin_ia32_bzhi_si:
18320 case clang::X86::BI__builtin_ia32_bzhi_di: {
18326 unsigned BitWidth = Val.getBitWidth();
18327 unsigned Index = Idx.extractBitsAsZExtValue(8, 0);
18328 if (Index < BitWidth)
18329 Val.clearHighBits(BitWidth - Index);
18333 case clang::X86::BI__builtin_ia32_ktestcqi:
18334 case clang::X86::BI__builtin_ia32_ktestchi:
18335 case clang::X86::BI__builtin_ia32_ktestcsi:
18336 case clang::X86::BI__builtin_ia32_ktestcdi: {
18342 return Success((~A & B) == 0, E);
18345 case clang::X86::BI__builtin_ia32_ktestzqi:
18346 case clang::X86::BI__builtin_ia32_ktestzhi:
18347 case clang::X86::BI__builtin_ia32_ktestzsi:
18348 case clang::X86::BI__builtin_ia32_ktestzdi: {
18354 return Success((A & B) == 0, E);
18357 case clang::X86::BI__builtin_ia32_kortestcqi:
18358 case clang::X86::BI__builtin_ia32_kortestchi:
18359 case clang::X86::BI__builtin_ia32_kortestcsi:
18360 case clang::X86::BI__builtin_ia32_kortestcdi: {
18366 return Success(~(A | B) == 0, E);
18369 case clang::X86::BI__builtin_ia32_kortestzqi:
18370 case clang::X86::BI__builtin_ia32_kortestzhi:
18371 case clang::X86::BI__builtin_ia32_kortestzsi:
18372 case clang::X86::BI__builtin_ia32_kortestzdi: {
18378 return Success((A | B) == 0, E);
18381 case clang::X86::BI__builtin_ia32_kunpckhi:
18382 case clang::X86::BI__builtin_ia32_kunpckdi:
18383 case clang::X86::BI__builtin_ia32_kunpcksi: {
18391 unsigned BW = A.getBitWidth();
18392 APSInt Result(A.trunc(BW / 2).concat(B.trunc(BW / 2)), A.isUnsigned());
18396 case clang::X86::BI__builtin_ia32_lzcnt_u16:
18397 case clang::X86::BI__builtin_ia32_lzcnt_u32:
18398 case clang::X86::BI__builtin_ia32_lzcnt_u64: {
18402 return Success(Val.countLeadingZeros(), E);
18405 case clang::X86::BI__builtin_ia32_tzcnt_u16:
18406 case clang::X86::BI__builtin_ia32_tzcnt_u32:
18407 case clang::X86::BI__builtin_ia32_tzcnt_u64: {
18411 return Success(Val.countTrailingZeros(), E);
18414 case clang::X86::BI__builtin_ia32_pdep_si:
18415 case clang::X86::BI__builtin_ia32_pdep_di:
18416 case Builtin::BI__builtin_elementwise_pdep: {
18421 return Success(llvm::APIntOps::pdep(Val, Msk), E);
18424 case clang::X86::BI__builtin_ia32_pext_si:
18425 case clang::X86::BI__builtin_ia32_pext_di:
18426 case Builtin::BI__builtin_elementwise_pext: {
18431 return Success(llvm::APIntOps::pext(Val, Msk), E);
18433 case X86::BI__builtin_ia32_ptestz128:
18434 case X86::BI__builtin_ia32_ptestz256:
18435 case X86::BI__builtin_ia32_vtestzps:
18436 case X86::BI__builtin_ia32_vtestzps256:
18437 case X86::BI__builtin_ia32_vtestzpd:
18438 case X86::BI__builtin_ia32_vtestzpd256: {
18440 [](
const APInt &A,
const APInt &B) {
return (A & B) == 0; });
18442 case X86::BI__builtin_ia32_ptestc128:
18443 case X86::BI__builtin_ia32_ptestc256:
18444 case X86::BI__builtin_ia32_vtestcps:
18445 case X86::BI__builtin_ia32_vtestcps256:
18446 case X86::BI__builtin_ia32_vtestcpd:
18447 case X86::BI__builtin_ia32_vtestcpd256: {
18449 [](
const APInt &A,
const APInt &B) {
return (~A & B) == 0; });
18451 case X86::BI__builtin_ia32_ptestnzc128:
18452 case X86::BI__builtin_ia32_ptestnzc256:
18453 case X86::BI__builtin_ia32_vtestnzcps:
18454 case X86::BI__builtin_ia32_vtestnzcps256:
18455 case X86::BI__builtin_ia32_vtestnzcpd:
18456 case X86::BI__builtin_ia32_vtestnzcpd256: {
18457 return EvalTestOp([](
const APInt &A,
const APInt &B) {
18458 return ((A & B) != 0) && ((~A & B) != 0);
18461 case X86::BI__builtin_ia32_kandqi:
18462 case X86::BI__builtin_ia32_kandhi:
18463 case X86::BI__builtin_ia32_kandsi:
18464 case X86::BI__builtin_ia32_kanddi: {
18465 return HandleMaskBinOp(
18466 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS & RHS; });
18469 case X86::BI__builtin_ia32_kandnqi:
18470 case X86::BI__builtin_ia32_kandnhi:
18471 case X86::BI__builtin_ia32_kandnsi:
18472 case X86::BI__builtin_ia32_kandndi: {
18473 return HandleMaskBinOp(
18474 [](
const APSInt &LHS,
const APSInt &RHS) {
return ~LHS & RHS; });
18477 case X86::BI__builtin_ia32_korqi:
18478 case X86::BI__builtin_ia32_korhi:
18479 case X86::BI__builtin_ia32_korsi:
18480 case X86::BI__builtin_ia32_kordi: {
18481 return HandleMaskBinOp(
18482 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS | RHS; });
18485 case X86::BI__builtin_ia32_kxnorqi:
18486 case X86::BI__builtin_ia32_kxnorhi:
18487 case X86::BI__builtin_ia32_kxnorsi:
18488 case X86::BI__builtin_ia32_kxnordi: {
18489 return HandleMaskBinOp(
18490 [](
const APSInt &LHS,
const APSInt &RHS) {
return ~(LHS ^ RHS); });
18493 case X86::BI__builtin_ia32_kxorqi:
18494 case X86::BI__builtin_ia32_kxorhi:
18495 case X86::BI__builtin_ia32_kxorsi:
18496 case X86::BI__builtin_ia32_kxordi: {
18497 return HandleMaskBinOp(
18498 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS ^ RHS; });
18501 case X86::BI__builtin_ia32_knotqi:
18502 case X86::BI__builtin_ia32_knothi:
18503 case X86::BI__builtin_ia32_knotsi:
18504 case X86::BI__builtin_ia32_knotdi: {
18512 case X86::BI__builtin_ia32_kaddqi:
18513 case X86::BI__builtin_ia32_kaddhi:
18514 case X86::BI__builtin_ia32_kaddsi:
18515 case X86::BI__builtin_ia32_kadddi: {
18516 return HandleMaskBinOp(
18517 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS + RHS; });
18520 case X86::BI__builtin_ia32_kmovb:
18521 case X86::BI__builtin_ia32_kmovw:
18522 case X86::BI__builtin_ia32_kmovd:
18523 case X86::BI__builtin_ia32_kmovq: {
18530 case X86::BI__builtin_ia32_kshiftliqi:
18531 case X86::BI__builtin_ia32_kshiftlihi:
18532 case X86::BI__builtin_ia32_kshiftlisi:
18533 case X86::BI__builtin_ia32_kshiftlidi: {
18534 return HandleMaskBinOp([](
const APSInt &LHS,
const APSInt &RHS) {
18535 unsigned Amt = RHS.getZExtValue() & 0xFF;
18536 if (Amt >= LHS.getBitWidth())
18537 return APSInt(APInt::getZero(LHS.getBitWidth()), LHS.isUnsigned());
18538 return APSInt(LHS.shl(Amt), LHS.isUnsigned());
18542 case X86::BI__builtin_ia32_kshiftriqi:
18543 case X86::BI__builtin_ia32_kshiftrihi:
18544 case X86::BI__builtin_ia32_kshiftrisi:
18545 case X86::BI__builtin_ia32_kshiftridi: {
18546 return HandleMaskBinOp([](
const APSInt &LHS,
const APSInt &RHS) {
18547 unsigned Amt = RHS.getZExtValue() & 0xFF;
18548 if (Amt >= LHS.getBitWidth())
18549 return APSInt(APInt::getZero(LHS.getBitWidth()), LHS.isUnsigned());
18550 return APSInt(LHS.lshr(Amt), LHS.isUnsigned());
18554 case clang::X86::BI__builtin_ia32_vec_ext_v4hi:
18555 case clang::X86::BI__builtin_ia32_vec_ext_v16qi:
18556 case clang::X86::BI__builtin_ia32_vec_ext_v8hi:
18557 case clang::X86::BI__builtin_ia32_vec_ext_v4si:
18558 case clang::X86::BI__builtin_ia32_vec_ext_v2di:
18559 case clang::X86::BI__builtin_ia32_vec_ext_v32qi:
18560 case clang::X86::BI__builtin_ia32_vec_ext_v16hi:
18561 case clang::X86::BI__builtin_ia32_vec_ext_v8si:
18562 case clang::X86::BI__builtin_ia32_vec_ext_v4di: {
18569 unsigned Idx =
static_cast<unsigned>(IdxAPS.getZExtValue() & (N - 1));
18573 case clang::X86::BI__builtin_ia32_cvtb2mask128:
18574 case clang::X86::BI__builtin_ia32_cvtb2mask256:
18575 case clang::X86::BI__builtin_ia32_cvtb2mask512:
18576 case clang::X86::BI__builtin_ia32_cvtw2mask128:
18577 case clang::X86::BI__builtin_ia32_cvtw2mask256:
18578 case clang::X86::BI__builtin_ia32_cvtw2mask512:
18579 case clang::X86::BI__builtin_ia32_cvtd2mask128:
18580 case clang::X86::BI__builtin_ia32_cvtd2mask256:
18581 case clang::X86::BI__builtin_ia32_cvtd2mask512:
18582 case clang::X86::BI__builtin_ia32_cvtq2mask128:
18583 case clang::X86::BI__builtin_ia32_cvtq2mask256:
18584 case clang::X86::BI__builtin_ia32_cvtq2mask512: {
18591 unsigned RetWidth = Info.Ctx.getIntWidth(E->
getType());
18592 llvm::APInt Bits(RetWidth, 0);
18594 for (
unsigned ElemNum = 0; ElemNum != VectorLen; ++ElemNum) {
18596 unsigned MSB = A[A.getBitWidth() - 1];
18597 Bits.setBitVal(ElemNum, MSB);
18600 APSInt RetMask(Bits,
true);
18604 case clang::X86::BI__builtin_ia32_cmpb128_mask:
18605 case clang::X86::BI__builtin_ia32_cmpw128_mask:
18606 case clang::X86::BI__builtin_ia32_cmpd128_mask:
18607 case clang::X86::BI__builtin_ia32_cmpq128_mask:
18608 case clang::X86::BI__builtin_ia32_cmpb256_mask:
18609 case clang::X86::BI__builtin_ia32_cmpw256_mask:
18610 case clang::X86::BI__builtin_ia32_cmpd256_mask:
18611 case clang::X86::BI__builtin_ia32_cmpq256_mask:
18612 case clang::X86::BI__builtin_ia32_cmpb512_mask:
18613 case clang::X86::BI__builtin_ia32_cmpw512_mask:
18614 case clang::X86::BI__builtin_ia32_cmpd512_mask:
18615 case clang::X86::BI__builtin_ia32_cmpq512_mask:
18616 case clang::X86::BI__builtin_ia32_ucmpb128_mask:
18617 case clang::X86::BI__builtin_ia32_ucmpw128_mask:
18618 case clang::X86::BI__builtin_ia32_ucmpd128_mask:
18619 case clang::X86::BI__builtin_ia32_ucmpq128_mask:
18620 case clang::X86::BI__builtin_ia32_ucmpb256_mask:
18621 case clang::X86::BI__builtin_ia32_ucmpw256_mask:
18622 case clang::X86::BI__builtin_ia32_ucmpd256_mask:
18623 case clang::X86::BI__builtin_ia32_ucmpq256_mask:
18624 case clang::X86::BI__builtin_ia32_ucmpb512_mask:
18625 case clang::X86::BI__builtin_ia32_ucmpw512_mask:
18626 case clang::X86::BI__builtin_ia32_ucmpd512_mask:
18627 case clang::X86::BI__builtin_ia32_ucmpq512_mask: {
18631 (BuiltinOp >= clang::X86::BI__builtin_ia32_ucmpb128_mask &&
18632 BuiltinOp <= clang::X86::BI__builtin_ia32_ucmpw512_mask);
18645 unsigned RetWidth = Mask.getBitWidth();
18647 APSInt RetMask(llvm::APInt(RetWidth, 0),
true);
18649 for (
unsigned ElemNum = 0; ElemNum < VectorLen; ++ElemNum) {
18654 switch (
Opcode.getExtValue() & 0x7) {
18659 Result = IsUnsigned ? A.ult(B) : A.slt(B);
18662 Result = IsUnsigned ? A.ule(B) : A.sle(B);
18671 Result = IsUnsigned ? A.uge(B) : A.sge(B);
18674 Result = IsUnsigned ? A.ugt(B) : A.sgt(B);
18681 RetMask.setBitVal(ElemNum, Mask[ElemNum] &&
Result);
18686 case X86::BI__builtin_ia32_vpshufbitqmb128_mask:
18687 case X86::BI__builtin_ia32_vpshufbitqmb256_mask:
18688 case X86::BI__builtin_ia32_vpshufbitqmb512_mask: {
18701 unsigned NumBytesInQWord = 8;
18702 unsigned NumBitsInByte = 8;
18704 unsigned NumQWords = NumBytes / NumBytesInQWord;
18705 unsigned RetWidth = ZeroMask.getBitWidth();
18706 APSInt RetMask(llvm::APInt(RetWidth, 0),
true);
18708 for (
unsigned QWordId = 0; QWordId != NumQWords; ++QWordId) {
18709 APInt SourceQWord(64, 0);
18710 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
18714 SourceQWord.insertBits(
APInt(8, Byte & 0xFF), ByteIdx * NumBitsInByte);
18717 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
18718 unsigned SelIdx = QWordId * NumBytesInQWord + ByteIdx;
18721 if (ZeroMask[SelIdx]) {
18722 RetMask.setBitVal(SelIdx, SourceQWord[M]);
18734 const LValue &LV) {
18737 if (!LV.getLValueBase())
18742 if (!LV.getLValueDesignator().Invalid &&
18743 !LV.getLValueDesignator().isOnePastTheEnd())
18753 if (LV.getLValueDesignator().Invalid)
18759 return LV.getLValueOffset() == Size;
18769class DataRecursiveIntBinOpEvaluator {
18770 struct EvalResult {
18772 bool Failed =
false;
18774 EvalResult() =
default;
18776 void swap(EvalResult &RHS) {
18778 Failed = RHS.Failed;
18779 RHS.Failed =
false;
18785 EvalResult LHSResult;
18786 enum { AnyExprKind, BinOpKind, BinOpVisitedLHSKind }
Kind;
18789 Job(Job &&) =
default;
18791 void startSpeculativeEval(EvalInfo &Info) {
18792 SpecEvalRAII = SpeculativeEvaluationRAII(Info);
18796 SpeculativeEvaluationRAII SpecEvalRAII;
18799 SmallVector<Job, 16> Queue;
18801 IntExprEvaluator &IntEval;
18806 DataRecursiveIntBinOpEvaluator(IntExprEvaluator &IntEval,
APValue &
Result)
18807 : IntEval(IntEval), Info(IntEval.getEvalInfo()), FinalResult(
Result) { }
18813 static bool shouldEnqueue(
const BinaryOperator *E) {
18820 bool Traverse(
const BinaryOperator *E) {
18822 EvalResult PrevResult;
18823 while (!Queue.empty())
18824 process(PrevResult);
18826 if (PrevResult.Failed)
return false;
18828 FinalResult.
swap(PrevResult.Val);
18839 bool Error(
const Expr *E) {
18840 return IntEval.Error(E);
18843 return IntEval.Error(E, D);
18846 OptionalDiagnostic CCEDiag(
const Expr *E,
diag::kind D) {
18847 return Info.CCEDiag(E, D);
18851 bool VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
18852 bool &SuppressRHSDiags);
18854 bool VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
18857 void EvaluateExpr(
const Expr *E, EvalResult &
Result) {
18863 void process(EvalResult &
Result);
18865 void enqueue(
const Expr *E) {
18867 Queue.resize(Queue.size()+1);
18868 Queue.back().E = E;
18869 Queue.back().Kind = Job::AnyExprKind;
18875bool DataRecursiveIntBinOpEvaluator::
18876 VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
18877 bool &SuppressRHSDiags) {
18880 if (LHSResult.Failed)
18881 return Info.noteSideEffect();
18890 if (LHSAsBool == (E->
getOpcode() == BO_LOr)) {
18891 Success(LHSAsBool, E, LHSResult.Val);
18895 LHSResult.Failed =
true;
18899 if (!Info.noteSideEffect())
18905 SuppressRHSDiags =
true;
18914 if (LHSResult.Failed && !Info.noteFailure())
18925 assert(!LVal.
hasLValuePath() &&
"have designator for integer lvalue");
18927 uint64_t Offset64 = Offset.getQuantity();
18928 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
18930 : Offset64 + Index64);
18933bool DataRecursiveIntBinOpEvaluator::
18934 VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
18937 if (RHSResult.Failed)
18944 bool lhsResult, rhsResult;
18959 if (rhsResult == (E->
getOpcode() == BO_LOr))
18970 if (LHSResult.Failed || RHSResult.Failed)
18973 const APValue &LHSVal = LHSResult.Val;
18974 const APValue &RHSVal = RHSResult.Val;
18998 if (!LHSExpr || !RHSExpr)
19000 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
19001 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
19002 if (!LHSAddrExpr || !RHSAddrExpr)
19027void DataRecursiveIntBinOpEvaluator::process(EvalResult &
Result) {
19028 Job &job = Queue.back();
19030 switch (job.Kind) {
19031 case Job::AnyExprKind: {
19032 if (
const BinaryOperator *Bop = dyn_cast<BinaryOperator>(job.E)) {
19033 if (shouldEnqueue(Bop)) {
19034 job.Kind = Job::BinOpKind;
19035 enqueue(Bop->getLHS());
19040 EvaluateExpr(job.E,
Result);
19045 case Job::BinOpKind: {
19047 bool SuppressRHSDiags =
false;
19048 if (!VisitBinOpLHSOnly(
Result, Bop, SuppressRHSDiags)) {
19052 if (SuppressRHSDiags)
19053 job.startSpeculativeEval(Info);
19054 job.LHSResult.swap(
Result);
19055 job.Kind = Job::BinOpVisitedLHSKind;
19060 case Job::BinOpVisitedLHSKind: {
19064 Result.Failed = !VisitBinOp(job.LHSResult, RHS, Bop,
Result.Val);
19070 llvm_unreachable(
"Invalid Job::Kind!");
19074enum class CmpResult {
19083template <
class SuccessCB,
class AfterCB>
19086 SuccessCB &&
Success, AfterCB &&DoAfter) {
19091 "unsupported binary expression evaluation");
19093 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
19107 if (!LHSOK && !Info.noteFailure())
19112 return Success(CmpResult::Less, E);
19114 return Success(CmpResult::Greater, E);
19115 return Success(CmpResult::Equal, E);
19119 APFixedPoint LHSFX(Info.Ctx.getFixedPointSemantics(LHSTy));
19120 APFixedPoint RHSFX(Info.Ctx.getFixedPointSemantics(RHSTy));
19123 if (!LHSOK && !Info.noteFailure())
19128 return Success(CmpResult::Less, E);
19130 return Success(CmpResult::Greater, E);
19131 return Success(CmpResult::Equal, E);
19135 ComplexValue LHS, RHS;
19144 LHS.makeComplexFloat();
19145 LHS.FloatImag = APFloat(LHS.FloatReal.getSemantics());
19150 if (!LHSOK && !Info.noteFailure())
19156 RHS.makeComplexFloat();
19157 RHS.FloatImag = APFloat(RHS.FloatReal.getSemantics());
19161 if (LHS.isComplexFloat()) {
19162 APFloat::cmpResult CR_r =
19163 LHS.getComplexFloatReal().compare(RHS.getComplexFloatReal());
19164 APFloat::cmpResult CR_i =
19165 LHS.getComplexFloatImag().compare(RHS.getComplexFloatImag());
19166 bool IsEqual = CR_r == APFloat::cmpEqual && CR_i == APFloat::cmpEqual;
19167 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal, E);
19169 assert(IsEquality &&
"invalid complex comparison");
19170 bool IsEqual = LHS.getComplexIntReal() == RHS.getComplexIntReal() &&
19171 LHS.getComplexIntImag() == RHS.getComplexIntImag();
19172 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal, E);
19178 APFloat RHS(0.0), LHS(0.0);
19181 if (!LHSOK && !Info.noteFailure())
19188 llvm::APFloatBase::cmpResult APFloatCmpResult = LHS.compare(RHS);
19189 if (!Info.InConstantContext &&
19190 APFloatCmpResult == APFloat::cmpUnordered &&
19193 Info.FFDiag(E, diag::note_constexpr_float_arithmetic_strict);
19196 auto GetCmpRes = [&]() {
19197 switch (APFloatCmpResult) {
19198 case APFloat::cmpEqual:
19199 return CmpResult::Equal;
19200 case APFloat::cmpLessThan:
19201 return CmpResult::Less;
19202 case APFloat::cmpGreaterThan:
19203 return CmpResult::Greater;
19204 case APFloat::cmpUnordered:
19205 return CmpResult::Unordered;
19207 llvm_unreachable(
"Unrecognised APFloat::cmpResult enum");
19209 return Success(GetCmpRes(), E);
19213 LValue LHSValue, RHSValue;
19216 if (!LHSOK && !Info.noteFailure())
19227 if (Info.checkingPotentialConstantExpression() &&
19228 (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown))
19230 auto DiagComparison = [&] (
unsigned DiagID,
bool Reversed =
false) {
19231 std::string LHS = LHSValue.toString(Info.Ctx, E->
getLHS()->
getType());
19232 std::string RHS = RHSValue.toString(Info.Ctx, E->
getRHS()->
getType());
19233 Info.FFDiag(E, DiagID)
19240 return DiagComparison(
19241 diag::note_constexpr_pointer_comparison_unspecified);
19247 if ((!LHSValue.Base && !LHSValue.Offset.
isZero()) ||
19248 (!RHSValue.Base && !RHSValue.Offset.
isZero()))
19249 return DiagComparison(diag::note_constexpr_pointer_constant_comparison,
19263 return DiagComparison(diag::note_constexpr_literal_comparison);
19265 return DiagComparison(diag::note_constexpr_opaque_call_comparison,
19270 return DiagComparison(diag::note_constexpr_pointer_weak_comparison,
19274 if (LHSValue.Base && LHSValue.Offset.
isZero() &&
19276 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
19278 if (RHSValue.Base && RHSValue.Offset.
isZero() &&
19280 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
19286 return DiagComparison(
19287 diag::note_constexpr_pointer_comparison_zero_sized);
19288 if (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown)
19289 return DiagComparison(
19290 diag::note_constexpr_pointer_comparison_unspecified);
19292 return Success(CmpResult::Unequal, E);
19295 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
19296 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
19298 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
19299 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
19309 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid && IsRelational) {
19310 bool WasArrayIndex;
19313 :
getType(LHSValue.Base).getNonReferenceType(),
19314 LHSDesignator, RHSDesignator, WasArrayIndex);
19321 if (!WasArrayIndex && Mismatch < LHSDesignator.Entries.size() &&
19322 Mismatch < RHSDesignator.Entries.size()) {
19323 const FieldDecl *LF = getAsField(LHSDesignator.Entries[Mismatch]);
19324 const FieldDecl *RF = getAsField(RHSDesignator.Entries[Mismatch]);
19326 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_classes);
19328 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
19329 << getAsBaseClass(LHSDesignator.Entries[Mismatch])
19332 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
19333 << getAsBaseClass(RHSDesignator.Entries[Mismatch])
19338 diag::note_constexpr_pointer_comparison_differing_access)
19346 unsigned PtrSize = Info.Ctx.getTypeSize(LHSTy);
19349 assert(PtrSize <= 64 &&
"Unexpected pointer width");
19350 uint64_t Mask = ~0ULL >> (64 - PtrSize);
19351 CompareLHS &= Mask;
19352 CompareRHS &= Mask;
19357 if (!LHSValue.Base.
isNull() && IsRelational) {
19361 CharUnits Size = Info.Ctx.getTypeSizeInChars(BaseTy);
19362 uint64_t OffsetLimit = Size.getQuantity();
19363 if (CompareLHS > OffsetLimit || CompareRHS > OffsetLimit)
19367 if (CompareLHS < CompareRHS)
19368 return Success(CmpResult::Less, E);
19369 if (CompareLHS > CompareRHS)
19370 return Success(CmpResult::Greater, E);
19371 return Success(CmpResult::Equal, E);
19375 assert(IsEquality &&
"unexpected member pointer operation");
19378 MemberPtr LHSValue, RHSValue;
19381 if (!LHSOK && !Info.noteFailure())
19389 if (LHSValue.getDecl() && LHSValue.getDecl()->isWeak()) {
19390 Info.FFDiag(E, diag::note_constexpr_mem_pointer_weak_comparison)
19391 << LHSValue.getDecl();
19394 if (RHSValue.getDecl() && RHSValue.getDecl()->isWeak()) {
19395 Info.FFDiag(E, diag::note_constexpr_mem_pointer_weak_comparison)
19396 << RHSValue.getDecl();
19403 if (!LHSValue.getDecl() || !RHSValue.getDecl()) {
19404 bool Equal = !LHSValue.getDecl() && !RHSValue.getDecl();
19405 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal, E);
19410 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(LHSValue.getDecl()))
19411 if (MD->isVirtual())
19412 Info.CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
19413 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(RHSValue.getDecl()))
19414 if (MD->isVirtual())
19415 Info.CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
19421 bool Equal = LHSValue == RHSValue;
19422 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal, E);
19427 assert(RHSTy->
isNullPtrType() &&
"missing pointer conversion");
19435 return Success(CmpResult::Equal, E);
19441bool RecordExprEvaluator::VisitBinCmp(
const BinaryOperator *E) {
19445 auto OnSuccess = [&](CmpResult CR,
const BinaryOperator *E) {
19448 case CmpResult::Unequal:
19449 llvm_unreachable(
"should never produce Unequal for three-way comparison");
19450 case CmpResult::Less:
19451 CCR = ComparisonCategoryResult::Less;
19453 case CmpResult::Equal:
19454 CCR = ComparisonCategoryResult::Equal;
19456 case CmpResult::Greater:
19457 CCR = ComparisonCategoryResult::Greater;
19459 case CmpResult::Unordered:
19460 CCR = ComparisonCategoryResult::Unordered;
19465 const ComparisonCategoryInfo &CmpInfo =
19466 Info.Ctx.CompCategories.getInfoForType(E->
getType());
19474 ConstantExprKind::Normal);
19477 return ExprEvaluatorBaseTy::VisitBinCmp(E);
19481bool RecordExprEvaluator::VisitCXXParenListInitExpr(
19482 const CXXParenListInitExpr *E) {
19483 return VisitCXXParenListOrInitListExpr(E, E->
getInitExprs());
19486bool IntExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
19491 if (!Info.noteFailure())
19495 if (DataRecursiveIntBinOpEvaluator::shouldEnqueue(E))
19496 return DataRecursiveIntBinOpEvaluator(*
this,
Result).Traverse(E);
19500 "DataRecursiveIntBinOpEvaluator should have handled integral types");
19505 auto OnSuccess = [&](CmpResult CR,
const BinaryOperator *E) {
19506 assert((CR != CmpResult::Unequal || E->
isEqualityOp()) &&
19507 "should only produce Unequal for equality comparisons");
19508 bool IsEqual = CR == CmpResult::Equal,
19509 IsLess = CR == CmpResult::Less,
19510 IsGreater = CR == CmpResult::Greater;
19514 llvm_unreachable(
"unsupported binary operator");
19517 return Success(IsEqual == (Op == BO_EQ), E);
19521 return Success(IsGreater, E);
19523 return Success(IsEqual || IsLess, E);
19525 return Success(IsEqual || IsGreater, E);
19529 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
19538 LValue LHSValue, RHSValue;
19541 if (!LHSOK && !Info.noteFailure())
19550 if (Info.checkingPotentialConstantExpression() &&
19551 (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown))
19554 const Expr *LHSExpr = LHSValue.Base.
dyn_cast<
const Expr *>();
19555 const Expr *RHSExpr = RHSValue.Base.
dyn_cast<
const Expr *>();
19557 auto DiagArith = [&](
unsigned DiagID) {
19558 std::string LHS = LHSValue.toString(Info.Ctx, E->
getLHS()->
getType());
19559 std::string RHS = RHSValue.toString(Info.Ctx, E->
getRHS()->
getType());
19560 Info.FFDiag(E, DiagID) << LHS << RHS;
19561 if (LHSExpr && LHSExpr == RHSExpr)
19563 diag::note_constexpr_repeated_literal_eval)
19568 if (!LHSExpr || !RHSExpr)
19569 return DiagArith(diag::note_constexpr_pointer_arith_unspecified);
19572 return DiagArith(diag::note_constexpr_literal_arith);
19574 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
19575 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
19576 if (!LHSAddrExpr || !RHSAddrExpr)
19584 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
19585 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
19587 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
19588 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
19594 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid &&
19597 Info.CCEDiag(E, diag::note_constexpr_pointer_subtraction_not_same_array);
19602 CharUnits ElementSize;
19609 if (ElementSize.
isZero()) {
19610 Info.FFDiag(E, diag::note_constexpr_pointer_subtraction_zero_size)
19627 APSInt TrueResult = (LHS - RHS) / ElemSize;
19630 if (
Result.extend(65) != TrueResult &&
19636 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
19641bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr(
19642 const UnaryExprOrTypeTraitExpr *E) {
19644 case UETT_PreferredAlignOf:
19645 case UETT_AlignOf: {
19654 case UETT_PtrAuthTypeDiscriminator: {
19660 case UETT_VecStep: {
19664 unsigned n = Ty->
castAs<VectorType>()->getNumElements();
19676 case UETT_DataSizeOf:
19677 case UETT_SizeOf: {
19681 if (
const ReferenceType *Ref = SrcTy->
getAs<ReferenceType>())
19692 case UETT_OpenMPRequiredSimdAlign:
19695 Info.Ctx.toCharUnitsFromBits(
19699 case UETT_VectorElements: {
19703 if (
const auto *VT = Ty->
getAs<VectorType>())
19707 if (Info.InConstantContext)
19708 Info.CCEDiag(E, diag::note_constexpr_non_const_vectorelements)
19713 case UETT_CountOf: {
19719 if (
const auto *CAT =
19729 const auto *VAT = Info.Ctx.getAsVariableArrayType(Ty);
19731 if (VAT->getElementType()->isArrayType()) {
19734 if (!VAT->getSizeExpr()) {
19739 std::optional<APSInt> Res =
19740 VAT->getSizeExpr()->getIntegerConstantExpr(Info.Ctx);
19745 static_cast<unsigned>(Info.Ctx.getTypeSize(Info.Ctx.getSizeType())),
19746 Res->getZExtValue()};
19758 llvm_unreachable(
"unknown expr/type trait");
19761bool IntExprEvaluator::VisitOffsetOfExpr(
const OffsetOfExpr *OOE) {
19762 Info.Ctx.recordOffsetOfEvaluation(OOE);
19768 for (
unsigned i = 0; i != n; ++i) {
19776 const ArrayType *AT = Info.Ctx.getAsArrayType(CurrentType);
19780 CharUnits ElementSize = Info.Ctx.getTypeSizeInChars(CurrentType);
19783 if (IdxResult.isNegative() || IdxResult.getActiveBits() > 63)
19785 int64_t IdxVal = IdxResult.getExtValue();
19788 ElemSize > std::numeric_limits<int64_t>::max() / IdxVal)
19789 return Error(OOE, diag::note_constexpr_offsetof_overflow);
19790 int64_t Offset = IdxVal * ElemSize;
19791 if (
Result.getQuantity() > std::numeric_limits<int64_t>::max() - Offset)
19792 return Error(OOE, diag::note_constexpr_offsetof_overflow);
19798 FieldDecl *MemberDecl = ON.
getField();
19803 const ASTRecordLayout &RL = Info.Ctx.getASTRecordLayout(RD);
19805 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
19812 llvm_unreachable(
"dependent __builtin_offsetof");
19815 CXXBaseSpecifier *BaseSpec = ON.
getBase();
19824 const ASTRecordLayout &RL = Info.Ctx.getASTRecordLayout(RD);
19827 CurrentType = BaseSpec->
getType();
19841bool IntExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
19861 if (Info.checkingForUndefinedBehavior())
19862 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
19863 diag::warn_integer_constant_overflow)
19891bool IntExprEvaluator::VisitCastExpr(
const CastExpr *E) {
19893 QualType DestType = E->
getType();
19894 QualType SrcType = SubExpr->
getType();
19897 case CK_BaseToDerived:
19898 case CK_DerivedToBase:
19899 case CK_UncheckedDerivedToBase:
19902 case CK_ArrayToPointerDecay:
19903 case CK_FunctionToPointerDecay:
19904 case CK_NullToPointer:
19905 case CK_NullToMemberPointer:
19906 case CK_BaseToDerivedMemberPointer:
19907 case CK_DerivedToBaseMemberPointer:
19908 case CK_ReinterpretMemberPointer:
19909 case CK_ConstructorConversion:
19910 case CK_IntegralToPointer:
19912 case CK_VectorSplat:
19913 case CK_IntegralToFloating:
19914 case CK_FloatingCast:
19915 case CK_CPointerToObjCPointerCast:
19916 case CK_BlockPointerToObjCPointerCast:
19917 case CK_AnyPointerToBlockPointerCast:
19918 case CK_ObjCObjectLValueCast:
19919 case CK_FloatingRealToComplex:
19920 case CK_FloatingComplexToReal:
19921 case CK_FloatingComplexCast:
19922 case CK_FloatingComplexToIntegralComplex:
19923 case CK_IntegralRealToComplex:
19924 case CK_IntegralComplexCast:
19925 case CK_IntegralComplexToFloatingComplex:
19926 case CK_BuiltinFnToFnPtr:
19927 case CK_ZeroToOCLOpaqueType:
19928 case CK_NonAtomicToAtomic:
19929 case CK_AddressSpaceConversion:
19930 case CK_IntToOCLSampler:
19931 case CK_FloatingToFixedPoint:
19932 case CK_FixedPointToFloating:
19933 case CK_FixedPointCast:
19934 case CK_IntegralToFixedPoint:
19935 case CK_MatrixCast:
19936 case CK_HLSLAggregateSplatCast:
19937 llvm_unreachable(
"invalid cast kind for integral value");
19941 case CK_LValueBitCast:
19942 case CK_ARCProduceObject:
19943 case CK_ARCConsumeObject:
19944 case CK_ARCReclaimReturnedObject:
19945 case CK_ARCExtendBlockObject:
19946 case CK_CopyAndAutoreleaseBlockObject:
19949 case CK_UserDefinedConversion:
19950 case CK_LValueToRValue:
19951 case CK_AtomicToNonAtomic:
19953 case CK_LValueToRValueBitCast:
19954 case CK_HLSLArrayRValue:
19955 return ExprEvaluatorBaseTy::VisitCastExpr(E);
19957 case CK_MemberPointerToBoolean:
19958 case CK_PointerToBoolean:
19959 case CK_IntegralToBoolean:
19960 case CK_FloatingToBoolean:
19961 case CK_BooleanToSignedIntegral:
19962 case CK_FloatingComplexToBoolean:
19963 case CK_IntegralComplexToBoolean: {
19968 if (BoolResult && E->
getCastKind() == CK_BooleanToSignedIntegral)
19970 return Success(IntResult, E);
19973 case CK_FixedPointToIntegral: {
19974 APFixedPoint Src(Info.Ctx.getFixedPointSemantics(SrcType));
19978 llvm::APSInt
Result = Src.convertToInt(
19979 Info.Ctx.getIntWidth(DestType),
19986 case CK_FixedPointToBoolean: {
19989 if (!
Evaluate(Val, Info, SubExpr))
19994 case CK_IntegralCast: {
19995 if (!Visit(SubExpr))
20005 if (
Result.isAddrLabelDiff()) {
20006 unsigned DestBits = Info.Ctx.getTypeSize(DestType);
20007 return DestBits >= 32 && DestBits <= Info.Ctx.getTypeSize(SrcType);
20010 return Info.Ctx.getTypeSize(DestType) == Info.Ctx.getTypeSize(SrcType);
20013 if (Info.Ctx.getLangOpts().CPlusPlus && DestType->
isEnumeralType()) {
20025 if (!ED->isFixed()) {
20029 ED->getValueRange(
Max,
Min);
20032 if (ED->getNumNegativeBits() &&
20033 (
Max.slt(
Result.getInt().getSExtValue()) ||
20034 Min.sgt(
Result.getInt().getSExtValue())))
20035 Info.CCEDiag(E, diag::note_constexpr_unscoped_enum_out_of_range)
20036 << llvm::toString(
Result.getInt(), 10) <<
Min.getSExtValue()
20037 <<
Max.getSExtValue() << ED;
20038 else if (!ED->getNumNegativeBits() &&
20039 Max.ult(
Result.getInt().getZExtValue()))
20040 Info.CCEDiag(E, diag::note_constexpr_unscoped_enum_out_of_range)
20041 << llvm::toString(
Result.getInt(), 10) <<
Min.getZExtValue()
20042 <<
Max.getZExtValue() << ED;
20050 case CK_PointerToIntegral: {
20051 CCEDiag(E, diag::note_constexpr_invalid_cast)
20052 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
20059 if (LV.getLValueBase()) {
20064 if (Info.Ctx.getTypeSize(DestType) != Info.Ctx.getTypeSize(SrcType))
20067 LV.Designator.setInvalid();
20075 if (!
V.toIntegralConstant(AsInt, SrcType, Info.Ctx))
20076 llvm_unreachable(
"Can't cast this!");
20081 case CK_IntegralComplexToReal: {
20085 return Success(
C.getComplexIntReal(), E);
20088 case CK_FloatingToIntegral: {
20098 case CK_HLSLVectorTruncation: {
20104 case CK_HLSLMatrixTruncation: {
20110 case CK_HLSLElementwiseCast: {
20123 return Success(ResultVal, E);
20127 llvm_unreachable(
"unknown cast resulting in integral value");
20130bool IntExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
20135 if (!LV.isComplexInt())
20137 return Success(LV.getComplexIntReal(), E);
20143bool IntExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
20148 if (!LV.isComplexInt())
20150 return Success(LV.getComplexIntImag(), E);
20157bool IntExprEvaluator::VisitSizeOfPackExpr(
const SizeOfPackExpr *E) {
20161bool IntExprEvaluator::VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E) {
20165bool IntExprEvaluator::VisitConceptSpecializationExpr(
20166 const ConceptSpecializationExpr *E) {
20170bool IntExprEvaluator::VisitRequiresExpr(
const RequiresExpr *E) {
20174bool FixedPointExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
20184 if (!
Result.isFixedPoint())
20187 APFixedPoint Negated =
Result.getFixedPoint().negate(&Overflowed);
20201bool FixedPointExprEvaluator::VisitCastExpr(
const CastExpr *E) {
20203 QualType DestType = E->
getType();
20205 "Expected destination type to be a fixed point type");
20206 auto DestFXSema = Info.Ctx.getFixedPointSemantics(DestType);
20209 case CK_FixedPointCast: {
20210 APFixedPoint Src(Info.Ctx.getFixedPointSemantics(SubExpr->
getType()));
20214 APFixedPoint
Result = Src.convert(DestFXSema, &Overflowed);
20216 if (Info.checkingForUndefinedBehavior())
20217 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
20218 diag::warn_fixedpoint_constant_overflow)
20225 case CK_IntegralToFixedPoint: {
20231 APFixedPoint IntResult = APFixedPoint::getFromIntValue(
20232 Src, Info.Ctx.getFixedPointSemantics(DestType), &Overflowed);
20235 if (Info.checkingForUndefinedBehavior())
20236 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
20237 diag::warn_fixedpoint_constant_overflow)
20238 << IntResult.toString() << E->
getType();
20243 return Success(IntResult, E);
20245 case CK_FloatingToFixedPoint: {
20251 APFixedPoint
Result = APFixedPoint::getFromFloatValue(
20252 Src, Info.Ctx.getFixedPointSemantics(DestType), &Overflowed);
20255 if (Info.checkingForUndefinedBehavior())
20256 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
20257 diag::warn_fixedpoint_constant_overflow)
20266 case CK_LValueToRValue:
20267 return ExprEvaluatorBaseTy::VisitCastExpr(E);
20273bool FixedPointExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
20275 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
20277 const Expr *LHS = E->
getLHS();
20278 const Expr *RHS = E->
getRHS();
20280 Info.Ctx.getFixedPointSemantics(E->
getType());
20282 APFixedPoint LHSFX(Info.Ctx.getFixedPointSemantics(LHS->
getType()));
20285 APFixedPoint RHSFX(Info.Ctx.getFixedPointSemantics(RHS->
getType()));
20289 bool OpOverflow =
false, ConversionOverflow =
false;
20290 APFixedPoint
Result(LHSFX.getSemantics());
20293 Result = LHSFX.add(RHSFX, &OpOverflow)
20294 .convert(ResultFXSema, &ConversionOverflow);
20298 Result = LHSFX.sub(RHSFX, &OpOverflow)
20299 .convert(ResultFXSema, &ConversionOverflow);
20303 Result = LHSFX.mul(RHSFX, &OpOverflow)
20304 .convert(ResultFXSema, &ConversionOverflow);
20308 if (RHSFX.getValue() == 0) {
20309 Info.FFDiag(E, diag::note_expr_divide_by_zero);
20312 Result = LHSFX.div(RHSFX, &OpOverflow)
20313 .convert(ResultFXSema, &ConversionOverflow);
20319 llvm::APSInt RHSVal = RHSFX.getValue();
20322 LHSSema.getWidth() - (unsigned)LHSSema.hasUnsignedPadding();
20323 unsigned Amt = RHSVal.getLimitedValue(ShiftBW - 1);
20327 if (RHSVal.isNegative())
20328 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHSVal;
20329 else if (Amt != RHSVal)
20330 Info.CCEDiag(E, diag::note_constexpr_large_shift)
20331 << RHSVal << E->
getType() << ShiftBW;
20334 Result = LHSFX.shl(Amt, &OpOverflow);
20336 Result = LHSFX.shr(Amt, &OpOverflow);
20342 if (OpOverflow || ConversionOverflow) {
20343 if (Info.checkingForUndefinedBehavior())
20344 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
20345 diag::warn_fixedpoint_constant_overflow)
20358class FloatExprEvaluator
20359 :
public ExprEvaluatorBase<FloatExprEvaluator> {
20362 FloatExprEvaluator(EvalInfo &info, APFloat &result)
20363 : ExprEvaluatorBaseTy(info),
Result(result) {}
20370 bool ZeroInitialization(
const Expr *E) {
20371 Result = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(E->
getType()));
20375 bool VisitCallExpr(
const CallExpr *E);
20377 bool VisitUnaryOperator(
const UnaryOperator *E);
20378 bool VisitBinaryOperator(
const BinaryOperator *E);
20379 bool VisitFloatingLiteral(
const FloatingLiteral *E);
20380 bool VisitCastExpr(
const CastExpr *E);
20382 bool VisitUnaryReal(
const UnaryOperator *E);
20383 bool VisitUnaryImag(
const UnaryOperator *E);
20392 return FloatExprEvaluator(Info,
Result).Visit(E);
20399 llvm::APFloat &
Result) {
20404 const llvm::fltSemantics &Sem = Context.getFloatTypeSemantics(ResultTy);
20410 fill = llvm::APInt(32, 0);
20411 else if (S->
getString().getAsInteger(0, fill))
20414 if (Context.getTargetInfo().isNan2008()) {
20416 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
20418 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
20426 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
20428 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
20434bool FloatExprEvaluator::VisitCallExpr(
const CallExpr *E) {
20435 if (!IsConstantEvaluatedBuiltinCall(E))
20436 return ExprEvaluatorBaseTy::VisitCallExpr(E);
20440 switch (BuiltinOp) {
20444 case Builtin::BI__builtin_huge_val:
20445 case Builtin::BI__builtin_huge_valf:
20446 case Builtin::BI__builtin_huge_vall:
20447 case Builtin::BI__builtin_huge_valf16:
20448 case Builtin::BI__builtin_huge_valf128:
20449 case Builtin::BI__builtin_inf:
20450 case Builtin::BI__builtin_inff:
20451 case Builtin::BI__builtin_infl:
20452 case Builtin::BI__builtin_inff16:
20453 case Builtin::BI__builtin_inff128: {
20454 const llvm::fltSemantics &Sem =
20455 Info.Ctx.getFloatTypeSemantics(E->
getType());
20456 Result = llvm::APFloat::getInf(Sem);
20460 case Builtin::BI__builtin_nans:
20461 case Builtin::BI__builtin_nansf:
20462 case Builtin::BI__builtin_nansl:
20463 case Builtin::BI__builtin_nansf16:
20464 case Builtin::BI__builtin_nansf128:
20470 case Builtin::BI__builtin_nan:
20471 case Builtin::BI__builtin_nanf:
20472 case Builtin::BI__builtin_nanl:
20473 case Builtin::BI__builtin_nanf16:
20474 case Builtin::BI__builtin_nanf128:
20482 case Builtin::BI__builtin_elementwise_abs:
20483 case Builtin::BI__builtin_fabs:
20484 case Builtin::BI__builtin_fabsf:
20485 case Builtin::BI__builtin_fabsl:
20486 case Builtin::BI__builtin_fabsf128:
20495 if (
Result.isNegative())
20499 case Builtin::BI__arithmetic_fence:
20506 case Builtin::BI__builtin_copysign:
20507 case Builtin::BI__builtin_copysignf:
20508 case Builtin::BI__builtin_copysignl:
20509 case Builtin::BI__builtin_copysignf128: {
20518 case Builtin::BI__builtin_fmax:
20519 case Builtin::BI__builtin_fmaxf:
20520 case Builtin::BI__builtin_fmaxl:
20521 case Builtin::BI__builtin_fmaxf16:
20522 case Builtin::BI__builtin_fmaxf128: {
20531 case Builtin::BI__builtin_fmin:
20532 case Builtin::BI__builtin_fminf:
20533 case Builtin::BI__builtin_fminl:
20534 case Builtin::BI__builtin_fminf16:
20535 case Builtin::BI__builtin_fminf128: {
20544 case Builtin::BI__builtin_fmaximum_num:
20545 case Builtin::BI__builtin_fmaximum_numf:
20546 case Builtin::BI__builtin_fmaximum_numl:
20547 case Builtin::BI__builtin_fmaximum_numf16:
20548 case Builtin::BI__builtin_fmaximum_numf128: {
20557 case Builtin::BI__builtin_fminimum_num:
20558 case Builtin::BI__builtin_fminimum_numf:
20559 case Builtin::BI__builtin_fminimum_numl:
20560 case Builtin::BI__builtin_fminimum_numf16:
20561 case Builtin::BI__builtin_fminimum_numf128: {
20570 case Builtin::BI__builtin_elementwise_fma: {
20575 APFloat SourceY(0.), SourceZ(0.);
20581 (void)
Result.fusedMultiplyAdd(SourceY, SourceZ, RM);
20585 case clang::X86::BI__builtin_ia32_vec_ext_v4sf: {
20592 unsigned Idx =
static_cast<unsigned>(IdxAPS.getZExtValue() & (N - 1));
20598bool FloatExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
20610bool FloatExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
20620 const llvm::fltSemantics &Sem = Info.Ctx.getFloatTypeSemantics(E->
getType());
20621 Result = llvm::APFloat::getZero(Sem);
20625bool FloatExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
20627 default:
return Error(E);
20641bool FloatExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
20643 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
20647 if (!LHSOK && !Info.noteFailure())
20653bool FloatExprEvaluator::VisitFloatingLiteral(
const FloatingLiteral *E) {
20658bool FloatExprEvaluator::VisitCastExpr(
const CastExpr *E) {
20663 return ExprEvaluatorBaseTy::VisitCastExpr(E);
20665 case CK_HLSLAggregateSplatCast:
20666 llvm_unreachable(
"invalid cast kind for floating value");
20668 case CK_IntegralToFloating: {
20671 Info.Ctx.getLangOpts());
20677 case CK_FixedPointToFloating: {
20678 APFixedPoint FixResult(Info.Ctx.getFixedPointSemantics(SubExpr->
getType()));
20682 FixResult.convertToFloat(Info.Ctx.getFloatTypeSemantics(E->
getType()));
20686 case CK_FloatingCast: {
20687 if (!Visit(SubExpr))
20693 case CK_FloatingComplexToReal: {
20697 Result =
V.getComplexFloatReal();
20700 case CK_HLSLVectorTruncation: {
20706 case CK_HLSLMatrixTruncation: {
20712 case CK_HLSLElementwiseCast: {
20727 return Success(ResultVal, E);
20737class ComplexExprEvaluator
20738 :
public ExprEvaluatorBase<ComplexExprEvaluator> {
20742 ComplexExprEvaluator(EvalInfo &info, ComplexValue &
Result)
20750 bool ZeroInitialization(
const Expr *E);
20756 bool VisitImaginaryLiteral(
const ImaginaryLiteral *E);
20757 bool VisitCastExpr(
const CastExpr *E);
20758 bool VisitBinaryOperator(
const BinaryOperator *E);
20759 bool VisitUnaryOperator(
const UnaryOperator *E);
20760 bool VisitInitListExpr(
const InitListExpr *E);
20761 bool VisitCallExpr(
const CallExpr *E);
20769 return ComplexExprEvaluator(Info,
Result).Visit(E);
20772bool ComplexExprEvaluator::ZeroInitialization(
const Expr *E) {
20773 QualType ElemTy = E->
getType()->
castAs<ComplexType>()->getElementType();
20775 Result.makeComplexFloat();
20776 APFloat Zero = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(ElemTy));
20780 Result.makeComplexInt();
20781 APSInt Zero = Info.Ctx.MakeIntValue(0, ElemTy);
20788bool ComplexExprEvaluator::VisitImaginaryLiteral(
const ImaginaryLiteral *E) {
20792 Result.makeComplexFloat();
20801 "Unexpected imaginary literal.");
20803 Result.makeComplexInt();
20808 Result.IntReal =
APSInt(Imag.getBitWidth(), !Imag.isSigned());
20813bool ComplexExprEvaluator::VisitCastExpr(
const CastExpr *E) {
20817 case CK_BaseToDerived:
20818 case CK_DerivedToBase:
20819 case CK_UncheckedDerivedToBase:
20822 case CK_ArrayToPointerDecay:
20823 case CK_FunctionToPointerDecay:
20824 case CK_NullToPointer:
20825 case CK_NullToMemberPointer:
20826 case CK_BaseToDerivedMemberPointer:
20827 case CK_DerivedToBaseMemberPointer:
20828 case CK_MemberPointerToBoolean:
20829 case CK_ReinterpretMemberPointer:
20830 case CK_ConstructorConversion:
20831 case CK_IntegralToPointer:
20832 case CK_PointerToIntegral:
20833 case CK_PointerToBoolean:
20835 case CK_VectorSplat:
20836 case CK_IntegralCast:
20837 case CK_BooleanToSignedIntegral:
20838 case CK_IntegralToBoolean:
20839 case CK_IntegralToFloating:
20840 case CK_FloatingToIntegral:
20841 case CK_FloatingToBoolean:
20842 case CK_FloatingCast:
20843 case CK_CPointerToObjCPointerCast:
20844 case CK_BlockPointerToObjCPointerCast:
20845 case CK_AnyPointerToBlockPointerCast:
20846 case CK_ObjCObjectLValueCast:
20847 case CK_FloatingComplexToReal:
20848 case CK_FloatingComplexToBoolean:
20849 case CK_IntegralComplexToReal:
20850 case CK_IntegralComplexToBoolean:
20851 case CK_ARCProduceObject:
20852 case CK_ARCConsumeObject:
20853 case CK_ARCReclaimReturnedObject:
20854 case CK_ARCExtendBlockObject:
20855 case CK_CopyAndAutoreleaseBlockObject:
20856 case CK_BuiltinFnToFnPtr:
20857 case CK_ZeroToOCLOpaqueType:
20858 case CK_NonAtomicToAtomic:
20859 case CK_AddressSpaceConversion:
20860 case CK_IntToOCLSampler:
20861 case CK_FloatingToFixedPoint:
20862 case CK_FixedPointToFloating:
20863 case CK_FixedPointCast:
20864 case CK_FixedPointToBoolean:
20865 case CK_FixedPointToIntegral:
20866 case CK_IntegralToFixedPoint:
20867 case CK_MatrixCast:
20868 case CK_HLSLVectorTruncation:
20869 case CK_HLSLMatrixTruncation:
20870 case CK_HLSLElementwiseCast:
20871 case CK_HLSLAggregateSplatCast:
20872 llvm_unreachable(
"invalid cast kind for complex value");
20874 case CK_LValueToRValue:
20875 case CK_AtomicToNonAtomic:
20877 case CK_LValueToRValueBitCast:
20878 case CK_HLSLArrayRValue:
20879 return ExprEvaluatorBaseTy::VisitCastExpr(E);
20882 case CK_LValueBitCast:
20883 case CK_UserDefinedConversion:
20886 case CK_FloatingRealToComplex: {
20891 Result.makeComplexFloat();
20896 case CK_FloatingComplexCast: {
20900 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
20908 case CK_FloatingComplexToIntegralComplex: {
20912 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
20915 Result.makeComplexInt();
20922 case CK_IntegralRealToComplex: {
20927 Result.makeComplexInt();
20928 Result.IntImag =
APSInt(Real.getBitWidth(), !Real.isSigned());
20932 case CK_IntegralComplexCast: {
20936 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
20945 case CK_IntegralComplexToFloatingComplex: {
20950 Info.Ctx.getLangOpts());
20951 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
20954 Result.makeComplexFloat();
20956 To,
Result.FloatReal) &&
20962 llvm_unreachable(
"unknown cast resulting in complex value");
20968 0x00, 0x01, 0x8d, 0xf6, 0xcb, 0x52, 0x7b, 0xd1, 0xe8, 0x4f, 0x29, 0xc0,
20969 0xb0, 0xe1, 0xe5, 0xc7, 0x74, 0xb4, 0xaa, 0x4b, 0x99, 0x2b, 0x60, 0x5f,
20970 0x58, 0x3f, 0xfd, 0xcc, 0xff, 0x40, 0xee, 0xb2, 0x3a, 0x6e, 0x5a, 0xf1,
20971 0x55, 0x4d, 0xa8, 0xc9, 0xc1, 0x0a, 0x98, 0x15, 0x30, 0x44, 0xa2, 0xc2,
20972 0x2c, 0x45, 0x92, 0x6c, 0xf3, 0x39, 0x66, 0x42, 0xf2, 0x35, 0x20, 0x6f,
20973 0x77, 0xbb, 0x59, 0x19, 0x1d, 0xfe, 0x37, 0x67, 0x2d, 0x31, 0xf5, 0x69,
20974 0xa7, 0x64, 0xab, 0x13, 0x54, 0x25, 0xe9, 0x09, 0xed, 0x5c, 0x05, 0xca,
20975 0x4c, 0x24, 0x87, 0xbf, 0x18, 0x3e, 0x22, 0xf0, 0x51, 0xec, 0x61, 0x17,
20976 0x16, 0x5e, 0xaf, 0xd3, 0x49, 0xa6, 0x36, 0x43, 0xf4, 0x47, 0x91, 0xdf,
20977 0x33, 0x93, 0x21, 0x3b, 0x79, 0xb7, 0x97, 0x85, 0x10, 0xb5, 0xba, 0x3c,
20978 0xb6, 0x70, 0xd0, 0x06, 0xa1, 0xfa, 0x81, 0x82, 0x83, 0x7e, 0x7f, 0x80,
20979 0x96, 0x73, 0xbe, 0x56, 0x9b, 0x9e, 0x95, 0xd9, 0xf7, 0x02, 0xb9, 0xa4,
20980 0xde, 0x6a, 0x32, 0x6d, 0xd8, 0x8a, 0x84, 0x72, 0x2a, 0x14, 0x9f, 0x88,
20981 0xf9, 0xdc, 0x89, 0x9a, 0xfb, 0x7c, 0x2e, 0xc3, 0x8f, 0xb8, 0x65, 0x48,
20982 0x26, 0xc8, 0x12, 0x4a, 0xce, 0xe7, 0xd2, 0x62, 0x0c, 0xe0, 0x1f, 0xef,
20983 0x11, 0x75, 0x78, 0x71, 0xa5, 0x8e, 0x76, 0x3d, 0xbd, 0xbc, 0x86, 0x57,
20984 0x0b, 0x28, 0x2f, 0xa3, 0xda, 0xd4, 0xe4, 0x0f, 0xa9, 0x27, 0x53, 0x04,
20985 0x1b, 0xfc, 0xac, 0xe6, 0x7a, 0x07, 0xae, 0x63, 0xc5, 0xdb, 0xe2, 0xea,
20986 0x94, 0x8b, 0xc4, 0xd5, 0x9d, 0xf8, 0x90, 0x6b, 0xb1, 0x0d, 0xd6, 0xeb,
20987 0xc6, 0x0e, 0xcf, 0xad, 0x08, 0x4e, 0xd7, 0xe3, 0x5d, 0x50, 0x1e, 0xb3,
20988 0x5b, 0x23, 0x38, 0x34, 0x68, 0x46, 0x03, 0x8c, 0xdd, 0x9c, 0x7d, 0xa0,
20989 0xcd, 0x1a, 0x41, 0x1c};
20991 return GFInv[Byte];
20996 unsigned NumBitsInByte = 8;
20999 for (
uint32_t BitIdx = 0; BitIdx != NumBitsInByte; ++BitIdx) {
21001 AQword.lshr((7 -
static_cast<int32_t>(BitIdx)) * NumBitsInByte)
21008 Product = AByte & XByte;
21013 for (
unsigned PBitIdx = 0; PBitIdx != NumBitsInByte; ++PBitIdx) {
21014 Parity = Parity ^ ((Product >> PBitIdx) & 0x1);
21017 uint8_t Temp = Imm[BitIdx] ? 1 : 0;
21018 RetByte |= (Temp ^ Parity) << BitIdx;
21028 unsigned NumBitsInByte = 8;
21029 for (
unsigned BitIdx = 0; BitIdx != NumBitsInByte; ++BitIdx) {
21030 if ((BByte >> BitIdx) & 0x1) {
21031 TWord = TWord ^ (AByte << BitIdx);
21039 for (
int32_t BitIdx = 14; BitIdx > 7; --BitIdx) {
21040 if ((TWord >> BitIdx) & 0x1) {
21041 TWord = TWord ^ (0x11B << (BitIdx - 8));
21044 return (TWord & 0xFF);
21048 APFloat &ResR, APFloat &ResI) {
21054 APFloat AC = A *
C;
21055 APFloat BD = B * D;
21056 APFloat AD = A * D;
21057 APFloat BC = B *
C;
21060 if (ResR.isNaN() && ResI.isNaN()) {
21061 bool Recalc =
false;
21062 if (A.isInfinity() || B.isInfinity()) {
21063 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
21065 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
21068 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
21070 D = APFloat::copySign(APFloat(D.getSemantics()), D);
21073 if (
C.isInfinity() || D.isInfinity()) {
21074 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
21076 D = APFloat::copySign(APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0),
21079 A = APFloat::copySign(APFloat(A.getSemantics()), A);
21081 B = APFloat::copySign(APFloat(B.getSemantics()), B);
21084 if (!Recalc && (AC.isInfinity() || BD.isInfinity() || AD.isInfinity() ||
21085 BC.isInfinity())) {
21087 A = APFloat::copySign(APFloat(A.getSemantics()), A);
21089 B = APFloat::copySign(APFloat(B.getSemantics()), B);
21091 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
21093 D = APFloat::copySign(APFloat(D.getSemantics()), D);
21097 ResR = APFloat::getInf(A.getSemantics()) * (A *
C - B * D);
21098 ResI = APFloat::getInf(A.getSemantics()) * (A * D + B *
C);
21104 APFloat &ResR, APFloat &ResI) {
21111 APFloat MaxCD = maxnum(
abs(
C),
abs(D));
21112 if (MaxCD.isFinite()) {
21113 DenomLogB =
ilogb(MaxCD);
21114 C =
scalbn(
C, -DenomLogB, APFloat::rmNearestTiesToEven);
21115 D =
scalbn(D, -DenomLogB, APFloat::rmNearestTiesToEven);
21117 APFloat Denom =
C *
C + D * D;
21119 scalbn((A *
C + B * D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
21121 scalbn((B *
C - A * D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
21122 if (ResR.isNaN() && ResI.isNaN()) {
21123 if (Denom.isPosZero() && (!A.isNaN() || !B.isNaN())) {
21124 ResR = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * A;
21125 ResI = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * B;
21126 }
else if ((A.isInfinity() || B.isInfinity()) &&
C.isFinite() &&
21128 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
21130 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
21132 ResR = APFloat::getInf(ResR.getSemantics()) * (A *
C + B * D);
21133 ResI = APFloat::getInf(ResI.getSemantics()) * (B *
C - A * D);
21134 }
else if (MaxCD.isInfinity() && A.isFinite() && B.isFinite()) {
21135 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
21137 D = APFloat::copySign(APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0),
21139 ResR = APFloat::getZero(ResR.getSemantics()) * (A *
C + B * D);
21140 ResI = APFloat::getZero(ResI.getSemantics()) * (B *
C - A * D);
21147 APSInt NormAmt = Amount;
21148 unsigned BitWidth =
Value.getBitWidth();
21149 unsigned AmtBitWidth = NormAmt.getBitWidth();
21150 if (BitWidth == 1) {
21152 NormAmt =
APSInt(APInt(AmtBitWidth, 0), NormAmt.isUnsigned());
21153 }
else if (BitWidth == 2) {
21158 APSInt(APInt(AmtBitWidth, NormAmt[0] ? 1 : 0), NormAmt.isUnsigned());
21161 if (AmtBitWidth > BitWidth) {
21162 Divisor = llvm::APInt(AmtBitWidth, BitWidth);
21164 Divisor = llvm::APInt(BitWidth, BitWidth);
21165 if (AmtBitWidth < BitWidth) {
21166 NormAmt = NormAmt.extend(BitWidth);
21171 if (NormAmt.isSigned()) {
21172 NormAmt =
APSInt(NormAmt.srem(Divisor),
false);
21173 if (NormAmt.isNegative()) {
21174 APSInt SignedDivisor(Divisor,
false);
21175 NormAmt += SignedDivisor;
21178 NormAmt =
APSInt(NormAmt.urem(Divisor),
true);
21185bool ComplexExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
21187 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
21191 bool LHSReal =
false, RHSReal =
false;
21199 Result.makeComplexFloat();
21203 LHSOK = Visit(E->
getLHS());
21205 if (!LHSOK && !Info.noteFailure())
21211 APFloat &Real = RHS.FloatReal;
21214 RHS.makeComplexFloat();
21215 RHS.FloatImag =
APFloat(Real.getSemantics());
21219 assert(!(LHSReal && RHSReal) &&
21220 "Cannot have both operands of a complex operation be real.");
21222 default:
return Error(E);
21224 if (
Result.isComplexFloat()) {
21225 Result.getComplexFloatReal().add(RHS.getComplexFloatReal(),
21226 APFloat::rmNearestTiesToEven);
21228 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
21230 Result.getComplexFloatImag().add(RHS.getComplexFloatImag(),
21231 APFloat::rmNearestTiesToEven);
21233 Result.getComplexIntReal() += RHS.getComplexIntReal();
21234 Result.getComplexIntImag() += RHS.getComplexIntImag();
21238 if (
Result.isComplexFloat()) {
21239 Result.getComplexFloatReal().subtract(RHS.getComplexFloatReal(),
21240 APFloat::rmNearestTiesToEven);
21242 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
21243 Result.getComplexFloatImag().changeSign();
21244 }
else if (!RHSReal) {
21245 Result.getComplexFloatImag().subtract(RHS.getComplexFloatImag(),
21246 APFloat::rmNearestTiesToEven);
21249 Result.getComplexIntReal() -= RHS.getComplexIntReal();
21250 Result.getComplexIntImag() -= RHS.getComplexIntImag();
21254 if (
Result.isComplexFloat()) {
21259 ComplexValue LHS =
Result;
21260 APFloat &A = LHS.getComplexFloatReal();
21261 APFloat &B = LHS.getComplexFloatImag();
21262 APFloat &
C = RHS.getComplexFloatReal();
21263 APFloat &D = RHS.getComplexFloatImag();
21267 assert(!RHSReal &&
"Cannot have two real operands for a complex op!");
21275 }
else if (RHSReal) {
21287 ComplexValue LHS =
Result;
21288 Result.getComplexIntReal() =
21289 (LHS.getComplexIntReal() * RHS.getComplexIntReal() -
21290 LHS.getComplexIntImag() * RHS.getComplexIntImag());
21291 Result.getComplexIntImag() =
21292 (LHS.getComplexIntReal() * RHS.getComplexIntImag() +
21293 LHS.getComplexIntImag() * RHS.getComplexIntReal());
21297 if (
Result.isComplexFloat()) {
21302 ComplexValue LHS =
Result;
21303 APFloat &A = LHS.getComplexFloatReal();
21304 APFloat &B = LHS.getComplexFloatImag();
21305 APFloat &
C = RHS.getComplexFloatReal();
21306 APFloat &D = RHS.getComplexFloatImag();
21320 B = APFloat::getZero(A.getSemantics());
21325 ComplexValue LHS =
Result;
21326 APSInt Den = RHS.getComplexIntReal() * RHS.getComplexIntReal() +
21327 RHS.getComplexIntImag() * RHS.getComplexIntImag();
21329 return Error(E, diag::note_expr_divide_by_zero);
21331 Result.getComplexIntReal() =
21332 (LHS.getComplexIntReal() * RHS.getComplexIntReal() +
21333 LHS.getComplexIntImag() * RHS.getComplexIntImag()) / Den;
21334 Result.getComplexIntImag() =
21335 (LHS.getComplexIntImag() * RHS.getComplexIntReal() -
21336 LHS.getComplexIntReal() * RHS.getComplexIntImag()) / Den;
21344bool ComplexExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
21358 if (
Result.isComplexFloat()) {
21359 Result.getComplexFloatReal().changeSign();
21360 Result.getComplexFloatImag().changeSign();
21363 Result.getComplexIntReal() = -
Result.getComplexIntReal();
21364 Result.getComplexIntImag() = -
Result.getComplexIntImag();
21368 if (
Result.isComplexFloat())
21369 Result.getComplexFloatImag().changeSign();
21371 Result.getComplexIntImag() = -
Result.getComplexIntImag();
21376bool ComplexExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
21379 Result.makeComplexFloat();
21385 Result.makeComplexInt();
21393 return ExprEvaluatorBaseTy::VisitInitListExpr(E);
21396bool ComplexExprEvaluator::VisitCallExpr(
const CallExpr *E) {
21397 if (!IsConstantEvaluatedBuiltinCall(E))
21398 return ExprEvaluatorBaseTy::VisitCallExpr(E);
21401 case Builtin::BI__builtin_complex:
21402 Result.makeComplexFloat();
21420class AtomicExprEvaluator :
21421 public ExprEvaluatorBase<AtomicExprEvaluator> {
21422 const LValue *
This;
21425 AtomicExprEvaluator(EvalInfo &Info,
const LValue *This,
APValue &
Result)
21433 bool ZeroInitialization(
const Expr *E) {
21434 ImplicitValueInitExpr VIE(
21442 bool VisitCastExpr(
const CastExpr *E) {
21445 return ExprEvaluatorBaseTy::VisitCastExpr(E);
21446 case CK_NullToPointer:
21448 return ZeroInitialization(E);
21449 case CK_NonAtomicToAtomic:
21461 return AtomicExprEvaluator(Info,
This,
Result).Visit(E);
21470class VoidExprEvaluator
21471 :
public ExprEvaluatorBase<VoidExprEvaluator> {
21473 VoidExprEvaluator(EvalInfo &Info) : ExprEvaluatorBaseTy(Info) {}
21477 bool ZeroInitialization(
const Expr *E) {
return true; }
21479 bool VisitCastExpr(
const CastExpr *E) {
21482 return ExprEvaluatorBaseTy::VisitCastExpr(E);
21489 bool VisitCallExpr(
const CallExpr *E) {
21490 if (!IsConstantEvaluatedBuiltinCall(E))
21491 return ExprEvaluatorBaseTy::VisitCallExpr(E);
21494 case Builtin::BI__assume:
21495 case Builtin::BI__builtin_assume:
21499 case Builtin::BI__builtin_operator_delete:
21507 bool VisitCXXDeleteExpr(
const CXXDeleteExpr *E);
21511bool VoidExprEvaluator::VisitCXXDeleteExpr(
const CXXDeleteExpr *E) {
21513 if (Info.SpeculativeEvaluationDepth)
21517 if (!OperatorDelete
21518 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
21519 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
21529 if (
Pointer.Designator.Invalid)
21533 if (
Pointer.isNullPointer()) {
21537 if (!Info.getLangOpts().CPlusPlus20)
21538 Info.CCEDiag(E, diag::note_constexpr_new);
21546 QualType AllocType =
Pointer.Base.getDynamicAllocType();
21552 Info.FFDiag(E, diag::note_constexpr_delete_base_nonvirt_dtor)
21561 if (VirtualDelete &&
21563 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
21564 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
21571 (*Alloc)->Value, AllocType))
21574 if (!Info.HeapAllocs.erase(
Pointer.Base.dyn_cast<DynamicAllocLValue>())) {
21579 Info.FFDiag(E, diag::note_constexpr_double_delete);
21589 return VoidExprEvaluator(Info).Visit(E);
21601 if (E->
isGLValue() ||
T->isFunctionType()) {
21606 }
else if (
T->isVectorType()) {
21609 }
else if (
T->isConstantMatrixType()) {
21612 }
else if (
T->isIntegralOrEnumerationType()) {
21613 if (!IntExprEvaluator(Info,
Result).Visit(E))
21615 }
else if (
T->hasPointerRepresentation()) {
21620 }
else if (
T->isRealFloatingType()) {
21621 llvm::APFloat F(0.0);
21625 }
else if (
T->isAnyComplexType()) {
21630 }
else if (
T->isFixedPointType()) {
21631 if (!FixedPointExprEvaluator(Info,
Result).Visit(E))
return false;
21632 }
else if (
T->isMemberPointerType()) {
21638 }
else if (
T->isArrayType()) {
21641 Info.CurrentCall->createTemporary(E,
T, ScopeKind::FullExpression, LV);
21645 }
else if (
T->isRecordType()) {
21648 Info.CurrentCall->createTemporary(E,
T, ScopeKind::FullExpression, LV);
21652 }
else if (
T->isVoidType()) {
21653 if (!Info.getLangOpts().CPlusPlus11)
21654 Info.CCEDiag(E, diag::note_constexpr_nonliteral)
21658 }
else if (
T->isAtomicType()) {
21659 QualType Unqual =
T.getAtomicUnqualifiedType();
21663 E, Unqual, ScopeKind::FullExpression, LV);
21671 }
else if (Info.getLangOpts().CPlusPlus11) {
21672 Info.FFDiag(E, diag::note_constexpr_nonliteral) << E->
getType();
21675 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
21686 const Expr *E,
bool AllowNonLiteralTypes) {
21702 if (
T->isArrayType())
21704 else if (
T->isRecordType())
21706 else if (
T->isAtomicType()) {
21707 QualType Unqual =
T.getAtomicUnqualifiedType();
21728 if (Info.EnableNewConstInterp) {
21729 if (!Info.Ctx.getInterpContext().evaluateAsRValue(Info, E,
Result))
21732 ConstantExprKind::Normal);
21741 LV.setFrom(Info.Ctx,
Result);
21748 ConstantExprKind::Normal) &&
21756 if (
const auto *L = dyn_cast<IntegerLiteral>(Exp)) {
21758 APValue(
APSInt(L->getValue(), L->getType()->isUnsignedIntegerType()));
21763 if (
const auto *L = dyn_cast<CXXBoolLiteralExpr>(Exp)) {
21769 if (
const auto *FL = dyn_cast<FloatingLiteral>(Exp)) {
21775 if (
const auto *L = dyn_cast<CharacterLiteral>(Exp)) {
21781 if (
const auto *CE = dyn_cast<ConstantExpr>(Exp)) {
21782 if (CE->hasAPValueResult()) {
21783 APValue APV = CE->getAPValueResult();
21785 Result = std::move(APV);
21861 bool InConstantContext)
const {
21863 "Expression evaluator can't be called on a dependent expression.");
21864 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsRValue");
21866 Info.InConstantContext = InConstantContext;
21867 return ::EvaluateAsRValue(
this,
Result, Ctx, Info);
21871 bool InConstantContext)
const {
21873 "Expression evaluator can't be called on a dependent expression.");
21874 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsBooleanCondition");
21882 bool InConstantContext)
const {
21884 "Expression evaluator can't be called on a dependent expression.");
21885 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsInt");
21887 Info.InConstantContext = InConstantContext;
21888 return ::EvaluateAsInt(
this,
Result, Ctx, AllowSideEffects, Info);
21893 bool InConstantContext)
const {
21895 "Expression evaluator can't be called on a dependent expression.");
21896 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFixedPoint");
21898 Info.InConstantContext = InConstantContext;
21899 return ::EvaluateAsFixedPoint(
this,
Result, Ctx, AllowSideEffects, Info);
21904 bool InConstantContext)
const {
21906 "Expression evaluator can't be called on a dependent expression.");
21908 if (!
getType()->isRealFloatingType())
21911 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFloat");
21923 bool InConstantContext)
const {
21925 "Expression evaluator can't be called on a dependent expression.");
21927 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsLValue");
21929 Info.InConstantContext = InConstantContext;
21933 if (Info.EnableNewConstInterp) {
21934 if (!Info.Ctx.getInterpContext().evaluate(Info,
this,
Result.Val,
21935 ConstantExprKind::Normal))
21938 LV.setFrom(Ctx,
Result.Val);
21941 ConstantExprKind::Normal, CheckedTemps);
21944 if (!
EvaluateLValue(
this, LV, Info) || !Info.discardCleanups() ||
21945 Result.HasSideEffects ||
21948 ConstantExprKind::Normal, CheckedTemps))
21951 LV.moveInto(
Result.Val);
21958 bool IsConstantDestruction) {
21959 EvalInfo Info(Ctx, EStatus,
21962 Info.setEvaluatingDecl(
Base, DestroyedValue,
21963 EvalInfo::EvaluatingDeclKind::Dtor);
21964 Info.InConstantContext = IsConstantDestruction;
21973 if (!Info.discardCleanups())
21974 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
21982 "Expression evaluator can't be called on a dependent expression.");
21988 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsConstantExpr");
21990 EvalInfo Info(Ctx,
Result, EM);
21991 Info.InConstantContext =
true;
21993 if (Info.EnableNewConstInterp) {
21994 if (!Info.Ctx.getInterpContext().evaluate(Info,
this,
Result.Val, Kind))
21997 getStorageType(Ctx,
this),
Result.Val, Kind);
22002 if (Kind == ConstantExprKind::ClassTemplateArgument)
22018 FullExpressionRAII
Scope(Info);
22023 if (!Info.discardCleanups())
22024 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
22034 if (Kind == ConstantExprKind::ClassTemplateArgument &&
22037 Result.HasSideEffects)) {
22048 bool IsConstantInitialization)
const {
22050 "Expression evaluator can't be called on a dependent expression.");
22051 assert(VD &&
"Need a valid VarDecl");
22053 llvm::TimeTraceScope TimeScope(
"EvaluateAsInitializer", [&] {
22055 llvm::raw_string_ostream OS(Name);
22060 EvalInfo Info(Ctx, EStatus,
22061 (IsConstantInitialization &&
22065 Info.setEvaluatingDecl(VD, EStatus.
Val);
22066 Info.InConstantContext = IsConstantInitialization;
22071 if (Info.EnableNewConstInterp) {
22073 if (!InterpCtx.evaluateAsInitializer(Info, VD,
this, EStatus.
Val))
22077 ConstantExprKind::Normal);
22092 FullExpressionRAII
Scope(Info);
22101 Info.performLifetimeExtension();
22103 if (!Info.discardCleanups())
22104 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
22108 ConstantExprKind::Normal) &&
22128 EStatus.
Diag = &Notes;
22145 EvalInfo Info(Ctx, EStatus,
22148 Info.InConstantContext = IsConstantDestruction;
22150 std::move(DestroyedValue)))
22157 getLocation(), EStatus, IsConstantDestruction) ||
22169 "Expression evaluator can't be called on a dependent expression.");
22178 "Expression evaluator can't be called on a dependent expression.");
22180 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstInt");
22183 Info.InConstantContext =
true;
22187 assert(
Result &&
"Could not evaluate expression");
22188 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
22190 return EVResult.Val.getInt();
22196 "Expression evaluator can't be called on a dependent expression.");
22198 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstIntCheckOverflow");
22200 EVResult.Diag =
Diag;
22202 Info.InConstantContext =
true;
22203 Info.CheckingForUndefinedBehavior =
true;
22207 assert(
Result &&
"Could not evaluate expression");
22208 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
22210 return EVResult.Val.getInt();
22215 "Expression evaluator can't be called on a dependent expression.");
22217 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateForOverflow");
22222 Info.CheckingForUndefinedBehavior =
true;
22228 assert(
Val.isLValue());
22254 IK_ICEIfUnevaluated,
22270static ICEDiag
Worst(ICEDiag A, ICEDiag B) {
return A.Kind >= B.Kind ? A : B; }
22277 Info.InConstantContext =
true;
22286 assert(!E->
isValueDependent() &&
"Should not see value dependent exprs!");
22291#define ABSTRACT_STMT(Node)
22292#define STMT(Node, Base) case Expr::Node##Class:
22293#define EXPR(Node, Base)
22294#include "clang/AST/StmtNodes.inc"
22295 case Expr::PredefinedExprClass:
22296 case Expr::FloatingLiteralClass:
22297 case Expr::ImaginaryLiteralClass:
22298 case Expr::StringLiteralClass:
22299 case Expr::ArraySubscriptExprClass:
22300 case Expr::MatrixSingleSubscriptExprClass:
22301 case Expr::MatrixSubscriptExprClass:
22302 case Expr::ArraySectionExprClass:
22303 case Expr::OMPArrayShapingExprClass:
22304 case Expr::OMPIteratorExprClass:
22305 case Expr::CompoundAssignOperatorClass:
22306 case Expr::CompoundLiteralExprClass:
22307 case Expr::ExtVectorElementExprClass:
22308 case Expr::MatrixElementExprClass:
22309 case Expr::DesignatedInitExprClass:
22310 case Expr::ArrayInitLoopExprClass:
22311 case Expr::ArrayInitIndexExprClass:
22312 case Expr::NoInitExprClass:
22313 case Expr::DesignatedInitUpdateExprClass:
22314 case Expr::ImplicitValueInitExprClass:
22315 case Expr::ParenListExprClass:
22316 case Expr::VAArgExprClass:
22317 case Expr::AddrLabelExprClass:
22318 case Expr::StmtExprClass:
22319 case Expr::CXXMemberCallExprClass:
22320 case Expr::CUDAKernelCallExprClass:
22321 case Expr::CXXAddrspaceCastExprClass:
22322 case Expr::CXXDynamicCastExprClass:
22323 case Expr::CXXTypeidExprClass:
22324 case Expr::CXXUuidofExprClass:
22325 case Expr::MSPropertyRefExprClass:
22326 case Expr::MSPropertySubscriptExprClass:
22327 case Expr::CXXNullPtrLiteralExprClass:
22328 case Expr::UserDefinedLiteralClass:
22329 case Expr::CXXThisExprClass:
22330 case Expr::CXXThrowExprClass:
22331 case Expr::CXXNewExprClass:
22332 case Expr::CXXDeleteExprClass:
22333 case Expr::CXXPseudoDestructorExprClass:
22334 case Expr::UnresolvedLookupExprClass:
22335 case Expr::RecoveryExprClass:
22336 case Expr::DependentScopeDeclRefExprClass:
22337 case Expr::CXXConstructExprClass:
22338 case Expr::CXXInheritedCtorInitExprClass:
22339 case Expr::CXXStdInitializerListExprClass:
22340 case Expr::CXXBindTemporaryExprClass:
22341 case Expr::ExprWithCleanupsClass:
22342 case Expr::CXXTemporaryObjectExprClass:
22343 case Expr::CXXUnresolvedConstructExprClass:
22344 case Expr::CXXDependentScopeMemberExprClass:
22345 case Expr::UnresolvedMemberExprClass:
22346 case Expr::ObjCStringLiteralClass:
22347 case Expr::ObjCBoxedExprClass:
22348 case Expr::ObjCArrayLiteralClass:
22349 case Expr::ObjCDictionaryLiteralClass:
22350 case Expr::ObjCEncodeExprClass:
22351 case Expr::ObjCMessageExprClass:
22352 case Expr::ObjCSelectorExprClass:
22353 case Expr::ObjCProtocolExprClass:
22354 case Expr::ObjCIvarRefExprClass:
22355 case Expr::ObjCPropertyRefExprClass:
22356 case Expr::ObjCSubscriptRefExprClass:
22357 case Expr::ObjCIsaExprClass:
22358 case Expr::ObjCAvailabilityCheckExprClass:
22359 case Expr::ShuffleVectorExprClass:
22360 case Expr::ConvertVectorExprClass:
22361 case Expr::BlockExprClass:
22363 case Expr::OpaqueValueExprClass:
22364 case Expr::PackExpansionExprClass:
22365 case Expr::SubstNonTypeTemplateParmPackExprClass:
22366 case Expr::FunctionParmPackExprClass:
22367 case Expr::AsTypeExprClass:
22368 case Expr::ObjCIndirectCopyRestoreExprClass:
22369 case Expr::MaterializeTemporaryExprClass:
22370 case Expr::PseudoObjectExprClass:
22371 case Expr::AtomicExprClass:
22372 case Expr::LambdaExprClass:
22373 case Expr::CXXFoldExprClass:
22374 case Expr::CoawaitExprClass:
22375 case Expr::DependentCoawaitExprClass:
22376 case Expr::CoyieldExprClass:
22377 case Expr::SYCLUniqueStableNameExprClass:
22378 case Expr::CXXParenListInitExprClass:
22379 case Expr::HLSLOutArgExprClass:
22380 case Expr::CXXExpansionSelectExprClass:
22383 case Expr::MemberExprClass: {
22386 while (
const auto *M = dyn_cast<MemberExpr>(ME)) {
22389 ME = M->getBase()->IgnoreParenImpCasts();
22391 const auto *DRE = dyn_cast<DeclRefExpr>(ME);
22393 if (
const auto *VD = dyn_cast<VarDecl>(DRE->getDecl());
22401 case Expr::InitListExprClass: {
22412 case Expr::SizeOfPackExprClass:
22413 case Expr::GNUNullExprClass:
22414 case Expr::SourceLocExprClass:
22415 case Expr::EmbedExprClass:
22416 case Expr::OpenACCAsteriskSizeExprClass:
22419 case Expr::PackIndexingExprClass:
22422 case Expr::SubstNonTypeTemplateParmExprClass:
22426 case Expr::ConstantExprClass:
22429 case Expr::ParenExprClass:
22431 case Expr::GenericSelectionExprClass:
22433 case Expr::IntegerLiteralClass:
22434 case Expr::FixedPointLiteralClass:
22435 case Expr::CharacterLiteralClass:
22436 case Expr::ObjCBoolLiteralExprClass:
22437 case Expr::CXXBoolLiteralExprClass:
22438 case Expr::CXXScalarValueInitExprClass:
22439 case Expr::TypeTraitExprClass:
22440 case Expr::ConceptSpecializationExprClass:
22441 case Expr::RequiresExprClass:
22442 case Expr::ArrayTypeTraitExprClass:
22443 case Expr::ExpressionTraitExprClass:
22444 case Expr::CXXNoexceptExprClass:
22445 case Expr::CXXReflectExprClass:
22447 case Expr::CallExprClass:
22448 case Expr::CXXOperatorCallExprClass: {
22457 case Expr::CXXRewrittenBinaryOperatorClass:
22460 case Expr::DeclRefExprClass: {
22474 const VarDecl *VD = dyn_cast<VarDecl>(D);
22481 case Expr::UnaryOperatorClass: {
22504 llvm_unreachable(
"invalid unary operator class");
22506 case Expr::OffsetOfExprClass: {
22515 case Expr::UnaryExprOrTypeTraitExprClass: {
22517 if ((Exp->
getKind() == UETT_SizeOf) &&
22520 if (Exp->
getKind() == UETT_CountOf) {
22527 if (VAT->getElementType()->isArrayType())
22539 case Expr::BinaryOperatorClass: {
22584 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE) {
22587 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
22588 if (REval.isSigned() && REval.isAllOnes()) {
22590 if (LEval.isMinSignedValue())
22591 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
22599 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE)
22600 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
22606 return Worst(LHSResult, RHSResult);
22612 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICEIfUnevaluated) {
22622 return Worst(LHSResult, RHSResult);
22625 llvm_unreachable(
"invalid binary operator kind");
22627 case Expr::ImplicitCastExprClass:
22628 case Expr::CStyleCastExprClass:
22629 case Expr::CXXFunctionalCastExprClass:
22630 case Expr::CXXStaticCastExprClass:
22631 case Expr::CXXReinterpretCastExprClass:
22632 case Expr::CXXConstCastExprClass:
22633 case Expr::ObjCBridgedCastExprClass: {
22640 APSInt IgnoredVal(DestWidth, !DestSigned);
22645 if (FL->getValue().convertToInteger(IgnoredVal,
22646 llvm::APFloat::rmTowardZero,
22647 &Ignored) & APFloat::opInvalidOp)
22653 case CK_LValueToRValue:
22654 case CK_AtomicToNonAtomic:
22655 case CK_NonAtomicToAtomic:
22657 case CK_IntegralToBoolean:
22658 case CK_IntegralCast:
22664 case Expr::BinaryConditionalOperatorClass: {
22667 if (CommonResult.Kind == IK_NotICE)
return CommonResult;
22669 if (FalseResult.Kind == IK_NotICE)
return FalseResult;
22670 if (CommonResult.Kind == IK_ICEIfUnevaluated)
return CommonResult;
22671 if (FalseResult.Kind == IK_ICEIfUnevaluated &&
22673 return FalseResult;
22675 case Expr::ConditionalOperatorClass: {
22683 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
22686 if (CondResult.Kind == IK_NotICE)
22692 if (TrueResult.Kind == IK_NotICE)
22694 if (FalseResult.Kind == IK_NotICE)
22695 return FalseResult;
22696 if (CondResult.Kind == IK_ICEIfUnevaluated)
22698 if (TrueResult.Kind == IK_ICE && FalseResult.Kind == IK_ICE)
22704 return FalseResult;
22707 case Expr::CXXDefaultArgExprClass:
22709 case Expr::CXXDefaultInitExprClass:
22711 case Expr::ChooseExprClass: {
22714 case Expr::BuiltinBitCastExprClass: {
22715 if (!checkBitCastConstexprEligibility(
nullptr, Ctx,
cast<CastExpr>(E)))
22721 llvm_unreachable(
"Invalid StmtClass!");
22727 llvm::APSInt *
Value) {
22744 "Expression evaluator can't be called on a dependent expression.");
22746 ExprTimeTraceScope TimeScope(
this, Ctx,
"isIntegerConstantExpr");
22752 if (D.Kind != IK_ICE)
22757std::optional<llvm::APSInt>
22761 return std::nullopt;
22768 return std::nullopt;
22772 return std::nullopt;
22781 Info.InConstantContext =
true;
22784 llvm_unreachable(
"ICE cannot be evaluated!");
22791 "Expression evaluator can't be called on a dependent expression.");
22793 return CheckICE(
this, Ctx).Kind == IK_ICE;
22798 "Expression evaluator can't be called on a dependent expression.");
22808 *
Result = std::move(Scratch);
22820 Info.discardCleanups() && !Status.HasSideEffects;
22822 return IsConstExpr && !Status.DiagEmitted;
22830 "Expression evaluator can't be called on a dependent expression.");
22832 llvm::TimeTraceScope TimeScope(
"EvaluateWithSubstitution", [&] {
22834 llvm::raw_string_ostream OS(Name);
22842 Info.InConstantContext =
true;
22844 if (Info.EnableNewConstInterp) {
22845 if (std::optional<bool> BoolResult =
22846 Info.Ctx.getInterpContext().evaluateWithSubstitution(
22847 Info, Callee, Args,
This,
this)) {
22855 const LValue *ThisPtr =
nullptr;
22858 auto *MD = dyn_cast<CXXMethodDecl>(Callee);
22859 assert(MD &&
"Don't provide `this` for non-methods.");
22860 assert(MD->isImplicitObjectMemberFunction() &&
22861 "Don't provide `this` for methods without an implicit object.");
22863 if (!
This->isValueDependent() &&
22865 !Info.EvalStatus.HasSideEffects)
22866 ThisPtr = &ThisVal;
22870 Info.EvalStatus.HasSideEffects =
false;
22873 CallRef
Call = Info.CurrentCall->createCall(Callee);
22876 unsigned Idx = I - Args.begin();
22877 if (Idx >= Callee->getNumParams())
22879 const ParmVarDecl *PVD = Callee->getParamDecl(Idx);
22880 if ((*I)->isValueDependent() ||
22882 Info.EvalStatus.HasSideEffects) {
22884 if (
APValue *Slot = Info.getParamSlot(
Call, PVD))
22890 Info.EvalStatus.HasSideEffects =
false;
22895 Info.discardCleanups();
22896 Info.EvalStatus.HasSideEffects =
false;
22899 CallStackFrame Frame(Info, Callee->getLocation(), Callee, ThisPtr,
This,
22902 FullExpressionRAII
Scope(Info);
22904 !Info.EvalStatus.HasSideEffects;
22916 llvm::TimeTraceScope TimeScope(
"isPotentialConstantExpr", [&] {
22918 llvm::raw_string_ostream OS(Name);
22925 Status.
Diag = &Diags;
22929 Info.InConstantContext =
true;
22930 Info.CheckingPotentialConstantExpression =
true;
22933 if (Info.EnableNewConstInterp) {
22934 Info.Ctx.getInterpContext().isPotentialConstantExpr(Info, FD);
22935 return Diags.empty();
22946 This.set({&VIE, Info.CurrentCall->Index});
22954 Info.setEvaluatingDecl(
This.getLValueBase(), Scratch);
22960 &VIE, Args, CallRef(), FD->
getBody(), Info, Scratch,
22964 return Diags.empty();
22972 "Expression evaluator can't be called on a dependent expression.");
22975 Status.
Diag = &Diags;
22979 Info.InConstantContext =
true;
22980 Info.CheckingPotentialConstantExpression =
true;
22982 if (Info.EnableNewConstInterp) {
22983 Info.Ctx.getInterpContext().isPotentialConstantExprUnevaluated(Info, E, FD);
22984 return Diags.empty();
22989 nullptr, CallRef());
22993 return Diags.empty();
22997 unsigned Type)
const {
22998 if (!
getType()->isPointerType())
22999 return std::nullopt;
23003 if (Info.EnableNewConstInterp)
23004 return Info.Ctx.getInterpContext().tryEvaluateObjectSize(Info,
this,
Type);
23008static std::optional<uint64_t>
23010 std::string *StringResult) {
23012 return std::nullopt;
23017 return std::nullopt;
23022 if (
const StringLiteral *S = dyn_cast_or_null<StringLiteral>(
23023 String.getLValueBase().dyn_cast<
const Expr *>())) {
23026 if (
Off >= 0 && (uint64_t)
Off <= (uint64_t)Str.size() &&
23029 Info.Ctx.hasSameUnqualifiedType(CharTy, Info.Ctx.CharTy)) {
23030 Str = Str.substr(
Off);
23032 StringRef::size_type Pos = Str.find(0);
23033 if (Pos != StringRef::npos)
23034 Str = Str.substr(0, Pos);
23037 *StringResult = Str;
23045 for (uint64_t Strlen = 0; ; ++Strlen) {
23049 return std::nullopt;
23052 else if (StringResult)
23053 StringResult->push_back(Char.
getInt().getExtValue());
23055 return std::nullopt;
23062 std::string StringResult;
23064 if (Info.EnableNewConstInterp) {
23065 if (!Info.Ctx.getInterpContext().evaluateString(Info,
this, StringResult))
23066 return std::nullopt;
23067 return StringResult;
23071 return StringResult;
23072 return std::nullopt;
23075template <
typename T>
23077 const Expr *SizeExpression,
23078 const Expr *PtrExpression,
23082 Info.InConstantContext =
true;
23084 if (Info.EnableNewConstInterp)
23085 return Info.Ctx.getInterpContext().evaluateCharRange(Info, SizeExpression,
23089 FullExpressionRAII
Scope(Info);
23094 uint64_t Size = SizeValue.getZExtValue();
23097 if constexpr (std::is_same_v<APValue, T>)
23100 if (Size <
Result.max_size())
23107 for (uint64_t I = 0; I < Size; ++I) {
23113 if constexpr (std::is_same_v<APValue, T>) {
23114 Result.getArrayInitializedElt(I) = std::move(Char);
23118 assert(
C.getBitWidth() <= 8 &&
23119 "string element not representable in char");
23121 Result.push_back(
static_cast<char>(
C.getExtValue()));
23132 const Expr *SizeExpression,
23136 PtrExpression, Ctx, Status);
23140 const Expr *SizeExpression,
23144 PtrExpression, Ctx, Status);
23151 if (Info.EnableNewConstInterp)
23152 return Info.Ctx.getInterpContext().evaluateStrlen(Info,
this);
23157struct IsWithinLifetimeHandler {
23160 using result_type = std::optional<bool>;
23161 std::optional<bool> failed() {
return std::nullopt; }
23162 template <
typename T>
23163 std::optional<bool> found(
T &Subobj,
QualType SubobjType,
23167 template <
typename T>
23168 std::optional<bool> found(
T &Subobj, QualType SubobjType) {
23173std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &IEE,
23174 const CallExpr *E) {
23175 EvalInfo &Info = IEE.Info;
23180 if (!Info.InConstantContext)
23181 return std::nullopt;
23183 const Expr *Arg = E->
getArg(0);
23185 return std::nullopt;
23188 return std::nullopt;
23190 if (Val.allowConstexprUnknown())
23194 bool CalledFromStd =
false;
23195 const auto *
Callee = Info.CurrentCall->getCallee();
23196 if (Callee &&
Callee->isInStdNamespace()) {
23197 const IdentifierInfo *Identifier =
Callee->getIdentifier();
23198 CalledFromStd = Identifier && Identifier->
isStr(
"is_within_lifetime");
23200 Info.CCEDiag(CalledFromStd ? Info.CurrentCall->getCallRange().getBegin()
23202 diag::err_invalid_is_within_lifetime)
23203 << (CalledFromStd ?
"std::is_within_lifetime"
23204 :
"__builtin_is_within_lifetime")
23206 return std::nullopt;
23216 if (Val.isNullPointer() || Val.getLValueBase().isNull())
23218 QualType
T = Val.getLValueBase().getType();
23220 "Pointers to functions should have been typed as function pointers "
23221 "which would have been rejected earlier");
23224 if (Val.getLValueDesignator().isOnePastTheEnd())
23226 assert(Val.getLValueDesignator().isValidSubobject() &&
23227 "Unchecked case for valid subobject");
23231 CompleteObject CO =
23235 if (Info.EvaluatingDeclValue && CO.Value == Info.EvaluatingDeclValue)
23240 IsWithinLifetimeHandler handler{Info};
23241 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 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 bool EvaluateCPlusPlus11IntegralConstantExpr(const ASTContext &Ctx, const Expr *E, llvm::APSInt *Value)
Evaluate an expression as a C++11 integral constant expression.
static CharUnits GetAlignOfType(const ASTContext &Ctx, QualType T, UnaryExprOrTypeTrait ExprKind)
static bool getBuiltinAlignArguments(const CallExpr *E, EvalInfo &Info, APValue &Val, APSInt &Alignment)
static bool HandleLValueArrayAdjustment(EvalInfo &Info, const Expr *E, LValue &LVal, QualType EltTy, APSInt Adjustment)
Update a pointer value to model pointer arithmetic.
static bool extractSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, const SubobjectDesignator &Sub, APValue &Result, AccessKinds AK=AK_Read)
Extract the designated sub-object of an rvalue.
static bool HandleLValueMember(EvalInfo &Info, const Expr *E, LValue &LVal, const FieldDecl *FD, const ASTRecordLayout *RL=nullptr)
Update LVal to refer to the given field, which must be a member of the type currently described by LV...
static void addOrSubLValueAsInteger(APValue &LVal, const APSInt &Index, bool IsSub)
static bool IsDeclSourceLocationCurrent(const FunctionDecl *FD)
static std::optional< uint64_t > EvaluateBuiltinStrLen(const Expr *E, EvalInfo &Info, std::string *StringResult=nullptr)
void HandleComplexComplexDiv(APFloat A, APFloat B, APFloat C, APFloat D, APFloat &ResR, APFloat &ResI)
static bool handleTrivialCopy(EvalInfo &Info, const ParmVarDecl *Param, const Expr *E, APValue &Result, bool CopyObjectRepresentation)
Perform a trivial copy from Param, which is the parameter of a copy or move constructor or assignment...
static bool checkFloatingPointResult(EvalInfo &Info, const Expr *E, APFloat::opStatus St)
Check if the given evaluation result is allowed for constant evaluation.
static bool EvaluateBuiltinConstantPForLValue(const APValue &LV)
EvaluateBuiltinConstantPForLValue - Determine the result of __builtin_constant_p when applied to the ...
static bool EvaluateBuiltinConstantP(EvalInfo &Info, const Expr *Arg)
EvaluateBuiltinConstantP - Evaluate __builtin_constant_p as similarly to GCC as we can manage.
static bool checkNonVirtualMemberCallThisPointer(EvalInfo &Info, const Expr *E, const LValue &This, const CXXMethodDecl *NamedMember)
Check that the pointee of the 'this' pointer in a member function call is either within its lifetime ...
static bool CheckConstantExpression(EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value, ConstantExprKind Kind)
Check that this core constant expression value is a valid value for a constant expression.
static bool EvaluateAsBooleanCondition(const Expr *E, bool &Result, EvalInfo &Info)
static std::optional< DynamicType > ComputeDynamicType(EvalInfo &Info, const Expr *E, LValue &This, AccessKinds AK)
Determine the dynamic type of an object.
static bool EvaluateDecl(EvalInfo &Info, const Decl *D, bool EvaluateConditionDecl=false)
static void expandArray(APValue &Array, unsigned Index)
static bool handleLogicalOpForVector(const APInt &LHSValue, BinaryOperatorKind Opcode, const APInt &RHSValue, APInt &Result)
static unsigned FindDesignatorMismatch(QualType ObjType, const SubobjectDesignator &A, const SubobjectDesignator &B, bool &WasArrayIndex)
Find the position where two subobject designators diverge, or equivalently the length of the common i...
static bool isOnePastTheEndOfCompleteObject(const ASTContext &Ctx, const LValue &LV)
Determine whether this is a pointer past the end of the complete object referred to by the lvalue.
static unsigned getBaseIndex(const CXXRecordDecl *Derived, const CXXRecordDecl *Base)
Get the base index of the given base class within an APValue representing the given derived class.
static bool EvaluateFixedPoint(const Expr *E, APFixedPoint &Result, EvalInfo &Info)
Evaluate only a fixed point expression into an APResult.
void HandleComplexComplexMul(APFloat A, APFloat B, APFloat C, APFloat D, APFloat &ResR, APFloat &ResI)
static bool 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 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. If successful, returns true and stores the result ...
static bool Evaluate(APValue &Result, EvalInfo &Info, const Expr *E)
static bool isReadByLvalueToRvalueConversion(const CXXRecordDecl *RD)
Determine whether a type would actually be read by an lvalue-to-rvalue conversion.
static void negateAsSigned(APSInt &Int)
Negate an APSInt in place, converting it to a signed form if necessary, and preserving its value (by ...
static bool HandleFunctionCall(SourceLocation CallLoc, const FunctionDecl *Callee, const LValue *ObjectArg, const Expr *E, ArrayRef< const Expr * > Args, CallRef Call, const Stmt *Body, EvalInfo &Info, APValue &Result, const LValue *ResultSlot)
Evaluate a function call.
static bool isUserWritingOffTheEnd(const ASTContext &Ctx, const LValue &LVal)
Attempts to detect a user writing into a piece of memory that's impossible to figure out the size of ...
static bool GetLValueBaseAsString(const EvalInfo &Info, const LValue &LVal, LValueBaseString &AsString)
static bool HandleOperatorDeleteCall(EvalInfo &Info, const CallExpr *E)
static bool EvaluateIntegerOrLValue(const Expr *E, APValue &Result, EvalInfo &Info)
EvaluateIntegerOrLValue - Evaluate an rvalue integral-typed expression, and produce either the intege...
static bool HandleDynamicCast(EvalInfo &Info, const ExplicitCastExpr *E, LValue &Ptr)
Apply the given dynamic cast operation on the provided lvalue.
static bool HandleOperatorNewCall(EvalInfo &Info, const CallExpr *E, LValue &Result)
Perform a call to 'operator new' or to ‘__builtin_operator_new’.
static bool HandleFloatToFloatCast(EvalInfo &Info, const Expr *E, QualType SrcType, QualType DestType, APFloat &Result)
static bool MaybeHandleUnionActiveMemberChange(EvalInfo &Info, const Expr *LHSExpr, const LValue &LHS)
Handle a builtin simple-assignment or a call to a trivial assignment operator whose left-hand side mi...
uint8_t GFNIMul(uint8_t AByte, uint8_t BByte)
static bool isFormalAccess(AccessKinds AK)
Is this an access per the C++ definition?
static bool handleCompoundAssignment(EvalInfo &Info, const CompoundAssignOperator *E, const LValue &LVal, QualType LValType, QualType PromotedLValType, BinaryOperatorKind Opcode, const APValue &RVal)
Perform a compound assignment of LVal <op>= RVal.
static bool handleIncDec(EvalInfo &Info, const Expr *E, const LValue &LVal, QualType LValType, bool IsIncrement, APValue *Old)
Perform an increment or decrement on LVal.
static bool EvaluateVoid(const Expr *E, EvalInfo &Info)
static bool HandleDestruction(EvalInfo &Info, const Expr *E, const LValue &This, QualType ThisType)
Perform a destructor or pseudo-destructor call on the given object, which might in general not be a c...
static bool 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 isCXX11ConstantExpr(const ASTContext &Ctx, APValue *Result=nullptr) const
isCXX11ConstantExpr - Return true if this expression is a constant expression in C++11.
bool EvaluateCharRangeAsString(std::string &Result, const Expr *SizeExpression, const Expr *PtrExpression, ASTContext &Ctx, EvalResult &Status) const
llvm::APSInt EvaluateKnownConstIntCheckOverflow(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
bool isValueDependent() const
Determines whether the value of this expression depends on.
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Returns the set of floating point options that apply to this expression.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
bool containsErrors() const
Whether this expression contains subexpressions which had errors.
bool EvaluateAsFloat(llvm::APFloat &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsFloat - Return true if this is a constant which we can fold and convert to a floating point...
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsLValue - Evaluate an expression to see if we can fold it to an lvalue with link time known ...
bool EvaluateAsInitializer(const ASTContext &Ctx, const VarDecl *VD, EvalResult &Result, bool IsConstantInitializer) const
EvaluateAsInitializer - Evaluate an expression as if it were the initializer of the given declaration...
bool EvaluateAsFixedPoint(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsFixedPoint - Return true if this is a constant which we can fold and convert to a fixed poi...
bool isEvaluatable(const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
isEvaluatable - Call EvaluateAsRValue to see if this expression can be constant folded without side-e...
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language.
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...
std::optional< uint64_t > tryEvaluateStrLen(const ASTContext &Ctx) const
If the current Expr is a pointer, this will try to statically determine the strlen of the string poin...
bool HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects=true) const
HasSideEffects - This routine returns true for all those expressions which have any effect other than...
bool EvaluateAsConstantExpr(EvalResult &Result, const ASTContext &Ctx, ConstantExprKind Kind=ConstantExprKind::Normal) const
Evaluate an expression that is required to be a constant expression.
std::optional< std::string > tryEvaluateString(ASTContext &Ctx) const
If the current Expr can be evaluated to a pointer to a null-terminated constant string,...
bool EvaluateAsBooleanCondition(bool &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsBooleanCondition - Return true if this is a constant which we can fold and convert to a boo...
bool isTemporaryObject(ASTContext &Ctx, const CXXRecordDecl *TempTy) const
Determine whether the result of this expression is a temporary object of the given class type.
std::optional< uint64_t > tryEvaluateObjectSize(const ASTContext &Ctx, unsigned Type) const
If the current Expr is a pointer, this will try to statically determine the number of bytes available...
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
bool isCXX98IntegralConstantExpr(const ASTContext &Ctx) const
isCXX98IntegralConstantExpr - Return true if this expression is an integral constant expression in C+...
bool EvaluateWithSubstitution(APValue &Value, ASTContext &Ctx, const FunctionDecl *Callee, ArrayRef< const Expr * > Args, const Expr *This=nullptr) const
EvaluateWithSubstitution - Evaluate an expression as if from the context of a call to the given funct...
void EvaluateForOverflow(const ASTContext &Ctx) const
bool isArrow() const
isArrow - Return true if the base expression is a pointer to vector, return false if the base express...
void getEncodedElementAccess(SmallVectorImpl< uint32_t > &Elts) const
getEncodedElementAccess - Encode the elements accessed into an llvm aggregate Constant of ConstantInt...
bool isFPConstrained() const
LangOptions::FPExceptionModeKind getExceptionMode() const
RoundingMode getRoundingMode() const
Represents a member of a struct/union/class.
bool isBitField() const
Determines whether this field is a bitfield.
unsigned getBitWidthValue() const
Computes the bit width of this field, if this is a bit field.
unsigned getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
FieldDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this field.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
llvm::APInt getValue() const
Returns an internal integer representation of the literal.
llvm::APFloat getValue() const
ForStmt - This represents a 'for (init;cond;inc)' stmt.
VarDecl * getConditionVariable() const
Retrieve the variable declared in this "for" statement, if any.
const Expr * getSubExpr() const
Represents a function declaration or definition.
const ParmVarDecl * getParamDecl(unsigned i) const
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
bool isFunctionTemplateSpecialization() const
Determine whether this function is a function template specialization.
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
bool hasCXXExplicitFunctionObjectParameter() const
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
bool isConstexpr() const
Whether this is a (C++11) constexpr function or constexpr constructor.
bool isUsableAsGlobalAllocationFunctionInConstantEvaluation(UnsignedOrNone *AlignmentParam=nullptr, bool *IsNothrow=nullptr) const
Determines whether this function is one of the replaceable global allocation functions described in i...
bool isDefaulted() const
Whether this function is defaulted.
void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override
Appends a human-readable name for this declaration into the given stream.
FunctionDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
Expr * getResultExpr()
Return the result expression of this controlling expression.
One of these records is kept for each identifier that is lexed.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
IfStmt - This represents an if/then/else.
bool isNonNegatedConsteval() const
VarDecl * getConditionVariable()
Retrieve the variable declared in this "if" statement, if any.
const Expr * getSubExpr() const
Represents an implicitly-generated value initialization of an object of a given type.
Represents a field injected from an anonymous union/struct into the parent scope.
ArrayRef< NamedDecl * > chain() const
Describes an C or C++ initializer list.
bool isTransparent() const
Is this a transparent initializer list (that is, an InitListExpr that is purely syntactic,...
bool isStringLiteralInit() const
Is this an initializer for an array of characters, initialized by a string literal or an @encode?
unsigned getNumInits() const
Expr * getArrayFiller()
If this initializer list initializes an array with more elements than there are initializers in the l...
const Expr * getInit(unsigned Init) const
ArrayRef< Expr * > inits() const
capture_init_iterator capture_init_end()
Retrieve the iterator pointing one past the last initialization argument for this lambda expression.
capture_init_iterator capture_init_begin()
Retrieve the first initialization argument for this lambda expression (which initializes the first ca...
CXXRecordDecl * getLambdaClass() const
Retrieve the class that corresponds to the lambda.
StrictFlexArraysLevelKind
@ FPE_Ignore
Assume that floating-point exceptions are masked.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
bool isCompatibleWith(ClangABI Version) const
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
StorageDuration getStorageDuration() const
Retrieve the storage duration for the materialized temporary.
Expr * getSubExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue.
APValue * getOrCreateValue(bool MayCreate) const
Get the storage for the constant value of a materialized temporary of static storage duration.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
void printQualifiedName(raw_ostream &OS) const
Returns a human-readable qualified name for this declaration, like A::B::i, for i being member of nam...
bool isExpressibleAsConstantInitializer() const
Expr * getIndexExpr(unsigned Idx)
const OffsetOfNode & getComponent(unsigned Idx) const
TypeSourceInfo * getTypeSourceInfo() const
unsigned getNumComponents() const
unsigned getArrayExprIndex() const
For an array element node, returns the index into the array of expressions.
FieldDecl * getField() const
For a field offsetof node, returns the field.
@ Array
An index into an array.
@ Identifier
A field in a dependent type, known only by its name.
@ Base
An implicit indirection through a C++ base class, when the field found is in a base class.
Kind getKind() const
Determine what kind of offsetof node this is.
CXXBaseSpecifier * getBase() const
For a base class node, returns the base specifier.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
Expr * getSelectedExpr() const
const Expr * getSubExpr() const
Represents a parameter to a function.
unsigned getFunctionScopeIndex() const
Returns the index of this parameter in its prototype or method scope.
bool isExplicitObjectParameter() const
PointerType - C99 6.7.5.1 - Pointer Declarators.
StringLiteral * getFunctionName()
Expr * getResultExpr()
Return the result-bearing expression, or null if there is none.
ArrayRef< Expr * > semantics()
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
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.
AccessKind
This enum distinguishes between different ways to access (read or write) a variable.
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
bool isa(CodeGen::Address addr)
const Expr * findStructFieldAccess(const Expr *E, const Expr **OutArrayIndex=nullptr, QualType *OutArrayElementTy=nullptr)
Walk E through parens, implicit casts, unary &/*, array subscripts and comma operators to find the he...
bool hasSpecificAttr(const Container &container)
@ NonNull
Values of this type can never be null.
@ Success
Annotation was successful.
Expr::ConstantExprKind ConstantExprKind
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
bool operator==(const CallGraphNode::CallRecord &LHS, const CallGraphNode::CallRecord &RHS)
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
bool isLambdaCallWithExplicitObjectParameter(const DeclContext *DC)
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)