58#include "llvm/ADT/APFixedPoint.h"
59#include "llvm/ADT/Sequence.h"
60#include "llvm/ADT/SmallBitVector.h"
61#include "llvm/ADT/StringExtras.h"
62#include "llvm/Support/Casting.h"
63#include "llvm/Support/Debug.h"
64#include "llvm/Support/SaveAndRestore.h"
65#include "llvm/Support/SipHash.h"
66#include "llvm/Support/TimeProfiler.h"
67#include "llvm/Support/raw_ostream.h"
73#define DEBUG_TYPE "exprconstant"
76using llvm::APFixedPoint;
80using llvm::FixedPointSemantics;
87 using SourceLocExprScopeGuard =
118 static unsigned countNonVirtualBases(
const CXXRecordDecl *RD) {
119 return llvm::count_if(RD->
bases(), [](
auto &B) { return !B.isVirtual(); });
126 static const CallExpr *tryUnwrapAllocSizeCall(
const Expr *E) {
134 if (
const auto *FE = dyn_cast<FullExpr>(E))
137 if (
const auto *Cast = dyn_cast<CastExpr>(E))
138 E = Cast->getSubExpr()->IgnoreParens();
140 if (
const auto *CE = dyn_cast<CallExpr>(E))
141 return CE->getCalleeAllocSizeAttr() ? CE :
nullptr;
148 const auto *E =
Base.dyn_cast<
const Expr *>();
149 return E && E->getType()->isPointerType() && tryUnwrapAllocSizeCall(E);
157 case ConstantExprKind::Normal:
158 case ConstantExprKind::ClassTemplateArgument:
159 case ConstantExprKind::ImmediateInvocation:
164 case ConstantExprKind::NonClassTemplateArgument:
167 llvm_unreachable(
"unknown ConstantExprKind");
172 case ConstantExprKind::Normal:
173 case ConstantExprKind::ImmediateInvocation:
176 case ConstantExprKind::ClassTemplateArgument:
177 case ConstantExprKind::NonClassTemplateArgument:
180 llvm_unreachable(
"unknown ConstantExprKind");
186 static const uint64_t AssumedSizeForUnsizedArray =
187 std::numeric_limits<uint64_t>::max() / 2;
197 bool &FirstEntryIsUnsizedArray) {
200 assert(!isBaseAnAllocSizeCall(
Base) &&
201 "Unsized arrays shouldn't appear here");
202 unsigned MostDerivedLength = 0;
207 for (
unsigned I = 0, N = Path.size(); I != N; ++I) {
211 MostDerivedLength = I + 1;
214 if (
auto *CAT = dyn_cast<ConstantArrayType>(AT)) {
215 ArraySize = CAT->getZExtSize();
217 assert(I == 0 &&
"unexpected unsized array designator");
218 FirstEntryIsUnsizedArray =
true;
219 ArraySize = AssumedSizeForUnsizedArray;
225 MostDerivedLength = I + 1;
228 Type = VT->getElementType();
229 ArraySize = VT->getNumElements();
230 MostDerivedLength = I + 1;
232 }
else if (
const FieldDecl *FD = getAsField(Path[I])) {
233 Type = FD->getType();
235 MostDerivedLength = I + 1;
243 return MostDerivedLength;
247 struct SubobjectDesignator {
251 LLVM_PREFERRED_TYPE(
bool)
255 LLVM_PREFERRED_TYPE(
bool)
256 unsigned IsOnePastTheEnd : 1;
259 LLVM_PREFERRED_TYPE(
bool)
260 unsigned FirstEntryIsAnUnsizedArray : 1;
263 LLVM_PREFERRED_TYPE(
bool)
264 unsigned MostDerivedIsArrayElement : 1;
268 unsigned MostDerivedPathLength : 28;
277 uint64_t MostDerivedArraySize;
286 SubobjectDesignator() :
Invalid(
true) {}
289 :
Invalid(
false), IsOnePastTheEnd(
false),
290 FirstEntryIsAnUnsizedArray(
false), MostDerivedIsArrayElement(
false),
291 MostDerivedPathLength(0), MostDerivedArraySize(0),
292 MostDerivedType(
T.isNull() ?
QualType() :
T.getNonReferenceType()) {}
295 :
Invalid(!
V.isLValue() || !
V.hasLValuePath()), IsOnePastTheEnd(
false),
296 FirstEntryIsAnUnsizedArray(
false), MostDerivedIsArrayElement(
false),
297 MostDerivedPathLength(0), MostDerivedArraySize(0) {
298 assert(
V.isLValue() &&
"Non-LValue used to make an LValue designator?");
300 IsOnePastTheEnd =
V.isLValueOnePastTheEnd();
301 llvm::append_range(Entries,
V.getLValuePath());
302 if (
V.getLValueBase()) {
303 bool IsArray =
false;
304 bool FirstIsUnsizedArray =
false;
305 MostDerivedPathLength = findMostDerivedSubobject(
306 Ctx,
V.getLValueBase(),
V.getLValuePath(), MostDerivedArraySize,
307 MostDerivedType, IsArray, FirstIsUnsizedArray);
308 MostDerivedIsArrayElement = IsArray;
309 FirstEntryIsAnUnsizedArray = FirstIsUnsizedArray;
315 unsigned NewLength) {
319 assert(
Base &&
"cannot truncate path for null pointer");
320 assert(NewLength <= Entries.size() &&
"not a truncation");
322 if (NewLength == Entries.size())
324 Entries.resize(NewLength);
326 bool IsArray =
false;
327 bool FirstIsUnsizedArray =
false;
328 MostDerivedPathLength = findMostDerivedSubobject(
329 Ctx,
Base, Entries, MostDerivedArraySize, MostDerivedType, IsArray,
330 FirstIsUnsizedArray);
331 MostDerivedIsArrayElement = IsArray;
332 FirstEntryIsAnUnsizedArray = FirstIsUnsizedArray;
342 bool isMostDerivedAnUnsizedArray()
const {
343 assert(!
Invalid &&
"Calling this makes no sense on invalid designators");
344 return Entries.size() == 1 && FirstEntryIsAnUnsizedArray;
349 uint64_t getMostDerivedArraySize()
const {
350 assert(!isMostDerivedAnUnsizedArray() &&
"Unsized array has no size");
351 return MostDerivedArraySize;
355 bool isOnePastTheEnd()
const {
359 if (!isMostDerivedAnUnsizedArray() && MostDerivedIsArrayElement &&
360 Entries[MostDerivedPathLength - 1].getAsArrayIndex() ==
361 MostDerivedArraySize)
369 std::pair<uint64_t, uint64_t> validIndexAdjustments() {
370 if (
Invalid || isMostDerivedAnUnsizedArray())
376 bool IsArray = MostDerivedPathLength == Entries.size() &&
377 MostDerivedIsArrayElement;
378 uint64_t ArrayIndex = IsArray ? Entries.back().getAsArrayIndex()
379 : (uint64_t)IsOnePastTheEnd;
381 IsArray ? getMostDerivedArraySize() : (uint64_t)1;
382 return {ArrayIndex, ArraySize - ArrayIndex};
386 bool isValidSubobject()
const {
389 return !isOnePastTheEnd();
397 assert(!
Invalid &&
"invalid designator has no subobject type");
398 return MostDerivedPathLength == Entries.size()
409 MostDerivedIsArrayElement =
true;
411 MostDerivedPathLength = Entries.size();
415 void addUnsizedArrayUnchecked(
QualType ElemTy) {
418 MostDerivedType = ElemTy;
419 MostDerivedIsArrayElement =
true;
423 MostDerivedArraySize = AssumedSizeForUnsizedArray;
424 MostDerivedPathLength = Entries.size();
428 void addDeclUnchecked(
const Decl *D,
bool Virtual =
false) {
432 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
433 MostDerivedType = FD->getType();
434 MostDerivedIsArrayElement =
false;
435 MostDerivedArraySize = 0;
436 MostDerivedPathLength = Entries.size();
440 void addComplexUnchecked(
QualType EltTy,
bool Imag) {
445 MostDerivedType = EltTy;
446 MostDerivedIsArrayElement =
true;
447 MostDerivedArraySize = 2;
448 MostDerivedPathLength = Entries.size();
451 void addVectorElementUnchecked(
QualType EltTy, uint64_t Size,
454 MostDerivedType = EltTy;
455 MostDerivedPathLength = Entries.size();
456 MostDerivedArraySize = 0;
457 MostDerivedIsArrayElement =
false;
460 void diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info,
const Expr *E);
461 void diagnosePointerArithmetic(EvalInfo &Info,
const Expr *E,
464 void adjustIndex(EvalInfo &Info,
const Expr *E,
APSInt N,
const LValue &LV);
468 enum class ScopeKind {
476 CallRef() : OrigCallee(), CallIndex(0), Version() {}
477 CallRef(
const FunctionDecl *Callee,
unsigned CallIndex,
unsigned Version)
478 : OrigCallee(Callee), CallIndex(CallIndex), Version(Version) {}
480 explicit operator bool()
const {
return OrigCallee; }
506 CallStackFrame *Caller;
528 typedef std::pair<const void *, unsigned> MapKeyTy;
529 typedef std::map<MapKeyTy, APValue>
MapTy;
541 unsigned CurTempVersion = TempVersionStack.back();
543 unsigned getTempVersion()
const {
return TempVersionStack.back(); }
545 void pushTempVersion() {
546 TempVersionStack.push_back(++CurTempVersion);
549 void popTempVersion() {
550 TempVersionStack.pop_back();
554 return {Callee, Index, ++CurTempVersion};
565 llvm::DenseMap<const ValueDecl *, FieldDecl *> LambdaCaptureFields;
566 FieldDecl *LambdaThisCaptureField =
nullptr;
568 CallStackFrame(EvalInfo &Info,
SourceRange CallRange,
574 APValue *getTemporary(
const void *Key,
unsigned Version) {
575 MapKeyTy KV(Key, Version);
576 auto LB = Temporaries.lower_bound(KV);
577 if (LB != Temporaries.end() && LB->first == KV)
583 APValue *getCurrentTemporary(
const void *Key) {
584 auto UB = Temporaries.upper_bound(MapKeyTy(Key,
UINT_MAX));
585 if (UB != Temporaries.begin() && std::prev(UB)->first.first == Key)
586 return &std::prev(UB)->second;
591 unsigned getCurrentTemporaryVersion(
const void *Key)
const {
592 auto UB = Temporaries.upper_bound(MapKeyTy(Key,
UINT_MAX));
593 if (UB != Temporaries.begin() && std::prev(UB)->first.first == Key)
594 return std::prev(UB)->first.second;
602 template<
typename KeyT>
604 ScopeKind
Scope, LValue &LV);
609 void describe(llvm::raw_ostream &OS)
const override;
611 Frame *getCaller()
const override {
return Caller; }
612 SourceRange getCallRange()
const override {
return CallRange; }
615 bool isStdFunction()
const {
616 for (
const DeclContext *DC = Callee; DC; DC = DC->getParent())
617 if (DC->isStdNamespace())
624 bool CanEvalMSConstexpr =
false;
632 class ThisOverrideRAII {
634 ThisOverrideRAII(CallStackFrame &Frame,
const LValue *NewThis,
bool Enable)
635 : Frame(Frame), OldThis(Frame.This) {
637 Frame.This = NewThis;
639 ~ThisOverrideRAII() {
640 Frame.This = OldThis;
643 CallStackFrame &Frame;
644 const LValue *OldThis;
649 class ExprTimeTraceScope {
651 ExprTimeTraceScope(
const Expr *E,
const ASTContext &Ctx, StringRef Name)
652 : TimeScope(Name, [E, &Ctx] {
657 llvm::TimeTraceScope TimeScope;
662 struct MSConstexprContextRAII {
663 CallStackFrame &Frame;
665 explicit MSConstexprContextRAII(CallStackFrame &Frame,
bool Value)
666 : Frame(Frame), OldValue(Frame.CanEvalMSConstexpr) {
667 Frame.CanEvalMSConstexpr =
Value;
670 ~MSConstexprContextRAII() { Frame.CanEvalMSConstexpr = OldValue; }
683 llvm::PointerIntPair<APValue*, 2, ScopeKind> Value;
684 APValue::LValueBase Base;
688 Cleanup(
APValue *Val, APValue::LValueBase Base, QualType T,
690 : Value(Val, Scope), Base(Base), T(T) {}
694 bool isDestroyedAtEndOf(ScopeKind K)
const {
695 return (
int)Value.getInt() >= (
int)K;
697 bool endLifetime(EvalInfo &Info,
bool RunDestructors) {
698 if (RunDestructors) {
700 if (
const ValueDecl *VD = Base.dyn_cast<
const ValueDecl*>())
701 Loc = VD->getLocation();
702 else if (
const Expr *E = Base.dyn_cast<
const Expr*>())
703 Loc = E->getExprLoc();
706 *Value.getPointer() =
APValue();
710 bool hasSideEffect() {
711 return T.isDestructedType();
716 struct ObjectUnderConstruction {
717 APValue::LValueBase Base;
718 ArrayRef<APValue::LValuePathEntry> Path;
719 friend bool operator==(
const ObjectUnderConstruction &LHS,
720 const ObjectUnderConstruction &RHS) {
721 return LHS.Base == RHS.Base && LHS.Path == RHS.Path;
723 friend llvm::hash_code
hash_value(
const ObjectUnderConstruction &Obj) {
724 return llvm::hash_combine(Obj.Base, Obj.Path);
727 enum class ConstructionPhase {
738template<>
struct DenseMapInfo<ObjectUnderConstruction> {
739 using Base = DenseMapInfo<APValue::LValueBase>;
743 static bool isEqual(
const ObjectUnderConstruction &LHS,
744 const ObjectUnderConstruction &RHS) {
758 const Expr *AllocExpr =
nullptr;
769 if (
auto *NE = dyn_cast<CXXNewExpr>(AllocExpr))
770 return NE->isArray() ? ArrayNew : New;
776 struct DynAllocOrder {
777 bool operator()(DynamicAllocLValue L, DynamicAllocLValue R)
const {
799 CallStackFrame *CurrentCall;
802 unsigned CallStackDepth;
805 unsigned NextCallIndex;
814 bool EnableNewConstInterp;
818 CallStackFrame BottomFrame;
822 llvm::SmallVector<Cleanup, 16> CleanupStack;
826 APValue::LValueBase EvaluatingDecl;
828 enum class EvaluatingDeclKind {
835 EvaluatingDeclKind IsEvaluatingDecl = EvaluatingDeclKind::None;
844 SmallVector<const Stmt *> BreakContinueStack;
847 llvm::DenseMap<ObjectUnderConstruction, ConstructionPhase>
848 ObjectsUnderConstruction;
853 std::map<DynamicAllocLValue, DynAlloc, DynAllocOrder> HeapAllocs;
856 unsigned NumHeapAllocs = 0;
858 struct EvaluatingConstructorRAII {
860 ObjectUnderConstruction Object;
862 EvaluatingConstructorRAII(EvalInfo &EI, ObjectUnderConstruction Object,
864 : EI(EI), Object(Object) {
866 EI.ObjectsUnderConstruction
867 .insert({Object, HasBases ? ConstructionPhase::Bases
868 : ConstructionPhase::AfterBases})
871 void finishedConstructingBases() {
872 EI.ObjectsUnderConstruction[Object] = ConstructionPhase::AfterBases;
874 void finishedConstructingFields() {
875 EI.ObjectsUnderConstruction[Object] = ConstructionPhase::AfterFields;
877 ~EvaluatingConstructorRAII() {
878 if (DidInsert) EI.ObjectsUnderConstruction.erase(Object);
882 struct EvaluatingDestructorRAII {
884 ObjectUnderConstruction Object;
886 EvaluatingDestructorRAII(EvalInfo &EI, ObjectUnderConstruction Object)
887 : EI(EI), Object(Object) {
888 DidInsert = EI.ObjectsUnderConstruction
889 .insert({Object, ConstructionPhase::Destroying})
892 void startedDestroyingBases() {
893 EI.ObjectsUnderConstruction[Object] =
894 ConstructionPhase::DestroyingBases;
896 ~EvaluatingDestructorRAII() {
898 EI.ObjectsUnderConstruction.erase(Object);
903 isEvaluatingCtorDtor(APValue::LValueBase Base,
904 ArrayRef<APValue::LValuePathEntry> Path) {
905 return ObjectsUnderConstruction.lookup({
Base, Path});
910 unsigned SpeculativeEvaluationDepth = 0;
916 EvalInfo(
const ASTContext &
C, Expr::EvalStatus &S,
EvaluationMode Mode)
917 : State(const_cast<ASTContext &>(
C), S), CurrentCall(
nullptr),
918 CallStackDepth(0), NextCallIndex(1),
919 StepsLeft(
C.getLangOpts().ConstexprStepLimit),
920 EnableNewConstInterp(
C.getLangOpts().EnableNewConstInterp),
921 BottomFrame(*this, SourceLocation(),
nullptr,
924 EvaluatingDecl((const ValueDecl *)
nullptr),
933 void setEvaluatingDecl(APValue::LValueBase Base,
APValue &
Value,
934 EvaluatingDeclKind EDK = EvaluatingDeclKind::Ctor) {
935 EvaluatingDecl =
Base;
936 IsEvaluatingDecl = EDK;
937 EvaluatingDeclValue = &
Value;
940 bool CheckCallLimit(SourceLocation Loc) {
943 if (checkingPotentialConstantExpression() && CallStackDepth > 1)
945 if (NextCallIndex == 0) {
947 FFDiag(Loc, diag::note_constexpr_call_limit_exceeded);
950 if (CallStackDepth <= getLangOpts().ConstexprCallDepth)
952 FFDiag(Loc, diag::note_constexpr_depth_limit_exceeded)
953 << getLangOpts().ConstexprCallDepth;
958 uint64_t ElemCount,
bool Diag) {
964 ElemCount >
uint64_t(std::numeric_limits<unsigned>::max())) {
966 FFDiag(Loc, diag::note_constexpr_new_too_large) << ElemCount;
975 uint64_t Limit = getLangOpts().ConstexprStepLimit;
976 if (Limit != 0 && ElemCount > Limit) {
978 FFDiag(Loc, diag::note_constexpr_new_exceeds_limits, 1)
979 << ElemCount << Limit;
980 Note(Loc, diag::note_constexpr_steps);
987 std::pair<CallStackFrame *, unsigned>
988 getCallFrameAndDepth(
unsigned CallIndex) {
989 assert(CallIndex &&
"no call index in getCallFrameAndDepth");
992 unsigned Depth = CallStackDepth;
993 CallStackFrame *Frame = CurrentCall;
994 while (Frame->Index > CallIndex) {
995 Frame = Frame->Caller;
998 if (Frame->Index == CallIndex)
999 return {Frame, Depth};
1000 return {
nullptr, 0};
1003 bool nextStep(
const Stmt *S) {
1004 if (getLangOpts().ConstexprStepLimit == 0)
1008 FFDiag(S->
getBeginLoc(), diag::note_constexpr_step_limit_exceeded, 1)
1009 << getLangOpts().ConstexprStepLimit;
1017 APValue *createHeapAlloc(
const Expr *E, QualType
T, LValue &LV);
1019 std::optional<DynAlloc *> lookupDynamicAlloc(DynamicAllocLValue DA) {
1020 std::optional<DynAlloc *>
Result;
1021 auto It = HeapAllocs.find(DA);
1022 if (It != HeapAllocs.end())
1028 APValue *getParamSlot(CallRef
Call,
const ParmVarDecl *PVD) {
1029 CallStackFrame *Frame = getCallFrameAndDepth(
Call.CallIndex).first;
1030 return Frame ? Frame->getTemporary(
Call.getOrigParam(PVD),
Call.Version)
1035 struct StdAllocatorCaller {
1036 unsigned FrameIndex;
1039 explicit operator bool()
const {
return FrameIndex != 0; };
1042 StdAllocatorCaller getStdAllocatorCaller(StringRef FnName)
const {
1043 for (
const CallStackFrame *
Call = CurrentCall;
Call->Caller !=
nullptr;
1045 const auto *MD = dyn_cast_or_null<CXXMethodDecl>(
Call->Callee);
1048 const IdentifierInfo *FnII = MD->getIdentifier();
1049 if (!FnII || !FnII->
isStr(FnName))
1053 dyn_cast<ClassTemplateSpecializationDecl>(MD->getParent());
1057 const IdentifierInfo *ClassII = CTSD->getIdentifier();
1058 const TemplateArgumentList &TAL = CTSD->getTemplateArgs();
1059 if (CTSD->isInStdNamespace() && ClassII &&
1060 ClassII->
isStr(
"allocator") && TAL.
size() >= 1 &&
1062 return {
Call->Index, TAL[0].getAsType(),
Call->CallExpr};
1068 void performLifetimeExtension() {
1070 llvm::erase_if(CleanupStack, [](Cleanup &
C) {
1071 return !
C.isDestroyedAtEndOf(ScopeKind::FullExpression);
1078 bool discardCleanups() {
1079 for (Cleanup &
C : CleanupStack) {
1080 if (
C.hasSideEffect() && !noteSideEffect()) {
1081 CleanupStack.clear();
1085 CleanupStack.clear();
1090 const interp::Frame *getCurrentFrame()
override {
return CurrentCall; }
1092 unsigned getCallStackDepth()
override {
return CallStackDepth; }
1093 bool stepsLeft()
const override {
return StepsLeft > 0; }
1106 [[nodiscard]]
bool noteFailure() {
1114 bool KeepGoing = keepEvaluatingAfterFailure();
1115 EvalStatus.HasSideEffects |= KeepGoing;
1119 class ArrayInitLoopIndex {
1124 ArrayInitLoopIndex(EvalInfo &Info)
1125 : Info(Info), OuterIndex(Info.ArrayInitIndex) {
1126 Info.ArrayInitIndex = 0;
1128 ~ArrayInitLoopIndex() { Info.ArrayInitIndex = OuterIndex; }
1130 operator uint64_t&() {
return Info.ArrayInitIndex; }
1135 struct FoldConstant {
1138 bool HadNoPriorDiags;
1141 explicit FoldConstant(EvalInfo &Info,
bool Enabled)
1144 HadNoPriorDiags(Info.EvalStatus.
Diag &&
1145 Info.EvalStatus.
Diag->empty() &&
1146 !Info.EvalStatus.HasSideEffects),
1147 OldMode(Info.EvalMode) {
1149 Info.EvalMode = EvaluationMode::ConstantFold;
1151 void keepDiagnostics() { Enabled =
false; }
1153 if (Enabled && HadNoPriorDiags && !Info.EvalStatus.Diag->empty() &&
1154 !Info.EvalStatus.HasSideEffects) {
1155 Info.EvalStatus.Diag->clear();
1156 Info.EvalStatus.DiagEmitted =
false;
1158 Info.EvalMode = OldMode;
1164 struct IgnoreSideEffectsRAII {
1167 explicit IgnoreSideEffectsRAII(EvalInfo &Info)
1168 : Info(Info), OldMode(Info.EvalMode) {
1169 Info.EvalMode = EvaluationMode::IgnoreSideEffects;
1172 ~IgnoreSideEffectsRAII() { Info.EvalMode = OldMode; }
1177 class SpeculativeEvaluationRAII {
1178 EvalInfo *Info =
nullptr;
1179 Expr::EvalStatus OldStatus;
1180 unsigned OldSpeculativeEvaluationDepth = 0;
1182 void moveFromAndCancel(SpeculativeEvaluationRAII &&
Other) {
1184 OldStatus =
Other.OldStatus;
1185 OldSpeculativeEvaluationDepth =
Other.OldSpeculativeEvaluationDepth;
1186 Other.Info =
nullptr;
1189 void maybeRestoreState() {
1193 Info->EvalStatus = OldStatus;
1194 Info->SpeculativeEvaluationDepth = OldSpeculativeEvaluationDepth;
1198 SpeculativeEvaluationRAII() =
default;
1200 SpeculativeEvaluationRAII(
1201 EvalInfo &Info, SmallVectorImpl<PartialDiagnosticAt> *NewDiag =
nullptr)
1202 : Info(&Info), OldStatus(Info.EvalStatus),
1203 OldSpeculativeEvaluationDepth(Info.SpeculativeEvaluationDepth) {
1204 Info.EvalStatus.Diag = NewDiag;
1205 Info.SpeculativeEvaluationDepth = Info.CallStackDepth + 1;
1208 SpeculativeEvaluationRAII(
const SpeculativeEvaluationRAII &
Other) =
delete;
1209 SpeculativeEvaluationRAII(SpeculativeEvaluationRAII &&
Other) {
1210 moveFromAndCancel(std::move(
Other));
1213 SpeculativeEvaluationRAII &operator=(SpeculativeEvaluationRAII &&
Other) {
1214 maybeRestoreState();
1215 moveFromAndCancel(std::move(
Other));
1219 ~SpeculativeEvaluationRAII() { maybeRestoreState(); }
1224 template<ScopeKind Kind>
1227 unsigned OldStackSize;
1229 ScopeRAII(EvalInfo &Info)
1230 : Info(Info), OldStackSize(Info.CleanupStack.size()) {
1233 Info.CurrentCall->pushTempVersion();
1235 bool destroy(
bool RunDestructors =
true) {
1236 bool OK =
cleanup(Info, RunDestructors, OldStackSize);
1237 OldStackSize = std::numeric_limits<unsigned>::max();
1241 if (OldStackSize != std::numeric_limits<unsigned>::max())
1245 Info.CurrentCall->popTempVersion();
1248 static bool cleanup(EvalInfo &Info,
bool RunDestructors,
1249 unsigned OldStackSize) {
1250 assert(OldStackSize <= Info.CleanupStack.size() &&
1251 "running cleanups out of order?");
1256 for (
unsigned I = Info.CleanupStack.size(); I > OldStackSize; --I) {
1257 if (Info.CleanupStack[I - 1].isDestroyedAtEndOf(Kind)) {
1258 if (!Info.CleanupStack[I - 1].endLifetime(Info, RunDestructors)) {
1266 auto NewEnd = Info.CleanupStack.begin() + OldStackSize;
1267 if (Kind != ScopeKind::Block)
1269 std::remove_if(NewEnd, Info.CleanupStack.end(), [](Cleanup &
C) {
1270 return C.isDestroyedAtEndOf(Kind);
1272 Info.CleanupStack.erase(NewEnd, Info.CleanupStack.end());
1276 typedef ScopeRAII<ScopeKind::Block> BlockScopeRAII;
1277 typedef ScopeRAII<ScopeKind::FullExpression> FullExpressionRAII;
1278 typedef ScopeRAII<ScopeKind::Call> CallScopeRAII;
1281bool SubobjectDesignator::checkSubobject(EvalInfo &Info,
const Expr *E,
1285 if (isOnePastTheEnd()) {
1286 Info.CCEDiag(E, diag::note_constexpr_past_end_subobject)
1297void SubobjectDesignator::diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info,
1299 Info.CCEDiag(E, diag::note_constexpr_unsized_array_indexed);
1304void SubobjectDesignator::diagnosePointerArithmetic(EvalInfo &Info,
1309 if (MostDerivedPathLength == Entries.size() && MostDerivedIsArrayElement)
1310 Info.CCEDiag(E, diag::note_constexpr_array_index)
1312 <<
static_cast<unsigned>(getMostDerivedArraySize());
1314 Info.CCEDiag(E, diag::note_constexpr_array_index)
1319CallStackFrame::CallStackFrame(EvalInfo &Info, SourceRange CallRange,
1320 const FunctionDecl *Callee,
const LValue *This,
1321 const Expr *CallExpr, CallRef Call)
1323 CallExpr(CallExpr),
Arguments(Call), CallRange(CallRange),
1324 Index(Info.NextCallIndex++) {
1325 Info.CurrentCall =
this;
1326 ++Info.CallStackDepth;
1329CallStackFrame::~CallStackFrame() {
1330 assert(Info.CurrentCall ==
this &&
"calls retired out of order");
1331 --Info.CallStackDepth;
1332 Info.CurrentCall = Caller;
1357 llvm_unreachable(
"unknown access kind");
1394 llvm_unreachable(
"unknown access kind");
1398 struct ComplexValue {
1406 ComplexValue() : FloatReal(
APFloat::Bogus()), FloatImag(
APFloat::Bogus()) {}
1408 void makeComplexFloat() { IsInt =
false; }
1409 bool isComplexFloat()
const {
return !IsInt; }
1410 APFloat &getComplexFloatReal() {
return FloatReal; }
1411 APFloat &getComplexFloatImag() {
return FloatImag; }
1413 void makeComplexInt() { IsInt =
true; }
1414 bool isComplexInt()
const {
return IsInt; }
1415 APSInt &getComplexIntReal() {
return IntReal; }
1416 APSInt &getComplexIntImag() {
return IntImag; }
1418 void moveInto(
APValue &v)
const {
1419 if (isComplexFloat())
1420 v =
APValue(FloatReal, FloatImag);
1422 v =
APValue(IntReal, IntImag);
1424 void setFrom(
const APValue &v) {
1439 APValue::LValueBase
Base;
1441 SubobjectDesignator Designator;
1443 bool InvalidBase : 1;
1445 bool AllowConstexprUnknown =
false;
1447 const APValue::LValueBase getLValueBase()
const {
return Base; }
1448 bool allowConstexprUnknown()
const {
return AllowConstexprUnknown; }
1449 CharUnits &getLValueOffset() {
return Offset; }
1450 const CharUnits &getLValueOffset()
const {
return Offset; }
1451 SubobjectDesignator &getLValueDesignator() {
return Designator; }
1452 const SubobjectDesignator &getLValueDesignator()
const {
return Designator;}
1453 bool isNullPointer()
const {
return IsNullPtr;}
1455 unsigned getLValueCallIndex()
const {
return Base.getCallIndex(); }
1456 unsigned getLValueVersion()
const {
return Base.getVersion(); }
1458 bool pointsToCompleteClass(
const CXXRecordDecl *D)
const {
1459 if (Designator.Entries.empty())
1466 if (Designator.Invalid)
1467 V =
APValue(Base, Offset, APValue::NoLValuePath(), IsNullPtr);
1469 assert(!InvalidBase &&
"APValues can't handle invalid LValue bases");
1470 V =
APValue(Base, Offset, Designator.Entries,
1471 Designator.IsOnePastTheEnd, IsNullPtr);
1473 if (AllowConstexprUnknown)
1474 V.setConstexprUnknown();
1476 void setFrom(
const ASTContext &Ctx,
const APValue &
V) {
1477 assert(
V.isLValue() &&
"Setting LValue from a non-LValue?");
1478 Base =
V.getLValueBase();
1479 Offset =
V.getLValueOffset();
1480 InvalidBase =
false;
1481 Designator = SubobjectDesignator(Ctx,
V);
1482 IsNullPtr =
V.isNullPointer();
1483 AllowConstexprUnknown =
V.allowConstexprUnknown();
1486 void set(APValue::LValueBase B,
bool BInvalid =
false) {
1490 const auto *E = B.
get<
const Expr *>();
1492 "Unexpected type of invalid base");
1498 InvalidBase = BInvalid;
1499 Designator = SubobjectDesignator(
getType(B));
1501 AllowConstexprUnknown =
false;
1504 void setNull(ASTContext &Ctx, QualType PointerTy) {
1505 Base = (
const ValueDecl *)
nullptr;
1508 InvalidBase =
false;
1511 AllowConstexprUnknown =
false;
1514 void setInvalid(APValue::LValueBase B,
unsigned I = 0) {
1518 std::string
toString(ASTContext &Ctx, QualType
T)
const {
1520 moveInto(Printable);
1527 template <
typename GenDiagType>
1528 bool checkNullPointerDiagnosingWith(
const GenDiagType &GenDiag) {
1529 if (Designator.Invalid)
1533 Designator.setInvalid();
1540 bool checkNullPointer(EvalInfo &Info,
const Expr *E,
1542 return checkNullPointerDiagnosingWith([&Info, E, CSK] {
1543 Info.CCEDiag(E, diag::note_constexpr_null_subobject) << CSK;
1547 bool checkNullPointerForFoldAccess(EvalInfo &Info,
const Expr *E,
1549 return checkNullPointerDiagnosingWith([&Info, E, AK] {
1550 if (AK == AccessKinds::AK_Dereference)
1551 Info.FFDiag(E, diag::note_constexpr_dereferencing_null);
1553 Info.FFDiag(E, diag::note_constexpr_access_null) << AK;
1561 Designator.checkSubobject(Info, E, CSK);
1564 void addDecl(EvalInfo &Info,
const Expr *E,
1565 const Decl *D,
bool Virtual =
false) {
1567 Designator.addDeclUnchecked(D,
Virtual);
1569 void addUnsizedArray(EvalInfo &Info,
const Expr *E, QualType ElemTy) {
1570 if (!Designator.Entries.empty()) {
1571 Info.CCEDiag(E, diag::note_constexpr_unsupported_unsized_array);
1572 Designator.setInvalid();
1576 assert(!Base ||
getType(Base).getNonReferenceType()->isPointerType() ||
1577 getType(Base).getNonReferenceType()->isArrayType());
1578 Designator.FirstEntryIsAnUnsizedArray =
true;
1579 Designator.addUnsizedArrayUnchecked(ElemTy);
1582 void addArray(EvalInfo &Info,
const Expr *E,
const ConstantArrayType *CAT) {
1584 Designator.addArrayUnchecked(CAT);
1586 void addComplex(EvalInfo &Info,
const Expr *E, QualType EltTy,
bool Imag) {
1588 Designator.addComplexUnchecked(EltTy, Imag);
1590 void addVectorElement(EvalInfo &Info,
const Expr *E, QualType EltTy,
1591 uint64_t Size, uint64_t Idx) {
1593 Designator.addVectorElementUnchecked(EltTy, Size, Idx);
1595 void clearIsNullPointer() {
1598 void adjustOffsetAndIndex(EvalInfo &Info,
const Expr *E,
1599 const APSInt &Index, CharUnits ElementSize) {
1610 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
1614 Designator.adjustIndex(Info, E, Index, *
this);
1615 clearIsNullPointer();
1617 void adjustOffset(CharUnits N) {
1620 clearIsNullPointer();
1626 explicit MemberPtr(
const ValueDecl *Decl)
1627 : DeclAndIsDerivedMember(
Decl,
false) {}
1631 const ValueDecl *getDecl()
const {
1632 return DeclAndIsDerivedMember.getPointer();
1635 bool isDerivedMember()
const {
1636 return DeclAndIsDerivedMember.getInt();
1639 const CXXRecordDecl *getContainingRecord()
const {
1641 DeclAndIsDerivedMember.getPointer()->getDeclContext());
1645 V =
APValue(getDecl(), isDerivedMember(), Path);
1648 assert(
V.isMemberPointer());
1649 DeclAndIsDerivedMember.setPointer(
V.getMemberPointerDecl());
1650 DeclAndIsDerivedMember.setInt(
V.isMemberPointerToDerivedMember());
1652 llvm::append_range(Path,
V.getMemberPointerPath());
1658 llvm::PointerIntPair<const ValueDecl*, 1, bool> DeclAndIsDerivedMember;
1661 SmallVector<const CXXRecordDecl*, 4> Path;
1665 bool castBack(
const CXXRecordDecl *
Class) {
1666 assert(!Path.empty());
1667 const CXXRecordDecl *Expected;
1668 if (Path.size() >= 2)
1669 Expected = Path[Path.size() - 2];
1671 Expected = getContainingRecord();
1685 bool castToDerived(
const CXXRecordDecl *Derived) {
1688 if (!isDerivedMember()) {
1689 Path.push_back(Derived);
1692 if (!castBack(Derived))
1695 DeclAndIsDerivedMember.setInt(
false);
1703 DeclAndIsDerivedMember.setInt(
true);
1704 if (isDerivedMember()) {
1705 Path.push_back(Base);
1708 return castBack(Base);
1713 static bool operator==(
const MemberPtr &LHS,
const MemberPtr &RHS) {
1714 if (!LHS.getDecl() || !RHS.getDecl())
1715 return !LHS.getDecl() && !RHS.getDecl();
1716 if (LHS.getDecl()->getCanonicalDecl() != RHS.getDecl()->getCanonicalDecl())
1718 return LHS.Path == RHS.Path;
1722void SubobjectDesignator::adjustIndex(EvalInfo &Info,
const Expr *E,
APSInt N,
1726 uint64_t TruncatedN = N.extOrTrunc(64).getZExtValue();
1727 if (isMostDerivedAnUnsizedArray()) {
1728 diagnoseUnsizedArrayPointerArithmetic(Info, E);
1733 PathEntry::ArrayIndex(Entries.back().getAsArrayIndex() + TruncatedN);
1741 MostDerivedPathLength == Entries.size() && MostDerivedIsArrayElement;
1743 IsArray ? Entries.back().getAsArrayIndex() : (
uint64_t)IsOnePastTheEnd;
1746 if (N < -(int64_t)ArrayIndex || N > ArraySize - ArrayIndex) {
1747 if (!Info.checkingPotentialConstantExpression() ||
1748 !LV.AllowConstexprUnknown) {
1751 N = N.extend(std::max<unsigned>(N.getBitWidth() + 1, 65));
1752 (llvm::APInt &)N += ArrayIndex;
1753 assert(N.ugt(ArraySize) &&
"bounds check failed for in-bounds index");
1754 diagnosePointerArithmetic(Info, E, N);
1760 ArrayIndex += TruncatedN;
1761 assert(ArrayIndex <= ArraySize &&
1762 "bounds check succeeded for out-of-bounds index");
1765 Entries.back() = PathEntry::ArrayIndex(ArrayIndex);
1767 IsOnePastTheEnd = (ArrayIndex != 0);
1772 const LValue &This,
const Expr *E,
1773 bool AllowNonLiteralTypes =
false);
1775 bool InvalidBaseOK =
false);
1777 bool InvalidBaseOK =
false);
1785static bool EvaluateComplex(
const Expr *E, ComplexValue &Res, EvalInfo &Info);
1790static std::optional<uint64_t>
1792 std::string *StringResult =
nullptr);
1809 if (Int.isUnsigned() || Int.isMinSignedValue()) {
1810 Int = Int.extend(Int.getBitWidth() + 1);
1811 Int.setIsSigned(
true);
1816template<
typename KeyT>
1817APValue &CallStackFrame::createTemporary(
const KeyT *Key, QualType
T,
1818 ScopeKind Scope, LValue &LV) {
1819 unsigned Version = getTempVersion();
1820 APValue::LValueBase
Base(Key, Index, Version);
1822 return createLocal(Base, Key,
T, Scope);
1826APValue &CallStackFrame::createParam(CallRef Args,
const ParmVarDecl *PVD,
1828 assert(Args.CallIndex == Index &&
"creating parameter in wrong frame");
1829 APValue::LValueBase
Base(PVD, Index, Args.Version);
1834 return createLocal(Base, PVD, PVD->
getType(), ScopeKind::Call);
1837APValue &CallStackFrame::createLocal(APValue::LValueBase Base,
const void *Key,
1838 QualType
T, ScopeKind Scope) {
1839 assert(
Base.getCallIndex() == Index &&
"lvalue for wrong frame");
1840 unsigned Version =
Base.getVersion();
1842 assert(
Result.isAbsent() &&
"local created multiple times");
1848 if (Index <= Info.SpeculativeEvaluationDepth) {
1849 if (
T.isDestructedType())
1850 Info.noteSideEffect();
1852 Info.CleanupStack.push_back(Cleanup(&
Result, Base,
T, Scope));
1857APValue *EvalInfo::createHeapAlloc(
const Expr *E, QualType
T, LValue &LV) {
1859 FFDiag(E, diag::note_constexpr_heap_alloc_limit_exceeded);
1863 DynamicAllocLValue DA(NumHeapAllocs++);
1865 auto Result = HeapAllocs.emplace(std::piecewise_construct,
1866 std::forward_as_tuple(DA), std::tuple<>());
1867 assert(
Result.second &&
"reused a heap alloc index?");
1868 Result.first->second.AllocExpr = E;
1869 return &
Result.first->second.Value;
1873void CallStackFrame::describe(raw_ostream &Out)
const {
1874 bool IsMemberCall =
false;
1875 bool ExplicitInstanceParam =
false;
1876 clang::PrintingPolicy PrintingPolicy = Info.Ctx.getPrintingPolicy();
1879 if (
const auto *MD = dyn_cast<CXXMethodDecl>(Callee)) {
1881 ExplicitInstanceParam = MD->isExplicitObjectMemberFunction();
1885 Callee->getNameForDiagnostic(Out, PrintingPolicy,
1888 if (This && IsMemberCall) {
1889 if (
const auto *MCE = dyn_cast_if_present<CXXMemberCallExpr>(CallExpr)) {
1890 const Expr *
Object = MCE->getImplicitObjectArgument();
1891 Object->printPretty(Out,
nullptr, PrintingPolicy,
1893 if (
Object->getType()->isPointerType())
1897 }
else if (
const auto *OCE =
1898 dyn_cast_if_present<CXXOperatorCallExpr>(CallExpr)) {
1899 OCE->getArg(0)->printPretty(Out,
nullptr, PrintingPolicy,
1904 This->moveInto(Val);
1907 Info.Ctx.getLValueReferenceType(
This->Designator.MostDerivedType));
1910 Callee->getNameForDiagnostic(Out, PrintingPolicy,
1916 llvm::ListSeparator
Comma;
1917 for (
const ParmVarDecl *Param :
1918 Callee->parameters().slice(ExplicitInstanceParam)) {
1920 const APValue *
V = Info.getParamSlot(Arguments, Param);
1922 V->printPretty(Out, Info.Ctx, Param->getType());
1938 return Info.noteSideEffect();
1945 return (
Builtin == Builtin::BI__builtin___CFStringMakeConstantString ||
1946 Builtin == Builtin::BI__builtin___NSStringMakeConstantString ||
1947 Builtin == Builtin::BI__builtin_ptrauth_sign_constant ||
1948 Builtin == Builtin::BI__builtin_function_start);
1952 const auto *BaseExpr =
1953 llvm::dyn_cast_if_present<CallExpr>(LVal.Base.
dyn_cast<
const Expr *>());
1968 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
1969 return VD->hasGlobalStorage();
1985 case Expr::CompoundLiteralExprClass: {
1989 case Expr::MaterializeTemporaryExprClass:
1994 case Expr::StringLiteralClass:
1995 case Expr::PredefinedExprClass:
1996 case Expr::ObjCStringLiteralClass:
1997 case Expr::ObjCEncodeExprClass:
1999 case Expr::ObjCBoxedExprClass:
2000 case Expr::ObjCArrayLiteralClass:
2001 case Expr::ObjCDictionaryLiteralClass:
2003 case Expr::CallExprClass:
2006 case Expr::AddrLabelExprClass:
2010 case Expr::BlockExprClass:
2014 case Expr::SourceLocExprClass:
2016 case Expr::ImplicitValueInitExprClass:
2041 const auto *BaseExpr = LVal.Base.
dyn_cast<
const Expr *>();
2046 if (
const auto *EE = dyn_cast<ObjCEncodeExpr>(BaseExpr)) {
2047 Info.Ctx.getObjCEncodingForType(EE->getEncodedType(),
2055 const auto *Lit = dyn_cast<StringLiteral>(BaseExpr);
2056 if (
const auto *PE = dyn_cast<PredefinedExpr>(BaseExpr))
2057 Lit = PE->getFunctionName();
2062 AsString.
Bytes = Lit->getBytes();
2063 AsString.
CharWidth = Lit->getCharByteWidth();
2083 const LValue &RHS) {
2092 CharUnits Offset = RHS.Offset - LHS.Offset;
2093 if (Offset.isNegative()) {
2094 if (LHSString.
Bytes.size() < (
size_t)-Offset.getQuantity())
2096 LHSString.
Bytes = LHSString.
Bytes.drop_front(-Offset.getQuantity());
2098 if (RHSString.
Bytes.size() < (
size_t)Offset.getQuantity())
2100 RHSString.
Bytes = RHSString.
Bytes.drop_front(Offset.getQuantity());
2103 bool LHSIsLonger = LHSString.
Bytes.size() > RHSString.
Bytes.size();
2104 StringRef Longer = LHSIsLonger ? LHSString.
Bytes : RHSString.
Bytes;
2105 StringRef Shorter = LHSIsLonger ? RHSString.
Bytes : LHSString.
Bytes;
2106 int ShorterCharWidth = (LHSIsLonger ? RHSString : LHSString).CharWidth;
2111 for (
int NullByte : llvm::seq(ShorterCharWidth)) {
2112 if (Shorter.size() + NullByte >= Longer.size())
2114 if (Longer[Shorter.size() + NullByte])
2120 return Shorter == Longer.take_front(Shorter.size());
2130 if (isa_and_nonnull<VarDecl>(
Decl)) {
2140 if (!A.getLValueBase())
2141 return !B.getLValueBase();
2142 if (!B.getLValueBase())
2145 if (A.getLValueBase().getOpaqueValue() !=
2146 B.getLValueBase().getOpaqueValue())
2149 return A.getLValueCallIndex() == B.getLValueCallIndex() &&
2150 A.getLValueVersion() == B.getLValueVersion();
2154 assert(
Base &&
"no location for a null lvalue");
2160 if (
auto *PVD = dyn_cast_or_null<ParmVarDecl>(VD)) {
2162 for (CallStackFrame *F = Info.CurrentCall; F; F = F->Caller) {
2163 if (F->Arguments.CallIndex ==
Base.getCallIndex() &&
2164 F->Arguments.Version ==
Base.getVersion() && F->Callee &&
2165 Idx < F->Callee->getNumParams()) {
2166 VD = F->Callee->getParamDecl(Idx);
2173 Info.Note(VD->
getLocation(), diag::note_declared_at);
2175 Info.Note(E->
getExprLoc(), diag::note_constexpr_temporary_here);
2178 if (std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA))
2179 Info.Note((*Alloc)->AllocExpr->getExprLoc(),
2180 diag::note_constexpr_dynamic_alloc_here);
2202 bool IsCompleteClass =
true);
2214 const SubobjectDesignator &
Designator = LVal.getLValueDesignator();
2222 if (isTemplateArgument(Kind)) {
2223 int InvalidBaseKind = -1;
2226 InvalidBaseKind = 0;
2227 else if (isa_and_nonnull<StringLiteral>(BaseE))
2228 InvalidBaseKind = 1;
2229 else if (isa_and_nonnull<MaterializeTemporaryExpr>(BaseE) ||
2230 isa_and_nonnull<LifetimeExtendedTemporaryDecl>(BaseVD))
2231 InvalidBaseKind = 2;
2232 else if (
auto *PE = dyn_cast_or_null<PredefinedExpr>(BaseE)) {
2233 InvalidBaseKind = 3;
2234 Ident = PE->getIdentKindName();
2237 if (InvalidBaseKind != -1) {
2238 Info.FFDiag(Loc, diag::note_constexpr_invalid_template_arg)
2239 << IsReferenceType << !
Designator.Entries.empty() << InvalidBaseKind
2245 if (
auto *FD = dyn_cast_or_null<FunctionDecl>(BaseVD);
2246 FD && FD->isImmediateFunction()) {
2247 Info.FFDiag(Loc, diag::note_consteval_address_accessible)
2249 Info.Note(FD->getLocation(), diag::note_declared_at);
2257 if (Info.getLangOpts().CPlusPlus11) {
2258 Info.FFDiag(Loc, diag::note_constexpr_non_global, 1)
2259 << IsReferenceType << !
Designator.Entries.empty() << !!BaseVD
2261 auto *VarD = dyn_cast_or_null<VarDecl>(BaseVD);
2262 if (VarD && VarD->isConstexpr()) {
2268 Info.Note(VarD->getLocation(), diag::note_constexpr_not_static)
2280 assert((Info.checkingPotentialConstantExpression() ||
2281 LVal.getLValueCallIndex() == 0) &&
2282 "have call index for global lvalue");
2284 if (LVal.allowConstexprUnknown()) {
2286 Info.FFDiag(Loc, diag::note_constexpr_var_init_non_constant, 1) << BaseVD;
2295 Info.FFDiag(Loc, diag::note_constexpr_dynamic_alloc)
2296 << IsReferenceType << !
Designator.Entries.empty();
2302 if (
const VarDecl *Var = dyn_cast<const VarDecl>(BaseVD)) {
2304 if (Var->getTLSKind())
2312 if (!isForManglingOnly(Kind) && Var->hasAttr<DLLImportAttr>() &&
2313 !Var->isStaticLocal())
2318 if (Info.getLangOpts().CUDA && Info.getLangOpts().CUDAIsDevice &&
2319 Info.Ctx.CUDAConstantEvalCtx.NoWrongSidedVars) {
2320 if ((!Var->hasAttr<CUDADeviceAttr>() &&
2321 !Var->hasAttr<CUDAConstantAttr>() &&
2322 !Var->getType()->isCUDADeviceBuiltinSurfaceType() &&
2323 !Var->getType()->isCUDADeviceBuiltinTextureType()) ||
2324 Var->hasAttr<HIPManagedAttr>())
2328 if (
const auto *FD = dyn_cast<const FunctionDecl>(BaseVD)) {
2339 if (Info.getLangOpts().CPlusPlus && !isForManglingOnly(Kind) &&
2340 FD->hasAttr<DLLImportAttr>())
2344 }
else if (
const auto *MTE =
2345 dyn_cast_or_null<MaterializeTemporaryExpr>(BaseE)) {
2346 if (CheckedTemps.insert(MTE).second) {
2349 Info.FFDiag(MTE->getExprLoc(),
2350 diag::note_constexpr_unsupported_temporary_nontrivial_dtor)
2355 APValue *
V = MTE->getOrCreateValue(
false);
2356 assert(
V &&
"evasluation result refers to uninitialised temporary");
2358 Info, MTE->getExprLoc(), TempType, *
V, Kind,
2359 nullptr, CheckedTemps))
2366 if (!IsReferenceType)
2378 Info.FFDiag(Loc, diag::note_constexpr_past_end, 1)
2379 << !
Designator.Entries.empty() << !!BaseVD << BaseVD;
2394 const auto *FD = dyn_cast_or_null<CXXMethodDecl>(
Member);
2397 if (FD->isImmediateFunction()) {
2398 Info.FFDiag(Loc, diag::note_consteval_address_accessible) << 0;
2399 Info.Note(FD->getLocation(), diag::note_declared_at);
2402 return isForManglingOnly(Kind) || FD->isVirtual() ||
2403 !FD->hasAttr<DLLImportAttr>();
2409 const LValue *
This =
nullptr) {
2411 if (Info.getLangOpts().CPlusPlus23)
2430 if (
This && Info.EvaluatingDecl ==
This->getLValueBase())
2434 if (Info.getLangOpts().CPlusPlus11)
2435 Info.FFDiag(E, diag::note_constexpr_nonliteral)
2438 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
2448 bool IsCompleteClass) {
2450 if (SubobjectDecl) {
2451 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
2452 << 1 << SubobjectDecl;
2454 diag::note_constexpr_subobject_declared_here);
2456 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
2465 Type = AT->getValueType();
2470 if (
Value.isArray()) {
2472 for (
unsigned I = 0, N =
Value.getArrayInitializedElts(); I != N; ++I) {
2474 Value.getArrayInitializedElt(I), Kind,
2475 SubobjectDecl, CheckedTemps))
2478 if (!
Value.hasArrayFiller())
2481 Value.getArrayFiller(), Kind, SubobjectDecl,
2484 if (
Value.isUnion() &&
Value.getUnionField()) {
2487 Value.getUnionValue(), Kind,
Value.getUnionField(), CheckedTemps);
2489 if (
Value.isStruct()) {
2491 if (
const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {
2492 unsigned BaseIndex = 0;
2496 const APValue &BaseValue =
Value.getStructBase(BaseIndex);
2499 Info.FFDiag(TypeBeginLoc, diag::note_constexpr_uninitialized_base)
2500 << BS.getType() <<
SourceRange(TypeBeginLoc, BS.getEndLoc());
2505 CheckedTemps,
false))
2510 for (
const auto *I : RD->fields()) {
2511 if (I->isUnnamedBitField())
2515 Value.getStructField(I->getFieldIndex()), Kind,
2520 if (IsCompleteClass) {
2521 if (
const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {
2522 unsigned BaseIndex = 0;
2524 assert(BS.isVirtual());
2525 const APValue &BaseValue =
Value.getStructVirtualBase(BaseIndex);
2528 Info.FFDiag(TypeBeginLoc, diag::note_constexpr_uninitialized_base)
2529 << BS.getType() <<
SourceRange(TypeBeginLoc, BS.getEndLoc());
2533 BaseValue, Kind,
nullptr,
2534 CheckedTemps,
false))
2542 if (
Value.isLValue() &&
2545 LVal.setFrom(Info.Ctx,
Value);
2550 if (
Value.isMemberPointer() &&
2571 nullptr, CheckedTemps);
2581 ConstantExprKind::Normal,
nullptr, CheckedTemps);
2587 if (!Info.HeapAllocs.empty()) {
2591 Info.CCEDiag(Info.HeapAllocs.begin()->second.AllocExpr,
2592 diag::note_constexpr_memory_leak)
2593 <<
unsigned(Info.HeapAllocs.size() - 1);
2601 if (!
Value.getLValueBase()) {
2654 llvm_unreachable(
"unknown APValue kind");
2660 assert(E->
isPRValue() &&
"missing lvalue-to-rvalue conv in bool condition");
2670 Info.CCEDiag(E, diag::note_constexpr_overflow) << SrcValue << DestType;
2671 if (
const auto *OBT = DestType->
getAs<OverflowBehaviorType>();
2672 OBT && OBT->isTrapKind()) {
2675 return Info.noteUndefinedBehavior();
2681 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
2687 if (
Value.convertToInteger(
Result, llvm::APFloat::rmTowardZero, &ignored)
2688 & APFloat::opInvalidOp)
2699 llvm::RoundingMode RM =
2701 if (RM == llvm::RoundingMode::Dynamic)
2702 RM = llvm::RoundingMode::NearestTiesToEven;
2711 APFloat::opStatus St) {
2714 if (Info.InConstantContext)
2718 if ((St & APFloat::opInexact) &&
2722 Info.FFDiag(E, diag::note_constexpr_dynamic_rounding);
2726 if ((St != APFloat::opOK) &&
2729 FPO.getAllowFEnvAccess())) {
2730 Info.FFDiag(E, diag::note_constexpr_float_arithmetic_strict);
2734 if ((St & APFloat::opStatus::opInvalidOp) &&
2755 "HandleFloatToFloatCast has been checked with only CastExpr, "
2756 "CompoundAssignOperator and ConvertVectorExpr. Please either validate "
2757 "the new expression or address the root cause of this usage.");
2759 APFloat::opStatus St;
2762 St =
Result.convert(Info.Ctx.getFloatTypeSemantics(DestType), RM, &ignored);
2769 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
2783 Result = APFloat(Info.Ctx.getFloatTypeSemantics(DestType), 1);
2785 APFloat::opStatus St =
Result.convertFromAPInt(
Value,
Value.isSigned(), RM);
2791 assert(FD->
isBitField() &&
"truncateBitfieldValue on non-bitfield");
2793 if (!
Value.isInt()) {
2797 assert(
Value.isLValue() &&
"integral value neither int nor lvalue?");
2803 unsigned OldBitWidth = Int.getBitWidth();
2805 if (NewBitWidth < OldBitWidth)
2806 Int = Int.trunc(NewBitWidth).extend(OldBitWidth);
2813template<
typename Operation>
2816 unsigned BitWidth, Operation Op,
2818 if (LHS.isUnsigned()) {
2823 APSInt Value(Op(LHS.extend(BitWidth), RHS.extend(BitWidth)),
false);
2826 if (Info.checkingForUndefinedBehavior())
2827 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
2828 diag::warn_integer_constant_overflow)
2841 bool HandleOverflowResult =
true;
2848 std::multiplies<APSInt>(),
Result);
2851 std::plus<APSInt>(),
Result);
2854 std::minus<APSInt>(),
Result);
2855 case BO_And:
Result = LHS & RHS;
return true;
2856 case BO_Xor:
Result = LHS ^ RHS;
return true;
2857 case BO_Or:
Result = LHS | RHS;
return true;
2861 Info.FFDiag(E, diag::note_expr_divide_by_zero)
2867 if (RHS.isNegative() && RHS.isAllOnes() && LHS.isSigned() &&
2868 LHS.isMinSignedValue())
2870 Info, E, -LHS.extend(LHS.getBitWidth() + 1), E->
getType());
2871 Result = (Opcode == BO_Rem ? LHS % RHS : LHS / RHS);
2872 return HandleOverflowResult;
2874 if (Info.getLangOpts().OpenCL)
2876 RHS &=
APSInt(llvm::APInt(RHS.getBitWidth(),
2877 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2879 else if (RHS.isSigned() && RHS.isNegative()) {
2882 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
2883 if (!Info.noteUndefinedBehavior())
2891 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
2893 Info.CCEDiag(E, diag::note_constexpr_large_shift)
2894 << RHS << E->
getType() << LHS.getBitWidth();
2895 if (!Info.noteUndefinedBehavior())
2897 }
else if (LHS.isSigned() && !Info.getLangOpts().CPlusPlus20) {
2902 if (LHS.isNegative()) {
2903 Info.CCEDiag(E, diag::note_constexpr_lshift_of_negative) << LHS;
2904 if (!Info.noteUndefinedBehavior())
2906 }
else if (LHS.countl_zero() < SA) {
2907 Info.CCEDiag(E, diag::note_constexpr_lshift_discards);
2908 if (!Info.noteUndefinedBehavior())
2916 if (Info.getLangOpts().OpenCL)
2918 RHS &=
APSInt(llvm::APInt(RHS.getBitWidth(),
2919 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2921 else if (RHS.isSigned() && RHS.isNegative()) {
2924 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
2925 if (!Info.noteUndefinedBehavior())
2933 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
2935 Info.CCEDiag(E, diag::note_constexpr_large_shift)
2936 << RHS << E->
getType() << LHS.getBitWidth();
2937 if (!Info.noteUndefinedBehavior())
2945 case BO_LT:
Result = LHS < RHS;
return true;
2946 case BO_GT:
Result = LHS > RHS;
return true;
2947 case BO_LE:
Result = LHS <= RHS;
return true;
2948 case BO_GE:
Result = LHS >= RHS;
return true;
2949 case BO_EQ:
Result = LHS == RHS;
return true;
2950 case BO_NE:
Result = LHS != RHS;
return true;
2952 llvm_unreachable(
"BO_Cmp should be handled elsewhere");
2959 const APFloat &RHS) {
2961 APFloat::opStatus St;
2967 St = LHS.multiply(RHS, RM);
2970 St = LHS.add(RHS, RM);
2973 St = LHS.subtract(RHS, RM);
2979 Info.CCEDiag(E, diag::note_expr_divide_by_zero);
2980 St = LHS.divide(RHS, RM);
2993 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << LHS.isNaN();
2994 return Info.noteUndefinedBehavior();
3002 const APInt &RHSValue, APInt &
Result) {
3003 bool LHS = (LHSValue != 0);
3004 bool RHS = (RHSValue != 0);
3006 if (Opcode == BO_LAnd)
3014 const APFloat &RHSValue, APInt &
Result) {
3015 bool LHS = !LHSValue.isZero();
3016 bool RHS = !RHSValue.isZero();
3018 if (Opcode == BO_LAnd)
3037template <
typename APTy>
3040 const APTy &RHSValue, APInt &
Result) {
3043 llvm_unreachable(
"unsupported binary operator");
3045 Result = (LHSValue == RHSValue);
3048 Result = (LHSValue != RHSValue);
3051 Result = (LHSValue < RHSValue);
3054 Result = (LHSValue > RHSValue);
3057 Result = (LHSValue <= RHSValue);
3060 Result = (LHSValue >= RHSValue);
3089 assert(Opcode != BO_PtrMemD && Opcode != BO_PtrMemI &&
3090 "Operation not supported on vector types");
3094 QualType EltTy = VT->getElementType();
3101 "A vector result that isn't a vector OR uncalculated LValue");
3107 RHSValue.
getVectorLength() == NumElements &&
"Different vector sizes");
3111 for (
unsigned EltNum = 0; EltNum < NumElements; ++EltNum) {
3116 APSInt EltResult{Info.Ctx.getIntWidth(EltTy),
3126 RHSElt.
getInt(), EltResult);
3132 ResultElements.emplace_back(EltResult);
3137 "Mismatched LHS/RHS/Result Type");
3138 APFloat LHSFloat = LHSElt.
getFloat();
3146 ResultElements.emplace_back(LHSFloat);
3150 LHSValue =
APValue(ResultElements.data(), ResultElements.size());
3158 unsigned TruncatedElements) {
3159 SubobjectDesignator &D =
Result.Designator;
3162 if (TruncatedElements == D.Entries.size())
3164 assert(TruncatedElements >= D.MostDerivedPathLength &&
3165 "not casting to a derived class");
3171 for (
unsigned I = TruncatedElements, N = D.Entries.size(); I != N; ++I) {
3175 if (isVirtualBaseClass(D.Entries[I]))
3181 D.Entries.resize(TruncatedElements);
3191 RL = &Info.Ctx.getASTRecordLayout(Derived);
3194 Obj.addDecl(Info, E,
Base,
false);
3195 Obj.getLValueOffset() += RL->getBaseClassOffset(
Base);
3207 RL = &Info.Ctx.getASTRecordLayout(Derived);
3210 Obj.addDecl(Info, E,
Base,
true);
3211 Obj.getLValueOffset() += RL->getVBaseClassOffset(
Base);
3220 if (!
Base->isVirtual())
3223 SubobjectDesignator &D = Obj.Designator;
3238 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(DerivedDecl);
3239 Obj.addDecl(Info, E, BaseDecl,
true);
3248 PathI != PathE; ++PathI) {
3252 Type = (*PathI)->getType();
3264 llvm_unreachable(
"Class must be derived from the passed in base class!");
3288 RL = &Info.Ctx.getASTRecordLayout(RD);
3292 LVal.addDecl(Info, E, FD);
3293 LVal.adjustOffset(Info.Ctx.toCharUnitsFromBits(RL->getFieldOffset(I)));
3301 for (
const auto *
C : IFD->
chain())
3335 Size = Info.Ctx.getTypeSizeInChars(
Type);
3337 Size = Info.Ctx.getTypeInfoDataSizeInChars(
Type).Width;
3354 LVal.adjustOffsetAndIndex(Info, E, Adjustment, SizeOfPointee);
3360 int64_t Adjustment) {
3362 APSInt::get(Adjustment));
3377 LVal.Offset += SizeOfComponent;
3379 LVal.addComplex(Info, E, EltTy, Imag);
3385 uint64_t Size, uint64_t Idx) {
3390 LVal.Offset += SizeOfElement * Idx;
3392 LVal.addVectorElement(Info, E, EltTy, Size, Idx);
3406 const VarDecl *VD, CallStackFrame *Frame,
3410 bool AllowConstexprUnknown =
3415 auto CheckUninitReference = [&](
bool IsLocalVariable) {
3427 if (!AllowConstexprUnknown || IsLocalVariable) {
3428 if (!Info.checkingPotentialConstantExpression())
3429 Info.FFDiag(E, diag::note_constexpr_use_uninit_reference);
3439 Result = Frame->getTemporary(VD, Version);
3441 return CheckUninitReference(
true);
3450 "missing value for local variable");
3451 if (Info.checkingPotentialConstantExpression())
3455 "A variable in a frame should either be a local or a parameter");
3461 if (Info.EvaluatingDecl ==
Base) {
3462 Result = Info.EvaluatingDeclValue;
3463 return CheckUninitReference(
false);
3471 if (AllowConstexprUnknown) {
3478 if (!Info.checkingPotentialConstantExpression() ||
3479 !Info.CurrentCall->Callee ||
3481 if (Info.getLangOpts().CPlusPlus11) {
3482 Info.FFDiag(E, diag::note_constexpr_function_param_value_unknown)
3503 if (!
Init && !AllowConstexprUnknown) {
3506 if (!Info.checkingPotentialConstantExpression()) {
3507 Info.FFDiag(E, diag::note_constexpr_var_init_unknown, 1)
3518 if (
Init &&
Init->isValueDependent()) {
3525 if (!Info.checkingPotentialConstantExpression()) {
3526 Info.FFDiag(E, Info.getLangOpts().CPlusPlus11
3527 ? diag::note_constexpr_ltor_non_constexpr
3528 : diag::note_constexpr_ltor_non_integral, 1)
3542 Info.FFDiag(E, diag::note_constexpr_var_init_non_constant, 1) << VD;
3558 !AllowConstexprUnknown) ||
3559 ((Info.getLangOpts().CPlusPlus || Info.getLangOpts().OpenCL) &&
3562 Info.CCEDiag(E, diag::note_constexpr_var_init_non_constant, 1) << VD;
3572 Info.FFDiag(E, diag::note_constexpr_var_init_weak) << VD;
3579 if (!
Result && !AllowConstexprUnknown)
3582 return CheckUninitReference(
false);
3605 llvm_unreachable(
"base class missing from derived class's bases list");
3612 "SourceLocExpr should have already been converted to a StringLiteral");
3615 if (
const auto *ObjCEnc = dyn_cast<ObjCEncodeExpr>(Lit)) {
3617 Info.Ctx.getObjCEncodingForType(ObjCEnc->getEncodedType(), Str);
3618 assert(Index <= Str.size() &&
"Index too large");
3619 return APSInt::getUnsigned(Str.c_str()[Index]);
3622 if (
auto PE = dyn_cast<PredefinedExpr>(Lit))
3623 Lit = PE->getFunctionName();
3626 Info.Ctx.getAsConstantArrayType(S->
getType());
3627 assert(CAT &&
"string literal isn't an array");
3629 assert(CharType->
isIntegerType() &&
"unexpected character type");
3632 if (Index < S->getLength())
3645 AllocType.isNull() ? S->
getType() : AllocType);
3646 assert(CAT &&
"string literal isn't an array");
3648 assert(CharType->
isIntegerType() &&
"unexpected character type");
3655 if (
Result.hasArrayFiller())
3657 for (
unsigned I = 0, N =
Result.getArrayInitializedElts(); I != N; ++I) {
3665 unsigned Size =
Array.getArraySize();
3666 assert(Index < Size);
3669 unsigned OldElts =
Array.getArrayInitializedElts();
3670 unsigned NewElts = std::max(Index+1, OldElts * 2);
3671 NewElts = std::min(Size, std::max(NewElts, 8u));
3675 for (
unsigned I = 0; I != OldElts; ++I)
3677 for (
unsigned I = OldElts; I != NewElts; ++I)
3681 Array.swap(NewValue);
3688 Vec =
APValue(Elts.data(), Elts.size());
3698 CXXRecordDecl *RD =
T->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
3709 for (
auto *Field : RD->
fields())
3710 if (!Field->isUnnamedBitField() &&
3714 for (
auto &BaseSpec : RD->
bases())
3725 CXXRecordDecl *RD =
T->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
3732 for (
auto *Field : RD->
fields()) {
3737 if (Field->isMutable() &&
3739 Info.FFDiag(E, diag::note_constexpr_access_mutable, 1) << AK << Field;
3740 Info.Note(Field->getLocation(), diag::note_declared_at);
3748 for (
auto &BaseSpec : RD->
bases())
3758 bool MutableSubobject =
false) {
3763 switch (Info.IsEvaluatingDecl) {
3764 case EvalInfo::EvaluatingDeclKind::None:
3767 case EvalInfo::EvaluatingDeclKind::Ctor:
3769 if (Info.EvaluatingDecl ==
Base)
3774 if (
auto *BaseE =
Base.dyn_cast<
const Expr *>())
3775 if (
auto *BaseMTE = dyn_cast<MaterializeTemporaryExpr>(BaseE))
3776 return Info.EvaluatingDecl == BaseMTE->getExtendingDecl();
3779 case EvalInfo::EvaluatingDeclKind::Dtor:
3784 if (MutableSubobject ||
Base != Info.EvaluatingDecl)
3790 return T.isConstQualified() ||
T->isReferenceType();
3793 llvm_unreachable(
"unknown evaluating decl kind");
3798 return Info.CheckArraySize(
3818 uint64_t IntResult = BoolResult;
3821 : Info.Ctx.getIntTypeForBitwidth(64,
false);
3822 Result =
APValue(Info.Ctx.MakeIntValue(IntResult, IntType));
3827 Info.Ctx.getIntTypeForBitwidth(64,
false),
3830 Result = std::move(Result2);
3838 DestTy,
Result.getFloat());
3844 uint64_t IntResult = BoolResult;
3863 uint64_t IntResult = BoolResult;
3870 DestTy,
Result.getInt());
3874 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
3887 {&
Result, ResultType, 0}};
3890 while (!WorkList.empty() && ElI < Elements.size()) {
3891 auto [Res,
Type, BitWidth] = WorkList.pop_back_val();
3907 APSInt &Int = Res->getInt();
3908 unsigned OldBitWidth = Int.getBitWidth();
3909 unsigned NewBitWidth = BitWidth;
3910 if (NewBitWidth < OldBitWidth)
3911 Int = Int.trunc(NewBitWidth).extend(OldBitWidth);
3920 for (
unsigned I = 0; I < NumEl; ++I) {
3926 *Res =
APValue(Vals.data(), NumEl);
3935 for (int64_t I = Size - 1; I > -1; --I)
3936 WorkList.emplace_back(&Res->getArrayInitializedElt(I), ElTy, 0u);
3942 unsigned NumBases = 0;
3943 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
3944 NumBases = CXXRD->getNumBases();
3951 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
3952 if (CXXRD->getNumBases() > 0) {
3953 assert(CXXRD->getNumBases() == 1);
3955 ReverseList.emplace_back(&Res->getStructBase(0), BS.
getType(), 0u);
3962 if (FD->isUnnamedBitField())
3964 if (FD->isBitField()) {
3965 FDBW = FD->getBitWidthValue();
3968 ReverseList.emplace_back(&Res->getStructField(FD->getFieldIndex()),
3969 FD->getType(), FDBW);
3972 std::reverse(ReverseList.begin(), ReverseList.end());
3973 llvm::append_range(WorkList, ReverseList);
3976 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
3989 assert((Elements.size() == SrcTypes.size()) &&
3990 (Elements.size() == DestTypes.size()));
3992 for (
unsigned I = 0, ESz = Elements.size(); I < ESz; ++I) {
3993 APValue Original = Elements[I];
3997 if (!
handleScalarCast(Info, FPO, E, SourceTy, DestTy, Original, Results[I]))
4008 while (!WorkList.empty()) {
4031 for (uint64_t I = 0; I < ArrSize; ++I) {
4032 WorkList.push_back(ElTy);
4040 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4041 if (CXXRD->getNumBases() > 0) {
4042 assert(CXXRD->getNumBases() == 1);
4044 WorkList.push_back(BS.
getType());
4050 if (FD->isUnnamedBitField())
4052 WorkList.push_back(FD->getType());
4069 "Not a valid HLSLAggregateSplatCast.");
4089 unsigned Populated = 0;
4090 while (!WorkList.empty() && Populated < Size) {
4091 auto [Work,
Type] = WorkList.pop_back_val();
4093 if (Work.isFloat() || Work.isInt()) {
4094 Elements.push_back(Work);
4095 Types.push_back(
Type);
4099 if (Work.isVector()) {
4102 for (
unsigned I = 0; I < Work.getVectorLength() && Populated < Size;
4104 Elements.push_back(Work.getVectorElt(I));
4105 Types.push_back(ElTy);
4110 if (Work.isMatrix()) {
4113 QualType ElTy = MT->getElementType();
4115 for (
unsigned Row = 0; Row < Work.getMatrixNumRows() && Populated < Size;
4117 for (
unsigned Col = 0;
4118 Col < Work.getMatrixNumColumns() && Populated < Size; Col++) {
4119 Elements.push_back(Work.getMatrixElt(Row, Col));
4120 Types.push_back(ElTy);
4126 if (Work.isArray()) {
4130 for (int64_t I = Work.getArraySize() - 1; I > -1; --I) {
4131 WorkList.emplace_back(Work.getArrayInitializedElt(I), ElTy);
4136 if (Work.isStruct()) {
4144 if (FD->isUnnamedBitField())
4146 ReverseList.emplace_back(Work.getStructField(FD->getFieldIndex()),
4150 std::reverse(ReverseList.begin(), ReverseList.end());
4151 llvm::append_range(WorkList, ReverseList);
4154 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4155 if (CXXRD->getNumBases() > 0) {
4156 assert(CXXRD->getNumBases() == 1);
4161 if (!
Base.isStruct())
4169 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
4178struct CompleteObject {
4180 APValue::LValueBase
Base;
4190 bool mayAccessMutableMembers(EvalInfo &Info,
AccessKinds AK)
const {
4201 if (!Info.getLangOpts().CPlusPlus14 &&
4202 AK != AccessKinds::AK_IsWithinLifetime)
4207 explicit operator bool()
const {
return !
Type.isNull(); }
4212 bool IsMutable =
false) {
4226template <
typename Sub
objectHandler>
4227static typename SubobjectHandler::result_type
4229 const SubobjectDesignator &Sub, SubobjectHandler &handler) {
4232 return handler.failed();
4233 if (Sub.isOnePastTheEnd() || Sub.isMostDerivedAnUnsizedArray()) {
4234 if (Info.getLangOpts().CPlusPlus11)
4235 Info.FFDiag(E, Sub.isOnePastTheEnd()
4236 ? diag::note_constexpr_access_past_end
4237 : diag::note_constexpr_access_unsized_array)
4238 << handler.AccessKind;
4241 return handler.failed();
4247 const FieldDecl *VolatileField =
nullptr;
4250 for (
unsigned I = 0, N = Sub.Entries.size(); ; ++I) {
4261 if (!Info.checkingPotentialConstantExpression()) {
4262 Info.FFDiag(E, diag::note_constexpr_access_uninit)
4267 return handler.failed();
4275 Info.isEvaluatingCtorDtor(
4276 Obj.Base,
ArrayRef(Sub.Entries.begin(), Sub.Entries.begin() + I)) !=
4277 ConstructionPhase::None) {
4278 ObjType = Info.Ctx.getCanonicalType(ObjType);
4287 if (Info.getLangOpts().CPlusPlus) {
4291 if (VolatileField) {
4294 Decl = VolatileField;
4297 Loc = VD->getLocation();
4304 Info.FFDiag(E, diag::note_constexpr_access_volatile_obj, 1)
4305 << handler.AccessKind << DiagKind <<
Decl;
4306 Info.Note(Loc, diag::note_constexpr_volatile_here) << DiagKind;
4308 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
4310 return handler.failed();
4318 !Obj.mayAccessMutableMembers(Info, handler.AccessKind) &&
4320 return handler.failed();
4324 if (!handler.found(*O, ObjType, Obj.Base))
4336 LastField =
nullptr;
4341 ObjType = Info.Ctx.getQualifiedType(AT->getValueType(),
4346 const ArrayType *AT = Info.Ctx.getAsArrayType(ObjType);
4348 "vla in literal type?");
4349 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4350 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT);
4351 CAT && CAT->
getSize().ule(Index)) {
4354 if (Info.getLangOpts().CPlusPlus11)
4355 Info.FFDiag(E, diag::note_constexpr_access_past_end)
4356 << handler.AccessKind;
4359 return handler.failed();
4366 else if (!
isRead(handler.AccessKind)) {
4367 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT);
4369 return handler.failed();
4377 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4379 if (Info.getLangOpts().CPlusPlus11)
4380 Info.FFDiag(E, diag::note_constexpr_access_past_end)
4381 << handler.AccessKind;
4384 return handler.failed();
4390 assert(I == N - 1 &&
"extracting subobject of scalar?");
4400 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4401 unsigned NumElements = VT->getNumElements();
4402 if (Index == NumElements) {
4403 if (Info.getLangOpts().CPlusPlus11)
4404 Info.FFDiag(E, diag::note_constexpr_access_past_end)
4405 << handler.AccessKind;
4408 return handler.failed();
4411 if (Index > NumElements) {
4412 Info.CCEDiag(E, diag::note_constexpr_array_index)
4413 << Index << 0 << NumElements;
4414 return handler.failed();
4417 ObjType = VT->getElementType();
4418 assert(I == N - 1 &&
"extracting subobject of scalar?");
4421 if (
isRead(handler.AccessKind)) {
4423 return handler.failed();
4427 assert(O->
isVector() &&
"unexpected object during vector element access");
4428 return handler.found(O->
getVectorElt(Index), ObjType, Obj.Base);
4429 }
else if (
const FieldDecl *Field = getAsField(Sub.Entries[I])) {
4430 if (Field->isMutable() &&
4431 !Obj.mayAccessMutableMembers(Info, handler.AccessKind)) {
4432 Info.FFDiag(E, diag::note_constexpr_access_mutable, 1)
4433 << handler.AccessKind << Field;
4434 Info.Note(Field->getLocation(), diag::note_declared_at);
4435 return handler.failed();
4444 if (I == N - 1 && handler.AccessKind ==
AK_Construct) {
4455 Info.FFDiag(E, diag::note_constexpr_access_inactive_union_member)
4456 << handler.AccessKind << Field << !UnionField << UnionField;
4457 return handler.failed();
4466 if (Field->getType().isVolatileQualified())
4467 VolatileField = Field;
4475 if (BaseIndex >= NumNonVirtualBases) {
4486struct ExtractSubobjectHandler {
4492 typedef bool result_type;
4493 bool failed() {
return false; }
4494 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
4504 bool found(APFloat &
Value, QualType SubobjType) {
4513 const CompleteObject &Obj,
4517 ExtractSubobjectHandler Handler = {Info, E,
Result, AK};
4522struct ModifySubobjectHandler {
4527 typedef bool result_type;
4530 bool checkConst(QualType QT) {
4533 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
4539 bool failed() {
return false; }
4540 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
4541 if (!checkConst(SubobjType))
4544 Subobj.
swap(NewVal);
4548 if (!checkConst(SubobjType))
4550 if (!NewVal.
isInt()) {
4558 bool found(APFloat &
Value, QualType SubobjType) {
4559 if (!checkConst(SubobjType))
4567const AccessKinds ModifySubobjectHandler::AccessKind;
4571 const CompleteObject &Obj,
4572 const SubobjectDesignator &Sub,
4574 ModifySubobjectHandler Handler = { Info, NewVal, E };
4581 const SubobjectDesignator &A,
4582 const SubobjectDesignator &B,
4583 bool &WasArrayIndex) {
4584 unsigned I = 0, N = std::min(A.Entries.size(), B.Entries.size());
4585 for (; I != N; ++I) {
4589 if (A.Entries[I].getAsArrayIndex() != B.Entries[I].getAsArrayIndex()) {
4590 WasArrayIndex =
true;
4598 if (A.Entries[I].getAsBaseOrMember() !=
4599 B.Entries[I].getAsBaseOrMember()) {
4600 WasArrayIndex =
false;
4603 if (
const FieldDecl *FD = getAsField(A.Entries[I]))
4605 ObjType = FD->getType();
4611 WasArrayIndex =
false;
4618 const SubobjectDesignator &A,
4619 const SubobjectDesignator &B) {
4620 if (A.Entries.size() != B.Entries.size())
4623 bool IsArray = A.MostDerivedIsArrayElement;
4624 if (IsArray && A.MostDerivedPathLength != A.Entries.size())
4633 return CommonLength >= A.Entries.size() - IsArray;
4640 if (LVal.InvalidBase) {
4642 return CompleteObject();
4647 Info.FFDiag(E, diag::note_constexpr_dereferencing_null);
4649 Info.FFDiag(E, diag::note_constexpr_access_null) << AK;
4650 return CompleteObject();
4653 CallStackFrame *Frame =
nullptr;
4655 if (LVal.getLValueCallIndex()) {
4656 std::tie(Frame, Depth) =
4657 Info.getCallFrameAndDepth(LVal.getLValueCallIndex());
4659 Info.FFDiag(E, diag::note_constexpr_access_uninit, 1)
4662 return CompleteObject();
4673 if (Info.getLangOpts().CPlusPlus)
4674 Info.FFDiag(E, diag::note_constexpr_access_volatile_type)
4678 return CompleteObject();
4685 if (Info.getLangOpts().CPlusPlus14 && LVal.Base == Info.EvaluatingDecl &&
4689 BaseVal = Info.EvaluatingDeclValue;
4692 if (
auto *GD = dyn_cast<MSGuidDecl>(D)) {
4695 Info.FFDiag(E, diag::note_constexpr_modify_global);
4696 return CompleteObject();
4700 Info.FFDiag(E, diag::note_constexpr_unsupported_layout)
4702 return CompleteObject();
4704 return CompleteObject(LVal.Base, &
V, GD->getType());
4708 if (
auto *GCD = dyn_cast<UnnamedGlobalConstantDecl>(D)) {
4710 Info.FFDiag(E, diag::note_constexpr_modify_global);
4711 return CompleteObject();
4713 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&GCD->getValue()),
4718 if (
auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
4720 Info.FFDiag(E, diag::note_constexpr_modify_global);
4721 return CompleteObject();
4723 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&TPO->getValue()),
4734 const VarDecl *VD = dyn_cast<VarDecl>(D);
4741 return CompleteObject();
4744 bool IsConstant = BaseType.isConstant(Info.Ctx);
4745 bool ConstexprVar =
false;
4746 if (
const auto *VD = dyn_cast_if_present<VarDecl>(
4758 }
else if (Info.getLangOpts().CPlusPlus14 &&
4765 Info.FFDiag(E, diag::note_constexpr_modify_global);
4766 return CompleteObject();
4769 }
else if (Info.getLangOpts().C23 && ConstexprVar) {
4771 return CompleteObject();
4772 }
else if (BaseType->isIntegralOrEnumerationType()) {
4775 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4776 if (Info.getLangOpts().CPlusPlus) {
4777 Info.FFDiag(E, diag::note_constexpr_ltor_non_const_int, 1) << VD;
4778 Info.Note(VD->
getLocation(), diag::note_declared_at);
4782 return CompleteObject();
4784 }
else if (!IsAccess) {
4785 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4786 }
else if ((IsConstant || BaseType->isReferenceType()) &&
4787 Info.checkingPotentialConstantExpression() &&
4788 BaseType->isLiteralType(Info.Ctx) && !VD->
hasDefinition()) {
4790 }
else if (IsConstant) {
4794 if (Info.getLangOpts().CPlusPlus) {
4795 Info.CCEDiag(E, Info.getLangOpts().CPlusPlus11
4796 ? diag::note_constexpr_ltor_non_constexpr
4797 : diag::note_constexpr_ltor_non_integral, 1)
4799 Info.Note(VD->
getLocation(), diag::note_declared_at);
4805 if (Info.getLangOpts().CPlusPlus) {
4806 Info.FFDiag(E, Info.getLangOpts().CPlusPlus11
4807 ? diag::note_constexpr_ltor_non_constexpr
4808 : diag::note_constexpr_ltor_non_integral, 1)
4810 Info.Note(VD->
getLocation(), diag::note_declared_at);
4814 return CompleteObject();
4823 return CompleteObject();
4828 if (!Info.checkingPotentialConstantExpression()) {
4829 Info.FFDiag(E, diag::note_constexpr_access_unknown_variable, 1)
4831 Info.Note(VD->getLocation(), diag::note_declared_at);
4833 return CompleteObject();
4836 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
4838 Info.FFDiag(E, diag::note_constexpr_access_deleted_object) << AK;
4839 return CompleteObject();
4841 return CompleteObject(LVal.Base, &(*Alloc)->Value,
4851 dyn_cast_or_null<MaterializeTemporaryExpr>(
Base)) {
4852 assert(MTE->getStorageDuration() ==
SD_Static &&
4853 "should have a frame for a non-global materialized temporary");
4880 if (!MTE->isUsableInConstantExpressions(Info.Ctx) &&
4883 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4884 Info.FFDiag(E, diag::note_constexpr_access_static_temporary, 1) << AK;
4885 Info.Note(MTE->getExprLoc(), diag::note_constexpr_temporary_here);
4886 return CompleteObject();
4889 BaseVal = MTE->getOrCreateValue(
false);
4890 assert(BaseVal &&
"got reference to unevaluated temporary");
4892 dyn_cast_or_null<CompoundLiteralExpr>(
Base)) {
4908 !CLETy.isConstant(Info.Ctx)) {
4910 Info.Note(CLE->getExprLoc(), diag::note_declared_at);
4911 return CompleteObject();
4914 BaseVal = &CLE->getStaticValue();
4917 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4920 Info.FFDiag(E, diag::note_constexpr_access_unreadable_object)
4923 Info.Ctx.getLValueReferenceType(LValType));
4925 return CompleteObject();
4929 assert(BaseVal &&
"missing value for temporary");
4940 unsigned VisibleDepth = Depth;
4941 if (llvm::isa_and_nonnull<ParmVarDecl>(
4944 if ((Frame && Info.getLangOpts().CPlusPlus14 &&
4945 Info.EvalStatus.HasSideEffects) ||
4946 (
isModification(AK) && VisibleDepth < Info.SpeculativeEvaluationDepth))
4947 return CompleteObject();
4949 return CompleteObject(LVal.getLValueBase(), BaseVal, BaseType);
4968 const LValue &LVal,
APValue &RVal,
4969 bool WantObjectRepresentation =
false) {
4970 if (LVal.Designator.Invalid)
4979 if (
Base && !LVal.getLValueCallIndex() && !
Type.isVolatileQualified()) {
4983 assert(LVal.Designator.Entries.size() <= 1 &&
4984 "Can only read characters from string literals");
4985 if (LVal.Designator.Entries.empty()) {
4992 if (LVal.Designator.isOnePastTheEnd()) {
4993 if (Info.getLangOpts().CPlusPlus11)
4994 Info.FFDiag(Conv, diag::note_constexpr_access_past_end) << AK;
4999 uint64_t CharIndex = LVal.Designator.Entries[0].getAsArrayIndex();
5006 return Obj &&
extractSubobject(Info, Conv, Obj, LVal.Designator, RVal, AK);
5020 LVal.setFrom(Info.Ctx, Val);
5036 if (LVal.Designator.Invalid)
5039 if (!Info.getLangOpts().CPlusPlus14) {
5049struct CompoundAssignSubobjectHandler {
5051 const CompoundAssignOperator *E;
5052 QualType PromotedLHSType;
5058 typedef bool result_type;
5060 bool checkConst(QualType QT) {
5063 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
5069 bool failed() {
return false; }
5070 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
5073 return found(Subobj.
getInt(), SubobjType);
5075 return found(Subobj.
getFloat(), SubobjType);
5082 return foundPointer(Subobj, SubobjType);
5084 return foundVector(Subobj, SubobjType);
5086 Info.FFDiag(E, diag::note_constexpr_access_uninit)
5098 bool foundVector(
APValue &
Value, QualType SubobjType) {
5099 if (!checkConst(SubobjType))
5110 if (!checkConst(SubobjType))
5129 Info.Ctx.getLangOpts());
5132 PromotedLHSType, FValue) &&
5141 bool found(APFloat &
Value, QualType SubobjType) {
5142 return checkConst(SubobjType) &&
5148 bool foundPointer(
APValue &Subobj, QualType SubobjType) {
5149 if (!checkConst(SubobjType))
5152 QualType PointeeType;
5153 if (
const PointerType *PT = SubobjType->
getAs<PointerType>())
5157 (Opcode != BO_Add && Opcode != BO_Sub)) {
5163 if (Opcode == BO_Sub)
5167 LVal.setFrom(Info.Ctx, Subobj);
5170 LVal.moveInto(Subobj);
5176const AccessKinds CompoundAssignSubobjectHandler::AccessKind;
5181 const LValue &LVal,
QualType LValType,
5185 if (LVal.Designator.Invalid)
5188 if (!Info.getLangOpts().CPlusPlus14) {
5194 CompoundAssignSubobjectHandler Handler = { Info, E, PromotedLValType, Opcode,
5196 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
5200struct IncDecSubobjectHandler {
5202 const UnaryOperator *E;
5206 typedef bool result_type;
5208 bool checkConst(QualType QT) {
5211 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
5217 bool failed() {
return false; }
5218 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
5228 return found(Subobj.
getInt(), SubobjType);
5230 return found(Subobj.
getFloat(), SubobjType);
5233 SubobjType->
castAs<ComplexType>()->getElementType()
5237 SubobjType->
castAs<ComplexType>()->getElementType()
5240 return foundPointer(Subobj, SubobjType);
5248 if (!checkConst(SubobjType))
5270 bool WasNegative =
Value.isNegative();
5284 unsigned BitWidth =
Value.getBitWidth();
5285 APSInt ActualValue(
Value.sext(BitWidth + 1),
false);
5286 ActualValue.setBit(BitWidth);
5292 bool found(APFloat &
Value, QualType SubobjType) {
5293 if (!checkConst(SubobjType))
5300 APFloat::opStatus St;
5302 St =
Value.add(One, RM);
5304 St =
Value.subtract(One, RM);
5307 bool foundPointer(
APValue &Subobj, QualType SubobjType) {
5308 if (!checkConst(SubobjType))
5311 QualType PointeeType;
5312 if (
const PointerType *PT = SubobjType->
getAs<PointerType>())
5320 LVal.setFrom(Info.Ctx, Subobj);
5324 LVal.moveInto(Subobj);
5333 if (LVal.Designator.Invalid)
5336 if (!Info.getLangOpts().CPlusPlus14) {
5344 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
5350 if (
Object->getType()->isPointerType() &&
Object->isPRValue())
5356 if (
Object->getType()->isLiteralType(Info.Ctx))
5359 if (
Object->getType()->isRecordType() &&
Object->isPRValue())
5362 Info.FFDiag(
Object, diag::note_constexpr_nonliteral) <<
Object->getType();
5381 bool IncludeMember =
true) {
5388 if (!MemPtr.getDecl()) {
5394 if (MemPtr.isDerivedMember()) {
5401 if (LV.Designator.MostDerivedPathLength + MemPtr.Path.size() >
5402 LV.Designator.Entries.size()) {
5406 unsigned PathLengthToMember =
5407 LV.Designator.Entries.size() - MemPtr.Path.size();
5408 for (
unsigned I = 0, N = MemPtr.Path.size(); I != N; ++I) {
5410 LV.Designator.Entries[PathLengthToMember + I]);
5427 (PathLengthToMember > LV.Designator.MostDerivedPathLength)
5428 ? getAsBaseClass(LV.Designator.Entries[PathLengthToMember - 1])
5430 const CXXRecordDecl *LastMPDecl = MemPtr.getContainingRecord();
5438 PathLengthToMember))
5440 }
else if (!MemPtr.Path.empty()) {
5442 LV.Designator.Entries.reserve(LV.Designator.Entries.size() +
5443 MemPtr.Path.size() + IncludeMember);
5449 assert(RD &&
"member pointer access on non-class-type expression");
5451 for (
unsigned I = 1, N = MemPtr.Path.size(); I != N; ++I) {
5459 MemPtr.getContainingRecord()))
5464 if (IncludeMember) {
5465 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(MemPtr.getDecl())) {
5469 dyn_cast<IndirectFieldDecl>(MemPtr.getDecl())) {
5473 llvm_unreachable(
"can't construct reference to bound member function");
5477 return MemPtr.getDecl();
5483 bool IncludeMember =
true) {
5487 if (Info.noteFailure()) {
5495 BO->
getRHS(), IncludeMember);
5502 SubobjectDesignator &D =
Result.Designator;
5510 auto InvalidCast = [&]() {
5511 if (!Info.checkingPotentialConstantExpression() ||
5512 !
Result.AllowConstexprUnknown) {
5513 Info.CCEDiag(E, diag::note_constexpr_invalid_downcast)
5514 << D.MostDerivedType << TargetQT;
5520 if (D.MostDerivedPathLength + E->
path_size() > D.Entries.size())
5521 return InvalidCast();
5525 unsigned NewEntriesSize = D.Entries.size() - E->
path_size();
5528 if (NewEntriesSize == D.MostDerivedPathLength)
5531 FinalType = getAsBaseClass(D.Entries[NewEntriesSize - 1]);
5533 return InvalidCast();
5542 bool IsCompleteClass =
true) {
5549 if (
auto *RD =
T->getAsCXXRecordDecl()) {
5550 if (RD->isInvalidDecl()) {
5554 if (RD->isUnion()) {
5560 unsigned NonVirtualBases = countNonVirtualBases(RD);
5563 IsCompleteClass ? RD->getNumVBases() : 0);
5574 for (
const auto *I : RD->fields()) {
5575 if (I->isUnnamedBitField())
5578 I->getType(),
Result.getStructField(I->getFieldIndex()));
5581 if (IsCompleteClass) {
5584 for (
const auto &B : RD->vbases()) {
5586 Result.getStructVirtualBase(Index),
5592 assert(
Result.getStructNumVirtualBases() == 0);
5599 dyn_cast_or_null<ConstantArrayType>(
T->getAsArrayTypeUnsafe())) {
5601 if (
Result.hasArrayFiller())
5612enum EvalStmtResult {
5641 if (!
Result.Designator.Invalid &&
Result.Designator.isOnePastTheEnd()) {
5659 APValue &Val = Info.CurrentCall->createTemporary(VD, VD->
getType(),
5660 ScopeKind::Block,
Result);
5665 return Info.noteSideEffect();
5686 const DecompositionDecl *DD);
5689 bool EvaluateConditionDecl =
false) {
5691 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
5695 EvaluateConditionDecl && DD)
5705 if (
auto *VD = BD->getHoldingVar())
5713 if (
auto *DD = dyn_cast_if_present<DecompositionDecl>(VD)) {
5722 if (Info.noteSideEffect())
5724 assert(E->
containsErrors() &&
"valid value-dependent expression should never "
5725 "reach invalid code path.");
5732 if (
Cond->isValueDependent())
5734 FullExpressionRAII
Scope(Info);
5741 return Scope.destroy();
5754struct TempVersionRAII {
5755 CallStackFrame &Frame;
5757 TempVersionRAII(CallStackFrame &Frame) : Frame(Frame) {
5758 Frame.pushTempVersion();
5761 ~TempVersionRAII() {
5762 Frame.popTempVersion();
5770 const SwitchCase *SC =
nullptr);
5776 const Stmt *LoopOrSwitch,
5778 EvalStmtResult &ESR) {
5782 if (!IsSwitch && ESR == ESR_Succeeded) {
5787 if (ESR != ESR_Break && ESR != ESR_Continue)
5791 bool CanBreakOrContinue = !IsSwitch || ESR == ESR_Break;
5792 const Stmt *StackTop = Info.BreakContinueStack.back();
5793 if (CanBreakOrContinue && (StackTop ==
nullptr || StackTop == LoopOrSwitch)) {
5794 Info.BreakContinueStack.pop_back();
5795 if (ESR == ESR_Break)
5796 ESR = ESR_Succeeded;
5801 for (BlockScopeRAII *S : Scopes) {
5802 if (!S->destroy()) {
5814 BlockScopeRAII
Scope(Info);
5817 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5826 BlockScopeRAII
Scope(Info);
5833 if (ESR != ESR_Succeeded) {
5834 if (ESR != ESR_Failed && !
Scope.destroy())
5840 FullExpressionRAII CondScope(Info);
5855 if (!CondScope.destroy())
5876 if (LHSValue <=
Value &&
Value <= RHSValue) {
5883 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5887 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5894 llvm_unreachable(
"Should have been converted to Succeeded");
5900 case ESR_CaseNotFound:
5903 Info.FFDiag(
Found->getBeginLoc(),
5904 diag::note_constexpr_stmt_expr_unsupported);
5907 llvm_unreachable(
"Invalid EvalStmtResult!");
5917 Info.CCEDiag(VD->
getLocation(), diag::note_constexpr_static_local)
5927 if (!Info.nextStep(S))
5934 case Stmt::CompoundStmtClass:
5938 case Stmt::LabelStmtClass:
5939 case Stmt::AttributedStmtClass:
5940 case Stmt::DoStmtClass:
5943 case Stmt::CaseStmtClass:
5944 case Stmt::DefaultStmtClass:
5949 case Stmt::IfStmtClass: {
5956 BlockScopeRAII
Scope(Info);
5962 if (ESR != ESR_CaseNotFound) {
5963 assert(ESR != ESR_Succeeded);
5974 if (ESR == ESR_Failed)
5976 if (ESR != ESR_CaseNotFound)
5977 return Scope.destroy() ? ESR : ESR_Failed;
5979 return ESR_CaseNotFound;
5982 if (ESR == ESR_Failed)
5984 if (ESR != ESR_CaseNotFound)
5985 return Scope.destroy() ? ESR : ESR_Failed;
5986 return ESR_CaseNotFound;
5989 case Stmt::WhileStmtClass: {
5990 EvalStmtResult ESR =
5994 if (ESR != ESR_Continue)
5999 case Stmt::ForStmtClass: {
6001 BlockScopeRAII
Scope(Info);
6007 if (ESR != ESR_CaseNotFound) {
6008 assert(ESR != ESR_Succeeded);
6013 EvalStmtResult ESR =
6017 if (ESR != ESR_Continue)
6019 if (
const auto *Inc = FS->
getInc()) {
6020 if (Inc->isValueDependent()) {
6024 FullExpressionRAII IncScope(Info);
6032 case Stmt::DeclStmtClass: {
6036 for (
const auto *D : DS->
decls()) {
6037 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
6040 if (VD->hasLocalStorage() && !VD->getInit())
6048 return ESR_CaseNotFound;
6052 return ESR_CaseNotFound;
6058 if (
const Expr *E = dyn_cast<Expr>(S)) {
6067 FullExpressionRAII
Scope(Info);
6071 return ESR_Succeeded;
6077 case Stmt::NullStmtClass:
6078 return ESR_Succeeded;
6080 case Stmt::DeclStmtClass: {
6082 for (
const auto *D : DS->
decls()) {
6083 const VarDecl *VD = dyn_cast_or_null<VarDecl>(D);
6087 if (
const auto *ESD = dyn_cast<CXXExpansionStmtDecl>(D)) {
6088 assert(ESD->getInstantiations() &&
"not expanded?");
6093 FullExpressionRAII
Scope(Info);
6095 !Info.noteFailure())
6097 if (!
Scope.destroy())
6100 return ESR_Succeeded;
6103 case Stmt::ReturnStmtClass: {
6105 FullExpressionRAII
Scope(Info);
6116 return Scope.destroy() ? ESR_Returned : ESR_Failed;
6119 case Stmt::CompoundStmtClass: {
6120 BlockScopeRAII
Scope(Info);
6123 for (
const auto *BI : CS->
body()) {
6125 if (ESR == ESR_Succeeded)
6127 else if (ESR != ESR_CaseNotFound) {
6128 if (ESR != ESR_Failed && !
Scope.destroy())
6134 return ESR_CaseNotFound;
6135 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
6138 case Stmt::IfStmtClass: {
6142 BlockScopeRAII
Scope(Info);
6145 if (ESR != ESR_Succeeded) {
6146 if (ESR != ESR_Failed && !
Scope.destroy())
6156 if (!Info.InConstantContext)
6164 if (ESR != ESR_Succeeded) {
6165 if (ESR != ESR_Failed && !
Scope.destroy())
6170 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
6173 case Stmt::WhileStmtClass: {
6176 BlockScopeRAII
Scope(Info);
6188 if (ESR != ESR_Continue) {
6189 if (ESR != ESR_Failed && !
Scope.destroy())
6193 if (!
Scope.destroy())
6196 return ESR_Succeeded;
6199 case Stmt::DoStmtClass: {
6206 if (ESR != ESR_Continue)
6215 FullExpressionRAII CondScope(Info);
6217 !CondScope.destroy())
6220 return ESR_Succeeded;
6223 case Stmt::ForStmtClass: {
6225 BlockScopeRAII ForScope(Info);
6228 if (ESR != ESR_Succeeded) {
6229 if (ESR != ESR_Failed && !ForScope.destroy())
6235 BlockScopeRAII IterScope(Info);
6236 bool Continue =
true;
6242 if (!IterScope.destroy())
6250 if (ESR != ESR_Continue) {
6251 if (ESR != ESR_Failed && (!IterScope.destroy() || !ForScope.destroy()))
6256 if (
const auto *Inc = FS->
getInc()) {
6257 if (Inc->isValueDependent()) {
6261 FullExpressionRAII IncScope(Info);
6267 if (!IterScope.destroy())
6270 return ForScope.destroy() ? ESR_Succeeded : ESR_Failed;
6273 case Stmt::CXXForRangeStmtClass: {
6275 BlockScopeRAII
Scope(Info);
6280 if (ESR != ESR_Succeeded) {
6281 if (ESR != ESR_Failed && !
Scope.destroy())
6289 if (ESR != ESR_Succeeded) {
6290 if (ESR != ESR_Failed && !
Scope.destroy())
6302 if (ESR != ESR_Succeeded) {
6303 if (ESR != ESR_Failed && !
Scope.destroy())
6308 if (ESR != ESR_Succeeded) {
6309 if (ESR != ESR_Failed && !
Scope.destroy())
6322 bool Continue =
true;
6323 FullExpressionRAII CondExpr(Info);
6331 BlockScopeRAII InnerScope(Info);
6333 if (ESR != ESR_Succeeded) {
6334 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
6343 if (ESR != ESR_Continue) {
6344 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
6357 if (!InnerScope.destroy())
6361 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
6364 case Stmt::CXXExpansionStmtInstantiationClass: {
6365 BlockScopeRAII
Scope(Info);
6367 for (
const Stmt *PreambleStmt : Expansion->getPreambleStmts()) {
6369 if (ESR != ESR_Succeeded) {
6370 if (ESR != ESR_Failed && !
Scope.destroy())
6378 EvalStmtResult ESR = ESR_Succeeded;
6379 for (
const Stmt *Instantiation : Expansion->getInstantiations()) {
6381 if (ESR == ESR_Failed ||
6384 if (ESR != ESR_Continue) {
6386 assert(ESR == ESR_Succeeded || ESR == ESR_Returned);
6392 if (ESR == ESR_Continue)
6393 ESR = ESR_Succeeded;
6395 return Scope.destroy() ? ESR : ESR_Failed;
6398 case Stmt::SwitchStmtClass:
6401 case Stmt::ContinueStmtClass:
6402 case Stmt::BreakStmtClass: {
6404 Info.BreakContinueStack.push_back(B->getNamedLoopOrSwitch());
6408 case Stmt::LabelStmtClass:
6411 case Stmt::AttributedStmtClass: {
6413 const auto *SS = AS->getSubStmt();
6414 MSConstexprContextRAII ConstexprContext(
6418 auto LO = Info.Ctx.getLangOpts();
6419 if (LO.CXXAssumptions && !LO.MSVCCompat) {
6420 for (
auto *
Attr : AS->getAttrs()) {
6421 auto *AA = dyn_cast<CXXAssumeAttr>(
Attr);
6425 auto *Assumption = AA->getAssumption();
6426 if (Assumption->isValueDependent())
6429 if (Assumption->HasSideEffects(Info.Ctx))
6436 Info.CCEDiag(Assumption->getExprLoc(),
6437 diag::note_constexpr_assumption_failed);
6446 case Stmt::CaseStmtClass:
6447 case Stmt::DefaultStmtClass:
6449 case Stmt::CXXTryStmtClass:
6461 bool IsValueInitialization) {
6468 if (!CD->
isConstexpr() && !IsValueInitialization) {
6469 if (Info.getLangOpts().CPlusPlus11) {
6472 Info.CCEDiag(Loc, diag::note_constexpr_invalid_function, 1)
6474 Info.Note(CD->
getLocation(), diag::note_declared_at);
6476 Info.CCEDiag(Loc, diag::note_invalid_subexpr_in_const_expr);
6490 if (Info.checkingPotentialConstantExpression() && !
Definition &&
6498 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6507 Info.CCEDiag(CallLoc, diag::note_constexpr_virtual_call);
6510 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6516 (
Definition->isConstexpr() || (Info.CurrentCall->CanEvalMSConstexpr &&
6526 StringRef Name = DiagDecl->
getName();
6528 Name ==
"__assert_rtn" || Name ==
"__assert_fail" || Name ==
"_wassert";
6530 Info.FFDiag(CallLoc, diag::note_constexpr_assert_failed);
6535 if (Info.getLangOpts().CPlusPlus11) {
6538 auto *CD = dyn_cast<CXXConstructorDecl>(DiagDecl);
6539 if (CD && CD->isInheritingConstructor()) {
6540 auto *Inherited = CD->getInheritedConstructor().getConstructor();
6541 if (!Inherited->isConstexpr())
6542 DiagDecl = CD = Inherited;
6548 if (CD && CD->isInheritingConstructor())
6549 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_inhctor, 1)
6550 << CD->getInheritedConstructor().getConstructor()->getParent();
6552 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_function, 1)
6554 Info.Note(DiagDecl->
getLocation(), diag::note_declared_at);
6556 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6562struct CheckDynamicTypeHandler {
6564 typedef bool result_type;
6565 bool failed() {
return false; }
6566 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
6569 bool found(
APSInt &
Value, QualType SubobjType) {
return true; }
6570 bool found(APFloat &
Value, QualType SubobjType) {
return true; }
6578 if (
This.Designator.Invalid)
6590 if (
This.Designator.isOnePastTheEnd() ||
6591 This.Designator.isMostDerivedAnUnsizedArray()) {
6592 Info.FFDiag(E,
This.Designator.isOnePastTheEnd()
6593 ? diag::note_constexpr_access_past_end
6594 : diag::note_constexpr_access_unsized_array)
6597 }
else if (Polymorphic) {
6600 if (!Info.checkingPotentialConstantExpression() ||
6601 !
This.AllowConstexprUnknown) {
6605 Info.Ctx.getLValueReferenceType(
This.Designator.getType(Info.Ctx));
6606 Info.FFDiag(E, diag::note_constexpr_polymorphic_unknown_dynamic_type)
6614 CheckDynamicTypeHandler Handler{AK};
6637 unsigned PathLength) {
6638 assert(PathLength >=
Designator.MostDerivedPathLength && PathLength <=
6639 Designator.Entries.size() &&
"invalid path length");
6640 return (PathLength ==
Designator.MostDerivedPathLength)
6641 ?
Designator.MostDerivedType->getAsCXXRecordDecl()
6642 : getAsBaseClass(
Designator.Entries[PathLength - 1]);
6655 return std::nullopt;
6657 if (
This.Designator.Invalid)
6658 return std::nullopt;
6664 This.Designator.MostDerivedType->getAsCXXRecordDecl();
6665 if (!Class || (!Info.getLangOpts().CPlusPlus26 && Class->getNumVBases())) {
6667 return std::nullopt;
6675 for (
unsigned PathLength =
This.Designator.MostDerivedPathLength;
6676 PathLength <= Path.size(); ++PathLength) {
6677 switch (Info.isEvaluatingCtorDtor(
This.getLValueBase(),
6678 Path.slice(0, PathLength))) {
6679 case ConstructionPhase::Bases:
6680 case ConstructionPhase::DestroyingBases:
6685 case ConstructionPhase::None:
6686 case ConstructionPhase::AfterBases:
6687 case ConstructionPhase::AfterFields:
6688 case ConstructionPhase::Destroying:
6700 return std::nullopt;
6718 unsigned PathLength = DynType->PathLength;
6719 for (; PathLength <=
This.Designator.Entries.size(); ++PathLength) {
6722 Found->getCorrespondingMethodDeclaredInClass(Class,
false);
6732 if (Callee->isPureVirtual()) {
6733 Info.FFDiag(E, diag::note_constexpr_pure_virtual_call, 1) << Callee;
6734 Info.Note(Callee->getLocation(), diag::note_declared_at);
6740 if (!Info.Ctx.hasSameUnqualifiedType(Callee->getReturnType(),
6741 Found->getReturnType())) {
6742 CovariantAdjustmentPath.push_back(Callee->getReturnType());
6743 for (
unsigned CovariantPathLength = PathLength + 1;
6744 CovariantPathLength !=
This.Designator.Entries.size();
6745 ++CovariantPathLength) {
6749 Found->getCorrespondingMethodDeclaredInClass(NextClass,
false);
6750 if (
Next && !Info.Ctx.hasSameUnqualifiedType(
6751 Next->getReturnType(), CovariantAdjustmentPath.back()))
6752 CovariantAdjustmentPath.push_back(
Next->getReturnType());
6754 if (!Info.Ctx.hasSameUnqualifiedType(
Found->getReturnType(),
6755 CovariantAdjustmentPath.back()))
6756 CovariantAdjustmentPath.push_back(
Found->getReturnType());
6772 assert(
Result.isLValue() &&
6773 "unexpected kind of APValue for covariant return");
6774 if (
Result.isNullPointer())
6778 LVal.setFrom(Info.Ctx,
Result);
6780 const CXXRecordDecl *OldClass = Path[0]->getPointeeCXXRecordDecl();
6781 for (
unsigned I = 1; I != Path.size(); ++I) {
6782 const CXXRecordDecl *NewClass = Path[I]->getPointeeCXXRecordDecl();
6783 assert(OldClass && NewClass &&
"unexpected kind of covariant return");
6784 if (OldClass != NewClass &&
6787 OldClass = NewClass;
6799 if (BaseSpec.isVirtual())
6801 auto *BaseClass = BaseSpec.getType()->getAsCXXRecordDecl();
6803 return BaseSpec.getAccessSpecifier() ==
AS_public;
6806 auto *BaseClass = BaseSpec.getType()->getAsCXXRecordDecl();
6808 return BaseSpec.getAccessSpecifier() ==
AS_public;
6811 llvm_unreachable(
"Base is not a direct base of Derived");
6821 SubobjectDesignator &D = Ptr.Designator;
6827 if (Ptr.isNullPointer() && !E->
isGLValue())
6833 std::optional<DynamicType> DynType =
6845 assert(
C &&
"dynamic_cast target is not void pointer nor class");
6853 Ptr.setNull(Info.Ctx, E->
getType());
6860 DynType->Type->isDerivedFrom(
C)))
6862 else if (!Paths || Paths->begin() == Paths->end())
6864 else if (Paths->isAmbiguous(CQT))
6867 assert(Paths->front().Access !=
AS_public &&
"why did the cast fail?");
6870 Info.FFDiag(E, diag::note_constexpr_dynamic_cast_to_reference_failed)
6871 << DiagKind << Ptr.Designator.getType(Info.Ctx)
6872 << Info.Ctx.getCanonicalTagType(DynType->Type)
6880 for (
int PathLength = Ptr.Designator.Entries.size();
6881 PathLength >= (
int)DynType->PathLength; --PathLength) {
6886 if (PathLength > (
int)DynType->PathLength &&
6889 return RuntimeCheckFailed(
nullptr);
6896 if (DynType->Type->isDerivedFrom(
C, Paths) && !Paths.
isAmbiguous(CQT) &&
6909 return RuntimeCheckFailed(&Paths);
6913struct StartLifetimeOfUnionMemberHandler {
6915 const Expr *LHSExpr;
6916 const FieldDecl *
Field;
6918 bool Failed =
false;
6921 typedef bool result_type;
6922 bool failed() {
return Failed; }
6923 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
6938 }
else if (DuringInit) {
6942 Info.FFDiag(LHSExpr,
6943 diag::note_constexpr_union_member_change_during_init);
6952 llvm_unreachable(
"wrong value kind for union object");
6954 bool found(APFloat &
Value, QualType SubobjType) {
6955 llvm_unreachable(
"wrong value kind for union object");
6960const AccessKinds StartLifetimeOfUnionMemberHandler::AccessKind;
6967 const Expr *LHSExpr,
6968 const LValue &LHS) {
6969 if (LHS.InvalidBase || LHS.Designator.Invalid)
6975 unsigned PathLength = LHS.Designator.Entries.size();
6976 for (
const Expr *E = LHSExpr; E !=
nullptr;) {
6978 if (
auto *ME = dyn_cast<MemberExpr>(E)) {
6979 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
6982 if (!FD || FD->getType()->isReferenceType())
6986 if (FD->getParent()->isUnion()) {
6991 FD->getType()->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
6992 if (!RD || RD->hasTrivialDefaultConstructor())
6993 UnionPathLengths.push_back({PathLength - 1, FD});
6999 LHS.Designator.Entries[PathLength]
7000 .getAsBaseOrMember().getPointer()));
7004 }
else if (
auto *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
7006 auto *
Base = ASE->getBase()->IgnoreImplicit();
7007 if (!
Base->getType()->isArrayType())
7013 }
else if (
auto *ICE = dyn_cast<ImplicitCastExpr>(E)) {
7016 if (ICE->getCastKind() == CK_NoOp)
7018 if (ICE->getCastKind() != CK_DerivedToBase &&
7019 ICE->getCastKind() != CK_UncheckedDerivedToBase)
7023 if (Elt->isVirtual()) {
7032 LHS.Designator.Entries[PathLength]
7033 .getAsBaseOrMember().getPointer()));
7043 if (UnionPathLengths.empty())
7048 CompleteObject Obj =
7052 for (std::pair<unsigned, const FieldDecl *> LengthAndField :
7053 llvm::reverse(UnionPathLengths)) {
7055 SubobjectDesignator D = LHS.Designator;
7056 D.truncate(Info.Ctx, LHS.Base, LengthAndField.first);
7058 bool DuringInit = Info.isEvaluatingCtorDtor(LHS.Base, D.Entries) ==
7059 ConstructionPhase::AfterBases;
7060 StartLifetimeOfUnionMemberHandler StartLifetime{
7061 Info, LHSExpr, LengthAndField.second, DuringInit};
7070 CallRef
Call, EvalInfo &Info,
bool NonNull =
false,
7071 APValue **EvaluatedArg =
nullptr) {
7078 APValue &
V = PVD ? Info.CurrentCall->createParam(
Call, PVD, LV)
7079 : Info.CurrentCall->createTemporary(Arg, Arg->
getType(),
7080 ScopeKind::Call, LV);
7086 if (
NonNull &&
V.isLValue() &&
V.isNullPointer()) {
7087 Info.CCEDiag(Arg, diag::note_non_null_attribute_failed);
7100 bool RightToLeft =
false,
7101 LValue *ObjectArg =
nullptr) {
7103 llvm::SmallBitVector ForbiddenNullArgs;
7104 if (Callee->hasAttr<NonNullAttr>()) {
7105 ForbiddenNullArgs.resize(Args.size());
7106 for (
const auto *
Attr : Callee->specific_attrs<NonNullAttr>()) {
7107 if (!
Attr->args_size()) {
7108 ForbiddenNullArgs.set();
7111 for (
auto Idx :
Attr->args()) {
7112 unsigned ASTIdx = Idx.getASTIndex();
7113 if (ASTIdx >= Args.size())
7115 ForbiddenNullArgs[ASTIdx] =
true;
7119 for (
unsigned I = 0; I < Args.size(); I++) {
7120 unsigned Idx = RightToLeft ? Args.size() - I - 1 : I;
7122 Idx < Callee->getNumParams() ? Callee->getParamDecl(Idx) :
nullptr;
7123 bool NonNull = !ForbiddenNullArgs.empty() && ForbiddenNullArgs[Idx];
7128 if (!Info.noteFailure())
7133 ObjectArg->setFrom(Info.Ctx, *That);
7142 bool CopyObjectRepresentation) {
7144 CallStackFrame *Frame = Info.CurrentCall;
7145 APValue *RefValue = Info.getParamSlot(Frame->Arguments, Param);
7153 RefLValue.setFrom(Info.Ctx, *RefValue);
7156 CopyObjectRepresentation);
7162 const LValue *ObjectArg,
const Expr *E,
7164 const Stmt *Body, EvalInfo &Info,
7166 if (!Info.CheckCallLimit(CallLoc))
7179 auto IsTrivialMemoryOperation = [&](
const CXXMethodDecl *MD) {
7189 if (IsTrivialMemoryOperation(MD)) {
7202 ObjectArg->moveInto(
Result);
7211 if (!Info.checkingPotentialConstantExpression())
7213 Frame.LambdaThisCaptureField);
7216 StmtResult Ret = {
Result, ResultSlot};
7218 if (ESR == ESR_Succeeded) {
7219 if (Callee->getReturnType()->isVoidType())
7221 Info.FFDiag(Callee->getEndLoc(), diag::note_constexpr_no_return);
7223 return ESR == ESR_Returned;
7230 bool IsCompleteClass =
true);
7236 bool IsCompleteClass =
true) {
7237 CallScopeRAII CallScope(Info);
7244 CallScope.destroy();
7252 bool IsCompleteClass) {
7255 if (!Info.CheckCallLimit(CallLoc))
7259 if (!Info.getLangOpts().CPlusPlus26 && RD->
getNumVBases()) {
7260 Info.FFDiag(CallLoc, diag::note_constexpr_virtual_base) << RD;
7264 EvalInfo::EvaluatingConstructorRAII EvalObj(
7266 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries},
7273 StmtResult Ret = {RetVal,
nullptr};
7278 if ((*I)->getInit()->isValueDependent()) {
7282 FullExpressionRAII InitScope(Info);
7284 !InitScope.destroy())
7307 if (!
Result.hasValue()) {
7309 unsigned NonVirtualBases = countNonVirtualBases(RD);
7321 BlockScopeRAII LifetimeExtendedScope(Info);
7324 unsigned BasesSeen = 0;
7325 unsigned VirtualBasesSeen = 0;
7326 unsigned NonVirtualBases = countNonVirtualBases(RD);
7329 auto SkipToField = [&](
FieldDecl *FD,
bool Indirect) {
7334 assert(Indirect &&
"fields out of order?");
7340 assert(FieldIt != RD->
field_end() &&
"missing field?");
7341 if (!FieldIt->isUnnamedBitField())
7344 Result.getStructField(FieldIt->getFieldIndex()));
7349 LValue Subobject =
This;
7350 LValue SubobjectParent =
This;
7355 if (I->isBaseInitializer()) {
7356 QualType BaseType(I->getBaseClass(), 0);
7357 if (I->isBaseVirtual()) {
7358 if (
This.pointsToCompleteClass(RD)) {
7360 BaseType->getAsCXXRecordDecl(),
7363 Value = &
Result.getStructVirtualBase(VirtualBasesSeen++);
7370 BaseType->getAsCXXRecordDecl(), &Layout))
7374 }
else if ((FD = I->getMember())) {
7381 SkipToField(FD,
false);
7387 auto IndirectFieldChain = IFD->chain();
7388 for (
auto *
C : IndirectFieldChain) {
7397 (
Value->isUnion() &&
7410 if (
C == IndirectFieldChain.back())
7411 SubobjectParent = Subobject;
7417 if (
C == IndirectFieldChain.front() && !RD->
isUnion())
7418 SkipToField(FD,
true);
7423 llvm_unreachable(
"unknown base initializer kind");
7430 if (
Init->isValueDependent()) {
7434 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &SubobjectParent,
7436 FullExpressionRAII InitScope(Info);
7442 if (!Info.noteFailure())
7451 if (!Info.noteFailure())
7459 if (I->isBaseInitializer() && BasesSeen == NonVirtualBases)
7460 EvalObj.finishedConstructingBases();
7465 for (; FieldIt != RD->
field_end(); ++FieldIt) {
7466 if (!FieldIt->isUnnamedBitField())
7469 Result.getStructField(FieldIt->getFieldIndex()));
7473 EvalObj.finishedConstructingFields();
7477 LifetimeExtendedScope.destroy();
7482 QualType T,
bool IsCompleteClass =
true) {
7487 if (
Value.isAbsent() && !
T->isNullPtrType()) {
7489 This.moveInto(Printable);
7491 diag::note_constexpr_destroy_out_of_lifetime)
7492 << Printable.
getAsString(Info.Ctx, Info.Ctx.getLValueReferenceType(
T));
7508 LValue ElemLV =
This;
7509 ElemLV.addArray(Info, &LocE, CAT);
7516 if (Size && Size >
Value.getArrayInitializedElts())
7521 for (Size =
Value.getArraySize(); Size != 0; --Size) {
7522 APValue &Elem =
Value.getArrayInitializedElt(Size - 1);
7535 if (
T.isDestructedType()) {
7537 diag::note_constexpr_unsupported_destruction)
7546 if (!Info.getLangOpts().CPlusPlus26 && RD->
getNumVBases()) {
7547 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_virtual_base) << RD;
7575 if (!Info.CheckCallLimit(CallRange.
getBegin()))
7584 CallStackFrame Frame(Info, CallRange,
Definition, &
This,
nullptr,
7588 EvalInfo::EvaluatingDestructorRAII EvalObj(
7590 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries});
7591 unsigned NonVirtualBases = countNonVirtualBases(RD);
7593 unsigned BasesLeft = NonVirtualBases;
7594 if (!EvalObj.DidInsert) {
7601 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_double_destroy);
7608 StmtResult Ret = {RetVal,
nullptr};
7621 for (
const FieldDecl *FD : llvm::reverse(Fields)) {
7622 if (FD->isUnnamedBitField())
7625 LValue Subobject =
This;
7629 APValue *SubobjectValue = &
Value.getStructField(FD->getFieldIndex());
7635 if (BasesLeft != 0 || NumVirtualBases != 0)
7636 EvalObj.startedDestroyingBases();
7640 if (
Base.isVirtual())
7645 LValue Subobject =
This;
7647 BaseType->getAsCXXRecordDecl(), &Layout))
7650 APValue *SubobjectValue = &
Value.getStructBase(BasesLeft);
7655 assert(BasesLeft == 0 &&
"NumBases was wrong?");
7658 if (IsCompleteClass) {
7659 unsigned VirtualBasesLeft = NumVirtualBases;
7664 LValue Subobject =
This;
7666 BaseType->getAsCXXRecordDecl(),
7670 APValue *SubobjectValue = &
Value.getStructVirtualBase(VirtualBasesLeft);
7675 assert(VirtualBasesLeft == 0 &&
"NumVirtualBases was wrong?");
7684struct DestroyObjectHandler {
7690 typedef bool result_type;
7691 bool failed() {
return false; }
7692 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
7697 Info.FFDiag(E, diag::note_constexpr_destroy_complex_elem);
7700 bool found(APFloat &
Value, QualType SubobjType) {
7701 Info.FFDiag(E, diag::note_constexpr_destroy_complex_elem);
7722 if (Info.EvalStatus.HasSideEffects)
7733 if (Info.checkingPotentialConstantExpression() ||
7734 Info.SpeculativeEvaluationDepth)
7738 auto Caller = Info.getStdAllocatorCaller(
"allocate");
7740 Info.FFDiag(E->
getExprLoc(), Info.getLangOpts().CPlusPlus20
7741 ? diag::note_constexpr_new_untyped
7742 : diag::note_constexpr_new);
7746 QualType ElemType = Caller.ElemType;
7749 diag::note_constexpr_new_not_complete_object_type)
7757 bool IsNothrow =
false;
7758 for (
unsigned I = 1, N = E->
getNumArgs(); I != N; ++I) {
7766 APInt Size, Remainder;
7767 APInt ElemSizeAP(ByteSize.getBitWidth(), ElemSize.
getQuantity());
7768 APInt::udivrem(ByteSize, ElemSizeAP, Size, Remainder);
7769 if (Remainder != 0) {
7771 Info.FFDiag(E->
getExprLoc(), diag::note_constexpr_operator_new_bad_size)
7772 << ByteSize <<
APSInt(ElemSizeAP,
true) << ElemType;
7776 if (!Info.CheckArraySize(E->
getBeginLoc(), ByteSize.getActiveBits(),
7777 Size.getZExtValue(), !IsNothrow)) {
7785 QualType AllocType = Info.Ctx.getConstantArrayType(
7787 APValue *Val = Info.createHeapAlloc(Caller.Call, AllocType,
Result);
7796 return DD->isVirtual();
7803 return DD->isVirtual() ? DD->getOperatorDelete() :
nullptr;
7814 DynAlloc::Kind DeallocKind) {
7815 auto PointerAsString = [&] {
7816 return Pointer.toString(Info.Ctx, Info.Ctx.VoidPtrTy);
7821 Info.FFDiag(E, diag::note_constexpr_delete_not_heap_alloc)
7822 << PointerAsString();
7825 return std::nullopt;
7828 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
7830 Info.FFDiag(E, diag::note_constexpr_double_delete);
7831 return std::nullopt;
7834 if (DeallocKind != (*Alloc)->getKind()) {
7836 Info.FFDiag(E, diag::note_constexpr_new_delete_mismatch)
7837 << DeallocKind << (*Alloc)->getKind() << AllocType;
7839 return std::nullopt;
7842 bool Subobject =
false;
7843 if (DeallocKind == DynAlloc::New) {
7844 Subobject =
Pointer.Designator.MostDerivedPathLength != 0 ||
7845 Pointer.Designator.isOnePastTheEnd();
7847 Subobject =
Pointer.Designator.Entries.size() != 1 ||
7848 Pointer.Designator.Entries[0].getAsArrayIndex() != 0;
7851 Info.FFDiag(E, diag::note_constexpr_delete_subobject)
7852 << PointerAsString() <<
Pointer.Designator.isOnePastTheEnd();
7853 return std::nullopt;
7861 if (Info.checkingPotentialConstantExpression() ||
7862 Info.SpeculativeEvaluationDepth)
7866 if (!Info.getStdAllocatorCaller(
"deallocate")) {
7874 for (
unsigned I = 1, N = E->
getNumArgs(); I != N; ++I)
7877 if (
Pointer.Designator.Invalid)
7882 if (
Pointer.isNullPointer()) {
7883 Info.CCEDiag(E->
getExprLoc(), diag::note_constexpr_deallocate_null);
7899class BitCastBuffer {
7905 SmallVector<std::optional<unsigned char>, 32> Bytes;
7907 static_assert(std::numeric_limits<unsigned char>::digits >= 8,
7908 "Need at least 8 bit unsigned char");
7910 bool TargetIsLittleEndian;
7913 BitCastBuffer(CharUnits Width,
bool TargetIsLittleEndian)
7914 : Bytes(Width.getQuantity()),
7915 TargetIsLittleEndian(TargetIsLittleEndian) {}
7917 [[nodiscard]]
bool readObject(CharUnits Offset, CharUnits Width,
7918 SmallVectorImpl<unsigned char> &Output)
const {
7919 for (CharUnits I = Offset, E = Offset + Width; I != E; ++I) {
7922 if (!Bytes[I.getQuantity()])
7924 Output.push_back(*Bytes[I.getQuantity()]);
7926 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
7927 std::reverse(Output.begin(), Output.end());
7931 void writeObject(CharUnits Offset, SmallVectorImpl<unsigned char> &Input) {
7932 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
7933 std::reverse(Input.begin(), Input.end());
7936 for (
unsigned char Byte : Input) {
7937 assert(!Bytes[Offset.
getQuantity() + Index] &&
"overwriting a byte?");
7943 size_t size() {
return Bytes.size(); }
7948class APValueToBufferConverter {
7950 BitCastBuffer Buffer;
7953 APValueToBufferConverter(EvalInfo &Info, CharUnits ObjectWidth,
7956 Buffer(ObjectWidth, Info.Ctx.getTargetInfo().isLittleEndian()),
7959 bool visit(
const APValue &Val, QualType Ty) {
7964 bool visit(
const APValue &Val, QualType Ty, CharUnits Offset) {
7965 assert((
size_t)Offset.
getQuantity() <= Buffer.size());
7978 return visitInt(Val.
getInt(), Ty, Offset);
7980 return visitFloat(Val.
getFloat(), Ty, Offset);
7982 return visitArray(Val, Ty, Offset);
7984 return visitRecord(Val, Ty, Offset);
7986 return visitVector(Val, Ty, Offset);
7990 return visitComplex(Val, Ty, Offset);
8000 diag::note_constexpr_bit_cast_unsupported_type)
8005 llvm_unreachable(
"Unhandled APValue::ValueKind");
8008 bool visitRecord(
const APValue &Val, QualType Ty, CharUnits Offset) {
8010 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD);
8013 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
8014 for (
size_t I = 0, E = CXXRD->getNumBases(); I != E; ++I) {
8015 const CXXBaseSpecifier &BS = CXXRD->bases_begin()[I];
8020 if (!
Base.isStruct())
8023 if (!visitRecord(Base, BS.
getType(),
8030 unsigned FieldIdx = 0;
8031 for (FieldDecl *FD : RD->
fields()) {
8032 if (FD->isBitField()) {
8034 diag::note_constexpr_bit_cast_unsupported_bitfield);
8040 assert(FieldOffsetBits % Info.Ctx.getCharWidth() == 0 &&
8041 "only bit-fields can have sub-char alignment");
8042 CharUnits FieldOffset =
8043 Info.Ctx.toCharUnitsFromBits(FieldOffsetBits) + Offset;
8044 QualType FieldTy = FD->getType();
8053 bool visitArray(
const APValue &Val, QualType Ty, CharUnits Offset) {
8059 CharUnits ElemWidth = Info.Ctx.getTypeSizeInChars(CAT->
getElementType());
8063 for (
unsigned I = 0; I != NumInitializedElts; ++I) {
8065 if (!visit(SubObj, CAT->
getElementType(), Offset + I * ElemWidth))
8072 for (
unsigned I = NumInitializedElts; I != ArraySize; ++I) {
8073 if (!visit(Filler, CAT->
getElementType(), Offset + I * ElemWidth))
8081 bool visitComplex(
const APValue &Val, QualType Ty, CharUnits Offset) {
8082 const ComplexType *ComplexTy = Ty->
castAs<ComplexType>();
8084 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
8089 Offset + (0 * EltSizeChars)))
8092 Offset + (1 * EltSizeChars)))
8096 Offset + (0 * EltSizeChars)))
8099 Offset + (1 * EltSizeChars)))
8106 bool visitVector(
const APValue &Val, QualType Ty, CharUnits Offset) {
8107 const VectorType *VTy = Ty->
castAs<VectorType>();
8120 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
8122 llvm::APInt Res = llvm::APInt::getZero(NElts);
8123 for (
unsigned I = 0; I < NElts; ++I) {
8125 assert(EltAsInt.isUnsigned() && EltAsInt.getBitWidth() == 1 &&
8126 "bool vector element must be 1-bit unsigned integer!");
8128 Res.insertBits(EltAsInt, BigEndian ? (NElts - I - 1) : I);
8131 SmallVector<uint8_t, 8> Bytes(NElts / 8);
8132 llvm::StoreIntToMemory(Res, &*Bytes.begin(), NElts / 8);
8133 Buffer.writeObject(Offset, Bytes);
8137 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
8138 for (
unsigned I = 0; I < NElts; ++I) {
8139 if (!visit(Val.
getVectorElt(I), EltTy, Offset + I * EltSizeChars))
8147 bool visitInt(
const APSInt &Val, QualType Ty, CharUnits Offset) {
8148 APSInt AdjustedVal = Val;
8149 unsigned Width = AdjustedVal.getBitWidth();
8151 Width = Info.Ctx.getTypeSize(Ty);
8152 AdjustedVal = AdjustedVal.extend(Width);
8155 SmallVector<uint8_t, 8> Bytes(Width / 8);
8156 llvm::StoreIntToMemory(AdjustedVal, &*Bytes.begin(), Width / 8);
8157 Buffer.writeObject(Offset, Bytes);
8161 bool visitFloat(
const APFloat &Val, QualType Ty, CharUnits Offset) {
8162 APSInt AsInt(Val.bitcastToAPInt());
8163 return visitInt(AsInt, Ty, Offset);
8167 static std::optional<BitCastBuffer>
8169 CharUnits DstSize = Info.Ctx.getTypeSizeInChars(BCE->
getType());
8170 APValueToBufferConverter Converter(Info, DstSize, BCE);
8172 return std::nullopt;
8173 return Converter.Buffer;
8178class BufferToAPValueConverter {
8180 const BitCastBuffer &Buffer;
8183 BufferToAPValueConverter(EvalInfo &Info,
const BitCastBuffer &Buffer,
8185 : Info(Info), Buffer(Buffer), BCE(BCE) {}
8190 std::nullopt_t unsupportedType(QualType Ty) {
8192 diag::note_constexpr_bit_cast_unsupported_type)
8194 return std::nullopt;
8197 std::nullopt_t unrepresentableValue(QualType Ty,
const APSInt &Val) {
8199 diag::note_constexpr_bit_cast_unrepresentable_value)
8201 return std::nullopt;
8204 std::optional<APValue> visit(
const BuiltinType *
T, CharUnits Offset,
8205 const EnumType *EnumSugar =
nullptr) {
8207 uint64_t NullValue = Info.Ctx.getTargetNullPointerValue(QualType(
T, 0));
8208 return APValue((Expr *)
nullptr,
8210 APValue::NoLValuePath{},
true);
8213 CharUnits
SizeOf = Info.Ctx.getTypeSizeInChars(
T);
8219 const llvm::fltSemantics &Semantics =
8220 Info.Ctx.getFloatTypeSemantics(QualType(
T, 0));
8221 unsigned NumBits = llvm::APFloatBase::getSizeInBits(Semantics);
8222 assert(NumBits % 8 == 0);
8228 SmallVector<uint8_t, 8> Bytes;
8229 if (!Buffer.readObject(Offset,
SizeOf, Bytes)) {
8232 bool IsStdByte = EnumSugar && EnumSugar->isStdByteType();
8236 if (!IsStdByte && !IsUChar) {
8237 QualType DisplayType(EnumSugar ? (
const Type *)EnumSugar :
T, 0);
8239 diag::note_constexpr_bit_cast_indet_dest)
8240 << DisplayType << Info.Ctx.getLangOpts().CharIsSigned;
8241 return std::nullopt;
8247 APSInt Val(
SizeOf.getQuantity() * Info.Ctx.getCharWidth(),
true);
8248 llvm::LoadIntFromMemory(Val, &*Bytes.begin(), Bytes.size());
8253 unsigned IntWidth = Info.Ctx.getIntWidth(QualType(
T, 0));
8254 if (IntWidth != Val.getBitWidth()) {
8255 APSInt Truncated = Val.trunc(IntWidth);
8256 if (Truncated.extend(Val.getBitWidth()) != Val)
8257 return unrepresentableValue(QualType(
T, 0), Val);
8265 const llvm::fltSemantics &Semantics =
8266 Info.Ctx.getFloatTypeSemantics(QualType(
T, 0));
8270 return unsupportedType(QualType(
T, 0));
8273 std::optional<APValue> visit(
const RecordType *RTy, CharUnits Offset) {
8274 const RecordDecl *RD = RTy->getAsRecordDecl();
8276 return std::nullopt;
8277 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD);
8279 unsigned NumBases = 0;
8280 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
8281 NumBases = CXXRD->getNumBases();
8286 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
8287 for (
size_t I = 0, E = CXXRD->getNumBases(); I != E; ++I) {
8288 const CXXBaseSpecifier &BS = CXXRD->bases_begin()[I];
8291 std::optional<APValue> SubObj = visitType(
8294 return std::nullopt;
8295 ResultVal.getStructBase(I) = *SubObj;
8300 unsigned FieldIdx = 0;
8301 for (FieldDecl *FD : RD->
fields()) {
8304 if (FD->isBitField()) {
8306 diag::note_constexpr_bit_cast_unsupported_bitfield);
8307 return std::nullopt;
8311 assert(FieldOffsetBits % Info.Ctx.getCharWidth() == 0);
8313 CharUnits FieldOffset =
8316 QualType FieldTy = FD->getType();
8317 std::optional<APValue> SubObj = visitType(FieldTy, FieldOffset);
8319 return std::nullopt;
8320 ResultVal.getStructField(FieldIdx) = *SubObj;
8327 std::optional<APValue> visit(
const EnumType *Ty, CharUnits Offset) {
8328 QualType RepresentationType =
8329 Ty->getDecl()->getDefinitionOrSelf()->getIntegerType();
8330 assert(!RepresentationType.
isNull() &&
8331 "enum forward decl should be caught by Sema");
8332 const auto *AsBuiltin =
8336 return visit(AsBuiltin, Offset, Ty);
8339 std::optional<APValue> visit(
const ConstantArrayType *Ty, CharUnits Offset) {
8341 CharUnits ElementWidth = Info.Ctx.getTypeSizeInChars(Ty->
getElementType());
8343 APValue ArrayValue(APValue::UninitArray(), Size, Size);
8344 for (
size_t I = 0; I !=
Size; ++I) {
8345 std::optional<APValue> ElementValue =
8348 return std::nullopt;
8349 ArrayValue.getArrayInitializedElt(I) = std::move(*ElementValue);
8355 std::optional<APValue> visit(
const ComplexType *Ty, CharUnits Offset) {
8357 CharUnits ElementWidth = Info.Ctx.getTypeSizeInChars(ElementType);
8360 std::optional<APValue> Values[2];
8361 for (
unsigned I = 0; I != 2; ++I) {
8362 Values[I] = visitType(Ty->
getElementType(), Offset + I * ElementWidth);
8364 return std::nullopt;
8368 return APValue(Values[0]->getInt(), Values[1]->getInt());
8369 return APValue(Values[0]->getFloat(), Values[1]->getFloat());
8372 std::optional<APValue> visit(
const VectorType *VTy, CharUnits Offset) {
8378 SmallVector<APValue, 4> Elts;
8379 Elts.reserve(NElts);
8389 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
8391 SmallVector<uint8_t, 8> Bytes;
8392 Bytes.reserve(NElts / 8);
8394 return std::nullopt;
8396 APSInt SValInt(NElts,
true);
8397 llvm::LoadIntFromMemory(SValInt, &*Bytes.begin(), Bytes.size());
8399 for (
unsigned I = 0; I < NElts; ++I) {
8401 SValInt.extractBits(1, (BigEndian ? NElts - I - 1 : I) * EltSize);
8408 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
8409 for (
unsigned I = 0; I < NElts; ++I) {
8410 std::optional<APValue> EltValue =
8411 visitType(EltTy, Offset + I * EltSizeChars);
8413 return std::nullopt;
8414 Elts.push_back(std::move(*EltValue));
8418 return APValue(Elts.data(), Elts.size());
8421 std::optional<APValue> visit(
const Type *Ty, CharUnits Offset) {
8422 return unsupportedType(QualType(Ty, 0));
8425 std::optional<APValue> visitType(QualType Ty, CharUnits Offset) {
8429#define TYPE(Class, Base) \
8431 return visit(cast<Class##Type>(Can.getTypePtr()), Offset);
8432#define ABSTRACT_TYPE(Class, Base)
8433#define NON_CANONICAL_TYPE(Class, Base) \
8435 llvm_unreachable("non-canonical type should be impossible!");
8436#define DEPENDENT_TYPE(Class, Base) \
8439 "dependent types aren't supported in the constant evaluator!");
8440#define NON_CANONICAL_UNLESS_DEPENDENT(Class, Base) \
8442 llvm_unreachable("either dependent or not canonical!");
8443#include "clang/AST/TypeNodes.inc"
8445 llvm_unreachable(
"Unhandled Type::TypeClass");
8450 static std::optional<APValue> convert(EvalInfo &Info, BitCastBuffer &Buffer,
8452 BufferToAPValueConverter Converter(Info, Buffer, BCE);
8457static bool checkBitCastConstexprEligibilityType(SourceLocation Loc,
8458 QualType Ty, EvalInfo *Info,
8459 const ASTContext &Ctx,
8460 bool CheckingDest) {
8463 auto diag = [&](
int Reason) {
8465 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_invalid_type)
8466 << CheckingDest << (Reason == 4) << Reason;
8469 auto note = [&](
int Construct, QualType NoteTy, SourceLocation NoteLoc) {
8471 Info->Note(NoteLoc, diag::note_constexpr_bit_cast_invalid_subtype)
8472 << NoteTy << Construct << Ty;
8486 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(
Record)) {
8487 for (CXXBaseSpecifier &BS : CXXRD->bases())
8488 if (!checkBitCastConstexprEligibilityType(Loc, BS.
getType(), Info, Ctx,
8492 for (FieldDecl *FD :
Record->fields()) {
8493 if (FD->getType()->isReferenceType())
8495 if (!checkBitCastConstexprEligibilityType(Loc, FD->getType(), Info, Ctx,
8497 return note(0, FD->getType(), FD->getBeginLoc());
8503 Info, Ctx, CheckingDest))
8506 if (
const auto *VTy = Ty->
getAs<VectorType>()) {
8518 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_invalid_vector)
8519 << QualType(VTy, 0) << EltSize << NElts << Ctx.
getCharWidth();
8529 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_unsupported_type)
8538static bool checkBitCastConstexprEligibility(EvalInfo *Info,
8539 const ASTContext &Ctx,
8541 bool DestOK = checkBitCastConstexprEligibilityType(
8543 bool SourceOK = DestOK && checkBitCastConstexprEligibilityType(
8549static bool handleRValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
8552 assert(
CHAR_BIT == 8 && Info.Ctx.getTargetInfo().getCharWidth() == 8 &&
8553 "no host or target supports non 8-bit chars");
8555 if (!checkBitCastConstexprEligibility(&Info, Info.Ctx, BCE))
8559 std::optional<BitCastBuffer> Buffer =
8560 APValueToBufferConverter::convert(Info, SourceRValue, BCE);
8565 std::optional<APValue> MaybeDestValue =
8566 BufferToAPValueConverter::convert(Info, *Buffer, BCE);
8567 if (!MaybeDestValue)
8570 DestValue = std::move(*MaybeDestValue);
8574static bool handleLValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
8577 assert(
CHAR_BIT == 8 && Info.Ctx.getTargetInfo().getCharWidth() == 8 &&
8578 "no host or target supports non 8-bit chars");
8580 "LValueToRValueBitcast requires an lvalue operand!");
8582 LValue SourceLValue;
8584 SourceLValue.setFrom(Info.Ctx, SourceValue);
8587 SourceRValue,
true))
8590 return handleRValueToRValueBitCast(Info, DestValue, SourceRValue, BCE);
8593template <
class Derived>
8594class ExprEvaluatorBase
8595 :
public ConstStmtVisitor<Derived, bool> {
8597 Derived &getDerived() {
return static_cast<Derived&
>(*this); }
8598 bool DerivedSuccess(
const APValue &
V,
const Expr *E) {
8599 return getDerived().Success(
V, E);
8601 bool DerivedZeroInitialization(
const Expr *E) {
8602 return getDerived().ZeroInitialization(E);
8608 template<
typename ConditionalOperator>
8609 void CheckPotentialConstantConditional(
const ConditionalOperator *E) {
8610 assert(Info.checkingPotentialConstantExpression());
8613 SmallVector<PartialDiagnosticAt, 8>
Diag;
8615 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
8622 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
8624 Info.EvalStatus.DiagEmitted =
false;
8630 Error(E, diag::note_constexpr_conditional_never_const);
8634 template<
typename ConditionalOperator>
8635 bool HandleConditionalOperator(
const ConditionalOperator *E) {
8638 if (Info.checkingPotentialConstantExpression() && Info.noteFailure()) {
8639 CheckPotentialConstantConditional(E);
8642 if (Info.noteFailure()) {
8650 return StmtVisitorTy::Visit(EvalExpr);
8655 typedef ConstStmtVisitor<Derived, bool> StmtVisitorTy;
8656 typedef ExprEvaluatorBase ExprEvaluatorBaseTy;
8658 OptionalDiagnostic CCEDiag(
const Expr *E,
diag::kind D) {
8659 return Info.CCEDiag(E, D);
8662 bool ZeroInitialization(
const Expr *E) {
return Error(E); }
8664 bool IsConstantEvaluatedBuiltinCall(
const CallExpr *E) {
8666 return BuiltinOp != 0 &&
8667 Info.Ctx.BuiltinInfo.isConstantEvaluated(BuiltinOp);
8671 ExprEvaluatorBase(EvalInfo &Info) : Info(Info) {}
8673 EvalInfo &getEvalInfo() {
return Info; }
8681 bool Error(
const Expr *E) {
8682 return Error(E, diag::note_invalid_subexpr_in_const_expr);
8685 bool VisitStmt(
const Stmt *) {
8686 llvm_unreachable(
"Expression evaluator should not be called on stmts");
8688 bool VisitExpr(
const Expr *E) {
8692 bool VisitEmbedExpr(
const EmbedExpr *E) {
8693 const auto It = E->
begin();
8694 return StmtVisitorTy::Visit(*It);
8697 bool VisitPredefinedExpr(
const PredefinedExpr *E) {
8700 bool VisitConstantExpr(
const ConstantExpr *E) {
8704 return StmtVisitorTy::Visit(E->
getSubExpr());
8707 bool VisitParenExpr(
const ParenExpr *E)
8708 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8709 bool VisitUnaryExtension(
const UnaryOperator *E)
8710 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8711 bool VisitUnaryPlus(
const UnaryOperator *E)
8712 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8713 bool VisitChooseExpr(
const ChooseExpr *E)
8715 bool VisitGenericSelectionExpr(
const GenericSelectionExpr *E)
8717 bool VisitSubstNonTypeTemplateParmExpr(
const SubstNonTypeTemplateParmExpr *E)
8719 bool VisitCXXDefaultArgExpr(
const CXXDefaultArgExpr *E) {
8720 TempVersionRAII RAII(*Info.CurrentCall);
8721 SourceLocExprScopeGuard Guard(E, Info.CurrentCall->CurSourceLocExprScope);
8722 return StmtVisitorTy::Visit(E->
getExpr());
8724 bool VisitCXXDefaultInitExpr(
const CXXDefaultInitExpr *E) {
8725 TempVersionRAII RAII(*Info.CurrentCall);
8729 SourceLocExprScopeGuard Guard(E, Info.CurrentCall->CurSourceLocExprScope);
8730 return StmtVisitorTy::Visit(E->
getExpr());
8733 bool VisitExprWithCleanups(
const ExprWithCleanups *E) {
8734 FullExpressionRAII Scope(Info);
8735 return StmtVisitorTy::Visit(E->
getSubExpr()) && Scope.destroy();
8740 bool VisitCXXBindTemporaryExpr(
const CXXBindTemporaryExpr *E) {
8741 return StmtVisitorTy::Visit(E->
getSubExpr());
8744 bool VisitCXXReinterpretCastExpr(
const CXXReinterpretCastExpr *E) {
8746 CCEDiag(E, diag::note_constexpr_invalid_cast)
8747 << diag::ConstexprInvalidCastKind::Reinterpret;
8748 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8750 bool VisitCXXDynamicCastExpr(
const CXXDynamicCastExpr *E) {
8751 if (!Info.Ctx.getLangOpts().CPlusPlus20)
8752 CCEDiag(E, diag::note_constexpr_invalid_cast)
8753 << diag::ConstexprInvalidCastKind::Dynamic;
8754 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8756 bool VisitBuiltinBitCastExpr(
const BuiltinBitCastExpr *E) {
8757 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8760 bool VisitBinaryOperator(
const BinaryOperator *E) {
8766 VisitIgnoredValue(E->
getLHS());
8767 return StmtVisitorTy::Visit(E->
getRHS());
8777 return DerivedSuccess(
Result, E);
8782 bool VisitCXXRewrittenBinaryOperator(
const CXXRewrittenBinaryOperator *E) {
8786 bool VisitBinaryConditionalOperator(
const BinaryConditionalOperator *E) {
8790 if (!
Evaluate(Info.CurrentCall->createTemporary(
8793 ScopeKind::FullExpression, CommonLV),
8797 return HandleConditionalOperator(E);
8800 bool VisitConditionalOperator(
const ConditionalOperator *E) {
8801 bool IsBcpCall =
false;
8806 if (
const CallExpr *CallCE =
8808 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
8815 if (Info.checkingPotentialConstantExpression() && IsBcpCall)
8818 FoldConstant Fold(Info, IsBcpCall);
8819 if (!HandleConditionalOperator(E)) {
8820 Fold.keepDiagnostics();
8827 bool VisitOpaqueValueExpr(
const OpaqueValueExpr *E) {
8828 if (
APValue *
Value = Info.CurrentCall->getCurrentTemporary(E);
8830 return DerivedSuccess(*
Value, E);
8836 assert(0 &&
"OpaqueValueExpr recursively refers to itself");
8839 return StmtVisitorTy::Visit(Source);
8842 bool VisitPseudoObjectExpr(
const PseudoObjectExpr *E) {
8843 for (
const Expr *SemE : E->
semantics()) {
8844 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
8853 if (OVE->isUnique())
8857 if (!
Evaluate(Info.CurrentCall->createTemporary(
8858 OVE, getStorageType(Info.Ctx, OVE),
8859 ScopeKind::FullExpression, LV),
8860 Info, OVE->getSourceExpr()))
8863 if (!StmtVisitorTy::Visit(SemE))
8873 bool VisitCallExpr(
const CallExpr *E) {
8875 if (!handleCallExpr(E,
Result,
nullptr))
8877 return DerivedSuccess(
Result, E);
8881 const LValue *ResultSlot) {
8882 CallScopeRAII CallScope(Info);
8885 QualType CalleeType =
Callee->getType();
8887 const FunctionDecl *FD =
nullptr;
8888 LValue *
This =
nullptr, ObjectArg;
8890 bool HasQualifier =
false;
8896 const CXXMethodDecl *
Member =
nullptr;
8897 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(Callee)) {
8901 Member = dyn_cast<CXXMethodDecl>(ME->getMemberDecl());
8903 return Error(Callee);
8905 HasQualifier = ME->hasQualifier();
8906 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(Callee)) {
8908 const ValueDecl *D =
8912 Member = dyn_cast<CXXMethodDecl>(D);
8914 return Error(Callee);
8916 }
else if (
const auto *PDE = dyn_cast<CXXPseudoDestructorExpr>(Callee)) {
8917 if (!Info.getLangOpts().CPlusPlus20)
8918 Info.CCEDiag(PDE, diag::note_constexpr_pseudo_destructor);
8922 return Error(Callee);
8929 if (!CalleeLV.getLValueOffset().isZero())
8930 return Error(Callee);
8931 if (CalleeLV.isNullPointer()) {
8932 Info.FFDiag(Callee, diag::note_constexpr_null_callee)
8933 <<
const_cast<Expr *
>(
Callee);
8936 FD = dyn_cast_or_null<FunctionDecl>(
8937 CalleeLV.getLValueBase().dyn_cast<
const ValueDecl *>());
8939 return Error(Callee);
8942 if (!Info.Ctx.hasSameFunctionTypeIgnoringExceptionSpec(
8949 auto *OCE = dyn_cast<CXXOperatorCallExpr>(E);
8950 if (OCE && OCE->isAssignmentOp()) {
8951 assert(Args.size() == 2 &&
"wrong number of arguments in assignment");
8952 Call = Info.CurrentCall->createCall(FD);
8953 bool HasThis =
false;
8954 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FD))
8955 HasThis = MD->isImplicitObjectMemberFunction();
8963 const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD);
8983 if (Info.getLangOpts().CPlusPlus20 && OCE &&
8984 OCE->getOperator() == OO_Equal && MD->
isTrivial() &&
8988 Args = Args.slice(1);
8994 const CXXRecordDecl *ClosureClass = MD->
getParent();
8996 ClosureClass->
captures().empty() &&
8997 "Number of captures must be zero for conversion to function-ptr");
8999 const CXXMethodDecl *LambdaCallOp =
9008 "A generic lambda's static-invoker function must be a "
9009 "template specialization");
9011 FunctionTemplateDecl *CallOpTemplate =
9013 void *InsertPos =
nullptr;
9014 FunctionDecl *CorrespondingCallOpSpecialization =
9016 assert(CorrespondingCallOpSpecialization &&
9017 "We must always have a function call operator specialization "
9018 "that corresponds to our static invoker specialization");
9020 FD = CorrespondingCallOpSpecialization;
9029 return CallScope.destroy();
9039 Call = Info.CurrentCall->createCall(FD);
9045 SmallVector<QualType, 4> CovariantAdjustmentPath;
9047 auto *NamedMember = dyn_cast<CXXMethodDecl>(FD);
9048 if (NamedMember && NamedMember->isVirtual() && !HasQualifier) {
9051 CovariantAdjustmentPath);
9054 }
else if (NamedMember && NamedMember->isImplicitObjectMemberFunction()) {
9064 if (
auto *DD = dyn_cast<CXXDestructorDecl>(FD)) {
9065 assert(This &&
"no 'this' pointer for destructor call");
9067 Info.Ctx.getCanonicalTagType(DD->getParent())) &&
9068 CallScope.destroy();
9085 if (!CovariantAdjustmentPath.empty() &&
9087 CovariantAdjustmentPath))
9090 return CallScope.destroy();
9093 bool VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E) {
9096 bool VisitInitListExpr(
const InitListExpr *E) {
9098 return DerivedZeroInitialization(E);
9100 return StmtVisitorTy::Visit(E->
getInit(0));
9103 bool VisitImplicitValueInitExpr(
const ImplicitValueInitExpr *E) {
9104 return DerivedZeroInitialization(E);
9106 bool VisitCXXScalarValueInitExpr(
const CXXScalarValueInitExpr *E) {
9107 return DerivedZeroInitialization(E);
9109 bool VisitCXXNullPtrLiteralExpr(
const CXXNullPtrLiteralExpr *E) {
9110 return DerivedZeroInitialization(E);
9114 bool VisitMemberExpr(
const MemberExpr *E) {
9115 assert(!Info.Ctx.getLangOpts().CPlusPlus11 &&
9116 "missing temporary materialization conversion");
9117 assert(!E->
isArrow() &&
"missing call to bound member function?");
9125 const FieldDecl *FD = dyn_cast<FieldDecl>(E->
getMemberDecl());
9126 if (!FD)
return Error(E);
9130 "record / field mismatch");
9135 CompleteObject Obj(APValue::LValueBase(), &Val, BaseTy);
9136 SubobjectDesignator Designator(BaseTy);
9137 Designator.addDeclUnchecked(FD);
9141 DerivedSuccess(
Result, E);
9144 bool VisitExtVectorElementExpr(
const ExtVectorElementExpr *E) {
9150 SmallVector<uint32_t, 4> Indices;
9152 if (Indices.size() == 1) {
9154 return DerivedSuccess(Val.
getVectorElt(Indices[0]), E);
9157 SmallVector<APValue, 4> Elts;
9158 for (
unsigned I = 0; I < Indices.size(); ++I) {
9161 APValue VecResult(Elts.data(), Indices.size());
9162 return DerivedSuccess(VecResult, E);
9169 bool VisitCastExpr(
const CastExpr *E) {
9174 case CK_AtomicToNonAtomic: {
9181 return DerivedSuccess(AtomicVal, E);
9185 case CK_UserDefinedConversion:
9186 return StmtVisitorTy::Visit(E->
getSubExpr());
9188 case CK_HLSLArrayRValue: {
9194 return DerivedSuccess(Val, E);
9205 return DerivedSuccess(RVal, E);
9207 case CK_LValueToRValue: {
9216 return DerivedSuccess(RVal, E);
9218 case CK_LValueToRValueBitCast: {
9219 APValue DestValue, SourceValue;
9222 if (!handleLValueToRValueBitCast(Info, DestValue, SourceValue, E))
9224 return DerivedSuccess(DestValue, E);
9227 case CK_AddressSpaceConversion: {
9231 return DerivedSuccess(
Value, E);
9238 bool VisitUnaryPostInc(
const UnaryOperator *UO) {
9239 return VisitUnaryPostIncDec(UO);
9241 bool VisitUnaryPostDec(
const UnaryOperator *UO) {
9242 return VisitUnaryPostIncDec(UO);
9244 bool VisitUnaryPostIncDec(
const UnaryOperator *UO) {
9245 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9255 return DerivedSuccess(RVal, UO);
9258 bool VisitStmtExpr(
const StmtExpr *E) {
9261 llvm::SaveAndRestore NotCheckingForUB(Info.CheckingForUndefinedBehavior,
9268 BlockScopeRAII Scope(Info);
9273 const Expr *FinalExpr = dyn_cast<Expr>(*BI);
9275 Info.FFDiag((*BI)->getBeginLoc(),
9276 diag::note_constexpr_stmt_expr_unsupported);
9279 return this->Visit(FinalExpr) && Scope.destroy();
9285 if (ESR != ESR_Succeeded) {
9289 if (ESR != ESR_Failed)
9290 Info.FFDiag((*BI)->getBeginLoc(),
9291 diag::note_constexpr_stmt_expr_unsupported);
9296 llvm_unreachable(
"Return from function from the loop above.");
9299 bool VisitPackIndexingExpr(
const PackIndexingExpr *E) {
9304 void VisitIgnoredValue(
const Expr *E) {
9309 void VisitIgnoredBaseExpression(
const Expr *E) {
9312 if (Info.getLangOpts().MSVCCompat && !E->
HasSideEffects(Info.Ctx))
9314 VisitIgnoredValue(E);
9324template<
class Derived>
9325class LValueExprEvaluatorBase
9326 :
public ExprEvaluatorBase<Derived> {
9330 typedef LValueExprEvaluatorBase LValueExprEvaluatorBaseTy;
9331 typedef ExprEvaluatorBase<Derived> ExprEvaluatorBaseTy;
9333 bool Success(APValue::LValueBase B) {
9338 bool evaluatePointer(
const Expr *E, LValue &
Result) {
9343 LValueExprEvaluatorBase(EvalInfo &Info, LValue &
Result,
bool InvalidBaseOK)
9345 InvalidBaseOK(InvalidBaseOK) {}
9348 Result.setFrom(this->Info.Ctx,
V);
9352 bool VisitMemberExpr(
const MemberExpr *E) {
9364 EvalOK = this->Visit(E->
getBase());
9375 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(E->
getMemberDecl())) {
9378 "record / field mismatch");
9382 }
else if (
const IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(MD)) {
9386 return this->
Error(E);
9398 bool VisitBinaryOperator(
const BinaryOperator *E) {
9401 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
9409 bool VisitCastExpr(
const CastExpr *E) {
9412 return ExprEvaluatorBaseTy::VisitCastExpr(E);
9414 case CK_DerivedToBase:
9415 case CK_UncheckedDerivedToBase:
9462class LValueExprEvaluator
9463 :
public LValueExprEvaluatorBase<LValueExprEvaluator> {
9465 LValueExprEvaluator(EvalInfo &Info, LValue &
Result,
bool InvalidBaseOK) :
9466 LValueExprEvaluatorBaseTy(Info,
Result, InvalidBaseOK) {}
9468 bool VisitVarDecl(
const Expr *E,
const VarDecl *VD);
9469 bool VisitUnaryPreIncDec(
const UnaryOperator *UO);
9471 bool VisitCallExpr(
const CallExpr *E);
9472 bool VisitDeclRefExpr(
const DeclRefExpr *E);
9473 bool VisitPredefinedExpr(
const PredefinedExpr *E) {
return Success(E); }
9474 bool VisitMaterializeTemporaryExpr(
const MaterializeTemporaryExpr *E);
9475 bool VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E);
9476 bool VisitMemberExpr(
const MemberExpr *E);
9477 bool VisitStringLiteral(
const StringLiteral *E) {
9479 APValue::LValueBase(E, 0, Info.Ctx.getNextStringLiteralVersion()));
9481 bool VisitObjCEncodeExpr(
const ObjCEncodeExpr *E) {
return Success(E); }
9482 bool VisitCXXTypeidExpr(
const CXXTypeidExpr *E);
9483 bool VisitCXXUuidofExpr(
const CXXUuidofExpr *E);
9484 bool VisitArraySubscriptExpr(
const ArraySubscriptExpr *E);
9485 bool VisitExtVectorElementExpr(
const ExtVectorElementExpr *E);
9486 bool VisitUnaryDeref(
const UnaryOperator *E);
9487 bool VisitUnaryReal(
const UnaryOperator *E);
9488 bool VisitUnaryImag(
const UnaryOperator *E);
9489 bool VisitUnaryPreInc(
const UnaryOperator *UO) {
9490 return VisitUnaryPreIncDec(UO);
9492 bool VisitUnaryPreDec(
const UnaryOperator *UO) {
9493 return VisitUnaryPreIncDec(UO);
9495 bool VisitBinAssign(
const BinaryOperator *BO);
9496 bool VisitCompoundAssignOperator(
const CompoundAssignOperator *CAO);
9498 bool VisitCastExpr(
const CastExpr *E) {
9501 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
9503 case CK_LValueBitCast:
9504 this->CCEDiag(E, diag::note_constexpr_invalid_cast)
9505 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
9509 Result.Designator.setInvalid();
9512 case CK_BaseToDerived:
9529 bool LValueToRValueConversion) {
9533 assert(Info.CurrentCall->This ==
nullptr &&
9534 "This should not be set for a static call operator");
9542 if (
Self->getType()->isReferenceType()) {
9543 APValue *RefValue = Info.getParamSlot(Info.CurrentCall->Arguments,
Self);
9545 Result.setFrom(Info.Ctx, *RefValue);
9547 const ParmVarDecl *VD = Info.CurrentCall->Arguments.getOrigParam(
Self);
9548 CallStackFrame *Frame =
9549 Info.getCallFrameAndDepth(Info.CurrentCall->Arguments.CallIndex)
9551 unsigned Version = Info.CurrentCall->Arguments.Version;
9552 Result.set({VD, Frame->Index, Version});
9555 Result = *Info.CurrentCall->This;
9565 if (LValueToRValueConversion) {
9569 Result.setFrom(Info.Ctx, RVal);
9580 bool InvalidBaseOK) {
9584 return LValueExprEvaluator(Info,
Result, InvalidBaseOK).Visit(E);
9587bool LValueExprEvaluator::VisitDeclRefExpr(
const DeclRefExpr *E) {
9588 const ValueDecl *D = E->
getDecl();
9600 if (Info.checkingPotentialConstantExpression())
9603 if (
auto *FD = Info.CurrentCall->LambdaCaptureFields.lookup(D)) {
9610 if (
isa<FunctionDecl, MSGuidDecl, TemplateParamObjectDecl,
9611 UnnamedGlobalConstantDecl>(D))
9613 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
9614 return VisitVarDecl(E, VD);
9615 if (
const BindingDecl *BD = dyn_cast<BindingDecl>(D))
9616 return Visit(BD->getBinding());
9620bool LValueExprEvaluator::VisitVarDecl(
const Expr *E,
const VarDecl *VD) {
9621 CallStackFrame *Frame =
nullptr;
9622 unsigned Version = 0;
9630 CallStackFrame *CurrFrame = Info.CurrentCall;
9635 if (
auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
9636 if (CurrFrame->Arguments) {
9637 VD = CurrFrame->Arguments.getOrigParam(PVD);
9639 Info.getCallFrameAndDepth(CurrFrame->Arguments.CallIndex).first;
9640 Version = CurrFrame->Arguments.Version;
9644 Version = CurrFrame->getCurrentTemporaryVersion(VD);
9651 Result.set({VD, Frame->Index, Version});
9657 if (!Info.getLangOpts().CPlusPlus11) {
9658 Info.CCEDiag(E, diag::note_constexpr_ltor_non_integral, 1)
9660 Info.Note(VD->
getLocation(), diag::note_declared_at);
9669 Result.AllowConstexprUnknown =
true;
9676bool LValueExprEvaluator::VisitCallExpr(
const CallExpr *E) {
9677 if (!IsConstantEvaluatedBuiltinCall(E))
9678 return ExprEvaluatorBaseTy::VisitCallExpr(E);
9683 case Builtin::BIas_const:
9684 case Builtin::BIforward:
9685 case Builtin::BIforward_like:
9686 case Builtin::BImove:
9687 case Builtin::BImove_if_noexcept:
9689 return Visit(E->
getArg(0));
9693 return ExprEvaluatorBaseTy::VisitCallExpr(E);
9696bool LValueExprEvaluator::VisitMaterializeTemporaryExpr(
9697 const MaterializeTemporaryExpr *E) {
9705 for (
const Expr *E : CommaLHSs)
9714 if (Info.EvalMode == EvaluationMode::ConstantFold)
9721 Value = &Info.CurrentCall->createTemporary(
9737 for (
unsigned I = Adjustments.size(); I != 0; ) {
9739 switch (Adjustments[I].Kind) {
9744 Type = Adjustments[I].DerivedToBase.BasePath->getType();
9750 Type = Adjustments[I].Field->getType();
9755 Adjustments[I].Ptr.RHS))
9757 Type = Adjustments[I].Ptr.MPT->getPointeeType();
9766LValueExprEvaluator::VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E) {
9767 assert((!Info.getLangOpts().CPlusPlus || E->
isFileScope()) &&
9768 "lvalue compound literal in c++?");
9780 assert(!Info.getLangOpts().CPlusPlus);
9782 ScopeKind::Block,
Result);
9794bool LValueExprEvaluator::VisitCXXTypeidExpr(
const CXXTypeidExpr *E) {
9795 TypeInfoLValue TypeInfo;
9803 if (!Info.Ctx.getLangOpts().CPlusPlus20) {
9804 Info.CCEDiag(E, diag::note_constexpr_typeid_polymorphic)
9812 std::optional<DynamicType> DynType =
9817 TypeInfo = TypeInfoLValue(
9818 Info.Ctx.getCanonicalTagType(DynType->Type).getTypePtr());
9824bool LValueExprEvaluator::VisitCXXUuidofExpr(
const CXXUuidofExpr *E) {
9828bool LValueExprEvaluator::VisitMemberExpr(
const MemberExpr *E) {
9830 if (
const VarDecl *VD = dyn_cast<VarDecl>(E->
getMemberDecl())) {
9831 VisitIgnoredBaseExpression(E->
getBase());
9832 return VisitVarDecl(E, VD);
9836 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(E->
getMemberDecl())) {
9837 if (MD->isStatic()) {
9838 VisitIgnoredBaseExpression(E->
getBase());
9844 return LValueExprEvaluatorBaseTy::VisitMemberExpr(E);
9847bool LValueExprEvaluator::VisitExtVectorElementExpr(
9848 const ExtVectorElementExpr *E) {
9853 if (!Info.noteFailure())
9861 if (Indices.size() > 1)
9865 Result.setFrom(Info.Ctx, Val);
9869 const auto *VT = BaseType->
castAs<VectorType>();
9871 VT->getNumElements(), Indices[0]);
9877bool LValueExprEvaluator::VisitArraySubscriptExpr(
const ArraySubscriptExpr *E) {
9887 if (!Info.noteFailure())
9893 if (!Info.noteFailure())
9899 Result.setFrom(Info.Ctx, Val);
9901 VT->getNumElements(), Index.getZExtValue());
9909 for (
const Expr *SubExpr : {E->
getLHS(), E->
getRHS()}) {
9910 if (SubExpr == E->
getBase() ? !evaluatePointer(SubExpr,
Result)
9912 if (!Info.noteFailure())
9922bool LValueExprEvaluator::VisitUnaryDeref(
const UnaryOperator *E) {
9933 Info.noteUndefinedBehavior();
9936bool LValueExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
9945bool LValueExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
9947 "lvalue __imag__ on scalar?");
9954bool LValueExprEvaluator::VisitUnaryPreIncDec(
const UnaryOperator *UO) {
9955 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9966bool LValueExprEvaluator::VisitCompoundAssignOperator(
9967 const CompoundAssignOperator *CAO) {
9968 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9976 if (!Info.noteFailure())
9991bool LValueExprEvaluator::VisitBinAssign(
const BinaryOperator *E) {
9992 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
10000 if (!Info.noteFailure())
10008 if (Info.getLangOpts().CPlusPlus20 &&
10023 const LValue &LVal,
10025 assert(isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
10026 "Can't get the size of a non alloc_size function");
10027 const auto *
Base = LVal.getLValueBase().get<
const Expr *>();
10029 std::optional<llvm::APInt> Size =
10030 CE->evaluateBytesReturnedByAllocSizeCall(Ctx);
10034 Result = std::move(*Size);
10053 dyn_cast_or_null<VarDecl>(
Base.dyn_cast<
const ValueDecl *>());
10058 if (!
Init ||
Init->getType().isNull())
10061 const Expr *E =
Init->IgnoreParens();
10062 if (!tryUnwrapAllocSizeCall(E))
10070 Result.addUnsizedArray(Info, E, Pointee);
10075class PointerExprEvaluator
10076 :
public ExprEvaluatorBase<PointerExprEvaluator> {
10078 bool InvalidBaseOK;
10080 bool Success(
const Expr *E) {
10085 bool evaluateLValue(
const Expr *E, LValue &
Result) {
10089 bool evaluatePointer(
const Expr *E, LValue &
Result) {
10093 bool visitNonBuiltinCallExpr(
const CallExpr *E);
10096 PointerExprEvaluator(EvalInfo &info, LValue &
Result,
bool InvalidBaseOK)
10098 InvalidBaseOK(InvalidBaseOK) {}
10104 bool ZeroInitialization(
const Expr *E) {
10109 bool VisitBinaryOperator(
const BinaryOperator *E);
10110 bool VisitCastExpr(
const CastExpr* E);
10111 bool VisitUnaryAddrOf(
const UnaryOperator *E);
10112 bool VisitObjCStringLiteral(
const ObjCStringLiteral *E)
10114 bool VisitObjCBoxedExpr(
const ObjCBoxedExpr *E) {
10117 if (Info.noteFailure())
10121 bool VisitObjCArrayLiteral(
const ObjCArrayLiteral *E) {
10124 bool VisitObjCDictionaryLiteral(
const ObjCDictionaryLiteral *E) {
10127 bool VisitAddrLabelExpr(
const AddrLabelExpr *E)
10129 bool VisitCallExpr(
const CallExpr *E);
10130 bool VisitBuiltinCallExpr(
const CallExpr *E,
unsigned BuiltinOp);
10131 bool VisitBlockExpr(
const BlockExpr *E) {
10136 bool VisitCXXThisExpr(
const CXXThisExpr *E) {
10137 auto DiagnoseInvalidUseOfThis = [&] {
10138 if (Info.getLangOpts().CPlusPlus11)
10139 Info.FFDiag(E, diag::note_constexpr_this) << E->
isImplicit();
10145 if (Info.checkingPotentialConstantExpression())
10148 bool IsExplicitLambda =
10150 if (!IsExplicitLambda) {
10151 if (!Info.CurrentCall->This) {
10152 DiagnoseInvalidUseOfThis();
10156 Result = *Info.CurrentCall->This;
10164 if (!Info.CurrentCall->LambdaThisCaptureField) {
10165 if (IsExplicitLambda && !Info.CurrentCall->This) {
10166 DiagnoseInvalidUseOfThis();
10175 Info, E,
Result, MD, Info.CurrentCall->LambdaThisCaptureField,
10181 bool VisitCXXNewExpr(
const CXXNewExpr *E);
10183 bool VisitSourceLocExpr(
const SourceLocExpr *E) {
10184 assert(!E->
isIntType() &&
"SourceLocExpr isn't a pointer type?");
10186 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.
getDefaultExpr());
10187 Result.setFrom(Info.Ctx, LValResult);
10191 bool VisitEmbedExpr(
const EmbedExpr *E) {
10192 llvm::report_fatal_error(
"Not yet implemented for ExprConstant.cpp");
10196 bool VisitSYCLUniqueStableNameExpr(
const SYCLUniqueStableNameExpr *E) {
10197 std::string ResultStr = E->
ComputeName(Info.Ctx);
10199 QualType CharTy = Info.Ctx.CharTy.withConst();
10200 APInt Size(Info.Ctx.getTypeSize(Info.Ctx.getSizeType()),
10201 ResultStr.size() + 1);
10202 QualType ArrayTy = Info.Ctx.getConstantArrayType(
10203 CharTy, Size,
nullptr, ArraySizeModifier::Normal, 0);
10205 StringLiteral *SL =
10206 StringLiteral::Create(Info.Ctx, ResultStr, StringLiteralKind::Ordinary,
10209 evaluateLValue(SL,
Result);
10219 bool InvalidBaseOK) {
10222 return PointerExprEvaluator(Info,
Result, InvalidBaseOK).Visit(E);
10225bool PointerExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
10228 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
10230 const Expr *PExp = E->
getLHS();
10231 const Expr *IExp = E->
getRHS();
10233 std::swap(PExp, IExp);
10235 bool EvalPtrOK = evaluatePointer(PExp,
Result);
10236 if (!EvalPtrOK && !Info.noteFailure())
10239 llvm::APSInt Offset;
10250bool PointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
10258 if (!Info.getLangOpts().CPlusPlus) {
10260 if (
const auto *Deref = dyn_cast<UnaryOperator>(Sub);
10261 Deref && Deref->getOpcode() == UO_Deref)
10262 return evaluatePointer(Deref->getSubExpr(),
Result);
10272 if (!FnII || !FnII->
isStr(
"current"))
10275 const auto *RD = dyn_cast<RecordDecl>(FD->
getParent());
10283bool PointerExprEvaluator::VisitCastExpr(
const CastExpr *E) {
10290 case CK_CPointerToObjCPointerCast:
10291 case CK_BlockPointerToObjCPointerCast:
10292 case CK_AnyPointerToBlockPointerCast:
10293 case CK_AddressSpaceConversion:
10294 if (!Visit(SubExpr))
10300 CCEDiag(E, diag::note_constexpr_invalid_cast)
10301 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
10302 << Info.Ctx.getLangOpts().CPlusPlus;
10303 Result.Designator.setInvalid();
10311 bool HasValidResult = !
Result.InvalidBase && !
Result.Designator.Invalid &&
10313 bool VoidPtrCastMaybeOK =
10316 Info.Ctx.hasSimilarType(
Result.Designator.getType(Info.Ctx),
10325 if (VoidPtrCastMaybeOK &&
10326 (Info.getStdAllocatorCaller(
"allocate") ||
10328 Info.getLangOpts().CPlusPlus26)) {
10332 Info.getLangOpts().CPlusPlus) {
10333 if (HasValidResult)
10334 CCEDiag(E, diag::note_constexpr_invalid_void_star_cast)
10335 << SubExpr->
getType() << Info.getLangOpts().CPlusPlus26
10336 <<
Result.Designator.getType(Info.Ctx).getCanonicalType()
10339 CCEDiag(E, diag::note_constexpr_invalid_cast)
10340 << diag::ConstexprInvalidCastKind::CastFrom
10343 CCEDiag(E, diag::note_constexpr_invalid_cast)
10344 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
10345 << Info.Ctx.getLangOpts().CPlusPlus;
10346 Result.Designator.setInvalid();
10350 ZeroInitialization(E);
10353 case CK_DerivedToBase:
10354 case CK_UncheckedDerivedToBase:
10366 case CK_BaseToDerived:
10378 case CK_NullToPointer:
10380 return ZeroInitialization(E);
10382 case CK_IntegralToPointer: {
10383 CCEDiag(E, diag::note_constexpr_invalid_cast)
10384 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
10385 << Info.Ctx.getLangOpts().CPlusPlus;
10391 if (
Value.isInt()) {
10392 unsigned Size = Info.Ctx.getTypeSize(E->
getType());
10393 uint64_t N =
Value.getInt().extOrTrunc(Size).getZExtValue();
10394 if (N == Info.Ctx.getTargetNullPointerValue(E->
getType())) {
10397 Result.Base = (Expr *)
nullptr;
10398 Result.InvalidBase =
false;
10400 Result.Designator.setInvalid();
10401 Result.IsNullPtr =
false;
10409 if (!
Value.isLValue())
10418 case CK_ArrayToPointerDecay: {
10420 if (!evaluateLValue(SubExpr,
Result))
10424 SubExpr, SubExpr->
getType(), ScopeKind::FullExpression,
Result);
10429 auto *AT = Info.Ctx.getAsArrayType(SubExpr->
getType());
10430 if (
auto *CAT = dyn_cast<ConstantArrayType>(AT))
10431 Result.addArray(Info, E, CAT);
10433 Result.addUnsizedArray(Info, E, AT->getElementType());
10437 case CK_FunctionToPointerDecay:
10438 return evaluateLValue(SubExpr,
Result);
10440 case CK_LValueToRValue: {
10449 return InvalidBaseOK &&
10455 return ExprEvaluatorBaseTy::VisitCastExpr(E);
10459 UnaryExprOrTypeTrait ExprKind) {
10463 T =
T.getNonReferenceType();
10465 if (
T.getQualifiers().hasUnaligned())
10468 const bool AlignOfReturnsPreferred =
10474 if (ExprKind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
10477 else if (ExprKind == UETT_AlignOf)
10480 llvm_unreachable(
"GetAlignOfType on a non-alignment ExprKind");
10495 unsigned BuiltinOp) {
10519 switch (OwningTarget->
getTriple().getArch()) {
10520 case llvm::Triple::x86:
10521 case llvm::Triple::x86_64:
10534 UnaryExprOrTypeTrait ExprKind) {
10543 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
10547 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(E))
10556 return Info.Ctx.getDeclAlign(VD);
10557 if (
const auto *E =
Value.Base.dyn_cast<
const Expr *>())
10565 EvalInfo &Info,
APSInt &Alignment) {
10568 if (Alignment < 0 || !Alignment.isPowerOf2()) {
10569 Info.FFDiag(E, diag::note_constexpr_invalid_alignment) << Alignment;
10572 unsigned SrcWidth = Info.Ctx.getIntWidth(ForType);
10573 APSInt MaxValue(APInt::getOneBitSet(SrcWidth, SrcWidth - 1));
10574 if (APSInt::compareValues(Alignment, MaxValue) > 0) {
10575 Info.FFDiag(E, diag::note_constexpr_alignment_too_big)
10576 << MaxValue << ForType << Alignment;
10582 APSInt(Alignment.zextOrTrunc(SrcWidth),
true);
10583 assert(APSInt::compareValues(Alignment, ExtAlignment) == 0 &&
10584 "Alignment should not be changed by ext/trunc");
10585 Alignment = ExtAlignment;
10586 assert(Alignment.getBitWidth() == SrcWidth);
10591bool PointerExprEvaluator::visitNonBuiltinCallExpr(
const CallExpr *E) {
10592 if (ExprEvaluatorBaseTy::VisitCallExpr(E))
10600 Result.addUnsizedArray(Info, E, PointeeTy);
10604bool PointerExprEvaluator::VisitCallExpr(
const CallExpr *E) {
10605 if (!IsConstantEvaluatedBuiltinCall(E))
10606 return visitNonBuiltinCallExpr(E);
10613 return T->isCharType() ||
T->isChar8Type();
10616bool PointerExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *E,
10617 unsigned BuiltinOp) {
10621 switch (BuiltinOp) {
10622 case Builtin::BIaddressof:
10623 case Builtin::BI__addressof:
10624 case Builtin::BI__builtin_addressof:
10626 case Builtin::BI__builtin_assume_aligned: {
10633 LValue OffsetResult(
Result);
10645 int64_t AdditionalOffset = -Offset.getZExtValue();
10650 if (OffsetResult.Base) {
10653 if (BaseAlignment < Align) {
10654 Result.Designator.setInvalid();
10655 CCEDiag(E->
getArg(0), diag::note_constexpr_baa_insufficient_alignment)
10662 if (OffsetResult.Offset.alignTo(Align) != OffsetResult.Offset) {
10663 Result.Designator.setInvalid();
10667 diag::note_constexpr_baa_insufficient_alignment)
10670 diag::note_constexpr_baa_value_insufficient_alignment))
10671 << OffsetResult.Offset.getQuantity() << Align.
getQuantity();
10677 case Builtin::BI__builtin_align_up:
10678 case Builtin::BI__builtin_align_down: {
10698 assert(Alignment.getBitWidth() <= 64 &&
10699 "Cannot handle > 64-bit address-space");
10700 uint64_t Alignment64 = Alignment.getZExtValue();
10702 BuiltinOp == Builtin::BI__builtin_align_down
10703 ? llvm::alignDown(
Result.Offset.getQuantity(), Alignment64)
10704 : llvm::alignTo(
Result.Offset.getQuantity(), Alignment64));
10710 Info.FFDiag(E->
getArg(0), diag::note_constexpr_alignment_adjust)
10714 case Builtin::BI__builtin_operator_new:
10716 case Builtin::BI__builtin_launder:
10718 case Builtin::BIstrchr:
10719 case Builtin::BIwcschr:
10720 case Builtin::BImemchr:
10721 case Builtin::BIwmemchr:
10722 if (Info.getLangOpts().CPlusPlus11)
10723 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
10725 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
10727 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
10729 case Builtin::BI__builtin_strchr:
10730 case Builtin::BI__builtin_wcschr:
10731 case Builtin::BI__builtin_memchr:
10732 case Builtin::BI__builtin_char_memchr:
10733 case Builtin::BI__builtin_wmemchr: {
10734 if (!Visit(E->
getArg(0)))
10740 if (BuiltinOp != Builtin::BIstrchr &&
10741 BuiltinOp != Builtin::BIwcschr &&
10742 BuiltinOp != Builtin::BI__builtin_strchr &&
10743 BuiltinOp != Builtin::BI__builtin_wcschr) {
10747 MaxLength = N.getZExtValue();
10750 if (MaxLength == 0u)
10751 return ZeroInitialization(E);
10752 if (!
Result.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
10753 Result.Designator.Invalid)
10755 QualType CharTy =
Result.Designator.getType(Info.Ctx);
10756 bool IsRawByte = BuiltinOp == Builtin::BImemchr ||
10757 BuiltinOp == Builtin::BI__builtin_memchr;
10758 assert(IsRawByte ||
10759 Info.Ctx.hasSameUnqualifiedType(
10763 Info.FFDiag(E, diag::note_constexpr_ltor_incomplete_type) << CharTy;
10769 Info.FFDiag(E, diag::note_constexpr_memchr_unsupported)
10770 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp) << CharTy;
10776 bool StopAtNull =
false;
10777 switch (BuiltinOp) {
10778 case Builtin::BIstrchr:
10779 case Builtin::BI__builtin_strchr:
10786 return ZeroInitialization(E);
10789 case Builtin::BImemchr:
10790 case Builtin::BI__builtin_memchr:
10791 case Builtin::BI__builtin_char_memchr:
10795 DesiredVal = Desired.trunc(Info.Ctx.getCharWidth()).getZExtValue();
10798 case Builtin::BIwcschr:
10799 case Builtin::BI__builtin_wcschr:
10802 case Builtin::BIwmemchr:
10803 case Builtin::BI__builtin_wmemchr:
10805 DesiredVal = Desired.getZExtValue();
10809 for (; MaxLength; --MaxLength) {
10814 if (Char.
getInt().getZExtValue() == DesiredVal)
10816 if (StopAtNull && !Char.
getInt())
10822 return ZeroInitialization(E);
10825 case Builtin::BImemcpy:
10826 case Builtin::BImemmove:
10827 case Builtin::BIwmemcpy:
10828 case Builtin::BIwmemmove:
10829 if (Info.getLangOpts().CPlusPlus11)
10830 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
10832 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
10834 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
10836 case Builtin::BI__builtin_memcpy:
10837 case Builtin::BI__builtin_memmove:
10838 case Builtin::BI__builtin_wmemcpy:
10839 case Builtin::BI__builtin_wmemmove: {
10840 bool WChar = BuiltinOp == Builtin::BIwmemcpy ||
10841 BuiltinOp == Builtin::BIwmemmove ||
10842 BuiltinOp == Builtin::BI__builtin_wmemcpy ||
10843 BuiltinOp == Builtin::BI__builtin_wmemmove;
10844 bool Move = BuiltinOp == Builtin::BImemmove ||
10845 BuiltinOp == Builtin::BIwmemmove ||
10846 BuiltinOp == Builtin::BI__builtin_memmove ||
10847 BuiltinOp == Builtin::BI__builtin_wmemmove;
10850 if (!Visit(E->
getArg(0)))
10861 assert(!N.isSigned() &&
"memcpy and friends take an unsigned size");
10871 if (!Src.Base || !Dest.Base) {
10873 (!Src.Base ? Src : Dest).moveInto(Val);
10874 Info.FFDiag(E, diag::note_constexpr_memcpy_null)
10875 <<
Move << WChar << !!Src.Base
10879 if (Src.Designator.Invalid || Dest.Designator.Invalid)
10885 QualType
T = Dest.Designator.getType(Info.Ctx);
10886 QualType SrcT = Src.Designator.getType(Info.Ctx);
10887 if (!Info.Ctx.hasSameUnqualifiedType(
T, SrcT)) {
10889 Info.FFDiag(E, diag::note_constexpr_memcpy_type_pun) <<
Move << SrcT <<
T;
10893 Info.FFDiag(E, diag::note_constexpr_memcpy_incomplete_type) <<
Move <<
T;
10896 if (!
T.isTriviallyCopyableType(Info.Ctx)) {
10897 Info.FFDiag(E, diag::note_constexpr_memcpy_nontrivial) <<
Move <<
T;
10902 uint64_t TSize = Info.Ctx.getTypeSizeInChars(
T).getQuantity();
10907 llvm::APInt OrigN = N;
10908 llvm::APInt::udivrem(OrigN, TSize, N, Remainder);
10910 Info.FFDiag(E, diag::note_constexpr_memcpy_unsupported)
10912 << (unsigned)TSize;
10920 uint64_t RemainingSrcSize = Src.Designator.validIndexAdjustments().second;
10921 uint64_t RemainingDestSize = Dest.Designator.validIndexAdjustments().second;
10922 if (N.ugt(RemainingSrcSize) || N.ugt(RemainingDestSize)) {
10923 Info.FFDiag(E, diag::note_constexpr_memcpy_unsupported)
10924 <<
Move << WChar << (N.ugt(RemainingSrcSize) ? 1 : 2) <<
T
10928 uint64_t NElems = N.getZExtValue();
10934 uint64_t SrcOffset = Src.getLValueOffset().getQuantity();
10935 uint64_t DestOffset = Dest.getLValueOffset().getQuantity();
10936 if (DestOffset >= SrcOffset && DestOffset - SrcOffset < NBytes) {
10939 Info.FFDiag(E, diag::note_constexpr_memcpy_overlap) << WChar;
10947 }
else if (!Move && SrcOffset >= DestOffset &&
10948 SrcOffset - DestOffset < NBytes) {
10950 Info.FFDiag(E, diag::note_constexpr_memcpy_overlap) << WChar;
10979 QualType AllocType);
10982 const CXXConstructExpr *CCE,
10983 QualType AllocType);
10985bool PointerExprEvaluator::VisitCXXNewExpr(
const CXXNewExpr *E) {
10986 if (!Info.getLangOpts().CPlusPlus20)
10987 Info.CCEDiag(E, diag::note_constexpr_new);
10990 if (Info.SpeculativeEvaluationDepth)
10995 QualType TargetType = AllocType;
10997 bool IsNothrow =
false;
10998 bool IsPlacement =
false;
11016 }
else if (OperatorNew->isReservedGlobalPlacementOperator()) {
11017 if (Info.CurrentCall->isStdFunction() || Info.getLangOpts().CPlusPlus26 ||
11018 (Info.CurrentCall->CanEvalMSConstexpr &&
11019 OperatorNew->hasAttr<MSConstexprAttr>())) {
11022 if (
Result.Designator.Invalid)
11025 IsPlacement =
true;
11027 Info.FFDiag(E, diag::note_constexpr_new_placement)
11032 Info.FFDiag(E, diag::note_constexpr_new_placement)
11035 }
else if (!OperatorNew
11036 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
11037 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
11043 const InitListExpr *ResizedArrayILE =
nullptr;
11044 const CXXConstructExpr *ResizedArrayCCE =
nullptr;
11045 bool ValueInit =
false;
11047 if (std::optional<const Expr *> ArraySize = E->
getArraySize()) {
11048 const Expr *Stripped = *ArraySize;
11049 for (;
auto *ICE = dyn_cast<ImplicitCastExpr>(Stripped);
11050 Stripped = ICE->getSubExpr())
11051 if (ICE->getCastKind() != CK_NoOp &&
11052 ICE->getCastKind() != CK_IntegralCast)
11065 return ZeroInitialization(E);
11067 Info.FFDiag(*ArraySize, diag::note_constexpr_new_negative)
11068 <<
ArrayBound << (*ArraySize)->getSourceRange();
11074 if (!Info.CheckArraySize(ArraySize.value()->getExprLoc(),
11079 return ZeroInitialization(E);
11091 }
else if (
auto *CCE = dyn_cast<CXXConstructExpr>(
Init)) {
11092 ResizedArrayCCE = CCE;
11094 auto *CAT = Info.Ctx.getAsConstantArrayType(
Init->getType());
11095 assert(CAT &&
"unexpected type for array initializer");
11099 llvm::APInt InitBound = CAT->
getSize().zext(Bits);
11100 llvm::APInt AllocBound =
ArrayBound.zext(Bits);
11101 if (InitBound.ugt(AllocBound)) {
11103 return ZeroInitialization(E);
11105 Info.FFDiag(*ArraySize, diag::note_constexpr_new_too_small)
11106 <<
toString(AllocBound, 10,
false)
11108 << (*ArraySize)->getSourceRange();
11114 if (InitBound != AllocBound)
11118 AllocType = Info.Ctx.getConstantArrayType(AllocType,
ArrayBound,
nullptr,
11119 ArraySizeModifier::Normal, 0);
11129 "array allocation with non-array new");
11135 struct FindObjectHandler {
11138 QualType AllocType;
11142 typedef bool result_type;
11143 bool failed() {
return false; }
11144 bool checkConst(QualType QT) {
11146 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
11151 bool found(
APValue &Subobj, QualType SubobjType,
11152 APValue::LValueBase Base) {
11153 if (!checkConst(SubobjType))
11157 if (!Info.Ctx.hasSimilarType(SubobjType, AllocType)) {
11158 Info.FFDiag(E, diag::note_constexpr_placement_new_wrong_type)
11159 << SubobjType << AllocType;
11166 Info.FFDiag(E, diag::note_constexpr_construct_complex_elem);
11169 bool found(APFloat &
Value, QualType SubobjType) {
11170 Info.FFDiag(E, diag::note_constexpr_construct_complex_elem);
11173 } Handler = {Info, E, AllocType, AK,
nullptr};
11176 Result.Designator.MostDerivedIsArrayElement &&
11177 Result.Designator.Entries.back().getAsArrayIndex() == 0) {
11182 QualType AllocElementType =
11183 Info.Ctx.getAsArrayType(AllocType)->getElementType();
11184 if (Info.Ctx.hasSimilarType(AllocElementType,
11185 Result.Designator.MostDerivedType)) {
11187 Result.Designator.MostDerivedPathLength - 1);
11195 Val = Handler.Value;
11204 Val = Info.createHeapAlloc(E, AllocType,
Result);
11210 ImplicitValueInitExpr VIE(AllocType);
11213 }
else if (ResizedArrayILE) {
11217 }
else if (ResizedArrayCCE) {
11240class MemberPointerExprEvaluator
11241 :
public ExprEvaluatorBase<MemberPointerExprEvaluator> {
11244 bool Success(
const ValueDecl *D) {
11250 MemberPointerExprEvaluator(EvalInfo &Info, MemberPtr &
Result)
11257 bool ZeroInitialization(
const Expr *E) {
11258 return Success((
const ValueDecl*)
nullptr);
11261 bool VisitCastExpr(
const CastExpr *E);
11262 bool VisitUnaryAddrOf(
const UnaryOperator *E);
11270 return MemberPointerExprEvaluator(Info,
Result).Visit(E);
11273bool MemberPointerExprEvaluator::VisitCastExpr(
const CastExpr *E) {
11276 return ExprEvaluatorBaseTy::VisitCastExpr(E);
11278 case CK_NullToMemberPointer:
11280 return ZeroInitialization(E);
11282 case CK_BaseToDerivedMemberPointer: {
11290 typedef std::reverse_iterator<CastExpr::path_const_iterator> ReverseIter;
11292 PathI != PathE; ++PathI) {
11293 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
11294 const CXXRecordDecl *Derived = (*PathI)->getType()->getAsCXXRecordDecl();
11295 if (!
Result.castToDerived(Derived))
11299 ->
castAs<MemberPointerType>()
11300 ->getMostRecentCXXRecordDecl()))
11305 case CK_DerivedToBaseMemberPointer:
11309 PathE = E->
path_end(); PathI != PathE; ++PathI) {
11310 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
11311 const CXXRecordDecl *
Base = (*PathI)->getType()->getAsCXXRecordDecl();
11312 if (!
Result.castToBase(Base))
11319bool MemberPointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
11330 class RecordExprEvaluator
11331 :
public ExprEvaluatorBase<RecordExprEvaluator> {
11332 const LValue &
This;
11336 RecordExprEvaluator(EvalInfo &info,
const LValue &This,
APValue &
Result)
11343 bool ZeroInitialization(
const Expr *E) {
11344 return ZeroInitialization(E, E->
getType());
11346 bool ZeroInitialization(
const Expr *E, QualType
T);
11348 bool VisitCallExpr(
const CallExpr *E) {
11349 return handleCallExpr(E,
Result, &This);
11351 bool VisitCastExpr(
const CastExpr *E);
11352 bool VisitInitListExpr(
const InitListExpr *E);
11353 bool VisitCXXConstructExpr(
const CXXConstructExpr *E) {
11354 return VisitCXXConstructExpr(E, E->
getType());
11357 bool VisitCXXInheritedCtorInitExpr(
const CXXInheritedCtorInitExpr *E);
11358 bool VisitCXXConstructExpr(
const CXXConstructExpr *E, QualType
T);
11359 bool VisitCXXStdInitializerListExpr(
const CXXStdInitializerListExpr *E);
11360 bool VisitBinCmp(
const BinaryOperator *E);
11361 bool VisitCXXParenListInitExpr(
const CXXParenListInitExpr *E);
11362 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
11363 ArrayRef<Expr *> Args);
11364 bool VisitDesignatedInitUpdateExpr(
const DesignatedInitUpdateExpr *E);
11378 bool IsCompleteClass =
true) {
11379 assert(!RD->
isUnion() &&
"Expected non-union class type");
11383 unsigned NonVirtualBases = countNonVirtualBases(CD);
11395 unsigned Index = 0;
11397 for (
const auto &B : CD->
bases()) {
11401 LValue Subobject =
This;
11405 Result.getStructBase(Index),
11412 for (
const auto *I : RD->
fields()) {
11414 if (I->isUnnamedBitField() || I->getType()->isReferenceType())
11417 LValue Subobject =
This;
11423 Result.getStructField(I->getFieldIndex()), Info, Subobject, &VIE))
11427 if (CD &&
This.pointsToCompleteClass(CD)) {
11428 unsigned Index = 0;
11429 for (
const auto &B : CD->
vbases()) {
11431 LValue Subobject =
This;
11435 Result.getStructVirtualBase(Index),
11445bool RecordExprEvaluator::ZeroInitialization(
const Expr *E, QualType
T) {
11452 while (I != RD->
field_end() && (*I)->isUnnamedBitField())
11459 LValue Subobject =
This;
11463 ImplicitValueInitExpr VIE(I->getType());
11467 if (!Info.getLangOpts().CPlusPlus26) {
11468 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
11469 CXXRD && CXXRD->getNumVBases()) {
11470 Info.FFDiag(E, diag::note_constexpr_virtual_base) << RD;
11478bool RecordExprEvaluator::VisitCastExpr(
const CastExpr *E) {
11481 return ExprEvaluatorBaseTy::VisitCastExpr(E);
11483 case CK_ConstructorConversion:
11486 case CK_DerivedToBase:
11487 case CK_UncheckedDerivedToBase: {
11498 PathE = E->
path_end(); PathI != PathE; ++PathI) {
11499 assert(!(*PathI)->isVirtual() &&
"record rvalue with virtual base");
11500 const CXXRecordDecl *
Base = (*PathI)->getType()->getAsCXXRecordDecl();
11507 case CK_HLSLAggregateSplatCast: {
11527 case CK_HLSLElementwiseCast: {
11545 LValue Subobject =
This;
11552 if (
Field->isBitField()) {
11562bool RecordExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
11565 return VisitCXXParenListOrInitListExpr(E, E->
inits());
11568bool RecordExprEvaluator::VisitCXXParenListOrInitListExpr(
11572 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD);
11573 auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
11575 EvalInfo::EvaluatingConstructorRAII EvalObj(
11577 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries},
11578 CXXRD && CXXRD->getNumBases());
11581 const FieldDecl *
Field;
11582 if (
auto *ILE = dyn_cast<InitListExpr>(ExprToVisit)) {
11583 Field = ILE->getInitializedFieldInUnion();
11584 }
else if (
auto *PLIE = dyn_cast<CXXParenListInitExpr>(ExprToVisit)) {
11585 Field = PLIE->getInitializedFieldInUnion();
11588 "Expression is neither an init list nor a C++ paren list");
11600 ImplicitValueInitExpr VIE(
Field->getType());
11601 const Expr *InitExpr = Args.empty() ? &VIE : Args[0];
11603 LValue Subobject =
This;
11608 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
11612 if (
Field->isBitField())
11622 Result =
APValue(APValue::UninitStruct(), CXXRD ? CXXRD->getNumBases() : 0,
11624 unsigned ElementNo = 0;
11628 if (CXXRD && CXXRD->getNumBases()) {
11629 for (
const auto &Base : CXXRD->bases()) {
11630 assert(ElementNo < Args.size() &&
"missing init for base class");
11631 const Expr *
Init = Args[ElementNo];
11633 LValue Subobject =
This;
11639 if (!Info.noteFailure())
11646 EvalObj.finishedConstructingBases();
11650 for (
const auto *Field : RD->
fields()) {
11653 if (
Field->isUnnamedBitField())
11656 LValue Subobject =
This;
11658 bool HaveInit = ElementNo < Args.size();
11663 Subobject, Field, &Layout))
11668 ImplicitValueInitExpr VIE(HaveInit ? Info.Ctx.IntTy :
Field->getType());
11669 const Expr *
Init = HaveInit ? Args[ElementNo++] : &VIE;
11676 if (
Field->getType()->isIncompleteArrayType()) {
11677 if (
auto *CAT = Info.Ctx.getAsConstantArrayType(
Init->getType())) {
11681 Info.FFDiag(
Init, diag::note_constexpr_unsupported_flexible_array);
11688 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
11692 if (
Field->getType()->isReferenceType()) {
11696 if (!Info.noteFailure())
11701 (
Field->isBitField() &&
11703 if (!Info.noteFailure())
11709 EvalObj.finishedConstructingFields();
11714bool RecordExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E,
11724 return ZeroInitialization(E,
T);
11742 const Expr *SrcObj = E->
getArg(0);
11744 assert(Info.Ctx.hasSameUnqualifiedType(E->
getType(), SrcObj->
getType()));
11745 if (
const MaterializeTemporaryExpr *ME =
11746 dyn_cast<MaterializeTemporaryExpr>(SrcObj))
11747 return Visit(ME->getSubExpr());
11750 if (ZeroInit && !ZeroInitialization(E,
T))
11759bool RecordExprEvaluator::VisitCXXInheritedCtorInitExpr(
11760 const CXXInheritedCtorInitExpr *E) {
11761 if (!Info.CurrentCall) {
11762 assert(Info.checkingPotentialConstantExpression());
11781bool RecordExprEvaluator::VisitCXXStdInitializerListExpr(
11782 const CXXStdInitializerListExpr *E) {
11783 const ConstantArrayType *ArrayType =
11790 assert(ArrayType &&
"unexpected type for array initializer");
11793 Array.addArray(Info, E, ArrayType);
11801 assert(Field !=
Record->field_end() &&
11802 Info.Ctx.hasSameType(
Field->getType()->getPointeeType(),
11804 "Expected std::initializer_list first field to be const E *");
11806 assert(Field !=
Record->field_end() &&
11807 "Expected std::initializer_list to have two fields");
11809 if (Info.Ctx.hasSameType(
Field->getType(), Info.Ctx.getSizeType())) {
11814 assert(Info.Ctx.hasSameType(
Field->getType()->getPointeeType(),
11816 "Expected std::initializer_list second field to be const E *");
11824 assert(++Field ==
Record->field_end() &&
11825 "Expected std::initializer_list to only have two fields");
11830bool RecordExprEvaluator::VisitLambdaExpr(
const LambdaExpr *E) {
11835 const size_t NumFields = ClosureClass->
getNumFields();
11839 "The number of lambda capture initializers should equal the number of "
11840 "fields within the closure type");
11847 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(ClosureClass);
11848 for (
const auto *Field : ClosureClass->
fields()) {
11851 Expr *
const CurFieldInit = *CaptureInitIt++;
11858 LValue Subobject =
This;
11865 if (!Info.keepEvaluatingAfterFailure())
11873bool RecordExprEvaluator::VisitDesignatedInitUpdateExpr(
11874 const DesignatedInitUpdateExpr *E) {
11884 "can't evaluate expression as a record rvalue");
11885 return RecordExprEvaluator(Info,
This,
Result).Visit(E);
11896class TemporaryExprEvaluator
11897 :
public LValueExprEvaluatorBase<TemporaryExprEvaluator> {
11899 TemporaryExprEvaluator(EvalInfo &Info, LValue &
Result) :
11900 LValueExprEvaluatorBaseTy(Info,
Result,
false) {}
11903 bool VisitConstructExpr(
const Expr *E) {
11909 bool VisitCastExpr(
const CastExpr *E) {
11912 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
11914 case CK_ConstructorConversion:
11918 bool VisitInitListExpr(
const InitListExpr *E) {
11919 return VisitConstructExpr(E);
11921 bool VisitCXXConstructExpr(
const CXXConstructExpr *E) {
11922 return VisitConstructExpr(E);
11924 bool VisitCallExpr(
const CallExpr *E) {
11925 return VisitConstructExpr(E);
11927 bool VisitCXXStdInitializerListExpr(
const CXXStdInitializerListExpr *E) {
11928 return VisitConstructExpr(E);
11931 return VisitConstructExpr(E);
11940 return TemporaryExprEvaluator(Info,
Result).Visit(E);
11948 class VectorExprEvaluator
11949 :
public ExprEvaluatorBase<VectorExprEvaluator> {
11956 bool Success(ArrayRef<APValue>
V,
const Expr *E) {
11957 assert(
V.size() == E->
getType()->
castAs<VectorType>()->getNumElements());
11963 assert(
V.isVector());
11967 bool ZeroInitialization(
const Expr *E);
11969 bool VisitUnaryReal(
const UnaryOperator *E)
11971 bool VisitCastExpr(
const CastExpr* E);
11972 bool VisitInitListExpr(
const InitListExpr *E);
11973 bool VisitUnaryImag(
const UnaryOperator *E);
11974 bool VisitBinaryOperator(
const BinaryOperator *E);
11975 bool VisitUnaryOperator(
const UnaryOperator *E);
11976 bool VisitCallExpr(
const CallExpr *E);
11977 bool VisitConvertVectorExpr(
const ConvertVectorExpr *E);
11978 bool VisitShuffleVectorExpr(
const ShuffleVectorExpr *E);
11987 "not a vector prvalue");
11988 return VectorExprEvaluator(Info,
Result).Visit(E);
11992 assert(Val.
isVector() &&
"expected vector APValue");
11996 llvm::APInt
Result(NumElts, 0);
11998 for (
unsigned I = 0; I < NumElts; ++I) {
12000 assert(Elt.
isInt() &&
"expected integer element in bool vector");
12002 if (Elt.
getInt().getBoolValue())
12009bool VectorExprEvaluator::VisitCastExpr(
const CastExpr *E) {
12010 const VectorType *VTy = E->
getType()->
castAs<VectorType>();
12014 QualType SETy = SE->
getType();
12017 case CK_VectorSplat: {
12023 Val =
APValue(std::move(IntResult));
12028 Val =
APValue(std::move(FloatResult));
12045 Info.FFDiag(E, diag::note_constexpr_invalid_cast)
12046 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
12047 << Info.Ctx.getLangOpts().CPlusPlus;
12051 if (!handleRValueToRValueBitCast(Info,
Result, SVal, E))
12056 case CK_HLSLVectorTruncation: {
12061 for (
unsigned I = 0; I < NElts; I++)
12065 case CK_HLSLMatrixTruncation: {
12071 for (
unsigned Row = 0;
12073 for (
unsigned Col = 0;
12078 case CK_HLSLAggregateSplatCast: {
12095 case CK_HLSLElementwiseCast: {
12108 return Success(ResultEls, E);
12110 case CK_IntegralToFloating:
12111 case CK_FloatingToIntegral:
12112 case CK_IntegralCast:
12113 case CK_FloatingCast:
12114 case CK_FloatingToBoolean:
12115 case CK_IntegralToBoolean: {
12117 assert(SETy->
isVectorType() &&
"expected vector source type");
12123 QualType SrcEltTy = SETy->
castAs<VectorType>()->getElementType();
12128 for (
unsigned I = 0; I < NElts; ++I) {
12133 return Success(ResultEls, E);
12136 return ExprEvaluatorBaseTy::VisitCastExpr(E);
12141VectorExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
12158 unsigned CountInits = 0, CountElts = 0;
12159 while (CountElts < NumElements) {
12161 if (CountInits < NumInits
12167 for (
unsigned j = 0; j < vlen; j++)
12171 llvm::APSInt sInt(32);
12172 if (CountInits < NumInits) {
12176 sInt = Info.Ctx.MakeIntValue(0, EltTy);
12177 Elements.push_back(
APValue(sInt));
12180 llvm::APFloat f(0.0);
12181 if (CountInits < NumInits) {
12185 f = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy));
12186 Elements.push_back(
APValue(f));
12195VectorExprEvaluator::ZeroInitialization(
const Expr *E) {
12199 if (EltTy->isIntegerType())
12200 ZeroElement =
APValue(Info.Ctx.MakeIntValue(0, EltTy));
12203 APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy)));
12209bool VectorExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
12211 return ZeroInitialization(E);
12214bool VectorExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
12216 assert(Op != BO_PtrMemD && Op != BO_PtrMemI && Op != BO_Cmp &&
12217 "Operation not supported on vector types");
12219 if (Op == BO_Comma)
12220 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
12222 Expr *LHS = E->
getLHS();
12223 Expr *RHS = E->
getRHS();
12226 "Must both be vector types");
12229 assert(LHS->
getType()->
castAs<VectorType>()->getNumElements() ==
12233 "All operands must be the same size.");
12237 bool LHSOK =
Evaluate(LHSValue, Info, LHS);
12238 if (!LHSOK && !Info.noteFailure())
12240 if (!
Evaluate(RHSValue, Info, RHS) || !LHSOK)
12262 "Vector can only be int or float type");
12270 "Vector operator ~ can only be int");
12271 Elt.
getInt().flipAllBits();
12281 "Vector can only be int or float type");
12287 EltResult.setAllBits();
12289 EltResult.clearAllBits();
12295 return std::nullopt;
12299bool VectorExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
12305 const QualType ResultEltTy = VD->getElementType();
12309 if (!
Evaluate(SubExprValue, Info, SubExpr))
12322 "Vector length doesn't match type?");
12325 for (
unsigned EltNum = 0; EltNum < VD->getNumElements(); ++EltNum) {
12327 Info.Ctx, ResultEltTy, Op, SubExprValue.
getVectorElt(EltNum));
12330 ResultElements.push_back(*Elt);
12332 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12343 DestTy,
Result.getFloat());
12359 DestTy,
Result.getInt());
12363 Info.FFDiag(E, diag::err_convertvector_constexpr_unsupported_vector_cast)
12364 << SourceTy << DestTy;
12369 llvm::function_ref<APInt(
const APSInt &)> PackFn) {
12378 assert(LHSVecLen != 0 && LHSVecLen == RHSVecLen &&
12379 "pack builtin LHSVecLen must equal to RHSVecLen");
12382 const unsigned SrcBits = Info.Ctx.getIntWidth(VT0->
getElementType());
12388 const unsigned SrcPerLane = 128 / SrcBits;
12389 const unsigned Lanes = LHSVecLen * SrcBits / 128;
12392 Out.reserve(LHSVecLen + RHSVecLen);
12394 for (
unsigned Lane = 0; Lane != Lanes; ++Lane) {
12395 unsigned base = Lane * SrcPerLane;
12396 for (
unsigned I = 0; I != SrcPerLane; ++I)
12399 for (
unsigned I = 0; I != SrcPerLane; ++I)
12410 llvm::function_ref<std::pair<unsigned, int>(
unsigned,
unsigned)>
12417 unsigned ShuffleMask = 0;
12419 bool IsVectorMask =
false;
12420 bool IsSingleOperand = (
Call->getNumArgs() == 2);
12422 if (IsSingleOperand) {
12425 IsVectorMask =
true;
12434 ShuffleMask =
static_cast<unsigned>(MaskImm.getZExtValue());
12444 IsVectorMask =
true;
12453 ShuffleMask =
static_cast<unsigned>(MaskImm.getZExtValue());
12464 ResultElements.reserve(NumElts);
12466 for (
unsigned DstIdx = 0; DstIdx != NumElts; ++DstIdx) {
12467 if (IsVectorMask) {
12468 ShuffleMask =
static_cast<unsigned>(
12469 MaskVector.getVectorElt(DstIdx).getInt().getZExtValue());
12471 auto [SrcVecIdx, SrcIdx] = GetSourceIndex(DstIdx, ShuffleMask);
12477 ResultElements.push_back(
12478 APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(ElemTy))));
12484 ResultElements.push_back(
APValue());
12487 const APValue &Src = (SrcVecIdx == 0) ? A : B;
12492 Out =
APValue(ResultElements.data(), ResultElements.size());
12498 if (OrigVal.isInfinity()) {
12499 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << 0;
12502 if (OrigVal.isNaN()) {
12503 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << 1;
12507 APFloat Val = OrigVal;
12508 bool LosesInfo =
false;
12509 APFloat::opStatus Status = Val.convert(
12510 APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven, &LosesInfo);
12512 if (LosesInfo || Val.isDenormal()) {
12513 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic_strict);
12517 if (Status != APFloat::opOK) {
12518 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
12527 llvm::function_ref<APInt(
const APInt &, uint64_t)> ShiftOp,
12528 llvm::function_ref<APInt(
const APInt &,
unsigned)> OverflowOp) {
12535 assert(
Call->getNumArgs() == 2);
12539 Call->getArg(1)->getType()->isVectorType());
12542 unsigned DestEltWidth = Source.getVectorElt(0).getInt().getBitWidth();
12543 unsigned DestLen = Source.getVectorLength();
12546 unsigned NumBitsInQWord = 64;
12547 unsigned NumCountElts = NumBitsInQWord / CountEltWidth;
12549 Result.reserve(DestLen);
12551 uint64_t CountLQWord = 0;
12552 for (
unsigned EltIdx = 0; EltIdx != NumCountElts; ++EltIdx) {
12554 CountLQWord |= (Elt << (EltIdx * CountEltWidth));
12557 for (
unsigned EltIdx = 0; EltIdx != DestLen; ++EltIdx) {
12558 APInt Elt = Source.getVectorElt(EltIdx).getInt();
12559 if (CountLQWord < DestEltWidth) {
12561 APValue(
APSInt(ShiftOp(Elt, CountLQWord), IsDestUnsigned)));
12564 APValue(
APSInt(OverflowOp(Elt, DestEltWidth), IsDestUnsigned)));
12572 std::optional<APSInt> RoundingMode,
12574 APSInt DefaultMode(APInt(32, 4),
true);
12575 if (RoundingMode.value_or(DefaultMode) != 4)
12576 return std::nullopt;
12577 if (A.isNaN() || A.isInfinity() || A.isDenormal() || B.isNaN() ||
12578 B.isInfinity() || B.isDenormal())
12579 return std::nullopt;
12580 if (A.isZero() && B.isZero())
12582 return IsMin ? llvm::minimum(A, B) : llvm::maximum(A, B);
12585bool VectorExprEvaluator::VisitCallExpr(
const CallExpr *E) {
12586 if (!IsConstantEvaluatedBuiltinCall(E))
12587 return ExprEvaluatorBaseTy::VisitCallExpr(E);
12591 auto EvaluateBinOpExpr =
12593 APValue SourceLHS, SourceRHS;
12599 QualType DestEltTy = DestTy->getElementType();
12600 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
12603 ResultElements.reserve(SourceLen);
12605 if (SourceRHS.
isInt()) {
12607 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12609 ResultElements.push_back(
12613 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12616 ResultElements.push_back(
12623 auto EvaluateFpBinOpExpr =
12624 [&](llvm::function_ref<std::optional<APFloat>(
12625 const APFloat &,
const APFloat &, std::optional<APSInt>)>
12627 bool IsScalar =
false) {
12637 std::optional<APSInt> RoundingMode;
12642 RoundingMode = Imm;
12647 ResultElements.reserve(NumElems);
12649 for (
unsigned EltNum = 0; EltNum < NumElems; ++EltNum) {
12650 if (IsScalar && EltNum > 0) {
12656 std::optional<APFloat>
Result =
Fn(EltA, EltB, RoundingMode);
12664 auto EvaluateScalarFpRoundMaskBinOp =
12665 [&](llvm::function_ref<std::optional<APFloat>(
12666 const APFloat &,
const APFloat &, std::optional<APSInt>)>
12670 APSInt MaskVal, Rounding;
12681 ResultElements.reserve(NumElems);
12683 if (MaskVal.getZExtValue() & 1) {
12686 std::optional<APFloat>
Result =
Fn(EltA, EltB, Rounding);
12694 for (
unsigned I = 1; I < NumElems; ++I)
12700 auto EvalSelectScalar = [&](
unsigned Len) ->
bool {
12708 bool TakeA0 = (Mask.getZExtValue() & 1u) != 0;
12712 for (
unsigned I = 1; I < Len; ++I)
12714 APValue V(Res.data(), Res.size());
12718 auto EvalVectorDotProduct = [&](
bool IsSaturating) ->
bool {
12719 APValue Source, OperandA, OperandB;
12728 unsigned ElemsPerLane = NumOperandElems / NumSrcElems;
12733 Result.reserve(NumSrcElems);
12734 for (
unsigned I = 0; I != NumSrcElems; ++I) {
12736 DotProduct = DotProduct.extend(64);
12737 for (
unsigned J = 0; J != ElemsPerLane; ++J) {
12744 DotProduct += OpA * OpB;
12746 if (IsSaturating) {
12747 DotProduct =
APSInt(DotProduct.truncSSat(32),
false);
12749 DotProduct =
APSInt(DotProduct.trunc(32),
false);
12757 switch (BuiltinOp) {
12760 case Builtin::BI__builtin_elementwise_popcount:
12761 case Builtin::BI__builtin_elementwise_bitreverse: {
12766 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12769 ResultElements.reserve(SourceLen);
12771 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12773 switch (BuiltinOp) {
12774 case Builtin::BI__builtin_elementwise_popcount:
12775 ResultElements.push_back(
APValue(
12776 APSInt(
APInt(Info.Ctx.getIntWidth(DestEltTy), Elt.popcount()),
12779 case Builtin::BI__builtin_elementwise_bitreverse:
12780 ResultElements.push_back(
12787 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12789 case Builtin::BI__builtin_elementwise_abs: {
12794 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12797 ResultElements.reserve(SourceLen);
12799 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12804 CurrentEle.getInt().
abs(),
12805 DestEltTy->isUnsignedIntegerOrEnumerationType()));
12806 ResultElements.push_back(Val);
12809 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12812 case Builtin::BI__builtin_elementwise_add_sat:
12813 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12814 return LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS);
12817 case Builtin::BI__builtin_elementwise_sub_sat:
12818 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12819 return LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
12822 case X86::BI__builtin_ia32_extract128i256:
12823 case X86::BI__builtin_ia32_vextractf128_pd256:
12824 case X86::BI__builtin_ia32_vextractf128_ps256:
12825 case X86::BI__builtin_ia32_vextractf128_si256: {
12826 APValue SourceVec, SourceImm;
12835 unsigned RetLen = RetVT->getNumElements();
12836 unsigned Idx = SourceImm.
getInt().getZExtValue() & 1;
12839 ResultElements.reserve(RetLen);
12841 for (
unsigned I = 0; I < RetLen; I++)
12842 ResultElements.push_back(SourceVec.
getVectorElt(Idx * RetLen + I));
12847 case clang::X86::BI__builtin_ia32_cvtmask2b128:
12848 case clang::X86::BI__builtin_ia32_cvtmask2b256:
12849 case clang::X86::BI__builtin_ia32_cvtmask2b512:
12850 case clang::X86::BI__builtin_ia32_cvtmask2w128:
12851 case clang::X86::BI__builtin_ia32_cvtmask2w256:
12852 case clang::X86::BI__builtin_ia32_cvtmask2w512:
12853 case clang::X86::BI__builtin_ia32_cvtmask2d128:
12854 case clang::X86::BI__builtin_ia32_cvtmask2d256:
12855 case clang::X86::BI__builtin_ia32_cvtmask2d512:
12856 case clang::X86::BI__builtin_ia32_cvtmask2q128:
12857 case clang::X86::BI__builtin_ia32_cvtmask2q256:
12858 case clang::X86::BI__builtin_ia32_cvtmask2q512: {
12864 QualType VecTy = E->
getType();
12865 const VectorType *VT = VecTy->
castAs<VectorType>();
12868 unsigned ElemWidth = Info.Ctx.getTypeSize(ElemTy);
12871 for (
unsigned I = 0; I != VectorLen; ++I) {
12872 bool BitSet = Mask[I];
12873 APSInt ElemVal(ElemWidth,
false);
12875 ElemVal.setAllBits();
12877 Elems.push_back(
APValue(ElemVal));
12882 case X86::BI__builtin_ia32_extracti32x4_256_mask:
12883 case X86::BI__builtin_ia32_extractf32x4_256_mask:
12884 case X86::BI__builtin_ia32_extracti32x4_mask:
12885 case X86::BI__builtin_ia32_extractf32x4_mask:
12886 case X86::BI__builtin_ia32_extracti32x8_mask:
12887 case X86::BI__builtin_ia32_extractf32x8_mask:
12888 case X86::BI__builtin_ia32_extracti64x2_256_mask:
12889 case X86::BI__builtin_ia32_extractf64x2_256_mask:
12890 case X86::BI__builtin_ia32_extracti64x2_512_mask:
12891 case X86::BI__builtin_ia32_extractf64x2_512_mask:
12892 case X86::BI__builtin_ia32_extracti64x4_mask:
12893 case X86::BI__builtin_ia32_extractf64x4_mask: {
12904 unsigned RetLen = RetVT->getNumElements();
12909 unsigned Lanes = SrcLen / RetLen;
12910 unsigned Lane =
static_cast<unsigned>(Imm.getZExtValue() % Lanes);
12911 unsigned Base = Lane * RetLen;
12914 ResultElements.reserve(RetLen);
12915 for (
unsigned I = 0; I < RetLen; ++I) {
12917 ResultElements.push_back(SourceVec.
getVectorElt(Base + I));
12921 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12924 case clang::X86::BI__builtin_ia32_pavgb128:
12925 case clang::X86::BI__builtin_ia32_pavgw128:
12926 case clang::X86::BI__builtin_ia32_pavgb256:
12927 case clang::X86::BI__builtin_ia32_pavgw256:
12928 case clang::X86::BI__builtin_ia32_pavgb512:
12929 case clang::X86::BI__builtin_ia32_pavgw512:
12930 return EvaluateBinOpExpr(llvm::APIntOps::avgCeilU);
12932 case clang::X86::BI__builtin_ia32_pmulhrsw128:
12933 case clang::X86::BI__builtin_ia32_pmulhrsw256:
12934 case clang::X86::BI__builtin_ia32_pmulhrsw512:
12935 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12936 return (llvm::APIntOps::mulsExtended(LHS, RHS).ashr(14) + 1)
12937 .extractBits(16, 1);
12940 case clang::X86::BI__builtin_ia32_psadbw128:
12941 case clang::X86::BI__builtin_ia32_psadbw256:
12942 case clang::X86::BI__builtin_ia32_psadbw512: {
12943 APValue SourceLHS, SourceRHS;
12951 assert((SourceLen % 8) == 0);
12954 QualType DestEltTy = DestTy->getElementType();
12955 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
12957 ResultElements.reserve(SourceLen / 8);
12959 for (
unsigned Lane = 0; Lane != SourceLen; Lane += 8) {
12961 for (
unsigned I = 0; I != 8; ++I) {
12964 Sum += llvm::APIntOps::abdu(LHS, RHS).zext(64);
12966 ResultElements.push_back(
APValue(
APSInt(Sum, DestUnsigned)));
12969 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12972 case clang::X86::BI__builtin_ia32_pmaddubsw128:
12973 case clang::X86::BI__builtin_ia32_pmaddubsw256:
12974 case clang::X86::BI__builtin_ia32_pmaddubsw512:
12975 case clang::X86::BI__builtin_ia32_pmaddwd128:
12976 case clang::X86::BI__builtin_ia32_pmaddwd256:
12977 case clang::X86::BI__builtin_ia32_pmaddwd512: {
12978 APValue SourceLHS, SourceRHS;
12984 QualType DestEltTy = DestTy->getElementType();
12986 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
12988 ResultElements.reserve(SourceLen / 2);
12990 for (
unsigned EltNum = 0; EltNum < SourceLen; EltNum += 2) {
12995 unsigned BitWidth = 2 * LoLHS.getBitWidth();
12997 switch (BuiltinOp) {
12998 case clang::X86::BI__builtin_ia32_pmaddubsw128:
12999 case clang::X86::BI__builtin_ia32_pmaddubsw256:
13000 case clang::X86::BI__builtin_ia32_pmaddubsw512:
13001 ResultElements.push_back(
APValue(
13002 APSInt((LoLHS.zext(BitWidth) * LoRHS.sext(BitWidth))
13003 .sadd_sat((HiLHS.zext(BitWidth) * HiRHS.sext(BitWidth))),
13006 case clang::X86::BI__builtin_ia32_pmaddwd128:
13007 case clang::X86::BI__builtin_ia32_pmaddwd256:
13008 case clang::X86::BI__builtin_ia32_pmaddwd512:
13009 ResultElements.push_back(
13010 APValue(
APSInt((LoLHS.sext(BitWidth) * LoRHS.sext(BitWidth)) +
13011 (HiLHS.sext(BitWidth) * HiRHS.sext(BitWidth)),
13017 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13020 case clang::X86::BI__builtin_ia32_bmacor16x16x16_v16hi:
13021 case clang::X86::BI__builtin_ia32_bmacor16x16x16_v32hi:
13022 case clang::X86::BI__builtin_ia32_bmacxor16x16x16_v16hi:
13023 case clang::X86::BI__builtin_ia32_bmacxor16x16x16_v32hi: {
13034 APValue SourceA, SourceB, SourceC;
13041 clang::X86::BI__builtin_ia32_bmacxor16x16x16_v16hi ||
13043 clang::X86::BI__builtin_ia32_bmacxor16x16x16_v32hi;
13046 assert(SourceLen % 16 == 0 &&
"BMM operates on 256-bit lanes of 16 x i16");
13048 QualType DestEltTy = DestTy->getElementType();
13049 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
13052 for (
unsigned Lane = 0; Lane != SourceLen; Lane += 16) {
13053 for (
unsigned I = 0; I != 16; ++I) {
13058 for (
unsigned J = 0; J != 16; ++J) {
13062 unsigned Bit = (Dst >> J) & 1u;
13063 for (
unsigned K = 0; K != 16; ++K) {
13067 unsigned Product = ((A >> K) & 1u) & ((B >> J) & 1u);
13068 Bit = IsXor ? (Bit ^ Product) : (Bit | Product);
13072 ResultElements[Lane + I] =
13076 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13079 case clang::X86::BI__builtin_ia32_dbpsadbw128:
13080 case clang::X86::BI__builtin_ia32_dbpsadbw256:
13081 case clang::X86::BI__builtin_ia32_dbpsadbw512: {
13082 APValue SourceA, SourceB, SourceImm;
13089 constexpr unsigned LaneSize = 16;
13090 unsigned Imm = SourceImm.
getInt().getZExtValue();
13093 QualType DestEltTy = DestTy->getElementType();
13094 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
13096 ResultElements.reserve(SourceLen / 2);
13102 for (
unsigned I = 0; I < SourceLen; I += LaneSize) {
13103 for (
unsigned J = 0; J < 4; ++J) {
13104 unsigned Part = (Imm >> (2 * J)) & 3;
13105 for (
unsigned K = 0; K < 4; ++K) {
13106 Shuffled[I + 4 * J + K] =
static_cast<uint8_t>(
13107 SourceB.
getVectorElt(I + 4 * Part + K).getInt().getZExtValue());
13115 unsigned Size = SourceLen / 2;
13116 for (
unsigned I = 0; I <
Size; I += 4) {
13117 unsigned Sad[4] = {0, 0, 0, 0};
13118 for (
unsigned J = 0; J < 4; ++J) {
13120 SourceA.
getVectorElt(2 * I + J).getInt().getZExtValue());
13122 SourceA.
getVectorElt(2 * I + J + 4).getInt().getZExtValue());
13123 uint8_t B0 = Shuffled[2 * I + J];
13124 uint8_t B1 = Shuffled[2 * I + J + 1];
13125 uint8_t B2 = Shuffled[2 * I + J + 2];
13126 uint8_t B3 = Shuffled[2 * I + J + 3];
13127 Sad[0] += (A1 > B0) ? (A1 - B0) : (B0 - A1);
13128 Sad[1] += (A1 > B1) ? (A1 - B1) : (B1 - A1);
13129 Sad[2] += (A2 > B2) ? (A2 - B2) : (B2 - A2);
13130 Sad[3] += (A2 > B3) ? (A2 - B3) : (B3 - A2);
13132 for (
unsigned R = 0;
R < 4; ++
R)
13133 ResultElements.push_back(
13137 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13140 case clang::X86::BI__builtin_ia32_mpsadbw128:
13141 case clang::X86::BI__builtin_ia32_mpsadbw256: {
13149 constexpr unsigned LaneSize = 16;
13150 assert((SourceLen == LaneSize || SourceLen == 2 * LaneSize) &&
13151 "MPSADBW operates on 128-bit or 256-bit vectors");
13152 unsigned NumLanes = SourceLen / LaneSize;
13153 unsigned Imm = SourceImm.getZExtValue();
13155 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13158 ResultElements.reserve(SourceLen / 2);
13160 for (
unsigned Lane = 0; Lane != NumLanes; ++Lane) {
13161 unsigned Ctrl = (Imm >> (3 * Lane)) & 0x7;
13162 unsigned AOff = ((Ctrl >> 2) & 1) * 4;
13163 unsigned BOff = (Ctrl & 3) * 4;
13164 for (
unsigned J = 0; J != 8; ++J) {
13166 for (
unsigned K = 0; K != 4; ++K) {
13175 Sad += (A > B) ? (A - B) : (B - A);
13180 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13183 case clang::X86::BI__builtin_ia32_pmulhuw128:
13184 case clang::X86::BI__builtin_ia32_pmulhuw256:
13185 case clang::X86::BI__builtin_ia32_pmulhuw512:
13186 return EvaluateBinOpExpr(llvm::APIntOps::mulhu);
13188 case clang::X86::BI__builtin_ia32_pmulhw128:
13189 case clang::X86::BI__builtin_ia32_pmulhw256:
13190 case clang::X86::BI__builtin_ia32_pmulhw512:
13191 return EvaluateBinOpExpr(llvm::APIntOps::mulhs);
13193 case clang::X86::BI__builtin_ia32_psllv2di:
13194 case clang::X86::BI__builtin_ia32_psllv4di:
13195 case clang::X86::BI__builtin_ia32_psllv4si:
13196 case clang::X86::BI__builtin_ia32_psllv8di:
13197 case clang::X86::BI__builtin_ia32_psllv8hi:
13198 case clang::X86::BI__builtin_ia32_psllv8si:
13199 case clang::X86::BI__builtin_ia32_psllv16hi:
13200 case clang::X86::BI__builtin_ia32_psllv16si:
13201 case clang::X86::BI__builtin_ia32_psllv32hi:
13202 case clang::X86::BI__builtin_ia32_psllwi128:
13203 case clang::X86::BI__builtin_ia32_pslldi128:
13204 case clang::X86::BI__builtin_ia32_psllqi128:
13205 case clang::X86::BI__builtin_ia32_psllwi256:
13206 case clang::X86::BI__builtin_ia32_pslldi256:
13207 case clang::X86::BI__builtin_ia32_psllqi256:
13208 case clang::X86::BI__builtin_ia32_psllwi512:
13209 case clang::X86::BI__builtin_ia32_pslldi512:
13210 case clang::X86::BI__builtin_ia32_psllqi512:
13211 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
13212 if (RHS.uge(LHS.getBitWidth())) {
13213 return APInt::getZero(LHS.getBitWidth());
13215 return LHS.shl(RHS.getZExtValue());
13218 case clang::X86::BI__builtin_ia32_psrav4si:
13219 case clang::X86::BI__builtin_ia32_psrav8di:
13220 case clang::X86::BI__builtin_ia32_psrav8hi:
13221 case clang::X86::BI__builtin_ia32_psrav8si:
13222 case clang::X86::BI__builtin_ia32_psrav16hi:
13223 case clang::X86::BI__builtin_ia32_psrav16si:
13224 case clang::X86::BI__builtin_ia32_psrav32hi:
13225 case clang::X86::BI__builtin_ia32_psravq128:
13226 case clang::X86::BI__builtin_ia32_psravq256:
13227 case clang::X86::BI__builtin_ia32_psrawi128:
13228 case clang::X86::BI__builtin_ia32_psradi128:
13229 case clang::X86::BI__builtin_ia32_psraqi128:
13230 case clang::X86::BI__builtin_ia32_psrawi256:
13231 case clang::X86::BI__builtin_ia32_psradi256:
13232 case clang::X86::BI__builtin_ia32_psraqi256:
13233 case clang::X86::BI__builtin_ia32_psrawi512:
13234 case clang::X86::BI__builtin_ia32_psradi512:
13235 case clang::X86::BI__builtin_ia32_psraqi512:
13236 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
13237 if (RHS.uge(LHS.getBitWidth())) {
13238 return LHS.ashr(LHS.getBitWidth() - 1);
13240 return LHS.ashr(RHS.getZExtValue());
13243 case clang::X86::BI__builtin_ia32_psrlv2di:
13244 case clang::X86::BI__builtin_ia32_psrlv4di:
13245 case clang::X86::BI__builtin_ia32_psrlv4si:
13246 case clang::X86::BI__builtin_ia32_psrlv8di:
13247 case clang::X86::BI__builtin_ia32_psrlv8hi:
13248 case clang::X86::BI__builtin_ia32_psrlv8si:
13249 case clang::X86::BI__builtin_ia32_psrlv16hi:
13250 case clang::X86::BI__builtin_ia32_psrlv16si:
13251 case clang::X86::BI__builtin_ia32_psrlv32hi:
13252 case clang::X86::BI__builtin_ia32_psrlwi128:
13253 case clang::X86::BI__builtin_ia32_psrldi128:
13254 case clang::X86::BI__builtin_ia32_psrlqi128:
13255 case clang::X86::BI__builtin_ia32_psrlwi256:
13256 case clang::X86::BI__builtin_ia32_psrldi256:
13257 case clang::X86::BI__builtin_ia32_psrlqi256:
13258 case clang::X86::BI__builtin_ia32_psrlwi512:
13259 case clang::X86::BI__builtin_ia32_psrldi512:
13260 case clang::X86::BI__builtin_ia32_psrlqi512:
13261 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
13262 if (RHS.uge(LHS.getBitWidth())) {
13263 return APInt::getZero(LHS.getBitWidth());
13265 return LHS.lshr(RHS.getZExtValue());
13267 case X86::BI__builtin_ia32_packsswb128:
13268 case X86::BI__builtin_ia32_packsswb256:
13269 case X86::BI__builtin_ia32_packsswb512:
13270 case X86::BI__builtin_ia32_packssdw128:
13271 case X86::BI__builtin_ia32_packssdw256:
13272 case X86::BI__builtin_ia32_packssdw512:
13274 return APSInt(Src).truncSSat(Src.getBitWidth() / 2);
13276 case X86::BI__builtin_ia32_packusdw128:
13277 case X86::BI__builtin_ia32_packusdw256:
13278 case X86::BI__builtin_ia32_packusdw512:
13279 case X86::BI__builtin_ia32_packuswb128:
13280 case X86::BI__builtin_ia32_packuswb256:
13281 case X86::BI__builtin_ia32_packuswb512:
13283 return APSInt(Src).truncSSatU(Src.getBitWidth() / 2);
13285 case clang::X86::BI__builtin_ia32_selectss_128:
13286 return EvalSelectScalar(4);
13287 case clang::X86::BI__builtin_ia32_selectsd_128:
13288 return EvalSelectScalar(2);
13289 case clang::X86::BI__builtin_ia32_selectsh_128:
13290 case clang::X86::BI__builtin_ia32_selectsbf_128:
13291 return EvalSelectScalar(8);
13292 case clang::X86::BI__builtin_ia32_pmuldq128:
13293 case clang::X86::BI__builtin_ia32_pmuldq256:
13294 case clang::X86::BI__builtin_ia32_pmuldq512:
13295 case clang::X86::BI__builtin_ia32_pmuludq128:
13296 case clang::X86::BI__builtin_ia32_pmuludq256:
13297 case clang::X86::BI__builtin_ia32_pmuludq512: {
13298 APValue SourceLHS, SourceRHS;
13305 ResultElements.reserve(SourceLen / 2);
13307 for (
unsigned EltNum = 0; EltNum < SourceLen; EltNum += 2) {
13311 switch (BuiltinOp) {
13312 case clang::X86::BI__builtin_ia32_pmuludq128:
13313 case clang::X86::BI__builtin_ia32_pmuludq256:
13314 case clang::X86::BI__builtin_ia32_pmuludq512:
13315 ResultElements.push_back(
13316 APValue(
APSInt(llvm::APIntOps::muluExtended(LHS, RHS),
true)));
13318 case clang::X86::BI__builtin_ia32_pmuldq128:
13319 case clang::X86::BI__builtin_ia32_pmuldq256:
13320 case clang::X86::BI__builtin_ia32_pmuldq512:
13321 ResultElements.push_back(
13322 APValue(
APSInt(llvm::APIntOps::mulsExtended(LHS, RHS),
false)));
13327 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13330 case X86::BI__builtin_ia32_vpmadd52luq128:
13331 case X86::BI__builtin_ia32_vpmadd52luq256:
13332 case X86::BI__builtin_ia32_vpmadd52luq512: {
13341 ResultElements.reserve(ALen);
13343 for (
unsigned EltNum = 0; EltNum < ALen; EltNum += 1) {
13346 APInt CElt =
C.getVectorElt(EltNum).getInt().trunc(52);
13347 APSInt ResElt(AElt + (BElt * CElt).zext(64),
false);
13348 ResultElements.push_back(
APValue(ResElt));
13351 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13353 case X86::BI__builtin_ia32_vpmadd52huq128:
13354 case X86::BI__builtin_ia32_vpmadd52huq256:
13355 case X86::BI__builtin_ia32_vpmadd52huq512: {
13364 ResultElements.reserve(ALen);
13366 for (
unsigned EltNum = 0; EltNum < ALen; EltNum += 1) {
13369 APInt CElt =
C.getVectorElt(EltNum).getInt().trunc(52);
13370 APSInt ResElt(AElt + llvm::APIntOps::mulhu(BElt, CElt).zext(64),
false);
13371 ResultElements.push_back(
APValue(ResElt));
13374 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13377 case clang::X86::BI__builtin_ia32_vprotbi:
13378 case clang::X86::BI__builtin_ia32_vprotdi:
13379 case clang::X86::BI__builtin_ia32_vprotqi:
13380 case clang::X86::BI__builtin_ia32_vprotwi:
13381 case clang::X86::BI__builtin_ia32_prold128:
13382 case clang::X86::BI__builtin_ia32_prold256:
13383 case clang::X86::BI__builtin_ia32_prold512:
13384 case clang::X86::BI__builtin_ia32_prolq128:
13385 case clang::X86::BI__builtin_ia32_prolq256:
13386 case clang::X86::BI__builtin_ia32_prolq512:
13387 return EvaluateBinOpExpr(
13388 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS.rotl(RHS); });
13390 case clang::X86::BI__builtin_ia32_prord128:
13391 case clang::X86::BI__builtin_ia32_prord256:
13392 case clang::X86::BI__builtin_ia32_prord512:
13393 case clang::X86::BI__builtin_ia32_prorq128:
13394 case clang::X86::BI__builtin_ia32_prorq256:
13395 case clang::X86::BI__builtin_ia32_prorq512:
13396 return EvaluateBinOpExpr(
13397 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS.rotr(RHS); });
13399 case Builtin::BI__builtin_elementwise_max:
13400 case Builtin::BI__builtin_elementwise_min: {
13401 APValue SourceLHS, SourceRHS;
13406 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13413 ResultElements.reserve(SourceLen);
13415 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13418 switch (BuiltinOp) {
13419 case Builtin::BI__builtin_elementwise_max:
13420 ResultElements.push_back(
13424 case Builtin::BI__builtin_elementwise_min:
13425 ResultElements.push_back(
13432 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13434 case X86::BI__builtin_ia32_vpshldd128:
13435 case X86::BI__builtin_ia32_vpshldd256:
13436 case X86::BI__builtin_ia32_vpshldd512:
13437 case X86::BI__builtin_ia32_vpshldq128:
13438 case X86::BI__builtin_ia32_vpshldq256:
13439 case X86::BI__builtin_ia32_vpshldq512:
13440 case X86::BI__builtin_ia32_vpshldw128:
13441 case X86::BI__builtin_ia32_vpshldw256:
13442 case X86::BI__builtin_ia32_vpshldw512: {
13443 APValue SourceHi, SourceLo, SourceAmt;
13449 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13452 ResultElements.reserve(SourceLen);
13455 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13458 APInt R = llvm::APIntOps::fshl(Hi, Lo, Amt);
13459 ResultElements.push_back(
13463 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13465 case X86::BI__builtin_ia32_vpshrdd128:
13466 case X86::BI__builtin_ia32_vpshrdd256:
13467 case X86::BI__builtin_ia32_vpshrdd512:
13468 case X86::BI__builtin_ia32_vpshrdq128:
13469 case X86::BI__builtin_ia32_vpshrdq256:
13470 case X86::BI__builtin_ia32_vpshrdq512:
13471 case X86::BI__builtin_ia32_vpshrdw128:
13472 case X86::BI__builtin_ia32_vpshrdw256:
13473 case X86::BI__builtin_ia32_vpshrdw512: {
13475 APValue SourceHi, SourceLo, SourceAmt;
13481 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13484 ResultElements.reserve(SourceLen);
13487 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13490 APInt R = llvm::APIntOps::fshr(Hi, Lo, Amt);
13491 ResultElements.push_back(
13495 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13497 case X86::BI__builtin_ia32_compressdf128_mask:
13498 case X86::BI__builtin_ia32_compressdf256_mask:
13499 case X86::BI__builtin_ia32_compressdf512_mask:
13500 case X86::BI__builtin_ia32_compressdi128_mask:
13501 case X86::BI__builtin_ia32_compressdi256_mask:
13502 case X86::BI__builtin_ia32_compressdi512_mask:
13503 case X86::BI__builtin_ia32_compresshi128_mask:
13504 case X86::BI__builtin_ia32_compresshi256_mask:
13505 case X86::BI__builtin_ia32_compresshi512_mask:
13506 case X86::BI__builtin_ia32_compressqi128_mask:
13507 case X86::BI__builtin_ia32_compressqi256_mask:
13508 case X86::BI__builtin_ia32_compressqi512_mask:
13509 case X86::BI__builtin_ia32_compresssf128_mask:
13510 case X86::BI__builtin_ia32_compresssf256_mask:
13511 case X86::BI__builtin_ia32_compresssf512_mask:
13512 case X86::BI__builtin_ia32_compresssi128_mask:
13513 case X86::BI__builtin_ia32_compresssi256_mask:
13514 case X86::BI__builtin_ia32_compresssi512_mask: {
13525 ResultElements.reserve(NumElts);
13527 for (
unsigned I = 0; I != NumElts; ++I) {
13531 for (
unsigned I = ResultElements.size(); I != NumElts; ++I) {
13535 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13537 case X86::BI__builtin_ia32_expanddf128_mask:
13538 case X86::BI__builtin_ia32_expanddf256_mask:
13539 case X86::BI__builtin_ia32_expanddf512_mask:
13540 case X86::BI__builtin_ia32_expanddi128_mask:
13541 case X86::BI__builtin_ia32_expanddi256_mask:
13542 case X86::BI__builtin_ia32_expanddi512_mask:
13543 case X86::BI__builtin_ia32_expandhi128_mask:
13544 case X86::BI__builtin_ia32_expandhi256_mask:
13545 case X86::BI__builtin_ia32_expandhi512_mask:
13546 case X86::BI__builtin_ia32_expandqi128_mask:
13547 case X86::BI__builtin_ia32_expandqi256_mask:
13548 case X86::BI__builtin_ia32_expandqi512_mask:
13549 case X86::BI__builtin_ia32_expandsf128_mask:
13550 case X86::BI__builtin_ia32_expandsf256_mask:
13551 case X86::BI__builtin_ia32_expandsf512_mask:
13552 case X86::BI__builtin_ia32_expandsi128_mask:
13553 case X86::BI__builtin_ia32_expandsi256_mask:
13554 case X86::BI__builtin_ia32_expandsi512_mask: {
13565 ResultElements.reserve(NumElts);
13567 unsigned SourceIdx = 0;
13568 for (
unsigned I = 0; I != NumElts; ++I) {
13570 ResultElements.push_back(Source.
getVectorElt(SourceIdx++));
13574 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13576 case X86::BI__builtin_ia32_vpconflictsi_128:
13577 case X86::BI__builtin_ia32_vpconflictsi_256:
13578 case X86::BI__builtin_ia32_vpconflictsi_512:
13579 case X86::BI__builtin_ia32_vpconflictdi_128:
13580 case X86::BI__builtin_ia32_vpconflictdi_256:
13581 case X86::BI__builtin_ia32_vpconflictdi_512: {
13589 ResultElements.reserve(SourceLen);
13592 bool DestUnsigned =
13593 VecT->getElementType()->isUnsignedIntegerOrEnumerationType();
13595 for (
unsigned I = 0; I != SourceLen; ++I) {
13598 APInt ConflictMask(EltI.
getInt().getBitWidth(), 0);
13599 for (
unsigned J = 0; J != I; ++J) {
13601 ConflictMask.setBitVal(J, EltI.
getInt() == EltJ.
getInt());
13603 ResultElements.push_back(
APValue(
APSInt(ConflictMask, DestUnsigned)));
13605 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13607 case X86::BI__builtin_ia32_blendpd:
13608 case X86::BI__builtin_ia32_blendpd256:
13609 case X86::BI__builtin_ia32_blendps:
13610 case X86::BI__builtin_ia32_blendps256:
13611 case X86::BI__builtin_ia32_pblendw128:
13612 case X86::BI__builtin_ia32_pblendw256:
13613 case X86::BI__builtin_ia32_pblendd128:
13614 case X86::BI__builtin_ia32_pblendd256: {
13615 APValue SourceF, SourceT, SourceC;
13624 ResultElements.reserve(SourceLen);
13625 for (
unsigned EltNum = 0; EltNum != SourceLen; ++EltNum) {
13628 ResultElements.push_back(
C[EltNum % 8] ?
T : F);
13631 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13634 case X86::BI__builtin_ia32_psignb128:
13635 case X86::BI__builtin_ia32_psignb256:
13636 case X86::BI__builtin_ia32_psignw128:
13637 case X86::BI__builtin_ia32_psignw256:
13638 case X86::BI__builtin_ia32_psignd128:
13639 case X86::BI__builtin_ia32_psignd256:
13640 return EvaluateBinOpExpr([](
const APInt &AElem,
const APInt &BElem) {
13641 if (BElem.isZero())
13642 return APInt::getZero(AElem.getBitWidth());
13643 if (BElem.isNegative())
13648 case X86::BI__builtin_ia32_blendvpd:
13649 case X86::BI__builtin_ia32_blendvpd256:
13650 case X86::BI__builtin_ia32_blendvps:
13651 case X86::BI__builtin_ia32_blendvps256:
13652 case X86::BI__builtin_ia32_pblendvb128:
13653 case X86::BI__builtin_ia32_pblendvb256: {
13655 APValue SourceF, SourceT, SourceC;
13663 ResultElements.reserve(SourceLen);
13665 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13669 APInt M =
C.isInt() ? (
APInt)
C.getInt() :
C.getFloat().bitcastToAPInt();
13670 ResultElements.push_back(M.isNegative() ?
T : F);
13673 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13675 case X86::BI__builtin_ia32_selectb_128:
13676 case X86::BI__builtin_ia32_selectb_256:
13677 case X86::BI__builtin_ia32_selectb_512:
13678 case X86::BI__builtin_ia32_selectw_128:
13679 case X86::BI__builtin_ia32_selectw_256:
13680 case X86::BI__builtin_ia32_selectw_512:
13681 case X86::BI__builtin_ia32_selectd_128:
13682 case X86::BI__builtin_ia32_selectd_256:
13683 case X86::BI__builtin_ia32_selectd_512:
13684 case X86::BI__builtin_ia32_selectq_128:
13685 case X86::BI__builtin_ia32_selectq_256:
13686 case X86::BI__builtin_ia32_selectq_512:
13687 case X86::BI__builtin_ia32_selectph_128:
13688 case X86::BI__builtin_ia32_selectph_256:
13689 case X86::BI__builtin_ia32_selectph_512:
13690 case X86::BI__builtin_ia32_selectpbf_128:
13691 case X86::BI__builtin_ia32_selectpbf_256:
13692 case X86::BI__builtin_ia32_selectpbf_512:
13693 case X86::BI__builtin_ia32_selectps_128:
13694 case X86::BI__builtin_ia32_selectps_256:
13695 case X86::BI__builtin_ia32_selectps_512:
13696 case X86::BI__builtin_ia32_selectpd_128:
13697 case X86::BI__builtin_ia32_selectpd_256:
13698 case X86::BI__builtin_ia32_selectpd_512: {
13700 APValue SourceMask, SourceLHS, SourceRHS;
13709 ResultElements.reserve(SourceLen);
13711 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13714 ResultElements.push_back(Mask[EltNum] ? LHS : RHS);
13717 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13720 case X86::BI__builtin_ia32_cvtsd2ss: {
13733 Elements.push_back(ResultVal);
13736 for (
unsigned I = 1; I < NumEltsA; ++I) {
13742 case X86::BI__builtin_ia32_cvtsd2ss_round_mask: {
13743 APValue VecA, VecB, VecSrc, MaskValue;
13751 unsigned Mask = MaskValue.
getInt().getZExtValue();
13759 Elements.push_back(ResultVal);
13765 for (
unsigned I = 1; I < NumEltsA; ++I) {
13771 case X86::BI__builtin_ia32_cvtpd2ps:
13772 case X86::BI__builtin_ia32_cvtpd2ps256:
13773 case X86::BI__builtin_ia32_cvtpd2ps_mask:
13774 case X86::BI__builtin_ia32_cvtpd2ps512_mask: {
13776 const auto BuiltinID = BuiltinOp;
13777 bool IsMasked = (BuiltinID == X86::BI__builtin_ia32_cvtpd2ps_mask ||
13778 BuiltinID == X86::BI__builtin_ia32_cvtpd2ps512_mask);
13785 unsigned Mask = 0xFFFFFFFF;
13786 bool NeedsMerge =
false;
13791 Mask = MaskValue.
getInt().getZExtValue();
13792 auto NumEltsResult = E->
getType()->
getAs<VectorType>()->getNumElements();
13793 for (
unsigned I = 0; I < NumEltsResult; ++I) {
13794 if (!((Mask >> I) & 1)) {
13805 unsigned NumEltsResult =
13809 for (
unsigned I = 0; I < NumEltsResult; ++I) {
13810 if (IsMasked && !((Mask >> I) & 1)) {
13818 if (I >= NumEltsInput) {
13819 Elements.push_back(
APValue(APFloat::getZero(APFloat::IEEEsingle())));
13828 Elements.push_back(ResultVal);
13833 case X86::BI__builtin_ia32_shufps:
13834 case X86::BI__builtin_ia32_shufps256:
13835 case X86::BI__builtin_ia32_shufps512: {
13839 [](
unsigned DstIdx,
13840 unsigned ShuffleMask) -> std::pair<unsigned, int> {
13841 constexpr unsigned LaneBits = 128u;
13842 unsigned NumElemPerLane = LaneBits / 32;
13843 unsigned NumSelectableElems = NumElemPerLane / 2;
13844 unsigned BitsPerElem = 2;
13845 unsigned IndexMask = (1u << BitsPerElem) - 1;
13846 unsigned MaskBits = 8;
13847 unsigned Lane = DstIdx / NumElemPerLane;
13848 unsigned ElemInLane = DstIdx % NumElemPerLane;
13849 unsigned LaneOffset = Lane * NumElemPerLane;
13850 unsigned BitIndex = (DstIdx * BitsPerElem) % MaskBits;
13851 unsigned SrcIdx = (ElemInLane < NumSelectableElems) ? 0 : 1;
13852 unsigned Index = (ShuffleMask >> BitIndex) & IndexMask;
13853 return {SrcIdx,
static_cast<int>(LaneOffset + Index)};
13858 case X86::BI__builtin_ia32_shufpd:
13859 case X86::BI__builtin_ia32_shufpd256:
13860 case X86::BI__builtin_ia32_shufpd512: {
13864 [](
unsigned DstIdx,
13865 unsigned ShuffleMask) -> std::pair<unsigned, int> {
13866 constexpr unsigned LaneBits = 128u;
13867 unsigned NumElemPerLane = LaneBits / 64;
13868 unsigned NumSelectableElems = NumElemPerLane / 2;
13869 unsigned BitsPerElem = 1;
13870 unsigned IndexMask = (1u << BitsPerElem) - 1;
13871 unsigned MaskBits = 8;
13872 unsigned Lane = DstIdx / NumElemPerLane;
13873 unsigned ElemInLane = DstIdx % NumElemPerLane;
13874 unsigned LaneOffset = Lane * NumElemPerLane;
13875 unsigned BitIndex = (DstIdx * BitsPerElem) % MaskBits;
13876 unsigned SrcIdx = (ElemInLane < NumSelectableElems) ? 0 : 1;
13877 unsigned Index = (ShuffleMask >> BitIndex) & IndexMask;
13878 return {SrcIdx,
static_cast<int>(LaneOffset + Index)};
13883 case X86::BI__builtin_ia32_insertps128: {
13887 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13889 if ((Mask & (1 << DstIdx)) != 0) {
13894 unsigned SrcElem = (Mask >> 6) & 0x3;
13895 unsigned DstElem = (Mask >> 4) & 0x3;
13896 if (DstIdx == DstElem) {
13898 return {1,
static_cast<int>(SrcElem)};
13901 return {0,
static_cast<int>(DstIdx)};
13907 case X86::BI__builtin_ia32_pshufb128:
13908 case X86::BI__builtin_ia32_pshufb256:
13909 case X86::BI__builtin_ia32_pshufb512: {
13913 [](
unsigned DstIdx,
13914 unsigned ShuffleMask) -> std::pair<unsigned, int> {
13917 return std::make_pair(0, -1);
13919 unsigned LaneBase = (DstIdx / 16) * 16;
13920 unsigned SrcOffset = Ctlb & 0x0F;
13921 unsigned SrcIdx = LaneBase + SrcOffset;
13922 return std::make_pair(0,
static_cast<int>(SrcIdx));
13928 case X86::BI__builtin_ia32_pshuflw:
13929 case X86::BI__builtin_ia32_pshuflw256:
13930 case X86::BI__builtin_ia32_pshuflw512: {
13934 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13935 constexpr unsigned LaneBits = 128u;
13936 constexpr unsigned ElemBits = 16u;
13937 constexpr unsigned LaneElts = LaneBits / ElemBits;
13938 constexpr unsigned HalfSize = 4;
13939 unsigned LaneBase = (DstIdx / LaneElts) * LaneElts;
13940 unsigned LaneIdx = DstIdx % LaneElts;
13941 if (LaneIdx < HalfSize) {
13942 unsigned Sel = (Mask >> (2 * LaneIdx)) & 0x3;
13943 return std::make_pair(0,
static_cast<int>(LaneBase + Sel));
13945 return std::make_pair(0,
static_cast<int>(DstIdx));
13951 case X86::BI__builtin_ia32_pshufhw:
13952 case X86::BI__builtin_ia32_pshufhw256:
13953 case X86::BI__builtin_ia32_pshufhw512: {
13957 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13958 constexpr unsigned LaneBits = 128u;
13959 constexpr unsigned ElemBits = 16u;
13960 constexpr unsigned LaneElts = LaneBits / ElemBits;
13961 constexpr unsigned HalfSize = 4;
13962 unsigned LaneBase = (DstIdx / LaneElts) * LaneElts;
13963 unsigned LaneIdx = DstIdx % LaneElts;
13964 if (LaneIdx >= HalfSize) {
13965 unsigned Rel = LaneIdx - HalfSize;
13966 unsigned Sel = (Mask >> (2 * Rel)) & 0x3;
13967 return std::make_pair(
13968 0,
static_cast<int>(LaneBase + HalfSize + Sel));
13970 return std::make_pair(0,
static_cast<int>(DstIdx));
13976 case X86::BI__builtin_ia32_pshufd:
13977 case X86::BI__builtin_ia32_pshufd256:
13978 case X86::BI__builtin_ia32_pshufd512:
13979 case X86::BI__builtin_ia32_vpermilps:
13980 case X86::BI__builtin_ia32_vpermilps256:
13981 case X86::BI__builtin_ia32_vpermilps512: {
13985 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13986 constexpr unsigned LaneBits = 128u;
13987 constexpr unsigned ElemBits = 32u;
13988 constexpr unsigned LaneElts = LaneBits / ElemBits;
13989 unsigned LaneBase = (DstIdx / LaneElts) * LaneElts;
13990 unsigned LaneIdx = DstIdx % LaneElts;
13991 unsigned Sel = (Mask >> (2 * LaneIdx)) & 0x3;
13992 return std::make_pair(0,
static_cast<int>(LaneBase + Sel));
13998 case X86::BI__builtin_ia32_vpermilvarpd:
13999 case X86::BI__builtin_ia32_vpermilvarpd256:
14000 case X86::BI__builtin_ia32_vpermilvarpd512: {
14004 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
14005 unsigned NumElemPerLane = 2;
14006 unsigned Lane = DstIdx / NumElemPerLane;
14007 unsigned Offset = Mask & 0b10 ? 1 : 0;
14008 return std::make_pair(
14009 0,
static_cast<int>(Lane * NumElemPerLane + Offset));
14015 case X86::BI__builtin_ia32_vpermilpd:
14016 case X86::BI__builtin_ia32_vpermilpd256:
14017 case X86::BI__builtin_ia32_vpermilpd512: {
14020 unsigned NumElemPerLane = 2;
14021 unsigned BitsPerElem = 1;
14022 unsigned MaskBits = 8;
14023 unsigned IndexMask = 0x1;
14024 unsigned Lane = DstIdx / NumElemPerLane;
14025 unsigned LaneOffset = Lane * NumElemPerLane;
14026 unsigned BitIndex = (DstIdx * BitsPerElem) % MaskBits;
14027 unsigned Index = (Control >> BitIndex) & IndexMask;
14028 return std::make_pair(0,
static_cast<int>(LaneOffset + Index));
14034 case X86::BI__builtin_ia32_permdf256:
14035 case X86::BI__builtin_ia32_permdi256: {
14040 unsigned Index = (Control >> (2 * DstIdx)) & 0x3;
14041 return std::make_pair(0,
static_cast<int>(Index));
14047 case X86::BI__builtin_ia32_vpermilvarps:
14048 case X86::BI__builtin_ia32_vpermilvarps256:
14049 case X86::BI__builtin_ia32_vpermilvarps512: {
14053 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
14054 unsigned NumElemPerLane = 4;
14055 unsigned Lane = DstIdx / NumElemPerLane;
14056 unsigned Offset = Mask & 0b11;
14057 return std::make_pair(
14058 0,
static_cast<int>(Lane * NumElemPerLane + Offset));
14064 case X86::BI__builtin_ia32_vpmultishiftqb128:
14065 case X86::BI__builtin_ia32_vpmultishiftqb256:
14066 case X86::BI__builtin_ia32_vpmultishiftqb512: {
14074 unsigned NumBytesInQWord = 8;
14075 unsigned NumBitsInByte = 8;
14077 unsigned NumQWords = NumBytes / NumBytesInQWord;
14079 Result.reserve(NumBytes);
14081 for (
unsigned QWordId = 0; QWordId != NumQWords; ++QWordId) {
14082 APInt BQWord(64, 0);
14083 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
14084 unsigned Idx = QWordId * NumBytesInQWord + ByteIdx;
14086 BQWord.insertBits(
APInt(8, Byte & 0xFF), ByteIdx * NumBitsInByte);
14089 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
14090 unsigned Idx = QWordId * NumBytesInQWord + ByteIdx;
14094 for (
unsigned BitIdx = 0; BitIdx != NumBitsInByte; ++BitIdx) {
14095 Byte.setBitVal(BitIdx, BQWord[(Ctrl + BitIdx) & 0x3F]);
14103 case X86::BI__builtin_ia32_phminposuw128: {
14110 unsigned ElemBitWidth = Info.Ctx.getTypeSize(ElemQT);
14112 APInt MinIndex(ElemBitWidth, 0);
14114 for (
unsigned I = 1; I != SourceLen; ++I) {
14116 if (MinVal.ugt(Val)) {
14125 ->isUnsignedIntegerOrEnumerationType();
14128 Result.reserve(SourceLen);
14130 Result.emplace_back(
APSInt(MinIndex, ResultUnsigned));
14131 for (
unsigned I = 0; I != SourceLen - 2; ++I) {
14137 case X86::BI__builtin_ia32_psraq128:
14138 case X86::BI__builtin_ia32_psraq256:
14139 case X86::BI__builtin_ia32_psraq512:
14140 case X86::BI__builtin_ia32_psrad128:
14141 case X86::BI__builtin_ia32_psrad256:
14142 case X86::BI__builtin_ia32_psrad512:
14143 case X86::BI__builtin_ia32_psraw128:
14144 case X86::BI__builtin_ia32_psraw256:
14145 case X86::BI__builtin_ia32_psraw512: {
14149 [](
const APInt &Elt, uint64_t Count) {
return Elt.ashr(Count); },
14150 [](
const APInt &Elt,
unsigned Width) {
14151 return Elt.ashr(Width - 1);
14157 case X86::BI__builtin_ia32_psllq128:
14158 case X86::BI__builtin_ia32_psllq256:
14159 case X86::BI__builtin_ia32_psllq512:
14160 case X86::BI__builtin_ia32_pslld128:
14161 case X86::BI__builtin_ia32_pslld256:
14162 case X86::BI__builtin_ia32_pslld512:
14163 case X86::BI__builtin_ia32_psllw128:
14164 case X86::BI__builtin_ia32_psllw256:
14165 case X86::BI__builtin_ia32_psllw512: {
14169 [](
const APInt &Elt, uint64_t Count) {
return Elt.shl(Count); },
14170 [](
const APInt &Elt,
unsigned Width) {
14171 return APInt::getZero(Width);
14177 case X86::BI__builtin_ia32_psrlq128:
14178 case X86::BI__builtin_ia32_psrlq256:
14179 case X86::BI__builtin_ia32_psrlq512:
14180 case X86::BI__builtin_ia32_psrld128:
14181 case X86::BI__builtin_ia32_psrld256:
14182 case X86::BI__builtin_ia32_psrld512:
14183 case X86::BI__builtin_ia32_psrlw128:
14184 case X86::BI__builtin_ia32_psrlw256:
14185 case X86::BI__builtin_ia32_psrlw512: {
14189 [](
const APInt &Elt, uint64_t Count) {
return Elt.lshr(Count); },
14190 [](
const APInt &Elt,
unsigned Width) {
14191 return APInt::getZero(Width);
14197 case X86::BI__builtin_ia32_pternlogd128_mask:
14198 case X86::BI__builtin_ia32_pternlogd256_mask:
14199 case X86::BI__builtin_ia32_pternlogd512_mask:
14200 case X86::BI__builtin_ia32_pternlogq128_mask:
14201 case X86::BI__builtin_ia32_pternlogq256_mask:
14202 case X86::BI__builtin_ia32_pternlogq512_mask: {
14203 APValue AValue, BValue, CValue, ImmValue, UValue;
14211 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14217 ResultElements.reserve(ResultLen);
14219 for (
unsigned EltNum = 0; EltNum < ResultLen; ++EltNum) {
14225 unsigned BitWidth = ALane.getBitWidth();
14226 APInt ResLane(BitWidth, 0);
14228 for (
unsigned Bit = 0; Bit < BitWidth; ++Bit) {
14229 unsigned ABit = ALane[Bit];
14230 unsigned BBit = BLane[Bit];
14231 unsigned CBit = CLane[Bit];
14233 unsigned Idx = (ABit << 2) | (BBit << 1) | CBit;
14234 ResLane.setBitVal(Bit, Imm[Idx]);
14236 ResultElements.push_back(
APValue(
APSInt(ResLane, DestUnsigned)));
14238 ResultElements.push_back(
APValue(
APSInt(ALane, DestUnsigned)));
14241 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14243 case X86::BI__builtin_ia32_pternlogd128_maskz:
14244 case X86::BI__builtin_ia32_pternlogd256_maskz:
14245 case X86::BI__builtin_ia32_pternlogd512_maskz:
14246 case X86::BI__builtin_ia32_pternlogq128_maskz:
14247 case X86::BI__builtin_ia32_pternlogq256_maskz:
14248 case X86::BI__builtin_ia32_pternlogq512_maskz: {
14249 APValue AValue, BValue, CValue, ImmValue, UValue;
14257 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14263 ResultElements.reserve(ResultLen);
14265 for (
unsigned EltNum = 0; EltNum < ResultLen; ++EltNum) {
14270 unsigned BitWidth = ALane.getBitWidth();
14271 APInt ResLane(BitWidth, 0);
14274 for (
unsigned Bit = 0; Bit < BitWidth; ++Bit) {
14275 unsigned ABit = ALane[Bit];
14276 unsigned BBit = BLane[Bit];
14277 unsigned CBit = CLane[Bit];
14279 unsigned Idx = (ABit << 2) | (BBit << 1) | CBit;
14280 ResLane.setBitVal(Bit, Imm[Idx]);
14283 ResultElements.push_back(
APValue(
APSInt(ResLane, DestUnsigned)));
14285 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14288 case Builtin::BI__builtin_elementwise_clzg:
14289 case Builtin::BI__builtin_elementwise_ctzg: {
14291 std::optional<APValue> Fallback;
14298 Fallback = FallbackTmp;
14301 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14304 ResultElements.reserve(SourceLen);
14306 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
14311 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
14313 Builtin::BI__builtin_elementwise_ctzg);
14316 ResultElements.push_back(Fallback->getVectorElt(EltNum));
14319 switch (BuiltinOp) {
14320 case Builtin::BI__builtin_elementwise_clzg:
14321 ResultElements.push_back(
APValue(
14322 APSInt(
APInt(Info.Ctx.getIntWidth(DestEltTy), LHS.countl_zero()),
14325 case Builtin::BI__builtin_elementwise_ctzg:
14326 ResultElements.push_back(
APValue(
14327 APSInt(
APInt(Info.Ctx.getIntWidth(DestEltTy), LHS.countr_zero()),
14333 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14336 case Builtin::BI__builtin_elementwise_fma: {
14337 APValue SourceX, SourceY, SourceZ;
14345 ResultElements.reserve(SourceLen);
14347 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
14352 (void)
Result.fusedMultiplyAdd(Y, Z, RM);
14355 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14358 case clang::X86::BI__builtin_ia32_phaddw128:
14359 case clang::X86::BI__builtin_ia32_phaddw256:
14360 case clang::X86::BI__builtin_ia32_phaddd128:
14361 case clang::X86::BI__builtin_ia32_phaddd256:
14362 case clang::X86::BI__builtin_ia32_phaddsw128:
14363 case clang::X86::BI__builtin_ia32_phaddsw256:
14365 case clang::X86::BI__builtin_ia32_phsubw128:
14366 case clang::X86::BI__builtin_ia32_phsubw256:
14367 case clang::X86::BI__builtin_ia32_phsubd128:
14368 case clang::X86::BI__builtin_ia32_phsubd256:
14369 case clang::X86::BI__builtin_ia32_phsubsw128:
14370 case clang::X86::BI__builtin_ia32_phsubsw256: {
14371 APValue SourceLHS, SourceRHS;
14375 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14379 unsigned EltBits = Info.Ctx.getIntWidth(DestEltTy);
14380 unsigned EltsPerLane = 128 / EltBits;
14382 ResultElements.reserve(NumElts);
14384 for (
unsigned LaneStart = 0; LaneStart != NumElts;
14385 LaneStart += EltsPerLane) {
14386 for (
unsigned I = 0; I != EltsPerLane; I += 2) {
14389 switch (BuiltinOp) {
14390 case clang::X86::BI__builtin_ia32_phaddw128:
14391 case clang::X86::BI__builtin_ia32_phaddw256:
14392 case clang::X86::BI__builtin_ia32_phaddd128:
14393 case clang::X86::BI__builtin_ia32_phaddd256: {
14394 APSInt Res(LHSA + LHSB, DestUnsigned);
14395 ResultElements.push_back(
APValue(Res));
14398 case clang::X86::BI__builtin_ia32_phaddsw128:
14399 case clang::X86::BI__builtin_ia32_phaddsw256: {
14400 APSInt Res(LHSA.sadd_sat(LHSB));
14401 ResultElements.push_back(
APValue(Res));
14404 case clang::X86::BI__builtin_ia32_phsubw128:
14405 case clang::X86::BI__builtin_ia32_phsubw256:
14406 case clang::X86::BI__builtin_ia32_phsubd128:
14407 case clang::X86::BI__builtin_ia32_phsubd256: {
14408 APSInt Res(LHSA - LHSB, DestUnsigned);
14409 ResultElements.push_back(
APValue(Res));
14412 case clang::X86::BI__builtin_ia32_phsubsw128:
14413 case clang::X86::BI__builtin_ia32_phsubsw256: {
14414 APSInt Res(LHSA.ssub_sat(LHSB));
14415 ResultElements.push_back(
APValue(Res));
14420 for (
unsigned I = 0; I != EltsPerLane; I += 2) {
14423 switch (BuiltinOp) {
14424 case clang::X86::BI__builtin_ia32_phaddw128:
14425 case clang::X86::BI__builtin_ia32_phaddw256:
14426 case clang::X86::BI__builtin_ia32_phaddd128:
14427 case clang::X86::BI__builtin_ia32_phaddd256: {
14428 APSInt Res(RHSA + RHSB, DestUnsigned);
14429 ResultElements.push_back(
APValue(Res));
14432 case clang::X86::BI__builtin_ia32_phaddsw128:
14433 case clang::X86::BI__builtin_ia32_phaddsw256: {
14434 APSInt Res(RHSA.sadd_sat(RHSB));
14435 ResultElements.push_back(
APValue(Res));
14438 case clang::X86::BI__builtin_ia32_phsubw128:
14439 case clang::X86::BI__builtin_ia32_phsubw256:
14440 case clang::X86::BI__builtin_ia32_phsubd128:
14441 case clang::X86::BI__builtin_ia32_phsubd256: {
14442 APSInt Res(RHSA - RHSB, DestUnsigned);
14443 ResultElements.push_back(
APValue(Res));
14446 case clang::X86::BI__builtin_ia32_phsubsw128:
14447 case clang::X86::BI__builtin_ia32_phsubsw256: {
14448 APSInt Res(RHSA.ssub_sat(RHSB));
14449 ResultElements.push_back(
APValue(Res));
14455 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14457 case clang::X86::BI__builtin_ia32_haddpd:
14458 case clang::X86::BI__builtin_ia32_haddps:
14459 case clang::X86::BI__builtin_ia32_haddps256:
14460 case clang::X86::BI__builtin_ia32_haddpd256:
14461 case clang::X86::BI__builtin_ia32_hsubpd:
14462 case clang::X86::BI__builtin_ia32_hsubps:
14463 case clang::X86::BI__builtin_ia32_hsubps256:
14464 case clang::X86::BI__builtin_ia32_hsubpd256: {
14465 APValue SourceLHS, SourceRHS;
14471 ResultElements.reserve(NumElts);
14473 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14474 unsigned EltBits = Info.Ctx.getTypeSize(DestEltTy);
14475 unsigned NumLanes = NumElts * EltBits / 128;
14476 unsigned NumElemsPerLane = NumElts / NumLanes;
14477 unsigned HalfElemsPerLane = NumElemsPerLane / 2;
14479 for (
unsigned L = 0; L != NumElts; L += NumElemsPerLane) {
14480 for (
unsigned I = 0; I != HalfElemsPerLane; ++I) {
14483 switch (BuiltinOp) {
14484 case clang::X86::BI__builtin_ia32_haddpd:
14485 case clang::X86::BI__builtin_ia32_haddps:
14486 case clang::X86::BI__builtin_ia32_haddps256:
14487 case clang::X86::BI__builtin_ia32_haddpd256:
14488 LHSA.add(LHSB, RM);
14490 case clang::X86::BI__builtin_ia32_hsubpd:
14491 case clang::X86::BI__builtin_ia32_hsubps:
14492 case clang::X86::BI__builtin_ia32_hsubps256:
14493 case clang::X86::BI__builtin_ia32_hsubpd256:
14494 LHSA.subtract(LHSB, RM);
14497 ResultElements.push_back(
APValue(LHSA));
14499 for (
unsigned I = 0; I != HalfElemsPerLane; ++I) {
14502 switch (BuiltinOp) {
14503 case clang::X86::BI__builtin_ia32_haddpd:
14504 case clang::X86::BI__builtin_ia32_haddps:
14505 case clang::X86::BI__builtin_ia32_haddps256:
14506 case clang::X86::BI__builtin_ia32_haddpd256:
14507 RHSA.add(RHSB, RM);
14509 case clang::X86::BI__builtin_ia32_hsubpd:
14510 case clang::X86::BI__builtin_ia32_hsubps:
14511 case clang::X86::BI__builtin_ia32_hsubps256:
14512 case clang::X86::BI__builtin_ia32_hsubpd256:
14513 RHSA.subtract(RHSB, RM);
14516 ResultElements.push_back(
APValue(RHSA));
14519 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14521 case clang::X86::BI__builtin_ia32_addsubpd:
14522 case clang::X86::BI__builtin_ia32_addsubps:
14523 case clang::X86::BI__builtin_ia32_addsubpd256:
14524 case clang::X86::BI__builtin_ia32_addsubps256: {
14527 APValue SourceLHS, SourceRHS;
14533 ResultElements.reserve(NumElems);
14536 for (
unsigned I = 0; I != NumElems; ++I) {
14541 LHS.subtract(RHS, RM);
14546 ResultElements.push_back(
APValue(LHS));
14548 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14550 case clang::X86::BI__builtin_ia32_pclmulqdq128:
14551 case clang::X86::BI__builtin_ia32_pclmulqdq256:
14552 case clang::X86::BI__builtin_ia32_pclmulqdq512: {
14556 APValue SourceLHS, SourceRHS;
14566 bool SelectUpperA = (Imm8 & 0x01) != 0;
14567 bool SelectUpperB = (Imm8 & 0x10) != 0;
14571 ResultElements.reserve(NumElems);
14572 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14576 for (
unsigned Lane = 0; Lane < NumElems; Lane += 2) {
14585 APInt A = SelectUpperA ? A1 : A0;
14586 APInt B = SelectUpperB ? B1 : B0;
14589 APInt A128 = A.zext(128);
14590 APInt B128 = B.zext(128);
14593 APInt Result = llvm::APIntOps::clmul(A128, B128);
14596 APSInt ResultLow(
Result.extractBits(64, 0), DestUnsigned);
14597 APSInt ResultHigh(
Result.extractBits(64, 64), DestUnsigned);
14599 ResultElements.push_back(
APValue(ResultLow));
14600 ResultElements.push_back(
APValue(ResultHigh));
14603 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14605 case Builtin::BI__builtin_elementwise_clmul:
14606 return EvaluateBinOpExpr(llvm::APIntOps::clmul);
14607 case Builtin::BI__builtin_elementwise_pext:
14608 return EvaluateBinOpExpr(llvm::APIntOps::pext);
14609 case Builtin::BI__builtin_elementwise_pdep:
14610 return EvaluateBinOpExpr(llvm::APIntOps::pdep);
14611 case Builtin::BI__builtin_elementwise_fshl:
14612 case Builtin::BI__builtin_elementwise_fshr: {
14613 APValue SourceHi, SourceLo, SourceShift;
14619 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14625 ResultElements.reserve(SourceLen);
14626 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
14630 switch (BuiltinOp) {
14631 case Builtin::BI__builtin_elementwise_fshl:
14632 ResultElements.push_back(
APValue(
14633 APSInt(llvm::APIntOps::fshl(Hi, Lo, Shift), Hi.isUnsigned())));
14635 case Builtin::BI__builtin_elementwise_fshr:
14636 ResultElements.push_back(
APValue(
14637 APSInt(llvm::APIntOps::fshr(Hi, Lo, Shift), Hi.isUnsigned())));
14642 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14645 case X86::BI__builtin_ia32_shuf_f32x4_256:
14646 case X86::BI__builtin_ia32_shuf_i32x4_256:
14647 case X86::BI__builtin_ia32_shuf_f64x2_256:
14648 case X86::BI__builtin_ia32_shuf_i64x2_256:
14649 case X86::BI__builtin_ia32_shuf_f32x4:
14650 case X86::BI__builtin_ia32_shuf_i32x4:
14651 case X86::BI__builtin_ia32_shuf_f64x2:
14652 case X86::BI__builtin_ia32_shuf_i64x2: {
14666 unsigned ElemBits = Info.Ctx.getTypeSize(ElemQT);
14667 unsigned LaneBits = 128u;
14668 unsigned NumLanes = (NumElems * ElemBits) / LaneBits;
14669 unsigned NumElemsPerLane = LaneBits / ElemBits;
14673 ResultElements.reserve(DstLen);
14678 [NumLanes, NumElemsPerLane](
unsigned DstIdx,
unsigned ShuffleMask)
14679 -> std::pair<unsigned, int> {
14681 unsigned BitsPerElem = NumLanes / 2;
14682 unsigned IndexMask = (1u << BitsPerElem) - 1;
14683 unsigned Lane = DstIdx / NumElemsPerLane;
14684 unsigned SrcIdx = (Lane < NumLanes / 2) ? 0 : 1;
14685 unsigned BitIdx = BitsPerElem * Lane;
14686 unsigned SrcLaneIdx = (ShuffleMask >> BitIdx) & IndexMask;
14687 unsigned ElemInLane = DstIdx % NumElemsPerLane;
14688 unsigned IdxToPick = SrcLaneIdx * NumElemsPerLane + ElemInLane;
14689 return {SrcIdx, IdxToPick};
14695 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v16qi:
14696 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v32qi:
14697 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v64qi:
14698 case X86::BI__builtin_ia32_vgf2p8affineqb_v16qi:
14699 case X86::BI__builtin_ia32_vgf2p8affineqb_v32qi:
14700 case X86::BI__builtin_ia32_vgf2p8affineqb_v64qi: {
14712 bool IsInverse =
false;
14713 switch (BuiltinOp) {
14714 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v16qi:
14715 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v32qi:
14716 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v64qi: {
14721 unsigned NumBitsInByte = 8;
14722 unsigned NumBytesInQWord = 8;
14723 unsigned NumBitsInQWord = 64;
14725 unsigned NumQWords = NumBytes / NumBytesInQWord;
14727 Result.reserve(NumBytes);
14730 for (
unsigned QWordIdx = 0; QWordIdx != NumQWords; ++QWordIdx) {
14732 APInt XQWord(NumBitsInQWord, 0);
14733 APInt AQWord(NumBitsInQWord, 0);
14734 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
14735 unsigned Idx = QWordIdx * NumBytesInQWord + ByteIdx;
14736 APInt XByte =
X.getVectorElt(Idx).getInt();
14738 XQWord.insertBits(XByte, ByteIdx * NumBitsInByte);
14739 AQWord.insertBits(AByte, ByteIdx * NumBitsInByte);
14742 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
14744 XQWord.lshr(ByteIdx * NumBitsInByte).getLoBits(8).getZExtValue();
14753 case X86::BI__builtin_ia32_vgf2p8mulb_v16qi:
14754 case X86::BI__builtin_ia32_vgf2p8mulb_v32qi:
14755 case X86::BI__builtin_ia32_vgf2p8mulb_v64qi: {
14766 Result.reserve(NumBytes);
14768 for (
unsigned ByteIdx = 0; ByteIdx != NumBytes; ++ByteIdx) {
14778 case X86::BI__builtin_ia32_insertf32x4_256:
14779 case X86::BI__builtin_ia32_inserti32x4_256:
14780 case X86::BI__builtin_ia32_insertf64x2_256:
14781 case X86::BI__builtin_ia32_inserti64x2_256:
14782 case X86::BI__builtin_ia32_insertf32x4:
14783 case X86::BI__builtin_ia32_inserti32x4:
14784 case X86::BI__builtin_ia32_insertf64x2_512:
14785 case X86::BI__builtin_ia32_inserti64x2_512:
14786 case X86::BI__builtin_ia32_insertf32x8:
14787 case X86::BI__builtin_ia32_inserti32x8:
14788 case X86::BI__builtin_ia32_insertf64x4:
14789 case X86::BI__builtin_ia32_inserti64x4:
14790 case X86::BI__builtin_ia32_vinsertf128_ps256:
14791 case X86::BI__builtin_ia32_vinsertf128_pd256:
14792 case X86::BI__builtin_ia32_vinsertf128_si256:
14793 case X86::BI__builtin_ia32_insert128i256: {
14794 APValue SourceDst, SourceSub;
14806 assert(SubLen != 0 && DstLen != 0 && (DstLen % SubLen) == 0);
14807 unsigned NumLanes = DstLen / SubLen;
14808 unsigned LaneIdx = (Imm.getZExtValue() % NumLanes) * SubLen;
14811 ResultElements.reserve(DstLen);
14813 for (
unsigned EltNum = 0; EltNum < DstLen; ++EltNum) {
14814 if (EltNum >= LaneIdx && EltNum < LaneIdx + SubLen)
14815 ResultElements.push_back(SourceSub.
getVectorElt(EltNum - LaneIdx));
14817 ResultElements.push_back(SourceDst.
getVectorElt(EltNum));
14820 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14823 case clang::X86::BI__builtin_ia32_vec_set_v4hi:
14824 case clang::X86::BI__builtin_ia32_vec_set_v16qi:
14825 case clang::X86::BI__builtin_ia32_vec_set_v8hi:
14826 case clang::X86::BI__builtin_ia32_vec_set_v4si:
14827 case clang::X86::BI__builtin_ia32_vec_set_v2di:
14828 case clang::X86::BI__builtin_ia32_vec_set_v32qi:
14829 case clang::X86::BI__builtin_ia32_vec_set_v16hi:
14830 case clang::X86::BI__builtin_ia32_vec_set_v8si:
14831 case clang::X86::BI__builtin_ia32_vec_set_v4di: {
14839 QualType ElemTy = E->
getType()->
castAs<VectorType>()->getElementType();
14840 unsigned ElemWidth = Info.Ctx.getIntWidth(ElemTy);
14842 Scalar.setIsUnsigned(ElemUnsigned);
14848 static_cast<unsigned>(IndexAPS.getZExtValue() & (NumElems - 1));
14851 Elems.reserve(NumElems);
14852 for (
unsigned ElemNum = 0; ElemNum != NumElems; ++ElemNum)
14853 Elems.push_back(ElemNum == Index ? ElemAV : VecVal.
getVectorElt(ElemNum));
14858 case X86::BI__builtin_ia32_pslldqi128_byteshift:
14859 case X86::BI__builtin_ia32_pslldqi256_byteshift:
14860 case X86::BI__builtin_ia32_pslldqi512_byteshift: {
14864 [](
unsigned DstIdx,
unsigned Shift) -> std::pair<unsigned, int> {
14865 unsigned LaneBase = (DstIdx / 16) * 16;
14866 unsigned LaneIdx = DstIdx % 16;
14867 if (LaneIdx < Shift)
14868 return std::make_pair(0, -1);
14870 return std::make_pair(
14871 0,
static_cast<int>(LaneBase + LaneIdx - Shift));
14877 case X86::BI__builtin_ia32_psrldqi128_byteshift:
14878 case X86::BI__builtin_ia32_psrldqi256_byteshift:
14879 case X86::BI__builtin_ia32_psrldqi512_byteshift: {
14883 [](
unsigned DstIdx,
unsigned Shift) -> std::pair<unsigned, int> {
14884 unsigned LaneBase = (DstIdx / 16) * 16;
14885 unsigned LaneIdx = DstIdx % 16;
14886 if (LaneIdx + Shift < 16)
14887 return std::make_pair(
14888 0,
static_cast<int>(LaneBase + LaneIdx + Shift));
14890 return std::make_pair(0, -1);
14896 case X86::BI__builtin_ia32_palignr128:
14897 case X86::BI__builtin_ia32_palignr256:
14898 case X86::BI__builtin_ia32_palignr512: {
14902 unsigned VecIdx = 1;
14905 int Lane = DstIdx / 16;
14906 int Offset = DstIdx % 16;
14909 unsigned ShiftedIdx = Offset + (
Shift & 0xFF);
14910 if (ShiftedIdx < 16) {
14911 ElemIdx = ShiftedIdx + (Lane * 16);
14912 }
else if (ShiftedIdx < 32) {
14914 ElemIdx = (ShiftedIdx - 16) + (Lane * 16);
14917 return std::pair<unsigned, int>{VecIdx, ElemIdx};
14922 case X86::BI__builtin_ia32_alignd128:
14923 case X86::BI__builtin_ia32_alignd256:
14924 case X86::BI__builtin_ia32_alignd512:
14925 case X86::BI__builtin_ia32_alignq128:
14926 case X86::BI__builtin_ia32_alignq256:
14927 case X86::BI__builtin_ia32_alignq512: {
14929 unsigned NumElems = E->
getType()->
castAs<VectorType>()->getNumElements();
14931 [NumElems](
unsigned DstIdx,
unsigned Shift) {
14932 unsigned Imm =
Shift & 0xFF;
14933 unsigned EffectiveShift = Imm & (NumElems - 1);
14934 unsigned SourcePos = DstIdx + EffectiveShift;
14935 unsigned VecIdx = SourcePos < NumElems ? 1 : 0;
14936 unsigned ElemIdx = SourcePos & (NumElems - 1);
14938 return std::pair<unsigned, int>{
14939 VecIdx,
static_cast<int>(ElemIdx)};
14944 case X86::BI__builtin_ia32_permvarsi256:
14945 case X86::BI__builtin_ia32_permvarsf256:
14946 case X86::BI__builtin_ia32_permvardf512:
14947 case X86::BI__builtin_ia32_permvardi512:
14948 case X86::BI__builtin_ia32_permvarhi128: {
14951 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14952 int Offset = ShuffleMask & 0x7;
14953 return std::pair<unsigned, int>{0, Offset};
14958 case X86::BI__builtin_ia32_permvarqi128:
14959 case X86::BI__builtin_ia32_permvarhi256:
14960 case X86::BI__builtin_ia32_permvarsi512:
14961 case X86::BI__builtin_ia32_permvarsf512: {
14964 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14965 int Offset = ShuffleMask & 0xF;
14966 return std::pair<unsigned, int>{0, Offset};
14971 case X86::BI__builtin_ia32_permvardi256:
14972 case X86::BI__builtin_ia32_permvardf256: {
14975 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14976 int Offset = ShuffleMask & 0x3;
14977 return std::pair<unsigned, int>{0, Offset};
14982 case X86::BI__builtin_ia32_permvarqi256:
14983 case X86::BI__builtin_ia32_permvarhi512: {
14986 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14987 int Offset = ShuffleMask & 0x1F;
14988 return std::pair<unsigned, int>{0, Offset};
14993 case X86::BI__builtin_ia32_permvarqi512: {
14996 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14997 int Offset = ShuffleMask & 0x3F;
14998 return std::pair<unsigned, int>{0, Offset};
15003 case X86::BI__builtin_ia32_vpermi2varq128:
15004 case X86::BI__builtin_ia32_vpermi2varpd128: {
15007 [](
unsigned DstIdx,
unsigned ShuffleMask) {
15008 int Offset = ShuffleMask & 0x1;
15009 unsigned SrcIdx = (ShuffleMask >> 1) & 0x1;
15010 return std::pair<unsigned, int>{SrcIdx, Offset};
15015 case X86::BI__builtin_ia32_vpermi2vard128:
15016 case X86::BI__builtin_ia32_vpermi2varps128:
15017 case X86::BI__builtin_ia32_vpermi2varq256:
15018 case X86::BI__builtin_ia32_vpermi2varpd256: {
15021 [](
unsigned DstIdx,
unsigned ShuffleMask) {
15022 int Offset = ShuffleMask & 0x3;
15023 unsigned SrcIdx = (ShuffleMask >> 2) & 0x1;
15024 return std::pair<unsigned, int>{SrcIdx, Offset};
15029 case X86::BI__builtin_ia32_vpermi2varhi128:
15030 case X86::BI__builtin_ia32_vpermi2vard256:
15031 case X86::BI__builtin_ia32_vpermi2varps256:
15032 case X86::BI__builtin_ia32_vpermi2varq512:
15033 case X86::BI__builtin_ia32_vpermi2varpd512: {
15036 [](
unsigned DstIdx,
unsigned ShuffleMask) {
15037 int Offset = ShuffleMask & 0x7;
15038 unsigned SrcIdx = (ShuffleMask >> 3) & 0x1;
15039 return std::pair<unsigned, int>{SrcIdx, Offset};
15044 case X86::BI__builtin_ia32_vpermi2varqi128:
15045 case X86::BI__builtin_ia32_vpermi2varhi256:
15046 case X86::BI__builtin_ia32_vpermi2vard512:
15047 case X86::BI__builtin_ia32_vpermi2varps512: {
15050 [](
unsigned DstIdx,
unsigned ShuffleMask) {
15051 int Offset = ShuffleMask & 0xF;
15052 unsigned SrcIdx = (ShuffleMask >> 4) & 0x1;
15053 return std::pair<unsigned, int>{SrcIdx, Offset};
15058 case X86::BI__builtin_ia32_vpermi2varqi256:
15059 case X86::BI__builtin_ia32_vpermi2varhi512: {
15062 [](
unsigned DstIdx,
unsigned ShuffleMask) {
15063 int Offset = ShuffleMask & 0x1F;
15064 unsigned SrcIdx = (ShuffleMask >> 5) & 0x1;
15065 return std::pair<unsigned, int>{SrcIdx, Offset};
15070 case X86::BI__builtin_ia32_vpermi2varqi512: {
15073 [](
unsigned DstIdx,
unsigned ShuffleMask) {
15074 int Offset = ShuffleMask & 0x3F;
15075 unsigned SrcIdx = (ShuffleMask >> 6) & 0x1;
15076 return std::pair<unsigned, int>{SrcIdx, Offset};
15082 case clang::X86::BI__builtin_ia32_minps:
15083 case clang::X86::BI__builtin_ia32_minpd:
15084 case clang::X86::BI__builtin_ia32_minps256:
15085 case clang::X86::BI__builtin_ia32_minpd256:
15086 case clang::X86::BI__builtin_ia32_minps512:
15087 case clang::X86::BI__builtin_ia32_minpd512:
15088 case clang::X86::BI__builtin_ia32_minph128:
15089 case clang::X86::BI__builtin_ia32_minph256:
15090 case clang::X86::BI__builtin_ia32_minph512:
15091 return EvaluateFpBinOpExpr(
15092 [](
const APFloat &A,
const APFloat &B,
15093 std::optional<APSInt>) -> std::optional<APFloat> {
15094 if (A.isNaN() || A.isInfinity() || A.isDenormal() || B.isNaN() ||
15095 B.isInfinity() || B.isDenormal())
15096 return std::nullopt;
15097 if (A.isZero() && B.isZero())
15099 return llvm::minimum(A, B);
15102 case clang::X86::BI__builtin_ia32_minss:
15103 case clang::X86::BI__builtin_ia32_minsd:
15104 return EvaluateFpBinOpExpr(
15105 [](
const APFloat &A,
const APFloat &B,
15106 std::optional<APSInt> RoundingMode) -> std::optional<APFloat> {
15111 case clang::X86::BI__builtin_ia32_minsd_round_mask:
15112 case clang::X86::BI__builtin_ia32_minss_round_mask:
15113 case clang::X86::BI__builtin_ia32_minsh_round_mask:
15114 case clang::X86::BI__builtin_ia32_maxsd_round_mask:
15115 case clang::X86::BI__builtin_ia32_maxss_round_mask:
15116 case clang::X86::BI__builtin_ia32_maxsh_round_mask: {
15117 bool IsMin = BuiltinOp == clang::X86::BI__builtin_ia32_minsd_round_mask ||
15118 BuiltinOp == clang::X86::BI__builtin_ia32_minss_round_mask ||
15119 BuiltinOp == clang::X86::BI__builtin_ia32_minsh_round_mask;
15120 return EvaluateScalarFpRoundMaskBinOp(
15121 [IsMin](
const APFloat &A,
const APFloat &B,
15122 std::optional<APSInt> RoundingMode) -> std::optional<APFloat> {
15127 case clang::X86::BI__builtin_ia32_maxps:
15128 case clang::X86::BI__builtin_ia32_maxpd:
15129 case clang::X86::BI__builtin_ia32_maxps256:
15130 case clang::X86::BI__builtin_ia32_maxpd256:
15131 case clang::X86::BI__builtin_ia32_maxps512:
15132 case clang::X86::BI__builtin_ia32_maxpd512:
15133 case clang::X86::BI__builtin_ia32_maxph128:
15134 case clang::X86::BI__builtin_ia32_maxph256:
15135 case clang::X86::BI__builtin_ia32_maxph512:
15136 return EvaluateFpBinOpExpr(
15137 [](
const APFloat &A,
const APFloat &B,
15138 std::optional<APSInt>) -> std::optional<APFloat> {
15139 if (A.isNaN() || A.isInfinity() || A.isDenormal() || B.isNaN() ||
15140 B.isInfinity() || B.isDenormal())
15141 return std::nullopt;
15142 if (A.isZero() && B.isZero())
15144 return llvm::maximum(A, B);
15147 case clang::X86::BI__builtin_ia32_maxss:
15148 case clang::X86::BI__builtin_ia32_maxsd:
15149 return EvaluateFpBinOpExpr(
15150 [](
const APFloat &A,
const APFloat &B,
15151 std::optional<APSInt> RoundingMode) -> std::optional<APFloat> {
15156 case clang::X86::BI__builtin_ia32_vcvtps2ph:
15157 case clang::X86::BI__builtin_ia32_vcvtps2ph256: {
15167 unsigned SrcNumElems = SrcVTy->getNumElements();
15169 unsigned DstNumElems = DstVTy->getNumElements();
15170 QualType DstElemTy = DstVTy->getElementType();
15172 const llvm::fltSemantics &HalfSem =
15173 Info.Ctx.getFloatTypeSemantics(Info.Ctx.HalfTy);
15175 int ImmVal = Imm.getZExtValue();
15176 bool UseMXCSR = (ImmVal & 4) != 0;
15177 bool IsFPConstrained =
15180 llvm::RoundingMode RM;
15182 switch (ImmVal & 3) {
15184 RM = llvm::RoundingMode::NearestTiesToEven;
15187 RM = llvm::RoundingMode::TowardNegative;
15190 RM = llvm::RoundingMode::TowardPositive;
15193 RM = llvm::RoundingMode::TowardZero;
15196 llvm_unreachable(
"Invalid immediate rounding mode");
15199 RM = llvm::RoundingMode::NearestTiesToEven;
15203 ResultElements.reserve(DstNumElems);
15205 for (
unsigned I = 0; I < SrcNumElems; ++I) {
15209 APFloat::opStatus St = SrcVal.convert(HalfSem, RM, &LostInfo);
15211 if (UseMXCSR && IsFPConstrained && St != APFloat::opOK) {
15212 Info.FFDiag(E, diag::note_constexpr_dynamic_rounding);
15216 APSInt DstInt(SrcVal.bitcastToAPInt(),
15218 ResultElements.push_back(
APValue(DstInt));
15221 if (DstNumElems > SrcNumElems) {
15222 APSInt Zero = Info.Ctx.MakeIntValue(0, DstElemTy);
15223 for (
unsigned I = SrcNumElems; I < DstNumElems; ++I) {
15228 return Success(ResultElements, E);
15230 case X86::BI__builtin_ia32_vperm2f128_pd256:
15231 case X86::BI__builtin_ia32_vperm2f128_ps256:
15232 case X86::BI__builtin_ia32_vperm2f128_si256:
15233 case X86::BI__builtin_ia32_permti256: {
15234 unsigned NumElements =
15236 unsigned PreservedBitsCnt = NumElements >> 2;
15240 [PreservedBitsCnt](
unsigned DstIdx,
unsigned ShuffleMask) {
15241 unsigned ControlBitsCnt = DstIdx >> PreservedBitsCnt << 2;
15242 unsigned ControlBits = ShuffleMask >> ControlBitsCnt;
15244 if (ControlBits & 0b1000)
15245 return std::make_pair(0u, -1);
15247 unsigned SrcVecIdx = (ControlBits & 0b10) >> 1;
15248 unsigned PreservedBitsMask = (1 << PreservedBitsCnt) - 1;
15249 int SrcIdx = ((ControlBits & 0b1) << PreservedBitsCnt) |
15250 (DstIdx & PreservedBitsMask);
15251 return std::make_pair(SrcVecIdx, SrcIdx);
15256 case X86::BI__builtin_ia32_vpdpwssd128:
15257 case X86::BI__builtin_ia32_vpdpwssd256:
15258 case X86::BI__builtin_ia32_vpdpwssd512:
15259 case X86::BI__builtin_ia32_vpdpbusd128:
15260 case X86::BI__builtin_ia32_vpdpbusd256:
15261 case X86::BI__builtin_ia32_vpdpbusd512:
15262 return EvalVectorDotProduct(
false);
15263 case X86::BI__builtin_ia32_vpdpwssds128:
15264 case X86::BI__builtin_ia32_vpdpwssds256:
15265 case X86::BI__builtin_ia32_vpdpwssds512:
15266 case X86::BI__builtin_ia32_vpdpbusds128:
15267 case X86::BI__builtin_ia32_vpdpbusds256:
15268 case X86::BI__builtin_ia32_vpdpbusds512:
15269 return EvalVectorDotProduct(
true);
15270 case X86::BI__builtin_ia32_cvtpd2dq:
15271 case X86::BI__builtin_ia32_cvtps2dq:
15272 case X86::BI__builtin_ia32_cvttpd2dq:
15273 case X86::BI__builtin_ia32_cvttps2dq:
15274 case X86::BI__builtin_ia32_cvtpd2dq256:
15275 case X86::BI__builtin_ia32_cvtps2dq256:
15276 case X86::BI__builtin_ia32_cvttpd2dq256:
15277 case X86::BI__builtin_ia32_cvttps2dq256: {
15284 bool isUnsigned = EltTy->isUnsignedIntegerType();
15285 unsigned BitWidth = Info.Ctx.getIntWidth(EltTy);
15291 for (
unsigned i = 0; i != NumDstElems; ++i) {
15292 if (i < NumSrcElems) {
15294 llvm::APSInt IntResult(BitWidth,
isUnsigned);
15295 bool IsExact =
false;
15298 FloatElem.convertToInteger(IntResult, llvm::APFloat::rmTowardZero,
15302 ResultElts.push_back(
APValue(IntResult));
15307 return Success(ResultElts, E);
15312bool VectorExprEvaluator::VisitConvertVectorExpr(
const ConvertVectorExpr *E) {
15318 QualType DestTy = E->
getType()->
castAs<VectorType>()->getElementType();
15319 QualType SourceTy = SourceVecType->
castAs<VectorType>()->getElementType();
15325 ResultElements.reserve(SourceLen);
15326 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
15331 ResultElements.push_back(std::move(Elt));
15334 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
15339 APValue const &VecVal2,
unsigned EltNum,
15341 unsigned const TotalElementsInInputVector1 = VecVal1.
getVectorLength();
15342 unsigned const TotalElementsInInputVector2 = VecVal2.
getVectorLength();
15345 int64_t
index = IndexVal.getExtValue();
15352 E, diag::err_shufflevector_minus_one_is_undefined_behavior_constexpr)
15358 index >= TotalElementsInInputVector1 + TotalElementsInInputVector2)
15359 llvm_unreachable(
"Out of bounds shuffle index");
15361 if (
index >= TotalElementsInInputVector1)
15368bool VectorExprEvaluator::VisitShuffleVectorExpr(
const ShuffleVectorExpr *E) {
15373 const Expr *Vec1 = E->
getExpr(0);
15377 const Expr *Vec2 = E->
getExpr(1);
15381 VectorType
const *DestVecTy = E->
getType()->
castAs<VectorType>();
15387 ResultElements.reserve(TotalElementsInOutputVector);
15388 for (
unsigned EltNum = 0; EltNum < TotalElementsInOutputVector; ++EltNum) {
15392 ResultElements.push_back(std::move(Elt));
15395 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
15403class MatrixExprEvaluator :
public ExprEvaluatorBase<MatrixExprEvaluator> {
15410 bool Success(ArrayRef<APValue> M,
const Expr *E) {
15412 assert(M.size() == CMTy->getNumElementsFlattened());
15414 Result =
APValue(M.data(), CMTy->getNumRows(), CMTy->getNumColumns());
15418 assert(M.
isMatrix() &&
"expected matrix");
15423 bool VisitCastExpr(
const CastExpr *E);
15424 bool VisitInitListExpr(
const InitListExpr *E);
15430 "not a matrix prvalue");
15431 return MatrixExprEvaluator(Info,
Result).Visit(E);
15434bool MatrixExprEvaluator::VisitCastExpr(
const CastExpr *E) {
15435 const auto *MT = E->
getType()->
castAs<ConstantMatrixType>();
15436 unsigned NumRows = MT->getNumRows();
15437 unsigned NumCols = MT->getNumColumns();
15438 unsigned NElts = NumRows * NumCols;
15439 QualType EltTy = MT->getElementType();
15443 case CK_HLSLAggregateSplatCast: {
15458 case CK_HLSLElementwiseCast: {
15471 return Success(ResultEls, E);
15474 return ExprEvaluatorBaseTy::VisitCastExpr(E);
15478bool MatrixExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
15479 const auto *MT = E->
getType()->
castAs<ConstantMatrixType>();
15480 QualType EltTy = MT->getElementType();
15482 assert(E->
getNumInits() == MT->getNumElementsFlattened() &&
15483 "Expected number of elements in initializer list to match the number "
15484 "of matrix elements");
15487 Elements.reserve(MT->getNumElementsFlattened());
15492 for (
unsigned I = 0, N = MT->getNumElementsFlattened(); I < N; ++I) {
15493 if (EltTy->isIntegerType()) {
15494 llvm::APSInt IntVal;
15497 Elements.push_back(
APValue(IntVal));
15499 llvm::APFloat FloatVal(0.0);
15502 Elements.push_back(
APValue(FloatVal));
15514 class ArrayExprEvaluator
15515 :
public ExprEvaluatorBase<ArrayExprEvaluator> {
15516 const LValue &
This;
15520 ArrayExprEvaluator(EvalInfo &Info,
const LValue &This,
APValue &
Result)
15524 assert(
V.isArray() &&
"expected array");
15529 bool ZeroInitialization(
const Expr *E) {
15530 const ConstantArrayType *CAT =
15531 Info.Ctx.getAsConstantArrayType(E->
getType());
15545 if (!
Result.hasArrayFiller())
15549 LValue Subobject =
This;
15550 Subobject.addArray(Info, E, CAT);
15555 bool VisitCallExpr(
const CallExpr *E) {
15556 return handleCallExpr(E,
Result, &This);
15558 bool VisitCastExpr(
const CastExpr *E);
15559 bool VisitInitListExpr(
const InitListExpr *E,
15560 QualType AllocType = QualType());
15561 bool VisitArrayInitLoopExpr(
const ArrayInitLoopExpr *E);
15562 bool VisitCXXConstructExpr(
const CXXConstructExpr *E);
15563 bool VisitCXXConstructExpr(
const CXXConstructExpr *E,
15564 const LValue &Subobject,
15566 bool VisitStringLiteral(
const StringLiteral *E,
15567 QualType AllocType = QualType()) {
15571 bool VisitCXXParenListInitExpr(
const CXXParenListInitExpr *E);
15572 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
15573 ArrayRef<Expr *> Args,
15574 const Expr *ArrayFiller,
15575 QualType AllocType = QualType());
15576 bool VisitDesignatedInitUpdateExpr(
const DesignatedInitUpdateExpr *E);
15584 "not an array prvalue");
15585 return ArrayExprEvaluator(Info,
This,
Result).Visit(E);
15593 "not an array prvalue");
15594 return ArrayExprEvaluator(Info,
This,
Result)
15595 .VisitInitListExpr(ILE, AllocType);
15604 "not an array prvalue");
15605 return ArrayExprEvaluator(Info,
This,
Result)
15606 .VisitCXXConstructExpr(CCE,
This, &
Result, AllocType);
15615 if (
const InitListExpr *ILE = dyn_cast<InitListExpr>(FillerExpr)) {
15616 for (
unsigned I = 0, E = ILE->
getNumInits(); I != E; ++I) {
15621 if (ILE->hasArrayFiller() &&
15630bool ArrayExprEvaluator::VisitCastExpr(
const CastExpr *E) {
15635 return ExprEvaluatorBaseTy::VisitCastExpr(E);
15636 case CK_HLSLAggregateSplatCast: {
15656 case CK_HLSLElementwiseCast: {
15673bool ArrayExprEvaluator::VisitInitListExpr(
const InitListExpr *E,
15674 QualType AllocType) {
15675 const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(
15688 return VisitStringLiteral(SL, AllocType);
15693 "transparent array list initialization is not string literal init?");
15699bool ArrayExprEvaluator::VisitCXXParenListOrInitListExpr(
15701 QualType AllocType) {
15702 const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(
15707 unsigned NumEltsToInit = Args.size();
15712 if (NumEltsToInit != NumElts &&
15714 NumEltsToInit = NumElts;
15717 for (
auto *
Init : Args) {
15718 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts()))
15719 NumEltsToInit += EmbedS->getDataElementCount() - 1;
15722 if (NumEltsToInit > NumElts)
15723 NumEltsToInit = NumElts;
15727 if (
Result.hasValue() && NumEltsToInit <
Result.getArrayInitializedElts())
15728 NumEltsToInit =
Result.getArrayInitializedElts();
15731 LLVM_DEBUG(llvm::dbgs() <<
"The number of elements to initialize: "
15732 << NumEltsToInit <<
".\n");
15734 if (!
Result.hasValue()) {
15735 Result =
APValue(APValue::UninitArray(), NumEltsToInit, NumElts);
15736 }
else if (
Result.getArrayInitializedElts() != NumEltsToInit) {
15747 APValue NewResult =
APValue(APValue::UninitArray(), NumEltsToInit, NumElts);
15749 unsigned NumOldElts =
Result.getArrayInitializedElts();
15750 for (
unsigned I = 0; I < NumOldElts; ++I) {
15752 std::move(
Result.getArrayInitializedElt(I));
15755 for (
unsigned I =
Result.getArrayInitializedElts(); I < NumEltsToInit; ++I)
15759 Result = std::move(NewResult);
15762 LValue Subobject =
This;
15763 Subobject.addArray(Info, ExprToVisit, CAT);
15764 auto Eval = [&](
const Expr *
Init,
unsigned ArrayIndex) {
15765 if (
Init->isValueDependent())
15774 Subobject,
Init) ||
15777 if (!Info.noteFailure())
15783 unsigned ArrayIndex = 0;
15786 for (
unsigned Index = 0; Index != NumEltsToInit; ++Index) {
15787 const Expr *
Init = Index < Args.size() ? Args[Index] : ArrayFiller;
15788 if (ArrayIndex >= NumEltsToInit)
15790 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
15791 StringLiteral *SL = EmbedS->getDataStringLiteral();
15792 for (
unsigned I = EmbedS->getStartingElementPos(),
15793 N = EmbedS->getDataElementCount();
15794 I != EmbedS->getStartingElementPos() + N; ++I) {
15800 const FPOptions FPO =
15801 Init->getFPFeaturesInEffect(Info.Ctx.getLangOpts());
15806 Result.getArrayInitializedElt(ArrayIndex) =
APValue(FValue);
15811 if (!Eval(
Init, ArrayIndex))
15817 if (!
Result.hasArrayFiller())
15822 assert(ArrayFiller &&
"no array filler for incomplete init list");
15828bool ArrayExprEvaluator::VisitArrayInitLoopExpr(
const ArrayInitLoopExpr *E) {
15831 !
Evaluate(Info.CurrentCall->createTemporary(
15834 ScopeKind::FullExpression, CommonLV),
15841 Result =
APValue(APValue::UninitArray(), Elements, Elements);
15843 LValue Subobject =
This;
15844 Subobject.addArray(Info, E, CAT);
15847 for (EvalInfo::ArrayInitLoopIndex Index(Info); Index != Elements; ++Index) {
15856 FullExpressionRAII Scope(Info);
15862 if (!Info.noteFailure())
15874bool ArrayExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E) {
15875 return VisitCXXConstructExpr(E, This, &
Result, E->
getType());
15878bool ArrayExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E,
15879 const LValue &Subobject,
15882 bool HadZeroInit =
Value->hasValue();
15884 if (
const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(
Type)) {
15889 HadZeroInit &&
Value->hasArrayFiller() ?
Value->getArrayFiller()
15892 *
Value =
APValue(APValue::UninitArray(), 0, FinalSize);
15893 if (FinalSize == 0)
15899 LValue ArrayElt = Subobject;
15900 ArrayElt.addArray(Info, E, CAT);
15906 for (
const unsigned N : {1u, FinalSize}) {
15907 unsigned OldElts =
Value->getArrayInitializedElts();
15912 APValue NewValue(APValue::UninitArray(), N, FinalSize);
15913 for (
unsigned I = 0; I < OldElts; ++I)
15914 NewValue.getArrayInitializedElt(I).swap(
15915 Value->getArrayInitializedElt(I));
15916 Value->swap(NewValue);
15919 for (
unsigned I = OldElts; I < N; ++I)
15920 Value->getArrayInitializedElt(I) = Filler;
15922 if (HasTrivialConstructor && N == FinalSize && FinalSize != 1) {
15925 APValue &FirstResult =
Value->getArrayInitializedElt(0);
15926 for (
unsigned I = OldElts; I < FinalSize; ++I)
15927 Value->getArrayInitializedElt(I) = FirstResult;
15929 for (
unsigned I = OldElts; I < N; ++I) {
15930 if (!VisitCXXConstructExpr(E, ArrayElt,
15931 &
Value->getArrayInitializedElt(I),
15938 if (Info.EvalStatus.Diag && !Info.EvalStatus.Diag->empty() &&
15939 !Info.keepEvaluatingAfterFailure())
15948 if (!
Type->isRecordType())
15951 return RecordExprEvaluator(Info, Subobject, *
Value)
15952 .VisitCXXConstructExpr(E,
Type);
15955bool ArrayExprEvaluator::VisitCXXParenListInitExpr(
15956 const CXXParenListInitExpr *E) {
15958 "Expression result is not a constant array type");
15960 return VisitCXXParenListOrInitListExpr(E, E->
getInitExprs(),
15964bool ArrayExprEvaluator::VisitDesignatedInitUpdateExpr(
15965 const DesignatedInitUpdateExpr *E) {
15980class IntExprEvaluator
15981 :
public ExprEvaluatorBase<IntExprEvaluator> {
15984 IntExprEvaluator(EvalInfo &info,
APValue &result)
15985 : ExprEvaluatorBaseTy(
info),
Result(result) {}
15989 "Invalid evaluation result.");
15991 "Invalid evaluation result.");
15992 assert(SI.getBitWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
15993 "Invalid evaluation result.");
15997 bool Success(
const llvm::APSInt &SI,
const Expr *E) {
16003 "Invalid evaluation result.");
16004 assert(I.getBitWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
16005 "Invalid evaluation result.");
16007 Result.getInt().setIsUnsigned(
16011 bool Success(
const llvm::APInt &I,
const Expr *E) {
16017 "Invalid evaluation result.");
16025 bool Success(CharUnits Size,
const Expr *E) {
16032 if (
V.isLValue() ||
V.isAddrLabelDiff() ||
V.isIndeterminate() ||
16033 V.allowConstexprUnknown()) {
16040 bool ZeroInitialization(
const Expr *E) {
return Success(0, E); }
16042 friend std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &,
16049 bool VisitIntegerLiteral(
const IntegerLiteral *E) {
16052 bool VisitCharacterLiteral(
const CharacterLiteral *E) {
16056 bool CheckReferencedDecl(
const Expr *E,
const Decl *D);
16057 bool VisitDeclRefExpr(
const DeclRefExpr *E) {
16058 if (CheckReferencedDecl(E, E->
getDecl()))
16061 return ExprEvaluatorBaseTy::VisitDeclRefExpr(E);
16063 bool VisitMemberExpr(
const MemberExpr *E) {
16065 VisitIgnoredBaseExpression(E->
getBase());
16069 return ExprEvaluatorBaseTy::VisitMemberExpr(E);
16072 bool VisitCallExpr(
const CallExpr *E);
16073 bool VisitBuiltinCallExpr(
const CallExpr *E,
unsigned BuiltinOp);
16074 bool VisitBinaryOperator(
const BinaryOperator *E);
16075 bool VisitOffsetOfExpr(
const OffsetOfExpr *E);
16076 bool VisitUnaryOperator(
const UnaryOperator *E);
16078 bool VisitCastExpr(
const CastExpr* E);
16079 bool VisitUnaryExprOrTypeTraitExpr(
const UnaryExprOrTypeTraitExpr *E);
16081 bool VisitCXXBoolLiteralExpr(
const CXXBoolLiteralExpr *E) {
16085 bool VisitObjCBoolLiteralExpr(
const ObjCBoolLiteralExpr *E) {
16089 bool VisitArrayInitIndexExpr(
const ArrayInitIndexExpr *E) {
16090 if (Info.ArrayInitIndex ==
uint64_t(-1)) {
16096 return Success(Info.ArrayInitIndex, E);
16100 bool VisitGNUNullExpr(
const GNUNullExpr *E) {
16101 return ZeroInitialization(E);
16104 bool VisitTypeTraitExpr(
const TypeTraitExpr *E) {
16113 bool VisitArrayTypeTraitExpr(
const ArrayTypeTraitExpr *E) {
16117 bool VisitExpressionTraitExpr(
const ExpressionTraitExpr *E) {
16121 bool VisitOpenACCAsteriskSizeExpr(
const OpenACCAsteriskSizeExpr *E) {
16128 bool VisitUnaryReal(
const UnaryOperator *E);
16129 bool VisitUnaryImag(
const UnaryOperator *E);
16131 bool VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E);
16132 bool VisitSizeOfPackExpr(
const SizeOfPackExpr *E);
16133 bool VisitSourceLocExpr(
const SourceLocExpr *E);
16134 bool VisitConceptSpecializationExpr(
const ConceptSpecializationExpr *E);
16139class FixedPointExprEvaluator
16140 :
public ExprEvaluatorBase<FixedPointExprEvaluator> {
16144 FixedPointExprEvaluator(EvalInfo &info,
APValue &result)
16145 : ExprEvaluatorBaseTy(
info),
Result(result) {}
16147 bool Success(
const llvm::APInt &I,
const Expr *E) {
16149 APFixedPoint(I, Info.Ctx.getFixedPointSemantics(E->
getType())), E);
16154 APFixedPoint(
Value, Info.Ctx.getFixedPointSemantics(E->
getType())), E);
16158 return Success(
V.getFixedPoint(), E);
16161 bool Success(
const APFixedPoint &
V,
const Expr *E) {
16163 assert(
V.getWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
16164 "Invalid evaluation result.");
16169 bool ZeroInitialization(
const Expr *E) {
16177 bool VisitFixedPointLiteral(
const FixedPointLiteral *E) {
16181 bool VisitCastExpr(
const CastExpr *E);
16182 bool VisitUnaryOperator(
const UnaryOperator *E);
16183 bool VisitBinaryOperator(
const BinaryOperator *E);
16199 return IntExprEvaluator(Info,
Result).Visit(E);
16207 if (!Val.
isInt()) {
16210 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
16217bool IntExprEvaluator::VisitSourceLocExpr(
const SourceLocExpr *E) {
16219 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.
getDefaultExpr());
16228 if (!FixedPointExprEvaluator(Info, Val).Visit(E))
16243 auto FXSema = Info.Ctx.getFixedPointSemantics(E->
getType());
16247 Result = APFixedPoint(Val, FXSema);
16258bool IntExprEvaluator::CheckReferencedDecl(
const Expr* E,
const Decl* D) {
16260 if (
const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(D)) {
16262 bool SameSign = (ECD->getInitVal().isSigned()
16264 bool SameWidth = (ECD->getInitVal().
getBitWidth()
16265 == Info.Ctx.getIntWidth(E->
getType()));
16266 if (SameSign && SameWidth)
16267 return Success(ECD->getInitVal(), E);
16271 llvm::APSInt Val = ECD->getInitVal();
16273 Val.setIsSigned(!ECD->getInitVal().isSigned());
16275 Val = Val.extOrTrunc(Info.Ctx.getIntWidth(E->
getType()));
16286 assert(!
T->isDependentType() &&
"unexpected dependent type");
16291#define TYPE(ID, BASE)
16292#define DEPENDENT_TYPE(ID, BASE) case Type::ID:
16293#define NON_CANONICAL_TYPE(ID, BASE) case Type::ID:
16294#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(ID, BASE) case Type::ID:
16295#include "clang/AST/TypeNodes.inc"
16297 case Type::DeducedTemplateSpecialization:
16298 llvm_unreachable(
"unexpected non-canonical or dependent type");
16300 case Type::Builtin:
16302#define BUILTIN_TYPE(ID, SINGLETON_ID)
16303#define SIGNED_TYPE(ID, SINGLETON_ID) \
16304 case BuiltinType::ID: return GCCTypeClass::Integer;
16305#define FLOATING_TYPE(ID, SINGLETON_ID) \
16306 case BuiltinType::ID: return GCCTypeClass::RealFloat;
16307#define PLACEHOLDER_TYPE(ID, SINGLETON_ID) \
16308 case BuiltinType::ID: break;
16309#include "clang/AST/BuiltinTypes.def"
16310 case BuiltinType::Void:
16313 case BuiltinType::Bool:
16316 case BuiltinType::Char_U:
16317 case BuiltinType::UChar:
16318 case BuiltinType::WChar_U:
16319 case BuiltinType::Char8:
16320 case BuiltinType::Char16:
16321 case BuiltinType::Char32:
16322 case BuiltinType::UShort:
16323 case BuiltinType::UInt:
16324 case BuiltinType::ULong:
16325 case BuiltinType::ULongLong:
16326 case BuiltinType::UInt128:
16329 case BuiltinType::UShortAccum:
16330 case BuiltinType::UAccum:
16331 case BuiltinType::ULongAccum:
16332 case BuiltinType::UShortFract:
16333 case BuiltinType::UFract:
16334 case BuiltinType::ULongFract:
16335 case BuiltinType::SatUShortAccum:
16336 case BuiltinType::SatUAccum:
16337 case BuiltinType::SatULongAccum:
16338 case BuiltinType::SatUShortFract:
16339 case BuiltinType::SatUFract:
16340 case BuiltinType::SatULongFract:
16343 case BuiltinType::NullPtr:
16345 case BuiltinType::ObjCId:
16346 case BuiltinType::ObjCClass:
16347 case BuiltinType::ObjCSel:
16348#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
16349 case BuiltinType::Id:
16350#include "clang/Basic/OpenCLImageTypes.def"
16351#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
16352 case BuiltinType::Id:
16353#include "clang/Basic/OpenCLExtensionTypes.def"
16354 case BuiltinType::OCLSampler:
16355 case BuiltinType::OCLEvent:
16356 case BuiltinType::OCLClkEvent:
16357 case BuiltinType::OCLQueue:
16358 case BuiltinType::OCLReserveID:
16359#define SVE_TYPE(Name, Id, SingletonId) \
16360 case BuiltinType::Id:
16361#include "clang/Basic/AArch64ACLETypes.def"
16362#define PPC_VECTOR_TYPE(Name, Id, Size) \
16363 case BuiltinType::Id:
16364#include "clang/Basic/PPCTypes.def"
16365#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
16366#include "clang/Basic/RISCVVTypes.def"
16367#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
16368#include "clang/Basic/WebAssemblyReferenceTypes.def"
16369#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
16370#include "clang/Basic/AMDGPUTypes.def"
16371#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
16372#include "clang/Basic/HLSLIntangibleTypes.def"
16373#define SPIRV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
16374#include "clang/Basic/SPIRVTypes.def"
16377 case BuiltinType::Dependent:
16378 llvm_unreachable(
"unexpected dependent type");
16380 llvm_unreachable(
"unexpected placeholder type");
16385 case Type::Pointer:
16386 case Type::ConstantArray:
16387 case Type::VariableArray:
16388 case Type::IncompleteArray:
16389 case Type::FunctionNoProto:
16390 case Type::FunctionProto:
16391 case Type::ArrayParameter:
16394 case Type::MemberPointer:
16399 case Type::Complex:
16412 case Type::ExtVector:
16415 case Type::BlockPointer:
16416 case Type::ConstantMatrix:
16417 case Type::ObjCObject:
16418 case Type::ObjCInterface:
16419 case Type::ObjCObjectPointer:
16421 case Type::HLSLAttributedResource:
16422 case Type::HLSLInlineSpirv:
16423 case Type::OverflowBehavior:
16431 case Type::LValueReference:
16432 case Type::RValueReference:
16433 llvm_unreachable(
"invalid type for expression");
16436 llvm_unreachable(
"unexpected type class");
16461 if (
Base.isNull()) {
16464 }
else if (
const Expr *E =
Base.dyn_cast<
const Expr *>()) {
16483 SpeculativeEvaluationRAII SpeculativeEval(Info);
16488 FoldConstant Fold(Info,
true);
16506 if (ArgType->isIntegralOrEnumerationType() || ArgType->isFloatingType() ||
16507 ArgType->isAnyComplexType() || ArgType->isPointerType() ||
16508 ArgType->isNullPtrType()) {
16511 Fold.keepDiagnostics();
16520 return V.hasValue();
16531 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
16555 const auto *Cast = dyn_cast<CastExpr>(NoParens);
16556 if (Cast ==
nullptr)
16561 auto CastKind = Cast->getCastKind();
16563 CastKind != CK_AddressSpaceConversion)
16566 const auto *SubExpr = Cast->getSubExpr();
16588 assert(!LVal.Designator.Invalid);
16590 auto IsLastOrInvalidFieldDecl = [&Ctx](
const FieldDecl *FD) {
16598 auto &
Base = LVal.getLValueBase();
16599 if (
auto *ME = dyn_cast_or_null<MemberExpr>(
Base.dyn_cast<
const Expr *>())) {
16600 if (
auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
16601 if (!IsLastOrInvalidFieldDecl(FD))
16603 }
else if (
auto *IFD = dyn_cast<IndirectFieldDecl>(ME->getMemberDecl())) {
16604 for (
auto *FD : IFD->chain()) {
16613 if (LVal.Designator.FirstEntryIsAnUnsizedArray) {
16617 if (BaseType->isIncompleteArrayType())
16623 for (
unsigned E = LVal.Designator.Entries.size(); I != E; ++I) {
16624 const auto &Entry = LVal.Designator.Entries[I];
16625 if (BaseType->isArrayType()) {
16631 uint64_t Index = Entry.getAsArrayIndex();
16635 }
else if (BaseType->isAnyComplexType()) {
16636 const auto *CT = BaseType->castAs<
ComplexType>();
16637 uint64_t Index = Entry.getAsArrayIndex();
16640 BaseType = CT->getElementType();
16641 }
else if (
auto *FD = getAsField(Entry)) {
16642 if (!IsLastOrInvalidFieldDecl(FD))
16646 assert(getAsBaseClass(Entry) &&
"Expecting cast to a base class");
16658 if (LVal.Designator.Invalid)
16661 if (!LVal.Designator.Entries.empty())
16662 return LVal.Designator.isMostDerivedAnUnsizedArray();
16664 if (!LVal.InvalidBase)
16676 const SubobjectDesignator &
Designator = LVal.Designator;
16688 auto isFlexibleArrayMember = [&] {
16690 FAMKind StrictFlexArraysLevel =
16693 if (
Designator.isMostDerivedAnUnsizedArray())
16696 if (StrictFlexArraysLevel == FAMKind::Default)
16699 if (
Designator.getMostDerivedArraySize() == 0 &&
16700 StrictFlexArraysLevel != FAMKind::IncompleteOnly)
16703 if (
Designator.getMostDerivedArraySize() == 1 &&
16704 StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete)
16710 return LVal.InvalidBase &&
16712 Designator.MostDerivedIsArrayElement && isFlexibleArrayMember() &&
16720 auto CharUnitsMax = std::numeric_limits<CharUnits::QuantityType>::max();
16721 if (Int.ugt(CharUnitsMax))
16731 if (!
T.isNull() &&
T->isStructureType() &&
16732 T->castAsRecordDecl()->hasFlexibleArrayMember())
16733 if (
const auto *
V = LV.getLValueBase().dyn_cast<
const ValueDecl *>())
16734 if (
const auto *VD = dyn_cast<VarDecl>(
V))
16746 unsigned Type,
const LValue &LVal,
16765 if (!(
Type & 1) || LVal.Designator.Invalid || DetermineForCompleteObject) {
16767 if (
Type == 3 && !DetermineForCompleteObject)
16770 llvm::APInt APEndOffset;
16771 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
16775 if (LVal.InvalidBase)
16779 const bool Ret = CheckedHandleSizeof(BaseTy, EndOffset);
16785 const SubobjectDesignator &
Designator = LVal.Designator;
16797 llvm::APInt APEndOffset;
16798 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
16810 if (!CheckedHandleSizeof(
Designator.MostDerivedType, BytesPerElem))
16816 int64_t ElemsRemaining;
16819 uint64_t ArraySize =
Designator.getMostDerivedArraySize();
16820 uint64_t ArrayIndex =
Designator.Entries.back().getAsArrayIndex();
16821 ElemsRemaining = ArraySize <= ArrayIndex ? 0 : ArraySize - ArrayIndex;
16823 ElemsRemaining =
Designator.isOnePastTheEnd() ? 0 : 1;
16826 EndOffset = LVal.getLValueOffset() + BytesPerElem * ElemsRemaining;
16836static std::optional<uint64_t>
16838 bool IsDynamic =
false) {
16846 SpeculativeEvaluationRAII SpeculativeEval(Info);
16847 IgnoreSideEffectsRAII Fold(Info);
16854 return std::nullopt;
16855 LVal.setFrom(Info.Ctx, RVal);
16858 return std::nullopt;
16863 if (LVal.getLValueOffset().isNegative())
16878 const auto *FD = ME ? dyn_cast<FieldDecl>(ME->getMemberDecl()) :
nullptr;
16880 return std::nullopt;
16885 return std::nullopt;
16889 if (EndOffset <= LVal.getLValueOffset())
16891 return (EndOffset - LVal.getLValueOffset()).
getQuantity();
16894bool IntExprEvaluator::VisitCallExpr(
const CallExpr *E) {
16895 if (!IsConstantEvaluatedBuiltinCall(E))
16896 return ExprEvaluatorBaseTy::VisitCallExpr(E);
16913 Info.FFDiag(E->
getArg(0));
16919 assert(SrcInt.getBitWidth() >= Alignment.getBitWidth() &&
16920 "Bit widths must be the same");
16927bool IntExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *E,
16928 unsigned BuiltinOp) {
16929 auto EvalTestOp = [&](llvm::function_ref<
bool(
const APInt &,
const APInt &)>
16931 APValue SourceLHS, SourceRHS;
16939 unsigned LaneWidth = Info.Ctx.getTypeSize(ElemQT);
16941 APInt AWide(LaneWidth * SourceLen, 0);
16942 APInt BWide(LaneWidth * SourceLen, 0);
16944 for (
unsigned I = 0; I != SourceLen; ++I) {
16947 if (ElemQT->isIntegerType()) {
16950 }
else if (ElemQT->isFloatingType()) {
16958 AWide.insertBits(ALane, I * LaneWidth);
16959 BWide.insertBits(BLane, I * LaneWidth);
16964 auto HandleMaskBinOp =
16977 auto HandleCRC32 = [&](
unsigned DataBytes) ->
bool {
16983 uint64_t CRCVal = CRC.getZExtValue();
16987 static const uint32_t CRC32C_POLY = 0x82F63B78;
16991 for (
unsigned I = 0; I != DataBytes; ++I) {
16992 uint8_t Byte =
static_cast<uint8_t>((DataVal >> (I * 8)) & 0xFF);
16994 for (
int J = 0; J != 8; ++J) {
17002 switch (BuiltinOp) {
17006 case X86::BI__builtin_ia32_crc32qi:
17007 return HandleCRC32(1);
17008 case X86::BI__builtin_ia32_crc32hi:
17009 return HandleCRC32(2);
17010 case X86::BI__builtin_ia32_crc32si:
17011 return HandleCRC32(4);
17012 case X86::BI__builtin_ia32_crc32di:
17013 return HandleCRC32(8);
17015 case Builtin::BI__builtin_dynamic_object_size:
17016 case Builtin::BI__builtin_object_size: {
17020 assert(
Type <= 3 &&
"unexpected type");
17022 bool IsDynamic = BuiltinOp == Builtin::BI__builtin_dynamic_object_size;
17023 if (std::optional<uint64_t> Size =
17032 switch (Info.EvalMode) {
17033 case EvaluationMode::ConstantExpression:
17034 case EvaluationMode::ConstantFold:
17035 case EvaluationMode::IgnoreSideEffects:
17038 case EvaluationMode::ConstantExpressionUnevaluated:
17043 llvm_unreachable(
"unexpected EvalMode");
17046 case Builtin::BI__builtin_os_log_format_buffer_size: {
17047 analyze_os_log::OSLogBufferLayout Layout;
17052 case Builtin::BI__builtin_is_aligned: {
17060 Ptr.setFrom(Info.Ctx, Src);
17066 assert(Alignment.isPowerOf2());
17079 Info.FFDiag(E->
getArg(0), diag::note_constexpr_alignment_compute)
17083 assert(Src.
isInt());
17084 return Success((Src.
getInt() & (Alignment - 1)) == 0 ? 1 : 0, E);
17086 case Builtin::BI__builtin_align_up: {
17094 APSInt((Src.
getInt() + (Alignment - 1)) & ~(Alignment - 1),
17095 Src.
getInt().isUnsigned());
17096 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
17097 return Success(AlignedVal, E);
17099 case Builtin::BI__builtin_align_down: {
17108 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
17109 return Success(AlignedVal, E);
17112 case Builtin::BI__builtin_bitreverseg:
17113 case Builtin::BI__builtin_bitreverse8:
17114 case Builtin::BI__builtin_bitreverse16:
17115 case Builtin::BI__builtin_bitreverse32:
17116 case Builtin::BI__builtin_bitreverse64:
17117 case Builtin::BI__builtin_elementwise_bitreverse: {
17122 return Success(Val.reverseBits(), E);
17124 case Builtin::BI__builtin_bswapg:
17125 case Builtin::BI__builtin_bswap16:
17126 case Builtin::BI__builtin_bswap32:
17127 case Builtin::BI__builtin_bswap64:
17128 case Builtin::BIstdc_memreverse8u8:
17129 case Builtin::BIstdc_memreverse8u16:
17130 case Builtin::BIstdc_memreverse8u32:
17131 case Builtin::BIstdc_memreverse8u64: {
17135 if (Val.getBitWidth() == 8 || Val.getBitWidth() == 1)
17138 return Success(Val.byteSwap(), E);
17141 case Builtin::BI__builtin_classify_type:
17144 case Builtin::BI__builtin_clrsb:
17145 case Builtin::BI__builtin_clrsbl:
17146 case Builtin::BI__builtin_clrsbll: {
17151 return Success(Val.getBitWidth() - Val.getSignificantBits(), E);
17154 case Builtin::BI__builtin_clz:
17155 case Builtin::BI__builtin_clzl:
17156 case Builtin::BI__builtin_clzll:
17157 case Builtin::BI__builtin_clzs:
17158 case Builtin::BI__builtin_clzg:
17159 case Builtin::BI__builtin_elementwise_clzg:
17160 case Builtin::BI__lzcnt16:
17161 case Builtin::BI__lzcnt:
17162 case Builtin::BI__lzcnt64: {
17173 std::optional<APSInt> Fallback;
17174 if ((BuiltinOp == Builtin::BI__builtin_clzg ||
17175 BuiltinOp == Builtin::BI__builtin_elementwise_clzg) &&
17180 Fallback = FallbackTemp;
17185 return Success(*Fallback, E);
17190 bool ZeroIsUndefined = BuiltinOp != Builtin::BI__lzcnt16 &&
17191 BuiltinOp != Builtin::BI__lzcnt &&
17192 BuiltinOp != Builtin::BI__lzcnt64;
17194 if (BuiltinOp == Builtin::BI__builtin_elementwise_clzg) {
17195 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
17199 if (ZeroIsUndefined)
17203 return Success(Val.countl_zero(), E);
17206 case Builtin::BI__builtin_constant_p: {
17207 const Expr *Arg = E->
getArg(0);
17216 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
17220 case Builtin::BI__noop:
17224 case Builtin::BI__builtin_is_constant_evaluated: {
17225 const auto *
Callee = Info.CurrentCall->getCallee();
17226 if (Info.InConstantContext && !Info.CheckingPotentialConstantExpression &&
17227 (Info.CallStackDepth == 1 ||
17228 (Info.CallStackDepth == 2 &&
Callee->isInStdNamespace() &&
17229 Callee->getIdentifier() &&
17230 Callee->getIdentifier()->isStr(
"is_constant_evaluated")))) {
17232 if (Info.EvalStatus.Diag)
17233 Info.report((Info.CallStackDepth == 1)
17235 : Info.CurrentCall->getCallRange().getBegin(),
17236 diag::warn_is_constant_evaluated_always_true_constexpr)
17237 << (Info.CallStackDepth == 1 ?
"__builtin_is_constant_evaluated"
17238 :
"std::is_constant_evaluated");
17241 return Success(Info.InConstantContext, E);
17244 case Builtin::BI__builtin_is_within_lifetime:
17245 if (
auto result = EvaluateBuiltinIsWithinLifetime(*
this, E))
17249 case Builtin::BI__builtin_ctz:
17250 case Builtin::BI__builtin_ctzl:
17251 case Builtin::BI__builtin_ctzll:
17252 case Builtin::BI__builtin_ctzs:
17253 case Builtin::BI__builtin_ctzg:
17254 case Builtin::BI__builtin_elementwise_ctzg: {
17265 std::optional<APSInt> Fallback;
17266 if ((BuiltinOp == Builtin::BI__builtin_ctzg ||
17267 BuiltinOp == Builtin::BI__builtin_elementwise_ctzg) &&
17272 Fallback = FallbackTemp;
17277 return Success(*Fallback, E);
17279 if (BuiltinOp == Builtin::BI__builtin_elementwise_ctzg) {
17280 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
17286 return Success(Val.countr_zero(), E);
17289 case Builtin::BI__builtin_eh_return_data_regno: {
17291 Operand = Info.Ctx.getTargetInfo().getEHDataRegisterNumber(Operand);
17295 case Builtin::BI__builtin_elementwise_abs: {
17300 return Success(Val.abs(), E);
17303 case Builtin::BI__builtin_expect:
17304 case Builtin::BI__builtin_expect_with_probability:
17305 return Visit(E->
getArg(0));
17307 case Builtin::BI__builtin_ptrauth_string_discriminator: {
17314 case Builtin::BI__builtin_infer_alloc_token: {
17320 E, diag::note_constexpr_infer_alloc_token_type_inference_failed);
17323 return Error(E, diag::note_constexpr_infer_alloc_token_no_metadata);
17325 Info.getLangOpts().AllocTokenMode.value_or(llvm::DefaultAllocTokenMode);
17326 uint64_t BitWidth = Info.Ctx.getTypeSize(Info.Ctx.getSizeType());
17327 auto MaxTokensOpt = Info.getLangOpts().AllocTokenMax;
17329 MaxTokensOpt.value_or(0) ? *MaxTokensOpt : (~0ULL >> (64 - BitWidth));
17330 auto MaybeToken = llvm::getAllocToken(Mode, *ATMD, MaxTokens);
17332 return Error(E, diag::note_constexpr_infer_alloc_token_stateful_mode);
17333 return Success(llvm::APInt(BitWidth, *MaybeToken), E);
17336 case Builtin::BI__builtin_ffs:
17337 case Builtin::BI__builtin_ffsl:
17338 case Builtin::BI__builtin_ffsll: {
17343 unsigned N = Val.countr_zero();
17344 return Success(N == Val.getBitWidth() ? 0 : N + 1, E);
17347 case Builtin::BI__builtin_fpclassify: {
17352 switch (Val.getCategory()) {
17353 case APFloat::fcNaN: Arg = 0;
break;
17354 case APFloat::fcInfinity: Arg = 1;
break;
17355 case APFloat::fcNormal: Arg = Val.isDenormal() ? 3 : 2;
break;
17356 case APFloat::fcZero: Arg = 4;
break;
17358 return Visit(E->
getArg(Arg));
17361 case Builtin::BI__builtin_isinf_sign: {
17364 Success(Val.isInfinity() ? (Val.isNegative() ? -1 : 1) : 0, E);
17367 case Builtin::BI__builtin_isinf: {
17370 Success(Val.isInfinity() ? 1 : 0, E);
17373 case Builtin::BI__builtin_isfinite: {
17376 Success(Val.isFinite() ? 1 : 0, E);
17379 case Builtin::BI__builtin_isnan: {
17382 Success(Val.isNaN() ? 1 : 0, E);
17385 case Builtin::BI__builtin_isnormal: {
17388 Success(Val.isNormal() ? 1 : 0, E);
17391 case Builtin::BI__builtin_issubnormal: {
17394 Success(Val.isDenormal() ? 1 : 0, E);
17397 case Builtin::BI__builtin_iszero: {
17400 Success(Val.isZero() ? 1 : 0, E);
17403 case Builtin::BI__builtin_signbit:
17404 case Builtin::BI__builtin_signbitf:
17405 case Builtin::BI__builtin_signbitl: {
17408 Success(Val.isNegative() ? 1 : 0, E);
17411 case Builtin::BI__builtin_isgreater:
17412 case Builtin::BI__builtin_isgreaterequal:
17413 case Builtin::BI__builtin_isless:
17414 case Builtin::BI__builtin_islessequal:
17415 case Builtin::BI__builtin_islessgreater:
17416 case Builtin::BI__builtin_isunordered: {
17425 switch (BuiltinOp) {
17426 case Builtin::BI__builtin_isgreater:
17428 case Builtin::BI__builtin_isgreaterequal:
17430 case Builtin::BI__builtin_isless:
17432 case Builtin::BI__builtin_islessequal:
17434 case Builtin::BI__builtin_islessgreater: {
17435 APFloat::cmpResult cmp = LHS.compare(RHS);
17436 return cmp == APFloat::cmpResult::cmpLessThan ||
17437 cmp == APFloat::cmpResult::cmpGreaterThan;
17439 case Builtin::BI__builtin_isunordered:
17440 return LHS.compare(RHS) == APFloat::cmpResult::cmpUnordered;
17442 llvm_unreachable(
"Unexpected builtin ID: Should be a floating "
17443 "point comparison function");
17451 case Builtin::BI__builtin_issignaling: {
17454 Success(Val.isSignaling() ? 1 : 0, E);
17457 case Builtin::BI__builtin_isfpclass: {
17461 unsigned Test =
static_cast<llvm::FPClassTest
>(MaskVal.getZExtValue());
17464 Success((Val.classify() & Test) ? 1 : 0, E);
17467 case Builtin::BI__builtin_parity:
17468 case Builtin::BI__builtin_parityl:
17469 case Builtin::BI__builtin_parityll: {
17474 return Success(Val.popcount() % 2, E);
17477 case Builtin::BI__builtin_abs:
17478 case Builtin::BI__builtin_labs:
17479 case Builtin::BI__builtin_llabs: {
17483 if (Val ==
APSInt(APInt::getSignedMinValue(Val.getBitWidth()),
17486 if (Val.isNegative())
17491 case Builtin::BI__builtin_popcount:
17492 case Builtin::BI__builtin_popcountl:
17493 case Builtin::BI__builtin_popcountll:
17494 case Builtin::BI__builtin_popcountg:
17495 case Builtin::BI__builtin_elementwise_popcount:
17496 case Builtin::BI__popcnt16:
17497 case Builtin::BI__popcnt:
17498 case Builtin::BI__popcnt64: {
17509 return Success(Val.popcount(), E);
17512 case Builtin::BI__builtin_rotateleft8:
17513 case Builtin::BI__builtin_rotateleft16:
17514 case Builtin::BI__builtin_rotateleft32:
17515 case Builtin::BI__builtin_rotateleft64:
17516 case Builtin::BI__builtin_rotateright8:
17517 case Builtin::BI__builtin_rotateright16:
17518 case Builtin::BI__builtin_rotateright32:
17519 case Builtin::BI__builtin_rotateright64:
17520 case Builtin::BI__builtin_stdc_rotate_left:
17521 case Builtin::BI__builtin_stdc_rotate_right:
17522 case Builtin::BIstdc_rotate_left_uc:
17523 case Builtin::BIstdc_rotate_left_us:
17524 case Builtin::BIstdc_rotate_left_ui:
17525 case Builtin::BIstdc_rotate_left_ul:
17526 case Builtin::BIstdc_rotate_left_ull:
17527 case Builtin::BIstdc_rotate_right_uc:
17528 case Builtin::BIstdc_rotate_right_us:
17529 case Builtin::BIstdc_rotate_right_ui:
17530 case Builtin::BIstdc_rotate_right_ul:
17531 case Builtin::BIstdc_rotate_right_ull:
17532 case Builtin::BI_rotl8:
17533 case Builtin::BI_rotl16:
17534 case Builtin::BI_rotl:
17535 case Builtin::BI_lrotl:
17536 case Builtin::BI_rotl64:
17537 case Builtin::BI_rotr8:
17538 case Builtin::BI_rotr16:
17539 case Builtin::BI_rotr:
17540 case Builtin::BI_lrotr:
17541 case Builtin::BI_rotr64: {
17549 switch (BuiltinOp) {
17550 case Builtin::BI__builtin_rotateright8:
17551 case Builtin::BI__builtin_rotateright16:
17552 case Builtin::BI__builtin_rotateright32:
17553 case Builtin::BI__builtin_rotateright64:
17554 case Builtin::BI__builtin_stdc_rotate_right:
17555 case Builtin::BIstdc_rotate_right_uc:
17556 case Builtin::BIstdc_rotate_right_us:
17557 case Builtin::BIstdc_rotate_right_ui:
17558 case Builtin::BIstdc_rotate_right_ul:
17559 case Builtin::BIstdc_rotate_right_ull:
17560 case Builtin::BI_rotr8:
17561 case Builtin::BI_rotr16:
17562 case Builtin::BI_rotr:
17563 case Builtin::BI_lrotr:
17564 case Builtin::BI_rotr64:
17573 case Builtin::BIstdc_leading_zeros_uc:
17574 case Builtin::BIstdc_leading_zeros_us:
17575 case Builtin::BIstdc_leading_zeros_ui:
17576 case Builtin::BIstdc_leading_zeros_ul:
17577 case Builtin::BIstdc_leading_zeros_ull:
17578 case Builtin::BIstdc_leading_ones_uc:
17579 case Builtin::BIstdc_leading_ones_us:
17580 case Builtin::BIstdc_leading_ones_ui:
17581 case Builtin::BIstdc_leading_ones_ul:
17582 case Builtin::BIstdc_leading_ones_ull:
17583 case Builtin::BIstdc_trailing_zeros_uc:
17584 case Builtin::BIstdc_trailing_zeros_us:
17585 case Builtin::BIstdc_trailing_zeros_ui:
17586 case Builtin::BIstdc_trailing_zeros_ul:
17587 case Builtin::BIstdc_trailing_zeros_ull:
17588 case Builtin::BIstdc_trailing_ones_uc:
17589 case Builtin::BIstdc_trailing_ones_us:
17590 case Builtin::BIstdc_trailing_ones_ui:
17591 case Builtin::BIstdc_trailing_ones_ul:
17592 case Builtin::BIstdc_trailing_ones_ull:
17593 case Builtin::BIstdc_first_leading_zero_uc:
17594 case Builtin::BIstdc_first_leading_zero_us:
17595 case Builtin::BIstdc_first_leading_zero_ui:
17596 case Builtin::BIstdc_first_leading_zero_ul:
17597 case Builtin::BIstdc_first_leading_zero_ull:
17598 case Builtin::BIstdc_first_leading_one_uc:
17599 case Builtin::BIstdc_first_leading_one_us:
17600 case Builtin::BIstdc_first_leading_one_ui:
17601 case Builtin::BIstdc_first_leading_one_ul:
17602 case Builtin::BIstdc_first_leading_one_ull:
17603 case Builtin::BIstdc_first_trailing_zero_uc:
17604 case Builtin::BIstdc_first_trailing_zero_us:
17605 case Builtin::BIstdc_first_trailing_zero_ui:
17606 case Builtin::BIstdc_first_trailing_zero_ul:
17607 case Builtin::BIstdc_first_trailing_zero_ull:
17608 case Builtin::BIstdc_first_trailing_one_uc:
17609 case Builtin::BIstdc_first_trailing_one_us:
17610 case Builtin::BIstdc_first_trailing_one_ui:
17611 case Builtin::BIstdc_first_trailing_one_ul:
17612 case Builtin::BIstdc_first_trailing_one_ull:
17613 case Builtin::BIstdc_count_zeros_uc:
17614 case Builtin::BIstdc_count_zeros_us:
17615 case Builtin::BIstdc_count_zeros_ui:
17616 case Builtin::BIstdc_count_zeros_ul:
17617 case Builtin::BIstdc_count_zeros_ull:
17618 case Builtin::BIstdc_count_ones_uc:
17619 case Builtin::BIstdc_count_ones_us:
17620 case Builtin::BIstdc_count_ones_ui:
17621 case Builtin::BIstdc_count_ones_ul:
17622 case Builtin::BIstdc_count_ones_ull:
17623 case Builtin::BIstdc_has_single_bit_uc:
17624 case Builtin::BIstdc_has_single_bit_us:
17625 case Builtin::BIstdc_has_single_bit_ui:
17626 case Builtin::BIstdc_has_single_bit_ul:
17627 case Builtin::BIstdc_has_single_bit_ull:
17628 case Builtin::BIstdc_bit_width_uc:
17629 case Builtin::BIstdc_bit_width_us:
17630 case Builtin::BIstdc_bit_width_ui:
17631 case Builtin::BIstdc_bit_width_ul:
17632 case Builtin::BIstdc_bit_width_ull:
17633 case Builtin::BIstdc_bit_floor_uc:
17634 case Builtin::BIstdc_bit_floor_us:
17635 case Builtin::BIstdc_bit_floor_ui:
17636 case Builtin::BIstdc_bit_floor_ul:
17637 case Builtin::BIstdc_bit_floor_ull:
17638 case Builtin::BIstdc_bit_ceil_uc:
17639 case Builtin::BIstdc_bit_ceil_us:
17640 case Builtin::BIstdc_bit_ceil_ui:
17641 case Builtin::BIstdc_bit_ceil_ul:
17642 case Builtin::BIstdc_bit_ceil_ull:
17643 case Builtin::BI__builtin_stdc_leading_zeros:
17644 case Builtin::BI__builtin_stdc_leading_ones:
17645 case Builtin::BI__builtin_stdc_trailing_zeros:
17646 case Builtin::BI__builtin_stdc_trailing_ones:
17647 case Builtin::BI__builtin_stdc_first_leading_zero:
17648 case Builtin::BI__builtin_stdc_first_leading_one:
17649 case Builtin::BI__builtin_stdc_first_trailing_zero:
17650 case Builtin::BI__builtin_stdc_first_trailing_one:
17651 case Builtin::BI__builtin_stdc_count_zeros:
17652 case Builtin::BI__builtin_stdc_count_ones:
17653 case Builtin::BI__builtin_stdc_has_single_bit:
17654 case Builtin::BI__builtin_stdc_bit_width:
17655 case Builtin::BI__builtin_stdc_bit_floor:
17656 case Builtin::BI__builtin_stdc_bit_ceil: {
17661 unsigned BitWidth = Val.getBitWidth();
17662 const unsigned ResBitWidth = Info.Ctx.getIntWidth(E->
getType());
17664 switch (BuiltinOp) {
17665 case Builtin::BIstdc_leading_zeros_uc:
17666 case Builtin::BIstdc_leading_zeros_us:
17667 case Builtin::BIstdc_leading_zeros_ui:
17668 case Builtin::BIstdc_leading_zeros_ul:
17669 case Builtin::BIstdc_leading_zeros_ull:
17670 case Builtin::BI__builtin_stdc_leading_zeros:
17671 return Success(
APInt(ResBitWidth, Val.countl_zero()), E);
17672 case Builtin::BIstdc_leading_ones_uc:
17673 case Builtin::BIstdc_leading_ones_us:
17674 case Builtin::BIstdc_leading_ones_ui:
17675 case Builtin::BIstdc_leading_ones_ul:
17676 case Builtin::BIstdc_leading_ones_ull:
17677 case Builtin::BI__builtin_stdc_leading_ones:
17678 return Success(
APInt(ResBitWidth, Val.countl_one()), E);
17679 case Builtin::BIstdc_trailing_zeros_uc:
17680 case Builtin::BIstdc_trailing_zeros_us:
17681 case Builtin::BIstdc_trailing_zeros_ui:
17682 case Builtin::BIstdc_trailing_zeros_ul:
17683 case Builtin::BIstdc_trailing_zeros_ull:
17684 case Builtin::BI__builtin_stdc_trailing_zeros:
17685 return Success(
APInt(ResBitWidth, Val.countr_zero()), E);
17686 case Builtin::BIstdc_trailing_ones_uc:
17687 case Builtin::BIstdc_trailing_ones_us:
17688 case Builtin::BIstdc_trailing_ones_ui:
17689 case Builtin::BIstdc_trailing_ones_ul:
17690 case Builtin::BIstdc_trailing_ones_ull:
17691 case Builtin::BI__builtin_stdc_trailing_ones:
17692 return Success(
APInt(ResBitWidth, Val.countr_one()), E);
17693 case Builtin::BIstdc_first_leading_zero_uc:
17694 case Builtin::BIstdc_first_leading_zero_us:
17695 case Builtin::BIstdc_first_leading_zero_ui:
17696 case Builtin::BIstdc_first_leading_zero_ul:
17697 case Builtin::BIstdc_first_leading_zero_ull:
17698 case Builtin::BI__builtin_stdc_first_leading_zero:
17700 APInt(ResBitWidth, Val.isAllOnes() ? 0 : Val.countl_one() + 1), E);
17701 case Builtin::BIstdc_first_leading_one_uc:
17702 case Builtin::BIstdc_first_leading_one_us:
17703 case Builtin::BIstdc_first_leading_one_ui:
17704 case Builtin::BIstdc_first_leading_one_ul:
17705 case Builtin::BIstdc_first_leading_one_ull:
17706 case Builtin::BI__builtin_stdc_first_leading_one:
17708 APInt(ResBitWidth, Val.isZero() ? 0 : Val.countl_zero() + 1), E);
17709 case Builtin::BIstdc_first_trailing_zero_uc:
17710 case Builtin::BIstdc_first_trailing_zero_us:
17711 case Builtin::BIstdc_first_trailing_zero_ui:
17712 case Builtin::BIstdc_first_trailing_zero_ul:
17713 case Builtin::BIstdc_first_trailing_zero_ull:
17714 case Builtin::BI__builtin_stdc_first_trailing_zero:
17716 APInt(ResBitWidth, Val.isAllOnes() ? 0 : Val.countr_one() + 1), E);
17717 case Builtin::BIstdc_first_trailing_one_uc:
17718 case Builtin::BIstdc_first_trailing_one_us:
17719 case Builtin::BIstdc_first_trailing_one_ui:
17720 case Builtin::BIstdc_first_trailing_one_ul:
17721 case Builtin::BIstdc_first_trailing_one_ull:
17722 case Builtin::BI__builtin_stdc_first_trailing_one:
17724 APInt(ResBitWidth, Val.isZero() ? 0 : Val.countr_zero() + 1), E);
17725 case Builtin::BIstdc_count_zeros_uc:
17726 case Builtin::BIstdc_count_zeros_us:
17727 case Builtin::BIstdc_count_zeros_ui:
17728 case Builtin::BIstdc_count_zeros_ul:
17729 case Builtin::BIstdc_count_zeros_ull:
17730 case Builtin::BI__builtin_stdc_count_zeros: {
17731 APInt Cnt(ResBitWidth, BitWidth - Val.popcount());
17734 case Builtin::BIstdc_count_ones_uc:
17735 case Builtin::BIstdc_count_ones_us:
17736 case Builtin::BIstdc_count_ones_ui:
17737 case Builtin::BIstdc_count_ones_ul:
17738 case Builtin::BIstdc_count_ones_ull:
17739 case Builtin::BI__builtin_stdc_count_ones: {
17740 APInt Cnt(ResBitWidth, Val.popcount());
17743 case Builtin::BIstdc_has_single_bit_uc:
17744 case Builtin::BIstdc_has_single_bit_us:
17745 case Builtin::BIstdc_has_single_bit_ui:
17746 case Builtin::BIstdc_has_single_bit_ul:
17747 case Builtin::BIstdc_has_single_bit_ull:
17748 case Builtin::BI__builtin_stdc_has_single_bit: {
17749 APInt Res(ResBitWidth, Val.popcount() == 1 ? 1 : 0);
17752 case Builtin::BIstdc_bit_width_uc:
17753 case Builtin::BIstdc_bit_width_us:
17754 case Builtin::BIstdc_bit_width_ui:
17755 case Builtin::BIstdc_bit_width_ul:
17756 case Builtin::BIstdc_bit_width_ull:
17757 case Builtin::BI__builtin_stdc_bit_width:
17758 return Success(
APInt(ResBitWidth, BitWidth - Val.countl_zero()), E);
17759 case Builtin::BIstdc_bit_floor_uc:
17760 case Builtin::BIstdc_bit_floor_us:
17761 case Builtin::BIstdc_bit_floor_ui:
17762 case Builtin::BIstdc_bit_floor_ul:
17763 case Builtin::BIstdc_bit_floor_ull:
17764 case Builtin::BI__builtin_stdc_bit_floor: {
17767 unsigned Exp = BitWidth - Val.countl_zero() - 1;
17769 APSInt(APInt::getOneBitSet(BitWidth, Exp),
true), E);
17771 case Builtin::BIstdc_bit_ceil_uc:
17772 case Builtin::BIstdc_bit_ceil_us:
17773 case Builtin::BIstdc_bit_ceil_ui:
17774 case Builtin::BIstdc_bit_ceil_ul:
17775 case Builtin::BIstdc_bit_ceil_ull:
17776 case Builtin::BI__builtin_stdc_bit_ceil: {
17779 APInt ValMinusOne = Val - 1;
17780 unsigned LZ = ValMinusOne.countl_zero();
17784 APInt Result = APInt::getOneBitSet(BitWidth, BitWidth - LZ);
17788 llvm_unreachable(
"Unknown stdc builtin");
17792 case Builtin::BI__builtin_elementwise_add_sat: {
17798 APInt Result = LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS);
17801 case Builtin::BI__builtin_elementwise_sub_sat: {
17807 APInt Result = LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
17810 case Builtin::BI__builtin_elementwise_max: {
17819 case Builtin::BI__builtin_elementwise_min: {
17828 case Builtin::BI__builtin_elementwise_clmul: {
17837 case Builtin::BI__builtin_elementwise_fshl:
17838 case Builtin::BI__builtin_elementwise_fshr: {
17845 switch (BuiltinOp) {
17846 case Builtin::BI__builtin_elementwise_fshl: {
17847 APSInt Result(llvm::APIntOps::fshl(Hi, Lo, Shift), Hi.isUnsigned());
17850 case Builtin::BI__builtin_elementwise_fshr: {
17851 APSInt Result(llvm::APIntOps::fshr(Hi, Lo, Shift), Hi.isUnsigned());
17855 llvm_unreachable(
"Fully covered switch above");
17857 case Builtin::BIstrlen:
17858 case Builtin::BIwcslen:
17860 if (Info.getLangOpts().CPlusPlus11)
17861 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
17863 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
17865 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
17867 case Builtin::BI__builtin_strlen:
17868 case Builtin::BI__builtin_wcslen: {
17871 if (std::optional<uint64_t> StrLen =
17877 case Builtin::BIstrcmp:
17878 case Builtin::BIwcscmp:
17879 case Builtin::BIstrncmp:
17880 case Builtin::BIwcsncmp:
17881 case Builtin::BImemcmp:
17882 case Builtin::BIbcmp:
17883 case Builtin::BIwmemcmp:
17885 if (Info.getLangOpts().CPlusPlus11)
17886 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
17888 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
17890 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
17892 case Builtin::BI__builtin_strcmp:
17893 case Builtin::BI__builtin_wcscmp:
17894 case Builtin::BI__builtin_strncmp:
17895 case Builtin::BI__builtin_wcsncmp:
17896 case Builtin::BI__builtin_memcmp:
17897 case Builtin::BI__builtin_bcmp:
17898 case Builtin::BI__builtin_wmemcmp: {
17899 LValue String1, String2;
17905 if (BuiltinOp != Builtin::BIstrcmp &&
17906 BuiltinOp != Builtin::BIwcscmp &&
17907 BuiltinOp != Builtin::BI__builtin_strcmp &&
17908 BuiltinOp != Builtin::BI__builtin_wcscmp) {
17912 MaxLength = N.getZExtValue();
17916 if (MaxLength == 0u)
17919 if (!String1.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
17920 !String2.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
17921 String1.Designator.Invalid || String2.Designator.Invalid)
17924 QualType CharTy1 = String1.Designator.getType(Info.Ctx);
17925 QualType CharTy2 = String2.Designator.getType(Info.Ctx);
17927 bool IsRawByte = BuiltinOp == Builtin::BImemcmp ||
17928 BuiltinOp == Builtin::BIbcmp ||
17929 BuiltinOp == Builtin::BI__builtin_memcmp ||
17930 BuiltinOp == Builtin::BI__builtin_bcmp;
17932 assert(IsRawByte ||
17933 (Info.Ctx.hasSameUnqualifiedType(
17935 Info.Ctx.hasSameUnqualifiedType(CharTy1, CharTy2)));
17942 Info.FFDiag(E, diag::note_constexpr_memcmp_unsupported)
17943 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp) << CharTy1
17948 const auto &ReadCurElems = [&](
APValue &Char1,
APValue &Char2) {
17951 Char1.
isInt() && Char2.isInt();
17953 const auto &AdvanceElems = [&] {
17959 (BuiltinOp != Builtin::BImemcmp && BuiltinOp != Builtin::BIbcmp &&
17960 BuiltinOp != Builtin::BIwmemcmp &&
17961 BuiltinOp != Builtin::BI__builtin_memcmp &&
17962 BuiltinOp != Builtin::BI__builtin_bcmp &&
17963 BuiltinOp != Builtin::BI__builtin_wmemcmp);
17964 bool IsWide = BuiltinOp == Builtin::BIwcscmp ||
17965 BuiltinOp == Builtin::BIwcsncmp ||
17966 BuiltinOp == Builtin::BIwmemcmp ||
17967 BuiltinOp == Builtin::BI__builtin_wcscmp ||
17968 BuiltinOp == Builtin::BI__builtin_wcsncmp ||
17969 BuiltinOp == Builtin::BI__builtin_wmemcmp;
17971 for (; MaxLength; --MaxLength) {
17973 if (!ReadCurElems(Char1, Char2))
17981 if (StopAtNull && !Char1.
getInt())
17983 assert(!(StopAtNull && !Char2.
getInt()));
17984 if (!AdvanceElems())
17991 case Builtin::BI__atomic_always_lock_free:
17992 case Builtin::BI__atomic_is_lock_free:
17993 case Builtin::BI__c11_atomic_is_lock_free: {
18009 if (
Size.isPowerOfTwo()) {
18011 unsigned InlineWidthBits =
18012 Info.Ctx.getTargetInfo().getMaxAtomicInlineWidth();
18013 if (Size <= Info.Ctx.toCharUnitsFromBits(InlineWidthBits)) {
18014 if (BuiltinOp == Builtin::BI__c11_atomic_is_lock_free ||
18020 const Expr *PtrArg = E->
getArg(1);
18026 IntResult.isAligned(
Size.getAsAlign()))
18030 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(PtrArg)) {
18033 if (ICE->getCastKind() == CK_BitCast)
18034 PtrArg = ICE->getSubExpr();
18037 if (
auto PtrTy = PtrArg->
getType()->
getAs<PointerType>()) {
18040 Info.Ctx.getTypeAlignInChars(PointeeType) >= Size) {
18048 return BuiltinOp == Builtin::BI__atomic_always_lock_free ?
18051 case Builtin::BI__builtin_addcb:
18052 case Builtin::BI__builtin_addcs:
18053 case Builtin::BI__builtin_addc:
18054 case Builtin::BI__builtin_addcl:
18055 case Builtin::BI__builtin_addcll:
18056 case Builtin::BI__builtin_subcb:
18057 case Builtin::BI__builtin_subcs:
18058 case Builtin::BI__builtin_subc:
18059 case Builtin::BI__builtin_subcl:
18060 case Builtin::BI__builtin_subcll: {
18061 LValue CarryOutLValue;
18073 bool FirstOverflowed =
false;
18074 bool SecondOverflowed =
false;
18075 switch (BuiltinOp) {
18077 llvm_unreachable(
"Invalid value for BuiltinOp");
18078 case Builtin::BI__builtin_addcb:
18079 case Builtin::BI__builtin_addcs:
18080 case Builtin::BI__builtin_addc:
18081 case Builtin::BI__builtin_addcl:
18082 case Builtin::BI__builtin_addcll:
18084 LHS.uadd_ov(RHS, FirstOverflowed).uadd_ov(CarryIn, SecondOverflowed);
18086 case Builtin::BI__builtin_subcb:
18087 case Builtin::BI__builtin_subcs:
18088 case Builtin::BI__builtin_subc:
18089 case Builtin::BI__builtin_subcl:
18090 case Builtin::BI__builtin_subcll:
18092 LHS.usub_ov(RHS, FirstOverflowed).usub_ov(CarryIn, SecondOverflowed);
18098 CarryOut = (
uint64_t)(FirstOverflowed | SecondOverflowed);
18104 case Builtin::BI__builtin_add_overflow:
18105 case Builtin::BI__builtin_sub_overflow:
18106 case Builtin::BI__builtin_mul_overflow:
18107 case Builtin::BI__builtin_sadd_overflow:
18108 case Builtin::BI__builtin_uadd_overflow:
18109 case Builtin::BI__builtin_uaddl_overflow:
18110 case Builtin::BI__builtin_uaddll_overflow:
18111 case Builtin::BI__builtin_usub_overflow:
18112 case Builtin::BI__builtin_usubl_overflow:
18113 case Builtin::BI__builtin_usubll_overflow:
18114 case Builtin::BI__builtin_umul_overflow:
18115 case Builtin::BI__builtin_umull_overflow:
18116 case Builtin::BI__builtin_umulll_overflow:
18117 case Builtin::BI__builtin_saddl_overflow:
18118 case Builtin::BI__builtin_saddll_overflow:
18119 case Builtin::BI__builtin_ssub_overflow:
18120 case Builtin::BI__builtin_ssubl_overflow:
18121 case Builtin::BI__builtin_ssubll_overflow:
18122 case Builtin::BI__builtin_smul_overflow:
18123 case Builtin::BI__builtin_smull_overflow:
18124 case Builtin::BI__builtin_smulll_overflow: {
18125 LValue ResultLValue;
18135 bool DidOverflow =
false;
18138 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
18139 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
18140 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
18141 bool IsSigned = LHS.isSigned() || RHS.isSigned() ||
18143 bool AllSigned = LHS.isSigned() && RHS.isSigned() &&
18145 uint64_t LHSSize = LHS.getBitWidth();
18146 uint64_t RHSSize = RHS.getBitWidth();
18147 uint64_t ResultSize = Info.Ctx.getIntWidth(ResultType);
18148 uint64_t MaxBits = std::max(std::max(LHSSize, RHSSize), ResultSize);
18154 if (IsSigned && !AllSigned)
18157 LHS =
APSInt(LHS.extOrTrunc(MaxBits), !IsSigned);
18158 RHS =
APSInt(RHS.extOrTrunc(MaxBits), !IsSigned);
18163 switch (BuiltinOp) {
18165 llvm_unreachable(
"Invalid value for BuiltinOp");
18166 case Builtin::BI__builtin_add_overflow:
18167 case Builtin::BI__builtin_sadd_overflow:
18168 case Builtin::BI__builtin_saddl_overflow:
18169 case Builtin::BI__builtin_saddll_overflow:
18170 case Builtin::BI__builtin_uadd_overflow:
18171 case Builtin::BI__builtin_uaddl_overflow:
18172 case Builtin::BI__builtin_uaddll_overflow:
18173 Result = LHS.isSigned() ? LHS.sadd_ov(RHS, DidOverflow)
18174 : LHS.uadd_ov(RHS, DidOverflow);
18176 case Builtin::BI__builtin_sub_overflow:
18177 case Builtin::BI__builtin_ssub_overflow:
18178 case Builtin::BI__builtin_ssubl_overflow:
18179 case Builtin::BI__builtin_ssubll_overflow:
18180 case Builtin::BI__builtin_usub_overflow:
18181 case Builtin::BI__builtin_usubl_overflow:
18182 case Builtin::BI__builtin_usubll_overflow:
18183 Result = LHS.isSigned() ? LHS.ssub_ov(RHS, DidOverflow)
18184 : LHS.usub_ov(RHS, DidOverflow);
18186 case Builtin::BI__builtin_mul_overflow:
18187 case Builtin::BI__builtin_smul_overflow:
18188 case Builtin::BI__builtin_smull_overflow:
18189 case Builtin::BI__builtin_smulll_overflow:
18190 case Builtin::BI__builtin_umul_overflow:
18191 case Builtin::BI__builtin_umull_overflow:
18192 case Builtin::BI__builtin_umulll_overflow:
18193 Result = LHS.isSigned() ? LHS.smul_ov(RHS, DidOverflow)
18194 : LHS.umul_ov(RHS, DidOverflow);
18203 APSInt Temp =
Result.extOrTrunc(Info.Ctx.getIntWidth(ResultType));
18208 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
18209 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
18210 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
18211 if (!APSInt::isSameValue(Temp,
Result))
18212 DidOverflow =
true;
18219 return Success(DidOverflow, E);
18222 case Builtin::BI__builtin_reduce_add:
18223 case Builtin::BI__builtin_reduce_mul:
18224 case Builtin::BI__builtin_reduce_and:
18225 case Builtin::BI__builtin_reduce_or:
18226 case Builtin::BI__builtin_reduce_xor:
18227 case Builtin::BI__builtin_reduce_min:
18228 case Builtin::BI__builtin_reduce_max: {
18235 for (
unsigned EltNum = 1; EltNum < SourceLen; ++EltNum) {
18236 switch (BuiltinOp) {
18239 case Builtin::BI__builtin_reduce_add: {
18242 Reduced.getBitWidth() + 1, std::plus<APSInt>(), Reduced))
18246 case Builtin::BI__builtin_reduce_mul: {
18249 Reduced.getBitWidth() * 2, std::multiplies<APSInt>(), Reduced))
18253 case Builtin::BI__builtin_reduce_and: {
18257 case Builtin::BI__builtin_reduce_or: {
18261 case Builtin::BI__builtin_reduce_xor: {
18265 case Builtin::BI__builtin_reduce_min: {
18269 case Builtin::BI__builtin_reduce_max: {
18279 case clang::X86::BI__builtin_ia32_addcarryx_u32:
18280 case clang::X86::BI__builtin_ia32_addcarryx_u64:
18281 case clang::X86::BI__builtin_ia32_subborrow_u32:
18282 case clang::X86::BI__builtin_ia32_subborrow_u64: {
18283 LValue ResultLValue;
18284 APSInt CarryIn, LHS, RHS;
18292 bool IsAdd = BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u32 ||
18293 BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u64;
18295 unsigned BitWidth = LHS.getBitWidth();
18296 unsigned CarryInBit = CarryIn.ugt(0) ? 1 : 0;
18299 ? (LHS.zext(BitWidth + 1) + (RHS.zext(BitWidth + 1) + CarryInBit))
18300 : (LHS.zext(BitWidth + 1) - (RHS.zext(BitWidth + 1) + CarryInBit));
18302 APInt Result = ExResult.extractBits(BitWidth, 0);
18303 uint64_t CarryOut = ExResult.extractBitsAsZExtValue(1, BitWidth);
18311 case clang::X86::BI__builtin_ia32_movmskps:
18312 case clang::X86::BI__builtin_ia32_movmskpd:
18313 case clang::X86::BI__builtin_ia32_pmovmskb128:
18314 case clang::X86::BI__builtin_ia32_pmovmskb256:
18315 case clang::X86::BI__builtin_ia32_movmskps256:
18316 case clang::X86::BI__builtin_ia32_movmskpd256: {
18323 unsigned ResultLen = Info.Ctx.getTypeSize(
18327 for (
unsigned I = 0; I != SourceLen; ++I) {
18329 if (ElemQT->isIntegerType()) {
18331 }
else if (ElemQT->isRealFloatingType()) {
18336 Result.setBitVal(I, Elem.isNegative());
18341 case clang::X86::BI__builtin_ia32_bextr_u32:
18342 case clang::X86::BI__builtin_ia32_bextr_u64:
18343 case clang::X86::BI__builtin_ia32_bextri_u32:
18344 case clang::X86::BI__builtin_ia32_bextri_u64: {
18350 unsigned BitWidth = Val.getBitWidth();
18352 uint64_t Length = Idx.extractBitsAsZExtValue(8, 8);
18353 Length = Length > BitWidth ? BitWidth : Length;
18356 if (Length == 0 || Shift >= BitWidth)
18360 Result &= llvm::maskTrailingOnes<uint64_t>(Length);
18364 case clang::X86::BI__builtin_ia32_bzhi_si:
18365 case clang::X86::BI__builtin_ia32_bzhi_di: {
18371 unsigned BitWidth = Val.getBitWidth();
18372 unsigned Index = Idx.extractBitsAsZExtValue(8, 0);
18373 if (Index < BitWidth)
18374 Val.clearHighBits(BitWidth - Index);
18378 case clang::X86::BI__builtin_ia32_ktestcqi:
18379 case clang::X86::BI__builtin_ia32_ktestchi:
18380 case clang::X86::BI__builtin_ia32_ktestcsi:
18381 case clang::X86::BI__builtin_ia32_ktestcdi: {
18387 return Success((~A & B) == 0, E);
18390 case clang::X86::BI__builtin_ia32_ktestzqi:
18391 case clang::X86::BI__builtin_ia32_ktestzhi:
18392 case clang::X86::BI__builtin_ia32_ktestzsi:
18393 case clang::X86::BI__builtin_ia32_ktestzdi: {
18399 return Success((A & B) == 0, E);
18402 case clang::X86::BI__builtin_ia32_kortestcqi:
18403 case clang::X86::BI__builtin_ia32_kortestchi:
18404 case clang::X86::BI__builtin_ia32_kortestcsi:
18405 case clang::X86::BI__builtin_ia32_kortestcdi: {
18411 return Success(~(A | B) == 0, E);
18414 case clang::X86::BI__builtin_ia32_kortestzqi:
18415 case clang::X86::BI__builtin_ia32_kortestzhi:
18416 case clang::X86::BI__builtin_ia32_kortestzsi:
18417 case clang::X86::BI__builtin_ia32_kortestzdi: {
18423 return Success((A | B) == 0, E);
18426 case clang::X86::BI__builtin_ia32_kunpckhi:
18427 case clang::X86::BI__builtin_ia32_kunpckdi:
18428 case clang::X86::BI__builtin_ia32_kunpcksi: {
18436 unsigned BW = A.getBitWidth();
18437 APSInt Result(A.trunc(BW / 2).concat(B.trunc(BW / 2)), A.isUnsigned());
18441 case clang::X86::BI__builtin_ia32_lzcnt_u16:
18442 case clang::X86::BI__builtin_ia32_lzcnt_u32:
18443 case clang::X86::BI__builtin_ia32_lzcnt_u64: {
18447 return Success(Val.countLeadingZeros(), E);
18450 case clang::X86::BI__builtin_ia32_tzcnt_u16:
18451 case clang::X86::BI__builtin_ia32_tzcnt_u32:
18452 case clang::X86::BI__builtin_ia32_tzcnt_u64: {
18456 return Success(Val.countTrailingZeros(), E);
18459 case clang::X86::BI__builtin_ia32_pdep_si:
18460 case clang::X86::BI__builtin_ia32_pdep_di:
18461 case Builtin::BI__builtin_elementwise_pdep: {
18466 return Success(llvm::APIntOps::pdep(Val, Msk), E);
18469 case clang::X86::BI__builtin_ia32_pext_si:
18470 case clang::X86::BI__builtin_ia32_pext_di:
18471 case Builtin::BI__builtin_elementwise_pext: {
18476 return Success(llvm::APIntOps::pext(Val, Msk), E);
18478 case X86::BI__builtin_ia32_ptestz128:
18479 case X86::BI__builtin_ia32_ptestz256:
18480 case X86::BI__builtin_ia32_vtestzps:
18481 case X86::BI__builtin_ia32_vtestzps256:
18482 case X86::BI__builtin_ia32_vtestzpd:
18483 case X86::BI__builtin_ia32_vtestzpd256: {
18485 [](
const APInt &A,
const APInt &B) {
return (A & B) == 0; });
18487 case X86::BI__builtin_ia32_ptestc128:
18488 case X86::BI__builtin_ia32_ptestc256:
18489 case X86::BI__builtin_ia32_vtestcps:
18490 case X86::BI__builtin_ia32_vtestcps256:
18491 case X86::BI__builtin_ia32_vtestcpd:
18492 case X86::BI__builtin_ia32_vtestcpd256: {
18494 [](
const APInt &A,
const APInt &B) {
return (~A & B) == 0; });
18496 case X86::BI__builtin_ia32_ptestnzc128:
18497 case X86::BI__builtin_ia32_ptestnzc256:
18498 case X86::BI__builtin_ia32_vtestnzcps:
18499 case X86::BI__builtin_ia32_vtestnzcps256:
18500 case X86::BI__builtin_ia32_vtestnzcpd:
18501 case X86::BI__builtin_ia32_vtestnzcpd256: {
18502 return EvalTestOp([](
const APInt &A,
const APInt &B) {
18503 return ((A & B) != 0) && ((~A & B) != 0);
18506 case X86::BI__builtin_ia32_kandqi:
18507 case X86::BI__builtin_ia32_kandhi:
18508 case X86::BI__builtin_ia32_kandsi:
18509 case X86::BI__builtin_ia32_kanddi: {
18510 return HandleMaskBinOp(
18511 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS & RHS; });
18514 case X86::BI__builtin_ia32_kandnqi:
18515 case X86::BI__builtin_ia32_kandnhi:
18516 case X86::BI__builtin_ia32_kandnsi:
18517 case X86::BI__builtin_ia32_kandndi: {
18518 return HandleMaskBinOp(
18519 [](
const APSInt &LHS,
const APSInt &RHS) {
return ~LHS & RHS; });
18522 case X86::BI__builtin_ia32_korqi:
18523 case X86::BI__builtin_ia32_korhi:
18524 case X86::BI__builtin_ia32_korsi:
18525 case X86::BI__builtin_ia32_kordi: {
18526 return HandleMaskBinOp(
18527 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS | RHS; });
18530 case X86::BI__builtin_ia32_kxnorqi:
18531 case X86::BI__builtin_ia32_kxnorhi:
18532 case X86::BI__builtin_ia32_kxnorsi:
18533 case X86::BI__builtin_ia32_kxnordi: {
18534 return HandleMaskBinOp(
18535 [](
const APSInt &LHS,
const APSInt &RHS) {
return ~(LHS ^ RHS); });
18538 case X86::BI__builtin_ia32_kxorqi:
18539 case X86::BI__builtin_ia32_kxorhi:
18540 case X86::BI__builtin_ia32_kxorsi:
18541 case X86::BI__builtin_ia32_kxordi: {
18542 return HandleMaskBinOp(
18543 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS ^ RHS; });
18546 case X86::BI__builtin_ia32_knotqi:
18547 case X86::BI__builtin_ia32_knothi:
18548 case X86::BI__builtin_ia32_knotsi:
18549 case X86::BI__builtin_ia32_knotdi: {
18557 case X86::BI__builtin_ia32_kaddqi:
18558 case X86::BI__builtin_ia32_kaddhi:
18559 case X86::BI__builtin_ia32_kaddsi:
18560 case X86::BI__builtin_ia32_kadddi: {
18561 return HandleMaskBinOp(
18562 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS + RHS; });
18565 case X86::BI__builtin_ia32_kmovb:
18566 case X86::BI__builtin_ia32_kmovw:
18567 case X86::BI__builtin_ia32_kmovd:
18568 case X86::BI__builtin_ia32_kmovq: {
18575 case X86::BI__builtin_ia32_kshiftliqi:
18576 case X86::BI__builtin_ia32_kshiftlihi:
18577 case X86::BI__builtin_ia32_kshiftlisi:
18578 case X86::BI__builtin_ia32_kshiftlidi: {
18579 return HandleMaskBinOp([](
const APSInt &LHS,
const APSInt &RHS) {
18580 unsigned Amt = RHS.getZExtValue() & 0xFF;
18581 if (Amt >= LHS.getBitWidth())
18582 return APSInt(APInt::getZero(LHS.getBitWidth()), LHS.isUnsigned());
18583 return APSInt(LHS.shl(Amt), LHS.isUnsigned());
18587 case X86::BI__builtin_ia32_kshiftriqi:
18588 case X86::BI__builtin_ia32_kshiftrihi:
18589 case X86::BI__builtin_ia32_kshiftrisi:
18590 case X86::BI__builtin_ia32_kshiftridi: {
18591 return HandleMaskBinOp([](
const APSInt &LHS,
const APSInt &RHS) {
18592 unsigned Amt = RHS.getZExtValue() & 0xFF;
18593 if (Amt >= LHS.getBitWidth())
18594 return APSInt(APInt::getZero(LHS.getBitWidth()), LHS.isUnsigned());
18595 return APSInt(LHS.lshr(Amt), LHS.isUnsigned());
18599 case clang::X86::BI__builtin_ia32_vec_ext_v4hi:
18600 case clang::X86::BI__builtin_ia32_vec_ext_v16qi:
18601 case clang::X86::BI__builtin_ia32_vec_ext_v8hi:
18602 case clang::X86::BI__builtin_ia32_vec_ext_v4si:
18603 case clang::X86::BI__builtin_ia32_vec_ext_v2di:
18604 case clang::X86::BI__builtin_ia32_vec_ext_v32qi:
18605 case clang::X86::BI__builtin_ia32_vec_ext_v16hi:
18606 case clang::X86::BI__builtin_ia32_vec_ext_v8si:
18607 case clang::X86::BI__builtin_ia32_vec_ext_v4di: {
18614 unsigned Idx =
static_cast<unsigned>(IdxAPS.getZExtValue() & (N - 1));
18618 case clang::X86::BI__builtin_ia32_cvtb2mask128:
18619 case clang::X86::BI__builtin_ia32_cvtb2mask256:
18620 case clang::X86::BI__builtin_ia32_cvtb2mask512:
18621 case clang::X86::BI__builtin_ia32_cvtw2mask128:
18622 case clang::X86::BI__builtin_ia32_cvtw2mask256:
18623 case clang::X86::BI__builtin_ia32_cvtw2mask512:
18624 case clang::X86::BI__builtin_ia32_cvtd2mask128:
18625 case clang::X86::BI__builtin_ia32_cvtd2mask256:
18626 case clang::X86::BI__builtin_ia32_cvtd2mask512:
18627 case clang::X86::BI__builtin_ia32_cvtq2mask128:
18628 case clang::X86::BI__builtin_ia32_cvtq2mask256:
18629 case clang::X86::BI__builtin_ia32_cvtq2mask512: {
18636 unsigned RetWidth = Info.Ctx.getIntWidth(E->
getType());
18637 llvm::APInt Bits(RetWidth, 0);
18639 for (
unsigned ElemNum = 0; ElemNum != VectorLen; ++ElemNum) {
18641 unsigned MSB = A[A.getBitWidth() - 1];
18642 Bits.setBitVal(ElemNum, MSB);
18645 APSInt RetMask(Bits,
true);
18649 case clang::X86::BI__builtin_ia32_cmpb128_mask:
18650 case clang::X86::BI__builtin_ia32_cmpw128_mask:
18651 case clang::X86::BI__builtin_ia32_cmpd128_mask:
18652 case clang::X86::BI__builtin_ia32_cmpq128_mask:
18653 case clang::X86::BI__builtin_ia32_cmpb256_mask:
18654 case clang::X86::BI__builtin_ia32_cmpw256_mask:
18655 case clang::X86::BI__builtin_ia32_cmpd256_mask:
18656 case clang::X86::BI__builtin_ia32_cmpq256_mask:
18657 case clang::X86::BI__builtin_ia32_cmpb512_mask:
18658 case clang::X86::BI__builtin_ia32_cmpw512_mask:
18659 case clang::X86::BI__builtin_ia32_cmpd512_mask:
18660 case clang::X86::BI__builtin_ia32_cmpq512_mask:
18661 case clang::X86::BI__builtin_ia32_ucmpb128_mask:
18662 case clang::X86::BI__builtin_ia32_ucmpw128_mask:
18663 case clang::X86::BI__builtin_ia32_ucmpd128_mask:
18664 case clang::X86::BI__builtin_ia32_ucmpq128_mask:
18665 case clang::X86::BI__builtin_ia32_ucmpb256_mask:
18666 case clang::X86::BI__builtin_ia32_ucmpw256_mask:
18667 case clang::X86::BI__builtin_ia32_ucmpd256_mask:
18668 case clang::X86::BI__builtin_ia32_ucmpq256_mask:
18669 case clang::X86::BI__builtin_ia32_ucmpb512_mask:
18670 case clang::X86::BI__builtin_ia32_ucmpw512_mask:
18671 case clang::X86::BI__builtin_ia32_ucmpd512_mask:
18672 case clang::X86::BI__builtin_ia32_ucmpq512_mask: {
18676 (BuiltinOp >= clang::X86::BI__builtin_ia32_ucmpb128_mask &&
18677 BuiltinOp <= clang::X86::BI__builtin_ia32_ucmpw512_mask);
18690 unsigned RetWidth = Mask.getBitWidth();
18692 APSInt RetMask(llvm::APInt(RetWidth, 0),
true);
18694 for (
unsigned ElemNum = 0; ElemNum < VectorLen; ++ElemNum) {
18699 switch (
Opcode.getExtValue() & 0x7) {
18704 Result = IsUnsigned ? A.ult(B) : A.slt(B);
18707 Result = IsUnsigned ? A.ule(B) : A.sle(B);
18716 Result = IsUnsigned ? A.uge(B) : A.sge(B);
18719 Result = IsUnsigned ? A.ugt(B) : A.sgt(B);
18726 RetMask.setBitVal(ElemNum, Mask[ElemNum] &&
Result);
18731 case X86::BI__builtin_ia32_cvtss2si:
18732 case X86::BI__builtin_ia32_cvtsd2si:
18733 case X86::BI__builtin_ia32_cvttss2si:
18734 case X86::BI__builtin_ia32_cvttsd2si:
18735 case X86::BI__builtin_ia32_cvtss2si64:
18736 case X86::BI__builtin_ia32_cvtsd2si64:
18737 case X86::BI__builtin_ia32_cvttss2si64:
18738 case X86::BI__builtin_ia32_cvttsd2si64: {
18743 assert(ArgVal.
isVector() &&
"Expected a vector argument");
18745 unsigned BitWidth = Info.Ctx.getIntWidth(E->
getType());
18748 llvm::APSInt IntResult(BitWidth,
isUnsigned);
18749 bool IsExact =
false;
18752 FloatElem.convertToInteger(IntResult, llvm::APFloat::rmTowardZero,
18757 return Success(IntResult, E);
18759 case X86::BI__builtin_ia32_vpshufbitqmb128_mask:
18760 case X86::BI__builtin_ia32_vpshufbitqmb256_mask:
18761 case X86::BI__builtin_ia32_vpshufbitqmb512_mask: {
18774 unsigned NumBytesInQWord = 8;
18775 unsigned NumBitsInByte = 8;
18777 unsigned NumQWords = NumBytes / NumBytesInQWord;
18778 unsigned RetWidth = ZeroMask.getBitWidth();
18779 APSInt RetMask(llvm::APInt(RetWidth, 0),
true);
18781 for (
unsigned QWordId = 0; QWordId != NumQWords; ++QWordId) {
18782 APInt SourceQWord(64, 0);
18783 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
18787 SourceQWord.insertBits(
APInt(8, Byte & 0xFF), ByteIdx * NumBitsInByte);
18790 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
18791 unsigned SelIdx = QWordId * NumBytesInQWord + ByteIdx;
18794 if (ZeroMask[SelIdx]) {
18795 RetMask.setBitVal(SelIdx, SourceQWord[M]);
18807 const LValue &LV) {
18810 if (!LV.getLValueBase())
18815 if (!LV.getLValueDesignator().Invalid &&
18816 !LV.getLValueDesignator().isOnePastTheEnd())
18826 if (LV.getLValueDesignator().Invalid)
18832 return LV.getLValueOffset() == Size;
18842class DataRecursiveIntBinOpEvaluator {
18843 struct EvalResult {
18845 bool Failed =
false;
18847 EvalResult() =
default;
18849 void swap(EvalResult &RHS) {
18851 Failed = RHS.Failed;
18852 RHS.Failed =
false;
18858 EvalResult LHSResult;
18859 enum { AnyExprKind, BinOpKind, BinOpVisitedLHSKind }
Kind;
18862 Job(Job &&) =
default;
18864 void startSpeculativeEval(EvalInfo &Info) {
18865 SpecEvalRAII = SpeculativeEvaluationRAII(Info);
18869 SpeculativeEvaluationRAII SpecEvalRAII;
18872 SmallVector<Job, 16> Queue;
18874 IntExprEvaluator &IntEval;
18879 DataRecursiveIntBinOpEvaluator(IntExprEvaluator &IntEval,
APValue &
Result)
18880 : IntEval(IntEval), Info(IntEval.getEvalInfo()), FinalResult(
Result) { }
18886 static bool shouldEnqueue(
const BinaryOperator *E) {
18893 bool Traverse(
const BinaryOperator *E) {
18895 EvalResult PrevResult;
18896 while (!Queue.empty())
18897 process(PrevResult);
18899 if (PrevResult.Failed)
return false;
18901 FinalResult.
swap(PrevResult.Val);
18912 bool Error(
const Expr *E) {
18913 return IntEval.Error(E);
18916 return IntEval.Error(E, D);
18919 OptionalDiagnostic CCEDiag(
const Expr *E,
diag::kind D) {
18920 return Info.CCEDiag(E, D);
18924 bool VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
18925 bool &SuppressRHSDiags);
18927 bool VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
18930 void EvaluateExpr(
const Expr *E, EvalResult &
Result) {
18936 void process(EvalResult &
Result);
18938 void enqueue(
const Expr *E) {
18940 Queue.resize(Queue.size()+1);
18941 Queue.back().E = E;
18942 Queue.back().Kind = Job::AnyExprKind;
18948bool DataRecursiveIntBinOpEvaluator::
18949 VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
18950 bool &SuppressRHSDiags) {
18953 if (LHSResult.Failed)
18954 return Info.noteSideEffect();
18963 if (LHSAsBool == (E->
getOpcode() == BO_LOr)) {
18964 Success(LHSAsBool, E, LHSResult.Val);
18968 LHSResult.Failed =
true;
18972 if (!Info.noteSideEffect())
18978 SuppressRHSDiags =
true;
18987 if (LHSResult.Failed && !Info.noteFailure())
18998 assert(!LVal.
hasLValuePath() &&
"have designator for integer lvalue");
19000 uint64_t Offset64 = Offset.getQuantity();
19001 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
19003 : Offset64 + Index64);
19006bool DataRecursiveIntBinOpEvaluator::
19007 VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
19010 if (RHSResult.Failed)
19017 bool lhsResult, rhsResult;
19032 if (rhsResult == (E->
getOpcode() == BO_LOr))
19043 if (LHSResult.Failed || RHSResult.Failed)
19046 const APValue &LHSVal = LHSResult.Val;
19047 const APValue &RHSVal = RHSResult.Val;
19071 if (!LHSExpr || !RHSExpr)
19073 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
19074 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
19075 if (!LHSAddrExpr || !RHSAddrExpr)
19100void DataRecursiveIntBinOpEvaluator::process(EvalResult &
Result) {
19101 Job &job = Queue.back();
19103 switch (job.Kind) {
19104 case Job::AnyExprKind: {
19105 if (
const BinaryOperator *Bop = dyn_cast<BinaryOperator>(job.E)) {
19106 if (shouldEnqueue(Bop)) {
19107 job.Kind = Job::BinOpKind;
19108 enqueue(Bop->getLHS());
19113 EvaluateExpr(job.E,
Result);
19118 case Job::BinOpKind: {
19120 bool SuppressRHSDiags =
false;
19121 if (!VisitBinOpLHSOnly(
Result, Bop, SuppressRHSDiags)) {
19125 if (SuppressRHSDiags)
19126 job.startSpeculativeEval(Info);
19127 job.LHSResult.swap(
Result);
19128 job.Kind = Job::BinOpVisitedLHSKind;
19133 case Job::BinOpVisitedLHSKind: {
19137 Result.Failed = !VisitBinOp(job.LHSResult, RHS, Bop,
Result.Val);
19143 llvm_unreachable(
"Invalid Job::Kind!");
19147enum class CmpResult {
19156template <
class SuccessCB,
class AfterCB>
19159 SuccessCB &&
Success, AfterCB &&DoAfter) {
19164 "unsupported binary expression evaluation");
19166 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
19180 if (!LHSOK && !Info.noteFailure())
19185 return Success(CmpResult::Less, E);
19187 return Success(CmpResult::Greater, E);
19188 return Success(CmpResult::Equal, E);
19192 APFixedPoint LHSFX(Info.Ctx.getFixedPointSemantics(LHSTy));
19193 APFixedPoint RHSFX(Info.Ctx.getFixedPointSemantics(RHSTy));
19196 if (!LHSOK && !Info.noteFailure())
19201 return Success(CmpResult::Less, E);
19203 return Success(CmpResult::Greater, E);
19204 return Success(CmpResult::Equal, E);
19208 ComplexValue LHS, RHS;
19217 LHS.makeComplexFloat();
19218 LHS.FloatImag = APFloat(LHS.FloatReal.getSemantics());
19223 if (!LHSOK && !Info.noteFailure())
19229 RHS.makeComplexFloat();
19230 RHS.FloatImag = APFloat(RHS.FloatReal.getSemantics());
19234 if (LHS.isComplexFloat()) {
19235 APFloat::cmpResult CR_r =
19236 LHS.getComplexFloatReal().compare(RHS.getComplexFloatReal());
19237 APFloat::cmpResult CR_i =
19238 LHS.getComplexFloatImag().compare(RHS.getComplexFloatImag());
19239 bool IsEqual = CR_r == APFloat::cmpEqual && CR_i == APFloat::cmpEqual;
19240 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal, E);
19242 assert(IsEquality &&
"invalid complex comparison");
19243 bool IsEqual = LHS.getComplexIntReal() == RHS.getComplexIntReal() &&
19244 LHS.getComplexIntImag() == RHS.getComplexIntImag();
19245 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal, E);
19251 APFloat RHS(0.0), LHS(0.0);
19254 if (!LHSOK && !Info.noteFailure())
19261 llvm::APFloatBase::cmpResult APFloatCmpResult = LHS.compare(RHS);
19262 if (!Info.InConstantContext &&
19263 APFloatCmpResult == APFloat::cmpUnordered &&
19266 Info.FFDiag(E, diag::note_constexpr_float_arithmetic_strict);
19269 auto GetCmpRes = [&]() {
19270 switch (APFloatCmpResult) {
19271 case APFloat::cmpEqual:
19272 return CmpResult::Equal;
19273 case APFloat::cmpLessThan:
19274 return CmpResult::Less;
19275 case APFloat::cmpGreaterThan:
19276 return CmpResult::Greater;
19277 case APFloat::cmpUnordered:
19278 return CmpResult::Unordered;
19280 llvm_unreachable(
"Unrecognised APFloat::cmpResult enum");
19282 return Success(GetCmpRes(), E);
19286 LValue LHSValue, RHSValue;
19289 if (!LHSOK && !Info.noteFailure())
19300 if (Info.checkingPotentialConstantExpression() &&
19301 (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown))
19303 auto DiagComparison = [&] (
unsigned DiagID,
bool Reversed =
false) {
19304 std::string LHS = LHSValue.toString(Info.Ctx, E->
getLHS()->
getType());
19305 std::string RHS = RHSValue.toString(Info.Ctx, E->
getRHS()->
getType());
19306 Info.FFDiag(E, DiagID)
19313 return DiagComparison(
19314 diag::note_constexpr_pointer_comparison_unspecified);
19320 if ((!LHSValue.Base && !LHSValue.Offset.
isZero()) ||
19321 (!RHSValue.Base && !RHSValue.Offset.
isZero()))
19322 return DiagComparison(diag::note_constexpr_pointer_constant_comparison,
19336 return DiagComparison(diag::note_constexpr_literal_comparison);
19338 return DiagComparison(diag::note_constexpr_opaque_call_comparison,
19343 return DiagComparison(diag::note_constexpr_pointer_weak_comparison,
19347 if (LHSValue.Base && LHSValue.Offset.
isZero() &&
19349 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
19351 if (RHSValue.Base && RHSValue.Offset.
isZero() &&
19353 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
19359 return DiagComparison(
19360 diag::note_constexpr_pointer_comparison_zero_sized);
19361 if (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown)
19362 return DiagComparison(
19363 diag::note_constexpr_pointer_comparison_unspecified);
19365 return Success(CmpResult::Unequal, E);
19368 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
19369 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
19371 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
19372 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
19382 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid && IsRelational) {
19383 bool WasArrayIndex;
19386 :
getType(LHSValue.Base).getNonReferenceType(),
19387 LHSDesignator, RHSDesignator, WasArrayIndex);
19394 if (!WasArrayIndex && Mismatch < LHSDesignator.Entries.size() &&
19395 Mismatch < RHSDesignator.Entries.size()) {
19396 const FieldDecl *LF = getAsField(LHSDesignator.Entries[Mismatch]);
19397 const FieldDecl *RF = getAsField(RHSDesignator.Entries[Mismatch]);
19399 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_classes);
19401 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
19402 << getAsBaseClass(LHSDesignator.Entries[Mismatch])
19405 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
19406 << getAsBaseClass(RHSDesignator.Entries[Mismatch])
19411 diag::note_constexpr_pointer_comparison_differing_access)
19419 unsigned PtrSize = Info.Ctx.getTypeSize(LHSTy);
19422 assert(PtrSize <= 64 &&
"Unexpected pointer width");
19423 uint64_t Mask = ~0ULL >> (64 - PtrSize);
19424 CompareLHS &= Mask;
19425 CompareRHS &= Mask;
19430 if (!LHSValue.Base.
isNull() && IsRelational) {
19434 CharUnits Size = Info.Ctx.getTypeSizeInChars(BaseTy);
19435 uint64_t OffsetLimit = Size.getQuantity();
19436 if (CompareLHS > OffsetLimit || CompareRHS > OffsetLimit)
19440 if (CompareLHS < CompareRHS)
19441 return Success(CmpResult::Less, E);
19442 if (CompareLHS > CompareRHS)
19443 return Success(CmpResult::Greater, E);
19444 return Success(CmpResult::Equal, E);
19448 assert(IsEquality &&
"unexpected member pointer operation");
19451 MemberPtr LHSValue, RHSValue;
19454 if (!LHSOK && !Info.noteFailure())
19462 if (LHSValue.getDecl() && LHSValue.getDecl()->isWeak()) {
19463 Info.FFDiag(E, diag::note_constexpr_mem_pointer_weak_comparison)
19464 << LHSValue.getDecl();
19467 if (RHSValue.getDecl() && RHSValue.getDecl()->isWeak()) {
19468 Info.FFDiag(E, diag::note_constexpr_mem_pointer_weak_comparison)
19469 << RHSValue.getDecl();
19476 if (!LHSValue.getDecl() || !RHSValue.getDecl()) {
19477 bool Equal = !LHSValue.getDecl() && !RHSValue.getDecl();
19478 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal, E);
19483 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(LHSValue.getDecl()))
19484 if (MD->isVirtual())
19485 Info.CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
19486 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(RHSValue.getDecl()))
19487 if (MD->isVirtual())
19488 Info.CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
19494 bool Equal = LHSValue == RHSValue;
19495 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal, E);
19500 assert(RHSTy->
isNullPtrType() &&
"missing pointer conversion");
19508 return Success(CmpResult::Equal, E);
19514bool RecordExprEvaluator::VisitBinCmp(
const BinaryOperator *E) {
19518 auto OnSuccess = [&](CmpResult CR,
const BinaryOperator *E) {
19521 case CmpResult::Unequal:
19522 llvm_unreachable(
"should never produce Unequal for three-way comparison");
19523 case CmpResult::Less:
19524 CCR = ComparisonCategoryResult::Less;
19526 case CmpResult::Equal:
19527 CCR = ComparisonCategoryResult::Equal;
19529 case CmpResult::Greater:
19530 CCR = ComparisonCategoryResult::Greater;
19532 case CmpResult::Unordered:
19533 CCR = ComparisonCategoryResult::Unordered;
19538 const ComparisonCategoryInfo &CmpInfo =
19539 Info.Ctx.CompCategories.getInfoForType(E->
getType());
19547 ConstantExprKind::Normal);
19550 return ExprEvaluatorBaseTy::VisitBinCmp(E);
19554bool RecordExprEvaluator::VisitCXXParenListInitExpr(
19555 const CXXParenListInitExpr *E) {
19556 return VisitCXXParenListOrInitListExpr(E, E->
getInitExprs());
19559bool IntExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
19564 if (!Info.noteFailure())
19568 if (DataRecursiveIntBinOpEvaluator::shouldEnqueue(E))
19569 return DataRecursiveIntBinOpEvaluator(*
this,
Result).Traverse(E);
19573 "DataRecursiveIntBinOpEvaluator should have handled integral types");
19578 auto OnSuccess = [&](CmpResult CR,
const BinaryOperator *E) {
19579 assert((CR != CmpResult::Unequal || E->
isEqualityOp()) &&
19580 "should only produce Unequal for equality comparisons");
19581 bool IsEqual = CR == CmpResult::Equal,
19582 IsLess = CR == CmpResult::Less,
19583 IsGreater = CR == CmpResult::Greater;
19587 llvm_unreachable(
"unsupported binary operator");
19590 return Success(IsEqual == (Op == BO_EQ), E);
19594 return Success(IsGreater, E);
19596 return Success(IsEqual || IsLess, E);
19598 return Success(IsEqual || IsGreater, E);
19602 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
19611 LValue LHSValue, RHSValue;
19614 if (!LHSOK && !Info.noteFailure())
19623 if (Info.checkingPotentialConstantExpression() &&
19624 (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown))
19627 const Expr *LHSExpr = LHSValue.Base.
dyn_cast<
const Expr *>();
19628 const Expr *RHSExpr = RHSValue.Base.
dyn_cast<
const Expr *>();
19630 auto DiagArith = [&](
unsigned DiagID) {
19631 std::string LHS = LHSValue.toString(Info.Ctx, E->
getLHS()->
getType());
19632 std::string RHS = RHSValue.toString(Info.Ctx, E->
getRHS()->
getType());
19633 Info.FFDiag(E, DiagID) << LHS << RHS;
19634 if (LHSExpr && LHSExpr == RHSExpr)
19636 diag::note_constexpr_repeated_literal_eval)
19641 if (!LHSExpr || !RHSExpr)
19642 return DiagArith(diag::note_constexpr_pointer_arith_unspecified);
19645 return DiagArith(diag::note_constexpr_literal_arith);
19647 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
19648 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
19649 if (!LHSAddrExpr || !RHSAddrExpr)
19657 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
19658 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
19660 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
19661 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
19667 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid &&
19670 Info.CCEDiag(E, diag::note_constexpr_pointer_subtraction_not_same_array);
19675 CharUnits ElementSize;
19682 if (ElementSize.
isZero()) {
19683 Info.FFDiag(E, diag::note_constexpr_pointer_subtraction_zero_size)
19700 APSInt TrueResult = (LHS - RHS) / ElemSize;
19703 if (
Result.extend(65) != TrueResult &&
19709 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
19714bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr(
19715 const UnaryExprOrTypeTraitExpr *E) {
19717 case UETT_PreferredAlignOf:
19718 case UETT_AlignOf: {
19727 case UETT_PtrAuthTypeDiscriminator: {
19733 case UETT_VecStep: {
19737 unsigned n = Ty->
castAs<VectorType>()->getNumElements();
19749 case UETT_DataSizeOf:
19750 case UETT_SizeOf: {
19754 if (
const ReferenceType *Ref = SrcTy->
getAs<ReferenceType>())
19765 case UETT_OpenMPRequiredSimdAlign:
19768 Info.Ctx.toCharUnitsFromBits(
19772 case UETT_VectorElements: {
19776 if (
const auto *VT = Ty->
getAs<VectorType>())
19780 if (Info.InConstantContext)
19781 Info.CCEDiag(E, diag::note_constexpr_non_const_vectorelements)
19786 case UETT_CountOf: {
19792 if (
const auto *CAT =
19802 const auto *VAT = Info.Ctx.getAsVariableArrayType(Ty);
19804 if (VAT->getElementType()->isArrayType()) {
19807 if (!VAT->getSizeExpr()) {
19812 std::optional<APSInt> Res =
19813 VAT->getSizeExpr()->getIntegerConstantExpr(Info.Ctx);
19818 static_cast<unsigned>(Info.Ctx.getTypeSize(Info.Ctx.getSizeType())),
19819 Res->getZExtValue()};
19831 llvm_unreachable(
"unknown expr/type trait");
19834bool IntExprEvaluator::VisitOffsetOfExpr(
const OffsetOfExpr *OOE) {
19835 Info.Ctx.recordOffsetOfEvaluation(OOE);
19841 for (
unsigned i = 0; i != n; ++i) {
19849 const ArrayType *AT = Info.Ctx.getAsArrayType(CurrentType);
19853 CharUnits ElementSize = Info.Ctx.getTypeSizeInChars(CurrentType);
19856 if (IdxResult.isNegative() || IdxResult.getActiveBits() > 63)
19858 int64_t IdxVal = IdxResult.getExtValue();
19861 ElemSize > std::numeric_limits<int64_t>::max() / IdxVal)
19862 return Error(OOE, diag::note_constexpr_offsetof_overflow);
19863 int64_t Offset = IdxVal * ElemSize;
19864 if (
Result.getQuantity() > std::numeric_limits<int64_t>::max() - Offset)
19865 return Error(OOE, diag::note_constexpr_offsetof_overflow);
19871 FieldDecl *MemberDecl = ON.
getField();
19876 const ASTRecordLayout &RL = Info.Ctx.getASTRecordLayout(RD);
19878 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
19885 llvm_unreachable(
"dependent __builtin_offsetof");
19888 CXXBaseSpecifier *BaseSpec = ON.
getBase();
19897 const ASTRecordLayout &RL = Info.Ctx.getASTRecordLayout(RD);
19900 CurrentType = BaseSpec->
getType();
19914bool IntExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
19934 if (Info.checkingForUndefinedBehavior())
19935 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
19936 diag::warn_integer_constant_overflow)
19964bool IntExprEvaluator::VisitCastExpr(
const CastExpr *E) {
19966 QualType DestType = E->
getType();
19967 QualType SrcType = SubExpr->
getType();
19970 case CK_BaseToDerived:
19971 case CK_DerivedToBase:
19972 case CK_UncheckedDerivedToBase:
19975 case CK_ArrayToPointerDecay:
19976 case CK_FunctionToPointerDecay:
19977 case CK_NullToPointer:
19978 case CK_NullToMemberPointer:
19979 case CK_BaseToDerivedMemberPointer:
19980 case CK_DerivedToBaseMemberPointer:
19981 case CK_ReinterpretMemberPointer:
19982 case CK_ConstructorConversion:
19983 case CK_IntegralToPointer:
19985 case CK_VectorSplat:
19986 case CK_IntegralToFloating:
19987 case CK_FloatingCast:
19988 case CK_CPointerToObjCPointerCast:
19989 case CK_BlockPointerToObjCPointerCast:
19990 case CK_AnyPointerToBlockPointerCast:
19991 case CK_ObjCObjectLValueCast:
19992 case CK_FloatingRealToComplex:
19993 case CK_FloatingComplexToReal:
19994 case CK_FloatingComplexCast:
19995 case CK_FloatingComplexToIntegralComplex:
19996 case CK_IntegralRealToComplex:
19997 case CK_IntegralComplexCast:
19998 case CK_IntegralComplexToFloatingComplex:
19999 case CK_BuiltinFnToFnPtr:
20000 case CK_ZeroToOCLOpaqueType:
20001 case CK_NonAtomicToAtomic:
20002 case CK_AddressSpaceConversion:
20003 case CK_IntToOCLSampler:
20004 case CK_FloatingToFixedPoint:
20005 case CK_FixedPointToFloating:
20006 case CK_FixedPointCast:
20007 case CK_IntegralToFixedPoint:
20008 case CK_MatrixCast:
20009 case CK_HLSLAggregateSplatCast:
20010 llvm_unreachable(
"invalid cast kind for integral value");
20014 case CK_LValueBitCast:
20015 case CK_ARCProduceObject:
20016 case CK_ARCConsumeObject:
20017 case CK_ARCReclaimReturnedObject:
20018 case CK_ARCExtendBlockObject:
20019 case CK_CopyAndAutoreleaseBlockObject:
20022 case CK_UserDefinedConversion:
20023 case CK_LValueToRValue:
20024 case CK_AtomicToNonAtomic:
20026 case CK_LValueToRValueBitCast:
20027 case CK_HLSLArrayRValue:
20028 return ExprEvaluatorBaseTy::VisitCastExpr(E);
20030 case CK_MemberPointerToBoolean:
20031 case CK_PointerToBoolean:
20032 case CK_IntegralToBoolean:
20033 case CK_FloatingToBoolean:
20034 case CK_BooleanToSignedIntegral:
20035 case CK_FloatingComplexToBoolean:
20036 case CK_IntegralComplexToBoolean: {
20041 if (BoolResult && E->
getCastKind() == CK_BooleanToSignedIntegral)
20043 return Success(IntResult, E);
20046 case CK_FixedPointToIntegral: {
20047 APFixedPoint Src(Info.Ctx.getFixedPointSemantics(SrcType));
20051 llvm::APSInt
Result = Src.convertToInt(
20052 Info.Ctx.getIntWidth(DestType),
20059 case CK_FixedPointToBoolean: {
20062 if (!
Evaluate(Val, Info, SubExpr))
20067 case CK_IntegralCast: {
20068 if (!Visit(SubExpr))
20078 if (
Result.isAddrLabelDiff()) {
20079 unsigned DestBits = Info.Ctx.getTypeSize(DestType);
20080 return DestBits >= 32 && DestBits <= Info.Ctx.getTypeSize(SrcType);
20083 return Info.Ctx.getTypeSize(DestType) == Info.Ctx.getTypeSize(SrcType);
20086 if (Info.Ctx.getLangOpts().CPlusPlus && DestType->
isEnumeralType()) {
20098 if (!ED->isFixed()) {
20102 ED->getValueRange(
Max,
Min);
20105 if (ED->getNumNegativeBits() &&
20106 (
Max.slt(
Result.getInt().getSExtValue()) ||
20107 Min.sgt(
Result.getInt().getSExtValue())))
20108 Info.CCEDiag(E, diag::note_constexpr_unscoped_enum_out_of_range)
20109 << llvm::toString(
Result.getInt(), 10) <<
Min.getSExtValue()
20110 <<
Max.getSExtValue() << ED;
20111 else if (!ED->getNumNegativeBits() &&
20112 Max.ult(
Result.getInt().getZExtValue()))
20113 Info.CCEDiag(E, diag::note_constexpr_unscoped_enum_out_of_range)
20114 << llvm::toString(
Result.getInt(), 10) <<
Min.getZExtValue()
20115 <<
Max.getZExtValue() << ED;
20123 case CK_PointerToIntegral: {
20124 CCEDiag(E, diag::note_constexpr_invalid_cast_ptrtoint)
20125 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
20132 if (LV.getLValueBase()) {
20133 CCEDiag(E, diag::note_constexpr_has_lvalue) << E->
getSourceRange();
20138 if (Info.Ctx.getTypeSize(DestType) != Info.Ctx.getTypeSize(SrcType))
20141 LV.Designator.setInvalid();
20149 if (!
V.toIntegralConstant(AsInt, SrcType, Info.Ctx))
20150 llvm_unreachable(
"Can't cast this!");
20155 case CK_IntegralComplexToReal: {
20159 return Success(
C.getComplexIntReal(), E);
20162 case CK_FloatingToIntegral: {
20172 case CK_HLSLVectorTruncation: {
20178 case CK_HLSLMatrixTruncation: {
20184 case CK_HLSLElementwiseCast: {
20197 return Success(ResultVal, E);
20201 llvm_unreachable(
"unknown cast resulting in integral value");
20204bool IntExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
20209 if (!LV.isComplexInt())
20211 return Success(LV.getComplexIntReal(), E);
20217bool IntExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
20222 if (!LV.isComplexInt())
20224 return Success(LV.getComplexIntImag(), E);
20231bool IntExprEvaluator::VisitSizeOfPackExpr(
const SizeOfPackExpr *E) {
20235bool IntExprEvaluator::VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E) {
20239bool IntExprEvaluator::VisitConceptSpecializationExpr(
20240 const ConceptSpecializationExpr *E) {
20244bool IntExprEvaluator::VisitRequiresExpr(
const RequiresExpr *E) {
20248bool FixedPointExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
20258 if (!
Result.isFixedPoint())
20261 APFixedPoint Negated =
Result.getFixedPoint().negate(&Overflowed);
20275bool FixedPointExprEvaluator::VisitCastExpr(
const CastExpr *E) {
20277 QualType DestType = E->
getType();
20279 "Expected destination type to be a fixed point type");
20280 auto DestFXSema = Info.Ctx.getFixedPointSemantics(DestType);
20283 case CK_FixedPointCast: {
20284 APFixedPoint Src(Info.Ctx.getFixedPointSemantics(SubExpr->
getType()));
20288 APFixedPoint
Result = Src.convert(DestFXSema, &Overflowed);
20290 if (Info.checkingForUndefinedBehavior())
20291 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
20292 diag::warn_fixedpoint_constant_overflow)
20299 case CK_IntegralToFixedPoint: {
20305 APFixedPoint IntResult = APFixedPoint::getFromIntValue(
20306 Src, Info.Ctx.getFixedPointSemantics(DestType), &Overflowed);
20309 if (Info.checkingForUndefinedBehavior())
20310 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
20311 diag::warn_fixedpoint_constant_overflow)
20312 << IntResult.toString() << E->
getType();
20317 return Success(IntResult, E);
20319 case CK_FloatingToFixedPoint: {
20325 APFixedPoint
Result = APFixedPoint::getFromFloatValue(
20326 Src, Info.Ctx.getFixedPointSemantics(DestType), &Overflowed);
20329 if (Info.checkingForUndefinedBehavior())
20330 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
20331 diag::warn_fixedpoint_constant_overflow)
20340 case CK_LValueToRValue:
20341 return ExprEvaluatorBaseTy::VisitCastExpr(E);
20347bool FixedPointExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
20349 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
20351 const Expr *LHS = E->
getLHS();
20352 const Expr *RHS = E->
getRHS();
20354 Info.Ctx.getFixedPointSemantics(E->
getType());
20356 APFixedPoint LHSFX(Info.Ctx.getFixedPointSemantics(LHS->
getType()));
20359 APFixedPoint RHSFX(Info.Ctx.getFixedPointSemantics(RHS->
getType()));
20363 bool OpOverflow =
false, ConversionOverflow =
false;
20364 APFixedPoint
Result(LHSFX.getSemantics());
20367 Result = LHSFX.add(RHSFX, &OpOverflow)
20368 .convert(ResultFXSema, &ConversionOverflow);
20372 Result = LHSFX.sub(RHSFX, &OpOverflow)
20373 .convert(ResultFXSema, &ConversionOverflow);
20377 Result = LHSFX.mul(RHSFX, &OpOverflow)
20378 .convert(ResultFXSema, &ConversionOverflow);
20382 if (RHSFX.getValue() == 0) {
20383 Info.FFDiag(E, diag::note_expr_divide_by_zero);
20386 Result = LHSFX.div(RHSFX, &OpOverflow)
20387 .convert(ResultFXSema, &ConversionOverflow);
20393 llvm::APSInt RHSVal = RHSFX.getValue();
20396 LHSSema.getWidth() - (unsigned)LHSSema.hasUnsignedPadding();
20397 unsigned Amt = RHSVal.getLimitedValue(ShiftBW - 1);
20401 if (RHSVal.isNegative())
20402 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHSVal;
20403 else if (Amt != RHSVal)
20404 Info.CCEDiag(E, diag::note_constexpr_large_shift)
20405 << RHSVal << E->
getType() << ShiftBW;
20408 Result = LHSFX.shl(Amt, &OpOverflow);
20410 Result = LHSFX.shr(Amt, &OpOverflow);
20416 if (OpOverflow || ConversionOverflow) {
20417 if (Info.checkingForUndefinedBehavior())
20418 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
20419 diag::warn_fixedpoint_constant_overflow)
20432class FloatExprEvaluator
20433 :
public ExprEvaluatorBase<FloatExprEvaluator> {
20436 FloatExprEvaluator(EvalInfo &info, APFloat &result)
20437 : ExprEvaluatorBaseTy(
info),
Result(result) {}
20444 bool ZeroInitialization(
const Expr *E) {
20445 Result = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(E->
getType()));
20449 bool VisitCallExpr(
const CallExpr *E);
20451 bool VisitUnaryOperator(
const UnaryOperator *E);
20452 bool VisitBinaryOperator(
const BinaryOperator *E);
20453 bool VisitFloatingLiteral(
const FloatingLiteral *E);
20454 bool VisitCastExpr(
const CastExpr *E);
20456 bool VisitUnaryReal(
const UnaryOperator *E);
20457 bool VisitUnaryImag(
const UnaryOperator *E);
20466 return FloatExprEvaluator(Info,
Result).Visit(E);
20473 llvm::APFloat &
Result) {
20478 const llvm::fltSemantics &Sem = Context.getFloatTypeSemantics(ResultTy);
20484 fill = llvm::APInt(32, 0);
20485 else if (S->
getString().getAsInteger(0, fill))
20488 if (Context.getTargetInfo().isNan2008()) {
20490 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
20492 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
20500 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
20502 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
20508bool FloatExprEvaluator::VisitCallExpr(
const CallExpr *E) {
20509 if (!IsConstantEvaluatedBuiltinCall(E))
20510 return ExprEvaluatorBaseTy::VisitCallExpr(E);
20514 switch (BuiltinOp) {
20518 case Builtin::BI__builtin_huge_val:
20519 case Builtin::BI__builtin_huge_valf:
20520 case Builtin::BI__builtin_huge_vall:
20521 case Builtin::BI__builtin_huge_valf16:
20522 case Builtin::BI__builtin_huge_valf128:
20523 case Builtin::BI__builtin_inf:
20524 case Builtin::BI__builtin_inff:
20525 case Builtin::BI__builtin_infl:
20526 case Builtin::BI__builtin_inff16:
20527 case Builtin::BI__builtin_inff128: {
20528 const llvm::fltSemantics &Sem =
20529 Info.Ctx.getFloatTypeSemantics(E->
getType());
20530 Result = llvm::APFloat::getInf(Sem);
20534 case Builtin::BI__builtin_nans:
20535 case Builtin::BI__builtin_nansf:
20536 case Builtin::BI__builtin_nansl:
20537 case Builtin::BI__builtin_nansf16:
20538 case Builtin::BI__builtin_nansf128:
20544 case Builtin::BI__builtin_nan:
20545 case Builtin::BI__builtin_nanf:
20546 case Builtin::BI__builtin_nanl:
20547 case Builtin::BI__builtin_nanf16:
20548 case Builtin::BI__builtin_nanf128:
20556 case Builtin::BI__builtin_elementwise_abs:
20557 case Builtin::BI__builtin_fabs:
20558 case Builtin::BI__builtin_fabsf:
20559 case Builtin::BI__builtin_fabsl:
20560 case Builtin::BI__builtin_fabsf128:
20569 if (
Result.isNegative())
20573 case Builtin::BI__arithmetic_fence:
20580 case Builtin::BI__builtin_copysign:
20581 case Builtin::BI__builtin_copysignf:
20582 case Builtin::BI__builtin_copysignl:
20583 case Builtin::BI__builtin_copysignf128: {
20592 case Builtin::BI__builtin_fmax:
20593 case Builtin::BI__builtin_fmaxf:
20594 case Builtin::BI__builtin_fmaxl:
20595 case Builtin::BI__builtin_fmaxf16:
20596 case Builtin::BI__builtin_fmaxf128: {
20605 case Builtin::BI__builtin_fmin:
20606 case Builtin::BI__builtin_fminf:
20607 case Builtin::BI__builtin_fminl:
20608 case Builtin::BI__builtin_fminf16:
20609 case Builtin::BI__builtin_fminf128: {
20618 case Builtin::BI__builtin_fmaximum_num:
20619 case Builtin::BI__builtin_fmaximum_numf:
20620 case Builtin::BI__builtin_fmaximum_numl:
20621 case Builtin::BI__builtin_fmaximum_numf16:
20622 case Builtin::BI__builtin_fmaximum_numf128: {
20631 case Builtin::BI__builtin_fminimum_num:
20632 case Builtin::BI__builtin_fminimum_numf:
20633 case Builtin::BI__builtin_fminimum_numl:
20634 case Builtin::BI__builtin_fminimum_numf16:
20635 case Builtin::BI__builtin_fminimum_numf128: {
20644 case Builtin::BI__builtin_elementwise_fma: {
20649 APFloat SourceY(0.), SourceZ(0.);
20655 (void)
Result.fusedMultiplyAdd(SourceY, SourceZ, RM);
20659 case clang::X86::BI__builtin_ia32_vec_ext_v4sf: {
20666 unsigned Idx =
static_cast<unsigned>(IdxAPS.getZExtValue() & (N - 1));
20672bool FloatExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
20684bool FloatExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
20694 const llvm::fltSemantics &Sem = Info.Ctx.getFloatTypeSemantics(E->
getType());
20695 Result = llvm::APFloat::getZero(Sem);
20699bool FloatExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
20701 default:
return Error(E);
20715bool FloatExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
20717 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
20721 if (!LHSOK && !Info.noteFailure())
20727bool FloatExprEvaluator::VisitFloatingLiteral(
const FloatingLiteral *E) {
20732bool FloatExprEvaluator::VisitCastExpr(
const CastExpr *E) {
20737 return ExprEvaluatorBaseTy::VisitCastExpr(E);
20739 case CK_HLSLAggregateSplatCast:
20740 llvm_unreachable(
"invalid cast kind for floating value");
20742 case CK_IntegralToFloating: {
20745 Info.Ctx.getLangOpts());
20751 case CK_FixedPointToFloating: {
20752 APFixedPoint FixResult(Info.Ctx.getFixedPointSemantics(SubExpr->
getType()));
20756 FixResult.convertToFloat(Info.Ctx.getFloatTypeSemantics(E->
getType()));
20760 case CK_FloatingCast: {
20761 if (!Visit(SubExpr))
20767 case CK_FloatingComplexToReal: {
20771 Result =
V.getComplexFloatReal();
20774 case CK_HLSLVectorTruncation: {
20780 case CK_HLSLMatrixTruncation: {
20786 case CK_HLSLElementwiseCast: {
20801 return Success(ResultVal, E);
20811class ComplexExprEvaluator
20812 :
public ExprEvaluatorBase<ComplexExprEvaluator> {
20816 ComplexExprEvaluator(EvalInfo &info, ComplexValue &
Result)
20824 bool ZeroInitialization(
const Expr *E);
20830 bool VisitImaginaryLiteral(
const ImaginaryLiteral *E);
20831 bool VisitCastExpr(
const CastExpr *E);
20832 bool VisitBinaryOperator(
const BinaryOperator *E);
20833 bool VisitUnaryOperator(
const UnaryOperator *E);
20834 bool VisitInitListExpr(
const InitListExpr *E);
20835 bool VisitCallExpr(
const CallExpr *E);
20843 return ComplexExprEvaluator(Info,
Result).Visit(E);
20846bool ComplexExprEvaluator::ZeroInitialization(
const Expr *E) {
20847 QualType ElemTy = E->
getType()->
castAs<ComplexType>()->getElementType();
20849 Result.makeComplexFloat();
20850 APFloat Zero = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(ElemTy));
20854 Result.makeComplexInt();
20855 APSInt Zero = Info.Ctx.MakeIntValue(0, ElemTy);
20862bool ComplexExprEvaluator::VisitImaginaryLiteral(
const ImaginaryLiteral *E) {
20866 Result.makeComplexFloat();
20875 "Unexpected imaginary literal.");
20877 Result.makeComplexInt();
20882 Result.IntReal =
APSInt(Imag.getBitWidth(), !Imag.isSigned());
20887bool ComplexExprEvaluator::VisitCastExpr(
const CastExpr *E) {
20891 case CK_BaseToDerived:
20892 case CK_DerivedToBase:
20893 case CK_UncheckedDerivedToBase:
20896 case CK_ArrayToPointerDecay:
20897 case CK_FunctionToPointerDecay:
20898 case CK_NullToPointer:
20899 case CK_NullToMemberPointer:
20900 case CK_BaseToDerivedMemberPointer:
20901 case CK_DerivedToBaseMemberPointer:
20902 case CK_MemberPointerToBoolean:
20903 case CK_ReinterpretMemberPointer:
20904 case CK_ConstructorConversion:
20905 case CK_IntegralToPointer:
20906 case CK_PointerToIntegral:
20907 case CK_PointerToBoolean:
20909 case CK_VectorSplat:
20910 case CK_IntegralCast:
20911 case CK_BooleanToSignedIntegral:
20912 case CK_IntegralToBoolean:
20913 case CK_IntegralToFloating:
20914 case CK_FloatingToIntegral:
20915 case CK_FloatingToBoolean:
20916 case CK_FloatingCast:
20917 case CK_CPointerToObjCPointerCast:
20918 case CK_BlockPointerToObjCPointerCast:
20919 case CK_AnyPointerToBlockPointerCast:
20920 case CK_ObjCObjectLValueCast:
20921 case CK_FloatingComplexToReal:
20922 case CK_FloatingComplexToBoolean:
20923 case CK_IntegralComplexToReal:
20924 case CK_IntegralComplexToBoolean:
20925 case CK_ARCProduceObject:
20926 case CK_ARCConsumeObject:
20927 case CK_ARCReclaimReturnedObject:
20928 case CK_ARCExtendBlockObject:
20929 case CK_CopyAndAutoreleaseBlockObject:
20930 case CK_BuiltinFnToFnPtr:
20931 case CK_ZeroToOCLOpaqueType:
20932 case CK_NonAtomicToAtomic:
20933 case CK_AddressSpaceConversion:
20934 case CK_IntToOCLSampler:
20935 case CK_FloatingToFixedPoint:
20936 case CK_FixedPointToFloating:
20937 case CK_FixedPointCast:
20938 case CK_FixedPointToBoolean:
20939 case CK_FixedPointToIntegral:
20940 case CK_IntegralToFixedPoint:
20941 case CK_MatrixCast:
20942 case CK_HLSLVectorTruncation:
20943 case CK_HLSLMatrixTruncation:
20944 case CK_HLSLElementwiseCast:
20945 case CK_HLSLAggregateSplatCast:
20946 llvm_unreachable(
"invalid cast kind for complex value");
20948 case CK_LValueToRValue:
20949 case CK_AtomicToNonAtomic:
20951 case CK_LValueToRValueBitCast:
20952 case CK_HLSLArrayRValue:
20953 return ExprEvaluatorBaseTy::VisitCastExpr(E);
20956 case CK_LValueBitCast:
20957 case CK_UserDefinedConversion:
20960 case CK_FloatingRealToComplex: {
20965 Result.makeComplexFloat();
20970 case CK_FloatingComplexCast: {
20974 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
20982 case CK_FloatingComplexToIntegralComplex: {
20986 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
20989 Result.makeComplexInt();
20996 case CK_IntegralRealToComplex: {
21001 Result.makeComplexInt();
21002 Result.IntImag =
APSInt(Real.getBitWidth(), !Real.isSigned());
21006 case CK_IntegralComplexCast: {
21010 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
21019 case CK_IntegralComplexToFloatingComplex: {
21024 Info.Ctx.getLangOpts());
21025 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
21028 Result.makeComplexFloat();
21030 To,
Result.FloatReal) &&
21036 llvm_unreachable(
"unknown cast resulting in complex value");
21042 0x00, 0x01, 0x8d, 0xf6, 0xcb, 0x52, 0x7b, 0xd1, 0xe8, 0x4f, 0x29, 0xc0,
21043 0xb0, 0xe1, 0xe5, 0xc7, 0x74, 0xb4, 0xaa, 0x4b, 0x99, 0x2b, 0x60, 0x5f,
21044 0x58, 0x3f, 0xfd, 0xcc, 0xff, 0x40, 0xee, 0xb2, 0x3a, 0x6e, 0x5a, 0xf1,
21045 0x55, 0x4d, 0xa8, 0xc9, 0xc1, 0x0a, 0x98, 0x15, 0x30, 0x44, 0xa2, 0xc2,
21046 0x2c, 0x45, 0x92, 0x6c, 0xf3, 0x39, 0x66, 0x42, 0xf2, 0x35, 0x20, 0x6f,
21047 0x77, 0xbb, 0x59, 0x19, 0x1d, 0xfe, 0x37, 0x67, 0x2d, 0x31, 0xf5, 0x69,
21048 0xa7, 0x64, 0xab, 0x13, 0x54, 0x25, 0xe9, 0x09, 0xed, 0x5c, 0x05, 0xca,
21049 0x4c, 0x24, 0x87, 0xbf, 0x18, 0x3e, 0x22, 0xf0, 0x51, 0xec, 0x61, 0x17,
21050 0x16, 0x5e, 0xaf, 0xd3, 0x49, 0xa6, 0x36, 0x43, 0xf4, 0x47, 0x91, 0xdf,
21051 0x33, 0x93, 0x21, 0x3b, 0x79, 0xb7, 0x97, 0x85, 0x10, 0xb5, 0xba, 0x3c,
21052 0xb6, 0x70, 0xd0, 0x06, 0xa1, 0xfa, 0x81, 0x82, 0x83, 0x7e, 0x7f, 0x80,
21053 0x96, 0x73, 0xbe, 0x56, 0x9b, 0x9e, 0x95, 0xd9, 0xf7, 0x02, 0xb9, 0xa4,
21054 0xde, 0x6a, 0x32, 0x6d, 0xd8, 0x8a, 0x84, 0x72, 0x2a, 0x14, 0x9f, 0x88,
21055 0xf9, 0xdc, 0x89, 0x9a, 0xfb, 0x7c, 0x2e, 0xc3, 0x8f, 0xb8, 0x65, 0x48,
21056 0x26, 0xc8, 0x12, 0x4a, 0xce, 0xe7, 0xd2, 0x62, 0x0c, 0xe0, 0x1f, 0xef,
21057 0x11, 0x75, 0x78, 0x71, 0xa5, 0x8e, 0x76, 0x3d, 0xbd, 0xbc, 0x86, 0x57,
21058 0x0b, 0x28, 0x2f, 0xa3, 0xda, 0xd4, 0xe4, 0x0f, 0xa9, 0x27, 0x53, 0x04,
21059 0x1b, 0xfc, 0xac, 0xe6, 0x7a, 0x07, 0xae, 0x63, 0xc5, 0xdb, 0xe2, 0xea,
21060 0x94, 0x8b, 0xc4, 0xd5, 0x9d, 0xf8, 0x90, 0x6b, 0xb1, 0x0d, 0xd6, 0xeb,
21061 0xc6, 0x0e, 0xcf, 0xad, 0x08, 0x4e, 0xd7, 0xe3, 0x5d, 0x50, 0x1e, 0xb3,
21062 0x5b, 0x23, 0x38, 0x34, 0x68, 0x46, 0x03, 0x8c, 0xdd, 0x9c, 0x7d, 0xa0,
21063 0xcd, 0x1a, 0x41, 0x1c};
21065 return GFInv[Byte];
21070 unsigned NumBitsInByte = 8;
21073 for (
uint32_t BitIdx = 0; BitIdx != NumBitsInByte; ++BitIdx) {
21075 AQword.lshr((7 -
static_cast<int32_t>(BitIdx)) * NumBitsInByte)
21082 Product = AByte & XByte;
21087 for (
unsigned PBitIdx = 0; PBitIdx != NumBitsInByte; ++PBitIdx) {
21088 Parity = Parity ^ ((Product >> PBitIdx) & 0x1);
21091 uint8_t Temp = Imm[BitIdx] ? 1 : 0;
21092 RetByte |= (Temp ^ Parity) << BitIdx;
21102 unsigned NumBitsInByte = 8;
21103 for (
unsigned BitIdx = 0; BitIdx != NumBitsInByte; ++BitIdx) {
21104 if ((BByte >> BitIdx) & 0x1) {
21105 TWord = TWord ^ (AByte << BitIdx);
21113 for (
int32_t BitIdx = 14; BitIdx > 7; --BitIdx) {
21114 if ((TWord >> BitIdx) & 0x1) {
21115 TWord = TWord ^ (0x11B << (BitIdx - 8));
21118 return (TWord & 0xFF);
21122 APFloat &ResR, APFloat &ResI) {
21128 APFloat AC = A *
C;
21129 APFloat BD = B * D;
21130 APFloat AD = A * D;
21131 APFloat BC = B *
C;
21134 if (ResR.isNaN() && ResI.isNaN()) {
21135 bool Recalc =
false;
21136 if (A.isInfinity() || B.isInfinity()) {
21137 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
21139 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
21142 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
21144 D = APFloat::copySign(APFloat(D.getSemantics()), D);
21147 if (
C.isInfinity() || D.isInfinity()) {
21148 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
21150 D = APFloat::copySign(APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0),
21153 A = APFloat::copySign(APFloat(A.getSemantics()), A);
21155 B = APFloat::copySign(APFloat(B.getSemantics()), B);
21158 if (!Recalc && (AC.isInfinity() || BD.isInfinity() || AD.isInfinity() ||
21159 BC.isInfinity())) {
21161 A = APFloat::copySign(APFloat(A.getSemantics()), A);
21163 B = APFloat::copySign(APFloat(B.getSemantics()), B);
21165 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
21167 D = APFloat::copySign(APFloat(D.getSemantics()), D);
21171 ResR = APFloat::getInf(A.getSemantics()) * (A *
C - B * D);
21172 ResI = APFloat::getInf(A.getSemantics()) * (A * D + B *
C);
21178 APFloat &ResR, APFloat &ResI) {
21185 APFloat MaxCD = maxnum(
abs(
C),
abs(D));
21186 if (MaxCD.isFinite()) {
21187 DenomLogB =
ilogb(MaxCD);
21188 C =
scalbn(
C, -DenomLogB, APFloat::rmNearestTiesToEven);
21189 D =
scalbn(D, -DenomLogB, APFloat::rmNearestTiesToEven);
21191 APFloat Denom =
C *
C + D * D;
21193 scalbn((A *
C + B * D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
21195 scalbn((B *
C - A * D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
21196 if (ResR.isNaN() && ResI.isNaN()) {
21197 if (Denom.isPosZero() && (!A.isNaN() || !B.isNaN())) {
21198 ResR = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * A;
21199 ResI = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * B;
21200 }
else if ((A.isInfinity() || B.isInfinity()) &&
C.isFinite() &&
21202 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
21204 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
21206 ResR = APFloat::getInf(ResR.getSemantics()) * (A *
C + B * D);
21207 ResI = APFloat::getInf(ResI.getSemantics()) * (B *
C - A * D);
21208 }
else if (MaxCD.isInfinity() && A.isFinite() && B.isFinite()) {
21209 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
21211 D = APFloat::copySign(APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0),
21213 ResR = APFloat::getZero(ResR.getSemantics()) * (A *
C + B * D);
21214 ResI = APFloat::getZero(ResI.getSemantics()) * (B *
C - A * D);
21221 APSInt NormAmt = Amount;
21222 unsigned BitWidth =
Value.getBitWidth();
21223 unsigned AmtBitWidth = NormAmt.getBitWidth();
21224 if (BitWidth == 1) {
21226 NormAmt =
APSInt(APInt(AmtBitWidth, 0), NormAmt.isUnsigned());
21227 }
else if (BitWidth == 2) {
21232 APSInt(APInt(AmtBitWidth, NormAmt[0] ? 1 : 0), NormAmt.isUnsigned());
21235 if (AmtBitWidth > BitWidth) {
21236 Divisor = llvm::APInt(AmtBitWidth, BitWidth);
21238 Divisor = llvm::APInt(BitWidth, BitWidth);
21239 if (AmtBitWidth < BitWidth) {
21240 NormAmt = NormAmt.extend(BitWidth);
21245 if (NormAmt.isSigned()) {
21246 NormAmt =
APSInt(NormAmt.srem(Divisor),
false);
21247 if (NormAmt.isNegative()) {
21248 APSInt SignedDivisor(Divisor,
false);
21249 NormAmt += SignedDivisor;
21252 NormAmt =
APSInt(NormAmt.urem(Divisor),
true);
21259bool ComplexExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
21261 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
21265 bool LHSReal =
false, RHSReal =
false;
21273 Result.makeComplexFloat();
21277 LHSOK = Visit(E->
getLHS());
21279 if (!LHSOK && !Info.noteFailure())
21285 APFloat &Real = RHS.FloatReal;
21288 RHS.makeComplexFloat();
21289 RHS.FloatImag =
APFloat(Real.getSemantics());
21293 assert(!(LHSReal && RHSReal) &&
21294 "Cannot have both operands of a complex operation be real.");
21296 default:
return Error(E);
21298 if (
Result.isComplexFloat()) {
21299 Result.getComplexFloatReal().add(RHS.getComplexFloatReal(),
21300 APFloat::rmNearestTiesToEven);
21302 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
21304 Result.getComplexFloatImag().add(RHS.getComplexFloatImag(),
21305 APFloat::rmNearestTiesToEven);
21307 Result.getComplexIntReal() += RHS.getComplexIntReal();
21308 Result.getComplexIntImag() += RHS.getComplexIntImag();
21312 if (
Result.isComplexFloat()) {
21313 Result.getComplexFloatReal().subtract(RHS.getComplexFloatReal(),
21314 APFloat::rmNearestTiesToEven);
21316 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
21317 Result.getComplexFloatImag().changeSign();
21318 }
else if (!RHSReal) {
21319 Result.getComplexFloatImag().subtract(RHS.getComplexFloatImag(),
21320 APFloat::rmNearestTiesToEven);
21323 Result.getComplexIntReal() -= RHS.getComplexIntReal();
21324 Result.getComplexIntImag() -= RHS.getComplexIntImag();
21328 if (
Result.isComplexFloat()) {
21333 ComplexValue LHS =
Result;
21334 APFloat &A = LHS.getComplexFloatReal();
21335 APFloat &B = LHS.getComplexFloatImag();
21336 APFloat &
C = RHS.getComplexFloatReal();
21337 APFloat &D = RHS.getComplexFloatImag();
21341 assert(!RHSReal &&
"Cannot have two real operands for a complex op!");
21349 }
else if (RHSReal) {
21361 ComplexValue LHS =
Result;
21362 Result.getComplexIntReal() =
21363 (LHS.getComplexIntReal() * RHS.getComplexIntReal() -
21364 LHS.getComplexIntImag() * RHS.getComplexIntImag());
21365 Result.getComplexIntImag() =
21366 (LHS.getComplexIntReal() * RHS.getComplexIntImag() +
21367 LHS.getComplexIntImag() * RHS.getComplexIntReal());
21371 if (
Result.isComplexFloat()) {
21376 ComplexValue LHS =
Result;
21377 APFloat &A = LHS.getComplexFloatReal();
21378 APFloat &B = LHS.getComplexFloatImag();
21379 APFloat &
C = RHS.getComplexFloatReal();
21380 APFloat &D = RHS.getComplexFloatImag();
21394 B = APFloat::getZero(A.getSemantics());
21399 ComplexValue LHS =
Result;
21400 APSInt Den = RHS.getComplexIntReal() * RHS.getComplexIntReal() +
21401 RHS.getComplexIntImag() * RHS.getComplexIntImag();
21403 return Error(E, diag::note_expr_divide_by_zero);
21405 Result.getComplexIntReal() =
21406 (LHS.getComplexIntReal() * RHS.getComplexIntReal() +
21407 LHS.getComplexIntImag() * RHS.getComplexIntImag()) / Den;
21408 Result.getComplexIntImag() =
21409 (LHS.getComplexIntImag() * RHS.getComplexIntReal() -
21410 LHS.getComplexIntReal() * RHS.getComplexIntImag()) / Den;
21418bool ComplexExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
21432 if (
Result.isComplexFloat()) {
21433 Result.getComplexFloatReal().changeSign();
21434 Result.getComplexFloatImag().changeSign();
21437 Result.getComplexIntReal() = -
Result.getComplexIntReal();
21438 Result.getComplexIntImag() = -
Result.getComplexIntImag();
21442 if (
Result.isComplexFloat())
21443 Result.getComplexFloatImag().changeSign();
21445 Result.getComplexIntImag() = -
Result.getComplexIntImag();
21450bool ComplexExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
21453 Result.makeComplexFloat();
21459 Result.makeComplexInt();
21467 return ExprEvaluatorBaseTy::VisitInitListExpr(E);
21470bool ComplexExprEvaluator::VisitCallExpr(
const CallExpr *E) {
21471 if (!IsConstantEvaluatedBuiltinCall(E))
21472 return ExprEvaluatorBaseTy::VisitCallExpr(E);
21475 case Builtin::BI__builtin_complex:
21476 Result.makeComplexFloat();
21494class AtomicExprEvaluator :
21495 public ExprEvaluatorBase<AtomicExprEvaluator> {
21496 const LValue *
This;
21499 AtomicExprEvaluator(EvalInfo &Info,
const LValue *This,
APValue &
Result)
21507 bool ZeroInitialization(
const Expr *E) {
21508 ImplicitValueInitExpr VIE(
21516 bool VisitCastExpr(
const CastExpr *E) {
21519 return ExprEvaluatorBaseTy::VisitCastExpr(E);
21520 case CK_NullToPointer:
21522 return ZeroInitialization(E);
21523 case CK_NonAtomicToAtomic:
21535 return AtomicExprEvaluator(Info,
This,
Result).Visit(E);
21544class VoidExprEvaluator
21545 :
public ExprEvaluatorBase<VoidExprEvaluator> {
21547 VoidExprEvaluator(EvalInfo &Info) : ExprEvaluatorBaseTy(Info) {}
21551 bool ZeroInitialization(
const Expr *E) {
return true; }
21553 bool VisitCastExpr(
const CastExpr *E) {
21556 return ExprEvaluatorBaseTy::VisitCastExpr(E);
21563 bool VisitCallExpr(
const CallExpr *E) {
21564 if (!IsConstantEvaluatedBuiltinCall(E))
21565 return ExprEvaluatorBaseTy::VisitCallExpr(E);
21568 case Builtin::BI__assume:
21569 case Builtin::BI__builtin_assume:
21573 case Builtin::BI__builtin_operator_delete:
21581 bool VisitCXXDeleteExpr(
const CXXDeleteExpr *E);
21585bool VoidExprEvaluator::VisitCXXDeleteExpr(
const CXXDeleteExpr *E) {
21587 if (Info.SpeculativeEvaluationDepth)
21591 if (!OperatorDelete
21592 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
21593 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
21603 if (
Pointer.Designator.Invalid)
21607 if (
Pointer.isNullPointer()) {
21611 if (!Info.getLangOpts().CPlusPlus20)
21612 Info.CCEDiag(E, diag::note_constexpr_new);
21620 QualType AllocType =
Pointer.Base.getDynamicAllocType();
21626 Info.FFDiag(E, diag::note_constexpr_delete_base_nonvirt_dtor)
21635 if (VirtualDelete &&
21637 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
21638 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
21645 (*Alloc)->Value, AllocType))
21648 if (!Info.HeapAllocs.erase(
Pointer.Base.dyn_cast<DynamicAllocLValue>())) {
21653 Info.FFDiag(E, diag::note_constexpr_double_delete);
21663 return VoidExprEvaluator(Info).Visit(E);
21675 if (E->
isGLValue() ||
T->isFunctionType()) {
21680 }
else if (
T->isVectorType()) {
21683 }
else if (
T->isConstantMatrixType()) {
21686 }
else if (
T->isIntegralOrEnumerationType()) {
21687 if (!IntExprEvaluator(Info,
Result).Visit(E))
21689 }
else if (
T->hasPointerRepresentation()) {
21694 }
else if (
T->isRealFloatingType()) {
21695 llvm::APFloat F(0.0);
21699 }
else if (
T->isAnyComplexType()) {
21704 }
else if (
T->isFixedPointType()) {
21705 if (!FixedPointExprEvaluator(Info,
Result).Visit(E))
return false;
21706 }
else if (
T->isMemberPointerType()) {
21712 }
else if (
T->isArrayType()) {
21715 Info.CurrentCall->createTemporary(E,
T, ScopeKind::FullExpression, LV);
21719 }
else if (
T->isRecordType()) {
21722 Info.CurrentCall->createTemporary(E,
T, ScopeKind::FullExpression, LV);
21726 }
else if (
T->isVoidType()) {
21727 if (!Info.getLangOpts().CPlusPlus11)
21728 Info.CCEDiag(E, diag::note_constexpr_nonliteral)
21732 }
else if (
T->isAtomicType()) {
21733 QualType Unqual =
T.getAtomicUnqualifiedType();
21737 E, Unqual, ScopeKind::FullExpression, LV);
21745 }
else if (Info.getLangOpts().CPlusPlus11) {
21746 Info.FFDiag(E, diag::note_constexpr_nonliteral) << E->
getType();
21749 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
21760 const Expr *E,
bool AllowNonLiteralTypes) {
21776 if (
T->isArrayType())
21778 else if (
T->isRecordType())
21780 else if (
T->isAtomicType()) {
21781 QualType Unqual =
T.getAtomicUnqualifiedType();
21802 if (Info.EnableNewConstInterp) {
21803 if (!Info.Ctx.getInterpContext().evaluateAsRValue(Info, E,
Result))
21806 ConstantExprKind::Normal);
21815 LV.setFrom(Info.Ctx,
Result);
21822 ConstantExprKind::Normal) &&
21830 if (
const auto *L = dyn_cast<IntegerLiteral>(Exp)) {
21832 APValue(
APSInt(L->getValue(), L->getType()->isUnsignedIntegerType()));
21837 if (
const auto *L = dyn_cast<CXXBoolLiteralExpr>(Exp)) {
21843 if (
const auto *FL = dyn_cast<FloatingLiteral>(Exp)) {
21849 if (
const auto *L = dyn_cast<CharacterLiteral>(Exp)) {
21855 if (
const auto *CE = dyn_cast<ConstantExpr>(Exp)) {
21856 if (CE->hasAPValueResult()) {
21857 APValue APV = CE->getAPValueResult();
21859 Result = std::move(APV);
21935 bool InConstantContext)
const {
21937 "Expression evaluator can't be called on a dependent expression.");
21938 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsRValue");
21940 Info.InConstantContext = InConstantContext;
21941 return ::EvaluateAsRValue(
this,
Result, Ctx, Info);
21945 bool InConstantContext)
const {
21947 "Expression evaluator can't be called on a dependent expression.");
21948 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsBooleanCondition");
21956 bool InConstantContext)
const {
21958 "Expression evaluator can't be called on a dependent expression.");
21959 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsInt");
21961 Info.InConstantContext = InConstantContext;
21962 return ::EvaluateAsInt(
this,
Result, Ctx, AllowSideEffects, Info);
21967 bool InConstantContext)
const {
21969 "Expression evaluator can't be called on a dependent expression.");
21970 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFixedPoint");
21972 Info.InConstantContext = InConstantContext;
21973 return ::EvaluateAsFixedPoint(
this,
Result, Ctx, AllowSideEffects, Info);
21978 bool InConstantContext)
const {
21980 "Expression evaluator can't be called on a dependent expression.");
21982 if (!
getType()->isRealFloatingType())
21985 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFloat");
21997 bool InConstantContext)
const {
21999 "Expression evaluator can't be called on a dependent expression.");
22001 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsLValue");
22003 Info.InConstantContext = InConstantContext;
22007 if (Info.EnableNewConstInterp) {
22008 if (!Info.Ctx.getInterpContext().evaluate(Info,
this,
Result.Val,
22009 ConstantExprKind::Normal))
22012 LV.setFrom(Ctx,
Result.Val);
22015 ConstantExprKind::Normal, CheckedTemps);
22018 if (!
EvaluateLValue(
this, LV, Info) || !Info.discardCleanups() ||
22019 Result.HasSideEffects ||
22022 ConstantExprKind::Normal, CheckedTemps))
22025 LV.moveInto(
Result.Val);
22032 bool IsConstantDestruction) {
22033 EvalInfo Info(Ctx, EStatus,
22036 Info.setEvaluatingDecl(
Base, DestroyedValue,
22037 EvalInfo::EvaluatingDeclKind::Dtor);
22038 Info.InConstantContext = IsConstantDestruction;
22047 if (!Info.discardCleanups())
22048 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
22056 "Expression evaluator can't be called on a dependent expression.");
22062 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsConstantExpr");
22064 EvalInfo Info(Ctx,
Result, EM);
22065 Info.InConstantContext =
true;
22067 if (Info.EnableNewConstInterp) {
22068 if (!Info.Ctx.getInterpContext().evaluate(Info,
this,
Result.Val, Kind))
22071 getStorageType(Ctx,
this),
Result.Val, Kind);
22076 if (Kind == ConstantExprKind::ClassTemplateArgument)
22092 FullExpressionRAII
Scope(Info);
22097 if (!Info.discardCleanups())
22098 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
22108 if (Kind == ConstantExprKind::ClassTemplateArgument &&
22111 Result.HasSideEffects)) {
22121 bool IsConstantInitialization)
const {
22123 "Expression evaluator can't be called on a dependent expression.");
22124 assert(VD &&
"Need a valid VarDecl");
22126 llvm::TimeTraceScope TimeScope(
"EvaluateAsInitializer", [&] {
22128 llvm::raw_string_ostream OS(Name);
22133 EvalInfo Info(Ctx, EStatus,
22134 (IsConstantInitialization &&
22138 Info.setEvaluatingDecl(VD, EStatus.
Val);
22139 Info.InConstantContext = IsConstantInitialization;
22144 if (Info.EnableNewConstInterp) {
22146 if (!InterpCtx.evaluateAsInitializer(Info, VD,
this, EStatus.
Val))
22150 ConstantExprKind::Normal);
22165 FullExpressionRAII
Scope(Info);
22174 Info.performLifetimeExtension();
22176 if (!Info.discardCleanups())
22177 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
22181 ConstantExprKind::Normal) &&
22201 EStatus.
Diag = &Notes;
22218 EvalInfo Info(Ctx, EStatus,
22221 Info.InConstantContext = IsConstantDestruction;
22223 std::move(DestroyedValue)))
22230 getLocation(), EStatus, IsConstantDestruction) ||
22242 "Expression evaluator can't be called on a dependent expression.");
22251 "Expression evaluator can't be called on a dependent expression.");
22253 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstInt");
22256 Info.InConstantContext =
true;
22260 assert(
Result &&
"Could not evaluate expression");
22261 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
22263 return EVResult.Val.getInt();
22269 "Expression evaluator can't be called on a dependent expression.");
22271 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstIntCheckOverflow");
22273 EVResult.Diag =
Diag;
22275 Info.InConstantContext =
true;
22276 Info.CheckingForUndefinedBehavior =
true;
22280 assert(
Result &&
"Could not evaluate expression");
22281 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
22283 return EVResult.Val.getInt();
22288 "Expression evaluator can't be called on a dependent expression.");
22290 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateForOverflow");
22295 Info.CheckingForUndefinedBehavior =
true;
22301 assert(
Val.isLValue());
22327 IK_ICEIfUnevaluated,
22343static ICEDiag
Worst(ICEDiag A, ICEDiag B) {
return A.Kind >= B.Kind ? A : B; }
22350 Info.InConstantContext =
true;
22359 assert(!E->
isValueDependent() &&
"Should not see value dependent exprs!");
22364#define ABSTRACT_STMT(Node)
22365#define STMT(Node, Base) case Expr::Node##Class:
22366#define EXPR(Node, Base)
22367#include "clang/AST/StmtNodes.inc"
22368 case Expr::PredefinedExprClass:
22369 case Expr::FloatingLiteralClass:
22370 case Expr::ImaginaryLiteralClass:
22371 case Expr::StringLiteralClass:
22372 case Expr::ArraySubscriptExprClass:
22373 case Expr::MatrixSingleSubscriptExprClass:
22374 case Expr::MatrixSubscriptExprClass:
22375 case Expr::ArraySectionExprClass:
22376 case Expr::OMPArrayShapingExprClass:
22377 case Expr::OMPIteratorExprClass:
22378 case Expr::CompoundAssignOperatorClass:
22379 case Expr::CompoundLiteralExprClass:
22380 case Expr::ExtVectorElementExprClass:
22381 case Expr::MatrixElementExprClass:
22382 case Expr::DesignatedInitExprClass:
22383 case Expr::ArrayInitLoopExprClass:
22384 case Expr::ArrayInitIndexExprClass:
22385 case Expr::NoInitExprClass:
22386 case Expr::DesignatedInitUpdateExprClass:
22387 case Expr::ImplicitValueInitExprClass:
22388 case Expr::ParenListExprClass:
22389 case Expr::VAArgExprClass:
22390 case Expr::AddrLabelExprClass:
22391 case Expr::StmtExprClass:
22392 case Expr::CXXMemberCallExprClass:
22393 case Expr::CUDAKernelCallExprClass:
22394 case Expr::CXXAddrspaceCastExprClass:
22395 case Expr::CXXDynamicCastExprClass:
22396 case Expr::CXXTypeidExprClass:
22397 case Expr::CXXUuidofExprClass:
22398 case Expr::MSPropertyRefExprClass:
22399 case Expr::MSPropertySubscriptExprClass:
22400 case Expr::CXXNullPtrLiteralExprClass:
22401 case Expr::UserDefinedLiteralClass:
22402 case Expr::CXXThisExprClass:
22403 case Expr::CXXThrowExprClass:
22404 case Expr::CXXNewExprClass:
22405 case Expr::CXXDeleteExprClass:
22406 case Expr::CXXPseudoDestructorExprClass:
22407 case Expr::UnresolvedLookupExprClass:
22408 case Expr::RecoveryExprClass:
22409 case Expr::DependentScopeDeclRefExprClass:
22410 case Expr::DependentTemplateIdExprClass:
22411 case Expr::CXXConstructExprClass:
22412 case Expr::CXXInheritedCtorInitExprClass:
22413 case Expr::CXXStdInitializerListExprClass:
22414 case Expr::CXXBindTemporaryExprClass:
22415 case Expr::ExprWithCleanupsClass:
22416 case Expr::CXXTemporaryObjectExprClass:
22417 case Expr::CXXUnresolvedConstructExprClass:
22418 case Expr::CXXDependentScopeMemberExprClass:
22419 case Expr::UnresolvedMemberExprClass:
22420 case Expr::ObjCStringLiteralClass:
22421 case Expr::ObjCBoxedExprClass:
22422 case Expr::ObjCArrayLiteralClass:
22423 case Expr::ObjCDictionaryLiteralClass:
22424 case Expr::ObjCEncodeExprClass:
22425 case Expr::ObjCMessageExprClass:
22426 case Expr::ObjCSelectorExprClass:
22427 case Expr::ObjCProtocolExprClass:
22428 case Expr::ObjCIvarRefExprClass:
22429 case Expr::ObjCPropertyRefExprClass:
22430 case Expr::ObjCSubscriptRefExprClass:
22431 case Expr::ObjCIsaExprClass:
22432 case Expr::ObjCAvailabilityCheckExprClass:
22433 case Expr::ShuffleVectorExprClass:
22434 case Expr::ConvertVectorExprClass:
22435 case Expr::BlockExprClass:
22437 case Expr::OpaqueValueExprClass:
22438 case Expr::PackExpansionExprClass:
22439 case Expr::SubstNonTypeTemplateParmPackExprClass:
22440 case Expr::FunctionParmPackExprClass:
22441 case Expr::AsTypeExprClass:
22442 case Expr::ObjCIndirectCopyRestoreExprClass:
22443 case Expr::MaterializeTemporaryExprClass:
22444 case Expr::PseudoObjectExprClass:
22445 case Expr::AtomicExprClass:
22446 case Expr::LambdaExprClass:
22447 case Expr::CXXFoldExprClass:
22448 case Expr::CoawaitExprClass:
22449 case Expr::DependentCoawaitExprClass:
22450 case Expr::CoyieldExprClass:
22451 case Expr::SYCLUniqueStableNameExprClass:
22452 case Expr::CXXParenListInitExprClass:
22453 case Expr::HLSLOutArgExprClass:
22454 case Expr::CXXExpansionSelectExprClass:
22457 case Expr::MemberExprClass: {
22460 while (
const auto *M = dyn_cast<MemberExpr>(ME)) {
22463 ME = M->getBase()->IgnoreParenImpCasts();
22465 const auto *DRE = dyn_cast<DeclRefExpr>(ME);
22467 if (
const auto *VD = dyn_cast<VarDecl>(DRE->getDecl());
22475 case Expr::InitListExprClass: {
22486 case Expr::SizeOfPackExprClass:
22487 case Expr::GNUNullExprClass:
22488 case Expr::SourceLocExprClass:
22489 case Expr::EmbedExprClass:
22490 case Expr::OpenACCAsteriskSizeExprClass:
22493 case Expr::PackIndexingExprClass:
22496 case Expr::SubstNonTypeTemplateParmExprClass:
22500 case Expr::ConstantExprClass:
22503 case Expr::ParenExprClass:
22505 case Expr::GenericSelectionExprClass:
22507 case Expr::IntegerLiteralClass:
22508 case Expr::FixedPointLiteralClass:
22509 case Expr::CharacterLiteralClass:
22510 case Expr::ObjCBoolLiteralExprClass:
22511 case Expr::CXXBoolLiteralExprClass:
22512 case Expr::CXXScalarValueInitExprClass:
22513 case Expr::TypeTraitExprClass:
22514 case Expr::ConceptSpecializationExprClass:
22515 case Expr::RequiresExprClass:
22516 case Expr::ArrayTypeTraitExprClass:
22517 case Expr::ExpressionTraitExprClass:
22518 case Expr::CXXNoexceptExprClass:
22519 case Expr::CXXReflectExprClass:
22521 case Expr::CallExprClass:
22522 case Expr::CXXOperatorCallExprClass: {
22531 case Expr::CXXRewrittenBinaryOperatorClass:
22534 case Expr::DeclRefExprClass: {
22548 const VarDecl *VD = dyn_cast<VarDecl>(D);
22555 case Expr::UnaryOperatorClass: {
22578 llvm_unreachable(
"invalid unary operator class");
22580 case Expr::OffsetOfExprClass: {
22589 case Expr::UnaryExprOrTypeTraitExprClass: {
22591 if ((Exp->
getKind() == UETT_SizeOf) &&
22594 if (Exp->
getKind() == UETT_CountOf) {
22601 if (VAT->getElementType()->isArrayType())
22613 case Expr::BinaryOperatorClass: {
22658 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE) {
22661 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
22662 if (REval.isSigned() && REval.isAllOnes()) {
22664 if (LEval.isMinSignedValue())
22665 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
22673 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE)
22674 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
22680 return Worst(LHSResult, RHSResult);
22686 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICEIfUnevaluated) {
22696 return Worst(LHSResult, RHSResult);
22699 llvm_unreachable(
"invalid binary operator kind");
22701 case Expr::ImplicitCastExprClass:
22702 case Expr::CStyleCastExprClass:
22703 case Expr::CXXFunctionalCastExprClass:
22704 case Expr::CXXStaticCastExprClass:
22705 case Expr::CXXReinterpretCastExprClass:
22706 case Expr::CXXConstCastExprClass:
22707 case Expr::ObjCBridgedCastExprClass: {
22714 APSInt IgnoredVal(DestWidth, !DestSigned);
22719 if (FL->getValue().convertToInteger(IgnoredVal,
22720 llvm::APFloat::rmTowardZero,
22721 &Ignored) & APFloat::opInvalidOp)
22727 case CK_LValueToRValue:
22728 case CK_AtomicToNonAtomic:
22729 case CK_NonAtomicToAtomic:
22731 case CK_IntegralToBoolean:
22732 case CK_IntegralCast:
22738 case Expr::BinaryConditionalOperatorClass: {
22741 if (CommonResult.Kind == IK_NotICE)
return CommonResult;
22743 if (FalseResult.Kind == IK_NotICE)
return FalseResult;
22744 if (CommonResult.Kind == IK_ICEIfUnevaluated)
return CommonResult;
22745 if (FalseResult.Kind == IK_ICEIfUnevaluated &&
22747 return FalseResult;
22749 case Expr::ConditionalOperatorClass: {
22757 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
22760 if (CondResult.Kind == IK_NotICE)
22766 if (TrueResult.Kind == IK_NotICE)
22768 if (FalseResult.Kind == IK_NotICE)
22769 return FalseResult;
22770 if (CondResult.Kind == IK_ICEIfUnevaluated)
22772 if (TrueResult.Kind == IK_ICE && FalseResult.Kind == IK_ICE)
22778 return FalseResult;
22781 case Expr::CXXDefaultArgExprClass:
22783 case Expr::CXXDefaultInitExprClass:
22785 case Expr::ChooseExprClass: {
22788 case Expr::BuiltinBitCastExprClass: {
22789 if (!checkBitCastConstexprEligibility(
nullptr, Ctx,
cast<CastExpr>(E)))
22795 llvm_unreachable(
"Invalid StmtClass!");
22801 llvm::APSInt *
Value,
22802 bool AllowRelaxedEval =
false) {
22819 "Expression evaluator can't be called on a dependent expression.");
22821 ExprTimeTraceScope TimeScope(
this, Ctx,
"isIntegerConstantExpr");
22827 if (D.Kind != IK_ICE)
22832std::optional<llvm::APSInt>
22834 bool AllowRelaxedEval)
const {
22837 return std::nullopt;
22845 return std::nullopt;
22849 return std::nullopt;
22858 Info.InConstantContext =
true;
22861 llvm_unreachable(
"ICE cannot be evaluated!");
22868 "Expression evaluator can't be called on a dependent expression.");
22870 return CheckICE(
this, Ctx).Kind == IK_ICE;
22874 bool AllowRelaxedEval)
const {
22876 "Expression evaluator can't be called on a dependent expression.");
22886 *
Result = std::move(Scratch);
22894 Status.ExtendedDiag = AllowRelaxedEval ? &MSRelaxedDiag :
nullptr;
22900 Info.discardCleanups() && !Status.HasSideEffects;
22902 return IsConstExpr && !Status.DiagEmitted;
22910 "Expression evaluator can't be called on a dependent expression.");
22912 llvm::TimeTraceScope TimeScope(
"EvaluateWithSubstitution", [&] {
22914 llvm::raw_string_ostream OS(Name);
22922 Info.InConstantContext =
true;
22924 if (Info.EnableNewConstInterp) {
22925 if (std::optional<bool> BoolResult =
22926 Info.Ctx.getInterpContext().evaluateWithSubstitution(
22927 Info, Callee, Args,
This,
this)) {
22935 const LValue *ThisPtr =
nullptr;
22938 auto *MD = dyn_cast<CXXMethodDecl>(Callee);
22939 assert(MD &&
"Don't provide `this` for non-methods.");
22940 assert(MD->isImplicitObjectMemberFunction() &&
22941 "Don't provide `this` for methods without an implicit object.");
22943 if (!
This->isValueDependent() &&
22945 !Info.EvalStatus.HasSideEffects)
22946 ThisPtr = &ThisVal;
22950 Info.EvalStatus.HasSideEffects =
false;
22953 CallRef
Call = Info.CurrentCall->createCall(Callee);
22956 unsigned Idx = I - Args.begin();
22957 if (Idx >= Callee->getNumParams())
22959 const ParmVarDecl *PVD = Callee->getParamDecl(Idx);
22960 if ((*I)->isValueDependent() ||
22962 Info.EvalStatus.HasSideEffects) {
22964 if (
APValue *Slot = Info.getParamSlot(
Call, PVD))
22970 Info.EvalStatus.HasSideEffects =
false;
22975 Info.discardCleanups();
22976 Info.EvalStatus.HasSideEffects =
false;
22979 CallStackFrame Frame(Info, Callee->getLocation(), Callee, ThisPtr,
This,
22982 FullExpressionRAII
Scope(Info);
22984 !Info.EvalStatus.HasSideEffects;
22996 llvm::TimeTraceScope TimeScope(
"isPotentialConstantExpr", [&] {
22998 llvm::raw_string_ostream OS(Name);
23005 Status.
Diag = &Diags;
23009 Info.InConstantContext =
true;
23010 Info.CheckingPotentialConstantExpression =
true;
23013 if (Info.EnableNewConstInterp) {
23014 Info.Ctx.getInterpContext().isPotentialConstantExpr(Info, FD);
23015 return Diags.empty();
23026 This.set({&VIE, Info.CurrentCall->Index});
23034 Info.setEvaluatingDecl(
This.getLValueBase(), Scratch);
23040 &VIE, Args, CallRef(), FD->
getBody(), Info, Scratch,
23044 return Diags.empty();
23052 "Expression evaluator can't be called on a dependent expression.");
23055 Status.
Diag = &Diags;
23059 Info.InConstantContext =
true;
23060 Info.CheckingPotentialConstantExpression =
true;
23062 if (Info.EnableNewConstInterp) {
23063 Info.Ctx.getInterpContext().isPotentialConstantExprUnevaluated(Info, E, FD);
23064 return Diags.empty();
23069 nullptr, CallRef());
23073 return Diags.empty();
23077 unsigned Type)
const {
23078 if (!
getType()->isPointerType())
23079 return std::nullopt;
23083 if (Info.EnableNewConstInterp)
23084 return Info.Ctx.getInterpContext().tryEvaluateObjectSize(Info,
this,
Type);
23088static std::optional<uint64_t>
23090 std::string *StringResult) {
23092 return std::nullopt;
23097 return std::nullopt;
23102 if (
const StringLiteral *S = dyn_cast_or_null<StringLiteral>(
23103 String.getLValueBase().dyn_cast<
const Expr *>())) {
23106 if (
Off >= 0 && (uint64_t)
Off <= (uint64_t)Str.size() &&
23109 Info.Ctx.hasSameUnqualifiedType(CharTy, Info.Ctx.CharTy)) {
23110 Str = Str.substr(
Off);
23112 StringRef::size_type Pos = Str.find(0);
23113 if (Pos != StringRef::npos)
23114 Str = Str.substr(0, Pos);
23117 *StringResult = Str;
23125 for (uint64_t Strlen = 0; ; ++Strlen) {
23129 return std::nullopt;
23132 else if (StringResult)
23133 StringResult->push_back(Char.
getInt().getExtValue());
23135 return std::nullopt;
23142 std::string StringResult;
23144 if (Info.EnableNewConstInterp) {
23145 if (!Info.Ctx.getInterpContext().evaluateString(Info,
this, StringResult))
23146 return std::nullopt;
23147 return StringResult;
23151 return StringResult;
23152 return std::nullopt;
23155template <
typename T>
23157 const Expr *SizeExpression,
23158 const Expr *PtrExpression,
23162 Info.InConstantContext =
true;
23164 if (Info.EnableNewConstInterp)
23165 return Info.Ctx.getInterpContext().evaluateCharRange(Info, SizeExpression,
23169 FullExpressionRAII
Scope(Info);
23174 uint64_t Size = SizeValue.getZExtValue();
23177 if constexpr (std::is_same_v<APValue, T>)
23180 if (Size <
Result.max_size())
23187 for (uint64_t I = 0; I < Size; ++I) {
23193 if constexpr (std::is_same_v<APValue, T>) {
23194 Result.getArrayInitializedElt(I) = std::move(Char);
23198 assert(
C.getBitWidth() <= 8 &&
23199 "string element not representable in char");
23201 Result.push_back(
static_cast<char>(
C.getExtValue()));
23212 const Expr *SizeExpression,
23216 PtrExpression, Ctx, Status);
23220 const Expr *SizeExpression,
23224 PtrExpression, Ctx, Status);
23231 if (Info.EnableNewConstInterp)
23232 return Info.Ctx.getInterpContext().evaluateStrlen(Info,
this);
23237struct IsWithinLifetimeHandler {
23240 using result_type = std::optional<bool>;
23241 std::optional<bool> failed() {
return std::nullopt; }
23242 template <
typename T>
23243 std::optional<bool> found(
T &Subobj,
QualType SubobjType,
23247 template <
typename T>
23248 std::optional<bool> found(
T &Subobj, QualType SubobjType) {
23253std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &IEE,
23254 const CallExpr *E) {
23255 EvalInfo &Info = IEE.Info;
23260 if (!Info.InConstantContext)
23261 return std::nullopt;
23263 const Expr *Arg = E->
getArg(0);
23265 return std::nullopt;
23268 return std::nullopt;
23270 if (Val.allowConstexprUnknown())
23274 bool CalledFromStd =
false;
23275 const auto *
Callee = Info.CurrentCall->getCallee();
23276 if (Callee &&
Callee->isInStdNamespace()) {
23277 const IdentifierInfo *Identifier =
Callee->getIdentifier();
23278 CalledFromStd = Identifier && Identifier->
isStr(
"is_within_lifetime");
23280 Info.CCEDiag(CalledFromStd ? Info.CurrentCall->getCallRange().getBegin()
23282 diag::err_invalid_is_within_lifetime)
23283 << (CalledFromStd ?
"std::is_within_lifetime"
23284 :
"__builtin_is_within_lifetime")
23286 return std::nullopt;
23296 if (Val.isNullPointer() || Val.getLValueBase().isNull())
23298 QualType
T = Val.getLValueBase().getType();
23300 "Pointers to functions should have been typed as function pointers "
23301 "which would have been rejected earlier");
23304 if (Val.getLValueDesignator().isOnePastTheEnd())
23306 assert(Val.getLValueDesignator().isValidSubobject() &&
23307 "Unchecked case for valid subobject");
23311 CompleteObject CO =
23315 if (Info.EvaluatingDeclValue && CO.Value == Info.EvaluatingDeclValue)
23320 IsWithinLifetimeHandler handler{Info};
23321 return findSubobject(Info, E, CO, Val.getLValueDesignator(), handler);
Defines the clang::ASTContext interface.
This file provides some common utility functions for processing Lambda related AST Constructs.
static bool isUnsigned(SValBuilder &SVB, NonLoc Value)
Defines enum values for all the target-independent builtin functions.
static Address castToBase(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy, Address OriginalBaseAddress, llvm::Value *Addr)
static uint32_t getBitWidth(const Expr *E)
static Decl::Kind getKind(const Decl *D)
GCCTypeClass
Values returned by __builtin_classify_type, chosen to match the values produced by GCC's builtin.
@ PointerToMemberFunction
static bool isRead(AccessKinds AK)
static bool EvaluateCharRangeAsStringImpl(const Expr *, T &Result, const Expr *SizeExpression, const Expr *PtrExpression, ASTContext &Ctx, Expr::EvalResult &Status)
static bool isValidIndeterminateAccess(AccessKinds AK)
Is this kind of access valid on an indeterminate object value?
static unsigned elementwiseSize(EvalInfo &Info, QualType BaseTy)
static bool EvaluateMemberPointer(const Expr *E, MemberPtr &Result, EvalInfo &Info)
static bool hasUnacceptableSideEffect(Expr::EvalStatus &Result, Expr::SideEffectsKind SEK)
static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E, AccessKinds AK, const LValue &LVal, QualType LValType)
Find the complete object to which an LValue refers.
static bool evaluateLValueAsAllocSize(EvalInfo &Info, APValue::LValueBase Base, LValue &Result)
Attempts to evaluate the given LValueBase as the result of a call to a function with the alloc_size a...
static bool CheckEvaluationResult(CheckEvaluationResultKind CERK, EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value, ConstantExprKind Kind, const FieldDecl *SubobjectDecl, CheckedTemporaries &CheckedTemps, bool IsCompleteClass=true)
static const CXXMethodDecl * HandleVirtualDispatch(EvalInfo &Info, const Expr *E, LValue &This, const CXXMethodDecl *Found, llvm::SmallVectorImpl< QualType > &CovariantAdjustmentPath)
Perform virtual dispatch.
static bool EvaluateVarDecl(EvalInfo &Info, const VarDecl *VD)
static bool HandleLValueComplexElement(EvalInfo &Info, const Expr *E, LValue &LVal, QualType EltTy, bool Imag)
Update an lvalue to refer to a component of a complex number.
static bool evalPackBuiltin(const CallExpr *E, EvalInfo &Info, APValue &Result, llvm::function_ref< APInt(const APSInt &)> PackFn)
static bool HandleSizeof(EvalInfo &Info, SourceLocation Loc, QualType Type, CharUnits &Size, SizeOfType SOT=SizeOfType::SizeOf)
Get the size of the given type in char units.
static bool hlslElementwiseCastHelper(EvalInfo &Info, const Expr *E, QualType DestTy, SmallVectorImpl< APValue > &SrcVals, SmallVectorImpl< QualType > &SrcTypes)
static bool ShouldPropagateBreakContinue(EvalInfo &Info, const Stmt *LoopOrSwitch, ArrayRef< BlockScopeRAII * > Scopes, EvalStmtResult &ESR)
Helper to implement named break/continue.
static EvalStmtResult EvaluateLoopBody(StmtResult &Result, EvalInfo &Info, const Stmt *Body, const SwitchCase *Case=nullptr)
Evaluate the body of a loop, and translate the result as appropriate.
static bool EvaluatePointer(const Expr *E, LValue &Result, EvalInfo &Info, bool InvalidBaseOK=false)
static bool CheckTrivialDefaultConstructor(EvalInfo &Info, SourceLocation Loc, const CXXConstructorDecl *CD, bool IsValueInitialization)
CheckTrivialDefaultConstructor - Check whether a constructor is a trivial default constructor.
static bool EvaluateVector(const Expr *E, APValue &Result, EvalInfo &Info)
static const ValueDecl * GetLValueBaseDecl(const LValue &LVal)
static bool TryEvaluateBuiltinNaN(const ASTContext &Context, QualType ResultTy, const Expr *Arg, bool SNaN, llvm::APFloat &Result)
static const Expr * ignorePointerCastsAndParens(const Expr *E)
A more selective version of E->IgnoreParenCasts for tryEvaluateBuiltinObjectSize. This ignores some c...
static bool isAnyAccess(AccessKinds AK)
static bool EvaluateComparisonBinaryOperator(EvalInfo &Info, const BinaryOperator *E, SuccessCB &&Success, AfterCB &&DoAfter)
static bool EvaluateComplex(const Expr *E, ComplexValue &Res, EvalInfo &Info)
std::optional< APFloat > EvalScalarMinMaxFp(const APFloat &A, const APFloat &B, std::optional< APSInt > RoundingMode, bool IsMin)
static bool CheckMemoryLeaks(EvalInfo &Info)
Enforce C++2a [expr.const]/4.17, which disallows new-expressions unless "the allocated storage is dea...
static bool handleScalarCast(EvalInfo &Info, const FPOptions FPO, const Expr *E, QualType SourceTy, QualType DestTy, APValue const &Original, APValue &Result)
static ICEDiag CheckEvalInICE(const Expr *E, const ASTContext &Ctx)
static llvm::APInt ConvertBoolVectorToInt(const APValue &Val)
static bool flattenAPValue(EvalInfo &Info, const Expr *E, APValue Value, QualType BaseTy, SmallVectorImpl< APValue > &Elements, SmallVectorImpl< QualType > &Types, unsigned Size)
static bool hlslAggSplatHelper(EvalInfo &Info, const Expr *E, APValue &SrcVal, QualType &SrcTy)
static bool isBaseClassPublic(const CXXRecordDecl *Derived, const CXXRecordDecl *Base)
Determine whether Base, which is known to be a direct base class of Derived, is a public base class.
static bool hasVirtualDestructor(QualType T)
static bool HandleOverflow(EvalInfo &Info, const Expr *E, const T &SrcValue, QualType DestType)
static CharUnits getBaseAlignment(EvalInfo &Info, const LValue &Value)
static bool HandleLValueIndirectMember(EvalInfo &Info, const Expr *E, LValue &LVal, const IndirectFieldDecl *IFD)
Update LVal to refer to the given indirect field.
unsigned ConvertBuiltinIDToX86BuiltinID(const ASTContext &Ctx, unsigned BuiltinOp)
Convert a builtin ID to the canonical x86 builtin ID the constant evaluators dispatch on in their x86...
static bool ConvertDoubleToFloatStrict(EvalInfo &Info, const Expr *E, APFloat OrigVal, APValue &Result)
static ICEDiag Worst(ICEDiag A, ICEDiag B)
static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E, const VarDecl *VD, CallStackFrame *Frame, unsigned Version, APValue *&Result)
Try to evaluate the initializer for a variable declaration.
static bool HandleLValueVectorElement(EvalInfo &Info, const Expr *E, LValue &LVal, QualType EltTy, uint64_t Size, uint64_t Idx)
static bool checkFloatingPointResultForConstantFolding(EvalInfo &Info, const Expr *E, APFloat::opStatus St)
Check if the given floating-point evaluation result is allowed for compile-time constant folding duri...
static void NoteLValueLocation(EvalInfo &Info, APValue::LValueBase Base)
static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc, QualType Type, const LValue &LVal, ConstantExprKind Kind, CheckedTemporaries &CheckedTemps)
Check that this reference or pointer core constant expression is a valid value for an address or refe...
static bool CheckedIntArithmetic(EvalInfo &Info, const Expr *E, const APSInt &LHS, const APSInt &RHS, unsigned BitWidth, Operation Op, APSInt &Result)
Perform the given integer operation, which is known to need at most BitWidth bits,...
static bool EvaluateTemporary(const Expr *E, LValue &Result, EvalInfo &Info)
Evaluate an expression of record type as a temporary.
static bool EvaluateArray(const Expr *E, const LValue &This, APValue &Result, EvalInfo &Info)
static bool truncateBitfieldValue(EvalInfo &Info, const Expr *E, APValue &Value, const FieldDecl *FD)
static bool handleVectorShuffle(EvalInfo &Info, const ShuffleVectorExpr *E, QualType ElemType, APValue const &VecVal1, APValue const &VecVal2, unsigned EltNum, APValue &Result)
static bool handleVectorElementCast(EvalInfo &Info, const FPOptions FPO, const Expr *E, QualType SourceTy, QualType DestTy, APValue const &Original, APValue &Result)
static const ValueDecl * HandleMemberPointerAccess(EvalInfo &Info, QualType LVType, LValue &LV, const Expr *RHS, bool IncludeMember=true)
HandleMemberPointerAccess - Evaluate a member access operation and build an lvalue referring to the r...
static bool HandleBaseToDerivedCast(EvalInfo &Info, const CastExpr *E, LValue &Result)
HandleBaseToDerivedCast - Apply the given base-to-derived cast operation on the provided lvalue,...
static bool EvaluateFloat(const Expr *E, APFloat &Result, EvalInfo &Info)
static bool IsOpaqueConstantCall(const CallExpr *E)
Should this call expression be treated as forming an opaque constant?
static bool CheckMemberPointerConstantExpression(EvalInfo &Info, SourceLocation Loc, QualType Type, const APValue &Value, ConstantExprKind Kind)
Member pointers are constant expressions unless they point to a non-virtual dllimport member function...
static bool EvaluateAsInt(const Expr *E, Expr::EvalResult &ExprResult, const ASTContext &Ctx, Expr::SideEffectsKind AllowSideEffects, EvalInfo &Info)
static bool handleLValueToRValueConversion(EvalInfo &Info, const Expr *Conv, QualType Type, const LValue &LVal, APValue &RVal, bool WantObjectRepresentation=false)
Perform an lvalue-to-rvalue conversion on the given glvalue.
static bool handleElementwiseCast(EvalInfo &Info, const Expr *E, const FPOptions FPO, SmallVectorImpl< APValue > &Elements, SmallVectorImpl< QualType > &SrcTypes, SmallVectorImpl< QualType > &DestTypes, SmallVectorImpl< APValue > &Results)
static bool refersToCompleteObject(const LValue &LVal)
Tests to see if the LValue has a user-specified designator (that isn't necessarily valid)....
static bool AreElementsOfSameArray(QualType ObjType, const SubobjectDesignator &A, const SubobjectDesignator &B)
Determine whether the given subobject designators refer to elements of the same array object.
static bool EvaluateDecompositionDeclInit(EvalInfo &Info, const DecompositionDecl *DD)
static bool IsWeakLValue(const LValue &Value)
static bool EvaluateArrayNewConstructExpr(EvalInfo &Info, LValue &This, APValue &Result, const CXXConstructExpr *CCE, QualType AllocType)
static bool EvaluateRecord(const Expr *E, const LValue &This, APValue &Result, EvalInfo &Info)
static bool handleAssignment(EvalInfo &Info, const Expr *E, const LValue &LVal, QualType LValType, APValue &Val)
Perform an assignment of Val to LVal. Takes ownership of Val.
static bool CastToDerivedClass(EvalInfo &Info, const Expr *E, LValue &Result, const RecordDecl *TruncatedType, unsigned TruncatedElements)
Cast an lvalue referring to a base subobject to a derived class, by truncating the lvalue's path to t...
static bool EvaluateIgnoredValue(EvalInfo &Info, const Expr *E)
Evaluate an expression to see if it had side-effects, and discard its result.
static bool constructAggregate(EvalInfo &Info, const FPOptions FPO, const Expr *E, APValue &Result, QualType ResultType, SmallVectorImpl< APValue > &Elements, SmallVectorImpl< QualType > &ElTypes)
static void addFlexibleArrayMemberInitSize(EvalInfo &Info, const QualType &T, const LValue &LV, CharUnits &Size)
If we're evaluating the object size of an instance of a struct that contains a flexible array member,...
static bool HandleLValueBasePath(EvalInfo &Info, const CastExpr *E, QualType Type, LValue &Result)
static bool evalShuffleGeneric(EvalInfo &Info, const CallExpr *Call, APValue &Out, llvm::function_ref< std::pair< unsigned, int >(unsigned, unsigned)> GetSourceIndex)
static QualType getSubobjectType(QualType ObjType, QualType SubobjType, bool IsMutable=false)
static bool EvaluateFixedPointOrInteger(const Expr *E, APFixedPoint &Result, EvalInfo &Info)
Evaluate an integer or fixed point expression into an APResult.
static bool HandleIntToFloatCast(EvalInfo &Info, const Expr *E, const FPOptions FPO, QualType SrcType, const APSInt &Value, QualType DestType, APFloat &Result)
static const CXXRecordDecl * getBaseClassType(SubobjectDesignator &Designator, unsigned PathLength)
static bool CastToBaseClass(EvalInfo &Info, const Expr *E, LValue &Result, const CXXRecordDecl *DerivedRD, const CXXRecordDecl *BaseRD)
Cast an lvalue referring to a derived class to a known base subobject.
static bool HandleLValueBase(EvalInfo &Info, const Expr *E, LValue &Obj, const CXXRecordDecl *DerivedDecl, const CXXBaseSpecifier *Base)
static bool HandleLValueDirectVirtualBase(EvalInfo &Info, const Expr *E, LValue &Obj, const CXXRecordDecl *Derived, const CXXRecordDecl *Base, const ASTRecordLayout *RL=nullptr)
static bool HandleConversionToBool(const APValue &Val, bool &Result)
static void expandVector(APValue &Vec, unsigned NumElements)
CharUnits GetAlignOfExpr(const ASTContext &Ctx, const Expr *E, UnaryExprOrTypeTrait ExprKind)
static bool handleCompareOpForVector(const APValue &LHSValue, BinaryOperatorKind Opcode, const APValue &RHSValue, APInt &Result)
static bool MaybeElementDependentArrayFiller(const Expr *FillerExpr)
static bool EvaluateObjectArgument(EvalInfo &Info, const Expr *Object, LValue &This)
Build an lvalue for the object argument of a member function call.
static bool CheckLiteralType(EvalInfo &Info, const Expr *E, const LValue *This=nullptr)
Check that this core constant expression is of literal type, and if not, produce an appropriate diagn...
static bool EvaluateInteger(const Expr *E, APSInt &Result, EvalInfo &Info)
CheckEvaluationResultKind
static bool isZeroSized(const LValue &Value)
static APSInt extractStringLiteralCharacter(EvalInfo &Info, const Expr *Lit, uint64_t Index)
Extract the value of a character from a string literal.
static bool modifySubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, const SubobjectDesignator &Sub, APValue &NewVal)
Update the designated sub-object of an rvalue to the given value.
static CharUnits GetAlignOfType(const ASTContext &Ctx, QualType T, UnaryExprOrTypeTrait ExprKind)
static bool getBuiltinAlignArguments(const CallExpr *E, EvalInfo &Info, APValue &Val, APSInt &Alignment)
static bool HandleLValueArrayAdjustment(EvalInfo &Info, const Expr *E, LValue &LVal, QualType EltTy, APSInt Adjustment)
Update a pointer value to model pointer arithmetic.
static bool extractSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, const SubobjectDesignator &Sub, APValue &Result, AccessKinds AK=AK_Read)
Extract the designated sub-object of an rvalue.
static bool HandleLValueMember(EvalInfo &Info, const Expr *E, LValue &LVal, const FieldDecl *FD, const ASTRecordLayout *RL=nullptr)
Update LVal to refer to the given field, which must be a member of the type currently described by LV...
static void addOrSubLValueAsInteger(APValue &LVal, const APSInt &Index, bool IsSub)
static bool IsDeclSourceLocationCurrent(const FunctionDecl *FD)
static std::optional< uint64_t > EvaluateBuiltinStrLen(const Expr *E, EvalInfo &Info, std::string *StringResult=nullptr)
void HandleComplexComplexDiv(APFloat A, APFloat B, APFloat C, APFloat D, APFloat &ResR, APFloat &ResI)
static bool handleTrivialCopy(EvalInfo &Info, const ParmVarDecl *Param, const Expr *E, APValue &Result, bool CopyObjectRepresentation)
Perform a trivial copy from Param, which is the parameter of a copy or move constructor or assignment...
static bool EvaluateBuiltinConstantPForLValue(const APValue &LV)
EvaluateBuiltinConstantPForLValue - Determine the result of __builtin_constant_p when applied to the ...
static bool EvaluateBuiltinConstantP(EvalInfo &Info, const Expr *Arg)
EvaluateBuiltinConstantP - Evaluate __builtin_constant_p as similarly to GCC as we can manage.
static bool checkNonVirtualMemberCallThisPointer(EvalInfo &Info, const Expr *E, const LValue &This, const CXXMethodDecl *NamedMember)
Check that the pointee of the 'this' pointer in a member function call is either within its lifetime ...
static bool CheckConstantExpression(EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value, ConstantExprKind Kind)
Check that this core constant expression value is a valid value for a constant expression.
static bool EvaluateAsBooleanCondition(const Expr *E, bool &Result, EvalInfo &Info)
static std::optional< DynamicType > ComputeDynamicType(EvalInfo &Info, const Expr *E, LValue &This, AccessKinds AK)
Determine the dynamic type of an object.
static bool EvaluateDecl(EvalInfo &Info, const Decl *D, bool EvaluateConditionDecl=false)
static void expandArray(APValue &Array, unsigned Index)
static bool handleLogicalOpForVector(const APInt &LHSValue, BinaryOperatorKind Opcode, const APInt &RHSValue, APInt &Result)
static unsigned FindDesignatorMismatch(QualType ObjType, const SubobjectDesignator &A, const SubobjectDesignator &B, bool &WasArrayIndex)
Find the position where two subobject designators diverge, or equivalently the length of the common i...
static bool isOnePastTheEndOfCompleteObject(const ASTContext &Ctx, const LValue &LV)
Determine whether this is a pointer past the end of the complete object referred to by the lvalue.
static unsigned getBaseIndex(const CXXRecordDecl *Derived, const CXXRecordDecl *Base)
Get the base index of the given base class within an APValue representing the given derived class.
static bool EvaluateFixedPoint(const Expr *E, APFixedPoint &Result, EvalInfo &Info)
Evaluate only a fixed point expression into an APResult.
void HandleComplexComplexMul(APFloat A, APFloat B, APFloat C, APFloat D, APFloat &ResR, APFloat &ResI)
static bool HandleDestructionImpl(EvalInfo &Info, SourceRange CallRange, const LValue &This, APValue &Value, QualType T, bool IsCompleteClass=true)
static bool EvalPointerValueAsBool(const APValue &Value, bool &Result)
static bool handleVectorVectorBinOp(EvalInfo &Info, const BinaryOperator *E, BinaryOperatorKind Opcode, APValue &LHSValue, const APValue &RHSValue)
static bool EvaluateMatrix(const Expr *E, APValue &Result, EvalInfo &Info)
static const FunctionDecl * getVirtualOperatorDelete(QualType T)
static bool isDesignatorAtObjectEnd(const ASTContext &Ctx, const LValue &LVal)
Checks to see if the given LValue's Designator is at the end of the LValue's record layout....
static bool CheckArraySize(EvalInfo &Info, const ConstantArrayType *CAT, SourceLocation CallLoc={})
static bool EvaluateInPlace(APValue &Result, EvalInfo &Info, const LValue &This, const Expr *E, bool AllowNonLiteralTypes=false)
EvaluateInPlace - Evaluate an expression in-place in an APValue. In some cases, the in-place evaluati...
static bool handleFloatFloatBinOp(EvalInfo &Info, const BinaryOperator *E, APFloat &LHS, BinaryOperatorKind Opcode, const APFloat &RHS)
Perform the given binary floating-point operation, in-place, on LHS.
static std::optional< DynAlloc * > CheckDeleteKind(EvalInfo &Info, const Expr *E, const LValue &Pointer, DynAlloc::Kind DeallocKind)
Check that the given object is a suitable pointer to a heap allocation that still exists and is of th...
static bool HandleClassZeroInitialization(EvalInfo &Info, const Expr *E, const RecordDecl *RD, const LValue &This, APValue &Result, bool IsCompleteClass=true)
Perform zero-initialization on an object of non-union class type. C++11 [dcl.init]p5: To zero-initial...
static bool EvaluateCPlusPlus11IntegralConstantExpr(const ASTContext &Ctx, const Expr *E, llvm::APSInt *Value, bool AllowRelaxedEval=false)
Evaluate an expression as a C++11 integral constant expression.
static bool EvaluateLValue(const Expr *E, LValue &Result, EvalInfo &Info, bool InvalidBaseOK=false)
Evaluate an expression as an lvalue. This can be legitimately called on expressions which are not glv...
static bool HandleConstructorCall(const Expr *E, const LValue &This, CallRef Call, const CXXConstructorDecl *Definition, EvalInfo &Info, APValue &Result, bool IsCompleteClass=true)
Evaluate a constructor call.
static bool FastEvaluateAsRValue(const Expr *Exp, APValue &Result, const ASTContext &Ctx, bool &IsConst)
static bool HandleCovariantReturnAdjustment(EvalInfo &Info, const Expr *E, APValue &Result, ArrayRef< QualType > Path)
Perform the adjustment from a value returned by a virtual function to a value of the statically expec...
static bool evalShiftWithCount(EvalInfo &Info, const CallExpr *Call, APValue &Out, llvm::function_ref< APInt(const APInt &, uint64_t)> ShiftOp, llvm::function_ref< APInt(const APInt &, unsigned)> OverflowOp)
static EvalStmtResult EvaluateSwitch(StmtResult &Result, EvalInfo &Info, const SwitchStmt *SS)
Evaluate a switch statement.
static void expandStringLiteral(EvalInfo &Info, const StringLiteral *S, APValue &Result, QualType AllocType=QualType())
static bool EvaluateArgs(ArrayRef< const Expr * > Args, CallRef Call, EvalInfo &Info, const FunctionDecl *Callee, bool RightToLeft=false, LValue *ObjectArg=nullptr)
Evaluate the arguments to a function call.
static bool EvaluateAtomic(const Expr *E, const LValue *This, APValue &Result, EvalInfo &Info)
static bool getBytesReturnedByAllocSizeCall(const ASTContext &Ctx, const LValue &LVal, llvm::APInt &Result)
Convenience function. LVal's base must be a call to an alloc_size function.
static bool handleIntIntBinOp(EvalInfo &Info, const BinaryOperator *E, const APSInt &LHS, BinaryOperatorKind Opcode, APSInt RHS, APSInt &Result)
Perform the given binary integer operation.
static bool EvaluateInitForDeclOfReferenceType(EvalInfo &Info, const ValueDecl *D, const Expr *Init, LValue &Result, APValue &Val)
Evaluates the initializer of a reference.
static bool checkDynamicType(EvalInfo &Info, const Expr *E, const LValue &This, AccessKinds AK, bool Polymorphic)
Check that we can access the notional vptr of an object / determine its dynamic type.
static bool HandleFloatToIntCast(EvalInfo &Info, const Expr *E, QualType SrcType, const APFloat &Value, QualType DestType, APSInt &Result)
static bool getAlignmentArgument(const Expr *E, QualType ForType, EvalInfo &Info, APSInt &Alignment)
Evaluate the value of the alignment argument to __builtin_align_{up,down}, __builtin_is_aligned and _...
static bool CheckFullyInitialized(EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value)
Check that this evaluated value is fully-initialized and can be loaded by an lvalue-to-rvalue convers...
static SubobjectHandler::result_type findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, const SubobjectDesignator &Sub, SubobjectHandler &handler)
Find the designated sub-object of an rvalue.
static bool determineEndOffset(EvalInfo &Info, SourceLocation ExprLoc, unsigned Type, const LValue &LVal, CharUnits &EndOffset)
Helper for tryEvaluateBuiltinObjectSize – Given an LValue, this will determine how many bytes exist f...
static bool convertUnsignedAPIntToCharUnits(const llvm::APInt &Int, CharUnits &Result)
Converts the given APInt to CharUnits, assuming the APInt is unsigned. Fails if the conversion would ...
static bool EvaluateCallArg(const ParmVarDecl *PVD, const Expr *Arg, CallRef Call, EvalInfo &Info, bool NonNull=false, APValue **EvaluatedArg=nullptr)
llvm::SmallPtrSet< const MaterializeTemporaryExpr *, 8 > CheckedTemporaries
Materialized temporaries that we've already checked to determine if they're initializsed by a constan...
GCCTypeClass EvaluateBuiltinClassifyType(QualType T, const LangOptions &LangOpts)
EvaluateBuiltinClassifyType - Evaluate __builtin_classify_type the same way as GCC.
static bool EvaluateDependentExpr(const Expr *E, EvalInfo &Info)
static bool MaybeEvaluateDeferredVarDeclInit(EvalInfo &Info, const VarDecl *VD)
static APSInt HandleIntToIntCast(EvalInfo &Info, const Expr *E, QualType DestType, QualType SrcType, const APSInt &Value)
static std::optional< APValue > handleVectorUnaryOperator(ASTContext &Ctx, QualType ResultTy, UnaryOperatorKind Op, APValue Elt)
static bool lifetimeStartedInEvaluation(EvalInfo &Info, APValue::LValueBase Base, bool MutableSubobject=false)
static bool isOneByteCharacterType(QualType T)
static bool HandleLambdaCapture(EvalInfo &Info, const Expr *E, LValue &Result, const CXXMethodDecl *MD, const FieldDecl *FD, bool LValueToRValueConversion)
Get an lvalue to a field of a lambda's closure type.
static bool EvaluateCond(EvalInfo &Info, const VarDecl *CondDecl, const Expr *Cond, bool &Result)
Evaluate a condition (either a variable declaration or an expression).
static bool EvaluateAsFixedPoint(const Expr *E, Expr::EvalResult &ExprResult, const ASTContext &Ctx, Expr::SideEffectsKind AllowSideEffects, EvalInfo &Info)
static bool EvaluateAsRValue(EvalInfo &Info, const Expr *E, APValue &Result)
EvaluateAsRValue - Try to evaluate this expression, performing an implicit lvalue-to-rvalue cast if i...
static bool diagnoseMutableFields(EvalInfo &Info, const Expr *E, AccessKinds AK, QualType T)
Diagnose an attempt to read from any unreadable field within the specified type, which might be a cla...
static ICEDiag CheckICE(const Expr *E, const ASTContext &Ctx)
static bool CheckConstexprFunction(EvalInfo &Info, SourceLocation CallLoc, const FunctionDecl *Declaration, const FunctionDecl *Definition, const Stmt *Body)
CheckConstexprFunction - Check that a function can be called in a constant expression.
static bool EvaluateDestruction(const ASTContext &Ctx, APValue::LValueBase Base, APValue DestroyedValue, QualType Type, SourceLocation Loc, Expr::EvalStatus &EStatus, bool IsConstantDestruction)
static bool handleDefaultInitValue(QualType T, APValue &Result, bool IsCompleteClass=true)
Get the value to use for a default-initialized object of type T.
static EvalStmtResult EvaluateStmt(StmtResult &Result, EvalInfo &Info, const Stmt *S, const SwitchCase *SC=nullptr)
static bool EvaluateArrayNewInitList(EvalInfo &Info, LValue &This, APValue &Result, const InitListExpr *ILE, QualType AllocType)
static bool HasSameBase(const LValue &A, const LValue &B)
static bool CheckLocalVariableDeclaration(EvalInfo &Info, const VarDecl *VD)
static bool HandleLValueDirectBase(EvalInfo &Info, const Expr *E, LValue &Obj, const CXXRecordDecl *Derived, const CXXRecordDecl *Base, const ASTRecordLayout *RL=nullptr)
static bool IsGlobalLValue(APValue::LValueBase B)
static llvm::RoundingMode getActiveRoundingMode(EvalInfo &Info, const Expr *E)
Get rounding mode to use in evaluation of the specified expression.
static QualType getObjectType(APValue::LValueBase B)
Retrieves the "underlying object type" of the given expression, as used by __builtin_object_size.
static bool handleCompareOpForVectorHelper(const APTy &LHSValue, BinaryOperatorKind Opcode, const APTy &RHSValue, APInt &Result)
static std::optional< uint64_t > tryEvaluateBuiltinObjectSize(const Expr *E, unsigned Type, EvalInfo &Info, bool IsDynamic=false)
Tries to evaluate the __builtin_object_size for E.
static bool Evaluate(APValue &Result, EvalInfo &Info, const Expr *E)
static bool isReadByLvalueToRvalueConversion(const CXXRecordDecl *RD)
Determine whether a type would actually be read by an lvalue-to-rvalue conversion.
static void negateAsSigned(APSInt &Int)
Negate an APSInt in place, converting it to a signed form if necessary, and preserving its value (by ...
static bool HandleFunctionCall(SourceLocation CallLoc, const FunctionDecl *Callee, const LValue *ObjectArg, const Expr *E, ArrayRef< const Expr * > Args, CallRef Call, const Stmt *Body, EvalInfo &Info, APValue &Result, const LValue *ResultSlot)
Evaluate a function call.
static bool isUserWritingOffTheEnd(const ASTContext &Ctx, const LValue &LVal)
Attempts to detect a user writing into a piece of memory that's impossible to figure out the size of ...
static bool GetLValueBaseAsString(const EvalInfo &Info, const LValue &LVal, LValueBaseString &AsString)
static bool HandleOperatorDeleteCall(EvalInfo &Info, const CallExpr *E)
static bool EvaluateIntegerOrLValue(const Expr *E, APValue &Result, EvalInfo &Info)
EvaluateIntegerOrLValue - Evaluate an rvalue integral-typed expression, and produce either the intege...
static bool HandleDynamicCast(EvalInfo &Info, const ExplicitCastExpr *E, LValue &Ptr)
Apply the given dynamic cast operation on the provided lvalue.
static bool HandleOperatorNewCall(EvalInfo &Info, const CallExpr *E, LValue &Result)
Perform a call to 'operator new' or to ‘__builtin_operator_new’.
static bool HandleFloatToFloatCast(EvalInfo &Info, const Expr *E, QualType SrcType, QualType DestType, APFloat &Result)
static bool MaybeHandleUnionActiveMemberChange(EvalInfo &Info, const Expr *LHSExpr, const LValue &LHS)
Handle a builtin simple-assignment or a call to a trivial assignment operator whose left-hand side mi...
uint8_t GFNIMul(uint8_t AByte, uint8_t BByte)
static bool isFormalAccess(AccessKinds AK)
Is this an access per the C++ definition?
static bool handleCompoundAssignment(EvalInfo &Info, const CompoundAssignOperator *E, const LValue &LVal, QualType LValType, QualType PromotedLValType, BinaryOperatorKind Opcode, const APValue &RVal)
Perform a compound assignment of LVal <op>= RVal.
static bool handleIncDec(EvalInfo &Info, const Expr *E, const LValue &LVal, QualType LValType, bool IsIncrement, APValue *Old)
Perform an increment or decrement on LVal.
static bool EvaluateVoid(const Expr *E, EvalInfo &Info)
static bool HandleDestruction(EvalInfo &Info, const Expr *E, const LValue &This, QualType ThisType)
Perform a destructor or pseudo-destructor call on the given object, which might in general not be a c...
static bool ArePotentiallyOverlappingStringLiterals(const EvalInfo &Info, const LValue &LHS, const LValue &RHS)
uint8_t GFNIMultiplicativeInverse(uint8_t Byte)
uint8_t GFNIAffine(uint8_t XByte, const APInt &AQword, const APSInt &Imm, bool Inverse)
APSInt NormalizeRotateAmount(const APSInt &Value, const APSInt &Amount)
Result
Implement __builtin_bit_cast and related operations.
static bool isModification(AccessKinds AK)
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
llvm::MachO::Record Record
Implements a partial diagnostic which may not be emitted.
llvm::DenseMap< Stmt *, Stmt * > MapTy
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
Expr * getExpr()
Get 'expr' part of the associated expression/statement.
static QualType getPointeeType(const MemRegion *R)
Enumerates target-specific builtins in their own namespaces within namespace clang.
Defines the clang::TypeLoc interface and its subclasses.
C Language Family Type Representation.
__DEVICE__ long long abs(long long __n)
a trap message and trap category.
llvm::APInt getValue() const
unsigned getVersion() const
QualType getDynamicAllocType() const
QualType getTypeInfoType() const
static LValueBase getTypeInfo(TypeInfoLValue LV, QualType TypeInfo)
static LValueBase getDynamicAlloc(DynamicAllocLValue LV, QualType Type)
A non-discriminated union of a base, field, or array index.
BaseOrMemberType getAsBaseOrMember() const
static LValuePathEntry ArrayIndex(uint64_t Index)
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
bool hasArrayFiller() const
const LValueBase getLValueBase() const
APValue & getArrayInitializedElt(unsigned I)
void swap(APValue &RHS)
Swaps the contents of this and the given APValue.
APValue & getStructField(unsigned i)
unsigned getMatrixNumColumns() const
const FieldDecl * getUnionField() const
APSInt & getComplexIntImag()
bool isComplexInt() const
llvm::PointerIntPair< const Decl *, 1, bool > BaseOrMemberType
A FieldDecl or CXXRecordDecl, along with a flag indicating whether we mean a virtual or non-virtual b...
ValueKind getKind() const
APValue & getStructVirtualBase(unsigned i)
unsigned getArrayInitializedElts() const
static APValue IndeterminateValue()
unsigned getStructNumBases() const
APFixedPoint & getFixedPoint()
bool hasLValuePath() const
const ValueDecl * getMemberPointerDecl() const
APValue & getUnionValue()
CharUnits & getLValueOffset()
void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const
bool isComplexFloat() const
APValue & getVectorElt(unsigned I)
APValue & getArrayFiller()
unsigned getVectorLength() const
void setUnion(const FieldDecl *Field, const APValue &Value)
bool isIndeterminate() const
unsigned getMatrixNumRows() const
unsigned getArraySize() const
bool allowConstexprUnknown() const
std::string getAsString(const ASTContext &Ctx, QualType Ty) const
bool isFixedPoint() const
APValue & getMatrixElt(unsigned Idx)
@ Indeterminate
This object has an indeterminate value (C++ [basic.indet]).
@ None
There is no such object (it's outside its lifetime).
APSInt & getComplexIntReal()
APFloat & getComplexFloatImag()
APFloat & getComplexFloatReal()
APValue & getStructBase(unsigned i)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
SourceManager & getSourceManager()
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
unsigned getIntWidth(QualType T) const
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
uint64_t getTargetNullPointerValue(QualType QT) const
Get target-dependent integer value for null pointer which is used for constant folding.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
unsigned getPreferredTypeAlign(QualType T) const
Return the "preferred" alignment of the specified type T for the current target, in bits.
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
Builtin::Context & BuiltinInfo
const LangOptions & getLangOpts() const
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
const TargetInfo * getAuxTargetInfo() const
interp::Context & getInterpContext() const
Returns the clang bytecode interpreter context.
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
const clang::PrintingPolicy & getPrintingPolicy() const
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
llvm::APSInt MakeIntValue(uint64_t Value, QualType Type) const
Make an APSInt of the appropriate width and signedness for the given Value and integer Type.
const VariableArrayType * getAsVariableArrayType(QualType T) const
const TargetInfo & getTargetInfo() const
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
CanQualType getCanonicalTagType(const TagDecl *TD) const
uint64_t getCharWidth() const
Return the size of the character type, in bits.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
unsigned getFieldCount() const
getFieldCount - Get the number of fields in the layout.
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - Get the offset, in chars, for the given base class.
LabelDecl * getLabel() const
OpaqueValueExpr * getCommonExpr() const
Get the common subexpression shared by all initializations (the source array).
Expr * getSubExpr() const
Get the initializer to use for each array element.
Expr * getLHS()
An array access can be written A[4] or 4[A] (both are equivalent).
uint64_t getValue() const
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
QualType getValueType() const
Gets the type contained by this atomic type, i.e.
Attr - This represents one attribute.
BinaryConditionalOperator - The GNU extension to the conditional operator which allows the middle ope...
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression which will be evaluated if the condition evaluates to false; ...
OpaqueValueExpr * getOpaqueValue() const
getOpaqueValue - Return the opaque value placeholder.
Expr * getCommon() const
getCommon - Return the common expression, written to the left of the condition.
A builtin binary operation expression such as "x + y" or "x <= y".
static bool isLogicalOp(Opcode Opc)
static bool isRelationalOp(Opcode Opc)
static bool isComparisonOp(Opcode Opc)
static Opcode getOpForCompoundAssignment(Opcode Opc)
SourceLocation getExprLoc() const
static bool isAdditiveOp(Opcode Opc)
static bool isPtrMemOp(Opcode Opc)
predicates to categorize the respective opcodes.
static bool isAssignmentOp(Opcode Opc)
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
static bool isEqualityOp(Opcode Opc)
bool hasCaptures() const
True if this block (or its nested blocks) captures anything of local storage from its enclosing scope...
const BlockDecl * getBlockDecl() const
bool isAuxBuiltinID(unsigned ID) const
Return true if the builtin ID belongs exclusively to the AuxTarget, and false if it belongs to both p...
unsigned getAuxBuiltinID(unsigned ID) const
Return real builtin ID (i.e.
AccessSpecifier Access
The access along this inheritance path.
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
bool isAmbiguous(CanQualType BaseType) const
Determine whether the path from the most-derived type to the given base type is ambiguous (i....
Represents a base class of a C++ class.
SourceLocation getBeginLoc() const LLVM_READONLY
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
QualType getType() const
Retrieves the type of the base class.
const Expr * getSubExpr() const
Represents a call to a C++ constructor.
bool isElidable() const
Whether this construction is elidable.
Expr * getArg(unsigned Arg)
Return the specified argument.
bool requiresZeroInitialization() const
Whether this construction first requires zero-initialization before the initializer is called.
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
unsigned getNumArgs() const
Return the number of arguments to the constructor call.
Represents a C++ constructor within a class.
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
CXXCtorInitializer *const * init_const_iterator
Iterates through the member/base initializer list.
Expr * getExpr()
Get the initialization expression that will be used.
FunctionDecl * getOperatorDelete() const
bool isGlobalDelete() const
Represents a C++ destructor within a class.
CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for statement, represented as 'for (ra...
DeclStmt * getBeginStmt()
DeclStmt * getLoopVarStmt()
DeclStmt * getRangeStmt()
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will call.
Represents a static or instance method of a struct/union/class.
bool isExplicitObjectMemberFunction() const
[C++2b][dcl.fct]/p7 An explicit object member function is a non-static member function with an explic...
bool isImplicitObjectMemberFunction() const
[C++2b][dcl.fct]/p7 An implicit object member function is a non-static member function without an exp...
QualType getFunctionObjectParameterReferenceType() const
Return the type of the object pointed by this.
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
bool isMoveAssignmentOperator() const
Determine whether this is a move assignment operator.
bool isCopyAssignmentOperator() const
Determine whether this is a copy-assignment operator, regardless of whether it was declared implicitl...
bool isLambdaStaticInvoker() const
Determine whether this is a lambda closure type's static member function that is used for the result ...
QualType getAllocatedType() const
std::optional< Expr * > getArraySize()
This might return std::nullopt even if isArray() returns true, since there might not be an array size...
Expr * getPlacementArg(unsigned I)
unsigned getNumPlacementArgs() const
SourceRange getSourceRange() const
FunctionDecl * getOperatorNew() const
Expr * getInitializer()
The initializer of this new-expression.
MutableArrayRef< Expr * > getInitExprs()
Represents a C++ struct/union/class.
bool hasMutableFields() const
Determine whether this class, or any of its class subobjects, contains a mutable field.
bool isGenericLambda() const
Determine whether this class describes a generic lambda function object (i.e.
bool hasTrivialDestructor() const
Determine whether this class has a trivial destructor (C++ [class.dtor]p3)
void getCaptureFields(llvm::DenseMap< const ValueDecl *, FieldDecl * > &Captures, FieldDecl *&ThisCapture) const
For a closure type, retrieve the mapping from captured variables and this to the non-static data memb...
unsigned getNumBases() const
Retrieves the number of base classes of this class.
base_class_range vbases()
capture_const_range captures() const
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
CXXMethodDecl * getLambdaCallOperator() const
Retrieve the lambda call operator of the closure type if this is a closure type.
CXXRecordDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
bool isDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is derived from the class Base.
Expr * getSemanticForm()
Get an equivalent semantic form for this expression.
bool isTypeOperand() const
QualType getTypeOperand(const ASTContext &Context) const
Retrieves the type operand of this typeid() expression after various required adjustments (removing r...
Expr * getExprOperand() const
bool isPotentiallyEvaluated() const
Determine whether this typeid has a type operand which is potentially evaluated, per C++11 [expr....
MSGuidDecl * getGuidDecl() const
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
SourceLocation getBeginLoc() const
const AllocSizeAttr * getCalleeAllocSizeAttr() const
Try to get the alloc_size attribute of the callee. May return null.
unsigned getBuiltinCallee() const
getBuiltinCallee - If this is a call to a builtin, return the builtin ID of the callee.
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
Expr ** getArgs()
Retrieve the call arguments.
QualType getCallReturnType(const ASTContext &Ctx) const
getCallReturnType - Get the return type of the call expr.
CaseStmt - Represent a case statement.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
path_iterator path_begin()
unsigned path_size() const
CastKind getCastKind() const
const FieldDecl * getTargetUnionField() const
const CXXBaseSpecifier *const * path_const_iterator
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operation.
CharUnits - This is an opaque type for sizes expressed in character units.
bool isPowerOfTwo() const
isPowerOfTwo - Test whether the quantity is a power of two.
CharUnits alignmentAtOffset(CharUnits offset) const
Given that this is a non-zero alignment value, what is the alignment at the given offset?
bool isZero() const
isZero - Test whether the quantity equals zero.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
unsigned getValue() const
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
const ValueInfo * getValueInfo(ComparisonCategoryResult ValueKind) const
ComparisonCategoryResult makeWeakResult(ComparisonCategoryResult Res) const
Converts the specified result kind into the correct result kind for this category.
Complex values, per C99 6.2.5p11.
QualType getElementType() const
CompoundAssignOperator - For compound assignments (e.g.
QualType getComputationLHSType() const
CompoundLiteralExpr - [C99 6.5.2.5].
bool hasStaticStorage() const
APValue & getOrCreateStaticValue(ASTContext &Ctx) const
const Expr * getInitializer() const
CompoundStmt - This represents a group of statements like { stmt stmt }.
Stmt *const * const_body_iterator
body_iterator body_begin()
bool isSatisfied() const
Whether or not the concept with the given arguments was satisfied when the expression was created.
ConditionalOperator - The ?
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
Expr * getCond() const
getCond - Return the expression representing the condition for the ?
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
Represents the canonical version of C arrays with a specified constant size.
unsigned getSizeBitWidth() const
Return the bit width of the size type.
static unsigned getNumAddressingBits(const ASTContext &Context, QualType ElementType, const llvm::APInt &NumElements)
Determine the number of bits required to address a member of.
static unsigned getMaxSizeBits(const ASTContext &Context)
Determine the maximum number of active bits that an array's size can require, which limits the maximu...
uint64_t getLimitedSize() const
Return the size zero-extended to uint64_t or UINT64_MAX if the value is larger than UINT64_MAX.
bool isZeroSize() const
Return true if the size is zero.
const Expr * getSizeExpr() const
Return a pointer to the size expression.
llvm::APInt getSize() const
Return the constant array size as an APInt.
uint64_t getZExtSize() const
Return the size zero-extended as a uint64_t.
APValue getAPValueResult() const
bool hasAPValueResult() const
Represents a concrete matrix type with constant number of rows and columns.
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
Represents the current source location and context used to determine the value of the source location...
const Expr * getDefaultExpr() const
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool Equals(const DeclContext *DC) const
Determine whether this declaration context is equivalent to the declaration context DC.
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
A reference to a declared variable, function, enum, etc.
bool refersToEnclosingVariableOrCapture() const
Does this DeclRefExpr refer to an enclosing local or a captured variable?
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Decl - This represents one declaration (or definition), e.g.
bool isInStdNamespace() const
ASTContext & getASTContext() const LLVM_READONLY
bool isInvalidDecl() const
SourceLocation getLocation() const
DeclContext * getDeclContext()
AccessSpecifier getAccess() const
bool isAnyOperatorNew() const
A decomposition declaration.
auto flat_bindings() const
InitListExpr * getUpdater() const
Designator - A designator in a C99 designated initializer.
DoStmt - This represents a 'do/while' stmt.
Symbolic representation of a dynamic allocation.
static unsigned getMaxIndex()
const Expr * getBase() const
ChildElementIter< false > begin()
ExplicitCastExpr - An explicit cast written in the source code.
QualType getTypeAsWritten() const
getTypeAsWritten - Returns the type that this expression is casting to, as written in the source code...
This represents one expression.
const Expr * skipRValueSubobjectAdjustments(SmallVectorImpl< const Expr * > &CommaLHS, SmallVectorImpl< SubobjectAdjustment > &Adjustments) const
Walk outwards from an expression we want to bind a reference to and find the expression whose lifetim...
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
static bool isPotentialConstantExpr(const FunctionDecl *FD, SmallVectorImpl< PartialDiagnosticAt > &Diags)
isPotentialConstantExpr - Return true if this function's definition might be usable in a constant exp...
bool isIntegerConstantExpr(const ASTContext &Ctx) const
static bool isPotentialConstantExprUnevaluated(Expr *E, const FunctionDecl *FD, SmallVectorImpl< PartialDiagnosticAt > &Diags)
isPotentialConstantExprUnevaluated - Return true if this expression might be usable in a constant exp...
@ SE_AllowSideEffects
Allow any unmodeled side effect.
@ SE_AllowUndefinedBehavior
Allow UB that we can give a value, but not arbitrary unmodeled side effects.
bool EvaluateCharRangeAsString(std::string &Result, const Expr *SizeExpression, const Expr *PtrExpression, ASTContext &Ctx, EvalResult &Status) const
llvm::APSInt EvaluateKnownConstIntCheckOverflow(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
bool isValueDependent() const
Determines whether the value of this expression depends on.
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Returns the set of floating point options that apply to this expression.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
bool containsErrors() const
Whether this expression contains subexpressions which had errors.
bool EvaluateAsFloat(llvm::APFloat &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsFloat - Return true if this is a constant which we can fold and convert to a floating point...
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsLValue - Evaluate an expression to see if we can fold it to an lvalue with link time known ...
bool EvaluateAsInitializer(const ASTContext &Ctx, const VarDecl *VD, EvalResult &Result, bool IsConstantInitializer) const
EvaluateAsInitializer - Evaluate an expression as if it were the initializer of the given declaration...
bool EvaluateAsFixedPoint(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsFixedPoint - Return true if this is a constant which we can fold and convert to a fixed poi...
bool isEvaluatable(const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
isEvaluatable - Call EvaluateAsRValue to see if this expression can be constant folded without side-e...
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language.
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...
std::optional< uint64_t > tryEvaluateStrLen(const ASTContext &Ctx) const
If the current Expr is a pointer, this will try to statically determine the strlen of the string poin...
bool HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects=true) const
HasSideEffects - This routine returns true for all those expressions which have any effect other than...
bool EvaluateAsConstantExpr(EvalResult &Result, const ASTContext &Ctx, ConstantExprKind Kind=ConstantExprKind::Normal) const
Evaluate an expression that is required to be a constant expression.
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx, bool AllowRelaxedEval=false) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
std::optional< std::string > tryEvaluateString(ASTContext &Ctx) const
If the current Expr can be evaluated to a pointer to a null-terminated constant string,...
bool EvaluateAsBooleanCondition(bool &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsBooleanCondition - Return true if this is a constant which we can fold and convert to a boo...
bool isTemporaryObject(ASTContext &Ctx, const CXXRecordDecl *TempTy) const
Determine whether the result of this expression is a temporary object of the given class type.
std::optional< uint64_t > tryEvaluateObjectSize(const ASTContext &Ctx, unsigned Type) const
If the current Expr is a pointer, this will try to statically determine the number of bytes available...
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
bool isCXX98IntegralConstantExpr(const ASTContext &Ctx) const
isCXX98IntegralConstantExpr - Return true if this expression is an integral constant expression in C+...
bool EvaluateWithSubstitution(APValue &Value, ASTContext &Ctx, const FunctionDecl *Callee, ArrayRef< const Expr * > Args, const Expr *This=nullptr) const
EvaluateWithSubstitution - Evaluate an expression as if from the context of a call to the given funct...
bool isCXX11ConstantExpr(const ASTContext &Ctx, APValue *Result=nullptr, bool AllowRelaxedEval=false) const
isCXX11ConstantExpr - Return true if this expression is a constant expression in C++11.
void EvaluateForOverflow(const ASTContext &Ctx) const
bool isArrow() const
isArrow - Return true if the base expression is a pointer to vector, return false if the base express...
void getEncodedElementAccess(SmallVectorImpl< uint32_t > &Elts) const
getEncodedElementAccess - Encode the elements accessed into an llvm aggregate Constant of ConstantInt...
bool isFPConstrained() const
LangOptions::FPExceptionModeKind getExceptionMode() const
RoundingMode getRoundingMode() const
Represents a member of a struct/union/class.
bool isBitField() const
Determines whether this field is a bitfield.
unsigned getBitWidthValue() const
Computes the bit width of this field, if this is a bit field.
unsigned getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
FieldDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this field.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
llvm::APInt getValue() const
Returns an internal integer representation of the literal.
llvm::APFloat getValue() const
ForStmt - This represents a 'for (init;cond;inc)' stmt.
VarDecl * getConditionVariable() const
Retrieve the variable declared in this "for" statement, if any.
const Expr * getSubExpr() const
Represents a function declaration or definition.
const ParmVarDecl * getParamDecl(unsigned i) const
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
bool isFunctionTemplateSpecialization() const
Determine whether this function is a function template specialization.
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
bool hasCXXExplicitFunctionObjectParameter() const
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
bool isConstexpr() const
Whether this is a (C++11) constexpr function or constexpr constructor.
bool isUsableAsGlobalAllocationFunctionInConstantEvaluation(UnsignedOrNone *AlignmentParam=nullptr, bool *IsNothrow=nullptr) const
Determines whether this function is one of the replaceable global allocation functions described in i...
bool isDefaulted() const
Whether this function is defaulted.
void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override
Appends a human-readable name for this declaration into the given stream.
FunctionDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
Expr * getResultExpr()
Return the result expression of this controlling expression.
One of these records is kept for each identifier that is lexed.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
IfStmt - This represents an if/then/else.
bool isNonNegatedConsteval() const
VarDecl * getConditionVariable()
Retrieve the variable declared in this "if" statement, if any.
const Expr * getSubExpr() const
Represents an implicitly-generated value initialization of an object of a given type.
Represents a field injected from an anonymous union/struct into the parent scope.
ArrayRef< NamedDecl * > chain() const
Describes an C or C++ initializer list.
bool isTransparent() const
Is this a transparent initializer list (that is, an InitListExpr that is purely syntactic,...
bool isStringLiteralInit() const
Is this an initializer for an array of characters, initialized by a string literal or an @encode?
unsigned getNumInits() const
Expr * getArrayFiller()
If this initializer list initializes an array with more elements than there are initializers in the l...
const Expr * getInit(unsigned Init) const
ArrayRef< Expr * > inits() const
capture_init_iterator capture_init_end()
Retrieve the iterator pointing one past the last initialization argument for this lambda expression.
capture_init_iterator capture_init_begin()
Retrieve the first initialization argument for this lambda expression (which initializes the first ca...
CXXRecordDecl * getLambdaClass() const
Retrieve the class that corresponds to the lambda.
StrictFlexArraysLevelKind
@ FPE_Ignore
Assume that floating-point exceptions are masked.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
bool isCompatibleWith(ClangABI Version) const
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
StorageDuration getStorageDuration() const
Retrieve the storage duration for the materialized temporary.
Expr * getSubExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue.
APValue * getOrCreateValue(bool MayCreate) const
Get the storage for the constant value of a materialized temporary of static storage duration.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
void printQualifiedName(raw_ostream &OS) const
Returns a human-readable qualified name for this declaration, like A::B::i, for i being member of nam...
bool isExpressibleAsConstantInitializer() const
Expr * getIndexExpr(unsigned Idx)
const OffsetOfNode & getComponent(unsigned Idx) const
TypeSourceInfo * getTypeSourceInfo() const
unsigned getNumComponents() const
unsigned getArrayExprIndex() const
For an array element node, returns the index into the array of expressions.
FieldDecl * getField() const
For a field offsetof node, returns the field.
@ Array
An index into an array.
@ Identifier
A field in a dependent type, known only by its name.
@ Base
An implicit indirection through a C++ base class, when the field found is in a base class.
Kind getKind() const
Determine what kind of offsetof node this is.
CXXBaseSpecifier * getBase() const
For a base class node, returns the base specifier.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
Expr * getSelectedExpr() const
const Expr * getSubExpr() const
Represents a parameter to a function.
unsigned getFunctionScopeIndex() const
Returns the index of this parameter in its prototype or method scope.
bool isExplicitObjectParameter() const
PointerType - C99 6.7.5.1 - Pointer Declarators.
StringLiteral * getFunctionName()
Expr * getResultExpr()
Return the result-bearing expression, or null if there is none.
ArrayRef< Expr * > semantics()
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
QualType withConst() const
void addConst()
Add the const type qualifier to this QualType.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
void removeLocalVolatile()
void addVolatile()
Add the volatile type qualifier to this QualType.
bool isConstQualified() const
Determine whether this type is const-qualified.
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after.
unsigned getCVRQualifiers() const
Retrieve the set of CVR (const-volatile-restrict) qualifiers applied to this type.
bool isWrapType() const
Returns true if it is a OverflowBehaviorType of Wrap kind.
Represents a struct/union/class.
unsigned getNumFields() const
Returns the number of fields (non-static data members) in this record.
field_iterator field_end() const
field_range fields() const
specific_decl_iterator< FieldDecl > field_iterator
bool isAnonymousStructOrUnion() const
Whether this is an anonymous struct or union.
field_iterator field_begin() const
bool isSatisfied() const
Whether or not the requires clause is satisfied.
SourceLocation getLocation() const
std::string ComputeName(ASTContext &Context) const
Scope - A scope is a transient data structure that is used while parsing the program.
ShuffleVectorExpr - clang-specific builtin-in function __builtin_shufflevector.
llvm::APSInt getShuffleMaskIdx(unsigned N) const
unsigned getNumSubExprs() const
getNumSubExprs - Return the size of the SubExprs array.
Expr * getExpr(unsigned Index)
getExpr - Return the Expr at the specified index.
unsigned getPackLength() const
Retrieve the length of the parameter pack.
APValue EvaluateInContext(const ASTContext &Ctx, const Expr *DefaultExpr) const
Return the result of evaluating this SourceLocExpr in the specified (and possibly null) default argum...
Encodes a location in the source.
A trivial tuple used to represent a source range.
SourceLocation getBegin() const
std::string printToString(const SourceManager &SM) const
CompoundStmt * getSubStmt()
Stmt - This represents one statement.
StmtClass getStmtClass() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
SourceLocation getBeginLoc() const LLVM_READONLY
StringLiteral - This represents a string literal expression, e.g.
unsigned getLength() const
StringRef getBytes() const
Allow access to clients that need the byte representation, such as ASTWriterStmt::VisitStringLiteral(...
uint32_t getCodeUnit(size_t i) const
StringRef getString() const
unsigned getCharByteWidth() const
Expr * getReplacement() const
const SwitchCase * getNextSwitchCase() const
SwitchStmt - This represents a 'switch' stmt.
VarDecl * getConditionVariable()
Retrieve the variable declared in this "switch" statement, if any.
SwitchCase * getSwitchCaseList()
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
TagDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Exposes information about the current target.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
unsigned size() const
Retrieve the number of template arguments in this template argument list.
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
@ Type
The template argument is a type.
Symbolic representation of typeid(T) for some type T.
QualType getType() const
Return the type wrapped by this type source info.
bool getBoolValue() const
const APValue & getAPValue() const
bool isStoredAsBoolean() const
The base class of the type hierarchy.
bool isBooleanType() const
bool isFunctionReferenceType() const
bool isMFloat8Type() const
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
bool isPackedVectorBoolType(const ASTContext &ctx) const
bool isLiteralType(const ASTContext &Ctx) const
Return true if this is a literal type (C++11 [basic.types]p10)
bool isIncompleteArrayType() const
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
bool isComplexType() const
isComplexType() does not include complex integers (a GCC extension).
const ArrayType * castAsArrayTypeUnsafe() const
A variant of castAs<> for array type which silently discards qualifiers from the outermost type.
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
bool isIntegralOrUnscopedEnumerationType() const
Determine whether this type is an integral or unscoped enumeration type.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isConstantArrayType() const
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isVoidPointerType() const
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6....
bool isFunctionPointerType() const
bool isCountAttributedType() const
bool isConstantMatrixType() const
bool isPointerType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isEnumeralType() const
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
bool isVariableArrayType() const
bool isSveVLSBuiltinType() const
Determines if this is a sizeless type supported by the 'arm_sve_vector_bits' type attribute,...
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
bool isExtVectorBoolType() const
bool isMemberDataPointerType() const
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
RecordDecl * castAsRecordDecl() const
bool isAnyComplexType() const
bool isFixedPointType() const
Return true if this is a fixed point type according to ISO/IEC JTC1 SC22 WG14 N1169.
bool isMemberPointerType() const
bool isAtomicType() const
bool isComplexIntegerType() const
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isObjectType() const
Determine whether this type is an object type.
EnumDecl * getAsEnumDecl() const
Retrieves the EnumDecl this type refers to.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
bool isFunctionType() const
bool isVectorType() const
bool isRealFloatingType() const
Floating point categories.
bool isFloatingType() const
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
const T * castAsCanonical() const
Return this type's canonical type cast to the specified type.
bool isAnyPointerType() const
TypeClass getTypeClass() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isNullPtrType() const
bool isRecordType() const
bool isSizelessVectorType() const
Returns true for all scalable vector types.
bool hasPointerRepresentation() const
Whether this type is represented natively as a pointer.
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
QualType getArgumentType() const
SourceLocation getBeginLoc() const LLVM_READONLY
QualType getTypeOfArgument() const
Gets the argument type, or the type of the argument expression, whichever is appropriate.
bool isArgumentType() const
UnaryExprOrTypeTrait getKind() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
SourceLocation getExprLoc() const
Expr * getSubExpr() const
static bool isIncrementOp(Opcode Op)
bool canOverflow() const
Returns true if the unary operator can cause an overflow.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
bool isWeak() const
Determine whether this symbol is weakly-imported, or declared with the weak or weak-ref attr.
Represents a variable declaration or definition.
bool isConstexpr() const
Whether this variable is (C++11) constexpr.
bool hasICEInitializer(const ASTContext &Context) const
Determine whether the initializer of this variable is an integer constant expression.
bool isInitCapture() const
Whether this variable is the implicit variable for a lambda init-capture.
const APValue * getEvaluatedValue() const
Return the already-evaluated value of this variable's initializer, or nullptr if the value is not yet...
CharUnits getFlexibleArrayInitChars(const ASTContext &Ctx) const
If hasFlexibleArrayInit is true, compute the number of additional bytes necessary to store those elem...
bool hasConstantInitialization() const
Determine whether this variable has constant initialization.
VarDecl * getDefinition(ASTContext &)
Get the real (not just tentative) definition for this declaration.
bool mightBeUsableInConstantExpressions(const ASTContext &C) const
Determine whether this variable's value might be usable in a constant expression, according to the re...
EvaluatedStmt * ensureEvaluatedStmt() const
Convert the initializer for this declaration to the elaborated EvaluatedStmt form,...
bool evaluateDestruction(SmallVectorImpl< PartialDiagnosticAt > &Notes) const
Evaluate the destruction of this variable to determine if it constitutes constant destruction.
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
ThreadStorageClassSpecifier getTSCSpec() const
const Expr * getInit() const
const APValue * evaluateValue() const
Attempt to evaluate the value of the initializer attached to this declaration, and produce notes expl...
bool hasLocalStorage() const
Returns true if a variable with function scope is a non-static local variable.
DefinitionKind hasDefinition(ASTContext &) const
Check whether this variable is defined in this translation unit.
bool isLocalVarDecl() const
Returns true for local variable declarations other than parameters.
bool isUsableInConstantExpressions(const ASTContext &C) const
Determine whether this variable's value can be used in a constant expression, according to the releva...
const Expr * getAnyInitializer() const
Get the initializer for this variable, no matter which declaration it is attached to.
Expr * getSizeExpr() const
Represents a GCC generic vector type.
unsigned getNumElements() const
QualType getElementType() const
WhileStmt - This represents a 'while' stmt.
VarDecl * getConditionVariable()
Retrieve the variable declared in this "while" statement, if any.
bool evaluateDestruction(State &Parent, const VarDecl *VD, APValue Value)
Evaluates the destruction of a variable.
Base class for stack frames, shared between VM and walker.
Interface for the VM to interact with the AST walker's context.
Defines the clang::TargetInfo interface.
bool computeOSLogBufferLayout(clang::ASTContext &Ctx, const clang::CallExpr *E, OSLogBufferLayout &layout)
static const FunctionDecl * getCallee(const CXXConstructExpr &D)
uint32_t Literal
Literals are represented as positive integers.
unsigned kind
All of the diagnostics that can be emitted by the frontend.
std::optional< llvm::AllocTokenMetadata > getAllocTokenMetadata(QualType T, const ASTContext &Ctx)
Get the information required for construction of an allocation token ID.
QualType inferPossibleType(const CallExpr *E, const ASTContext &Ctx, const CastExpr *CastE)
Infer the possible allocated type from an allocation call expression.
bool Sub(InterpState &S, CodePtr OpPC)
bool NE(InterpState &S, CodePtr OpPC)
llvm::FixedPointSemantics FixedPointSemantics
bool This(InterpState &S, CodePtr OpPC)
bool Alloc(InterpState &S, CodePtr OpPC, const Descriptor *Desc)
std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl
All declarations that can appear in a module declaration.
void info(bool Verbose, unsigned Level, const char *Fmt, Ts &&...Args)
Prints an indented note to stderr when Verbose is set.
AccessKind
This enum distinguishes between different ways to access (read or write) a variable.
Top level wrappers for InstallAPI frontend operations.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
bool isa(CodeGen::Address addr)
const Expr * findStructFieldAccess(const Expr *E, const Expr **OutArrayIndex=nullptr, QualType *OutArrayElementTy=nullptr)
Walk E through parens, implicit casts, unary &/*, array subscripts and comma operators to find the he...
bool hasSpecificAttr(const Container &container)
@ NonNull
Values of this type can never be null.
@ Success
Annotation was successful.
Expr::ConstantExprKind ConstantExprKind
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
bool operator==(const CallGraphNode::CallRecord &LHS, const CallGraphNode::CallRecord &RHS)
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
bool isLambdaCallWithExplicitObjectParameter(const DeclContext *DC)
ComparisonCategoryResult
An enumeration representing the possible results of a three-way comparison.
CheckSubobjectKind
The order of this enum is important for diagnostics.
@ SD_Static
Static storage duration.
@ SD_FullExpression
Full-expression storage duration (for temporaries).
bool isLambdaCallOperator(const CXXMethodDecl *MD)
@ Result
The result type of a method or function.
AccessKinds
Kinds of access we can perform on an object, for diagnostics.
@ AK_ReadObjectRepresentation
const FunctionProtoType * T
@ Off
Never emit colors regardless of the output stream.
@ Type
The name was classified as a type.
CastKind
CastKind - The kind of operation required for a conversion.
llvm::hash_code hash_value(const CustomizableOptional< T > &O)
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs.
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
@ ConstantFold
Fold the expression to a constant.
@ ConstantExpressionUnevaluated
Evaluate as a constant expression.
@ ConstantExpression
Evaluate as a constant expression.
@ IgnoreSideEffects
Evaluate in any way we know how.
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
U cast(CodeGen::Address addr)
@ None
The alignment was not explicit in code.
@ ArrayBound
Array bound in array declarator or new-expression.
@ Class
The "class" keyword introduces the elaborated-type-specifier.
ActionResult< Expr * > ExprResult
@ Other
Other implicit parameter.
ActionResult< Stmt * > StmtResult
Diagnostic wrappers for TextAPI types for error reporting.
hash_code hash_value(const clang::dependencies::ModuleID &ID)
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 int32_t
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 uint8_t
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 __packed_splat4 uint16_t
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 __packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 uint32_t
unsigned PathLength
The corresponding path length in the lvalue.
const CXXRecordDecl * Type
The dynamic class type of the object.
std::string ObjCEncodeStorage
Represents an element in a path from a derived class to a base class.
EvalResult is a struct with detailed info about an evaluated expression.
APValue Val
Val - This is the value the expression can be folded to.
bool isGlobalLValue() const
Return true if the evaluated lvalue expression is global.
EvalStatus is a struct with detailed info about an evaluation in progress.
SmallVectorImpl< PartialDiagnosticAt > * Diag
Diag - If this is non-null, it will be filled in with a stack of notes indicating why evaluation fail...
bool HasSideEffects
Whether the evaluated expression has side effects.
unsigned SuppressLambdaBody
Whether to suppress printing the body of a lambda.
@ DerivedToBaseAdjustment
@ MemberPointerAdjustment
DenseMapInfo< APValue::LValueBase > Base
static unsigned getHashValue(const ObjectUnderConstruction &Object)
static bool isEqual(const ObjectUnderConstruction &LHS, const ObjectUnderConstruction &RHS)