59#include "llvm/ADT/APFixedPoint.h"
60#include "llvm/ADT/Sequence.h"
61#include "llvm/ADT/SmallBitVector.h"
62#include "llvm/ADT/StringExtras.h"
63#include "llvm/Support/Casting.h"
64#include "llvm/Support/Debug.h"
65#include "llvm/Support/SaveAndRestore.h"
66#include "llvm/Support/SipHash.h"
67#include "llvm/Support/TimeProfiler.h"
68#include "llvm/Support/raw_ostream.h"
74#define DEBUG_TYPE "exprconstant"
77using llvm::APFixedPoint;
81using llvm::FixedPointSemantics;
88 using SourceLocExprScopeGuard =
119 static unsigned countNonVirtualBases(
const CXXRecordDecl *RD) {
120 return llvm::count_if(RD->
bases(), [](
auto &B) { return !B.isVirtual(); });
127 static const CallExpr *tryUnwrapAllocSizeCall(
const Expr *E) {
135 if (
const auto *FE = dyn_cast<FullExpr>(E))
138 if (
const auto *Cast = dyn_cast<CastExpr>(E))
139 E = Cast->getSubExpr()->IgnoreParens();
141 if (
const auto *CE = dyn_cast<CallExpr>(E))
142 return CE->getCalleeAllocSizeAttr() ? CE :
nullptr;
149 const auto *E =
Base.dyn_cast<
const Expr *>();
150 return E && E->getType()->isPointerType() && tryUnwrapAllocSizeCall(E);
158 case ConstantExprKind::Normal:
159 case ConstantExprKind::ClassTemplateArgument:
160 case ConstantExprKind::ImmediateInvocation:
165 case ConstantExprKind::NonClassTemplateArgument:
168 llvm_unreachable(
"unknown ConstantExprKind");
173 case ConstantExprKind::Normal:
174 case ConstantExprKind::ImmediateInvocation:
177 case ConstantExprKind::ClassTemplateArgument:
178 case ConstantExprKind::NonClassTemplateArgument:
181 llvm_unreachable(
"unknown ConstantExprKind");
187 static const uint64_t AssumedSizeForUnsizedArray =
188 std::numeric_limits<uint64_t>::max() / 2;
198 bool &FirstEntryIsUnsizedArray) {
201 assert(!isBaseAnAllocSizeCall(
Base) &&
202 "Unsized arrays shouldn't appear here");
203 unsigned MostDerivedLength = 0;
208 for (
unsigned I = 0, N = Path.size(); I != N; ++I) {
212 MostDerivedLength = I + 1;
215 if (
auto *CAT = dyn_cast<ConstantArrayType>(AT)) {
216 ArraySize = CAT->getZExtSize();
218 assert(I == 0 &&
"unexpected unsized array designator");
219 FirstEntryIsUnsizedArray =
true;
220 ArraySize = AssumedSizeForUnsizedArray;
226 MostDerivedLength = I + 1;
229 Type = VT->getElementType();
230 ArraySize = VT->getNumElements();
231 MostDerivedLength = I + 1;
233 }
else if (
const FieldDecl *FD = getAsField(Path[I])) {
234 Type = FD->getType();
236 MostDerivedLength = I + 1;
244 return MostDerivedLength;
248 struct SubobjectDesignator {
252 LLVM_PREFERRED_TYPE(
bool)
256 LLVM_PREFERRED_TYPE(
bool)
257 unsigned IsOnePastTheEnd : 1;
260 LLVM_PREFERRED_TYPE(
bool)
261 unsigned FirstEntryIsAnUnsizedArray : 1;
264 LLVM_PREFERRED_TYPE(
bool)
265 unsigned MostDerivedIsArrayElement : 1;
269 unsigned MostDerivedPathLength : 28;
278 uint64_t MostDerivedArraySize;
287 SubobjectDesignator() :
Invalid(
true) {}
290 :
Invalid(
false), IsOnePastTheEnd(
false),
291 FirstEntryIsAnUnsizedArray(
false), MostDerivedIsArrayElement(
false),
292 MostDerivedPathLength(0), MostDerivedArraySize(0),
293 MostDerivedType(
T.isNull() ?
QualType() :
T.getNonReferenceType()) {}
296 :
Invalid(!
V.isLValue() || !
V.hasLValuePath()), IsOnePastTheEnd(
false),
297 FirstEntryIsAnUnsizedArray(
false), MostDerivedIsArrayElement(
false),
298 MostDerivedPathLength(0), MostDerivedArraySize(0) {
299 assert(
V.isLValue() &&
"Non-LValue used to make an LValue designator?");
301 IsOnePastTheEnd =
V.isLValueOnePastTheEnd();
302 llvm::append_range(Entries,
V.getLValuePath());
303 if (
V.getLValueBase()) {
304 bool IsArray =
false;
305 bool FirstIsUnsizedArray =
false;
306 MostDerivedPathLength = findMostDerivedSubobject(
307 Ctx,
V.getLValueBase(),
V.getLValuePath(), MostDerivedArraySize,
308 MostDerivedType, IsArray, FirstIsUnsizedArray);
309 MostDerivedIsArrayElement = IsArray;
310 FirstEntryIsAnUnsizedArray = FirstIsUnsizedArray;
316 unsigned NewLength) {
320 assert(
Base &&
"cannot truncate path for null pointer");
321 assert(NewLength <= Entries.size() &&
"not a truncation");
323 if (NewLength == Entries.size())
325 Entries.resize(NewLength);
327 bool IsArray =
false;
328 bool FirstIsUnsizedArray =
false;
329 MostDerivedPathLength = findMostDerivedSubobject(
330 Ctx,
Base, Entries, MostDerivedArraySize, MostDerivedType, IsArray,
331 FirstIsUnsizedArray);
332 MostDerivedIsArrayElement = IsArray;
333 FirstEntryIsAnUnsizedArray = FirstIsUnsizedArray;
343 bool isMostDerivedAnUnsizedArray()
const {
344 assert(!
Invalid &&
"Calling this makes no sense on invalid designators");
345 return Entries.size() == 1 && FirstEntryIsAnUnsizedArray;
350 uint64_t getMostDerivedArraySize()
const {
351 assert(!isMostDerivedAnUnsizedArray() &&
"Unsized array has no size");
352 return MostDerivedArraySize;
356 bool isOnePastTheEnd()
const {
360 if (!isMostDerivedAnUnsizedArray() && MostDerivedIsArrayElement &&
361 Entries[MostDerivedPathLength - 1].getAsArrayIndex() ==
362 MostDerivedArraySize)
370 std::pair<uint64_t, uint64_t> validIndexAdjustments() {
371 if (
Invalid || isMostDerivedAnUnsizedArray())
377 bool IsArray = MostDerivedPathLength == Entries.size() &&
378 MostDerivedIsArrayElement;
379 uint64_t ArrayIndex = IsArray ? Entries.back().getAsArrayIndex()
380 : (uint64_t)IsOnePastTheEnd;
382 IsArray ? getMostDerivedArraySize() : (uint64_t)1;
383 return {ArrayIndex, ArraySize - ArrayIndex};
387 bool isValidSubobject()
const {
390 return !isOnePastTheEnd();
398 assert(!
Invalid &&
"invalid designator has no subobject type");
399 return MostDerivedPathLength == Entries.size()
410 MostDerivedIsArrayElement =
true;
412 MostDerivedPathLength = Entries.size();
416 void addUnsizedArrayUnchecked(
QualType ElemTy) {
419 MostDerivedType = ElemTy;
420 MostDerivedIsArrayElement =
true;
424 MostDerivedArraySize = AssumedSizeForUnsizedArray;
425 MostDerivedPathLength = Entries.size();
429 void addDeclUnchecked(
const Decl *D,
bool Virtual =
false) {
433 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
434 MostDerivedType = FD->getType();
435 MostDerivedIsArrayElement =
false;
436 MostDerivedArraySize = 0;
437 MostDerivedPathLength = Entries.size();
441 void addComplexUnchecked(
QualType EltTy,
bool Imag) {
446 MostDerivedType = EltTy;
447 MostDerivedIsArrayElement =
true;
448 MostDerivedArraySize = 2;
449 MostDerivedPathLength = Entries.size();
452 void addVectorElementUnchecked(
QualType EltTy, uint64_t Size,
455 MostDerivedType = EltTy;
456 MostDerivedPathLength = Entries.size();
457 MostDerivedArraySize = 0;
458 MostDerivedIsArrayElement =
false;
461 void diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info,
const Expr *E);
462 void diagnosePointerArithmetic(EvalInfo &Info,
const Expr *E,
465 void adjustIndex(EvalInfo &Info,
const Expr *E,
APSInt N,
const LValue &LV);
469 enum class ScopeKind {
477 CallRef() : OrigCallee(), CallIndex(0), Version() {}
478 CallRef(
const FunctionDecl *Callee,
unsigned CallIndex,
unsigned Version)
479 : OrigCallee(Callee), CallIndex(CallIndex), Version(Version) {}
481 explicit operator bool()
const {
return OrigCallee; }
507 CallStackFrame *Caller;
529 typedef std::pair<const void *, unsigned> MapKeyTy;
530 typedef std::map<MapKeyTy, APValue>
MapTy;
542 unsigned CurTempVersion = TempVersionStack.back();
544 unsigned getTempVersion()
const {
return TempVersionStack.back(); }
546 void pushTempVersion() {
547 TempVersionStack.push_back(++CurTempVersion);
550 void popTempVersion() {
551 TempVersionStack.pop_back();
555 return {Callee, Index, ++CurTempVersion};
566 llvm::DenseMap<const ValueDecl *, FieldDecl *> LambdaCaptureFields;
567 FieldDecl *LambdaThisCaptureField =
nullptr;
569 CallStackFrame(EvalInfo &Info,
SourceRange CallRange,
575 APValue *getTemporary(
const void *Key,
unsigned Version) {
576 MapKeyTy KV(Key, Version);
577 auto LB = Temporaries.lower_bound(KV);
578 if (LB != Temporaries.end() && LB->first == KV)
584 APValue *getCurrentTemporary(
const void *Key) {
585 auto UB = Temporaries.upper_bound(MapKeyTy(Key,
UINT_MAX));
586 if (UB != Temporaries.begin() && std::prev(UB)->first.first == Key)
587 return &std::prev(UB)->second;
592 unsigned getCurrentTemporaryVersion(
const void *Key)
const {
593 auto UB = Temporaries.upper_bound(MapKeyTy(Key,
UINT_MAX));
594 if (UB != Temporaries.begin() && std::prev(UB)->first.first == Key)
595 return std::prev(UB)->first.second;
603 template<
typename KeyT>
605 ScopeKind
Scope, LValue &LV);
610 void describe(llvm::raw_ostream &OS)
const override;
612 Frame *getCaller()
const override {
return Caller; }
613 SourceRange getCallRange()
const override {
return CallRange; }
616 bool isStdFunction()
const {
617 for (
const DeclContext *DC = Callee; DC; DC = DC->getParent())
618 if (DC->isStdNamespace())
625 bool CanEvalMSConstexpr =
false;
633 class ThisOverrideRAII {
635 ThisOverrideRAII(CallStackFrame &Frame,
const LValue *NewThis,
bool Enable)
636 : Frame(Frame), OldThis(Frame.This) {
638 Frame.This = NewThis;
640 ~ThisOverrideRAII() {
641 Frame.This = OldThis;
644 CallStackFrame &Frame;
645 const LValue *OldThis;
650 class ExprTimeTraceScope {
652 ExprTimeTraceScope(
const Expr *E,
const ASTContext &Ctx, StringRef Name)
653 : TimeScope(Name, [E, &Ctx] {
658 llvm::TimeTraceScope TimeScope;
663 struct MSConstexprContextRAII {
664 CallStackFrame &Frame;
666 explicit MSConstexprContextRAII(CallStackFrame &Frame,
bool Value)
667 : Frame(Frame), OldValue(Frame.CanEvalMSConstexpr) {
668 Frame.CanEvalMSConstexpr =
Value;
671 ~MSConstexprContextRAII() { Frame.CanEvalMSConstexpr = OldValue; }
684 llvm::PointerIntPair<APValue*, 2, ScopeKind> Value;
685 APValue::LValueBase Base;
689 Cleanup(
APValue *Val, APValue::LValueBase Base, QualType T,
691 : Value(Val, Scope), Base(Base), T(T) {}
695 bool isDestroyedAtEndOf(ScopeKind K)
const {
696 return (
int)Value.getInt() >= (
int)K;
698 bool endLifetime(EvalInfo &Info,
bool RunDestructors) {
699 if (RunDestructors) {
701 if (
const ValueDecl *VD = Base.dyn_cast<
const ValueDecl*>())
702 Loc = VD->getLocation();
703 else if (
const Expr *E = Base.dyn_cast<
const Expr*>())
704 Loc = E->getExprLoc();
707 *Value.getPointer() =
APValue();
711 bool hasSideEffect() {
712 return T.isDestructedType();
717 struct ObjectUnderConstruction {
718 APValue::LValueBase Base;
719 ArrayRef<APValue::LValuePathEntry> Path;
720 friend bool operator==(
const ObjectUnderConstruction &LHS,
721 const ObjectUnderConstruction &RHS) {
722 return LHS.Base == RHS.Base && LHS.Path == RHS.Path;
724 friend llvm::hash_code
hash_value(
const ObjectUnderConstruction &Obj) {
725 return llvm::hash_combine(Obj.Base, Obj.Path);
728 enum class ConstructionPhase {
739template<>
struct DenseMapInfo<ObjectUnderConstruction> {
740 using Base = DenseMapInfo<APValue::LValueBase>;
744 static bool isEqual(
const ObjectUnderConstruction &LHS,
745 const ObjectUnderConstruction &RHS) {
759 const Expr *AllocExpr =
nullptr;
770 if (
auto *NE = dyn_cast<CXXNewExpr>(AllocExpr))
771 return NE->isArray() ? ArrayNew : New;
777 struct DynAllocOrder {
778 bool operator()(DynamicAllocLValue L, DynamicAllocLValue R)
const {
800 CallStackFrame *CurrentCall;
803 unsigned CallStackDepth;
806 unsigned NextCallIndex;
815 bool EnableNewConstInterp;
819 CallStackFrame BottomFrame;
823 llvm::SmallVector<Cleanup, 16> CleanupStack;
827 APValue::LValueBase EvaluatingDecl;
829 enum class EvaluatingDeclKind {
836 EvaluatingDeclKind IsEvaluatingDecl = EvaluatingDeclKind::None;
845 SmallVector<const Stmt *> BreakContinueStack;
848 llvm::DenseMap<ObjectUnderConstruction, ConstructionPhase>
849 ObjectsUnderConstruction;
854 std::map<DynamicAllocLValue, DynAlloc, DynAllocOrder> HeapAllocs;
857 unsigned NumHeapAllocs = 0;
859 struct EvaluatingConstructorRAII {
861 ObjectUnderConstruction Object;
863 EvaluatingConstructorRAII(EvalInfo &EI, ObjectUnderConstruction Object,
865 : EI(EI), Object(Object) {
867 EI.ObjectsUnderConstruction
868 .insert({Object, HasBases ? ConstructionPhase::Bases
869 : ConstructionPhase::AfterBases})
872 void finishedConstructingBases() {
873 EI.ObjectsUnderConstruction[Object] = ConstructionPhase::AfterBases;
875 void finishedConstructingFields() {
876 EI.ObjectsUnderConstruction[Object] = ConstructionPhase::AfterFields;
878 ~EvaluatingConstructorRAII() {
879 if (DidInsert) EI.ObjectsUnderConstruction.erase(Object);
883 struct EvaluatingDestructorRAII {
885 ObjectUnderConstruction Object;
887 EvaluatingDestructorRAII(EvalInfo &EI, ObjectUnderConstruction Object)
888 : EI(EI), Object(Object) {
889 DidInsert = EI.ObjectsUnderConstruction
890 .insert({Object, ConstructionPhase::Destroying})
893 void startedDestroyingBases() {
894 EI.ObjectsUnderConstruction[Object] =
895 ConstructionPhase::DestroyingBases;
897 ~EvaluatingDestructorRAII() {
899 EI.ObjectsUnderConstruction.erase(Object);
904 isEvaluatingCtorDtor(APValue::LValueBase Base,
905 ArrayRef<APValue::LValuePathEntry> Path) {
906 return ObjectsUnderConstruction.lookup({
Base, Path});
911 unsigned SpeculativeEvaluationDepth = 0;
917 EvalInfo(
const ASTContext &
C, Expr::EvalStatus &S,
EvaluationMode Mode)
918 : State(const_cast<ASTContext &>(
C), S), CurrentCall(
nullptr),
919 CallStackDepth(0), NextCallIndex(1),
920 StepsLeft(
C.getLangOpts().ConstexprStepLimit),
921 EnableNewConstInterp(
C.getLangOpts().EnableNewConstInterp),
922 BottomFrame(*this, SourceLocation(),
nullptr,
925 EvaluatingDecl((const ValueDecl *)
nullptr),
934 void setEvaluatingDecl(APValue::LValueBase Base,
APValue &
Value,
935 EvaluatingDeclKind EDK = EvaluatingDeclKind::Ctor) {
936 EvaluatingDecl =
Base;
937 IsEvaluatingDecl = EDK;
938 EvaluatingDeclValue = &
Value;
941 bool CheckCallLimit(SourceLocation Loc) {
944 if (checkingPotentialConstantExpression() && CallStackDepth > 1)
946 if (NextCallIndex == 0) {
948 FFDiag(Loc, diag::note_constexpr_call_limit_exceeded);
951 if (CallStackDepth <= getLangOpts().ConstexprCallDepth)
953 FFDiag(Loc, diag::note_constexpr_depth_limit_exceeded)
954 << getLangOpts().ConstexprCallDepth;
959 uint64_t ElemCount,
bool Diag) {
965 ElemCount >
uint64_t(std::numeric_limits<unsigned>::max())) {
967 FFDiag(Loc, diag::note_constexpr_new_too_large) << ElemCount;
976 uint64_t Limit = getLangOpts().ConstexprStepLimit;
977 if (Limit != 0 && ElemCount > Limit) {
979 FFDiag(Loc, diag::note_constexpr_new_exceeds_limits, 1)
980 << ElemCount << Limit;
981 Note(Loc, diag::note_constexpr_steps);
988 std::pair<CallStackFrame *, unsigned>
989 getCallFrameAndDepth(
unsigned CallIndex) {
990 assert(CallIndex &&
"no call index in getCallFrameAndDepth");
993 unsigned Depth = CallStackDepth;
994 CallStackFrame *Frame = CurrentCall;
995 while (Frame->Index > CallIndex) {
996 Frame = Frame->Caller;
999 if (Frame->Index == CallIndex)
1000 return {Frame, Depth};
1001 return {
nullptr, 0};
1004 bool nextStep(
const Stmt *S) {
1005 if (getLangOpts().ConstexprStepLimit == 0)
1009 FFDiag(S->
getBeginLoc(), diag::note_constexpr_step_limit_exceeded, 1)
1010 << getLangOpts().ConstexprStepLimit;
1018 APValue *createHeapAlloc(
const Expr *E, QualType
T, LValue &LV);
1020 std::optional<DynAlloc *> lookupDynamicAlloc(DynamicAllocLValue DA) {
1021 std::optional<DynAlloc *>
Result;
1022 auto It = HeapAllocs.find(DA);
1023 if (It != HeapAllocs.end())
1029 APValue *getParamSlot(CallRef
Call,
const ParmVarDecl *PVD) {
1030 CallStackFrame *Frame = getCallFrameAndDepth(
Call.CallIndex).first;
1031 return Frame ? Frame->getTemporary(
Call.getOrigParam(PVD),
Call.Version)
1036 struct StdAllocatorCaller {
1037 unsigned FrameIndex;
1040 explicit operator bool()
const {
return FrameIndex != 0; };
1043 StdAllocatorCaller getStdAllocatorCaller(StringRef FnName)
const {
1044 for (
const CallStackFrame *
Call = CurrentCall;
Call->Caller !=
nullptr;
1046 const auto *MD = dyn_cast_or_null<CXXMethodDecl>(
Call->Callee);
1049 const IdentifierInfo *FnII = MD->getIdentifier();
1050 if (!FnII || !FnII->
isStr(FnName))
1054 dyn_cast<ClassTemplateSpecializationDecl>(MD->getParent());
1058 const IdentifierInfo *ClassII = CTSD->getIdentifier();
1059 const TemplateArgumentList &TAL = CTSD->getTemplateArgs();
1060 if (CTSD->isInStdNamespace() && ClassII &&
1061 ClassII->
isStr(
"allocator") && TAL.
size() >= 1 &&
1063 return {
Call->Index, TAL[0].getAsType(),
Call->CallExpr};
1069 void performLifetimeExtension() {
1071 llvm::erase_if(CleanupStack, [](Cleanup &
C) {
1072 return !
C.isDestroyedAtEndOf(ScopeKind::FullExpression);
1079 bool discardCleanups() {
1080 for (Cleanup &
C : CleanupStack) {
1081 if (
C.hasSideEffect() && !noteSideEffect()) {
1082 CleanupStack.clear();
1086 CleanupStack.clear();
1091 const interp::Frame *getCurrentFrame()
override {
return CurrentCall; }
1093 unsigned getCallStackDepth()
override {
return CallStackDepth; }
1094 bool stepsLeft()
const override {
return StepsLeft > 0; }
1107 [[nodiscard]]
bool noteFailure() {
1115 bool KeepGoing = keepEvaluatingAfterFailure();
1116 EvalStatus.HasSideEffects |= KeepGoing;
1120 class ArrayInitLoopIndex {
1125 ArrayInitLoopIndex(EvalInfo &Info)
1126 : Info(Info), OuterIndex(Info.ArrayInitIndex) {
1127 Info.ArrayInitIndex = 0;
1129 ~ArrayInitLoopIndex() { Info.ArrayInitIndex = OuterIndex; }
1131 operator uint64_t&() {
return Info.ArrayInitIndex; }
1136 struct FoldConstant {
1139 bool HadNoPriorDiags;
1142 explicit FoldConstant(EvalInfo &Info,
bool Enabled)
1145 HadNoPriorDiags(Info.EvalStatus.
Diag &&
1146 Info.EvalStatus.
Diag->empty() &&
1147 !Info.EvalStatus.HasSideEffects),
1148 OldMode(Info.EvalMode) {
1150 Info.EvalMode = EvaluationMode::ConstantFold;
1152 void keepDiagnostics() { Enabled =
false; }
1154 if (Enabled && HadNoPriorDiags && !Info.EvalStatus.Diag->empty() &&
1155 !Info.EvalStatus.HasSideEffects) {
1156 Info.EvalStatus.Diag->clear();
1157 Info.EvalStatus.DiagEmitted =
false;
1159 Info.EvalMode = OldMode;
1165 struct IgnoreSideEffectsRAII {
1168 explicit IgnoreSideEffectsRAII(EvalInfo &Info)
1169 : Info(Info), OldMode(Info.EvalMode) {
1170 Info.EvalMode = EvaluationMode::IgnoreSideEffects;
1173 ~IgnoreSideEffectsRAII() { Info.EvalMode = OldMode; }
1178 class SpeculativeEvaluationRAII {
1179 EvalInfo *Info =
nullptr;
1180 Expr::EvalStatus OldStatus;
1181 unsigned OldSpeculativeEvaluationDepth = 0;
1183 void moveFromAndCancel(SpeculativeEvaluationRAII &&
Other) {
1185 OldStatus =
Other.OldStatus;
1186 OldSpeculativeEvaluationDepth =
Other.OldSpeculativeEvaluationDepth;
1187 Other.Info =
nullptr;
1190 void maybeRestoreState() {
1194 Info->EvalStatus = OldStatus;
1195 Info->SpeculativeEvaluationDepth = OldSpeculativeEvaluationDepth;
1199 SpeculativeEvaluationRAII() =
default;
1201 SpeculativeEvaluationRAII(
1202 EvalInfo &Info, SmallVectorImpl<PartialDiagnosticAt> *NewDiag =
nullptr)
1203 : Info(&Info), OldStatus(Info.EvalStatus),
1204 OldSpeculativeEvaluationDepth(Info.SpeculativeEvaluationDepth) {
1205 Info.EvalStatus.Diag = NewDiag;
1206 Info.SpeculativeEvaluationDepth = Info.CallStackDepth + 1;
1209 SpeculativeEvaluationRAII(
const SpeculativeEvaluationRAII &
Other) =
delete;
1210 SpeculativeEvaluationRAII(SpeculativeEvaluationRAII &&
Other) {
1211 moveFromAndCancel(std::move(
Other));
1214 SpeculativeEvaluationRAII &operator=(SpeculativeEvaluationRAII &&
Other) {
1215 maybeRestoreState();
1216 moveFromAndCancel(std::move(
Other));
1220 ~SpeculativeEvaluationRAII() { maybeRestoreState(); }
1225 template<ScopeKind Kind>
1228 unsigned OldStackSize;
1230 ScopeRAII(EvalInfo &Info)
1231 : Info(Info), OldStackSize(Info.CleanupStack.size()) {
1234 Info.CurrentCall->pushTempVersion();
1236 bool destroy(
bool RunDestructors =
true) {
1237 bool OK =
cleanup(Info, RunDestructors, OldStackSize);
1238 OldStackSize = std::numeric_limits<unsigned>::max();
1242 if (OldStackSize != std::numeric_limits<unsigned>::max())
1246 Info.CurrentCall->popTempVersion();
1249 static bool cleanup(EvalInfo &Info,
bool RunDestructors,
1250 unsigned OldStackSize) {
1251 assert(OldStackSize <= Info.CleanupStack.size() &&
1252 "running cleanups out of order?");
1257 for (
unsigned I = Info.CleanupStack.size(); I > OldStackSize; --I) {
1258 if (Info.CleanupStack[I - 1].isDestroyedAtEndOf(Kind)) {
1259 if (!Info.CleanupStack[I - 1].endLifetime(Info, RunDestructors)) {
1267 auto NewEnd = Info.CleanupStack.begin() + OldStackSize;
1268 if (Kind != ScopeKind::Block)
1270 std::remove_if(NewEnd, Info.CleanupStack.end(), [](Cleanup &
C) {
1271 return C.isDestroyedAtEndOf(Kind);
1273 Info.CleanupStack.erase(NewEnd, Info.CleanupStack.end());
1277 typedef ScopeRAII<ScopeKind::Block> BlockScopeRAII;
1278 typedef ScopeRAII<ScopeKind::FullExpression> FullExpressionRAII;
1279 typedef ScopeRAII<ScopeKind::Call> CallScopeRAII;
1282bool SubobjectDesignator::checkSubobject(EvalInfo &Info,
const Expr *E,
1286 if (isOnePastTheEnd()) {
1287 Info.CCEDiag(E, diag::note_constexpr_past_end_subobject)
1298void SubobjectDesignator::diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info,
1300 Info.CCEDiag(E, diag::note_constexpr_unsized_array_indexed);
1305void SubobjectDesignator::diagnosePointerArithmetic(EvalInfo &Info,
1310 if (MostDerivedPathLength == Entries.size() && MostDerivedIsArrayElement)
1311 Info.CCEDiag(E, diag::note_constexpr_array_index)
1313 <<
static_cast<unsigned>(getMostDerivedArraySize());
1315 Info.CCEDiag(E, diag::note_constexpr_array_index)
1320CallStackFrame::CallStackFrame(EvalInfo &Info, SourceRange CallRange,
1321 const FunctionDecl *Callee,
const LValue *This,
1322 const Expr *CallExpr, CallRef Call)
1324 CallExpr(CallExpr),
Arguments(Call), CallRange(CallRange),
1325 Index(Info.NextCallIndex++) {
1326 Info.CurrentCall =
this;
1327 ++Info.CallStackDepth;
1330CallStackFrame::~CallStackFrame() {
1331 assert(Info.CurrentCall ==
this &&
"calls retired out of order");
1332 --Info.CallStackDepth;
1333 Info.CurrentCall = Caller;
1358 llvm_unreachable(
"unknown access kind");
1395 llvm_unreachable(
"unknown access kind");
1399 struct ComplexValue {
1407 ComplexValue() : FloatReal(
APFloat::Bogus()), FloatImag(
APFloat::Bogus()) {}
1409 void makeComplexFloat() { IsInt =
false; }
1410 bool isComplexFloat()
const {
return !IsInt; }
1411 APFloat &getComplexFloatReal() {
return FloatReal; }
1412 APFloat &getComplexFloatImag() {
return FloatImag; }
1414 void makeComplexInt() { IsInt =
true; }
1415 bool isComplexInt()
const {
return IsInt; }
1416 APSInt &getComplexIntReal() {
return IntReal; }
1417 APSInt &getComplexIntImag() {
return IntImag; }
1419 void moveInto(
APValue &v)
const {
1420 if (isComplexFloat())
1421 v =
APValue(FloatReal, FloatImag);
1423 v =
APValue(IntReal, IntImag);
1425 void setFrom(
const APValue &v) {
1440 APValue::LValueBase
Base;
1442 SubobjectDesignator Designator;
1444 bool InvalidBase : 1;
1446 bool AllowConstexprUnknown =
false;
1448 const APValue::LValueBase getLValueBase()
const {
return Base; }
1449 bool allowConstexprUnknown()
const {
return AllowConstexprUnknown; }
1450 CharUnits &getLValueOffset() {
return Offset; }
1451 const CharUnits &getLValueOffset()
const {
return Offset; }
1452 SubobjectDesignator &getLValueDesignator() {
return Designator; }
1453 const SubobjectDesignator &getLValueDesignator()
const {
return Designator;}
1454 bool isNullPointer()
const {
return IsNullPtr;}
1456 unsigned getLValueCallIndex()
const {
return Base.getCallIndex(); }
1457 unsigned getLValueVersion()
const {
return Base.getVersion(); }
1459 bool pointsToCompleteClass(
const CXXRecordDecl *D)
const {
1460 if (Designator.Entries.empty())
1467 if (Designator.Invalid)
1468 V =
APValue(Base, Offset, APValue::NoLValuePath(), IsNullPtr);
1470 assert(!InvalidBase &&
"APValues can't handle invalid LValue bases");
1471 V =
APValue(Base, Offset, Designator.Entries,
1472 Designator.IsOnePastTheEnd, IsNullPtr);
1474 if (AllowConstexprUnknown)
1475 V.setConstexprUnknown();
1477 void setFrom(
const ASTContext &Ctx,
const APValue &
V) {
1478 assert(
V.isLValue() &&
"Setting LValue from a non-LValue?");
1479 Base =
V.getLValueBase();
1480 Offset =
V.getLValueOffset();
1481 InvalidBase =
false;
1482 Designator = SubobjectDesignator(Ctx,
V);
1483 IsNullPtr =
V.isNullPointer();
1484 AllowConstexprUnknown =
V.allowConstexprUnknown();
1487 void set(APValue::LValueBase B,
bool BInvalid =
false) {
1491 const auto *E = B.
get<
const Expr *>();
1493 "Unexpected type of invalid base");
1499 InvalidBase = BInvalid;
1500 Designator = SubobjectDesignator(
getType(B));
1502 AllowConstexprUnknown =
false;
1505 void setNull(ASTContext &Ctx, QualType PointerTy) {
1506 Base = (
const ValueDecl *)
nullptr;
1509 InvalidBase =
false;
1512 AllowConstexprUnknown =
false;
1515 void setInvalid(APValue::LValueBase B,
unsigned I = 0) {
1519 std::string
toString(ASTContext &Ctx, QualType
T)
const {
1521 moveInto(Printable);
1528 template <
typename GenDiagType>
1529 bool checkNullPointerDiagnosingWith(
const GenDiagType &GenDiag) {
1530 if (Designator.Invalid)
1534 Designator.setInvalid();
1541 bool checkNullPointer(EvalInfo &Info,
const Expr *E,
1543 return checkNullPointerDiagnosingWith([&Info, E, CSK] {
1544 Info.CCEDiag(E, diag::note_constexpr_null_subobject) << CSK;
1548 bool checkNullPointerForFoldAccess(EvalInfo &Info,
const Expr *E,
1550 return checkNullPointerDiagnosingWith([&Info, E, AK] {
1551 if (AK == AccessKinds::AK_Dereference)
1552 Info.FFDiag(E, diag::note_constexpr_dereferencing_null);
1554 Info.FFDiag(E, diag::note_constexpr_access_null) << AK;
1562 Designator.checkSubobject(Info, E, CSK);
1565 void addDecl(EvalInfo &Info,
const Expr *E,
1566 const Decl *D,
bool Virtual =
false) {
1568 Designator.addDeclUnchecked(D,
Virtual);
1570 void addUnsizedArray(EvalInfo &Info,
const Expr *E, QualType ElemTy) {
1571 if (!Designator.Entries.empty()) {
1572 Info.CCEDiag(E, diag::note_constexpr_unsupported_unsized_array);
1573 Designator.setInvalid();
1577 assert(!Base ||
getType(Base).getNonReferenceType()->isPointerType() ||
1578 getType(Base).getNonReferenceType()->isArrayType());
1579 Designator.FirstEntryIsAnUnsizedArray =
true;
1580 Designator.addUnsizedArrayUnchecked(ElemTy);
1583 void addArray(EvalInfo &Info,
const Expr *E,
const ConstantArrayType *CAT) {
1585 Designator.addArrayUnchecked(CAT);
1587 void addComplex(EvalInfo &Info,
const Expr *E, QualType EltTy,
bool Imag) {
1589 Designator.addComplexUnchecked(EltTy, Imag);
1591 void addVectorElement(EvalInfo &Info,
const Expr *E, QualType EltTy,
1592 uint64_t Size, uint64_t Idx) {
1594 Designator.addVectorElementUnchecked(EltTy, Size, Idx);
1596 void clearIsNullPointer() {
1599 void adjustOffsetAndIndex(EvalInfo &Info,
const Expr *E,
1600 const APSInt &Index, CharUnits ElementSize) {
1611 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
1615 Designator.adjustIndex(Info, E, Index, *
this);
1616 clearIsNullPointer();
1618 void adjustOffset(CharUnits N) {
1621 clearIsNullPointer();
1627 explicit MemberPtr(
const ValueDecl *Decl)
1628 : DeclAndIsDerivedMember(
Decl,
false) {}
1632 const ValueDecl *getDecl()
const {
1633 return DeclAndIsDerivedMember.getPointer();
1636 bool isDerivedMember()
const {
1637 return DeclAndIsDerivedMember.getInt();
1640 const CXXRecordDecl *getContainingRecord()
const {
1642 DeclAndIsDerivedMember.getPointer()->getDeclContext());
1646 V =
APValue(getDecl(), isDerivedMember(), Path);
1649 assert(
V.isMemberPointer());
1650 DeclAndIsDerivedMember.setPointer(
V.getMemberPointerDecl());
1651 DeclAndIsDerivedMember.setInt(
V.isMemberPointerToDerivedMember());
1653 llvm::append_range(Path,
V.getMemberPointerPath());
1659 llvm::PointerIntPair<const ValueDecl*, 1, bool> DeclAndIsDerivedMember;
1662 SmallVector<const CXXRecordDecl*, 4> Path;
1666 bool castBack(
const CXXRecordDecl *
Class) {
1667 assert(!Path.empty());
1668 const CXXRecordDecl *Expected;
1669 if (Path.size() >= 2)
1670 Expected = Path[Path.size() - 2];
1672 Expected = getContainingRecord();
1686 bool castToDerived(
const CXXRecordDecl *Derived) {
1689 if (!isDerivedMember()) {
1690 Path.push_back(Derived);
1693 if (!castBack(Derived))
1696 DeclAndIsDerivedMember.setInt(
false);
1704 DeclAndIsDerivedMember.setInt(
true);
1705 if (isDerivedMember()) {
1706 Path.push_back(Base);
1709 return castBack(Base);
1714 static bool operator==(
const MemberPtr &LHS,
const MemberPtr &RHS) {
1715 if (!LHS.getDecl() || !RHS.getDecl())
1716 return !LHS.getDecl() && !RHS.getDecl();
1717 if (LHS.getDecl()->getCanonicalDecl() != RHS.getDecl()->getCanonicalDecl())
1719 return LHS.Path == RHS.Path;
1723void SubobjectDesignator::adjustIndex(EvalInfo &Info,
const Expr *E,
APSInt N,
1727 uint64_t TruncatedN = N.extOrTrunc(64).getZExtValue();
1728 if (isMostDerivedAnUnsizedArray()) {
1729 diagnoseUnsizedArrayPointerArithmetic(Info, E);
1734 PathEntry::ArrayIndex(Entries.back().getAsArrayIndex() + TruncatedN);
1742 MostDerivedPathLength == Entries.size() && MostDerivedIsArrayElement;
1744 IsArray ? Entries.back().getAsArrayIndex() : (
uint64_t)IsOnePastTheEnd;
1747 if (N < -(int64_t)ArrayIndex || N > ArraySize - ArrayIndex) {
1748 if (!Info.checkingPotentialConstantExpression() ||
1749 !LV.AllowConstexprUnknown) {
1752 N = N.extend(std::max<unsigned>(N.getBitWidth() + 1, 65));
1753 (llvm::APInt &)N += ArrayIndex;
1754 assert(N.ugt(ArraySize) &&
"bounds check failed for in-bounds index");
1755 diagnosePointerArithmetic(Info, E, N);
1761 ArrayIndex += TruncatedN;
1762 assert(ArrayIndex <= ArraySize &&
1763 "bounds check succeeded for out-of-bounds index");
1766 Entries.back() = PathEntry::ArrayIndex(ArrayIndex);
1768 IsOnePastTheEnd = (ArrayIndex != 0);
1773 const LValue &This,
const Expr *E,
1774 bool AllowNonLiteralTypes =
false);
1776 bool InvalidBaseOK =
false);
1778 bool InvalidBaseOK =
false);
1786static bool EvaluateComplex(
const Expr *E, ComplexValue &Res, EvalInfo &Info);
1791static std::optional<uint64_t>
1793 std::string *StringResult =
nullptr);
1810 if (Int.isUnsigned() || Int.isMinSignedValue()) {
1811 Int = Int.extend(Int.getBitWidth() + 1);
1812 Int.setIsSigned(
true);
1817template<
typename KeyT>
1818APValue &CallStackFrame::createTemporary(
const KeyT *Key, QualType
T,
1819 ScopeKind Scope, LValue &LV) {
1820 unsigned Version = getTempVersion();
1821 APValue::LValueBase
Base(Key, Index, Version);
1823 return createLocal(Base, Key,
T, Scope);
1827APValue &CallStackFrame::createParam(CallRef Args,
const ParmVarDecl *PVD,
1829 assert(Args.CallIndex == Index &&
"creating parameter in wrong frame");
1830 APValue::LValueBase
Base(PVD, Index, Args.Version);
1835 return createLocal(Base, PVD, PVD->
getType(), ScopeKind::Call);
1838APValue &CallStackFrame::createLocal(APValue::LValueBase Base,
const void *Key,
1839 QualType
T, ScopeKind Scope) {
1840 assert(
Base.getCallIndex() == Index &&
"lvalue for wrong frame");
1841 unsigned Version =
Base.getVersion();
1843 assert(
Result.isAbsent() &&
"local created multiple times");
1849 if (Index <= Info.SpeculativeEvaluationDepth) {
1850 if (
T.isDestructedType())
1851 Info.noteSideEffect();
1853 Info.CleanupStack.push_back(Cleanup(&
Result, Base,
T, Scope));
1858APValue *EvalInfo::createHeapAlloc(
const Expr *E, QualType
T, LValue &LV) {
1860 FFDiag(E, diag::note_constexpr_heap_alloc_limit_exceeded);
1864 DynamicAllocLValue DA(NumHeapAllocs++);
1866 auto Result = HeapAllocs.emplace(std::piecewise_construct,
1867 std::forward_as_tuple(DA), std::tuple<>());
1868 assert(
Result.second &&
"reused a heap alloc index?");
1869 Result.first->second.AllocExpr = E;
1870 return &
Result.first->second.Value;
1874void CallStackFrame::describe(raw_ostream &Out)
const {
1875 bool IsMemberCall =
false;
1876 bool ExplicitInstanceParam =
false;
1877 clang::PrintingPolicy PrintingPolicy = Info.Ctx.getPrintingPolicy();
1880 if (
const auto *MD = dyn_cast<CXXMethodDecl>(Callee)) {
1882 ExplicitInstanceParam = MD->isExplicitObjectMemberFunction();
1886 Callee->getNameForDiagnostic(Out, PrintingPolicy,
1889 if (This && IsMemberCall) {
1890 if (
const auto *MCE = dyn_cast_if_present<CXXMemberCallExpr>(CallExpr)) {
1891 const Expr *
Object = MCE->getImplicitObjectArgument();
1892 Object->printPretty(Out,
nullptr, PrintingPolicy,
1894 if (
Object->getType()->isPointerType())
1898 }
else if (
const auto *OCE =
1899 dyn_cast_if_present<CXXOperatorCallExpr>(CallExpr)) {
1900 OCE->getArg(0)->printPretty(Out,
nullptr, PrintingPolicy,
1905 This->moveInto(Val);
1908 Info.Ctx.getLValueReferenceType(
This->Designator.MostDerivedType));
1911 Callee->getNameForDiagnostic(Out, PrintingPolicy,
1917 llvm::ListSeparator
Comma;
1918 for (
const ParmVarDecl *Param :
1919 Callee->parameters().slice(ExplicitInstanceParam)) {
1921 const APValue *
V = Info.getParamSlot(Arguments, Param);
1923 V->printPretty(Out, Info.Ctx, Param->getType());
1939 return Info.noteSideEffect();
1946 return (
Builtin == Builtin::BI__builtin___CFStringMakeConstantString ||
1947 Builtin == Builtin::BI__builtin___NSStringMakeConstantString ||
1948 Builtin == Builtin::BI__builtin_ptrauth_sign_constant ||
1949 Builtin == Builtin::BI__builtin_function_start);
1953 const auto *BaseExpr =
1954 llvm::dyn_cast_if_present<CallExpr>(LVal.Base.
dyn_cast<
const Expr *>());
1969 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
1970 return VD->hasGlobalStorage();
1986 case Expr::CompoundLiteralExprClass: {
1990 case Expr::MaterializeTemporaryExprClass:
1995 case Expr::StringLiteralClass:
1996 case Expr::PredefinedExprClass:
1997 case Expr::ObjCStringLiteralClass:
1998 case Expr::ObjCEncodeExprClass:
2000 case Expr::ObjCBoxedExprClass:
2001 case Expr::ObjCArrayLiteralClass:
2002 case Expr::ObjCDictionaryLiteralClass:
2004 case Expr::CallExprClass:
2007 case Expr::AddrLabelExprClass:
2011 case Expr::BlockExprClass:
2015 case Expr::SourceLocExprClass:
2017 case Expr::ImplicitValueInitExprClass:
2042 const auto *BaseExpr = LVal.Base.
dyn_cast<
const Expr *>();
2047 if (
const auto *EE = dyn_cast<ObjCEncodeExpr>(BaseExpr)) {
2048 Info.Ctx.getObjCEncodingForType(EE->getEncodedType(),
2056 const auto *Lit = dyn_cast<StringLiteral>(BaseExpr);
2057 if (
const auto *PE = dyn_cast<PredefinedExpr>(BaseExpr))
2058 Lit = PE->getFunctionName();
2063 AsString.
Bytes = Lit->getBytes();
2064 AsString.
CharWidth = Lit->getCharByteWidth();
2084 const LValue &RHS) {
2093 CharUnits Offset = RHS.Offset - LHS.Offset;
2094 if (Offset.isNegative()) {
2095 if (LHSString.
Bytes.size() < (
size_t)-Offset.getQuantity())
2097 LHSString.
Bytes = LHSString.
Bytes.drop_front(-Offset.getQuantity());
2099 if (RHSString.
Bytes.size() < (
size_t)Offset.getQuantity())
2101 RHSString.
Bytes = RHSString.
Bytes.drop_front(Offset.getQuantity());
2104 bool LHSIsLonger = LHSString.
Bytes.size() > RHSString.
Bytes.size();
2105 StringRef Longer = LHSIsLonger ? LHSString.
Bytes : RHSString.
Bytes;
2106 StringRef Shorter = LHSIsLonger ? RHSString.
Bytes : LHSString.
Bytes;
2107 int ShorterCharWidth = (LHSIsLonger ? RHSString : LHSString).CharWidth;
2112 for (
int NullByte : llvm::seq(ShorterCharWidth)) {
2113 if (Shorter.size() + NullByte >= Longer.size())
2115 if (Longer[Shorter.size() + NullByte])
2121 return Shorter == Longer.take_front(Shorter.size());
2131 if (isa_and_nonnull<VarDecl>(
Decl)) {
2141 if (!A.getLValueBase())
2142 return !B.getLValueBase();
2143 if (!B.getLValueBase())
2146 if (A.getLValueBase().getOpaqueValue() !=
2147 B.getLValueBase().getOpaqueValue())
2150 return A.getLValueCallIndex() == B.getLValueCallIndex() &&
2151 A.getLValueVersion() == B.getLValueVersion();
2155 assert(
Base &&
"no location for a null lvalue");
2161 if (
auto *PVD = dyn_cast_or_null<ParmVarDecl>(VD)) {
2163 for (CallStackFrame *F = Info.CurrentCall; F; F = F->Caller) {
2164 if (F->Arguments.CallIndex ==
Base.getCallIndex() &&
2165 F->Arguments.Version ==
Base.getVersion() && F->Callee &&
2166 Idx < F->Callee->getNumParams()) {
2167 VD = F->Callee->getParamDecl(Idx);
2174 Info.Note(VD->
getLocation(), diag::note_declared_at);
2176 Info.Note(E->
getExprLoc(), diag::note_constexpr_temporary_here);
2179 if (std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA))
2180 Info.Note((*Alloc)->AllocExpr->getExprLoc(),
2181 diag::note_constexpr_dynamic_alloc_here);
2203 bool IsCompleteClass =
true);
2215 const SubobjectDesignator &
Designator = LVal.getLValueDesignator();
2223 if (isTemplateArgument(Kind)) {
2224 int InvalidBaseKind = -1;
2227 InvalidBaseKind = 0;
2228 else if (isa_and_nonnull<StringLiteral>(BaseE))
2229 InvalidBaseKind = 1;
2230 else if (isa_and_nonnull<MaterializeTemporaryExpr>(BaseE) ||
2231 isa_and_nonnull<LifetimeExtendedTemporaryDecl>(BaseVD))
2232 InvalidBaseKind = 2;
2233 else if (
auto *PE = dyn_cast_or_null<PredefinedExpr>(BaseE)) {
2234 InvalidBaseKind = 3;
2235 Ident = PE->getIdentKindName();
2238 if (InvalidBaseKind != -1) {
2239 Info.FFDiag(Loc, diag::note_constexpr_invalid_template_arg)
2240 << IsReferenceType << !
Designator.Entries.empty() << InvalidBaseKind
2246 if (
auto *FD = dyn_cast_or_null<FunctionDecl>(BaseVD);
2247 FD && FD->isImmediateFunction()) {
2248 Info.FFDiag(Loc, diag::note_consteval_address_accessible)
2250 Info.Note(FD->getLocation(), diag::note_declared_at);
2258 if (Info.getLangOpts().CPlusPlus11) {
2259 Info.FFDiag(Loc, diag::note_constexpr_non_global, 1)
2260 << IsReferenceType << !
Designator.Entries.empty() << !!BaseVD
2262 auto *VarD = dyn_cast_or_null<VarDecl>(BaseVD);
2263 if (VarD && VarD->isConstexpr()) {
2269 Info.Note(VarD->getLocation(), diag::note_constexpr_not_static)
2281 assert((Info.checkingPotentialConstantExpression() ||
2282 LVal.getLValueCallIndex() == 0) &&
2283 "have call index for global lvalue");
2285 if (LVal.allowConstexprUnknown()) {
2287 Info.FFDiag(Loc, diag::note_constexpr_var_init_non_constant, 1) << BaseVD;
2296 Info.FFDiag(Loc, diag::note_constexpr_dynamic_alloc)
2297 << IsReferenceType << !
Designator.Entries.empty();
2303 if (
const VarDecl *Var = dyn_cast<const VarDecl>(BaseVD)) {
2305 if (Var->getTLSKind())
2313 if (!isForManglingOnly(Kind) && Var->hasAttr<DLLImportAttr>() &&
2314 !Var->isStaticLocal())
2318 if (Info.getLangOpts().CUDA && Var->hasAttr<HIPManagedAttr>())
2323 if (Info.getLangOpts().CUDA && Info.getLangOpts().CUDAIsDevice &&
2324 Info.Ctx.CUDAConstantEvalCtx.NoWrongSidedVars) {
2325 if ((!Var->hasAttr<CUDADeviceAttr>() &&
2326 !Var->hasAttr<CUDAConstantAttr>() &&
2327 !Var->getType()->isCUDADeviceBuiltinSurfaceType() &&
2328 !Var->getType()->isCUDADeviceBuiltinTextureType()))
2332 if (
const auto *FD = dyn_cast<const FunctionDecl>(BaseVD)) {
2343 if (Info.getLangOpts().CPlusPlus && !isForManglingOnly(Kind) &&
2344 FD->hasAttr<DLLImportAttr>())
2348 }
else if (
const auto *MTE =
2349 dyn_cast_or_null<MaterializeTemporaryExpr>(BaseE)) {
2350 if (CheckedTemps.insert(MTE).second) {
2353 Info.FFDiag(MTE->getExprLoc(),
2354 diag::note_constexpr_unsupported_temporary_nontrivial_dtor)
2359 APValue *
V = MTE->getOrCreateValue(
false);
2360 assert(
V &&
"evasluation result refers to uninitialised temporary");
2362 Info, MTE->getExprLoc(), TempType, *
V, Kind,
2363 nullptr, CheckedTemps))
2370 if (!IsReferenceType)
2382 Info.FFDiag(Loc, diag::note_constexpr_past_end, 1)
2383 << !
Designator.Entries.empty() << !!BaseVD << BaseVD;
2398 const auto *FD = dyn_cast_or_null<CXXMethodDecl>(
Member);
2401 if (FD->isImmediateFunction()) {
2402 Info.FFDiag(Loc, diag::note_consteval_address_accessible) << 0;
2403 Info.Note(FD->getLocation(), diag::note_declared_at);
2406 return isForManglingOnly(Kind) || FD->isVirtual() ||
2407 !FD->hasAttr<DLLImportAttr>();
2413 const LValue *
This =
nullptr) {
2415 if (Info.getLangOpts().CPlusPlus23)
2434 if (
This && Info.EvaluatingDecl ==
This->getLValueBase())
2438 if (Info.getLangOpts().CPlusPlus11)
2439 Info.FFDiag(E, diag::note_constexpr_nonliteral)
2442 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
2452 bool IsCompleteClass) {
2454 if (SubobjectDecl) {
2455 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
2456 << 1 << SubobjectDecl;
2458 diag::note_constexpr_subobject_declared_here);
2460 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
2469 Type = AT->getValueType();
2474 if (
Value.isArray()) {
2476 for (
unsigned I = 0, N =
Value.getArrayInitializedElts(); I != N; ++I) {
2478 Value.getArrayInitializedElt(I), Kind,
2479 SubobjectDecl, CheckedTemps))
2482 if (!
Value.hasArrayFiller())
2485 Value.getArrayFiller(), Kind, SubobjectDecl,
2488 if (
Value.isUnion() &&
Value.getUnionField()) {
2491 Value.getUnionValue(), Kind,
Value.getUnionField(), CheckedTemps);
2493 if (
Value.isStruct()) {
2495 if (
const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {
2496 unsigned BaseIndex = 0;
2500 const APValue &BaseValue =
Value.getStructBase(BaseIndex);
2503 Info.FFDiag(TypeBeginLoc, diag::note_constexpr_uninitialized_base)
2504 << BS.getType() <<
SourceRange(TypeBeginLoc, BS.getEndLoc());
2509 CheckedTemps,
false))
2514 for (
const auto *I : RD->fields()) {
2515 if (I->isUnnamedBitField())
2519 Value.getStructField(I->getFieldIndex()), Kind,
2524 if (IsCompleteClass) {
2525 if (
const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {
2526 unsigned BaseIndex = 0;
2528 assert(BS.isVirtual());
2529 const APValue &BaseValue =
Value.getStructVirtualBase(BaseIndex);
2532 Info.FFDiag(TypeBeginLoc, diag::note_constexpr_uninitialized_base)
2533 << BS.getType() <<
SourceRange(TypeBeginLoc, BS.getEndLoc());
2537 BaseValue, Kind,
nullptr,
2538 CheckedTemps,
false))
2546 if (
Value.isLValue() &&
2549 LVal.setFrom(Info.Ctx,
Value);
2554 if (
Value.isMemberPointer() &&
2575 nullptr, CheckedTemps);
2585 ConstantExprKind::Normal,
nullptr, CheckedTemps);
2591 if (!Info.HeapAllocs.empty()) {
2595 Info.CCEDiag(Info.HeapAllocs.begin()->second.AllocExpr,
2596 diag::note_constexpr_memory_leak)
2597 <<
unsigned(Info.HeapAllocs.size() - 1);
2605 if (!
Value.getLValueBase()) {
2658 llvm_unreachable(
"unknown APValue kind");
2664 assert(E->
isPRValue() &&
"missing lvalue-to-rvalue conv in bool condition");
2674 Info.CCEDiag(E, diag::note_constexpr_overflow) << SrcValue << DestType;
2675 if (
const auto *OBT = DestType->
getAs<OverflowBehaviorType>();
2676 OBT && OBT->isTrapKind()) {
2679 return Info.noteUndefinedBehavior();
2685 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
2691 if (
Value.convertToInteger(
Result, llvm::APFloat::rmTowardZero, &ignored)
2692 & APFloat::opInvalidOp)
2703 llvm::RoundingMode RM =
2705 if (RM == llvm::RoundingMode::Dynamic)
2706 RM = llvm::RoundingMode::NearestTiesToEven;
2715 APFloat::opStatus St) {
2718 if (Info.InConstantContext)
2722 if ((St & APFloat::opInexact) &&
2726 Info.FFDiag(E, diag::note_constexpr_dynamic_rounding);
2730 if ((St != APFloat::opOK) &&
2733 FPO.getAllowFEnvAccess())) {
2734 Info.FFDiag(E, diag::note_constexpr_float_arithmetic_strict);
2738 if ((St & APFloat::opStatus::opInvalidOp) &&
2759 "HandleFloatToFloatCast has been checked with only CastExpr, "
2760 "CompoundAssignOperator and ConvertVectorExpr. Please either validate "
2761 "the new expression or address the root cause of this usage.");
2763 APFloat::opStatus St;
2766 St =
Result.convert(Info.Ctx.getFloatTypeSemantics(DestType), RM, &ignored);
2773 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
2787 Result = APFloat(Info.Ctx.getFloatTypeSemantics(DestType), 1);
2789 APFloat::opStatus St =
Result.convertFromAPInt(
Value,
Value.isSigned(), RM);
2795 assert(FD->
isBitField() &&
"truncateBitfieldValue on non-bitfield");
2797 if (!
Value.isInt()) {
2801 assert(
Value.isLValue() &&
"integral value neither int nor lvalue?");
2807 unsigned OldBitWidth = Int.getBitWidth();
2809 if (NewBitWidth < OldBitWidth)
2810 Int = Int.trunc(NewBitWidth).extend(OldBitWidth);
2817template<
typename Operation>
2820 unsigned BitWidth, Operation Op,
2822 if (LHS.isUnsigned()) {
2827 APSInt Value(Op(LHS.extend(BitWidth), RHS.extend(BitWidth)),
false);
2830 if (Info.checkingForUndefinedBehavior())
2831 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
2832 diag::warn_integer_constant_overflow)
2845 bool HandleOverflowResult =
true;
2852 std::multiplies<APSInt>(),
Result);
2855 std::plus<APSInt>(),
Result);
2858 std::minus<APSInt>(),
Result);
2859 case BO_And:
Result = LHS & RHS;
return true;
2860 case BO_Xor:
Result = LHS ^ RHS;
return true;
2861 case BO_Or:
Result = LHS | RHS;
return true;
2865 Info.FFDiag(E, diag::note_expr_divide_by_zero)
2871 if (RHS.isNegative() && RHS.isAllOnes() && LHS.isSigned() &&
2872 LHS.isMinSignedValue())
2874 Info, E, -LHS.extend(LHS.getBitWidth() + 1), E->
getType());
2875 Result = (Opcode == BO_Rem ? LHS % RHS : LHS / RHS);
2876 return HandleOverflowResult;
2878 if (Info.getLangOpts().OpenCL)
2880 RHS &=
APSInt(llvm::APInt(RHS.getBitWidth(),
2881 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2883 else if (RHS.isSigned() && RHS.isNegative()) {
2886 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
2887 if (!Info.noteUndefinedBehavior())
2895 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
2897 Info.CCEDiag(E, diag::note_constexpr_large_shift)
2898 << RHS << E->
getType() << LHS.getBitWidth();
2899 if (!Info.noteUndefinedBehavior())
2901 }
else if (LHS.isSigned() && !Info.getLangOpts().CPlusPlus20) {
2906 if (LHS.isNegative()) {
2907 Info.CCEDiag(E, diag::note_constexpr_lshift_of_negative) << LHS;
2908 if (!Info.noteUndefinedBehavior())
2910 }
else if (LHS.countl_zero() < SA) {
2911 Info.CCEDiag(E, diag::note_constexpr_lshift_discards);
2912 if (!Info.noteUndefinedBehavior())
2920 if (Info.getLangOpts().OpenCL)
2922 RHS &=
APSInt(llvm::APInt(RHS.getBitWidth(),
2923 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2925 else if (RHS.isSigned() && RHS.isNegative()) {
2928 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
2929 if (!Info.noteUndefinedBehavior())
2937 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
2939 Info.CCEDiag(E, diag::note_constexpr_large_shift)
2940 << RHS << E->
getType() << LHS.getBitWidth();
2941 if (!Info.noteUndefinedBehavior())
2949 case BO_LT:
Result = LHS < RHS;
return true;
2950 case BO_GT:
Result = LHS > RHS;
return true;
2951 case BO_LE:
Result = LHS <= RHS;
return true;
2952 case BO_GE:
Result = LHS >= RHS;
return true;
2953 case BO_EQ:
Result = LHS == RHS;
return true;
2954 case BO_NE:
Result = LHS != RHS;
return true;
2956 llvm_unreachable(
"BO_Cmp should be handled elsewhere");
2963 const APFloat &RHS) {
2965 APFloat::opStatus St;
2971 St = LHS.multiply(RHS, RM);
2974 St = LHS.add(RHS, RM);
2977 St = LHS.subtract(RHS, RM);
2983 Info.CCEDiag(E, diag::note_expr_divide_by_zero);
2984 St = LHS.divide(RHS, RM);
2997 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << LHS.isNaN();
2998 return Info.noteUndefinedBehavior();
3006 const APInt &RHSValue, APInt &
Result) {
3007 bool LHS = (LHSValue != 0);
3008 bool RHS = (RHSValue != 0);
3010 if (Opcode == BO_LAnd)
3018 const APFloat &RHSValue, APInt &
Result) {
3019 bool LHS = !LHSValue.isZero();
3020 bool RHS = !RHSValue.isZero();
3022 if (Opcode == BO_LAnd)
3041template <
typename APTy>
3044 const APTy &RHSValue, APInt &
Result) {
3047 llvm_unreachable(
"unsupported binary operator");
3049 Result = (LHSValue == RHSValue);
3052 Result = (LHSValue != RHSValue);
3055 Result = (LHSValue < RHSValue);
3058 Result = (LHSValue > RHSValue);
3061 Result = (LHSValue <= RHSValue);
3064 Result = (LHSValue >= RHSValue);
3093 assert(Opcode != BO_PtrMemD && Opcode != BO_PtrMemI &&
3094 "Operation not supported on vector types");
3098 QualType EltTy = VT->getElementType();
3105 "A vector result that isn't a vector OR uncalculated LValue");
3111 RHSValue.
getVectorLength() == NumElements &&
"Different vector sizes");
3115 for (
unsigned EltNum = 0; EltNum < NumElements; ++EltNum) {
3120 APSInt EltResult{Info.Ctx.getIntWidth(EltTy),
3130 RHSElt.
getInt(), EltResult);
3136 ResultElements.emplace_back(EltResult);
3141 "Mismatched LHS/RHS/Result Type");
3142 APFloat LHSFloat = LHSElt.
getFloat();
3150 ResultElements.emplace_back(LHSFloat);
3154 LHSValue =
APValue(ResultElements.data(), ResultElements.size());
3162 unsigned TruncatedElements) {
3163 SubobjectDesignator &D =
Result.Designator;
3166 if (TruncatedElements == D.Entries.size())
3168 assert(TruncatedElements >= D.MostDerivedPathLength &&
3169 "not casting to a derived class");
3175 for (
unsigned I = TruncatedElements, N = D.Entries.size(); I != N; ++I) {
3179 if (isVirtualBaseClass(D.Entries[I]))
3185 D.Entries.resize(TruncatedElements);
3195 RL = &Info.Ctx.getASTRecordLayout(Derived);
3198 Obj.addDecl(Info, E,
Base,
false);
3199 Obj.getLValueOffset() += RL->getBaseClassOffset(
Base);
3211 RL = &Info.Ctx.getASTRecordLayout(Derived);
3214 Obj.addDecl(Info, E,
Base,
true);
3215 Obj.getLValueOffset() += RL->getVBaseClassOffset(
Base);
3224 if (!
Base->isVirtual())
3227 SubobjectDesignator &D = Obj.Designator;
3242 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(DerivedDecl);
3243 Obj.addDecl(Info, E, BaseDecl,
true);
3252 PathI != PathE; ++PathI) {
3256 Type = (*PathI)->getType();
3268 llvm_unreachable(
"Class must be derived from the passed in base class!");
3292 RL = &Info.Ctx.getASTRecordLayout(RD);
3296 LVal.addDecl(Info, E, FD);
3297 LVal.adjustOffset(Info.Ctx.toCharUnitsFromBits(RL->getFieldOffset(I)));
3305 for (
const auto *
C : IFD->
chain())
3339 Size = Info.Ctx.getTypeSizeInChars(
Type);
3341 Size = Info.Ctx.getTypeInfoDataSizeInChars(
Type).Width;
3358 LVal.adjustOffsetAndIndex(Info, E, Adjustment, SizeOfPointee);
3364 int64_t Adjustment) {
3366 APSInt::get(Adjustment));
3381 LVal.Offset += SizeOfComponent;
3383 LVal.addComplex(Info, E, EltTy, Imag);
3389 uint64_t Size, uint64_t Idx) {
3394 LVal.Offset += SizeOfElement * Idx;
3396 LVal.addVectorElement(Info, E, EltTy, Size, Idx);
3410 const VarDecl *VD, CallStackFrame *Frame,
3414 bool AllowConstexprUnknown =
3419 auto CheckUninitReference = [&](
bool IsLocalVariable) {
3431 if (!AllowConstexprUnknown || IsLocalVariable) {
3432 if (!Info.checkingPotentialConstantExpression())
3433 Info.FFDiag(E, diag::note_constexpr_use_uninit_reference);
3443 Result = Frame->getTemporary(VD, Version);
3445 return CheckUninitReference(
true);
3454 "missing value for local variable");
3455 if (Info.checkingPotentialConstantExpression())
3459 "A variable in a frame should either be a local or a parameter");
3465 if (Info.EvaluatingDecl ==
Base) {
3466 Result = Info.EvaluatingDeclValue;
3467 return CheckUninitReference(
false);
3475 if (AllowConstexprUnknown) {
3482 if (!Info.checkingPotentialConstantExpression() ||
3483 !Info.CurrentCall->Callee ||
3485 if (Info.getLangOpts().CPlusPlus11) {
3486 Info.FFDiag(E, diag::note_constexpr_function_param_value_unknown)
3507 if (!
Init && !AllowConstexprUnknown) {
3510 if (!Info.checkingPotentialConstantExpression()) {
3511 Info.FFDiag(E, diag::note_constexpr_var_init_unknown, 1)
3522 if (
Init &&
Init->isValueDependent()) {
3529 if (!Info.checkingPotentialConstantExpression()) {
3530 Info.FFDiag(E, Info.getLangOpts().CPlusPlus11
3531 ? diag::note_constexpr_ltor_non_constexpr
3532 : diag::note_constexpr_ltor_non_integral, 1)
3546 Info.FFDiag(E, diag::note_constexpr_var_init_non_constant, 1) << VD;
3562 !AllowConstexprUnknown) ||
3563 ((Info.getLangOpts().CPlusPlus || Info.getLangOpts().OpenCL) &&
3566 Info.CCEDiag(E, diag::note_constexpr_var_init_non_constant, 1) << VD;
3576 Info.FFDiag(E, diag::note_constexpr_var_init_weak) << VD;
3583 if (!
Result && !AllowConstexprUnknown)
3586 return CheckUninitReference(
false);
3609 llvm_unreachable(
"base class missing from derived class's bases list");
3616 "SourceLocExpr should have already been converted to a StringLiteral");
3619 if (
const auto *ObjCEnc = dyn_cast<ObjCEncodeExpr>(Lit)) {
3621 Info.Ctx.getObjCEncodingForType(ObjCEnc->getEncodedType(), Str);
3622 assert(Index <= Str.size() &&
"Index too large");
3623 return APSInt::getUnsigned(Str.c_str()[Index]);
3626 if (
auto PE = dyn_cast<PredefinedExpr>(Lit))
3627 Lit = PE->getFunctionName();
3630 Info.Ctx.getAsConstantArrayType(S->
getType());
3631 assert(CAT &&
"string literal isn't an array");
3633 assert(CharType->
isIntegerType() &&
"unexpected character type");
3636 if (Index < S->getLength())
3649 AllocType.isNull() ? S->
getType() : AllocType);
3650 assert(CAT &&
"string literal isn't an array");
3652 assert(CharType->
isIntegerType() &&
"unexpected character type");
3659 if (
Result.hasArrayFiller())
3661 for (
unsigned I = 0, N =
Result.getArrayInitializedElts(); I != N; ++I) {
3669 unsigned Size =
Array.getArraySize();
3670 assert(Index < Size);
3673 unsigned OldElts =
Array.getArrayInitializedElts();
3674 unsigned NewElts = std::max(Index+1, OldElts * 2);
3675 NewElts = std::min(Size, std::max(NewElts, 8u));
3679 for (
unsigned I = 0; I != OldElts; ++I)
3681 for (
unsigned I = OldElts; I != NewElts; ++I)
3685 Array.swap(NewValue);
3692 Vec =
APValue(Elts.data(), Elts.size());
3702 CXXRecordDecl *RD =
T->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
3713 for (
auto *Field : RD->
fields())
3714 if (!Field->isUnnamedBitField() &&
3718 for (
auto &BaseSpec : RD->
bases())
3729 CXXRecordDecl *RD =
T->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
3736 for (
auto *Field : RD->
fields()) {
3741 if (Field->isMutable() &&
3743 Info.FFDiag(E, diag::note_constexpr_access_mutable, 1) << AK << Field;
3744 Info.Note(Field->getLocation(), diag::note_declared_at);
3752 for (
auto &BaseSpec : RD->
bases())
3762 bool MutableSubobject =
false) {
3767 switch (Info.IsEvaluatingDecl) {
3768 case EvalInfo::EvaluatingDeclKind::None:
3771 case EvalInfo::EvaluatingDeclKind::Ctor:
3773 if (Info.EvaluatingDecl ==
Base)
3778 if (
auto *BaseE =
Base.dyn_cast<
const Expr *>())
3779 if (
auto *BaseMTE = dyn_cast<MaterializeTemporaryExpr>(BaseE))
3780 return Info.EvaluatingDecl == BaseMTE->getExtendingDecl();
3783 case EvalInfo::EvaluatingDeclKind::Dtor:
3788 if (MutableSubobject ||
Base != Info.EvaluatingDecl)
3794 return T.isConstQualified() ||
T->isReferenceType();
3797 llvm_unreachable(
"unknown evaluating decl kind");
3802 return Info.CheckArraySize(
3822 uint64_t IntResult = BoolResult;
3825 : Info.Ctx.getIntTypeForBitwidth(64,
false);
3826 Result =
APValue(Info.Ctx.MakeIntValue(IntResult, IntType));
3831 Info.Ctx.getIntTypeForBitwidth(64,
false),
3834 Result = std::move(Result2);
3842 DestTy,
Result.getFloat());
3848 uint64_t IntResult = BoolResult;
3867 uint64_t IntResult = BoolResult;
3874 DestTy,
Result.getInt());
3878 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
3891 {&
Result, ResultType, 0}};
3894 while (!WorkList.empty() && ElI < Elements.size()) {
3895 auto [Res,
Type, BitWidth] = WorkList.pop_back_val();
3911 APSInt &Int = Res->getInt();
3912 unsigned OldBitWidth = Int.getBitWidth();
3913 unsigned NewBitWidth = BitWidth;
3914 if (NewBitWidth < OldBitWidth)
3915 Int = Int.trunc(NewBitWidth).extend(OldBitWidth);
3924 for (
unsigned I = 0; I < NumEl; ++I) {
3930 *Res =
APValue(Vals.data(), NumEl);
3939 for (int64_t I = Size - 1; I > -1; --I)
3940 WorkList.emplace_back(&Res->getArrayInitializedElt(I), ElTy, 0u);
3946 unsigned NumBases = 0;
3947 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
3948 NumBases = CXXRD->getNumBases();
3955 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
3956 if (CXXRD->getNumBases() > 0) {
3957 assert(CXXRD->getNumBases() == 1);
3959 ReverseList.emplace_back(&Res->getStructBase(0), BS.
getType(), 0u);
3966 if (FD->isUnnamedBitField())
3968 if (FD->isBitField()) {
3969 FDBW = FD->getBitWidthValue();
3972 ReverseList.emplace_back(&Res->getStructField(FD->getFieldIndex()),
3973 FD->getType(), FDBW);
3976 std::reverse(ReverseList.begin(), ReverseList.end());
3977 llvm::append_range(WorkList, ReverseList);
3980 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
3993 assert((Elements.size() == SrcTypes.size()) &&
3994 (Elements.size() == DestTypes.size()));
3996 for (
unsigned I = 0, ESz = Elements.size(); I < ESz; ++I) {
3997 APValue Original = Elements[I];
4001 if (!
handleScalarCast(Info, FPO, E, SourceTy, DestTy, Original, Results[I]))
4012 while (!WorkList.empty()) {
4035 for (uint64_t I = 0; I < ArrSize; ++I) {
4036 WorkList.push_back(ElTy);
4044 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4045 if (CXXRD->getNumBases() > 0) {
4046 assert(CXXRD->getNumBases() == 1);
4048 WorkList.push_back(BS.
getType());
4054 if (FD->isUnnamedBitField())
4056 WorkList.push_back(FD->getType());
4073 "Not a valid HLSLAggregateSplatCast.");
4093 unsigned Populated = 0;
4094 while (!WorkList.empty() && Populated < Size) {
4095 auto [Work,
Type] = WorkList.pop_back_val();
4097 if (Work.isFloat() || Work.isInt()) {
4098 Elements.push_back(Work);
4099 Types.push_back(
Type);
4103 if (Work.isVector()) {
4106 for (
unsigned I = 0; I < Work.getVectorLength() && Populated < Size;
4108 Elements.push_back(Work.getVectorElt(I));
4109 Types.push_back(ElTy);
4114 if (Work.isMatrix()) {
4117 QualType ElTy = MT->getElementType();
4119 for (
unsigned Row = 0; Row < Work.getMatrixNumRows() && Populated < Size;
4121 for (
unsigned Col = 0;
4122 Col < Work.getMatrixNumColumns() && Populated < Size; Col++) {
4123 Elements.push_back(Work.getMatrixElt(Row, Col));
4124 Types.push_back(ElTy);
4130 if (Work.isArray()) {
4134 for (int64_t I = Work.getArraySize() - 1; I > -1; --I) {
4135 WorkList.emplace_back(Work.getArrayInitializedElt(I), ElTy);
4140 if (Work.isStruct()) {
4148 if (FD->isUnnamedBitField())
4150 ReverseList.emplace_back(Work.getStructField(FD->getFieldIndex()),
4154 std::reverse(ReverseList.begin(), ReverseList.end());
4155 llvm::append_range(WorkList, ReverseList);
4158 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4159 if (CXXRD->getNumBases() > 0) {
4160 assert(CXXRD->getNumBases() == 1);
4165 if (!
Base.isStruct())
4173 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
4182struct CompleteObject {
4184 APValue::LValueBase
Base;
4194 bool mayAccessMutableMembers(EvalInfo &Info,
AccessKinds AK)
const {
4205 if (!Info.getLangOpts().CPlusPlus14 &&
4206 AK != AccessKinds::AK_IsWithinLifetime)
4211 explicit operator bool()
const {
return !
Type.isNull(); }
4216 bool IsMutable =
false) {
4230template <
typename Sub
objectHandler>
4231static typename SubobjectHandler::result_type
4233 const SubobjectDesignator &Sub, SubobjectHandler &handler) {
4236 return handler.failed();
4237 if (Sub.isOnePastTheEnd() || Sub.isMostDerivedAnUnsizedArray()) {
4238 if (Info.getLangOpts().CPlusPlus11)
4239 Info.FFDiag(E, Sub.isOnePastTheEnd()
4240 ? diag::note_constexpr_access_past_end
4241 : diag::note_constexpr_access_unsized_array)
4242 << handler.AccessKind;
4245 return handler.failed();
4251 const FieldDecl *VolatileField =
nullptr;
4254 for (
unsigned I = 0, N = Sub.Entries.size(); ; ++I) {
4265 if (!Info.checkingPotentialConstantExpression()) {
4266 Info.FFDiag(E, diag::note_constexpr_access_uninit)
4271 return handler.failed();
4279 Info.isEvaluatingCtorDtor(
4280 Obj.Base,
ArrayRef(Sub.Entries.begin(), Sub.Entries.begin() + I)) !=
4281 ConstructionPhase::None) {
4282 ObjType = Info.Ctx.getCanonicalType(ObjType);
4291 if (Info.getLangOpts().CPlusPlus) {
4295 if (VolatileField) {
4298 Decl = VolatileField;
4301 Loc = VD->getLocation();
4308 Info.FFDiag(E, diag::note_constexpr_access_volatile_obj, 1)
4309 << handler.AccessKind << DiagKind <<
Decl;
4310 Info.Note(Loc, diag::note_constexpr_volatile_here) << DiagKind;
4312 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
4314 return handler.failed();
4322 !Obj.mayAccessMutableMembers(Info, handler.AccessKind) &&
4324 return handler.failed();
4328 if (!handler.found(*O, ObjType, Obj.Base))
4340 LastField =
nullptr;
4345 ObjType = Info.Ctx.getQualifiedType(AT->getValueType(),
4350 const ArrayType *AT = Info.Ctx.getAsArrayType(ObjType);
4352 "vla in literal type?");
4353 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4354 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT);
4355 CAT && CAT->
getSize().ule(Index)) {
4358 if (Info.getLangOpts().CPlusPlus11)
4359 Info.FFDiag(E, diag::note_constexpr_access_past_end)
4360 << handler.AccessKind;
4363 return handler.failed();
4370 else if (!
isRead(handler.AccessKind)) {
4371 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT);
4373 return handler.failed();
4381 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4383 if (Info.getLangOpts().CPlusPlus11)
4384 Info.FFDiag(E, diag::note_constexpr_access_past_end)
4385 << handler.AccessKind;
4388 return handler.failed();
4394 assert(I == N - 1 &&
"extracting subobject of scalar?");
4404 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4405 unsigned NumElements = VT->getNumElements();
4406 if (Index == NumElements) {
4407 if (Info.getLangOpts().CPlusPlus11)
4408 Info.FFDiag(E, diag::note_constexpr_access_past_end)
4409 << handler.AccessKind;
4412 return handler.failed();
4415 if (Index > NumElements) {
4416 Info.CCEDiag(E, diag::note_constexpr_array_index)
4417 << Index << 0 << NumElements;
4418 return handler.failed();
4421 ObjType = VT->getElementType();
4422 assert(I == N - 1 &&
"extracting subobject of scalar?");
4425 if (
isRead(handler.AccessKind)) {
4427 return handler.failed();
4431 assert(O->
isVector() &&
"unexpected object during vector element access");
4432 return handler.found(O->
getVectorElt(Index), ObjType, Obj.Base);
4433 }
else if (
const FieldDecl *Field = getAsField(Sub.Entries[I])) {
4434 if (Field->isMutable() &&
4435 !Obj.mayAccessMutableMembers(Info, handler.AccessKind)) {
4436 Info.FFDiag(E, diag::note_constexpr_access_mutable, 1)
4437 << handler.AccessKind << Field;
4438 Info.Note(Field->getLocation(), diag::note_declared_at);
4439 return handler.failed();
4448 if (I == N - 1 && handler.AccessKind ==
AK_Construct) {
4459 Info.FFDiag(E, diag::note_constexpr_access_inactive_union_member)
4460 << handler.AccessKind << Field << !UnionField << UnionField;
4461 return handler.failed();
4470 if (Field->getType().isVolatileQualified())
4471 VolatileField = Field;
4479 if (BaseIndex >= NumNonVirtualBases) {
4490struct ExtractSubobjectHandler {
4496 typedef bool result_type;
4497 bool failed() {
return false; }
4498 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
4508 bool found(APFloat &
Value, QualType SubobjType) {
4517 const CompleteObject &Obj,
4521 ExtractSubobjectHandler Handler = {Info, E,
Result, AK};
4526struct ModifySubobjectHandler {
4531 typedef bool result_type;
4534 bool checkConst(QualType QT) {
4537 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
4543 bool failed() {
return false; }
4544 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
4545 if (!checkConst(SubobjType))
4548 Subobj.
swap(NewVal);
4552 if (!checkConst(SubobjType))
4554 if (!NewVal.
isInt()) {
4562 bool found(APFloat &
Value, QualType SubobjType) {
4563 if (!checkConst(SubobjType))
4571const AccessKinds ModifySubobjectHandler::AccessKind;
4575 const CompleteObject &Obj,
4576 const SubobjectDesignator &Sub,
4578 ModifySubobjectHandler Handler = { Info, NewVal, E };
4585 const SubobjectDesignator &A,
4586 const SubobjectDesignator &B,
4587 bool &WasArrayIndex) {
4588 unsigned I = 0, N = std::min(A.Entries.size(), B.Entries.size());
4589 for (; I != N; ++I) {
4593 if (A.Entries[I].getAsArrayIndex() != B.Entries[I].getAsArrayIndex()) {
4594 WasArrayIndex =
true;
4602 if (A.Entries[I].getAsBaseOrMember() !=
4603 B.Entries[I].getAsBaseOrMember()) {
4604 WasArrayIndex =
false;
4607 if (
const FieldDecl *FD = getAsField(A.Entries[I]))
4609 ObjType = FD->getType();
4615 WasArrayIndex =
false;
4622 const SubobjectDesignator &A,
4623 const SubobjectDesignator &B) {
4624 if (A.Entries.size() != B.Entries.size())
4627 bool IsArray = A.MostDerivedIsArrayElement;
4628 if (IsArray && A.MostDerivedPathLength != A.Entries.size())
4637 return CommonLength >= A.Entries.size() - IsArray;
4644 if (LVal.InvalidBase) {
4646 return CompleteObject();
4651 Info.FFDiag(E, diag::note_constexpr_dereferencing_null);
4653 Info.FFDiag(E, diag::note_constexpr_access_null) << AK;
4654 return CompleteObject();
4657 CallStackFrame *Frame =
nullptr;
4659 if (LVal.getLValueCallIndex()) {
4660 std::tie(Frame, Depth) =
4661 Info.getCallFrameAndDepth(LVal.getLValueCallIndex());
4663 Info.FFDiag(E, diag::note_constexpr_access_uninit, 1)
4666 return CompleteObject();
4677 if (Info.getLangOpts().CPlusPlus)
4678 Info.FFDiag(E, diag::note_constexpr_access_volatile_type)
4682 return CompleteObject();
4689 if (Info.getLangOpts().CPlusPlus14 && LVal.Base == Info.EvaluatingDecl &&
4693 BaseVal = Info.EvaluatingDeclValue;
4696 if (
auto *GD = dyn_cast<MSGuidDecl>(D)) {
4699 Info.FFDiag(E, diag::note_constexpr_modify_global);
4700 return CompleteObject();
4704 Info.FFDiag(E, diag::note_constexpr_unsupported_layout)
4706 return CompleteObject();
4708 return CompleteObject(LVal.Base, &
V, GD->getType());
4712 if (
auto *GCD = dyn_cast<UnnamedGlobalConstantDecl>(D)) {
4714 Info.FFDiag(E, diag::note_constexpr_modify_global);
4715 return CompleteObject();
4717 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&GCD->getValue()),
4722 if (
auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
4724 Info.FFDiag(E, diag::note_constexpr_modify_global);
4725 return CompleteObject();
4727 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&TPO->getValue()),
4738 const VarDecl *VD = dyn_cast<VarDecl>(D);
4745 return CompleteObject();
4748 bool IsConstant = BaseType.isConstant(Info.Ctx);
4749 bool ConstexprVar =
false;
4750 if (
const auto *VD = dyn_cast_if_present<VarDecl>(
4762 }
else if (Info.getLangOpts().CPlusPlus14 &&
4769 Info.FFDiag(E, diag::note_constexpr_modify_global);
4770 return CompleteObject();
4773 }
else if (Info.getLangOpts().C23 && ConstexprVar) {
4775 return CompleteObject();
4776 }
else if (BaseType->isIntegralOrEnumerationType()) {
4779 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4780 if (Info.getLangOpts().CPlusPlus) {
4781 Info.FFDiag(E, diag::note_constexpr_ltor_non_const_int, 1) << VD;
4782 Info.Note(VD->
getLocation(), diag::note_declared_at);
4786 return CompleteObject();
4788 }
else if (!IsAccess) {
4789 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4790 }
else if ((IsConstant || BaseType->isReferenceType()) &&
4791 Info.checkingPotentialConstantExpression() &&
4792 BaseType->isLiteralType(Info.Ctx) && !VD->
hasDefinition()) {
4794 }
else if (IsConstant) {
4798 if (Info.getLangOpts().CPlusPlus) {
4799 Info.CCEDiag(E, Info.getLangOpts().CPlusPlus11
4800 ? diag::note_constexpr_ltor_non_constexpr
4801 : diag::note_constexpr_ltor_non_integral, 1)
4803 Info.Note(VD->
getLocation(), diag::note_declared_at);
4809 if (Info.getLangOpts().CPlusPlus) {
4810 Info.FFDiag(E, Info.getLangOpts().CPlusPlus11
4811 ? diag::note_constexpr_ltor_non_constexpr
4812 : diag::note_constexpr_ltor_non_integral, 1)
4814 Info.Note(VD->
getLocation(), diag::note_declared_at);
4818 return CompleteObject();
4827 return CompleteObject();
4832 if (!Info.checkingPotentialConstantExpression()) {
4833 Info.FFDiag(E, diag::note_constexpr_access_unknown_variable, 1)
4835 Info.Note(VD->getLocation(), diag::note_declared_at);
4837 return CompleteObject();
4840 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
4842 Info.FFDiag(E, diag::note_constexpr_access_deleted_object) << AK;
4843 return CompleteObject();
4845 return CompleteObject(LVal.Base, &(*Alloc)->Value,
4855 dyn_cast_or_null<MaterializeTemporaryExpr>(
Base)) {
4856 assert(MTE->getStorageDuration() ==
SD_Static &&
4857 "should have a frame for a non-global materialized temporary");
4884 if (!MTE->isUsableInConstantExpressions(Info.Ctx) &&
4887 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4888 Info.FFDiag(E, diag::note_constexpr_access_static_temporary, 1) << AK;
4889 Info.Note(MTE->getExprLoc(), diag::note_constexpr_temporary_here);
4890 return CompleteObject();
4893 BaseVal = MTE->getOrCreateValue(
false);
4894 assert(BaseVal &&
"got reference to unevaluated temporary");
4896 dyn_cast_or_null<CompoundLiteralExpr>(
Base)) {
4912 !CLETy.isConstant(Info.Ctx)) {
4914 Info.Note(CLE->getExprLoc(), diag::note_declared_at);
4915 return CompleteObject();
4918 BaseVal = &CLE->getStaticValue();
4921 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4924 Info.FFDiag(E, diag::note_constexpr_access_unreadable_object)
4927 Info.Ctx.getLValueReferenceType(LValType));
4929 return CompleteObject();
4933 assert(BaseVal &&
"missing value for temporary");
4944 unsigned VisibleDepth = Depth;
4945 if (llvm::isa_and_nonnull<ParmVarDecl>(
4948 if ((Frame && Info.getLangOpts().CPlusPlus14 &&
4949 Info.EvalStatus.HasSideEffects) ||
4950 (
isModification(AK) && VisibleDepth < Info.SpeculativeEvaluationDepth))
4951 return CompleteObject();
4953 return CompleteObject(LVal.getLValueBase(), BaseVal, BaseType);
4972 const LValue &LVal,
APValue &RVal,
4973 bool WantObjectRepresentation =
false) {
4974 if (LVal.Designator.Invalid)
4983 if (
Base && !LVal.getLValueCallIndex() && !
Type.isVolatileQualified()) {
4987 assert(LVal.Designator.Entries.size() <= 1 &&
4988 "Can only read characters from string literals");
4989 if (LVal.Designator.Entries.empty()) {
4996 if (LVal.Designator.isOnePastTheEnd()) {
4997 if (Info.getLangOpts().CPlusPlus11)
4998 Info.FFDiag(Conv, diag::note_constexpr_access_past_end) << AK;
5003 uint64_t CharIndex = LVal.Designator.Entries[0].getAsArrayIndex();
5010 return Obj &&
extractSubobject(Info, Conv, Obj, LVal.Designator, RVal, AK);
5024 LVal.setFrom(Info.Ctx, Val);
5040 if (LVal.Designator.Invalid)
5043 if (!Info.getLangOpts().CPlusPlus14) {
5053struct CompoundAssignSubobjectHandler {
5055 const CompoundAssignOperator *E;
5056 QualType PromotedLHSType;
5062 typedef bool result_type;
5064 bool checkConst(QualType QT) {
5067 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
5073 bool failed() {
return false; }
5074 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
5077 return found(Subobj.
getInt(), SubobjType);
5079 return found(Subobj.
getFloat(), SubobjType);
5086 return foundPointer(Subobj, SubobjType);
5088 return foundVector(Subobj, SubobjType);
5090 Info.FFDiag(E, diag::note_constexpr_access_uninit)
5102 bool foundVector(
APValue &
Value, QualType SubobjType) {
5103 if (!checkConst(SubobjType))
5114 if (!checkConst(SubobjType))
5133 Info.Ctx.getLangOpts());
5136 PromotedLHSType, FValue) &&
5145 bool found(APFloat &
Value, QualType SubobjType) {
5146 return checkConst(SubobjType) &&
5152 bool foundPointer(
APValue &Subobj, QualType SubobjType) {
5153 if (!checkConst(SubobjType))
5156 QualType PointeeType;
5157 if (
const PointerType *PT = SubobjType->
getAs<PointerType>())
5161 (Opcode != BO_Add && Opcode != BO_Sub)) {
5167 if (Opcode == BO_Sub)
5171 LVal.setFrom(Info.Ctx, Subobj);
5174 LVal.moveInto(Subobj);
5180const AccessKinds CompoundAssignSubobjectHandler::AccessKind;
5185 const LValue &LVal,
QualType LValType,
5189 if (LVal.Designator.Invalid)
5192 if (!Info.getLangOpts().CPlusPlus14) {
5198 CompoundAssignSubobjectHandler Handler = { Info, E, PromotedLValType, Opcode,
5200 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
5204struct IncDecSubobjectHandler {
5206 const UnaryOperator *E;
5210 typedef bool result_type;
5212 bool checkConst(QualType QT) {
5215 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
5221 bool failed() {
return false; }
5222 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
5232 return found(Subobj.
getInt(), SubobjType);
5234 return found(Subobj.
getFloat(), SubobjType);
5237 SubobjType->
castAs<ComplexType>()->getElementType()
5241 SubobjType->
castAs<ComplexType>()->getElementType()
5244 return foundPointer(Subobj, SubobjType);
5252 if (!checkConst(SubobjType))
5274 bool WasNegative =
Value.isNegative();
5288 unsigned BitWidth =
Value.getBitWidth();
5289 APSInt ActualValue(
Value.sext(BitWidth + 1),
false);
5290 ActualValue.setBit(BitWidth);
5296 bool found(APFloat &
Value, QualType SubobjType) {
5297 if (!checkConst(SubobjType))
5304 APFloat::opStatus St;
5306 St =
Value.add(One, RM);
5308 St =
Value.subtract(One, RM);
5311 bool foundPointer(
APValue &Subobj, QualType SubobjType) {
5312 if (!checkConst(SubobjType))
5315 QualType PointeeType;
5316 if (
const PointerType *PT = SubobjType->
getAs<PointerType>())
5324 LVal.setFrom(Info.Ctx, Subobj);
5328 LVal.moveInto(Subobj);
5337 if (LVal.Designator.Invalid)
5340 if (!Info.getLangOpts().CPlusPlus14) {
5348 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
5354 if (
Object->getType()->isPointerType() &&
Object->isPRValue())
5360 if (
Object->getType()->isLiteralType(Info.Ctx))
5363 if (
Object->getType()->isRecordType() &&
Object->isPRValue())
5366 Info.FFDiag(
Object, diag::note_constexpr_nonliteral) <<
Object->getType();
5385 bool IncludeMember =
true) {
5392 if (!MemPtr.getDecl()) {
5398 if (MemPtr.isDerivedMember()) {
5405 if (LV.Designator.MostDerivedPathLength + MemPtr.Path.size() >
5406 LV.Designator.Entries.size()) {
5410 unsigned PathLengthToMember =
5411 LV.Designator.Entries.size() - MemPtr.Path.size();
5412 for (
unsigned I = 0, N = MemPtr.Path.size(); I != N; ++I) {
5414 LV.Designator.Entries[PathLengthToMember + I]);
5431 (PathLengthToMember > LV.Designator.MostDerivedPathLength)
5432 ? getAsBaseClass(LV.Designator.Entries[PathLengthToMember - 1])
5434 const CXXRecordDecl *LastMPDecl = MemPtr.getContainingRecord();
5442 PathLengthToMember))
5444 }
else if (!MemPtr.Path.empty()) {
5446 LV.Designator.Entries.reserve(LV.Designator.Entries.size() +
5447 MemPtr.Path.size() + IncludeMember);
5453 assert(RD &&
"member pointer access on non-class-type expression");
5455 for (
unsigned I = 1, N = MemPtr.Path.size(); I != N; ++I) {
5463 MemPtr.getContainingRecord()))
5468 if (IncludeMember) {
5469 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(MemPtr.getDecl())) {
5473 dyn_cast<IndirectFieldDecl>(MemPtr.getDecl())) {
5477 llvm_unreachable(
"can't construct reference to bound member function");
5481 return MemPtr.getDecl();
5487 bool IncludeMember =
true) {
5491 if (Info.noteFailure()) {
5499 BO->
getRHS(), IncludeMember);
5506 SubobjectDesignator &D =
Result.Designator;
5514 auto InvalidCast = [&]() {
5515 if (!Info.checkingPotentialConstantExpression() ||
5516 !
Result.AllowConstexprUnknown) {
5517 Info.CCEDiag(E, diag::note_constexpr_invalid_downcast)
5518 << D.MostDerivedType << TargetQT;
5524 if (D.MostDerivedPathLength + E->
path_size() > D.Entries.size())
5525 return InvalidCast();
5529 unsigned NewEntriesSize = D.Entries.size() - E->
path_size();
5532 if (NewEntriesSize == D.MostDerivedPathLength)
5535 FinalType = getAsBaseClass(D.Entries[NewEntriesSize - 1]);
5537 return InvalidCast();
5546 bool IsCompleteClass =
true) {
5553 if (
auto *RD =
T->getAsCXXRecordDecl()) {
5554 if (RD->isInvalidDecl()) {
5558 if (RD->isUnion()) {
5564 unsigned NonVirtualBases = countNonVirtualBases(RD);
5567 IsCompleteClass ? RD->getNumVBases() : 0);
5578 for (
const auto *I : RD->fields()) {
5579 if (I->isUnnamedBitField())
5582 I->getType(),
Result.getStructField(I->getFieldIndex()));
5585 if (IsCompleteClass) {
5588 for (
const auto &B : RD->vbases()) {
5590 Result.getStructVirtualBase(Index),
5596 assert(
Result.getStructNumVirtualBases() == 0);
5603 dyn_cast_or_null<ConstantArrayType>(
T->getAsArrayTypeUnsafe())) {
5605 if (
Result.hasArrayFiller())
5616enum EvalStmtResult {
5645 if (!
Result.Designator.Invalid &&
Result.Designator.isOnePastTheEnd()) {
5663 APValue &Val = Info.CurrentCall->createTemporary(VD, VD->
getType(),
5664 ScopeKind::Block,
Result);
5669 return Info.noteSideEffect();
5690 const DecompositionDecl *DD);
5693 bool EvaluateConditionDecl =
false) {
5695 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
5699 EvaluateConditionDecl && DD)
5709 if (
auto *VD = BD->getHoldingVar())
5717 if (
auto *DD = dyn_cast_if_present<DecompositionDecl>(VD)) {
5726 if (Info.noteSideEffect())
5728 assert(E->
containsErrors() &&
"valid value-dependent expression should never "
5729 "reach invalid code path.");
5738 FullExpressionRAII
Scope(Info);
5745 return Scope.destroy();
5758struct TempVersionRAII {
5759 CallStackFrame &Frame;
5761 TempVersionRAII(CallStackFrame &Frame) : Frame(Frame) {
5762 Frame.pushTempVersion();
5765 ~TempVersionRAII() {
5766 Frame.popTempVersion();
5774 const SwitchCase *SC =
nullptr);
5780 const Stmt *LoopOrSwitch,
5782 EvalStmtResult &ESR) {
5786 if (!IsSwitch && ESR == ESR_Succeeded) {
5791 if (ESR != ESR_Break && ESR != ESR_Continue)
5795 bool CanBreakOrContinue = !IsSwitch || ESR == ESR_Break;
5796 const Stmt *StackTop = Info.BreakContinueStack.back();
5797 if (CanBreakOrContinue && (StackTop ==
nullptr || StackTop == LoopOrSwitch)) {
5798 Info.BreakContinueStack.pop_back();
5799 if (ESR == ESR_Break)
5800 ESR = ESR_Succeeded;
5805 for (BlockScopeRAII *S : Scopes) {
5806 if (!S->destroy()) {
5818 BlockScopeRAII
Scope(Info);
5821 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5830 BlockScopeRAII
Scope(Info);
5837 if (ESR != ESR_Succeeded) {
5838 if (ESR != ESR_Failed && !
Scope.destroy())
5844 FullExpressionRAII CondScope(Info);
5859 if (!CondScope.destroy())
5880 if (LHSValue <=
Value &&
Value <= RHSValue) {
5887 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5891 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5898 llvm_unreachable(
"Should have been converted to Succeeded");
5904 case ESR_CaseNotFound:
5907 Info.FFDiag(
Found->getBeginLoc(),
5908 diag::note_constexpr_stmt_expr_unsupported);
5911 llvm_unreachable(
"Invalid EvalStmtResult!");
5921 Info.CCEDiag(VD->
getLocation(), diag::note_constexpr_static_local)
5931 if (!Info.nextStep(S))
5938 case Stmt::CompoundStmtClass:
5942 case Stmt::LabelStmtClass:
5943 case Stmt::AttributedStmtClass:
5944 case Stmt::DoStmtClass:
5947 case Stmt::CaseStmtClass:
5948 case Stmt::DefaultStmtClass:
5953 case Stmt::IfStmtClass: {
5960 BlockScopeRAII
Scope(Info);
5966 if (ESR != ESR_CaseNotFound) {
5967 assert(ESR != ESR_Succeeded);
5978 if (ESR == ESR_Failed)
5980 if (ESR != ESR_CaseNotFound)
5981 return Scope.destroy() ? ESR : ESR_Failed;
5983 return ESR_CaseNotFound;
5986 if (ESR == ESR_Failed)
5988 if (ESR != ESR_CaseNotFound)
5989 return Scope.destroy() ? ESR : ESR_Failed;
5990 return ESR_CaseNotFound;
5993 case Stmt::WhileStmtClass: {
5994 EvalStmtResult ESR =
5998 if (ESR != ESR_Continue)
6003 case Stmt::ForStmtClass: {
6005 BlockScopeRAII
Scope(Info);
6011 if (ESR != ESR_CaseNotFound) {
6012 assert(ESR != ESR_Succeeded);
6017 EvalStmtResult ESR =
6021 if (ESR != ESR_Continue)
6023 if (
const auto *Inc = FS->
getInc()) {
6024 if (Inc->isValueDependent()) {
6028 FullExpressionRAII IncScope(Info);
6036 case Stmt::DeclStmtClass: {
6040 for (
const auto *D : DS->
decls()) {
6041 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
6044 if (VD->hasLocalStorage() && !VD->getInit())
6052 return ESR_CaseNotFound;
6056 return ESR_CaseNotFound;
6062 if (
const Expr *E = dyn_cast<Expr>(S)) {
6071 FullExpressionRAII
Scope(Info);
6075 return ESR_Succeeded;
6081 case Stmt::NullStmtClass:
6082 return ESR_Succeeded;
6084 case Stmt::DeclStmtClass: {
6086 for (
const auto *D : DS->
decls()) {
6087 const VarDecl *VD = dyn_cast_or_null<VarDecl>(D);
6091 if (
const auto *ESD = dyn_cast<CXXExpansionStmtDecl>(D)) {
6092 assert(ESD->getInstantiations() &&
"not expanded?");
6097 FullExpressionRAII
Scope(Info);
6099 !Info.noteFailure())
6101 if (!
Scope.destroy())
6104 return ESR_Succeeded;
6107 case Stmt::ReturnStmtClass: {
6109 FullExpressionRAII
Scope(Info);
6120 return Scope.destroy() ? ESR_Returned : ESR_Failed;
6123 case Stmt::CompoundStmtClass: {
6124 BlockScopeRAII
Scope(Info);
6127 for (
const auto *BI : CS->
body()) {
6129 if (ESR == ESR_Succeeded)
6131 else if (ESR != ESR_CaseNotFound) {
6132 if (ESR != ESR_Failed && !
Scope.destroy())
6138 return ESR_CaseNotFound;
6139 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
6142 case Stmt::IfStmtClass: {
6146 BlockScopeRAII
Scope(Info);
6149 if (ESR != ESR_Succeeded) {
6150 if (ESR != ESR_Failed && !
Scope.destroy())
6160 if (!Info.InConstantContext)
6168 if (ESR != ESR_Succeeded) {
6169 if (ESR != ESR_Failed && !
Scope.destroy())
6174 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
6177 case Stmt::WhileStmtClass: {
6180 BlockScopeRAII
Scope(Info);
6192 if (ESR != ESR_Continue) {
6193 if (ESR != ESR_Failed && !
Scope.destroy())
6197 if (!
Scope.destroy())
6200 return ESR_Succeeded;
6203 case Stmt::DoStmtClass: {
6210 if (ESR != ESR_Continue)
6219 FullExpressionRAII CondScope(Info);
6221 !CondScope.destroy())
6224 return ESR_Succeeded;
6227 case Stmt::ForStmtClass: {
6229 BlockScopeRAII ForScope(Info);
6232 if (ESR != ESR_Succeeded) {
6233 if (ESR != ESR_Failed && !ForScope.destroy())
6239 BlockScopeRAII IterScope(Info);
6240 bool Continue =
true;
6246 if (!IterScope.destroy())
6254 if (ESR != ESR_Continue) {
6255 if (ESR != ESR_Failed && (!IterScope.destroy() || !ForScope.destroy()))
6260 if (
const auto *Inc = FS->
getInc()) {
6261 if (Inc->isValueDependent()) {
6265 FullExpressionRAII IncScope(Info);
6271 if (!IterScope.destroy())
6274 return ForScope.destroy() ? ESR_Succeeded : ESR_Failed;
6277 case Stmt::CXXForRangeStmtClass: {
6279 BlockScopeRAII
Scope(Info);
6284 if (ESR != ESR_Succeeded) {
6285 if (ESR != ESR_Failed && !
Scope.destroy())
6293 if (ESR != ESR_Succeeded) {
6294 if (ESR != ESR_Failed && !
Scope.destroy())
6306 if (ESR != ESR_Succeeded) {
6307 if (ESR != ESR_Failed && !
Scope.destroy())
6312 if (ESR != ESR_Succeeded) {
6313 if (ESR != ESR_Failed && !
Scope.destroy())
6326 bool Continue =
true;
6327 FullExpressionRAII CondExpr(Info);
6335 BlockScopeRAII InnerScope(Info);
6337 if (ESR != ESR_Succeeded) {
6338 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
6347 if (ESR != ESR_Continue) {
6348 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
6361 if (!InnerScope.destroy())
6365 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
6368 case Stmt::CXXExpansionStmtInstantiationClass: {
6369 BlockScopeRAII
Scope(Info);
6371 for (
const Stmt *PreambleStmt : Expansion->getPreambleStmts()) {
6373 if (ESR != ESR_Succeeded) {
6374 if (ESR != ESR_Failed && !
Scope.destroy())
6382 EvalStmtResult ESR = ESR_Succeeded;
6383 for (
const Stmt *Instantiation : Expansion->getInstantiations()) {
6385 if (ESR == ESR_Failed ||
6388 if (ESR != ESR_Continue) {
6390 assert(ESR == ESR_Succeeded || ESR == ESR_Returned);
6396 if (ESR == ESR_Continue)
6397 ESR = ESR_Succeeded;
6399 return Scope.destroy() ? ESR : ESR_Failed;
6402 case Stmt::SwitchStmtClass:
6405 case Stmt::ContinueStmtClass:
6406 case Stmt::BreakStmtClass: {
6408 Info.BreakContinueStack.push_back(B->getNamedLoopOrSwitch());
6412 case Stmt::LabelStmtClass:
6415 case Stmt::AttributedStmtClass: {
6417 const auto *SS = AS->getSubStmt();
6418 MSConstexprContextRAII ConstexprContext(
6422 auto LO = Info.Ctx.getLangOpts();
6423 if (LO.CXXAssumptions && !LO.MSVCCompat) {
6424 for (
auto *
Attr : AS->getAttrs()) {
6425 auto *AA = dyn_cast<CXXAssumeAttr>(
Attr);
6429 auto *Assumption = AA->getAssumption();
6430 if (Assumption->isValueDependent())
6433 if (Assumption->HasSideEffects(Info.Ctx))
6440 Info.CCEDiag(Assumption->getExprLoc(),
6441 diag::note_constexpr_assumption_failed);
6450 case Stmt::CaseStmtClass:
6451 case Stmt::DefaultStmtClass:
6453 case Stmt::CXXTryStmtClass:
6465 bool IsValueInitialization) {
6472 if (!CD->
isConstexpr() && !IsValueInitialization) {
6473 if (Info.getLangOpts().CPlusPlus11) {
6476 Info.CCEDiag(Loc, diag::note_constexpr_invalid_function, 1)
6478 Info.Note(CD->
getLocation(), diag::note_declared_at);
6480 Info.CCEDiag(Loc, diag::note_invalid_subexpr_in_const_expr);
6494 if (Info.checkingPotentialConstantExpression() && !
Definition &&
6502 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6511 Info.CCEDiag(CallLoc, diag::note_constexpr_virtual_call);
6514 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6520 (
Definition->isConstexpr() || (Info.CurrentCall->CanEvalMSConstexpr &&
6530 StringRef Name = DiagDecl->
getName();
6532 Name ==
"__assert_rtn" || Name ==
"__assert_fail" || Name ==
"_wassert";
6534 Info.FFDiag(CallLoc, diag::note_constexpr_assert_failed);
6539 if (Info.getLangOpts().CPlusPlus11) {
6542 auto *CD = dyn_cast<CXXConstructorDecl>(DiagDecl);
6543 if (CD && CD->isInheritingConstructor()) {
6544 auto *Inherited = CD->getInheritedConstructor().getConstructor();
6545 if (!Inherited->isConstexpr())
6546 DiagDecl = CD = Inherited;
6552 if (CD && CD->isInheritingConstructor())
6553 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_inhctor, 1)
6554 << CD->getInheritedConstructor().getConstructor()->getParent();
6556 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_function, 1)
6558 Info.Note(DiagDecl->
getLocation(), diag::note_declared_at);
6560 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6566struct CheckDynamicTypeHandler {
6568 typedef bool result_type;
6569 bool failed() {
return false; }
6570 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
6573 bool found(
APSInt &
Value, QualType SubobjType) {
return true; }
6574 bool found(APFloat &
Value, QualType SubobjType) {
return true; }
6582 if (
This.Designator.Invalid)
6594 if (
This.Designator.isOnePastTheEnd() ||
6595 This.Designator.isMostDerivedAnUnsizedArray()) {
6596 Info.FFDiag(E,
This.Designator.isOnePastTheEnd()
6597 ? diag::note_constexpr_access_past_end
6598 : diag::note_constexpr_access_unsized_array)
6601 }
else if (Polymorphic) {
6604 if (!Info.checkingPotentialConstantExpression() ||
6605 !
This.AllowConstexprUnknown) {
6609 Info.Ctx.getLValueReferenceType(
This.Designator.getType(Info.Ctx));
6610 Info.FFDiag(E, diag::note_constexpr_polymorphic_unknown_dynamic_type)
6618 CheckDynamicTypeHandler Handler{AK};
6641 unsigned PathLength) {
6642 assert(PathLength >=
Designator.MostDerivedPathLength && PathLength <=
6643 Designator.Entries.size() &&
"invalid path length");
6644 return (PathLength ==
Designator.MostDerivedPathLength)
6645 ?
Designator.MostDerivedType->getAsCXXRecordDecl()
6646 : getAsBaseClass(
Designator.Entries[PathLength - 1]);
6659 return std::nullopt;
6661 if (
This.Designator.Invalid)
6662 return std::nullopt;
6668 This.Designator.MostDerivedType->getAsCXXRecordDecl();
6669 if (!Class || (!Info.getLangOpts().CPlusPlus26 && Class->getNumVBases())) {
6671 return std::nullopt;
6679 for (
unsigned PathLength =
This.Designator.MostDerivedPathLength;
6680 PathLength <= Path.size(); ++PathLength) {
6681 switch (Info.isEvaluatingCtorDtor(
This.getLValueBase(),
6682 Path.slice(0, PathLength))) {
6683 case ConstructionPhase::Bases:
6684 case ConstructionPhase::DestroyingBases:
6689 case ConstructionPhase::None:
6690 case ConstructionPhase::AfterBases:
6691 case ConstructionPhase::AfterFields:
6692 case ConstructionPhase::Destroying:
6704 return std::nullopt;
6722 unsigned PathLength = DynType->PathLength;
6723 for (; PathLength <=
This.Designator.Entries.size(); ++PathLength) {
6726 Found->getCorrespondingMethodDeclaredInClass(Class,
false);
6736 if (Callee->isPureVirtual()) {
6737 Info.FFDiag(E, diag::note_constexpr_pure_virtual_call, 1) << Callee;
6738 Info.Note(Callee->getLocation(), diag::note_declared_at);
6744 if (!Info.Ctx.hasSameUnqualifiedType(Callee->getReturnType(),
6745 Found->getReturnType())) {
6746 CovariantAdjustmentPath.push_back(Callee->getReturnType());
6747 for (
unsigned CovariantPathLength = PathLength + 1;
6748 CovariantPathLength !=
This.Designator.Entries.size();
6749 ++CovariantPathLength) {
6753 Found->getCorrespondingMethodDeclaredInClass(NextClass,
false);
6754 if (
Next && !Info.Ctx.hasSameUnqualifiedType(
6755 Next->getReturnType(), CovariantAdjustmentPath.back()))
6756 CovariantAdjustmentPath.push_back(
Next->getReturnType());
6758 if (!Info.Ctx.hasSameUnqualifiedType(
Found->getReturnType(),
6759 CovariantAdjustmentPath.back()))
6760 CovariantAdjustmentPath.push_back(
Found->getReturnType());
6776 assert(
Result.isLValue() &&
6777 "unexpected kind of APValue for covariant return");
6778 if (
Result.isNullPointer())
6782 LVal.setFrom(Info.Ctx,
Result);
6784 const CXXRecordDecl *OldClass = Path[0]->getPointeeCXXRecordDecl();
6785 for (
unsigned I = 1; I != Path.size(); ++I) {
6786 const CXXRecordDecl *NewClass = Path[I]->getPointeeCXXRecordDecl();
6787 assert(OldClass && NewClass &&
"unexpected kind of covariant return");
6788 if (OldClass != NewClass &&
6791 OldClass = NewClass;
6803 if (BaseSpec.isVirtual())
6805 auto *BaseClass = BaseSpec.getType()->getAsCXXRecordDecl();
6807 return BaseSpec.getAccessSpecifier() ==
AS_public;
6810 auto *BaseClass = BaseSpec.getType()->getAsCXXRecordDecl();
6812 return BaseSpec.getAccessSpecifier() ==
AS_public;
6815 llvm_unreachable(
"Base is not a direct base of Derived");
6825 SubobjectDesignator &D = Ptr.Designator;
6831 if (Ptr.isNullPointer() && !E->
isGLValue())
6837 std::optional<DynamicType> DynType =
6849 assert(
C &&
"dynamic_cast target is not void pointer nor class");
6857 Ptr.setNull(Info.Ctx, E->
getType());
6864 DynType->Type->isDerivedFrom(
C)))
6866 else if (!Paths || Paths->begin() == Paths->end())
6868 else if (Paths->isAmbiguous(CQT))
6871 assert(Paths->front().Access !=
AS_public &&
"why did the cast fail?");
6874 Info.FFDiag(E, diag::note_constexpr_dynamic_cast_to_reference_failed)
6875 << DiagKind << Ptr.Designator.getType(Info.Ctx)
6876 << Info.Ctx.getCanonicalTagType(DynType->Type)
6884 for (
int PathLength = Ptr.Designator.Entries.size();
6885 PathLength >= (
int)DynType->PathLength; --PathLength) {
6890 if (PathLength > (
int)DynType->PathLength &&
6893 return RuntimeCheckFailed(
nullptr);
6900 if (DynType->Type->isDerivedFrom(
C, Paths) && !Paths.
isAmbiguous(CQT) &&
6913 return RuntimeCheckFailed(&Paths);
6917struct StartLifetimeOfUnionMemberHandler {
6919 const Expr *LHSExpr;
6920 const FieldDecl *
Field;
6922 bool Failed =
false;
6925 typedef bool result_type;
6926 bool failed() {
return Failed; }
6927 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
6942 }
else if (DuringInit) {
6946 Info.FFDiag(LHSExpr,
6947 diag::note_constexpr_union_member_change_during_init);
6956 llvm_unreachable(
"wrong value kind for union object");
6958 bool found(APFloat &
Value, QualType SubobjType) {
6959 llvm_unreachable(
"wrong value kind for union object");
6964const AccessKinds StartLifetimeOfUnionMemberHandler::AccessKind;
6971 const Expr *LHSExpr,
6972 const LValue &LHS) {
6973 if (LHS.InvalidBase || LHS.Designator.Invalid)
6979 unsigned PathLength = LHS.Designator.Entries.size();
6980 for (
const Expr *E = LHSExpr; E !=
nullptr;) {
6982 if (
auto *ME = dyn_cast<MemberExpr>(E)) {
6983 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
6986 if (!FD || FD->getType()->isReferenceType())
6990 if (FD->getParent()->isUnion()) {
6995 FD->getType()->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
6996 if (!RD || RD->hasTrivialDefaultConstructor())
6997 UnionPathLengths.push_back({PathLength - 1, FD});
7003 LHS.Designator.Entries[PathLength]
7004 .getAsBaseOrMember().getPointer()));
7008 }
else if (
auto *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
7010 auto *
Base = ASE->getBase()->IgnoreImplicit();
7011 if (!
Base->getType()->isArrayType())
7017 }
else if (
auto *ICE = dyn_cast<ImplicitCastExpr>(E)) {
7020 if (ICE->getCastKind() == CK_NoOp)
7022 if (ICE->getCastKind() != CK_DerivedToBase &&
7023 ICE->getCastKind() != CK_UncheckedDerivedToBase)
7027 if (Elt->isVirtual()) {
7036 LHS.Designator.Entries[PathLength]
7037 .getAsBaseOrMember().getPointer()));
7047 if (UnionPathLengths.empty())
7052 CompleteObject Obj =
7056 for (std::pair<unsigned, const FieldDecl *> LengthAndField :
7057 llvm::reverse(UnionPathLengths)) {
7059 SubobjectDesignator D = LHS.Designator;
7060 D.truncate(Info.Ctx, LHS.Base, LengthAndField.first);
7062 bool DuringInit = Info.isEvaluatingCtorDtor(LHS.Base, D.Entries) ==
7063 ConstructionPhase::AfterBases;
7064 StartLifetimeOfUnionMemberHandler StartLifetime{
7065 Info, LHSExpr, LengthAndField.second, DuringInit};
7074 CallRef
Call, EvalInfo &Info,
bool NonNull =
false,
7075 APValue **EvaluatedArg =
nullptr) {
7082 APValue &
V = PVD ? Info.CurrentCall->createParam(
Call, PVD, LV)
7083 : Info.CurrentCall->createTemporary(Arg, Arg->
getType(),
7084 ScopeKind::Call, LV);
7090 if (
NonNull &&
V.isLValue() &&
V.isNullPointer()) {
7091 Info.CCEDiag(Arg, diag::note_non_null_attribute_failed);
7104 bool RightToLeft =
false,
7105 LValue *ObjectArg =
nullptr) {
7107 llvm::SmallBitVector ForbiddenNullArgs;
7108 if (Callee->hasAttr<NonNullAttr>()) {
7109 ForbiddenNullArgs.resize(Args.size());
7110 for (
const auto *
Attr : Callee->specific_attrs<NonNullAttr>()) {
7111 if (!
Attr->args_size()) {
7112 ForbiddenNullArgs.set();
7115 for (
auto Idx :
Attr->args()) {
7116 unsigned ASTIdx = Idx.getASTIndex();
7117 if (ASTIdx >= Args.size())
7119 ForbiddenNullArgs[ASTIdx] =
true;
7123 for (
unsigned I = 0; I < Args.size(); I++) {
7124 unsigned Idx = RightToLeft ? Args.size() - I - 1 : I;
7126 Idx < Callee->getNumParams() ? Callee->getParamDecl(Idx) :
nullptr;
7127 bool NonNull = !ForbiddenNullArgs.empty() && ForbiddenNullArgs[Idx];
7132 if (!Info.noteFailure())
7137 ObjectArg->setFrom(Info.Ctx, *That);
7146 bool CopyObjectRepresentation) {
7148 CallStackFrame *Frame = Info.CurrentCall;
7149 APValue *RefValue = Info.getParamSlot(Frame->Arguments, Param);
7157 RefLValue.setFrom(Info.Ctx, *RefValue);
7160 CopyObjectRepresentation);
7166 const LValue *ObjectArg,
const Expr *E,
7168 const Stmt *Body, EvalInfo &Info,
7170 if (!Info.CheckCallLimit(CallLoc))
7183 auto IsTrivialMemoryOperation = [&](
const CXXMethodDecl *MD) {
7193 if (IsTrivialMemoryOperation(MD)) {
7206 ObjectArg->moveInto(
Result);
7215 if (!Info.checkingPotentialConstantExpression())
7217 Frame.LambdaThisCaptureField);
7220 StmtResult Ret = {
Result, ResultSlot};
7222 if (ESR == ESR_Succeeded) {
7223 if (Callee->getReturnType()->isVoidType())
7225 Info.FFDiag(Callee->getEndLoc(), diag::note_constexpr_no_return);
7227 return ESR == ESR_Returned;
7234 bool IsCompleteClass =
true);
7240 bool IsCompleteClass =
true) {
7241 CallScopeRAII CallScope(Info);
7248 CallScope.destroy();
7256 bool IsCompleteClass) {
7259 if (!Info.CheckCallLimit(CallLoc))
7263 if (!Info.getLangOpts().CPlusPlus26 && RD->
getNumVBases()) {
7264 Info.FFDiag(CallLoc, diag::note_constexpr_virtual_base) << RD;
7268 EvalInfo::EvaluatingConstructorRAII EvalObj(
7270 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries},
7277 StmtResult Ret = {RetVal,
nullptr};
7282 if ((*I)->getInit()->isValueDependent()) {
7286 FullExpressionRAII InitScope(Info);
7288 !InitScope.destroy())
7311 if (!
Result.hasValue()) {
7313 unsigned NonVirtualBases = countNonVirtualBases(RD);
7325 BlockScopeRAII LifetimeExtendedScope(Info);
7328 unsigned BasesSeen = 0;
7329 unsigned VirtualBasesSeen = 0;
7330 unsigned NonVirtualBases = countNonVirtualBases(RD);
7333 auto SkipToField = [&](
FieldDecl *FD,
bool Indirect) {
7338 assert(Indirect &&
"fields out of order?");
7344 assert(FieldIt != RD->
field_end() &&
"missing field?");
7345 if (!FieldIt->isUnnamedBitField())
7348 Result.getStructField(FieldIt->getFieldIndex()));
7353 LValue Subobject =
This;
7354 LValue SubobjectParent =
This;
7359 if (I->isBaseInitializer()) {
7360 QualType BaseType(I->getBaseClass(), 0);
7361 if (I->isBaseVirtual()) {
7362 if (
This.pointsToCompleteClass(RD)) {
7364 BaseType->getAsCXXRecordDecl(),
7367 Value = &
Result.getStructVirtualBase(VirtualBasesSeen++);
7374 BaseType->getAsCXXRecordDecl(), &Layout))
7378 }
else if ((FD = I->getMember())) {
7385 SkipToField(FD,
false);
7391 auto IndirectFieldChain = IFD->chain();
7392 for (
auto *
C : IndirectFieldChain) {
7401 (
Value->isUnion() &&
7414 if (
C == IndirectFieldChain.back())
7415 SubobjectParent = Subobject;
7421 if (
C == IndirectFieldChain.front() && !RD->
isUnion())
7422 SkipToField(FD,
true);
7427 llvm_unreachable(
"unknown base initializer kind");
7434 if (
Init->isValueDependent()) {
7438 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &SubobjectParent,
7440 FullExpressionRAII InitScope(Info);
7446 if (!Info.noteFailure())
7455 if (!Info.noteFailure())
7463 if (I->isBaseInitializer() && BasesSeen == NonVirtualBases)
7464 EvalObj.finishedConstructingBases();
7469 for (; FieldIt != RD->
field_end(); ++FieldIt) {
7470 if (!FieldIt->isUnnamedBitField())
7473 Result.getStructField(FieldIt->getFieldIndex()));
7477 EvalObj.finishedConstructingFields();
7481 LifetimeExtendedScope.destroy();
7486 QualType T,
bool IsCompleteClass =
true) {
7491 if (
Value.isAbsent() && !
T->isNullPtrType()) {
7493 This.moveInto(Printable);
7495 diag::note_constexpr_destroy_out_of_lifetime)
7496 << Printable.
getAsString(Info.Ctx, Info.Ctx.getLValueReferenceType(
T));
7512 LValue ElemLV =
This;
7513 ElemLV.addArray(Info, &LocE, CAT);
7520 if (Size && Size >
Value.getArrayInitializedElts())
7525 for (Size =
Value.getArraySize(); Size != 0; --Size) {
7526 APValue &Elem =
Value.getArrayInitializedElt(Size - 1);
7539 if (
T.isDestructedType()) {
7541 diag::note_constexpr_unsupported_destruction)
7550 if (!Info.getLangOpts().CPlusPlus26 && RD->
getNumVBases()) {
7551 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_virtual_base) << RD;
7579 if (!Info.CheckCallLimit(CallRange.
getBegin()))
7588 CallStackFrame Frame(Info, CallRange,
Definition, &
This,
nullptr,
7592 EvalInfo::EvaluatingDestructorRAII EvalObj(
7594 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries});
7595 unsigned NonVirtualBases = countNonVirtualBases(RD);
7597 unsigned BasesLeft = NonVirtualBases;
7598 if (!EvalObj.DidInsert) {
7605 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_double_destroy);
7612 StmtResult Ret = {RetVal,
nullptr};
7627 for (
const FieldDecl *FD : llvm::reverse(Fields)) {
7628 if (FD->isUnnamedBitField())
7631 LValue Subobject =
This;
7635 APValue *SubobjectValue = &
Value.getStructField(FD->getFieldIndex());
7641 if (BasesLeft != 0 || NumVirtualBases != 0)
7642 EvalObj.startedDestroyingBases();
7646 if (
Base.isVirtual())
7651 LValue Subobject =
This;
7653 BaseType->getAsCXXRecordDecl(), &Layout))
7656 APValue *SubobjectValue = &
Value.getStructBase(BasesLeft);
7661 assert(BasesLeft == 0 &&
"NumBases was wrong?");
7664 if (IsCompleteClass) {
7665 unsigned VirtualBasesLeft = NumVirtualBases;
7670 LValue Subobject =
This;
7672 BaseType->getAsCXXRecordDecl(),
7676 APValue *SubobjectValue = &
Value.getStructVirtualBase(VirtualBasesLeft);
7681 assert(VirtualBasesLeft == 0 &&
"NumVirtualBases was wrong?");
7690struct DestroyObjectHandler {
7696 typedef bool result_type;
7697 bool failed() {
return false; }
7698 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
7703 Info.FFDiag(E, diag::note_constexpr_destroy_complex_elem);
7706 bool found(APFloat &
Value, QualType SubobjType) {
7707 Info.FFDiag(E, diag::note_constexpr_destroy_complex_elem);
7728 if (Info.EvalStatus.HasSideEffects)
7739 if (Info.checkingPotentialConstantExpression() ||
7740 Info.SpeculativeEvaluationDepth)
7744 auto Caller = Info.getStdAllocatorCaller(
"allocate");
7746 Info.FFDiag(E->
getExprLoc(), Info.getLangOpts().CPlusPlus20
7747 ? diag::note_constexpr_new_untyped
7748 : diag::note_constexpr_new);
7752 QualType ElemType = Caller.ElemType;
7755 diag::note_constexpr_new_not_complete_object_type)
7763 bool IsNothrow =
false;
7764 for (
unsigned I = 1, N = E->
getNumArgs(); I != N; ++I) {
7772 APInt Size, Remainder;
7773 APInt ElemSizeAP(ByteSize.getBitWidth(), ElemSize.
getQuantity());
7774 APInt::udivrem(ByteSize, ElemSizeAP, Size, Remainder);
7775 if (Remainder != 0) {
7777 Info.FFDiag(E->
getExprLoc(), diag::note_constexpr_operator_new_bad_size)
7778 << ByteSize <<
APSInt(ElemSizeAP,
true) << ElemType;
7782 if (!Info.CheckArraySize(E->
getBeginLoc(), ByteSize.getActiveBits(),
7783 Size.getZExtValue(), !IsNothrow)) {
7791 QualType AllocType = Info.Ctx.getConstantArrayType(
7793 APValue *Val = Info.createHeapAlloc(Caller.Call, AllocType,
Result);
7802 return DD->isVirtual();
7809 return DD->isVirtual() ? DD->getOperatorDelete() :
nullptr;
7820 DynAlloc::Kind DeallocKind) {
7821 auto PointerAsString = [&] {
7822 return Pointer.toString(Info.Ctx, Info.Ctx.VoidPtrTy);
7827 Info.FFDiag(E, diag::note_constexpr_delete_not_heap_alloc)
7828 << PointerAsString();
7831 return std::nullopt;
7834 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
7836 Info.FFDiag(E, diag::note_constexpr_double_delete);
7837 return std::nullopt;
7840 if (DeallocKind != (*Alloc)->getKind()) {
7842 Info.FFDiag(E, diag::note_constexpr_new_delete_mismatch)
7843 << DeallocKind << (*Alloc)->getKind() << AllocType;
7845 return std::nullopt;
7848 bool Subobject =
false;
7849 if (DeallocKind == DynAlloc::New) {
7850 Subobject =
Pointer.Designator.MostDerivedPathLength != 0 ||
7851 Pointer.Designator.isOnePastTheEnd();
7853 Subobject =
Pointer.Designator.Entries.size() != 1 ||
7854 Pointer.Designator.Entries[0].getAsArrayIndex() != 0;
7857 Info.FFDiag(E, diag::note_constexpr_delete_subobject)
7858 << PointerAsString() <<
Pointer.Designator.isOnePastTheEnd();
7859 return std::nullopt;
7867 if (Info.checkingPotentialConstantExpression() ||
7868 Info.SpeculativeEvaluationDepth)
7872 if (!Info.getStdAllocatorCaller(
"deallocate")) {
7880 for (
unsigned I = 1, N = E->
getNumArgs(); I != N; ++I)
7883 if (
Pointer.Designator.Invalid)
7888 if (
Pointer.isNullPointer()) {
7889 Info.CCEDiag(E->
getExprLoc(), diag::note_constexpr_deallocate_null);
7905class BitCastBuffer {
7911 SmallVector<std::optional<unsigned char>, 32> Bytes;
7913 static_assert(std::numeric_limits<unsigned char>::digits >= 8,
7914 "Need at least 8 bit unsigned char");
7916 bool TargetIsLittleEndian;
7919 BitCastBuffer(CharUnits Width,
bool TargetIsLittleEndian)
7920 : Bytes(Width.getQuantity()),
7921 TargetIsLittleEndian(TargetIsLittleEndian) {}
7923 [[nodiscard]]
bool readObject(CharUnits Offset, CharUnits Width,
7924 SmallVectorImpl<unsigned char> &Output)
const {
7925 for (CharUnits I = Offset, E = Offset + Width; I != E; ++I) {
7928 if (!Bytes[I.getQuantity()])
7930 Output.push_back(*Bytes[I.getQuantity()]);
7932 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
7933 std::reverse(Output.begin(), Output.end());
7937 void writeObject(CharUnits Offset, SmallVectorImpl<unsigned char> &Input) {
7938 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
7939 std::reverse(Input.begin(), Input.end());
7942 for (
unsigned char Byte : Input) {
7943 assert(!Bytes[Offset.
getQuantity() + Index] &&
"overwriting a byte?");
7949 size_t size() {
return Bytes.size(); }
7954class APValueToBufferConverter {
7956 BitCastBuffer Buffer;
7959 APValueToBufferConverter(EvalInfo &Info, CharUnits ObjectWidth,
7962 Buffer(ObjectWidth, Info.Ctx.getTargetInfo().isLittleEndian()),
7965 bool visit(
const APValue &Val, QualType Ty) {
7970 bool visit(
const APValue &Val, QualType Ty, CharUnits Offset) {
7971 assert((
size_t)Offset.
getQuantity() <= Buffer.size());
7984 return visitInt(Val.
getInt(), Ty, Offset);
7986 return visitFloat(Val.
getFloat(), Ty, Offset);
7988 return visitArray(Val, Ty, Offset);
7990 return visitRecord(Val, Ty, Offset);
7992 return visitVector(Val, Ty, Offset);
7996 return visitComplex(Val, Ty, Offset);
8006 diag::note_constexpr_bit_cast_unsupported_type)
8011 llvm_unreachable(
"Unhandled APValue::ValueKind");
8014 bool visitRecord(
const APValue &Val, QualType Ty, CharUnits Offset) {
8018 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD);
8021 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
8022 for (
size_t I = 0, E = CXXRD->getNumBases(); I != E; ++I) {
8023 const CXXBaseSpecifier &BS = CXXRD->bases_begin()[I];
8028 if (!
Base.isStruct())
8031 if (!visitRecord(Base, BS.
getType(),
8038 unsigned FieldIdx = 0;
8039 for (FieldDecl *FD : RD->
fields()) {
8040 if (FD->isBitField()) {
8042 diag::note_constexpr_bit_cast_unsupported_bitfield);
8048 assert(FieldOffsetBits % Info.Ctx.getCharWidth() == 0 &&
8049 "only bit-fields can have sub-char alignment");
8050 CharUnits FieldOffset =
8051 Info.Ctx.toCharUnitsFromBits(FieldOffsetBits) + Offset;
8052 QualType FieldTy = FD->getType();
8061 bool visitArray(
const APValue &Val, QualType Ty, CharUnits Offset) {
8067 CharUnits ElemWidth = Info.Ctx.getTypeSizeInChars(CAT->
getElementType());
8071 for (
unsigned I = 0; I != NumInitializedElts; ++I) {
8073 if (!visit(SubObj, CAT->
getElementType(), Offset + I * ElemWidth))
8080 for (
unsigned I = NumInitializedElts; I != ArraySize; ++I) {
8081 if (!visit(Filler, CAT->
getElementType(), Offset + I * ElemWidth))
8089 bool visitComplex(
const APValue &Val, QualType Ty, CharUnits Offset) {
8090 const ComplexType *ComplexTy = Ty->
castAs<ComplexType>();
8092 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
8097 Offset + (0 * EltSizeChars)))
8100 Offset + (1 * EltSizeChars)))
8104 Offset + (0 * EltSizeChars)))
8107 Offset + (1 * EltSizeChars)))
8114 bool visitVector(
const APValue &Val, QualType Ty, CharUnits Offset) {
8115 const VectorType *VTy = Ty->
castAs<VectorType>();
8128 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
8130 llvm::APInt Res = llvm::APInt::getZero(NElts);
8131 for (
unsigned I = 0; I < NElts; ++I) {
8133 assert(EltAsInt.isUnsigned() && EltAsInt.getBitWidth() == 1 &&
8134 "bool vector element must be 1-bit unsigned integer!");
8136 Res.insertBits(EltAsInt, BigEndian ? (NElts - I - 1) : I);
8139 SmallVector<uint8_t, 8> Bytes(NElts / 8);
8140 llvm::StoreIntToMemory(Res, &*Bytes.begin(), NElts / 8);
8141 Buffer.writeObject(Offset, Bytes);
8145 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
8146 for (
unsigned I = 0; I < NElts; ++I) {
8147 if (!visit(Val.
getVectorElt(I), EltTy, Offset + I * EltSizeChars))
8155 bool visitInt(
const APSInt &Val, QualType Ty, CharUnits Offset) {
8156 APSInt AdjustedVal = Val;
8157 unsigned Width = AdjustedVal.getBitWidth();
8159 Width = Info.Ctx.getTypeSize(Ty);
8160 AdjustedVal = AdjustedVal.extend(Width);
8163 SmallVector<uint8_t, 8> Bytes(Width / 8);
8164 llvm::StoreIntToMemory(AdjustedVal, &*Bytes.begin(), Width / 8);
8165 Buffer.writeObject(Offset, Bytes);
8169 bool visitFloat(
const APFloat &Val, QualType Ty, CharUnits Offset) {
8170 APSInt AsInt(Val.bitcastToAPInt());
8171 return visitInt(AsInt, Ty, Offset);
8175 static std::optional<BitCastBuffer>
8177 CharUnits DstSize = Info.Ctx.getTypeSizeInChars(BCE->
getType());
8178 APValueToBufferConverter Converter(Info, DstSize, BCE);
8180 return std::nullopt;
8181 return Converter.Buffer;
8186class BufferToAPValueConverter {
8188 const BitCastBuffer &Buffer;
8191 BufferToAPValueConverter(EvalInfo &Info,
const BitCastBuffer &Buffer,
8193 : Info(Info), Buffer(Buffer), BCE(BCE) {}
8198 std::nullopt_t unsupportedType(QualType Ty) {
8200 diag::note_constexpr_bit_cast_unsupported_type)
8202 return std::nullopt;
8205 std::nullopt_t unrepresentableValue(QualType Ty,
const APSInt &Val) {
8207 diag::note_constexpr_bit_cast_unrepresentable_value)
8209 return std::nullopt;
8212 std::optional<APValue> visit(
const BuiltinType *
T, CharUnits Offset,
8213 const EnumType *EnumSugar =
nullptr) {
8215 uint64_t NullValue = Info.Ctx.getTargetNullPointerValue(QualType(
T, 0));
8216 return APValue((Expr *)
nullptr,
8218 APValue::NoLValuePath{},
true);
8221 CharUnits
SizeOf = Info.Ctx.getTypeSizeInChars(
T);
8227 const llvm::fltSemantics &Semantics =
8228 Info.Ctx.getFloatTypeSemantics(QualType(
T, 0));
8229 unsigned NumBits = llvm::APFloatBase::getSizeInBits(Semantics);
8230 assert(NumBits % 8 == 0);
8236 SmallVector<uint8_t, 8> Bytes;
8237 if (!Buffer.readObject(Offset,
SizeOf, Bytes)) {
8240 bool IsStdByte = EnumSugar && EnumSugar->isStdByteType();
8244 if (!IsStdByte && !IsUChar) {
8245 QualType DisplayType(EnumSugar ? (
const Type *)EnumSugar :
T, 0);
8247 diag::note_constexpr_bit_cast_indet_dest)
8248 << DisplayType << Info.Ctx.getLangOpts().CharIsSigned;
8249 return std::nullopt;
8255 APSInt Val(
SizeOf.getQuantity() * Info.Ctx.getCharWidth(),
true);
8256 llvm::LoadIntFromMemory(Val, &*Bytes.begin(), Bytes.size());
8261 unsigned IntWidth = Info.Ctx.getIntWidth(QualType(
T, 0));
8262 if (IntWidth != Val.getBitWidth()) {
8263 APSInt Truncated = Val.trunc(IntWidth);
8264 if (Truncated.extend(Val.getBitWidth()) != Val)
8265 return unrepresentableValue(QualType(
T, 0), Val);
8273 const llvm::fltSemantics &Semantics =
8274 Info.Ctx.getFloatTypeSemantics(QualType(
T, 0));
8278 return unsupportedType(QualType(
T, 0));
8281 std::optional<APValue> visit(
const RecordType *RTy, CharUnits Offset) {
8282 const RecordDecl *RD = RTy->getAsRecordDecl();
8284 return std::nullopt;
8285 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD);
8287 unsigned NumBases = 0;
8288 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
8289 NumBases = CXXRD->getNumBases();
8294 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
8295 for (
size_t I = 0, E = CXXRD->getNumBases(); I != E; ++I) {
8296 const CXXBaseSpecifier &BS = CXXRD->bases_begin()[I];
8299 std::optional<APValue> SubObj = visitType(
8302 return std::nullopt;
8303 ResultVal.getStructBase(I) = *SubObj;
8308 unsigned FieldIdx = 0;
8309 for (FieldDecl *FD : RD->
fields()) {
8312 if (FD->isBitField()) {
8314 diag::note_constexpr_bit_cast_unsupported_bitfield);
8315 return std::nullopt;
8319 assert(FieldOffsetBits % Info.Ctx.getCharWidth() == 0);
8321 CharUnits FieldOffset =
8324 QualType FieldTy = FD->getType();
8325 std::optional<APValue> SubObj = visitType(FieldTy, FieldOffset);
8327 return std::nullopt;
8328 ResultVal.getStructField(FieldIdx) = *SubObj;
8335 std::optional<APValue> visit(
const EnumType *Ty, CharUnits Offset) {
8336 QualType RepresentationType =
8337 Ty->getDecl()->getDefinitionOrSelf()->getIntegerType();
8338 assert(!RepresentationType.
isNull() &&
8339 "enum forward decl should be caught by Sema");
8340 const auto *AsBuiltin =
8344 return visit(AsBuiltin, Offset, Ty);
8347 std::optional<APValue> visit(
const ConstantArrayType *Ty, CharUnits Offset) {
8349 CharUnits ElementWidth = Info.Ctx.getTypeSizeInChars(Ty->
getElementType());
8351 APValue ArrayValue(APValue::UninitArray(), Size, Size);
8352 for (
size_t I = 0; I !=
Size; ++I) {
8353 std::optional<APValue> ElementValue =
8356 return std::nullopt;
8357 ArrayValue.getArrayInitializedElt(I) = std::move(*ElementValue);
8363 std::optional<APValue> visit(
const ComplexType *Ty, CharUnits Offset) {
8365 CharUnits ElementWidth = Info.Ctx.getTypeSizeInChars(ElementType);
8366 bool IsInt = ElementType->isIntegerType();
8368 std::optional<APValue> Values[2];
8369 for (
unsigned I = 0; I != 2; ++I) {
8370 Values[I] = visitType(Ty->
getElementType(), Offset + I * ElementWidth);
8372 return std::nullopt;
8376 return APValue(Values[0]->getInt(), Values[1]->getInt());
8377 return APValue(Values[0]->getFloat(), Values[1]->getFloat());
8380 std::optional<APValue> visit(
const VectorType *VTy, CharUnits Offset) {
8386 SmallVector<APValue, 4> Elts;
8387 Elts.reserve(NElts);
8397 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
8399 SmallVector<uint8_t, 8> Bytes;
8400 Bytes.reserve(NElts / 8);
8402 return std::nullopt;
8404 APSInt SValInt(NElts,
true);
8405 llvm::LoadIntFromMemory(SValInt, &*Bytes.begin(), Bytes.size());
8407 for (
unsigned I = 0; I < NElts; ++I) {
8409 SValInt.extractBits(1, (BigEndian ? NElts - I - 1 : I) * EltSize);
8416 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
8417 for (
unsigned I = 0; I < NElts; ++I) {
8418 std::optional<APValue> EltValue =
8419 visitType(EltTy, Offset + I * EltSizeChars);
8421 return std::nullopt;
8422 Elts.push_back(std::move(*EltValue));
8426 return APValue(Elts.data(), Elts.size());
8429 std::optional<APValue> visit(
const Type *Ty, CharUnits Offset) {
8430 return unsupportedType(QualType(Ty, 0));
8433 std::optional<APValue> visitType(QualType Ty, CharUnits Offset) {
8437#define TYPE(Class, Base) \
8439 return visit(cast<Class##Type>(Can.getTypePtr()), Offset);
8440#define ABSTRACT_TYPE(Class, Base)
8441#define NON_CANONICAL_TYPE(Class, Base) \
8443 llvm_unreachable("non-canonical type should be impossible!");
8444#define DEPENDENT_TYPE(Class, Base) \
8447 "dependent types aren't supported in the constant evaluator!");
8448#define NON_CANONICAL_UNLESS_DEPENDENT(Class, Base) \
8450 llvm_unreachable("either dependent or not canonical!");
8451#include "clang/AST/TypeNodes.inc"
8453 llvm_unreachable(
"Unhandled Type::TypeClass");
8458 static std::optional<APValue> convert(EvalInfo &Info, BitCastBuffer &Buffer,
8460 BufferToAPValueConverter Converter(Info, Buffer, BCE);
8465static bool checkBitCastConstexprEligibilityType(SourceLocation Loc,
8466 QualType Ty, EvalInfo *Info,
8467 const ASTContext &Ctx,
8468 bool CheckingDest) {
8471 auto diag = [&](
int Reason) {
8473 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_invalid_type)
8474 << CheckingDest << (Reason == 4) << Reason;
8477 auto note = [&](
int Construct, QualType NoteTy, SourceLocation NoteLoc) {
8479 Info->Note(NoteLoc, diag::note_constexpr_bit_cast_invalid_subtype)
8480 << NoteTy << Construct << Ty;
8494 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(
Record)) {
8495 for (CXXBaseSpecifier &BS : CXXRD->bases())
8496 if (!checkBitCastConstexprEligibilityType(Loc, BS.
getType(), Info, Ctx,
8500 for (FieldDecl *FD :
Record->fields()) {
8501 if (FD->getType()->isReferenceType())
8503 if (!checkBitCastConstexprEligibilityType(Loc, FD->getType(), Info, Ctx,
8505 return note(0, FD->getType(), FD->getBeginLoc());
8511 Info, Ctx, CheckingDest))
8514 if (
const auto *VTy = Ty->
getAs<VectorType>()) {
8526 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_invalid_vector)
8527 << QualType(VTy, 0) << EltSize << NElts << Ctx.
getCharWidth();
8537 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_unsupported_type)
8546static bool checkBitCastConstexprEligibility(EvalInfo *Info,
8547 const ASTContext &Ctx,
8549 bool DestOK = checkBitCastConstexprEligibilityType(
8551 bool SourceOK = DestOK && checkBitCastConstexprEligibilityType(
8557static bool handleRValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
8560 assert(
CHAR_BIT == 8 && Info.Ctx.getTargetInfo().getCharWidth() == 8 &&
8561 "no host or target supports non 8-bit chars");
8563 if (!checkBitCastConstexprEligibility(&Info, Info.Ctx, BCE))
8567 std::optional<BitCastBuffer> Buffer =
8568 APValueToBufferConverter::convert(Info, SourceRValue, BCE);
8573 std::optional<APValue> MaybeDestValue =
8574 BufferToAPValueConverter::convert(Info, *Buffer, BCE);
8575 if (!MaybeDestValue)
8578 DestValue = std::move(*MaybeDestValue);
8582static bool handleLValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
8585 assert(
CHAR_BIT == 8 && Info.Ctx.getTargetInfo().getCharWidth() == 8 &&
8586 "no host or target supports non 8-bit chars");
8588 "LValueToRValueBitcast requires an lvalue operand!");
8590 LValue SourceLValue;
8592 SourceLValue.setFrom(Info.Ctx, SourceValue);
8595 SourceRValue,
true))
8598 return handleRValueToRValueBitCast(Info, DestValue, SourceRValue, BCE);
8601template <
class Derived>
8602class ExprEvaluatorBase
8603 :
public ConstStmtVisitor<Derived, bool> {
8605 Derived &getDerived() {
return static_cast<Derived&
>(*this); }
8606 bool DerivedSuccess(
const APValue &
V,
const Expr *E) {
8607 return getDerived().Success(
V, E);
8609 bool DerivedZeroInitialization(
const Expr *E) {
8610 return getDerived().ZeroInitialization(E);
8616 template<
typename ConditionalOperator>
8617 void CheckPotentialConstantConditional(
const ConditionalOperator *E) {
8618 assert(Info.checkingPotentialConstantExpression());
8621 SmallVector<PartialDiagnosticAt, 8>
Diag;
8623 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
8630 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
8632 Info.EvalStatus.DiagEmitted =
false;
8638 Error(E, diag::note_constexpr_conditional_never_const);
8642 template<
typename ConditionalOperator>
8643 bool HandleConditionalOperator(
const ConditionalOperator *E) {
8646 if (Info.checkingPotentialConstantExpression() && Info.noteFailure()) {
8647 CheckPotentialConstantConditional(E);
8650 if (Info.noteFailure()) {
8658 return StmtVisitorTy::Visit(EvalExpr);
8663 typedef ConstStmtVisitor<Derived, bool> StmtVisitorTy;
8664 typedef ExprEvaluatorBase ExprEvaluatorBaseTy;
8666 OptionalDiagnostic CCEDiag(
const Expr *E,
diag::kind D) {
8667 return Info.CCEDiag(E, D);
8670 bool ZeroInitialization(
const Expr *E) {
return Error(E); }
8672 bool IsConstantEvaluatedBuiltinCall(
const CallExpr *E) {
8674 return BuiltinOp != 0 &&
8675 Info.Ctx.BuiltinInfo.isConstantEvaluated(BuiltinOp);
8679 ExprEvaluatorBase(EvalInfo &Info) : Info(Info) {}
8681 EvalInfo &getEvalInfo() {
return Info; }
8689 bool Error(
const Expr *E) {
8690 return Error(E, diag::note_invalid_subexpr_in_const_expr);
8693 bool VisitStmt(
const Stmt *) {
8694 llvm_unreachable(
"Expression evaluator should not be called on stmts");
8696 bool VisitExpr(
const Expr *E) {
8700 bool VisitEmbedExpr(
const EmbedExpr *E) {
8701 const auto It = E->
begin();
8702 return StmtVisitorTy::Visit(*It);
8705 bool VisitPredefinedExpr(
const PredefinedExpr *E) {
8708 bool VisitConstantExpr(
const ConstantExpr *E) {
8712 return StmtVisitorTy::Visit(E->
getSubExpr());
8715 bool VisitParenExpr(
const ParenExpr *E)
8716 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8717 bool VisitUnaryExtension(
const UnaryOperator *E)
8718 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8719 bool VisitUnaryPlus(
const UnaryOperator *E)
8720 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8721 bool VisitChooseExpr(
const ChooseExpr *E)
8723 bool VisitGenericSelectionExpr(
const GenericSelectionExpr *E)
8725 bool VisitSubstNonTypeTemplateParmExpr(
const SubstNonTypeTemplateParmExpr *E)
8727 bool VisitCXXDefaultArgExpr(
const CXXDefaultArgExpr *E) {
8728 TempVersionRAII RAII(*Info.CurrentCall);
8729 SourceLocExprScopeGuard Guard(E, Info.CurrentCall->CurSourceLocExprScope);
8730 return StmtVisitorTy::Visit(E->
getExpr());
8732 bool VisitCXXDefaultInitExpr(
const CXXDefaultInitExpr *E) {
8733 TempVersionRAII RAII(*Info.CurrentCall);
8737 SourceLocExprScopeGuard Guard(E, Info.CurrentCall->CurSourceLocExprScope);
8738 return StmtVisitorTy::Visit(E->
getExpr());
8741 bool VisitExprWithCleanups(
const ExprWithCleanups *E) {
8742 FullExpressionRAII Scope(Info);
8743 return StmtVisitorTy::Visit(E->
getSubExpr()) && Scope.destroy();
8748 bool VisitCXXBindTemporaryExpr(
const CXXBindTemporaryExpr *E) {
8749 return StmtVisitorTy::Visit(E->
getSubExpr());
8752 bool VisitCXXReinterpretCastExpr(
const CXXReinterpretCastExpr *E) {
8754 CCEDiag(E, diag::note_constexpr_invalid_cast)
8755 << diag::ConstexprInvalidCastKind::Reinterpret;
8756 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8758 bool VisitCXXDynamicCastExpr(
const CXXDynamicCastExpr *E) {
8759 if (!Info.Ctx.getLangOpts().CPlusPlus20)
8760 CCEDiag(E, diag::note_constexpr_invalid_cast)
8761 << diag::ConstexprInvalidCastKind::Dynamic;
8762 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8764 bool VisitBuiltinBitCastExpr(
const BuiltinBitCastExpr *E) {
8765 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8768 bool VisitBinaryOperator(
const BinaryOperator *E) {
8774 VisitIgnoredValue(E->
getLHS());
8775 return StmtVisitorTy::Visit(E->
getRHS());
8785 return DerivedSuccess(
Result, E);
8790 bool VisitCXXRewrittenBinaryOperator(
const CXXRewrittenBinaryOperator *E) {
8794 bool VisitBinaryConditionalOperator(
const BinaryConditionalOperator *E) {
8798 if (!
Evaluate(Info.CurrentCall->createTemporary(
8801 ScopeKind::FullExpression, CommonLV),
8805 return HandleConditionalOperator(E);
8808 bool VisitConditionalOperator(
const ConditionalOperator *E) {
8809 bool IsBcpCall =
false;
8814 if (
const CallExpr *CallCE =
8816 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
8823 if (Info.checkingPotentialConstantExpression() && IsBcpCall)
8826 FoldConstant Fold(Info, IsBcpCall);
8827 if (!HandleConditionalOperator(E)) {
8828 Fold.keepDiagnostics();
8835 bool VisitOpaqueValueExpr(
const OpaqueValueExpr *E) {
8836 if (
APValue *
Value = Info.CurrentCall->getCurrentTemporary(E);
8838 return DerivedSuccess(*
Value, E);
8844 assert(0 &&
"OpaqueValueExpr recursively refers to itself");
8847 return StmtVisitorTy::Visit(Source);
8850 bool VisitPseudoObjectExpr(
const PseudoObjectExpr *E) {
8851 for (
const Expr *SemE : E->
semantics()) {
8852 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
8861 if (OVE->isUnique())
8865 if (!
Evaluate(Info.CurrentCall->createTemporary(
8866 OVE, getStorageType(Info.Ctx, OVE),
8867 ScopeKind::FullExpression, LV),
8868 Info, OVE->getSourceExpr()))
8871 if (!StmtVisitorTy::Visit(SemE))
8881 bool VisitCallExpr(
const CallExpr *E) {
8883 if (!handleCallExpr(E,
Result,
nullptr))
8885 return DerivedSuccess(
Result, E);
8889 const LValue *ResultSlot) {
8890 CallScopeRAII CallScope(Info);
8893 QualType CalleeType =
Callee->getType();
8895 const FunctionDecl *FD =
nullptr;
8896 LValue *
This =
nullptr, ObjectArg;
8898 bool HasQualifier =
false;
8904 const CXXMethodDecl *
Member =
nullptr;
8905 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(Callee)) {
8909 Member = dyn_cast<CXXMethodDecl>(ME->getMemberDecl());
8911 return Error(Callee);
8913 HasQualifier = ME->hasQualifier();
8914 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(Callee)) {
8916 const ValueDecl *D =
8920 Member = dyn_cast<CXXMethodDecl>(D);
8922 return Error(Callee);
8924 }
else if (
const auto *PDE = dyn_cast<CXXPseudoDestructorExpr>(Callee)) {
8925 if (!Info.getLangOpts().CPlusPlus20)
8926 Info.CCEDiag(PDE, diag::note_constexpr_pseudo_destructor);
8930 return Error(Callee);
8937 if (!CalleeLV.getLValueOffset().isZero())
8938 return Error(Callee);
8939 if (CalleeLV.isNullPointer()) {
8940 Info.FFDiag(Callee, diag::note_constexpr_null_callee)
8941 <<
const_cast<Expr *
>(
Callee);
8944 FD = dyn_cast_or_null<FunctionDecl>(
8945 CalleeLV.getLValueBase().dyn_cast<
const ValueDecl *>());
8947 return Error(Callee);
8950 if (!Info.Ctx.hasSameFunctionTypeIgnoringExceptionSpec(
8957 auto *OCE = dyn_cast<CXXOperatorCallExpr>(E);
8958 if (OCE && OCE->isAssignmentOp()) {
8959 assert(Args.size() == 2 &&
"wrong number of arguments in assignment");
8960 Call = Info.CurrentCall->createCall(FD);
8961 bool HasThis =
false;
8962 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FD))
8963 HasThis = MD->isImplicitObjectMemberFunction();
8971 const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD);
8991 if (Info.getLangOpts().CPlusPlus20 && OCE &&
8992 OCE->getOperator() == OO_Equal && MD->
isTrivial() &&
8996 Args = Args.slice(1);
9002 const CXXRecordDecl *ClosureClass = MD->
getParent();
9004 ClosureClass->
captures().empty() &&
9005 "Number of captures must be zero for conversion to function-ptr");
9007 const CXXMethodDecl *LambdaCallOp =
9016 "A generic lambda's static-invoker function must be a "
9017 "template specialization");
9019 FunctionTemplateDecl *CallOpTemplate =
9021 llvm::FoldingSetInsertToken InsertToken;
9022 FunctionDecl *CorrespondingCallOpSpecialization =
9024 assert(CorrespondingCallOpSpecialization &&
9025 "We must always have a function call operator specialization "
9026 "that corresponds to our static invoker specialization");
9028 FD = CorrespondingCallOpSpecialization;
9037 return CallScope.destroy();
9047 Call = Info.CurrentCall->createCall(FD);
9053 SmallVector<QualType, 4> CovariantAdjustmentPath;
9055 auto *NamedMember = dyn_cast<CXXMethodDecl>(FD);
9056 if (NamedMember && NamedMember->isVirtual() && !HasQualifier) {
9059 CovariantAdjustmentPath);
9062 }
else if (NamedMember && NamedMember->isImplicitObjectMemberFunction()) {
9072 if (
auto *DD = dyn_cast<CXXDestructorDecl>(FD)) {
9073 assert(This &&
"no 'this' pointer for destructor call");
9075 Info.Ctx.getCanonicalTagType(DD->getParent())) &&
9076 CallScope.destroy();
9093 if (!CovariantAdjustmentPath.empty() &&
9095 CovariantAdjustmentPath))
9098 return CallScope.destroy();
9101 bool VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E) {
9104 bool VisitInitListExpr(
const InitListExpr *E) {
9106 return DerivedZeroInitialization(E);
9108 return StmtVisitorTy::Visit(E->
getInit(0));
9111 bool VisitImplicitValueInitExpr(
const ImplicitValueInitExpr *E) {
9112 return DerivedZeroInitialization(E);
9114 bool VisitCXXScalarValueInitExpr(
const CXXScalarValueInitExpr *E) {
9115 return DerivedZeroInitialization(E);
9117 bool VisitCXXNullPtrLiteralExpr(
const CXXNullPtrLiteralExpr *E) {
9118 return DerivedZeroInitialization(E);
9122 bool VisitMemberExpr(
const MemberExpr *E) {
9123 assert(!Info.Ctx.getLangOpts().CPlusPlus11 &&
9124 "missing temporary materialization conversion");
9125 assert(!E->
isArrow() &&
"missing call to bound member function?");
9133 const FieldDecl *FD = dyn_cast<FieldDecl>(E->
getMemberDecl());
9134 if (!FD)
return Error(E);
9138 "record / field mismatch");
9143 CompleteObject Obj(APValue::LValueBase(), &Val, BaseTy);
9144 SubobjectDesignator Designator(BaseTy);
9145 Designator.addDeclUnchecked(FD);
9149 DerivedSuccess(
Result, E);
9152 bool VisitExtVectorElementExpr(
const ExtVectorElementExpr *E) {
9158 SmallVector<uint32_t, 4> Indices;
9160 if (Indices.size() == 1) {
9162 return DerivedSuccess(Val.
getVectorElt(Indices[0]), E);
9165 SmallVector<APValue, 4> Elts;
9166 for (
unsigned I = 0; I < Indices.size(); ++I) {
9169 APValue VecResult(Elts.data(), Indices.size());
9170 return DerivedSuccess(VecResult, E);
9177 bool VisitCastExpr(
const CastExpr *E) {
9182 case CK_AtomicToNonAtomic: {
9189 return DerivedSuccess(AtomicVal, E);
9193 case CK_UserDefinedConversion:
9194 return StmtVisitorTy::Visit(E->
getSubExpr());
9196 case CK_HLSLArrayRValue: {
9202 return DerivedSuccess(Val, E);
9213 return DerivedSuccess(RVal, E);
9215 case CK_LValueToRValue: {
9224 return DerivedSuccess(RVal, E);
9226 case CK_LValueToRValueBitCast: {
9227 APValue DestValue, SourceValue;
9230 if (!handleLValueToRValueBitCast(Info, DestValue, SourceValue, E))
9232 return DerivedSuccess(DestValue, E);
9235 case CK_AddressSpaceConversion: {
9239 return DerivedSuccess(
Value, E);
9246 bool VisitUnaryPostInc(
const UnaryOperator *UO) {
9247 return VisitUnaryPostIncDec(UO);
9249 bool VisitUnaryPostDec(
const UnaryOperator *UO) {
9250 return VisitUnaryPostIncDec(UO);
9252 bool VisitUnaryPostIncDec(
const UnaryOperator *UO) {
9253 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9263 return DerivedSuccess(RVal, UO);
9266 bool VisitStmtExpr(
const StmtExpr *E) {
9269 llvm::SaveAndRestore NotCheckingForUB(Info.CheckingForUndefinedBehavior,
9276 BlockScopeRAII Scope(Info);
9281 const Expr *FinalExpr = dyn_cast<Expr>(*BI);
9283 Info.FFDiag((*BI)->getBeginLoc(),
9284 diag::note_constexpr_stmt_expr_unsupported);
9287 return this->Visit(FinalExpr) && Scope.destroy();
9293 if (ESR != ESR_Succeeded) {
9297 if (ESR != ESR_Failed)
9298 Info.FFDiag((*BI)->getBeginLoc(),
9299 diag::note_constexpr_stmt_expr_unsupported);
9304 llvm_unreachable(
"Return from function from the loop above.");
9307 bool VisitPackIndexingExpr(
const PackIndexingExpr *E) {
9312 void VisitIgnoredValue(
const Expr *E) {
9317 void VisitIgnoredBaseExpression(
const Expr *E) {
9320 if (Info.getLangOpts().MSVCCompat && !E->
HasSideEffects(Info.Ctx))
9322 VisitIgnoredValue(E);
9332template<
class Derived>
9333class LValueExprEvaluatorBase
9334 :
public ExprEvaluatorBase<Derived> {
9338 typedef LValueExprEvaluatorBase LValueExprEvaluatorBaseTy;
9339 typedef ExprEvaluatorBase<Derived> ExprEvaluatorBaseTy;
9341 bool Success(APValue::LValueBase B) {
9346 bool evaluatePointer(
const Expr *E, LValue &
Result) {
9351 LValueExprEvaluatorBase(EvalInfo &Info, LValue &
Result,
bool InvalidBaseOK)
9353 InvalidBaseOK(InvalidBaseOK) {}
9356 Result.setFrom(this->Info.Ctx,
V);
9360 bool VisitMemberExpr(
const MemberExpr *E) {
9372 EvalOK = this->Visit(E->
getBase());
9383 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(E->
getMemberDecl())) {
9386 "record / field mismatch");
9390 }
else if (
const IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(MD)) {
9394 return this->
Error(E);
9406 bool VisitBinaryOperator(
const BinaryOperator *E) {
9409 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
9417 bool VisitCastExpr(
const CastExpr *E) {
9420 return ExprEvaluatorBaseTy::VisitCastExpr(E);
9422 case CK_DerivedToBase:
9423 case CK_UncheckedDerivedToBase:
9470class LValueExprEvaluator
9471 :
public LValueExprEvaluatorBase<LValueExprEvaluator> {
9473 LValueExprEvaluator(EvalInfo &Info, LValue &
Result,
bool InvalidBaseOK) :
9474 LValueExprEvaluatorBaseTy(Info,
Result, InvalidBaseOK) {}
9476 bool VisitVarDecl(
const Expr *E,
const VarDecl *VD);
9477 bool VisitUnaryPreIncDec(
const UnaryOperator *UO);
9479 bool VisitCallExpr(
const CallExpr *E);
9480 bool VisitDeclRefExpr(
const DeclRefExpr *E);
9481 bool VisitPredefinedExpr(
const PredefinedExpr *E) {
return Success(E); }
9482 bool VisitMaterializeTemporaryExpr(
const MaterializeTemporaryExpr *E);
9483 bool VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E);
9484 bool VisitMemberExpr(
const MemberExpr *E);
9485 bool VisitStringLiteral(
const StringLiteral *E) {
9487 APValue::LValueBase(E, 0, Info.Ctx.getNextStringLiteralVersion()));
9489 bool VisitObjCEncodeExpr(
const ObjCEncodeExpr *E) {
return Success(E); }
9490 bool VisitCXXTypeidExpr(
const CXXTypeidExpr *E);
9491 bool VisitCXXUuidofExpr(
const CXXUuidofExpr *E);
9492 bool VisitArraySubscriptExpr(
const ArraySubscriptExpr *E);
9493 bool VisitExtVectorElementExpr(
const ExtVectorElementExpr *E);
9494 bool VisitUnaryDeref(
const UnaryOperator *E);
9495 bool VisitUnaryReal(
const UnaryOperator *E);
9496 bool VisitUnaryImag(
const UnaryOperator *E);
9497 bool VisitUnaryPreInc(
const UnaryOperator *UO) {
9498 return VisitUnaryPreIncDec(UO);
9500 bool VisitUnaryPreDec(
const UnaryOperator *UO) {
9501 return VisitUnaryPreIncDec(UO);
9503 bool VisitBinAssign(
const BinaryOperator *BO);
9504 bool VisitCompoundAssignOperator(
const CompoundAssignOperator *CAO);
9506 bool VisitCastExpr(
const CastExpr *E) {
9509 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
9511 case CK_LValueBitCast:
9512 this->CCEDiag(E, diag::note_constexpr_invalid_cast)
9513 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
9517 Result.Designator.setInvalid();
9520 case CK_BaseToDerived:
9537 bool LValueToRValueConversion) {
9541 assert(Info.CurrentCall->This ==
nullptr &&
9542 "This should not be set for a static call operator");
9550 if (
Self->getType()->isReferenceType()) {
9551 APValue *RefValue = Info.getParamSlot(Info.CurrentCall->Arguments,
Self);
9553 Result.setFrom(Info.Ctx, *RefValue);
9555 const ParmVarDecl *VD = Info.CurrentCall->Arguments.getOrigParam(
Self);
9556 CallStackFrame *Frame =
9557 Info.getCallFrameAndDepth(Info.CurrentCall->Arguments.CallIndex)
9559 unsigned Version = Info.CurrentCall->Arguments.Version;
9560 Result.set({VD, Frame->Index, Version});
9563 Result = *Info.CurrentCall->This;
9573 if (LValueToRValueConversion) {
9577 Result.setFrom(Info.Ctx, RVal);
9588 bool InvalidBaseOK) {
9592 return LValueExprEvaluator(Info,
Result, InvalidBaseOK).Visit(E);
9595bool LValueExprEvaluator::VisitDeclRefExpr(
const DeclRefExpr *E) {
9596 const ValueDecl *D = E->
getDecl();
9608 if (Info.checkingPotentialConstantExpression())
9611 if (
auto *FD = Info.CurrentCall->LambdaCaptureFields.lookup(D)) {
9618 if (
isa<FunctionDecl, MSGuidDecl, TemplateParamObjectDecl,
9619 UnnamedGlobalConstantDecl>(D))
9621 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
9622 return VisitVarDecl(E, VD);
9623 if (
const BindingDecl *BD = dyn_cast<BindingDecl>(D))
9624 return Visit(BD->getBinding());
9628bool LValueExprEvaluator::VisitVarDecl(
const Expr *E,
const VarDecl *VD) {
9629 CallStackFrame *Frame =
nullptr;
9630 unsigned Version = 0;
9638 CallStackFrame *CurrFrame = Info.CurrentCall;
9643 if (
auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
9644 if (CurrFrame->Arguments) {
9645 VD = CurrFrame->Arguments.getOrigParam(PVD);
9647 Info.getCallFrameAndDepth(CurrFrame->Arguments.CallIndex).first;
9648 Version = CurrFrame->Arguments.Version;
9652 Version = CurrFrame->getCurrentTemporaryVersion(VD);
9659 Result.set({VD, Frame->Index, Version});
9665 if (!Info.getLangOpts().CPlusPlus11) {
9666 Info.CCEDiag(E, diag::note_constexpr_ltor_non_integral, 1)
9668 Info.Note(VD->
getLocation(), diag::note_declared_at);
9677 Result.AllowConstexprUnknown =
true;
9684bool LValueExprEvaluator::VisitCallExpr(
const CallExpr *E) {
9685 if (!IsConstantEvaluatedBuiltinCall(E))
9686 return ExprEvaluatorBaseTy::VisitCallExpr(E);
9691 case Builtin::BIas_const:
9692 case Builtin::BIforward:
9693 case Builtin::BIforward_like:
9694 case Builtin::BImove:
9695 case Builtin::BImove_if_noexcept:
9697 return Visit(E->
getArg(0));
9701 return ExprEvaluatorBaseTy::VisitCallExpr(E);
9704bool LValueExprEvaluator::VisitMaterializeTemporaryExpr(
9705 const MaterializeTemporaryExpr *E) {
9713 for (
const Expr *E : CommaLHSs)
9722 if (Info.EvalMode == EvaluationMode::ConstantFold)
9729 Value = &Info.CurrentCall->createTemporary(
9745 for (
unsigned I = Adjustments.size(); I != 0; ) {
9747 switch (Adjustments[I].Kind) {
9752 Type = Adjustments[I].DerivedToBase.BasePath->getType();
9758 Type = Adjustments[I].Field->getType();
9763 Adjustments[I].
Ptr.RHS))
9765 Type = Adjustments[I].Ptr.MPT->getPointeeType();
9774LValueExprEvaluator::VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E) {
9775 assert((!Info.getLangOpts().CPlusPlus || E->
isFileScope()) &&
9776 "lvalue compound literal in c++?");
9788 assert(!Info.getLangOpts().CPlusPlus);
9790 ScopeKind::Block,
Result);
9802bool LValueExprEvaluator::VisitCXXTypeidExpr(
const CXXTypeidExpr *E) {
9803 TypeInfoLValue TypeInfo;
9811 if (!Info.Ctx.getLangOpts().CPlusPlus20) {
9812 Info.CCEDiag(E, diag::note_constexpr_typeid_polymorphic)
9820 std::optional<DynamicType> DynType =
9825 TypeInfo = TypeInfoLValue(
9826 Info.Ctx.getCanonicalTagType(DynType->Type).getTypePtr());
9832bool LValueExprEvaluator::VisitCXXUuidofExpr(
const CXXUuidofExpr *E) {
9836bool LValueExprEvaluator::VisitMemberExpr(
const MemberExpr *E) {
9838 if (
const VarDecl *VD = dyn_cast<VarDecl>(E->
getMemberDecl())) {
9839 VisitIgnoredBaseExpression(E->
getBase());
9840 return VisitVarDecl(E, VD);
9844 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(E->
getMemberDecl())) {
9845 if (MD->isStatic()) {
9846 VisitIgnoredBaseExpression(E->
getBase());
9852 return LValueExprEvaluatorBaseTy::VisitMemberExpr(E);
9855bool LValueExprEvaluator::VisitExtVectorElementExpr(
9856 const ExtVectorElementExpr *E) {
9861 if (!Info.noteFailure())
9869 if (Indices.size() > 1)
9873 Result.setFrom(Info.Ctx, Val);
9877 const auto *VT = BaseType->
castAs<VectorType>();
9879 VT->getNumElements(), Indices[0]);
9885bool LValueExprEvaluator::VisitArraySubscriptExpr(
const ArraySubscriptExpr *E) {
9895 if (!Info.noteFailure())
9901 if (!Info.noteFailure())
9907 Result.setFrom(Info.Ctx, Val);
9909 VT->getNumElements(), Index.getZExtValue());
9917 for (
const Expr *SubExpr : {E->
getLHS(), E->
getRHS()}) {
9918 if (SubExpr == E->
getBase() ? !evaluatePointer(SubExpr,
Result)
9920 if (!Info.noteFailure())
9930bool LValueExprEvaluator::VisitUnaryDeref(
const UnaryOperator *E) {
9941 Info.noteUndefinedBehavior();
9944bool LValueExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
9953bool LValueExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
9955 "lvalue __imag__ on scalar?");
9962bool LValueExprEvaluator::VisitUnaryPreIncDec(
const UnaryOperator *UO) {
9963 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9974bool LValueExprEvaluator::VisitCompoundAssignOperator(
9975 const CompoundAssignOperator *CAO) {
9976 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9984 if (!Info.noteFailure())
9999bool LValueExprEvaluator::VisitBinAssign(
const BinaryOperator *E) {
10000 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
10008 if (!Info.noteFailure())
10016 if (Info.getLangOpts().CPlusPlus20 &&
10031 const LValue &LVal,
10033 assert(isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
10034 "Can't get the size of a non alloc_size function");
10035 const auto *
Base = LVal.getLValueBase().get<
const Expr *>();
10037 std::optional<llvm::APInt> Size =
10038 CE->evaluateBytesReturnedByAllocSizeCall(Ctx);
10042 Result = std::move(*Size);
10061 dyn_cast_or_null<VarDecl>(
Base.dyn_cast<
const ValueDecl *>());
10066 if (!
Init ||
Init->getType().isNull())
10069 const Expr *E =
Init->IgnoreParens();
10070 if (!tryUnwrapAllocSizeCall(E))
10078 Result.addUnsizedArray(Info, E, Pointee);
10083class PointerExprEvaluator
10084 :
public ExprEvaluatorBase<PointerExprEvaluator> {
10086 bool InvalidBaseOK;
10088 bool Success(
const Expr *E) {
10093 bool evaluateLValue(
const Expr *E, LValue &
Result) {
10097 bool evaluatePointer(
const Expr *E, LValue &
Result) {
10101 bool visitNonBuiltinCallExpr(
const CallExpr *E);
10104 PointerExprEvaluator(EvalInfo &info, LValue &
Result,
bool InvalidBaseOK)
10106 InvalidBaseOK(InvalidBaseOK) {}
10112 bool ZeroInitialization(
const Expr *E) {
10117 bool VisitBinaryOperator(
const BinaryOperator *E);
10118 bool VisitCastExpr(
const CastExpr* E);
10119 bool VisitUnaryAddrOf(
const UnaryOperator *E);
10120 bool VisitObjCStringLiteral(
const ObjCStringLiteral *E)
10122 bool VisitObjCBoxedExpr(
const ObjCBoxedExpr *E) {
10125 if (Info.noteFailure())
10129 bool VisitObjCArrayLiteral(
const ObjCArrayLiteral *E) {
10132 bool VisitObjCDictionaryLiteral(
const ObjCDictionaryLiteral *E) {
10135 bool VisitAddrLabelExpr(
const AddrLabelExpr *E)
10137 bool VisitCallExpr(
const CallExpr *E);
10138 bool VisitBuiltinCallExpr(
const CallExpr *E,
unsigned BuiltinOp);
10139 bool VisitBlockExpr(
const BlockExpr *E) {
10144 bool VisitCXXThisExpr(
const CXXThisExpr *E) {
10145 auto DiagnoseInvalidUseOfThis = [&] {
10146 if (Info.getLangOpts().CPlusPlus11)
10147 Info.FFDiag(E, diag::note_constexpr_this) << E->
isImplicit();
10153 if (Info.checkingPotentialConstantExpression())
10156 bool IsExplicitLambda =
10158 if (!IsExplicitLambda) {
10159 if (!Info.CurrentCall->This) {
10160 DiagnoseInvalidUseOfThis();
10164 Result = *Info.CurrentCall->This;
10172 if (!Info.CurrentCall->LambdaThisCaptureField) {
10173 if (IsExplicitLambda && !Info.CurrentCall->This) {
10174 DiagnoseInvalidUseOfThis();
10183 Info, E,
Result, MD, Info.CurrentCall->LambdaThisCaptureField,
10189 bool VisitCXXNewExpr(
const CXXNewExpr *E);
10191 bool VisitSourceLocExpr(
const SourceLocExpr *E) {
10192 assert(!E->
isIntType() &&
"SourceLocExpr isn't a pointer type?");
10194 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.
getDefaultExpr());
10195 Result.setFrom(Info.Ctx, LValResult);
10199 bool VisitEmbedExpr(
const EmbedExpr *E) {
10200 llvm::report_fatal_error(
"Not yet implemented for ExprConstant.cpp");
10204 bool VisitSYCLUniqueStableNameExpr(
const SYCLUniqueStableNameExpr *E) {
10205 std::string ResultStr = E->
ComputeName(Info.Ctx);
10207 QualType CharTy = Info.Ctx.CharTy.withConst();
10208 APInt Size(Info.Ctx.getTypeSize(Info.Ctx.getSizeType()),
10209 ResultStr.size() + 1);
10210 QualType ArrayTy = Info.Ctx.getConstantArrayType(
10211 CharTy, Size,
nullptr, ArraySizeModifier::Normal, 0);
10213 StringLiteral *SL =
10214 StringLiteral::Create(Info.Ctx, ResultStr, StringLiteralKind::Ordinary,
10217 evaluateLValue(SL,
Result);
10227 bool InvalidBaseOK) {
10230 return PointerExprEvaluator(Info,
Result, InvalidBaseOK).Visit(E);
10233bool PointerExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
10236 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
10238 const Expr *PExp = E->
getLHS();
10239 const Expr *IExp = E->
getRHS();
10241 std::swap(PExp, IExp);
10243 bool EvalPtrOK = evaluatePointer(PExp,
Result);
10244 if (!EvalPtrOK && !Info.noteFailure())
10247 llvm::APSInt Offset;
10258bool PointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
10266 if (!Info.getLangOpts().CPlusPlus) {
10268 if (
const auto *Deref = dyn_cast<UnaryOperator>(Sub);
10269 Deref && Deref->getOpcode() == UO_Deref)
10270 return evaluatePointer(Deref->getSubExpr(),
Result);
10280 if (!FnII || !FnII->
isStr(
"current"))
10283 const auto *RD = dyn_cast<RecordDecl>(FD->
getParent());
10291bool PointerExprEvaluator::VisitCastExpr(
const CastExpr *E) {
10298 case CK_CPointerToObjCPointerCast:
10299 case CK_BlockPointerToObjCPointerCast:
10300 case CK_AnyPointerToBlockPointerCast:
10301 case CK_AddressSpaceConversion:
10302 if (!Visit(SubExpr))
10308 CCEDiag(E, diag::note_constexpr_invalid_cast)
10309 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
10310 << Info.Ctx.getLangOpts().CPlusPlus;
10311 Result.Designator.setInvalid();
10319 bool HasValidResult = !
Result.InvalidBase && !
Result.Designator.Invalid &&
10321 bool VoidPtrCastMaybeOK =
10324 Info.Ctx.hasSimilarType(
Result.Designator.getType(Info.Ctx),
10333 if (VoidPtrCastMaybeOK &&
10334 (Info.getStdAllocatorCaller(
"allocate") ||
10336 Info.getLangOpts().CPlusPlus26)) {
10340 Info.getLangOpts().CPlusPlus) {
10341 if (HasValidResult)
10342 CCEDiag(E, diag::note_constexpr_invalid_void_star_cast)
10343 << SubExpr->
getType() << Info.getLangOpts().CPlusPlus26
10344 <<
Result.Designator.getType(Info.Ctx).getCanonicalType()
10347 CCEDiag(E, diag::note_constexpr_invalid_cast)
10348 << diag::ConstexprInvalidCastKind::CastFrom
10351 CCEDiag(E, diag::note_constexpr_invalid_cast)
10352 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
10353 << Info.Ctx.getLangOpts().CPlusPlus;
10354 Result.Designator.setInvalid();
10358 ZeroInitialization(E);
10361 case CK_DerivedToBase:
10362 case CK_UncheckedDerivedToBase:
10374 case CK_BaseToDerived:
10386 case CK_NullToPointer:
10388 return ZeroInitialization(E);
10390 case CK_IntegralToPointer: {
10391 CCEDiag(E, diag::note_constexpr_invalid_cast)
10392 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
10393 << Info.Ctx.getLangOpts().CPlusPlus;
10399 if (
Value.isInt()) {
10400 unsigned Size = Info.Ctx.getTypeSize(E->
getType());
10401 uint64_t N =
Value.getInt().extOrTrunc(Size).getZExtValue();
10402 if (N == Info.Ctx.getTargetNullPointerValue(E->
getType())) {
10405 Result.Base = (Expr *)
nullptr;
10406 Result.InvalidBase =
false;
10408 Result.Designator.setInvalid();
10409 Result.IsNullPtr =
false;
10417 if (!
Value.isLValue())
10426 case CK_ArrayToPointerDecay: {
10428 if (!evaluateLValue(SubExpr,
Result))
10432 SubExpr, SubExpr->
getType(), ScopeKind::FullExpression,
Result);
10437 auto *AT = Info.Ctx.getAsArrayType(SubExpr->
getType());
10438 if (
auto *CAT = dyn_cast<ConstantArrayType>(AT))
10439 Result.addArray(Info, E, CAT);
10441 Result.addUnsizedArray(Info, E, AT->getElementType());
10445 case CK_FunctionToPointerDecay:
10446 return evaluateLValue(SubExpr,
Result);
10448 case CK_LValueToRValue: {
10457 return InvalidBaseOK &&
10463 return ExprEvaluatorBaseTy::VisitCastExpr(E);
10467 UnaryExprOrTypeTrait ExprKind) {
10471 T =
T.getNonReferenceType();
10473 if (
T.getQualifiers().hasUnaligned())
10476 const bool AlignOfReturnsPreferred =
10482 if (ExprKind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
10485 else if (ExprKind == UETT_AlignOf)
10488 llvm_unreachable(
"GetAlignOfType on a non-alignment ExprKind");
10503 unsigned BuiltinOp) {
10527 switch (OwningTarget->
getTriple().getArch()) {
10528 case llvm::Triple::x86:
10529 case llvm::Triple::x86_64:
10542 UnaryExprOrTypeTrait ExprKind) {
10551 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
10555 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(E))
10564 return Info.Ctx.getDeclAlign(VD);
10565 if (
const auto *E =
Value.Base.dyn_cast<
const Expr *>())
10573 EvalInfo &Info,
APSInt &Alignment) {
10576 if (Alignment < 0 || !Alignment.isPowerOf2()) {
10577 Info.FFDiag(E, diag::note_constexpr_invalid_alignment) << Alignment;
10580 unsigned SrcWidth = Info.Ctx.getIntWidth(ForType);
10581 APSInt MaxValue(APInt::getOneBitSet(SrcWidth, SrcWidth - 1));
10582 if (APSInt::compareValues(Alignment, MaxValue) > 0) {
10583 Info.FFDiag(E, diag::note_constexpr_alignment_too_big)
10584 << MaxValue << ForType << Alignment;
10590 APSInt(Alignment.zextOrTrunc(SrcWidth),
true);
10591 assert(APSInt::compareValues(Alignment, ExtAlignment) == 0 &&
10592 "Alignment should not be changed by ext/trunc");
10593 Alignment = ExtAlignment;
10594 assert(Alignment.getBitWidth() == SrcWidth);
10599bool PointerExprEvaluator::visitNonBuiltinCallExpr(
const CallExpr *E) {
10600 if (ExprEvaluatorBaseTy::VisitCallExpr(E))
10608 Result.addUnsizedArray(Info, E, PointeeTy);
10612bool PointerExprEvaluator::VisitCallExpr(
const CallExpr *E) {
10613 if (!IsConstantEvaluatedBuiltinCall(E))
10614 return visitNonBuiltinCallExpr(E);
10621 return T->isCharType() ||
T->isChar8Type();
10624bool PointerExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *E,
10625 unsigned BuiltinOp) {
10629 switch (BuiltinOp) {
10630 case Builtin::BIaddressof:
10631 case Builtin::BI__addressof:
10632 case Builtin::BI__builtin_addressof:
10634 case Builtin::BI__builtin_assume_aligned: {
10641 LValue OffsetResult(
Result);
10653 int64_t AdditionalOffset = -Offset.getZExtValue();
10658 if (OffsetResult.Base) {
10661 if (BaseAlignment < Align) {
10662 Result.Designator.setInvalid();
10663 CCEDiag(E->
getArg(0), diag::note_constexpr_baa_insufficient_alignment)
10670 if (OffsetResult.Offset.alignTo(Align) != OffsetResult.Offset) {
10671 Result.Designator.setInvalid();
10675 diag::note_constexpr_baa_insufficient_alignment)
10678 diag::note_constexpr_baa_value_insufficient_alignment))
10679 << OffsetResult.Offset.getQuantity() << Align.
getQuantity();
10685 case Builtin::BI__builtin_align_up:
10686 case Builtin::BI__builtin_align_down: {
10706 assert(Alignment.getBitWidth() <= 64 &&
10707 "Cannot handle > 64-bit address-space");
10708 uint64_t Alignment64 = Alignment.getZExtValue();
10710 BuiltinOp == Builtin::BI__builtin_align_down
10711 ? llvm::alignDown(
Result.Offset.getQuantity(), Alignment64)
10712 : llvm::alignTo(
Result.Offset.getQuantity(), Alignment64));
10718 Info.FFDiag(E->
getArg(0), diag::note_constexpr_alignment_adjust)
10722 case Builtin::BI__builtin_operator_new:
10724 case Builtin::BI__builtin_launder:
10726 case Builtin::BIstrchr:
10727 case Builtin::BIwcschr:
10728 case Builtin::BImemchr:
10729 case Builtin::BIwmemchr:
10730 if (Info.getLangOpts().CPlusPlus11)
10731 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
10733 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
10735 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
10737 case Builtin::BI__builtin_strchr:
10738 case Builtin::BI__builtin_wcschr:
10739 case Builtin::BI__builtin_memchr:
10740 case Builtin::BI__builtin_char_memchr:
10741 case Builtin::BI__builtin_wmemchr: {
10742 if (!Visit(E->
getArg(0)))
10748 if (BuiltinOp != Builtin::BIstrchr &&
10749 BuiltinOp != Builtin::BIwcschr &&
10750 BuiltinOp != Builtin::BI__builtin_strchr &&
10751 BuiltinOp != Builtin::BI__builtin_wcschr) {
10755 MaxLength = N.getZExtValue();
10758 if (MaxLength == 0u)
10759 return ZeroInitialization(E);
10760 if (!
Result.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
10761 Result.Designator.Invalid)
10763 QualType CharTy =
Result.Designator.getType(Info.Ctx);
10764 bool IsRawByte = BuiltinOp == Builtin::BImemchr ||
10765 BuiltinOp == Builtin::BI__builtin_memchr;
10766 assert(IsRawByte ||
10767 Info.Ctx.hasSameUnqualifiedType(
10771 Info.FFDiag(E, diag::note_constexpr_ltor_incomplete_type) << CharTy;
10777 Info.FFDiag(E, diag::note_constexpr_memchr_unsupported)
10778 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp) << CharTy;
10784 bool StopAtNull =
false;
10785 switch (BuiltinOp) {
10786 case Builtin::BIstrchr:
10787 case Builtin::BI__builtin_strchr:
10794 return ZeroInitialization(E);
10797 case Builtin::BImemchr:
10798 case Builtin::BI__builtin_memchr:
10799 case Builtin::BI__builtin_char_memchr:
10803 DesiredVal = Desired.trunc(Info.Ctx.getCharWidth()).getZExtValue();
10806 case Builtin::BIwcschr:
10807 case Builtin::BI__builtin_wcschr:
10810 case Builtin::BIwmemchr:
10811 case Builtin::BI__builtin_wmemchr:
10813 DesiredVal = Desired.getZExtValue();
10817 for (; MaxLength; --MaxLength) {
10822 if (Char.
getInt().getZExtValue() == DesiredVal)
10824 if (StopAtNull && !Char.
getInt())
10830 return ZeroInitialization(E);
10833 case Builtin::BImemcpy:
10834 case Builtin::BImemmove:
10835 case Builtin::BIwmemcpy:
10836 case Builtin::BIwmemmove:
10837 if (Info.getLangOpts().CPlusPlus11)
10838 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
10840 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
10842 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
10844 case Builtin::BI__builtin_memcpy:
10845 case Builtin::BI__builtin_memmove:
10846 case Builtin::BI__builtin_wmemcpy:
10847 case Builtin::BI__builtin_wmemmove: {
10848 bool WChar = BuiltinOp == Builtin::BIwmemcpy ||
10849 BuiltinOp == Builtin::BIwmemmove ||
10850 BuiltinOp == Builtin::BI__builtin_wmemcpy ||
10851 BuiltinOp == Builtin::BI__builtin_wmemmove;
10852 bool Move = BuiltinOp == Builtin::BImemmove ||
10853 BuiltinOp == Builtin::BIwmemmove ||
10854 BuiltinOp == Builtin::BI__builtin_memmove ||
10855 BuiltinOp == Builtin::BI__builtin_wmemmove;
10858 if (!Visit(E->
getArg(0)))
10869 assert(!N.isSigned() &&
"memcpy and friends take an unsigned size");
10879 if (!Src.Base || !Dest.Base) {
10881 (!Src.Base ? Src : Dest).moveInto(Val);
10882 Info.FFDiag(E, diag::note_constexpr_memcpy_null)
10883 <<
Move << WChar << !!Src.Base
10887 if (Src.Designator.Invalid || Dest.Designator.Invalid)
10893 QualType
T = Dest.Designator.getType(Info.Ctx);
10894 QualType SrcT = Src.Designator.getType(Info.Ctx);
10895 if (!Info.Ctx.hasSameUnqualifiedType(
T, SrcT)) {
10897 Info.FFDiag(E, diag::note_constexpr_memcpy_type_pun) <<
Move << SrcT <<
T;
10901 Info.FFDiag(E, diag::note_constexpr_memcpy_incomplete_type) <<
Move <<
T;
10904 if (!
T.isTriviallyCopyableType(Info.Ctx)) {
10905 Info.FFDiag(E, diag::note_constexpr_memcpy_nontrivial) <<
Move <<
T;
10910 uint64_t TSize = Info.Ctx.getTypeSizeInChars(
T).getQuantity();
10915 llvm::APInt OrigN = N;
10916 llvm::APInt::udivrem(OrigN, TSize, N, Remainder);
10918 Info.FFDiag(E, diag::note_constexpr_memcpy_unsupported)
10920 << (unsigned)TSize;
10928 uint64_t RemainingSrcSize = Src.Designator.validIndexAdjustments().second;
10929 uint64_t RemainingDestSize = Dest.Designator.validIndexAdjustments().second;
10930 if (N.ugt(RemainingSrcSize) || N.ugt(RemainingDestSize)) {
10931 Info.FFDiag(E, diag::note_constexpr_memcpy_unsupported)
10932 <<
Move << WChar << (N.ugt(RemainingSrcSize) ? 1 : 2) <<
T
10936 uint64_t NElems = N.getZExtValue();
10942 uint64_t SrcOffset = Src.getLValueOffset().getQuantity();
10943 uint64_t DestOffset = Dest.getLValueOffset().getQuantity();
10944 if (DestOffset >= SrcOffset && DestOffset - SrcOffset < NBytes) {
10947 Info.FFDiag(E, diag::note_constexpr_memcpy_overlap) << WChar;
10955 }
else if (!Move && SrcOffset >= DestOffset &&
10956 SrcOffset - DestOffset < NBytes) {
10958 Info.FFDiag(E, diag::note_constexpr_memcpy_overlap) << WChar;
10987 QualType AllocType);
10990 const CXXConstructExpr *CCE,
10991 QualType AllocType);
10993bool PointerExprEvaluator::VisitCXXNewExpr(
const CXXNewExpr *E) {
10994 if (!Info.getLangOpts().CPlusPlus20)
10995 Info.CCEDiag(E, diag::note_constexpr_new);
10998 if (Info.SpeculativeEvaluationDepth)
11003 QualType TargetType = AllocType;
11005 bool IsNothrow =
false;
11006 bool IsPlacement =
false;
11024 }
else if (OperatorNew->isReservedGlobalPlacementOperator()) {
11025 if (Info.CurrentCall->isStdFunction() || Info.getLangOpts().CPlusPlus26 ||
11026 (Info.CurrentCall->CanEvalMSConstexpr &&
11027 OperatorNew->hasAttr<MSConstexprAttr>())) {
11030 if (
Result.Designator.Invalid)
11033 IsPlacement =
true;
11035 Info.FFDiag(E, diag::note_constexpr_new_placement)
11040 Info.FFDiag(E, diag::note_constexpr_new_placement)
11043 }
else if (!OperatorNew
11044 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
11045 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
11051 const InitListExpr *ResizedArrayILE =
nullptr;
11052 const CXXConstructExpr *ResizedArrayCCE =
nullptr;
11053 bool ValueInit =
false;
11055 if (std::optional<const Expr *> ArraySize = E->
getArraySize()) {
11056 const Expr *Stripped = *ArraySize;
11057 for (;
auto *ICE = dyn_cast<ImplicitCastExpr>(Stripped);
11058 Stripped = ICE->getSubExpr())
11059 if (ICE->getCastKind() != CK_NoOp &&
11060 ICE->getCastKind() != CK_IntegralCast)
11073 return ZeroInitialization(E);
11075 Info.FFDiag(*ArraySize, diag::note_constexpr_new_negative)
11076 <<
ArrayBound << (*ArraySize)->getSourceRange();
11082 if (!Info.CheckArraySize(ArraySize.value()->getExprLoc(),
11087 return ZeroInitialization(E);
11099 }
else if (
auto *CCE = dyn_cast<CXXConstructExpr>(
Init)) {
11100 ResizedArrayCCE = CCE;
11102 auto *CAT = Info.Ctx.getAsConstantArrayType(
Init->getType());
11103 assert(CAT &&
"unexpected type for array initializer");
11107 llvm::APInt InitBound = CAT->
getSize().zext(Bits);
11108 llvm::APInt AllocBound =
ArrayBound.zext(Bits);
11109 if (InitBound.ugt(AllocBound)) {
11111 return ZeroInitialization(E);
11113 Info.FFDiag(*ArraySize, diag::note_constexpr_new_too_small)
11114 <<
toString(AllocBound, 10,
false)
11116 << (*ArraySize)->getSourceRange();
11122 if (InitBound != AllocBound)
11126 AllocType = Info.Ctx.getConstantArrayType(AllocType,
ArrayBound,
nullptr,
11127 ArraySizeModifier::Normal, 0);
11137 "array allocation with non-array new");
11143 struct FindObjectHandler {
11146 QualType AllocType;
11150 typedef bool result_type;
11151 bool failed() {
return false; }
11152 bool checkConst(QualType QT) {
11154 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
11159 bool found(
APValue &Subobj, QualType SubobjType,
11160 APValue::LValueBase Base) {
11161 if (!checkConst(SubobjType))
11165 if (!Info.Ctx.hasSimilarType(SubobjType, AllocType)) {
11166 Info.FFDiag(E, diag::note_constexpr_placement_new_wrong_type)
11167 << SubobjType << AllocType;
11174 Info.FFDiag(E, diag::note_constexpr_construct_complex_elem);
11177 bool found(APFloat &
Value, QualType SubobjType) {
11178 Info.FFDiag(E, diag::note_constexpr_construct_complex_elem);
11181 } Handler = {Info, E, AllocType, AK,
nullptr};
11184 Result.Designator.MostDerivedIsArrayElement &&
11185 Result.Designator.Entries.back().getAsArrayIndex() == 0) {
11190 QualType AllocElementType =
11191 Info.Ctx.getAsArrayType(AllocType)->getElementType();
11192 if (Info.Ctx.hasSimilarType(AllocElementType,
11193 Result.Designator.MostDerivedType)) {
11195 Result.Designator.MostDerivedPathLength - 1);
11203 Val = Handler.Value;
11212 Val = Info.createHeapAlloc(E, AllocType,
Result);
11218 ImplicitValueInitExpr VIE(AllocType);
11221 }
else if (ResizedArrayILE) {
11225 }
else if (ResizedArrayCCE) {
11248class MemberPointerExprEvaluator
11249 :
public ExprEvaluatorBase<MemberPointerExprEvaluator> {
11252 bool Success(
const ValueDecl *D) {
11258 MemberPointerExprEvaluator(EvalInfo &Info, MemberPtr &
Result)
11265 bool ZeroInitialization(
const Expr *E) {
11266 return Success((
const ValueDecl*)
nullptr);
11269 bool VisitCastExpr(
const CastExpr *E);
11270 bool VisitUnaryAddrOf(
const UnaryOperator *E);
11278 return MemberPointerExprEvaluator(Info,
Result).Visit(E);
11281bool MemberPointerExprEvaluator::VisitCastExpr(
const CastExpr *E) {
11284 return ExprEvaluatorBaseTy::VisitCastExpr(E);
11286 case CK_NullToMemberPointer:
11288 return ZeroInitialization(E);
11290 case CK_BaseToDerivedMemberPointer: {
11298 typedef std::reverse_iterator<CastExpr::path_const_iterator> ReverseIter;
11300 PathI != PathE; ++PathI) {
11301 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
11302 const CXXRecordDecl *Derived = (*PathI)->getType()->getAsCXXRecordDecl();
11303 if (!
Result.castToDerived(Derived))
11307 ->
castAs<MemberPointerType>()
11308 ->getMostRecentCXXRecordDecl()))
11313 case CK_DerivedToBaseMemberPointer:
11317 PathE = E->
path_end(); PathI != PathE; ++PathI) {
11318 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
11319 const CXXRecordDecl *
Base = (*PathI)->getType()->getAsCXXRecordDecl();
11320 if (!
Result.castToBase(Base))
11327bool MemberPointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
11338 class RecordExprEvaluator
11339 :
public ExprEvaluatorBase<RecordExprEvaluator> {
11340 const LValue &
This;
11344 RecordExprEvaluator(EvalInfo &info,
const LValue &This,
APValue &
Result)
11351 bool ZeroInitialization(
const Expr *E) {
11352 return ZeroInitialization(E, E->
getType());
11354 bool ZeroInitialization(
const Expr *E, QualType
T);
11356 bool VisitCallExpr(
const CallExpr *E) {
11357 return handleCallExpr(E,
Result, &This);
11359 bool VisitCastExpr(
const CastExpr *E);
11360 bool VisitInitListExpr(
const InitListExpr *E);
11361 bool VisitCXXConstructExpr(
const CXXConstructExpr *E) {
11362 return VisitCXXConstructExpr(E, E->
getType());
11365 bool VisitCXXInheritedCtorInitExpr(
const CXXInheritedCtorInitExpr *E);
11366 bool VisitCXXConstructExpr(
const CXXConstructExpr *E, QualType
T);
11367 bool VisitCXXStdInitializerListExpr(
const CXXStdInitializerListExpr *E);
11368 bool VisitBinCmp(
const BinaryOperator *E);
11369 bool VisitTypeTraitExpr(
const TypeTraitExpr *E);
11370 bool VisitCXXParenListInitExpr(
const CXXParenListInitExpr *E);
11371 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
11372 ArrayRef<Expr *> Args);
11373 bool VisitDesignatedInitUpdateExpr(
const DesignatedInitUpdateExpr *E);
11387 bool IsCompleteClass =
true) {
11388 assert(!RD->
isUnion() &&
"Expected non-union class type");
11392 unsigned NonVirtualBases = countNonVirtualBases(CD);
11404 unsigned Index = 0;
11406 for (
const auto &B : CD->
bases()) {
11410 LValue Subobject =
This;
11414 Result.getStructBase(Index),
11421 for (
const auto *I : RD->
fields()) {
11423 if (I->isUnnamedBitField() || I->getType()->isReferenceType())
11426 LValue Subobject =
This;
11432 Result.getStructField(I->getFieldIndex()), Info, Subobject, &VIE))
11436 if (CD &&
This.pointsToCompleteClass(CD)) {
11437 unsigned Index = 0;
11438 for (
const auto &B : CD->
vbases()) {
11440 LValue Subobject =
This;
11444 Result.getStructVirtualBase(Index),
11454bool RecordExprEvaluator::ZeroInitialization(
const Expr *E, QualType
T) {
11461 while (I != RD->
field_end() && (*I)->isUnnamedBitField())
11468 LValue Subobject =
This;
11472 ImplicitValueInitExpr VIE(I->getType());
11476 if (!Info.getLangOpts().CPlusPlus26) {
11477 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
11478 CXXRD && CXXRD->getNumVBases()) {
11479 Info.FFDiag(E, diag::note_constexpr_virtual_base) << RD;
11487bool RecordExprEvaluator::VisitCastExpr(
const CastExpr *E) {
11490 return ExprEvaluatorBaseTy::VisitCastExpr(E);
11492 case CK_ConstructorConversion:
11495 case CK_DerivedToBase:
11496 case CK_UncheckedDerivedToBase: {
11507 PathE = E->
path_end(); PathI != PathE; ++PathI) {
11508 assert(!(*PathI)->isVirtual() &&
"record rvalue with virtual base");
11509 const CXXRecordDecl *
Base = (*PathI)->getType()->getAsCXXRecordDecl();
11516 case CK_HLSLAggregateSplatCast: {
11536 case CK_HLSLElementwiseCast: {
11554 LValue Subobject =
This;
11561 if (
Field->isBitField()) {
11571bool RecordExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
11574 return VisitCXXParenListOrInitListExpr(E, E->
inits());
11577bool RecordExprEvaluator::VisitCXXParenListOrInitListExpr(
11581 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD);
11582 auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
11584 EvalInfo::EvaluatingConstructorRAII EvalObj(
11586 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries},
11587 CXXRD && CXXRD->getNumBases());
11590 const FieldDecl *
Field;
11591 if (
auto *ILE = dyn_cast<InitListExpr>(ExprToVisit)) {
11592 Field = ILE->getInitializedFieldInUnion();
11593 }
else if (
auto *PLIE = dyn_cast<CXXParenListInitExpr>(ExprToVisit)) {
11594 Field = PLIE->getInitializedFieldInUnion();
11597 "Expression is neither an init list nor a C++ paren list");
11609 ImplicitValueInitExpr VIE(
Field->getType());
11610 const Expr *InitExpr = Args.empty() ? &VIE : Args[0];
11612 LValue Subobject =
This;
11617 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
11621 if (
Field->isBitField())
11631 Result =
APValue(APValue::UninitStruct(), CXXRD ? CXXRD->getNumBases() : 0,
11633 unsigned ElementNo = 0;
11637 if (CXXRD && CXXRD->getNumBases()) {
11638 for (
const auto &Base : CXXRD->bases()) {
11639 assert(ElementNo < Args.size() &&
"missing init for base class");
11640 const Expr *
Init = Args[ElementNo];
11642 LValue Subobject =
This;
11648 if (!Info.noteFailure())
11655 EvalObj.finishedConstructingBases();
11659 for (
const auto *Field : RD->
fields()) {
11662 if (
Field->isUnnamedBitField())
11665 LValue Subobject =
This;
11667 bool HaveInit = ElementNo < Args.size();
11672 Subobject, Field, &Layout))
11677 ImplicitValueInitExpr VIE(HaveInit ? Info.Ctx.IntTy :
Field->getType());
11678 const Expr *
Init = HaveInit ? Args[ElementNo++] : &VIE;
11685 if (
Field->getType()->isIncompleteArrayType()) {
11686 if (
auto *CAT = Info.Ctx.getAsConstantArrayType(
Init->getType())) {
11690 Info.FFDiag(
Init, diag::note_constexpr_unsupported_flexible_array);
11697 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
11701 if (
Field->getType()->isReferenceType()) {
11705 if (!Info.noteFailure())
11710 (
Field->isBitField() &&
11712 if (!Info.noteFailure())
11718 EvalObj.finishedConstructingFields();
11723bool RecordExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E,
11733 return ZeroInitialization(E,
T);
11751 const Expr *SrcObj = E->
getArg(0);
11753 assert(Info.Ctx.hasSameUnqualifiedType(E->
getType(), SrcObj->
getType()));
11754 if (
const MaterializeTemporaryExpr *ME =
11755 dyn_cast<MaterializeTemporaryExpr>(SrcObj))
11756 return Visit(ME->getSubExpr());
11759 if (ZeroInit && !ZeroInitialization(E,
T))
11768bool RecordExprEvaluator::VisitCXXInheritedCtorInitExpr(
11769 const CXXInheritedCtorInitExpr *E) {
11770 if (!Info.CurrentCall) {
11771 assert(Info.checkingPotentialConstantExpression());
11790bool RecordExprEvaluator::VisitCXXStdInitializerListExpr(
11791 const CXXStdInitializerListExpr *E) {
11792 const ConstantArrayType *ArrayType =
11799 assert(ArrayType &&
"unexpected type for array initializer");
11802 Array.addArray(Info, E, ArrayType);
11810 assert(Field !=
Record->field_end() &&
11811 Info.Ctx.hasSameType(
Field->getType()->getPointeeType(),
11813 "Expected std::initializer_list first field to be const E *");
11815 assert(Field !=
Record->field_end() &&
11816 "Expected std::initializer_list to have two fields");
11818 if (Info.Ctx.hasSameType(
Field->getType(), Info.Ctx.getSizeType())) {
11823 assert(Info.Ctx.hasSameType(
Field->getType()->getPointeeType(),
11825 "Expected std::initializer_list second field to be const E *");
11833 assert(++Field ==
Record->field_end() &&
11834 "Expected std::initializer_list to only have two fields");
11839bool RecordExprEvaluator::VisitLambdaExpr(
const LambdaExpr *E) {
11844 const size_t NumFields = ClosureClass->
getNumFields();
11848 "The number of lambda capture initializers should equal the number of "
11849 "fields within the closure type");
11856 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(ClosureClass);
11857 for (
const auto *Field : ClosureClass->
fields()) {
11860 Expr *
const CurFieldInit = *CaptureInitIt++;
11867 LValue Subobject =
This;
11874 if (!Info.keepEvaluatingAfterFailure())
11882bool RecordExprEvaluator::VisitDesignatedInitUpdateExpr(
11883 const DesignatedInitUpdateExpr *E) {
11893 "can't evaluate expression as a record rvalue");
11894 return RecordExprEvaluator(Info,
This,
Result).Visit(E);
11905class TemporaryExprEvaluator
11906 :
public LValueExprEvaluatorBase<TemporaryExprEvaluator> {
11908 TemporaryExprEvaluator(EvalInfo &Info, LValue &
Result) :
11909 LValueExprEvaluatorBaseTy(Info,
Result,
false) {}
11912 bool VisitConstructExpr(
const Expr *E) {
11918 bool VisitCastExpr(
const CastExpr *E) {
11921 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
11923 case CK_ConstructorConversion:
11927 bool VisitInitListExpr(
const InitListExpr *E) {
11928 return VisitConstructExpr(E);
11930 bool VisitCXXConstructExpr(
const CXXConstructExpr *E) {
11931 return VisitConstructExpr(E);
11933 bool VisitCallExpr(
const CallExpr *E) {
11934 return VisitConstructExpr(E);
11936 bool VisitCXXStdInitializerListExpr(
const CXXStdInitializerListExpr *E) {
11937 return VisitConstructExpr(E);
11940 return VisitConstructExpr(E);
11949 return TemporaryExprEvaluator(Info,
Result).Visit(E);
11957 class VectorExprEvaluator
11958 :
public ExprEvaluatorBase<VectorExprEvaluator> {
11965 bool Success(ArrayRef<APValue>
V,
const Expr *E) {
11966 assert(
V.size() == E->
getType()->
castAs<VectorType>()->getNumElements());
11972 assert(
V.isVector());
11976 bool ZeroInitialization(
const Expr *E);
11978 bool VisitUnaryReal(
const UnaryOperator *E)
11980 bool VisitCastExpr(
const CastExpr* E);
11981 bool VisitInitListExpr(
const InitListExpr *E);
11982 bool VisitUnaryImag(
const UnaryOperator *E);
11983 bool VisitBinaryOperator(
const BinaryOperator *E);
11984 bool VisitUnaryOperator(
const UnaryOperator *E);
11985 bool VisitCallExpr(
const CallExpr *E);
11986 bool VisitConvertVectorExpr(
const ConvertVectorExpr *E);
11987 bool VisitShuffleVectorExpr(
const ShuffleVectorExpr *E);
11996 "not a vector prvalue");
11997 return VectorExprEvaluator(Info,
Result).Visit(E);
12001 assert(Val.
isVector() &&
"expected vector APValue");
12005 llvm::APInt
Result(NumElts, 0);
12007 for (
unsigned I = 0; I < NumElts; ++I) {
12009 assert(Elt.
isInt() &&
"expected integer element in bool vector");
12011 if (Elt.
getInt().getBoolValue())
12018bool VectorExprEvaluator::VisitCastExpr(
const CastExpr *E) {
12019 const VectorType *VTy = E->
getType()->
castAs<VectorType>();
12023 QualType SETy = SE->
getType();
12026 case CK_VectorSplat: {
12032 Val =
APValue(std::move(IntResult));
12037 Val =
APValue(std::move(FloatResult));
12054 Info.FFDiag(E, diag::note_constexpr_invalid_cast)
12055 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
12056 << Info.Ctx.getLangOpts().CPlusPlus;
12060 if (!handleRValueToRValueBitCast(Info,
Result, SVal, E))
12065 case CK_HLSLVectorTruncation: {
12070 for (
unsigned I = 0; I < NElts; I++)
12074 case CK_HLSLMatrixTruncation: {
12080 for (
unsigned Row = 0;
12082 for (
unsigned Col = 0;
12087 case CK_HLSLAggregateSplatCast: {
12104 case CK_HLSLElementwiseCast: {
12117 return Success(ResultEls, E);
12119 case CK_IntegralToFloating:
12120 case CK_FloatingToIntegral:
12121 case CK_IntegralCast:
12122 case CK_FloatingCast:
12123 case CK_FloatingToBoolean:
12124 case CK_IntegralToBoolean: {
12126 assert(SETy->
isVectorType() &&
"expected vector source type");
12132 QualType SrcEltTy = SETy->
castAs<VectorType>()->getElementType();
12137 for (
unsigned I = 0; I < NElts; ++I) {
12142 return Success(ResultEls, E);
12145 return ExprEvaluatorBaseTy::VisitCastExpr(E);
12150VectorExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
12167 unsigned CountInits = 0, CountElts = 0;
12168 while (CountElts < NumElements) {
12170 if (CountInits < NumInits
12176 for (
unsigned j = 0; j < vlen; j++)
12180 llvm::APSInt sInt(32);
12181 if (CountInits < NumInits) {
12185 sInt = Info.Ctx.MakeIntValue(0, EltTy);
12186 Elements.push_back(
APValue(sInt));
12189 llvm::APFloat f(0.0);
12190 if (CountInits < NumInits) {
12194 f = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy));
12195 Elements.push_back(
APValue(f));
12204VectorExprEvaluator::ZeroInitialization(
const Expr *E) {
12208 if (EltTy->isIntegerType())
12209 ZeroElement =
APValue(Info.Ctx.MakeIntValue(0, EltTy));
12212 APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy)));
12218bool VectorExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
12220 return ZeroInitialization(E);
12223bool VectorExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
12225 assert(Op != BO_PtrMemD && Op != BO_PtrMemI && Op != BO_Cmp &&
12226 "Operation not supported on vector types");
12228 if (Op == BO_Comma)
12229 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
12231 Expr *LHS = E->
getLHS();
12232 Expr *RHS = E->
getRHS();
12235 "Must both be vector types");
12238 assert(LHS->
getType()->
castAs<VectorType>()->getNumElements() ==
12242 "All operands must be the same size.");
12246 bool LHSOK =
Evaluate(LHSValue, Info, LHS);
12247 if (!LHSOK && !Info.noteFailure())
12249 if (!
Evaluate(RHSValue, Info, RHS) || !LHSOK)
12271 "Vector can only be int or float type");
12279 "Vector operator ~ can only be int");
12280 Elt.
getInt().flipAllBits();
12290 "Vector can only be int or float type");
12296 EltResult.setAllBits();
12298 EltResult.clearAllBits();
12304 return std::nullopt;
12308bool VectorExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
12314 const QualType ResultEltTy = VD->getElementType();
12318 if (!
Evaluate(SubExprValue, Info, SubExpr))
12331 "Vector length doesn't match type?");
12334 for (
unsigned EltNum = 0; EltNum < VD->getNumElements(); ++EltNum) {
12336 Info.Ctx, ResultEltTy, Op, SubExprValue.
getVectorElt(EltNum));
12339 ResultElements.push_back(*Elt);
12341 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12352 DestTy,
Result.getFloat());
12368 DestTy,
Result.getInt());
12372 Info.FFDiag(E, diag::err_convertvector_constexpr_unsupported_vector_cast)
12373 << SourceTy << DestTy;
12378 llvm::function_ref<APInt(
const APSInt &)> PackFn) {
12387 assert(LHSVecLen != 0 && LHSVecLen == RHSVecLen &&
12388 "pack builtin LHSVecLen must equal to RHSVecLen");
12391 const unsigned SrcBits = Info.Ctx.getIntWidth(VT0->
getElementType());
12397 const unsigned SrcPerLane = 128 / SrcBits;
12398 const unsigned Lanes = LHSVecLen * SrcBits / 128;
12401 Out.reserve(LHSVecLen + RHSVecLen);
12403 for (
unsigned Lane = 0; Lane != Lanes; ++Lane) {
12404 unsigned base = Lane * SrcPerLane;
12405 for (
unsigned I = 0; I != SrcPerLane; ++I)
12408 for (
unsigned I = 0; I != SrcPerLane; ++I)
12419 llvm::function_ref<std::pair<unsigned, int>(
unsigned,
unsigned)>
12426 unsigned ShuffleMask = 0;
12428 bool IsVectorMask =
false;
12429 bool IsSingleOperand = (
Call->getNumArgs() == 2);
12431 if (IsSingleOperand) {
12434 IsVectorMask =
true;
12443 ShuffleMask =
static_cast<unsigned>(MaskImm.getZExtValue());
12453 IsVectorMask =
true;
12462 ShuffleMask =
static_cast<unsigned>(MaskImm.getZExtValue());
12473 ResultElements.reserve(NumElts);
12475 for (
unsigned DstIdx = 0; DstIdx != NumElts; ++DstIdx) {
12476 if (IsVectorMask) {
12477 ShuffleMask =
static_cast<unsigned>(
12478 MaskVector.getVectorElt(DstIdx).getInt().getZExtValue());
12480 auto [SrcVecIdx, SrcIdx] = GetSourceIndex(DstIdx, ShuffleMask);
12486 ResultElements.push_back(
12487 APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(ElemTy))));
12493 ResultElements.push_back(
APValue());
12496 const APValue &Src = (SrcVecIdx == 0) ? A : B;
12501 Out =
APValue(ResultElements.data(), ResultElements.size());
12507 if (OrigVal.isInfinity()) {
12508 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << 0;
12511 if (OrigVal.isNaN()) {
12512 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << 1;
12516 APFloat Val = OrigVal;
12517 bool LosesInfo =
false;
12518 APFloat::opStatus Status = Val.convert(
12519 APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven, &LosesInfo);
12521 if (LosesInfo || Val.isDenormal()) {
12522 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic_strict);
12526 if (Status != APFloat::opOK) {
12527 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
12536 llvm::function_ref<APInt(
const APInt &, uint64_t)> ShiftOp,
12537 llvm::function_ref<APInt(
const APInt &,
unsigned)> OverflowOp) {
12544 assert(
Call->getNumArgs() == 2);
12548 Call->getArg(1)->getType()->isVectorType());
12551 unsigned DestEltWidth = Source.getVectorElt(0).getInt().getBitWidth();
12552 unsigned DestLen = Source.getVectorLength();
12555 unsigned NumBitsInQWord = 64;
12556 unsigned NumCountElts = NumBitsInQWord / CountEltWidth;
12558 Result.reserve(DestLen);
12560 uint64_t CountLQWord = 0;
12561 for (
unsigned EltIdx = 0; EltIdx != NumCountElts; ++EltIdx) {
12563 CountLQWord |= (Elt << (EltIdx * CountEltWidth));
12566 for (
unsigned EltIdx = 0; EltIdx != DestLen; ++EltIdx) {
12567 APInt Elt = Source.getVectorElt(EltIdx).getInt();
12568 if (CountLQWord < DestEltWidth) {
12570 APValue(
APSInt(ShiftOp(Elt, CountLQWord), IsDestUnsigned)));
12573 APValue(
APSInt(OverflowOp(Elt, DestEltWidth), IsDestUnsigned)));
12581 std::optional<APSInt> RoundingMode,
12583 APSInt DefaultMode(APInt(32, 4),
true);
12584 if (RoundingMode.value_or(DefaultMode) != 4)
12585 return std::nullopt;
12586 if (A.isNaN() || A.isInfinity() || A.isDenormal() || B.isNaN() ||
12587 B.isInfinity() || B.isDenormal())
12588 return std::nullopt;
12589 if (A.isZero() && B.isZero())
12591 return IsMin ? llvm::minimum(A, B) : llvm::maximum(A, B);
12594bool VectorExprEvaluator::VisitCallExpr(
const CallExpr *E) {
12595 if (!IsConstantEvaluatedBuiltinCall(E))
12596 return ExprEvaluatorBaseTy::VisitCallExpr(E);
12600 auto EvaluateBinOpExpr =
12602 APValue SourceLHS, SourceRHS;
12608 QualType DestEltTy = DestTy->getElementType();
12609 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
12612 ResultElements.reserve(SourceLen);
12614 if (SourceRHS.
isInt()) {
12616 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12618 ResultElements.push_back(
12622 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12625 ResultElements.push_back(
12632 auto EvaluateFpBinOpExpr =
12633 [&](llvm::function_ref<std::optional<APFloat>(
12634 const APFloat &,
const APFloat &, std::optional<APSInt>)>
12636 bool IsScalar =
false) {
12646 std::optional<APSInt> RoundingMode;
12651 RoundingMode = Imm;
12656 ResultElements.reserve(NumElems);
12658 for (
unsigned EltNum = 0; EltNum < NumElems; ++EltNum) {
12659 if (IsScalar && EltNum > 0) {
12665 std::optional<APFloat>
Result =
Fn(EltA, EltB, RoundingMode);
12673 auto EvaluateScalarFpRoundMaskBinOp =
12674 [&](llvm::function_ref<std::optional<APFloat>(
12675 const APFloat &,
const APFloat &, std::optional<APSInt>)>
12679 APSInt MaskVal, Rounding;
12690 ResultElements.reserve(NumElems);
12692 if (MaskVal.getZExtValue() & 1) {
12695 std::optional<APFloat>
Result =
Fn(EltA, EltB, Rounding);
12703 for (
unsigned I = 1; I < NumElems; ++I)
12709 auto EvalSelectScalar = [&](
unsigned Len) ->
bool {
12717 bool TakeA0 = (Mask.getZExtValue() & 1u) != 0;
12721 for (
unsigned I = 1; I < Len; ++I)
12723 APValue V(Res.data(), Res.size());
12727 auto EvalVectorDotProduct = [&](
bool IsSaturating) ->
bool {
12728 APValue Source, OperandA, OperandB;
12737 unsigned ElemsPerLane = NumOperandElems / NumSrcElems;
12742 Result.reserve(NumSrcElems);
12743 for (
unsigned I = 0; I != NumSrcElems; ++I) {
12745 DotProduct = DotProduct.extend(64);
12746 for (
unsigned J = 0; J != ElemsPerLane; ++J) {
12753 DotProduct += OpA * OpB;
12755 if (IsSaturating) {
12756 DotProduct =
APSInt(DotProduct.truncSSat(32),
false);
12758 DotProduct =
APSInt(DotProduct.trunc(32),
false);
12766 switch (BuiltinOp) {
12769 case Builtin::BI__builtin_elementwise_popcount:
12770 case Builtin::BI__builtin_elementwise_bitreverse: {
12775 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12778 ResultElements.reserve(SourceLen);
12780 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12782 switch (BuiltinOp) {
12783 case Builtin::BI__builtin_elementwise_popcount:
12784 ResultElements.push_back(
APValue(
12785 APSInt(
APInt(Info.Ctx.getIntWidth(DestEltTy), Elt.popcount()),
12788 case Builtin::BI__builtin_elementwise_bitreverse:
12789 ResultElements.push_back(
12796 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12798 case Builtin::BI__builtin_elementwise_abs: {
12803 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12806 ResultElements.reserve(SourceLen);
12808 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12813 CurrentEle.getInt().
abs(),
12814 DestEltTy->isUnsignedIntegerOrEnumerationType()));
12815 ResultElements.push_back(Val);
12818 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12821 case Builtin::BI__builtin_elementwise_add_sat:
12822 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12823 return LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS);
12826 case Builtin::BI__builtin_elementwise_sub_sat:
12827 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12828 return LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
12831 case X86::BI__builtin_ia32_extract128i256:
12832 case X86::BI__builtin_ia32_vextractf128_pd256:
12833 case X86::BI__builtin_ia32_vextractf128_ps256:
12834 case X86::BI__builtin_ia32_vextractf128_si256: {
12835 APValue SourceVec, SourceImm;
12844 unsigned RetLen = RetVT->getNumElements();
12845 unsigned Idx = SourceImm.
getInt().getZExtValue() & 1;
12848 ResultElements.reserve(RetLen);
12850 for (
unsigned I = 0; I < RetLen; I++)
12851 ResultElements.push_back(SourceVec.
getVectorElt(Idx * RetLen + I));
12856 case clang::X86::BI__builtin_ia32_cvtmask2b128:
12857 case clang::X86::BI__builtin_ia32_cvtmask2b256:
12858 case clang::X86::BI__builtin_ia32_cvtmask2b512:
12859 case clang::X86::BI__builtin_ia32_cvtmask2w128:
12860 case clang::X86::BI__builtin_ia32_cvtmask2w256:
12861 case clang::X86::BI__builtin_ia32_cvtmask2w512:
12862 case clang::X86::BI__builtin_ia32_cvtmask2d128:
12863 case clang::X86::BI__builtin_ia32_cvtmask2d256:
12864 case clang::X86::BI__builtin_ia32_cvtmask2d512:
12865 case clang::X86::BI__builtin_ia32_cvtmask2q128:
12866 case clang::X86::BI__builtin_ia32_cvtmask2q256:
12867 case clang::X86::BI__builtin_ia32_cvtmask2q512: {
12873 QualType VecTy = E->
getType();
12874 const VectorType *VT = VecTy->
castAs<VectorType>();
12877 unsigned ElemWidth = Info.Ctx.getTypeSize(ElemTy);
12880 for (
unsigned I = 0; I != VectorLen; ++I) {
12881 bool BitSet = Mask[I];
12882 APSInt ElemVal(ElemWidth,
false);
12884 ElemVal.setAllBits();
12886 Elems.push_back(
APValue(ElemVal));
12891 case X86::BI__builtin_ia32_extracti32x4_256_mask:
12892 case X86::BI__builtin_ia32_extractf32x4_256_mask:
12893 case X86::BI__builtin_ia32_extracti32x4_mask:
12894 case X86::BI__builtin_ia32_extractf32x4_mask:
12895 case X86::BI__builtin_ia32_extracti32x8_mask:
12896 case X86::BI__builtin_ia32_extractf32x8_mask:
12897 case X86::BI__builtin_ia32_extracti64x2_256_mask:
12898 case X86::BI__builtin_ia32_extractf64x2_256_mask:
12899 case X86::BI__builtin_ia32_extracti64x2_512_mask:
12900 case X86::BI__builtin_ia32_extractf64x2_512_mask:
12901 case X86::BI__builtin_ia32_extracti64x4_mask:
12902 case X86::BI__builtin_ia32_extractf64x4_mask: {
12913 unsigned RetLen = RetVT->getNumElements();
12918 unsigned Lanes = SrcLen / RetLen;
12919 unsigned Lane =
static_cast<unsigned>(Imm.getZExtValue() % Lanes);
12920 unsigned Base = Lane * RetLen;
12923 ResultElements.reserve(RetLen);
12924 for (
unsigned I = 0; I < RetLen; ++I) {
12926 ResultElements.push_back(SourceVec.
getVectorElt(Base + I));
12930 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12933 case clang::X86::BI__builtin_ia32_pavgb128:
12934 case clang::X86::BI__builtin_ia32_pavgw128:
12935 case clang::X86::BI__builtin_ia32_pavgb256:
12936 case clang::X86::BI__builtin_ia32_pavgw256:
12937 case clang::X86::BI__builtin_ia32_pavgb512:
12938 case clang::X86::BI__builtin_ia32_pavgw512:
12939 return EvaluateBinOpExpr(llvm::APIntOps::avgCeilU);
12941 case clang::X86::BI__builtin_ia32_pmulhrsw128:
12942 case clang::X86::BI__builtin_ia32_pmulhrsw256:
12943 case clang::X86::BI__builtin_ia32_pmulhrsw512:
12944 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12945 return (llvm::APIntOps::mulsExtended(LHS, RHS).ashr(14) + 1)
12946 .extractBits(16, 1);
12949 case clang::X86::BI__builtin_ia32_psadbw128:
12950 case clang::X86::BI__builtin_ia32_psadbw256:
12951 case clang::X86::BI__builtin_ia32_psadbw512: {
12952 APValue SourceLHS, SourceRHS;
12960 assert((SourceLen % 8) == 0);
12963 QualType DestEltTy = DestTy->getElementType();
12964 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
12966 ResultElements.reserve(SourceLen / 8);
12968 for (
unsigned Lane = 0; Lane != SourceLen; Lane += 8) {
12970 for (
unsigned I = 0; I != 8; ++I) {
12973 Sum += llvm::APIntOps::abdu(LHS, RHS).zext(64);
12975 ResultElements.push_back(
APValue(
APSInt(Sum, DestUnsigned)));
12978 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12981 case clang::X86::BI__builtin_ia32_pmaddubsw128:
12982 case clang::X86::BI__builtin_ia32_pmaddubsw256:
12983 case clang::X86::BI__builtin_ia32_pmaddubsw512:
12984 case clang::X86::BI__builtin_ia32_pmaddwd128:
12985 case clang::X86::BI__builtin_ia32_pmaddwd256:
12986 case clang::X86::BI__builtin_ia32_pmaddwd512: {
12987 APValue SourceLHS, SourceRHS;
12993 QualType DestEltTy = DestTy->getElementType();
12995 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
12997 ResultElements.reserve(SourceLen / 2);
12999 for (
unsigned EltNum = 0; EltNum < SourceLen; EltNum += 2) {
13004 unsigned BitWidth = 2 * LoLHS.getBitWidth();
13006 switch (BuiltinOp) {
13007 case clang::X86::BI__builtin_ia32_pmaddubsw128:
13008 case clang::X86::BI__builtin_ia32_pmaddubsw256:
13009 case clang::X86::BI__builtin_ia32_pmaddubsw512:
13010 ResultElements.push_back(
APValue(
13011 APSInt((LoLHS.zext(BitWidth) * LoRHS.sext(BitWidth))
13012 .sadd_sat((HiLHS.zext(BitWidth) * HiRHS.sext(BitWidth))),
13015 case clang::X86::BI__builtin_ia32_pmaddwd128:
13016 case clang::X86::BI__builtin_ia32_pmaddwd256:
13017 case clang::X86::BI__builtin_ia32_pmaddwd512:
13018 ResultElements.push_back(
13019 APValue(
APSInt((LoLHS.sext(BitWidth) * LoRHS.sext(BitWidth)) +
13020 (HiLHS.sext(BitWidth) * HiRHS.sext(BitWidth)),
13026 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13029 case clang::X86::BI__builtin_ia32_bmacor16x16x16_v16hi:
13030 case clang::X86::BI__builtin_ia32_bmacor16x16x16_v32hi:
13031 case clang::X86::BI__builtin_ia32_bmacxor16x16x16_v16hi:
13032 case clang::X86::BI__builtin_ia32_bmacxor16x16x16_v32hi: {
13043 APValue SourceA, SourceB, SourceC;
13050 clang::X86::BI__builtin_ia32_bmacxor16x16x16_v16hi ||
13052 clang::X86::BI__builtin_ia32_bmacxor16x16x16_v32hi;
13055 assert(SourceLen % 16 == 0 &&
"BMM operates on 256-bit lanes of 16 x i16");
13057 QualType DestEltTy = DestTy->getElementType();
13058 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
13061 for (
unsigned Lane = 0; Lane != SourceLen; Lane += 16) {
13062 for (
unsigned I = 0; I != 16; ++I) {
13067 for (
unsigned J = 0; J != 16; ++J) {
13071 unsigned Bit = (Dst >> J) & 1u;
13072 for (
unsigned K = 0; K != 16; ++K) {
13076 unsigned Product = ((A >> K) & 1u) & ((B >> J) & 1u);
13077 Bit = IsXor ? (Bit ^ Product) : (Bit | Product);
13081 ResultElements[Lane + I] =
13085 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13088 case clang::X86::BI__builtin_ia32_dbpsadbw128:
13089 case clang::X86::BI__builtin_ia32_dbpsadbw256:
13090 case clang::X86::BI__builtin_ia32_dbpsadbw512: {
13091 APValue SourceA, SourceB, SourceImm;
13098 constexpr unsigned LaneSize = 16;
13099 unsigned Imm = SourceImm.
getInt().getZExtValue();
13102 QualType DestEltTy = DestTy->getElementType();
13103 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
13105 ResultElements.reserve(SourceLen / 2);
13111 for (
unsigned I = 0; I < SourceLen; I += LaneSize) {
13112 for (
unsigned J = 0; J < 4; ++J) {
13113 unsigned Part = (Imm >> (2 * J)) & 3;
13114 for (
unsigned K = 0; K < 4; ++K) {
13115 Shuffled[I + 4 * J + K] =
static_cast<uint8_t>(
13116 SourceB.
getVectorElt(I + 4 * Part + K).getInt().getZExtValue());
13124 unsigned Size = SourceLen / 2;
13125 for (
unsigned I = 0; I <
Size; I += 4) {
13126 unsigned Sad[4] = {0, 0, 0, 0};
13127 for (
unsigned J = 0; J < 4; ++J) {
13129 SourceA.
getVectorElt(2 * I + J).getInt().getZExtValue());
13131 SourceA.
getVectorElt(2 * I + J + 4).getInt().getZExtValue());
13132 uint8_t B0 = Shuffled[2 * I + J];
13133 uint8_t B1 = Shuffled[2 * I + J + 1];
13134 uint8_t B2 = Shuffled[2 * I + J + 2];
13135 uint8_t B3 = Shuffled[2 * I + J + 3];
13136 Sad[0] += (A1 > B0) ? (A1 - B0) : (B0 - A1);
13137 Sad[1] += (A1 > B1) ? (A1 - B1) : (B1 - A1);
13138 Sad[2] += (A2 > B2) ? (A2 - B2) : (B2 - A2);
13139 Sad[3] += (A2 > B3) ? (A2 - B3) : (B3 - A2);
13141 for (
unsigned R = 0;
R < 4; ++
R)
13142 ResultElements.push_back(
13146 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13149 case clang::X86::BI__builtin_ia32_mpsadbw128:
13150 case clang::X86::BI__builtin_ia32_mpsadbw256: {
13158 constexpr unsigned LaneSize = 16;
13159 assert((SourceLen == LaneSize || SourceLen == 2 * LaneSize) &&
13160 "MPSADBW operates on 128-bit or 256-bit vectors");
13161 unsigned NumLanes = SourceLen / LaneSize;
13162 unsigned Imm = SourceImm.getZExtValue();
13164 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13167 ResultElements.reserve(SourceLen / 2);
13169 for (
unsigned Lane = 0; Lane != NumLanes; ++Lane) {
13170 unsigned Ctrl = (Imm >> (3 * Lane)) & 0x7;
13171 unsigned AOff = ((Ctrl >> 2) & 1) * 4;
13172 unsigned BOff = (Ctrl & 3) * 4;
13173 for (
unsigned J = 0; J != 8; ++J) {
13175 for (
unsigned K = 0; K != 4; ++K) {
13184 Sad += (A > B) ? (A - B) : (B - A);
13189 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13192 case clang::X86::BI__builtin_ia32_pmulhuw128:
13193 case clang::X86::BI__builtin_ia32_pmulhuw256:
13194 case clang::X86::BI__builtin_ia32_pmulhuw512:
13195 return EvaluateBinOpExpr(llvm::APIntOps::mulhu);
13197 case clang::X86::BI__builtin_ia32_pmulhw128:
13198 case clang::X86::BI__builtin_ia32_pmulhw256:
13199 case clang::X86::BI__builtin_ia32_pmulhw512:
13200 return EvaluateBinOpExpr(llvm::APIntOps::mulhs);
13202 case clang::X86::BI__builtin_ia32_psllv2di:
13203 case clang::X86::BI__builtin_ia32_psllv4di:
13204 case clang::X86::BI__builtin_ia32_psllv4si:
13205 case clang::X86::BI__builtin_ia32_psllv8di:
13206 case clang::X86::BI__builtin_ia32_psllv8hi:
13207 case clang::X86::BI__builtin_ia32_psllv8si:
13208 case clang::X86::BI__builtin_ia32_psllv16hi:
13209 case clang::X86::BI__builtin_ia32_psllv16si:
13210 case clang::X86::BI__builtin_ia32_psllv32hi:
13211 case clang::X86::BI__builtin_ia32_psllwi128:
13212 case clang::X86::BI__builtin_ia32_pslldi128:
13213 case clang::X86::BI__builtin_ia32_psllqi128:
13214 case clang::X86::BI__builtin_ia32_psllwi256:
13215 case clang::X86::BI__builtin_ia32_pslldi256:
13216 case clang::X86::BI__builtin_ia32_psllqi256:
13217 case clang::X86::BI__builtin_ia32_psllwi512:
13218 case clang::X86::BI__builtin_ia32_pslldi512:
13219 case clang::X86::BI__builtin_ia32_psllqi512:
13220 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
13221 if (RHS.uge(LHS.getBitWidth())) {
13222 return APInt::getZero(LHS.getBitWidth());
13224 return LHS.shl(RHS.getZExtValue());
13227 case clang::X86::BI__builtin_ia32_psrav4si:
13228 case clang::X86::BI__builtin_ia32_psrav8di:
13229 case clang::X86::BI__builtin_ia32_psrav8hi:
13230 case clang::X86::BI__builtin_ia32_psrav8si:
13231 case clang::X86::BI__builtin_ia32_psrav16hi:
13232 case clang::X86::BI__builtin_ia32_psrav16si:
13233 case clang::X86::BI__builtin_ia32_psrav32hi:
13234 case clang::X86::BI__builtin_ia32_psravq128:
13235 case clang::X86::BI__builtin_ia32_psravq256:
13236 case clang::X86::BI__builtin_ia32_psrawi128:
13237 case clang::X86::BI__builtin_ia32_psradi128:
13238 case clang::X86::BI__builtin_ia32_psraqi128:
13239 case clang::X86::BI__builtin_ia32_psrawi256:
13240 case clang::X86::BI__builtin_ia32_psradi256:
13241 case clang::X86::BI__builtin_ia32_psraqi256:
13242 case clang::X86::BI__builtin_ia32_psrawi512:
13243 case clang::X86::BI__builtin_ia32_psradi512:
13244 case clang::X86::BI__builtin_ia32_psraqi512:
13245 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
13246 if (RHS.uge(LHS.getBitWidth())) {
13247 return LHS.ashr(LHS.getBitWidth() - 1);
13249 return LHS.ashr(RHS.getZExtValue());
13252 case clang::X86::BI__builtin_ia32_psrlv2di:
13253 case clang::X86::BI__builtin_ia32_psrlv4di:
13254 case clang::X86::BI__builtin_ia32_psrlv4si:
13255 case clang::X86::BI__builtin_ia32_psrlv8di:
13256 case clang::X86::BI__builtin_ia32_psrlv8hi:
13257 case clang::X86::BI__builtin_ia32_psrlv8si:
13258 case clang::X86::BI__builtin_ia32_psrlv16hi:
13259 case clang::X86::BI__builtin_ia32_psrlv16si:
13260 case clang::X86::BI__builtin_ia32_psrlv32hi:
13261 case clang::X86::BI__builtin_ia32_psrlwi128:
13262 case clang::X86::BI__builtin_ia32_psrldi128:
13263 case clang::X86::BI__builtin_ia32_psrlqi128:
13264 case clang::X86::BI__builtin_ia32_psrlwi256:
13265 case clang::X86::BI__builtin_ia32_psrldi256:
13266 case clang::X86::BI__builtin_ia32_psrlqi256:
13267 case clang::X86::BI__builtin_ia32_psrlwi512:
13268 case clang::X86::BI__builtin_ia32_psrldi512:
13269 case clang::X86::BI__builtin_ia32_psrlqi512:
13270 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
13271 if (RHS.uge(LHS.getBitWidth())) {
13272 return APInt::getZero(LHS.getBitWidth());
13274 return LHS.lshr(RHS.getZExtValue());
13276 case X86::BI__builtin_ia32_packsswb128:
13277 case X86::BI__builtin_ia32_packsswb256:
13278 case X86::BI__builtin_ia32_packsswb512:
13279 case X86::BI__builtin_ia32_packssdw128:
13280 case X86::BI__builtin_ia32_packssdw256:
13281 case X86::BI__builtin_ia32_packssdw512:
13283 return APSInt(Src).truncSSat(Src.getBitWidth() / 2);
13285 case X86::BI__builtin_ia32_packusdw128:
13286 case X86::BI__builtin_ia32_packusdw256:
13287 case X86::BI__builtin_ia32_packusdw512:
13288 case X86::BI__builtin_ia32_packuswb128:
13289 case X86::BI__builtin_ia32_packuswb256:
13290 case X86::BI__builtin_ia32_packuswb512:
13292 return APSInt(Src).truncSSatU(Src.getBitWidth() / 2);
13294 case clang::X86::BI__builtin_ia32_selectss_128:
13295 return EvalSelectScalar(4);
13296 case clang::X86::BI__builtin_ia32_selectsd_128:
13297 return EvalSelectScalar(2);
13298 case clang::X86::BI__builtin_ia32_selectsh_128:
13299 case clang::X86::BI__builtin_ia32_selectsbf_128:
13300 return EvalSelectScalar(8);
13301 case clang::X86::BI__builtin_ia32_pmuldq128:
13302 case clang::X86::BI__builtin_ia32_pmuldq256:
13303 case clang::X86::BI__builtin_ia32_pmuldq512:
13304 case clang::X86::BI__builtin_ia32_pmuludq128:
13305 case clang::X86::BI__builtin_ia32_pmuludq256:
13306 case clang::X86::BI__builtin_ia32_pmuludq512: {
13307 APValue SourceLHS, SourceRHS;
13314 ResultElements.reserve(SourceLen / 2);
13316 for (
unsigned EltNum = 0; EltNum < SourceLen; EltNum += 2) {
13320 switch (BuiltinOp) {
13321 case clang::X86::BI__builtin_ia32_pmuludq128:
13322 case clang::X86::BI__builtin_ia32_pmuludq256:
13323 case clang::X86::BI__builtin_ia32_pmuludq512:
13324 ResultElements.push_back(
13325 APValue(
APSInt(llvm::APIntOps::muluExtended(LHS, RHS),
true)));
13327 case clang::X86::BI__builtin_ia32_pmuldq128:
13328 case clang::X86::BI__builtin_ia32_pmuldq256:
13329 case clang::X86::BI__builtin_ia32_pmuldq512:
13330 ResultElements.push_back(
13331 APValue(
APSInt(llvm::APIntOps::mulsExtended(LHS, RHS),
false)));
13336 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13339 case X86::BI__builtin_ia32_vpmadd52luq128:
13340 case X86::BI__builtin_ia32_vpmadd52luq256:
13341 case X86::BI__builtin_ia32_vpmadd52luq512: {
13350 ResultElements.reserve(ALen);
13352 for (
unsigned EltNum = 0; EltNum < ALen; EltNum += 1) {
13355 APInt CElt =
C.getVectorElt(EltNum).getInt().trunc(52);
13356 APSInt ResElt(AElt + (BElt * CElt).zext(64),
false);
13357 ResultElements.push_back(
APValue(ResElt));
13360 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13362 case X86::BI__builtin_ia32_vpmadd52huq128:
13363 case X86::BI__builtin_ia32_vpmadd52huq256:
13364 case X86::BI__builtin_ia32_vpmadd52huq512: {
13373 ResultElements.reserve(ALen);
13375 for (
unsigned EltNum = 0; EltNum < ALen; EltNum += 1) {
13378 APInt CElt =
C.getVectorElt(EltNum).getInt().trunc(52);
13379 APSInt ResElt(AElt + llvm::APIntOps::mulhu(BElt, CElt).zext(64),
false);
13380 ResultElements.push_back(
APValue(ResElt));
13383 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13386 case clang::X86::BI__builtin_ia32_vprotbi:
13387 case clang::X86::BI__builtin_ia32_vprotdi:
13388 case clang::X86::BI__builtin_ia32_vprotqi:
13389 case clang::X86::BI__builtin_ia32_vprotwi:
13390 case clang::X86::BI__builtin_ia32_prold128:
13391 case clang::X86::BI__builtin_ia32_prold256:
13392 case clang::X86::BI__builtin_ia32_prold512:
13393 case clang::X86::BI__builtin_ia32_prolq128:
13394 case clang::X86::BI__builtin_ia32_prolq256:
13395 case clang::X86::BI__builtin_ia32_prolq512:
13396 return EvaluateBinOpExpr(
13397 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS.rotl(RHS); });
13399 case clang::X86::BI__builtin_ia32_prord128:
13400 case clang::X86::BI__builtin_ia32_prord256:
13401 case clang::X86::BI__builtin_ia32_prord512:
13402 case clang::X86::BI__builtin_ia32_prorq128:
13403 case clang::X86::BI__builtin_ia32_prorq256:
13404 case clang::X86::BI__builtin_ia32_prorq512:
13405 return EvaluateBinOpExpr(
13406 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS.rotr(RHS); });
13408 case Builtin::BI__builtin_elementwise_max:
13409 case Builtin::BI__builtin_elementwise_min: {
13410 APValue SourceLHS, SourceRHS;
13415 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13422 ResultElements.reserve(SourceLen);
13424 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13427 switch (BuiltinOp) {
13428 case Builtin::BI__builtin_elementwise_max:
13429 ResultElements.push_back(
13433 case Builtin::BI__builtin_elementwise_min:
13434 ResultElements.push_back(
13441 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13443 case X86::BI__builtin_ia32_vpshldd128:
13444 case X86::BI__builtin_ia32_vpshldd256:
13445 case X86::BI__builtin_ia32_vpshldd512:
13446 case X86::BI__builtin_ia32_vpshldq128:
13447 case X86::BI__builtin_ia32_vpshldq256:
13448 case X86::BI__builtin_ia32_vpshldq512:
13449 case X86::BI__builtin_ia32_vpshldw128:
13450 case X86::BI__builtin_ia32_vpshldw256:
13451 case X86::BI__builtin_ia32_vpshldw512: {
13452 APValue SourceHi, SourceLo, SourceAmt;
13458 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13461 ResultElements.reserve(SourceLen);
13464 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13467 APInt R = llvm::APIntOps::fshl(Hi, Lo, Amt);
13468 ResultElements.push_back(
13472 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13474 case X86::BI__builtin_ia32_vpshrdd128:
13475 case X86::BI__builtin_ia32_vpshrdd256:
13476 case X86::BI__builtin_ia32_vpshrdd512:
13477 case X86::BI__builtin_ia32_vpshrdq128:
13478 case X86::BI__builtin_ia32_vpshrdq256:
13479 case X86::BI__builtin_ia32_vpshrdq512:
13480 case X86::BI__builtin_ia32_vpshrdw128:
13481 case X86::BI__builtin_ia32_vpshrdw256:
13482 case X86::BI__builtin_ia32_vpshrdw512: {
13484 APValue SourceHi, SourceLo, SourceAmt;
13490 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13493 ResultElements.reserve(SourceLen);
13496 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13499 APInt R = llvm::APIntOps::fshr(Hi, Lo, Amt);
13500 ResultElements.push_back(
13504 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13506 case X86::BI__builtin_ia32_compressdf128_mask:
13507 case X86::BI__builtin_ia32_compressdf256_mask:
13508 case X86::BI__builtin_ia32_compressdf512_mask:
13509 case X86::BI__builtin_ia32_compressdi128_mask:
13510 case X86::BI__builtin_ia32_compressdi256_mask:
13511 case X86::BI__builtin_ia32_compressdi512_mask:
13512 case X86::BI__builtin_ia32_compresshi128_mask:
13513 case X86::BI__builtin_ia32_compresshi256_mask:
13514 case X86::BI__builtin_ia32_compresshi512_mask:
13515 case X86::BI__builtin_ia32_compressqi128_mask:
13516 case X86::BI__builtin_ia32_compressqi256_mask:
13517 case X86::BI__builtin_ia32_compressqi512_mask:
13518 case X86::BI__builtin_ia32_compresssf128_mask:
13519 case X86::BI__builtin_ia32_compresssf256_mask:
13520 case X86::BI__builtin_ia32_compresssf512_mask:
13521 case X86::BI__builtin_ia32_compresssi128_mask:
13522 case X86::BI__builtin_ia32_compresssi256_mask:
13523 case X86::BI__builtin_ia32_compresssi512_mask: {
13534 ResultElements.reserve(NumElts);
13536 for (
unsigned I = 0; I != NumElts; ++I) {
13540 for (
unsigned I = ResultElements.size(); I != NumElts; ++I) {
13544 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13546 case X86::BI__builtin_ia32_expanddf128_mask:
13547 case X86::BI__builtin_ia32_expanddf256_mask:
13548 case X86::BI__builtin_ia32_expanddf512_mask:
13549 case X86::BI__builtin_ia32_expanddi128_mask:
13550 case X86::BI__builtin_ia32_expanddi256_mask:
13551 case X86::BI__builtin_ia32_expanddi512_mask:
13552 case X86::BI__builtin_ia32_expandhi128_mask:
13553 case X86::BI__builtin_ia32_expandhi256_mask:
13554 case X86::BI__builtin_ia32_expandhi512_mask:
13555 case X86::BI__builtin_ia32_expandqi128_mask:
13556 case X86::BI__builtin_ia32_expandqi256_mask:
13557 case X86::BI__builtin_ia32_expandqi512_mask:
13558 case X86::BI__builtin_ia32_expandsf128_mask:
13559 case X86::BI__builtin_ia32_expandsf256_mask:
13560 case X86::BI__builtin_ia32_expandsf512_mask:
13561 case X86::BI__builtin_ia32_expandsi128_mask:
13562 case X86::BI__builtin_ia32_expandsi256_mask:
13563 case X86::BI__builtin_ia32_expandsi512_mask: {
13574 ResultElements.reserve(NumElts);
13576 unsigned SourceIdx = 0;
13577 for (
unsigned I = 0; I != NumElts; ++I) {
13579 ResultElements.push_back(Source.
getVectorElt(SourceIdx++));
13583 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13585 case X86::BI__builtin_ia32_vpconflictsi_128:
13586 case X86::BI__builtin_ia32_vpconflictsi_256:
13587 case X86::BI__builtin_ia32_vpconflictsi_512:
13588 case X86::BI__builtin_ia32_vpconflictdi_128:
13589 case X86::BI__builtin_ia32_vpconflictdi_256:
13590 case X86::BI__builtin_ia32_vpconflictdi_512: {
13598 ResultElements.reserve(SourceLen);
13601 bool DestUnsigned =
13602 VecT->getElementType()->isUnsignedIntegerOrEnumerationType();
13604 for (
unsigned I = 0; I != SourceLen; ++I) {
13607 APInt ConflictMask(EltI.
getInt().getBitWidth(), 0);
13608 for (
unsigned J = 0; J != I; ++J) {
13610 ConflictMask.setBitVal(J, EltI.
getInt() == EltJ.
getInt());
13612 ResultElements.push_back(
APValue(
APSInt(ConflictMask, DestUnsigned)));
13614 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13616 case X86::BI__builtin_ia32_blendpd:
13617 case X86::BI__builtin_ia32_blendpd256:
13618 case X86::BI__builtin_ia32_blendps:
13619 case X86::BI__builtin_ia32_blendps256:
13620 case X86::BI__builtin_ia32_pblendw128:
13621 case X86::BI__builtin_ia32_pblendw256:
13622 case X86::BI__builtin_ia32_pblendd128:
13623 case X86::BI__builtin_ia32_pblendd256: {
13624 APValue SourceF, SourceT, SourceC;
13633 ResultElements.reserve(SourceLen);
13634 for (
unsigned EltNum = 0; EltNum != SourceLen; ++EltNum) {
13637 ResultElements.push_back(
C[EltNum % 8] ?
T : F);
13640 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13643 case X86::BI__builtin_ia32_psignb128:
13644 case X86::BI__builtin_ia32_psignb256:
13645 case X86::BI__builtin_ia32_psignw128:
13646 case X86::BI__builtin_ia32_psignw256:
13647 case X86::BI__builtin_ia32_psignd128:
13648 case X86::BI__builtin_ia32_psignd256:
13649 return EvaluateBinOpExpr([](
const APInt &AElem,
const APInt &BElem) {
13650 if (BElem.isZero())
13651 return APInt::getZero(AElem.getBitWidth());
13652 if (BElem.isNegative())
13657 case X86::BI__builtin_ia32_blendvpd:
13658 case X86::BI__builtin_ia32_blendvpd256:
13659 case X86::BI__builtin_ia32_blendvps:
13660 case X86::BI__builtin_ia32_blendvps256:
13661 case X86::BI__builtin_ia32_pblendvb128:
13662 case X86::BI__builtin_ia32_pblendvb256: {
13664 APValue SourceF, SourceT, SourceC;
13672 ResultElements.reserve(SourceLen);
13674 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13678 APInt M =
C.isInt() ? (
APInt)
C.getInt() :
C.getFloat().bitcastToAPInt();
13679 ResultElements.push_back(M.isNegative() ?
T : F);
13682 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13684 case X86::BI__builtin_ia32_selectb_128:
13685 case X86::BI__builtin_ia32_selectb_256:
13686 case X86::BI__builtin_ia32_selectb_512:
13687 case X86::BI__builtin_ia32_selectw_128:
13688 case X86::BI__builtin_ia32_selectw_256:
13689 case X86::BI__builtin_ia32_selectw_512:
13690 case X86::BI__builtin_ia32_selectd_128:
13691 case X86::BI__builtin_ia32_selectd_256:
13692 case X86::BI__builtin_ia32_selectd_512:
13693 case X86::BI__builtin_ia32_selectq_128:
13694 case X86::BI__builtin_ia32_selectq_256:
13695 case X86::BI__builtin_ia32_selectq_512:
13696 case X86::BI__builtin_ia32_selectph_128:
13697 case X86::BI__builtin_ia32_selectph_256:
13698 case X86::BI__builtin_ia32_selectph_512:
13699 case X86::BI__builtin_ia32_selectpbf_128:
13700 case X86::BI__builtin_ia32_selectpbf_256:
13701 case X86::BI__builtin_ia32_selectpbf_512:
13702 case X86::BI__builtin_ia32_selectps_128:
13703 case X86::BI__builtin_ia32_selectps_256:
13704 case X86::BI__builtin_ia32_selectps_512:
13705 case X86::BI__builtin_ia32_selectpd_128:
13706 case X86::BI__builtin_ia32_selectpd_256:
13707 case X86::BI__builtin_ia32_selectpd_512: {
13709 APValue SourceMask, SourceLHS, SourceRHS;
13718 ResultElements.reserve(SourceLen);
13720 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13723 ResultElements.push_back(Mask[EltNum] ? LHS : RHS);
13726 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13729 case X86::BI__builtin_ia32_cvtsd2ss: {
13742 Elements.push_back(ResultVal);
13745 for (
unsigned I = 1; I < NumEltsA; ++I) {
13751 case X86::BI__builtin_ia32_cvtsd2ss_round_mask: {
13752 APValue VecA, VecB, VecSrc, MaskValue;
13760 unsigned Mask = MaskValue.
getInt().getZExtValue();
13768 Elements.push_back(ResultVal);
13774 for (
unsigned I = 1; I < NumEltsA; ++I) {
13780 case X86::BI__builtin_ia32_cvtpd2ps:
13781 case X86::BI__builtin_ia32_cvtpd2ps256:
13782 case X86::BI__builtin_ia32_cvtpd2ps_mask:
13783 case X86::BI__builtin_ia32_cvtpd2ps512_mask: {
13785 const auto BuiltinID = BuiltinOp;
13786 bool IsMasked = (BuiltinID == X86::BI__builtin_ia32_cvtpd2ps_mask ||
13787 BuiltinID == X86::BI__builtin_ia32_cvtpd2ps512_mask);
13794 unsigned Mask = 0xFFFFFFFF;
13795 bool NeedsMerge =
false;
13800 Mask = MaskValue.
getInt().getZExtValue();
13801 auto NumEltsResult = E->
getType()->
getAs<VectorType>()->getNumElements();
13802 for (
unsigned I = 0; I < NumEltsResult; ++I) {
13803 if (!((Mask >> I) & 1)) {
13814 unsigned NumEltsResult =
13818 for (
unsigned I = 0; I < NumEltsResult; ++I) {
13819 if (IsMasked && !((Mask >> I) & 1)) {
13827 if (I >= NumEltsInput) {
13828 Elements.push_back(
APValue(APFloat::getZero(APFloat::IEEEsingle())));
13837 Elements.push_back(ResultVal);
13842 case X86::BI__builtin_ia32_shufps:
13843 case X86::BI__builtin_ia32_shufps256:
13844 case X86::BI__builtin_ia32_shufps512: {
13848 [](
unsigned DstIdx,
13849 unsigned ShuffleMask) -> std::pair<unsigned, int> {
13850 constexpr unsigned LaneBits = 128u;
13851 unsigned NumElemPerLane = LaneBits / 32;
13852 unsigned NumSelectableElems = NumElemPerLane / 2;
13853 unsigned BitsPerElem = 2;
13854 unsigned IndexMask = (1u << BitsPerElem) - 1;
13855 unsigned MaskBits = 8;
13856 unsigned Lane = DstIdx / NumElemPerLane;
13857 unsigned ElemInLane = DstIdx % NumElemPerLane;
13858 unsigned LaneOffset = Lane * NumElemPerLane;
13859 unsigned BitIndex = (DstIdx * BitsPerElem) % MaskBits;
13860 unsigned SrcIdx = (ElemInLane < NumSelectableElems) ? 0 : 1;
13861 unsigned Index = (ShuffleMask >> BitIndex) & IndexMask;
13862 return {SrcIdx,
static_cast<int>(LaneOffset + Index)};
13867 case X86::BI__builtin_ia32_shufpd:
13868 case X86::BI__builtin_ia32_shufpd256:
13869 case X86::BI__builtin_ia32_shufpd512: {
13873 [](
unsigned DstIdx,
13874 unsigned ShuffleMask) -> std::pair<unsigned, int> {
13875 constexpr unsigned LaneBits = 128u;
13876 unsigned NumElemPerLane = LaneBits / 64;
13877 unsigned NumSelectableElems = NumElemPerLane / 2;
13878 unsigned BitsPerElem = 1;
13879 unsigned IndexMask = (1u << BitsPerElem) - 1;
13880 unsigned MaskBits = 8;
13881 unsigned Lane = DstIdx / NumElemPerLane;
13882 unsigned ElemInLane = DstIdx % NumElemPerLane;
13883 unsigned LaneOffset = Lane * NumElemPerLane;
13884 unsigned BitIndex = (DstIdx * BitsPerElem) % MaskBits;
13885 unsigned SrcIdx = (ElemInLane < NumSelectableElems) ? 0 : 1;
13886 unsigned Index = (ShuffleMask >> BitIndex) & IndexMask;
13887 return {SrcIdx,
static_cast<int>(LaneOffset + Index)};
13892 case X86::BI__builtin_ia32_insertps128: {
13896 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13898 if ((Mask & (1 << DstIdx)) != 0) {
13903 unsigned SrcElem = (Mask >> 6) & 0x3;
13904 unsigned DstElem = (Mask >> 4) & 0x3;
13905 if (DstIdx == DstElem) {
13907 return {1,
static_cast<int>(SrcElem)};
13910 return {0,
static_cast<int>(DstIdx)};
13916 case X86::BI__builtin_ia32_pshufb128:
13917 case X86::BI__builtin_ia32_pshufb256:
13918 case X86::BI__builtin_ia32_pshufb512: {
13922 [](
unsigned DstIdx,
13923 unsigned ShuffleMask) -> std::pair<unsigned, int> {
13926 return std::make_pair(0, -1);
13928 unsigned LaneBase = (DstIdx / 16) * 16;
13929 unsigned SrcOffset = Ctlb & 0x0F;
13930 unsigned SrcIdx = LaneBase + SrcOffset;
13931 return std::make_pair(0,
static_cast<int>(SrcIdx));
13937 case X86::BI__builtin_ia32_pshuflw:
13938 case X86::BI__builtin_ia32_pshuflw256:
13939 case X86::BI__builtin_ia32_pshuflw512: {
13943 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13944 constexpr unsigned LaneBits = 128u;
13945 constexpr unsigned ElemBits = 16u;
13946 constexpr unsigned LaneElts = LaneBits / ElemBits;
13947 constexpr unsigned HalfSize = 4;
13948 unsigned LaneBase = (DstIdx / LaneElts) * LaneElts;
13949 unsigned LaneIdx = DstIdx % LaneElts;
13950 if (LaneIdx < HalfSize) {
13951 unsigned Sel = (Mask >> (2 * LaneIdx)) & 0x3;
13952 return std::make_pair(0,
static_cast<int>(LaneBase + Sel));
13954 return std::make_pair(0,
static_cast<int>(DstIdx));
13960 case X86::BI__builtin_ia32_pshufhw:
13961 case X86::BI__builtin_ia32_pshufhw256:
13962 case X86::BI__builtin_ia32_pshufhw512: {
13966 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13967 constexpr unsigned LaneBits = 128u;
13968 constexpr unsigned ElemBits = 16u;
13969 constexpr unsigned LaneElts = LaneBits / ElemBits;
13970 constexpr unsigned HalfSize = 4;
13971 unsigned LaneBase = (DstIdx / LaneElts) * LaneElts;
13972 unsigned LaneIdx = DstIdx % LaneElts;
13973 if (LaneIdx >= HalfSize) {
13974 unsigned Rel = LaneIdx - HalfSize;
13975 unsigned Sel = (Mask >> (2 * Rel)) & 0x3;
13976 return std::make_pair(
13977 0,
static_cast<int>(LaneBase + HalfSize + Sel));
13979 return std::make_pair(0,
static_cast<int>(DstIdx));
13985 case X86::BI__builtin_ia32_pshufd:
13986 case X86::BI__builtin_ia32_pshufd256:
13987 case X86::BI__builtin_ia32_pshufd512:
13988 case X86::BI__builtin_ia32_vpermilps:
13989 case X86::BI__builtin_ia32_vpermilps256:
13990 case X86::BI__builtin_ia32_vpermilps512: {
13994 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13995 constexpr unsigned LaneBits = 128u;
13996 constexpr unsigned ElemBits = 32u;
13997 constexpr unsigned LaneElts = LaneBits / ElemBits;
13998 unsigned LaneBase = (DstIdx / LaneElts) * LaneElts;
13999 unsigned LaneIdx = DstIdx % LaneElts;
14000 unsigned Sel = (Mask >> (2 * LaneIdx)) & 0x3;
14001 return std::make_pair(0,
static_cast<int>(LaneBase + Sel));
14007 case X86::BI__builtin_ia32_vpermilvarpd:
14008 case X86::BI__builtin_ia32_vpermilvarpd256:
14009 case X86::BI__builtin_ia32_vpermilvarpd512: {
14013 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
14014 unsigned NumElemPerLane = 2;
14015 unsigned Lane = DstIdx / NumElemPerLane;
14016 unsigned Offset = Mask & 0b10 ? 1 : 0;
14017 return std::make_pair(
14018 0,
static_cast<int>(Lane * NumElemPerLane + Offset));
14024 case X86::BI__builtin_ia32_vpermilpd:
14025 case X86::BI__builtin_ia32_vpermilpd256:
14026 case X86::BI__builtin_ia32_vpermilpd512: {
14029 unsigned NumElemPerLane = 2;
14030 unsigned BitsPerElem = 1;
14031 unsigned MaskBits = 8;
14032 unsigned IndexMask = 0x1;
14033 unsigned Lane = DstIdx / NumElemPerLane;
14034 unsigned LaneOffset = Lane * NumElemPerLane;
14035 unsigned BitIndex = (DstIdx * BitsPerElem) % MaskBits;
14036 unsigned Index = (Control >> BitIndex) & IndexMask;
14037 return std::make_pair(0,
static_cast<int>(LaneOffset + Index));
14043 case X86::BI__builtin_ia32_permdf256:
14044 case X86::BI__builtin_ia32_permdi256: {
14049 unsigned Index = (Control >> (2 * DstIdx)) & 0x3;
14050 return std::make_pair(0,
static_cast<int>(Index));
14056 case X86::BI__builtin_ia32_vpermilvarps:
14057 case X86::BI__builtin_ia32_vpermilvarps256:
14058 case X86::BI__builtin_ia32_vpermilvarps512: {
14062 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
14063 unsigned NumElemPerLane = 4;
14064 unsigned Lane = DstIdx / NumElemPerLane;
14065 unsigned Offset = Mask & 0b11;
14066 return std::make_pair(
14067 0,
static_cast<int>(Lane * NumElemPerLane + Offset));
14073 case X86::BI__builtin_ia32_vpmultishiftqb128:
14074 case X86::BI__builtin_ia32_vpmultishiftqb256:
14075 case X86::BI__builtin_ia32_vpmultishiftqb512: {
14083 unsigned NumBytesInQWord = 8;
14084 unsigned NumBitsInByte = 8;
14086 unsigned NumQWords = NumBytes / NumBytesInQWord;
14088 Result.reserve(NumBytes);
14090 for (
unsigned QWordId = 0; QWordId != NumQWords; ++QWordId) {
14091 APInt BQWord(64, 0);
14092 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
14093 unsigned Idx = QWordId * NumBytesInQWord + ByteIdx;
14095 BQWord.insertBits(
APInt(8, Byte & 0xFF), ByteIdx * NumBitsInByte);
14098 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
14099 unsigned Idx = QWordId * NumBytesInQWord + ByteIdx;
14103 for (
unsigned BitIdx = 0; BitIdx != NumBitsInByte; ++BitIdx) {
14104 Byte.setBitVal(BitIdx, BQWord[(Ctrl + BitIdx) & 0x3F]);
14112 case X86::BI__builtin_ia32_phminposuw128: {
14119 unsigned ElemBitWidth = Info.Ctx.getTypeSize(ElemQT);
14121 APInt MinIndex(ElemBitWidth, 0);
14123 for (
unsigned I = 1; I != SourceLen; ++I) {
14125 if (MinVal.ugt(Val)) {
14134 ->isUnsignedIntegerOrEnumerationType();
14137 Result.reserve(SourceLen);
14139 Result.emplace_back(
APSInt(MinIndex, ResultUnsigned));
14140 for (
unsigned I = 0; I != SourceLen - 2; ++I) {
14146 case X86::BI__builtin_ia32_psraq128:
14147 case X86::BI__builtin_ia32_psraq256:
14148 case X86::BI__builtin_ia32_psraq512:
14149 case X86::BI__builtin_ia32_psrad128:
14150 case X86::BI__builtin_ia32_psrad256:
14151 case X86::BI__builtin_ia32_psrad512:
14152 case X86::BI__builtin_ia32_psraw128:
14153 case X86::BI__builtin_ia32_psraw256:
14154 case X86::BI__builtin_ia32_psraw512: {
14158 [](
const APInt &Elt, uint64_t Count) {
return Elt.ashr(Count); },
14159 [](
const APInt &Elt,
unsigned Width) {
14160 return Elt.ashr(Width - 1);
14166 case X86::BI__builtin_ia32_psllq128:
14167 case X86::BI__builtin_ia32_psllq256:
14168 case X86::BI__builtin_ia32_psllq512:
14169 case X86::BI__builtin_ia32_pslld128:
14170 case X86::BI__builtin_ia32_pslld256:
14171 case X86::BI__builtin_ia32_pslld512:
14172 case X86::BI__builtin_ia32_psllw128:
14173 case X86::BI__builtin_ia32_psllw256:
14174 case X86::BI__builtin_ia32_psllw512: {
14178 [](
const APInt &Elt, uint64_t Count) {
return Elt.shl(Count); },
14179 [](
const APInt &Elt,
unsigned Width) {
14180 return APInt::getZero(Width);
14186 case X86::BI__builtin_ia32_psrlq128:
14187 case X86::BI__builtin_ia32_psrlq256:
14188 case X86::BI__builtin_ia32_psrlq512:
14189 case X86::BI__builtin_ia32_psrld128:
14190 case X86::BI__builtin_ia32_psrld256:
14191 case X86::BI__builtin_ia32_psrld512:
14192 case X86::BI__builtin_ia32_psrlw128:
14193 case X86::BI__builtin_ia32_psrlw256:
14194 case X86::BI__builtin_ia32_psrlw512: {
14198 [](
const APInt &Elt, uint64_t Count) {
return Elt.lshr(Count); },
14199 [](
const APInt &Elt,
unsigned Width) {
14200 return APInt::getZero(Width);
14206 case X86::BI__builtin_ia32_pternlogd128_mask:
14207 case X86::BI__builtin_ia32_pternlogd256_mask:
14208 case X86::BI__builtin_ia32_pternlogd512_mask:
14209 case X86::BI__builtin_ia32_pternlogq128_mask:
14210 case X86::BI__builtin_ia32_pternlogq256_mask:
14211 case X86::BI__builtin_ia32_pternlogq512_mask: {
14212 APValue AValue, BValue, CValue, ImmValue, UValue;
14220 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14226 ResultElements.reserve(ResultLen);
14228 for (
unsigned EltNum = 0; EltNum < ResultLen; ++EltNum) {
14234 unsigned BitWidth = ALane.getBitWidth();
14235 APInt ResLane(BitWidth, 0);
14237 for (
unsigned Bit = 0; Bit < BitWidth; ++Bit) {
14238 unsigned ABit = ALane[Bit];
14239 unsigned BBit = BLane[Bit];
14240 unsigned CBit = CLane[Bit];
14242 unsigned Idx = (ABit << 2) | (BBit << 1) | CBit;
14243 ResLane.setBitVal(Bit, Imm[Idx]);
14245 ResultElements.push_back(
APValue(
APSInt(ResLane, DestUnsigned)));
14247 ResultElements.push_back(
APValue(
APSInt(ALane, DestUnsigned)));
14250 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14252 case X86::BI__builtin_ia32_pternlogd128_maskz:
14253 case X86::BI__builtin_ia32_pternlogd256_maskz:
14254 case X86::BI__builtin_ia32_pternlogd512_maskz:
14255 case X86::BI__builtin_ia32_pternlogq128_maskz:
14256 case X86::BI__builtin_ia32_pternlogq256_maskz:
14257 case X86::BI__builtin_ia32_pternlogq512_maskz: {
14258 APValue AValue, BValue, CValue, ImmValue, UValue;
14266 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14272 ResultElements.reserve(ResultLen);
14274 for (
unsigned EltNum = 0; EltNum < ResultLen; ++EltNum) {
14279 unsigned BitWidth = ALane.getBitWidth();
14280 APInt ResLane(BitWidth, 0);
14283 for (
unsigned Bit = 0; Bit < BitWidth; ++Bit) {
14284 unsigned ABit = ALane[Bit];
14285 unsigned BBit = BLane[Bit];
14286 unsigned CBit = CLane[Bit];
14288 unsigned Idx = (ABit << 2) | (BBit << 1) | CBit;
14289 ResLane.setBitVal(Bit, Imm[Idx]);
14292 ResultElements.push_back(
APValue(
APSInt(ResLane, DestUnsigned)));
14294 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14297 case Builtin::BI__builtin_elementwise_clzg:
14298 case Builtin::BI__builtin_elementwise_ctzg: {
14300 std::optional<APValue> Fallback;
14307 Fallback = FallbackTmp;
14310 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14313 ResultElements.reserve(SourceLen);
14315 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
14320 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
14322 Builtin::BI__builtin_elementwise_ctzg);
14325 ResultElements.push_back(Fallback->getVectorElt(EltNum));
14328 switch (BuiltinOp) {
14329 case Builtin::BI__builtin_elementwise_clzg:
14330 ResultElements.push_back(
APValue(
14331 APSInt(
APInt(Info.Ctx.getIntWidth(DestEltTy), LHS.countl_zero()),
14334 case Builtin::BI__builtin_elementwise_ctzg:
14335 ResultElements.push_back(
APValue(
14336 APSInt(
APInt(Info.Ctx.getIntWidth(DestEltTy), LHS.countr_zero()),
14342 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14345 case Builtin::BI__builtin_elementwise_fma: {
14346 APValue SourceX, SourceY, SourceZ;
14354 ResultElements.reserve(SourceLen);
14356 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
14361 (void)
Result.fusedMultiplyAdd(Y, Z, RM);
14364 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14367 case clang::X86::BI__builtin_ia32_phaddw128:
14368 case clang::X86::BI__builtin_ia32_phaddw256:
14369 case clang::X86::BI__builtin_ia32_phaddd128:
14370 case clang::X86::BI__builtin_ia32_phaddd256:
14371 case clang::X86::BI__builtin_ia32_phaddsw128:
14372 case clang::X86::BI__builtin_ia32_phaddsw256:
14374 case clang::X86::BI__builtin_ia32_phsubw128:
14375 case clang::X86::BI__builtin_ia32_phsubw256:
14376 case clang::X86::BI__builtin_ia32_phsubd128:
14377 case clang::X86::BI__builtin_ia32_phsubd256:
14378 case clang::X86::BI__builtin_ia32_phsubsw128:
14379 case clang::X86::BI__builtin_ia32_phsubsw256: {
14380 APValue SourceLHS, SourceRHS;
14384 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14388 unsigned EltBits = Info.Ctx.getIntWidth(DestEltTy);
14389 unsigned EltsPerLane = 128 / EltBits;
14391 ResultElements.reserve(NumElts);
14393 for (
unsigned LaneStart = 0; LaneStart != NumElts;
14394 LaneStart += EltsPerLane) {
14395 for (
unsigned I = 0; I != EltsPerLane; I += 2) {
14398 switch (BuiltinOp) {
14399 case clang::X86::BI__builtin_ia32_phaddw128:
14400 case clang::X86::BI__builtin_ia32_phaddw256:
14401 case clang::X86::BI__builtin_ia32_phaddd128:
14402 case clang::X86::BI__builtin_ia32_phaddd256: {
14403 APSInt Res(LHSA + LHSB, DestUnsigned);
14404 ResultElements.push_back(
APValue(Res));
14407 case clang::X86::BI__builtin_ia32_phaddsw128:
14408 case clang::X86::BI__builtin_ia32_phaddsw256: {
14409 APSInt Res(LHSA.sadd_sat(LHSB));
14410 ResultElements.push_back(
APValue(Res));
14413 case clang::X86::BI__builtin_ia32_phsubw128:
14414 case clang::X86::BI__builtin_ia32_phsubw256:
14415 case clang::X86::BI__builtin_ia32_phsubd128:
14416 case clang::X86::BI__builtin_ia32_phsubd256: {
14417 APSInt Res(LHSA - LHSB, DestUnsigned);
14418 ResultElements.push_back(
APValue(Res));
14421 case clang::X86::BI__builtin_ia32_phsubsw128:
14422 case clang::X86::BI__builtin_ia32_phsubsw256: {
14423 APSInt Res(LHSA.ssub_sat(LHSB));
14424 ResultElements.push_back(
APValue(Res));
14429 for (
unsigned I = 0; I != EltsPerLane; I += 2) {
14432 switch (BuiltinOp) {
14433 case clang::X86::BI__builtin_ia32_phaddw128:
14434 case clang::X86::BI__builtin_ia32_phaddw256:
14435 case clang::X86::BI__builtin_ia32_phaddd128:
14436 case clang::X86::BI__builtin_ia32_phaddd256: {
14437 APSInt Res(RHSA + RHSB, DestUnsigned);
14438 ResultElements.push_back(
APValue(Res));
14441 case clang::X86::BI__builtin_ia32_phaddsw128:
14442 case clang::X86::BI__builtin_ia32_phaddsw256: {
14443 APSInt Res(RHSA.sadd_sat(RHSB));
14444 ResultElements.push_back(
APValue(Res));
14447 case clang::X86::BI__builtin_ia32_phsubw128:
14448 case clang::X86::BI__builtin_ia32_phsubw256:
14449 case clang::X86::BI__builtin_ia32_phsubd128:
14450 case clang::X86::BI__builtin_ia32_phsubd256: {
14451 APSInt Res(RHSA - RHSB, DestUnsigned);
14452 ResultElements.push_back(
APValue(Res));
14455 case clang::X86::BI__builtin_ia32_phsubsw128:
14456 case clang::X86::BI__builtin_ia32_phsubsw256: {
14457 APSInt Res(RHSA.ssub_sat(RHSB));
14458 ResultElements.push_back(
APValue(Res));
14464 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14466 case clang::X86::BI__builtin_ia32_haddpd:
14467 case clang::X86::BI__builtin_ia32_haddps:
14468 case clang::X86::BI__builtin_ia32_haddps256:
14469 case clang::X86::BI__builtin_ia32_haddpd256:
14470 case clang::X86::BI__builtin_ia32_hsubpd:
14471 case clang::X86::BI__builtin_ia32_hsubps:
14472 case clang::X86::BI__builtin_ia32_hsubps256:
14473 case clang::X86::BI__builtin_ia32_hsubpd256: {
14474 APValue SourceLHS, SourceRHS;
14480 ResultElements.reserve(NumElts);
14482 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14483 unsigned EltBits = Info.Ctx.getTypeSize(DestEltTy);
14484 unsigned NumLanes = NumElts * EltBits / 128;
14485 unsigned NumElemsPerLane = NumElts / NumLanes;
14486 unsigned HalfElemsPerLane = NumElemsPerLane / 2;
14488 for (
unsigned L = 0; L != NumElts; L += NumElemsPerLane) {
14489 for (
unsigned I = 0; I != HalfElemsPerLane; ++I) {
14492 switch (BuiltinOp) {
14493 case clang::X86::BI__builtin_ia32_haddpd:
14494 case clang::X86::BI__builtin_ia32_haddps:
14495 case clang::X86::BI__builtin_ia32_haddps256:
14496 case clang::X86::BI__builtin_ia32_haddpd256:
14497 LHSA.add(LHSB, RM);
14499 case clang::X86::BI__builtin_ia32_hsubpd:
14500 case clang::X86::BI__builtin_ia32_hsubps:
14501 case clang::X86::BI__builtin_ia32_hsubps256:
14502 case clang::X86::BI__builtin_ia32_hsubpd256:
14503 LHSA.subtract(LHSB, RM);
14506 ResultElements.push_back(
APValue(LHSA));
14508 for (
unsigned I = 0; I != HalfElemsPerLane; ++I) {
14511 switch (BuiltinOp) {
14512 case clang::X86::BI__builtin_ia32_haddpd:
14513 case clang::X86::BI__builtin_ia32_haddps:
14514 case clang::X86::BI__builtin_ia32_haddps256:
14515 case clang::X86::BI__builtin_ia32_haddpd256:
14516 RHSA.add(RHSB, RM);
14518 case clang::X86::BI__builtin_ia32_hsubpd:
14519 case clang::X86::BI__builtin_ia32_hsubps:
14520 case clang::X86::BI__builtin_ia32_hsubps256:
14521 case clang::X86::BI__builtin_ia32_hsubpd256:
14522 RHSA.subtract(RHSB, RM);
14525 ResultElements.push_back(
APValue(RHSA));
14528 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14530 case clang::X86::BI__builtin_ia32_addsubpd:
14531 case clang::X86::BI__builtin_ia32_addsubps:
14532 case clang::X86::BI__builtin_ia32_addsubpd256:
14533 case clang::X86::BI__builtin_ia32_addsubps256: {
14536 APValue SourceLHS, SourceRHS;
14542 ResultElements.reserve(NumElems);
14545 for (
unsigned I = 0; I != NumElems; ++I) {
14550 LHS.subtract(RHS, RM);
14555 ResultElements.push_back(
APValue(LHS));
14557 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14559 case clang::X86::BI__builtin_ia32_pclmulqdq128:
14560 case clang::X86::BI__builtin_ia32_pclmulqdq256:
14561 case clang::X86::BI__builtin_ia32_pclmulqdq512: {
14565 APValue SourceLHS, SourceRHS;
14575 bool SelectUpperA = (Imm8 & 0x01) != 0;
14576 bool SelectUpperB = (Imm8 & 0x10) != 0;
14580 ResultElements.reserve(NumElems);
14581 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14585 for (
unsigned Lane = 0; Lane < NumElems; Lane += 2) {
14594 APInt A = SelectUpperA ? A1 : A0;
14595 APInt B = SelectUpperB ? B1 : B0;
14598 APInt A128 = A.zext(128);
14599 APInt B128 = B.zext(128);
14602 APInt Result = llvm::APIntOps::clmul(A128, B128);
14605 APSInt ResultLow(
Result.extractBits(64, 0), DestUnsigned);
14606 APSInt ResultHigh(
Result.extractBits(64, 64), DestUnsigned);
14608 ResultElements.push_back(
APValue(ResultLow));
14609 ResultElements.push_back(
APValue(ResultHigh));
14612 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14614 case Builtin::BI__builtin_elementwise_clmul:
14615 return EvaluateBinOpExpr(llvm::APIntOps::clmul);
14616 case Builtin::BI__builtin_elementwise_pext:
14617 return EvaluateBinOpExpr(llvm::APIntOps::pext);
14618 case Builtin::BI__builtin_elementwise_pdep:
14619 return EvaluateBinOpExpr(llvm::APIntOps::pdep);
14620 case Builtin::BI__builtin_elementwise_fshl:
14621 case Builtin::BI__builtin_elementwise_fshr: {
14622 APValue SourceHi, SourceLo, SourceShift;
14628 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14634 ResultElements.reserve(SourceLen);
14635 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
14639 switch (BuiltinOp) {
14640 case Builtin::BI__builtin_elementwise_fshl:
14641 ResultElements.push_back(
APValue(
14642 APSInt(llvm::APIntOps::fshl(Hi, Lo, Shift), Hi.isUnsigned())));
14644 case Builtin::BI__builtin_elementwise_fshr:
14645 ResultElements.push_back(
APValue(
14646 APSInt(llvm::APIntOps::fshr(Hi, Lo, Shift), Hi.isUnsigned())));
14651 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14654 case X86::BI__builtin_ia32_shuf_f32x4_256:
14655 case X86::BI__builtin_ia32_shuf_i32x4_256:
14656 case X86::BI__builtin_ia32_shuf_f64x2_256:
14657 case X86::BI__builtin_ia32_shuf_i64x2_256:
14658 case X86::BI__builtin_ia32_shuf_f32x4:
14659 case X86::BI__builtin_ia32_shuf_i32x4:
14660 case X86::BI__builtin_ia32_shuf_f64x2:
14661 case X86::BI__builtin_ia32_shuf_i64x2: {
14675 unsigned ElemBits = Info.Ctx.getTypeSize(ElemQT);
14676 unsigned LaneBits = 128u;
14677 unsigned NumLanes = (NumElems * ElemBits) / LaneBits;
14678 unsigned NumElemsPerLane = LaneBits / ElemBits;
14682 ResultElements.reserve(DstLen);
14687 [NumLanes, NumElemsPerLane](
unsigned DstIdx,
unsigned ShuffleMask)
14688 -> std::pair<unsigned, int> {
14690 unsigned BitsPerElem = NumLanes / 2;
14691 unsigned IndexMask = (1u << BitsPerElem) - 1;
14692 unsigned Lane = DstIdx / NumElemsPerLane;
14693 unsigned SrcIdx = (Lane < NumLanes / 2) ? 0 : 1;
14694 unsigned BitIdx = BitsPerElem * Lane;
14695 unsigned SrcLaneIdx = (ShuffleMask >> BitIdx) & IndexMask;
14696 unsigned ElemInLane = DstIdx % NumElemsPerLane;
14697 unsigned IdxToPick = SrcLaneIdx * NumElemsPerLane + ElemInLane;
14698 return {SrcIdx, IdxToPick};
14704 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v16qi:
14705 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v32qi:
14706 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v64qi:
14707 case X86::BI__builtin_ia32_vgf2p8affineqb_v16qi:
14708 case X86::BI__builtin_ia32_vgf2p8affineqb_v32qi:
14709 case X86::BI__builtin_ia32_vgf2p8affineqb_v64qi: {
14721 bool IsInverse =
false;
14722 switch (BuiltinOp) {
14723 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v16qi:
14724 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v32qi:
14725 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v64qi: {
14730 unsigned NumBitsInByte = 8;
14731 unsigned NumBytesInQWord = 8;
14732 unsigned NumBitsInQWord = 64;
14734 unsigned NumQWords = NumBytes / NumBytesInQWord;
14736 Result.reserve(NumBytes);
14739 for (
unsigned QWordIdx = 0; QWordIdx != NumQWords; ++QWordIdx) {
14741 APInt XQWord(NumBitsInQWord, 0);
14742 APInt AQWord(NumBitsInQWord, 0);
14743 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
14744 unsigned Idx = QWordIdx * NumBytesInQWord + ByteIdx;
14745 APInt XByte =
X.getVectorElt(Idx).getInt();
14747 XQWord.insertBits(XByte, ByteIdx * NumBitsInByte);
14748 AQWord.insertBits(AByte, ByteIdx * NumBitsInByte);
14751 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
14753 XQWord.lshr(ByteIdx * NumBitsInByte).getLoBits(8).getZExtValue();
14762 case X86::BI__builtin_ia32_vgf2p8mulb_v16qi:
14763 case X86::BI__builtin_ia32_vgf2p8mulb_v32qi:
14764 case X86::BI__builtin_ia32_vgf2p8mulb_v64qi: {
14775 Result.reserve(NumBytes);
14777 for (
unsigned ByteIdx = 0; ByteIdx != NumBytes; ++ByteIdx) {
14787 case X86::BI__builtin_ia32_insertf32x4_256:
14788 case X86::BI__builtin_ia32_inserti32x4_256:
14789 case X86::BI__builtin_ia32_insertf64x2_256:
14790 case X86::BI__builtin_ia32_inserti64x2_256:
14791 case X86::BI__builtin_ia32_insertf32x4:
14792 case X86::BI__builtin_ia32_inserti32x4:
14793 case X86::BI__builtin_ia32_insertf64x2_512:
14794 case X86::BI__builtin_ia32_inserti64x2_512:
14795 case X86::BI__builtin_ia32_insertf32x8:
14796 case X86::BI__builtin_ia32_inserti32x8:
14797 case X86::BI__builtin_ia32_insertf64x4:
14798 case X86::BI__builtin_ia32_inserti64x4:
14799 case X86::BI__builtin_ia32_vinsertf128_ps256:
14800 case X86::BI__builtin_ia32_vinsertf128_pd256:
14801 case X86::BI__builtin_ia32_vinsertf128_si256:
14802 case X86::BI__builtin_ia32_insert128i256: {
14803 APValue SourceDst, SourceSub;
14815 assert(SubLen != 0 && DstLen != 0 && (DstLen % SubLen) == 0);
14816 unsigned NumLanes = DstLen / SubLen;
14817 unsigned LaneIdx = (Imm.getZExtValue() % NumLanes) * SubLen;
14820 ResultElements.reserve(DstLen);
14822 for (
unsigned EltNum = 0; EltNum < DstLen; ++EltNum) {
14823 if (EltNum >= LaneIdx && EltNum < LaneIdx + SubLen)
14824 ResultElements.push_back(SourceSub.
getVectorElt(EltNum - LaneIdx));
14826 ResultElements.push_back(SourceDst.
getVectorElt(EltNum));
14829 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14832 case clang::X86::BI__builtin_ia32_vec_set_v4hi:
14833 case clang::X86::BI__builtin_ia32_vec_set_v16qi:
14834 case clang::X86::BI__builtin_ia32_vec_set_v8hi:
14835 case clang::X86::BI__builtin_ia32_vec_set_v4si:
14836 case clang::X86::BI__builtin_ia32_vec_set_v2di:
14837 case clang::X86::BI__builtin_ia32_vec_set_v32qi:
14838 case clang::X86::BI__builtin_ia32_vec_set_v16hi:
14839 case clang::X86::BI__builtin_ia32_vec_set_v8si:
14840 case clang::X86::BI__builtin_ia32_vec_set_v4di: {
14848 QualType ElemTy = E->
getType()->
castAs<VectorType>()->getElementType();
14849 unsigned ElemWidth = Info.Ctx.getIntWidth(ElemTy);
14851 Scalar.setIsUnsigned(ElemUnsigned);
14857 static_cast<unsigned>(IndexAPS.getZExtValue() & (NumElems - 1));
14860 Elems.reserve(NumElems);
14861 for (
unsigned ElemNum = 0; ElemNum != NumElems; ++ElemNum)
14862 Elems.push_back(ElemNum == Index ? ElemAV : VecVal.
getVectorElt(ElemNum));
14867 case X86::BI__builtin_ia32_pslldqi128_byteshift:
14868 case X86::BI__builtin_ia32_pslldqi256_byteshift:
14869 case X86::BI__builtin_ia32_pslldqi512_byteshift: {
14873 [](
unsigned DstIdx,
unsigned Shift) -> std::pair<unsigned, int> {
14874 unsigned LaneBase = (DstIdx / 16) * 16;
14875 unsigned LaneIdx = DstIdx % 16;
14876 if (LaneIdx < Shift)
14877 return std::make_pair(0, -1);
14879 return std::make_pair(
14880 0,
static_cast<int>(LaneBase + LaneIdx - Shift));
14886 case X86::BI__builtin_ia32_psrldqi128_byteshift:
14887 case X86::BI__builtin_ia32_psrldqi256_byteshift:
14888 case X86::BI__builtin_ia32_psrldqi512_byteshift: {
14892 [](
unsigned DstIdx,
unsigned Shift) -> std::pair<unsigned, int> {
14893 unsigned LaneBase = (DstIdx / 16) * 16;
14894 unsigned LaneIdx = DstIdx % 16;
14895 if (LaneIdx + Shift < 16)
14896 return std::make_pair(
14897 0,
static_cast<int>(LaneBase + LaneIdx + Shift));
14899 return std::make_pair(0, -1);
14905 case X86::BI__builtin_ia32_palignr128:
14906 case X86::BI__builtin_ia32_palignr256:
14907 case X86::BI__builtin_ia32_palignr512: {
14911 unsigned VecIdx = 1;
14914 int Lane = DstIdx / 16;
14915 int Offset = DstIdx % 16;
14918 unsigned ShiftedIdx = Offset + (
Shift & 0xFF);
14919 if (ShiftedIdx < 16) {
14920 ElemIdx = ShiftedIdx + (Lane * 16);
14921 }
else if (ShiftedIdx < 32) {
14923 ElemIdx = (ShiftedIdx - 16) + (Lane * 16);
14926 return std::pair<unsigned, int>{VecIdx, ElemIdx};
14931 case X86::BI__builtin_ia32_alignd128:
14932 case X86::BI__builtin_ia32_alignd256:
14933 case X86::BI__builtin_ia32_alignd512:
14934 case X86::BI__builtin_ia32_alignq128:
14935 case X86::BI__builtin_ia32_alignq256:
14936 case X86::BI__builtin_ia32_alignq512: {
14938 unsigned NumElems = E->
getType()->
castAs<VectorType>()->getNumElements();
14940 [NumElems](
unsigned DstIdx,
unsigned Shift) {
14941 unsigned Imm =
Shift & 0xFF;
14942 unsigned EffectiveShift = Imm & (NumElems - 1);
14943 unsigned SourcePos = DstIdx + EffectiveShift;
14944 unsigned VecIdx = SourcePos < NumElems ? 1 : 0;
14945 unsigned ElemIdx = SourcePos & (NumElems - 1);
14947 return std::pair<unsigned, int>{
14948 VecIdx,
static_cast<int>(ElemIdx)};
14953 case X86::BI__builtin_ia32_permvarsi256:
14954 case X86::BI__builtin_ia32_permvarsf256:
14955 case X86::BI__builtin_ia32_permvardf512:
14956 case X86::BI__builtin_ia32_permvardi512:
14957 case X86::BI__builtin_ia32_permvarhi128: {
14960 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14961 int Offset = ShuffleMask & 0x7;
14962 return std::pair<unsigned, int>{0, Offset};
14967 case X86::BI__builtin_ia32_permvarqi128:
14968 case X86::BI__builtin_ia32_permvarhi256:
14969 case X86::BI__builtin_ia32_permvarsi512:
14970 case X86::BI__builtin_ia32_permvarsf512: {
14973 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14974 int Offset = ShuffleMask & 0xF;
14975 return std::pair<unsigned, int>{0, Offset};
14980 case X86::BI__builtin_ia32_permvardi256:
14981 case X86::BI__builtin_ia32_permvardf256: {
14984 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14985 int Offset = ShuffleMask & 0x3;
14986 return std::pair<unsigned, int>{0, Offset};
14991 case X86::BI__builtin_ia32_permvarqi256:
14992 case X86::BI__builtin_ia32_permvarhi512: {
14995 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14996 int Offset = ShuffleMask & 0x1F;
14997 return std::pair<unsigned, int>{0, Offset};
15002 case X86::BI__builtin_ia32_permvarqi512: {
15005 [](
unsigned DstIdx,
unsigned ShuffleMask) {
15006 int Offset = ShuffleMask & 0x3F;
15007 return std::pair<unsigned, int>{0, Offset};
15012 case X86::BI__builtin_ia32_vpermi2varq128:
15013 case X86::BI__builtin_ia32_vpermi2varpd128: {
15016 [](
unsigned DstIdx,
unsigned ShuffleMask) {
15017 int Offset = ShuffleMask & 0x1;
15018 unsigned SrcIdx = (ShuffleMask >> 1) & 0x1;
15019 return std::pair<unsigned, int>{SrcIdx, Offset};
15024 case X86::BI__builtin_ia32_vpermi2vard128:
15025 case X86::BI__builtin_ia32_vpermi2varps128:
15026 case X86::BI__builtin_ia32_vpermi2varq256:
15027 case X86::BI__builtin_ia32_vpermi2varpd256: {
15030 [](
unsigned DstIdx,
unsigned ShuffleMask) {
15031 int Offset = ShuffleMask & 0x3;
15032 unsigned SrcIdx = (ShuffleMask >> 2) & 0x1;
15033 return std::pair<unsigned, int>{SrcIdx, Offset};
15038 case X86::BI__builtin_ia32_vpermi2varhi128:
15039 case X86::BI__builtin_ia32_vpermi2vard256:
15040 case X86::BI__builtin_ia32_vpermi2varps256:
15041 case X86::BI__builtin_ia32_vpermi2varq512:
15042 case X86::BI__builtin_ia32_vpermi2varpd512: {
15045 [](
unsigned DstIdx,
unsigned ShuffleMask) {
15046 int Offset = ShuffleMask & 0x7;
15047 unsigned SrcIdx = (ShuffleMask >> 3) & 0x1;
15048 return std::pair<unsigned, int>{SrcIdx, Offset};
15053 case X86::BI__builtin_ia32_vpermi2varqi128:
15054 case X86::BI__builtin_ia32_vpermi2varhi256:
15055 case X86::BI__builtin_ia32_vpermi2vard512:
15056 case X86::BI__builtin_ia32_vpermi2varps512: {
15059 [](
unsigned DstIdx,
unsigned ShuffleMask) {
15060 int Offset = ShuffleMask & 0xF;
15061 unsigned SrcIdx = (ShuffleMask >> 4) & 0x1;
15062 return std::pair<unsigned, int>{SrcIdx, Offset};
15067 case X86::BI__builtin_ia32_vpermi2varqi256:
15068 case X86::BI__builtin_ia32_vpermi2varhi512: {
15071 [](
unsigned DstIdx,
unsigned ShuffleMask) {
15072 int Offset = ShuffleMask & 0x1F;
15073 unsigned SrcIdx = (ShuffleMask >> 5) & 0x1;
15074 return std::pair<unsigned, int>{SrcIdx, Offset};
15079 case X86::BI__builtin_ia32_vpermi2varqi512: {
15082 [](
unsigned DstIdx,
unsigned ShuffleMask) {
15083 int Offset = ShuffleMask & 0x3F;
15084 unsigned SrcIdx = (ShuffleMask >> 6) & 0x1;
15085 return std::pair<unsigned, int>{SrcIdx, Offset};
15091 case clang::X86::BI__builtin_ia32_minps:
15092 case clang::X86::BI__builtin_ia32_minpd:
15093 case clang::X86::BI__builtin_ia32_minps256:
15094 case clang::X86::BI__builtin_ia32_minpd256:
15095 case clang::X86::BI__builtin_ia32_minps512:
15096 case clang::X86::BI__builtin_ia32_minpd512:
15097 case clang::X86::BI__builtin_ia32_minph128:
15098 case clang::X86::BI__builtin_ia32_minph256:
15099 case clang::X86::BI__builtin_ia32_minph512:
15100 return EvaluateFpBinOpExpr(
15101 [](
const APFloat &A,
const APFloat &B,
15102 std::optional<APSInt>) -> std::optional<APFloat> {
15103 if (A.isNaN() || A.isInfinity() || A.isDenormal() || B.isNaN() ||
15104 B.isInfinity() || B.isDenormal())
15105 return std::nullopt;
15106 if (A.isZero() && B.isZero())
15108 return llvm::minimum(A, B);
15111 case clang::X86::BI__builtin_ia32_minss:
15112 case clang::X86::BI__builtin_ia32_minsd:
15113 return EvaluateFpBinOpExpr(
15114 [](
const APFloat &A,
const APFloat &B,
15115 std::optional<APSInt> RoundingMode) -> std::optional<APFloat> {
15120 case clang::X86::BI__builtin_ia32_minsd_round_mask:
15121 case clang::X86::BI__builtin_ia32_minss_round_mask:
15122 case clang::X86::BI__builtin_ia32_minsh_round_mask:
15123 case clang::X86::BI__builtin_ia32_maxsd_round_mask:
15124 case clang::X86::BI__builtin_ia32_maxss_round_mask:
15125 case clang::X86::BI__builtin_ia32_maxsh_round_mask: {
15126 bool IsMin = BuiltinOp == clang::X86::BI__builtin_ia32_minsd_round_mask ||
15127 BuiltinOp == clang::X86::BI__builtin_ia32_minss_round_mask ||
15128 BuiltinOp == clang::X86::BI__builtin_ia32_minsh_round_mask;
15129 return EvaluateScalarFpRoundMaskBinOp(
15130 [IsMin](
const APFloat &A,
const APFloat &B,
15131 std::optional<APSInt> RoundingMode) -> std::optional<APFloat> {
15136 case clang::X86::BI__builtin_ia32_maxps:
15137 case clang::X86::BI__builtin_ia32_maxpd:
15138 case clang::X86::BI__builtin_ia32_maxps256:
15139 case clang::X86::BI__builtin_ia32_maxpd256:
15140 case clang::X86::BI__builtin_ia32_maxps512:
15141 case clang::X86::BI__builtin_ia32_maxpd512:
15142 case clang::X86::BI__builtin_ia32_maxph128:
15143 case clang::X86::BI__builtin_ia32_maxph256:
15144 case clang::X86::BI__builtin_ia32_maxph512:
15145 return EvaluateFpBinOpExpr(
15146 [](
const APFloat &A,
const APFloat &B,
15147 std::optional<APSInt>) -> std::optional<APFloat> {
15148 if (A.isNaN() || A.isInfinity() || A.isDenormal() || B.isNaN() ||
15149 B.isInfinity() || B.isDenormal())
15150 return std::nullopt;
15151 if (A.isZero() && B.isZero())
15153 return llvm::maximum(A, B);
15156 case clang::X86::BI__builtin_ia32_maxss:
15157 case clang::X86::BI__builtin_ia32_maxsd:
15158 return EvaluateFpBinOpExpr(
15159 [](
const APFloat &A,
const APFloat &B,
15160 std::optional<APSInt> RoundingMode) -> std::optional<APFloat> {
15165 case clang::X86::BI__builtin_ia32_vcvtps2ph:
15166 case clang::X86::BI__builtin_ia32_vcvtps2ph256: {
15176 unsigned SrcNumElems = SrcVTy->getNumElements();
15178 unsigned DstNumElems = DstVTy->getNumElements();
15179 QualType DstElemTy = DstVTy->getElementType();
15181 const llvm::fltSemantics &HalfSem =
15182 Info.Ctx.getFloatTypeSemantics(Info.Ctx.HalfTy);
15184 int ImmVal = Imm.getZExtValue();
15185 bool UseMXCSR = (ImmVal & 4) != 0;
15186 bool IsFPConstrained =
15189 llvm::RoundingMode RM;
15191 switch (ImmVal & 3) {
15193 RM = llvm::RoundingMode::NearestTiesToEven;
15196 RM = llvm::RoundingMode::TowardNegative;
15199 RM = llvm::RoundingMode::TowardPositive;
15202 RM = llvm::RoundingMode::TowardZero;
15205 llvm_unreachable(
"Invalid immediate rounding mode");
15208 RM = llvm::RoundingMode::NearestTiesToEven;
15212 ResultElements.reserve(DstNumElems);
15214 for (
unsigned I = 0; I < SrcNumElems; ++I) {
15218 APFloat::opStatus St = SrcVal.convert(HalfSem, RM, &LostInfo);
15220 if (UseMXCSR && IsFPConstrained && St != APFloat::opOK) {
15221 Info.FFDiag(E, diag::note_constexpr_dynamic_rounding);
15225 APSInt DstInt(SrcVal.bitcastToAPInt(),
15227 ResultElements.push_back(
APValue(DstInt));
15230 if (DstNumElems > SrcNumElems) {
15231 APSInt Zero = Info.Ctx.MakeIntValue(0, DstElemTy);
15232 for (
unsigned I = SrcNumElems; I < DstNumElems; ++I) {
15237 return Success(ResultElements, E);
15239 case X86::BI__builtin_ia32_vperm2f128_pd256:
15240 case X86::BI__builtin_ia32_vperm2f128_ps256:
15241 case X86::BI__builtin_ia32_vperm2f128_si256:
15242 case X86::BI__builtin_ia32_permti256: {
15243 unsigned NumElements =
15245 unsigned PreservedBitsCnt = NumElements >> 2;
15249 [PreservedBitsCnt](
unsigned DstIdx,
unsigned ShuffleMask) {
15250 unsigned ControlBitsCnt = DstIdx >> PreservedBitsCnt << 2;
15251 unsigned ControlBits = ShuffleMask >> ControlBitsCnt;
15253 if (ControlBits & 0b1000)
15254 return std::make_pair(0u, -1);
15256 unsigned SrcVecIdx = (ControlBits & 0b10) >> 1;
15257 unsigned PreservedBitsMask = (1 << PreservedBitsCnt) - 1;
15258 int SrcIdx = ((ControlBits & 0b1) << PreservedBitsCnt) |
15259 (DstIdx & PreservedBitsMask);
15260 return std::make_pair(SrcVecIdx, SrcIdx);
15265 case X86::BI__builtin_ia32_vpdpwssd128:
15266 case X86::BI__builtin_ia32_vpdpwssd256:
15267 case X86::BI__builtin_ia32_vpdpwssd512:
15268 case X86::BI__builtin_ia32_vpdpbusd128:
15269 case X86::BI__builtin_ia32_vpdpbusd256:
15270 case X86::BI__builtin_ia32_vpdpbusd512:
15271 return EvalVectorDotProduct(
false);
15272 case X86::BI__builtin_ia32_vpdpwssds128:
15273 case X86::BI__builtin_ia32_vpdpwssds256:
15274 case X86::BI__builtin_ia32_vpdpwssds512:
15275 case X86::BI__builtin_ia32_vpdpbusds128:
15276 case X86::BI__builtin_ia32_vpdpbusds256:
15277 case X86::BI__builtin_ia32_vpdpbusds512:
15278 return EvalVectorDotProduct(
true);
15279 case X86::BI__builtin_ia32_cvtpd2dq:
15280 case X86::BI__builtin_ia32_cvtps2dq:
15281 case X86::BI__builtin_ia32_cvttpd2dq:
15282 case X86::BI__builtin_ia32_cvttps2dq:
15283 case X86::BI__builtin_ia32_cvtpd2dq256:
15284 case X86::BI__builtin_ia32_cvtps2dq256:
15285 case X86::BI__builtin_ia32_cvttpd2dq256:
15286 case X86::BI__builtin_ia32_cvttps2dq256: {
15293 bool isUnsigned = EltTy->isUnsignedIntegerType();
15294 unsigned BitWidth = Info.Ctx.getIntWidth(EltTy);
15300 for (
unsigned i = 0; i != NumDstElems; ++i) {
15301 if (i < NumSrcElems) {
15303 llvm::APSInt IntResult(BitWidth,
isUnsigned);
15304 bool IsExact =
false;
15307 FloatElem.convertToInteger(IntResult, llvm::APFloat::rmTowardZero,
15311 ResultElts.push_back(
APValue(IntResult));
15316 return Success(ResultElts, E);
15321bool VectorExprEvaluator::VisitConvertVectorExpr(
const ConvertVectorExpr *E) {
15327 QualType DestTy = E->
getType()->
castAs<VectorType>()->getElementType();
15328 QualType SourceTy = SourceVecType->
castAs<VectorType>()->getElementType();
15334 ResultElements.reserve(SourceLen);
15335 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
15340 ResultElements.push_back(std::move(Elt));
15343 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
15348 APValue const &VecVal2,
unsigned EltNum,
15350 unsigned const TotalElementsInInputVector1 = VecVal1.
getVectorLength();
15351 unsigned const TotalElementsInInputVector2 = VecVal2.
getVectorLength();
15354 int64_t
index = IndexVal.getExtValue();
15361 E, diag::err_shufflevector_minus_one_is_undefined_behavior_constexpr)
15367 index >= TotalElementsInInputVector1 + TotalElementsInInputVector2)
15368 llvm_unreachable(
"Out of bounds shuffle index");
15370 if (
index >= TotalElementsInInputVector1)
15377bool VectorExprEvaluator::VisitShuffleVectorExpr(
const ShuffleVectorExpr *E) {
15382 const Expr *Vec1 = E->
getExpr(0);
15386 const Expr *Vec2 = E->
getExpr(1);
15390 VectorType
const *DestVecTy = E->
getType()->
castAs<VectorType>();
15396 ResultElements.reserve(TotalElementsInOutputVector);
15397 for (
unsigned EltNum = 0; EltNum < TotalElementsInOutputVector; ++EltNum) {
15401 ResultElements.push_back(std::move(Elt));
15404 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
15412class MatrixExprEvaluator :
public ExprEvaluatorBase<MatrixExprEvaluator> {
15419 bool Success(ArrayRef<APValue> M,
const Expr *E) {
15421 assert(M.size() == CMTy->getNumElementsFlattened());
15423 Result =
APValue(M.data(), CMTy->getNumRows(), CMTy->getNumColumns());
15427 assert(M.
isMatrix() &&
"expected matrix");
15432 bool VisitCastExpr(
const CastExpr *E);
15433 bool VisitInitListExpr(
const InitListExpr *E);
15439 "not a matrix prvalue");
15440 return MatrixExprEvaluator(Info,
Result).Visit(E);
15443bool MatrixExprEvaluator::VisitCastExpr(
const CastExpr *E) {
15444 const auto *MT = E->
getType()->
castAs<ConstantMatrixType>();
15445 unsigned NumRows = MT->getNumRows();
15446 unsigned NumCols = MT->getNumColumns();
15447 unsigned NElts = NumRows * NumCols;
15448 QualType EltTy = MT->getElementType();
15452 case CK_HLSLAggregateSplatCast: {
15467 case CK_HLSLElementwiseCast: {
15480 return Success(ResultEls, E);
15483 return ExprEvaluatorBaseTy::VisitCastExpr(E);
15487bool MatrixExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
15488 const auto *MT = E->
getType()->
castAs<ConstantMatrixType>();
15489 QualType EltTy = MT->getElementType();
15491 assert(E->
getNumInits() == MT->getNumElementsFlattened() &&
15492 "Expected number of elements in initializer list to match the number "
15493 "of matrix elements");
15496 Elements.reserve(MT->getNumElementsFlattened());
15501 for (
unsigned I = 0, N = MT->getNumElementsFlattened(); I < N; ++I) {
15502 if (EltTy->isIntegerType()) {
15503 llvm::APSInt IntVal;
15506 Elements.push_back(
APValue(IntVal));
15508 llvm::APFloat FloatVal(0.0);
15511 Elements.push_back(
APValue(FloatVal));
15523 class ArrayExprEvaluator
15524 :
public ExprEvaluatorBase<ArrayExprEvaluator> {
15525 const LValue &
This;
15529 ArrayExprEvaluator(EvalInfo &Info,
const LValue &This,
APValue &
Result)
15533 assert(
V.isArray() &&
"expected array");
15538 bool ZeroInitialization(
const Expr *E) {
15539 const ConstantArrayType *CAT =
15540 Info.Ctx.getAsConstantArrayType(E->
getType());
15554 if (!
Result.hasArrayFiller())
15558 LValue Subobject =
This;
15559 Subobject.addArray(Info, E, CAT);
15564 bool VisitCallExpr(
const CallExpr *E) {
15565 return handleCallExpr(E,
Result, &This);
15567 bool VisitCastExpr(
const CastExpr *E);
15568 bool VisitInitListExpr(
const InitListExpr *E,
15569 QualType AllocType = QualType());
15570 bool VisitArrayInitLoopExpr(
const ArrayInitLoopExpr *E);
15571 bool VisitCXXConstructExpr(
const CXXConstructExpr *E);
15572 bool VisitCXXConstructExpr(
const CXXConstructExpr *E,
15573 const LValue &Subobject,
15575 bool VisitStringLiteral(
const StringLiteral *E,
15576 QualType AllocType = QualType()) {
15580 bool VisitCXXParenListInitExpr(
const CXXParenListInitExpr *E);
15581 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
15582 ArrayRef<Expr *> Args,
15583 const Expr *ArrayFiller,
15584 QualType AllocType = QualType());
15585 bool VisitDesignatedInitUpdateExpr(
const DesignatedInitUpdateExpr *E);
15593 "not an array prvalue");
15594 return ArrayExprEvaluator(Info,
This,
Result).Visit(E);
15602 "not an array prvalue");
15603 return ArrayExprEvaluator(Info,
This,
Result)
15604 .VisitInitListExpr(ILE, AllocType);
15613 "not an array prvalue");
15614 return ArrayExprEvaluator(Info,
This,
Result)
15615 .VisitCXXConstructExpr(CCE,
This, &
Result, AllocType);
15624 if (
const InitListExpr *ILE = dyn_cast<InitListExpr>(FillerExpr)) {
15625 for (
unsigned I = 0, E = ILE->
getNumInits(); I != E; ++I) {
15630 if (ILE->hasArrayFiller() &&
15639bool ArrayExprEvaluator::VisitCastExpr(
const CastExpr *E) {
15644 return ExprEvaluatorBaseTy::VisitCastExpr(E);
15645 case CK_HLSLAggregateSplatCast: {
15665 case CK_HLSLElementwiseCast: {
15682bool ArrayExprEvaluator::VisitInitListExpr(
const InitListExpr *E,
15683 QualType AllocType) {
15684 const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(
15697 return VisitStringLiteral(SL, AllocType);
15702 "transparent array list initialization is not string literal init?");
15708bool ArrayExprEvaluator::VisitCXXParenListOrInitListExpr(
15710 QualType AllocType) {
15711 const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(
15716 unsigned NumEltsToInit = Args.size();
15721 if (NumEltsToInit != NumElts &&
15723 NumEltsToInit = NumElts;
15726 for (
auto *
Init : Args) {
15727 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts()))
15728 NumEltsToInit += EmbedS->getDataElementCount() - 1;
15731 if (NumEltsToInit > NumElts)
15732 NumEltsToInit = NumElts;
15736 if (
Result.hasValue() && NumEltsToInit <
Result.getArrayInitializedElts())
15737 NumEltsToInit =
Result.getArrayInitializedElts();
15740 LLVM_DEBUG(llvm::dbgs() <<
"The number of elements to initialize: "
15741 << NumEltsToInit <<
".\n");
15743 if (!
Result.hasValue()) {
15744 Result =
APValue(APValue::UninitArray(), NumEltsToInit, NumElts);
15745 }
else if (
Result.getArrayInitializedElts() != NumEltsToInit) {
15756 APValue NewResult =
APValue(APValue::UninitArray(), NumEltsToInit, NumElts);
15758 unsigned NumOldElts =
Result.getArrayInitializedElts();
15759 for (
unsigned I = 0; I < NumOldElts; ++I) {
15761 std::move(
Result.getArrayInitializedElt(I));
15764 for (
unsigned I =
Result.getArrayInitializedElts(); I < NumEltsToInit; ++I)
15768 Result = std::move(NewResult);
15771 LValue Subobject =
This;
15772 Subobject.addArray(Info, ExprToVisit, CAT);
15773 auto Eval = [&](
const Expr *
Init,
unsigned ArrayIndex) {
15774 if (
Init->isValueDependent())
15783 Subobject,
Init) ||
15786 if (!Info.noteFailure())
15792 unsigned ArrayIndex = 0;
15795 for (
unsigned Index = 0; Index != NumEltsToInit; ++Index) {
15796 const Expr *
Init = Index < Args.size() ? Args[Index] : ArrayFiller;
15797 if (ArrayIndex >= NumEltsToInit)
15799 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
15800 StringLiteral *SL = EmbedS->getDataStringLiteral();
15801 for (
unsigned I = EmbedS->getStartingElementPos(),
15802 N = EmbedS->getDataElementCount();
15803 I != EmbedS->getStartingElementPos() + N; ++I) {
15809 const FPOptions FPO =
15810 Init->getFPFeaturesInEffect(Info.Ctx.getLangOpts());
15815 Result.getArrayInitializedElt(ArrayIndex) =
APValue(FValue);
15820 if (!Eval(
Init, ArrayIndex))
15826 if (!
Result.hasArrayFiller())
15831 assert(ArrayFiller &&
"no array filler for incomplete init list");
15837bool ArrayExprEvaluator::VisitArrayInitLoopExpr(
const ArrayInitLoopExpr *E) {
15840 !
Evaluate(Info.CurrentCall->createTemporary(
15843 ScopeKind::FullExpression, CommonLV),
15850 Result =
APValue(APValue::UninitArray(), Elements, Elements);
15852 LValue Subobject =
This;
15853 Subobject.addArray(Info, E, CAT);
15856 for (EvalInfo::ArrayInitLoopIndex Index(Info); Index != Elements; ++Index) {
15865 FullExpressionRAII Scope(Info);
15871 if (!Info.noteFailure())
15883bool ArrayExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E) {
15884 return VisitCXXConstructExpr(E, This, &
Result, E->
getType());
15887bool ArrayExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E,
15888 const LValue &Subobject,
15891 bool HadZeroInit =
Value->hasValue();
15893 if (
const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(
Type)) {
15898 HadZeroInit &&
Value->hasArrayFiller() ?
Value->getArrayFiller()
15901 *
Value =
APValue(APValue::UninitArray(), 0, FinalSize);
15902 if (FinalSize == 0)
15908 LValue ArrayElt = Subobject;
15909 ArrayElt.addArray(Info, E, CAT);
15915 for (
const unsigned N : {1u, FinalSize}) {
15916 unsigned OldElts =
Value->getArrayInitializedElts();
15921 APValue NewValue(APValue::UninitArray(), N, FinalSize);
15922 for (
unsigned I = 0; I < OldElts; ++I)
15923 NewValue.getArrayInitializedElt(I).swap(
15924 Value->getArrayInitializedElt(I));
15925 Value->swap(NewValue);
15928 for (
unsigned I = OldElts; I < N; ++I)
15929 Value->getArrayInitializedElt(I) = Filler;
15931 if (HasTrivialConstructor && N == FinalSize && FinalSize != 1) {
15934 APValue &FirstResult =
Value->getArrayInitializedElt(0);
15935 for (
unsigned I = OldElts; I < FinalSize; ++I)
15936 Value->getArrayInitializedElt(I) = FirstResult;
15938 for (
unsigned I = OldElts; I < N; ++I) {
15939 if (!VisitCXXConstructExpr(E, ArrayElt,
15940 &
Value->getArrayInitializedElt(I),
15947 if (Info.EvalStatus.Diag && !Info.EvalStatus.Diag->empty() &&
15948 !Info.keepEvaluatingAfterFailure())
15957 if (!
Type->isRecordType())
15960 return RecordExprEvaluator(Info, Subobject, *
Value)
15961 .VisitCXXConstructExpr(E,
Type);
15964bool ArrayExprEvaluator::VisitCXXParenListInitExpr(
15965 const CXXParenListInitExpr *E) {
15967 "Expression result is not a constant array type");
15969 return VisitCXXParenListOrInitListExpr(E, E->
getInitExprs(),
15973bool ArrayExprEvaluator::VisitDesignatedInitUpdateExpr(
15974 const DesignatedInitUpdateExpr *E) {
15989class IntExprEvaluator
15990 :
public ExprEvaluatorBase<IntExprEvaluator> {
15993 IntExprEvaluator(EvalInfo &info,
APValue &result)
15994 : ExprEvaluatorBaseTy(
info),
Result(result) {}
15998 "Invalid evaluation result.");
16000 "Invalid evaluation result.");
16001 assert(SI.getBitWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
16002 "Invalid evaluation result.");
16006 bool Success(
const llvm::APSInt &SI,
const Expr *E) {
16012 "Invalid evaluation result.");
16013 assert(I.getBitWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
16014 "Invalid evaluation result.");
16016 Result.getInt().setIsUnsigned(
16020 bool Success(
const llvm::APInt &I,
const Expr *E) {
16026 "Invalid evaluation result.");
16034 bool Success(CharUnits Size,
const Expr *E) {
16041 if (
V.isLValue() ||
V.isAddrLabelDiff() ||
V.isIndeterminate() ||
16042 V.allowConstexprUnknown()) {
16049 bool ZeroInitialization(
const Expr *E) {
return Success(0, E); }
16051 friend std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &,
16058 bool VisitIntegerLiteral(
const IntegerLiteral *E) {
16061 bool VisitCharacterLiteral(
const CharacterLiteral *E) {
16065 bool CheckReferencedDecl(
const Expr *E,
const Decl *D);
16066 bool VisitDeclRefExpr(
const DeclRefExpr *E) {
16067 if (CheckReferencedDecl(E, E->
getDecl()))
16070 return ExprEvaluatorBaseTy::VisitDeclRefExpr(E);
16072 bool VisitMemberExpr(
const MemberExpr *E) {
16074 VisitIgnoredBaseExpression(E->
getBase());
16078 return ExprEvaluatorBaseTy::VisitMemberExpr(E);
16081 bool VisitCallExpr(
const CallExpr *E);
16082 bool VisitBuiltinCallExpr(
const CallExpr *E,
unsigned BuiltinOp);
16083 bool VisitBinaryOperator(
const BinaryOperator *E);
16084 bool VisitOffsetOfExpr(
const OffsetOfExpr *E);
16085 bool VisitUnaryOperator(
const UnaryOperator *E);
16087 bool VisitCastExpr(
const CastExpr* E);
16088 bool VisitUnaryExprOrTypeTraitExpr(
const UnaryExprOrTypeTraitExpr *E);
16090 bool VisitCXXBoolLiteralExpr(
const CXXBoolLiteralExpr *E) {
16094 bool VisitObjCBoolLiteralExpr(
const ObjCBoolLiteralExpr *E) {
16098 bool VisitArrayInitIndexExpr(
const ArrayInitIndexExpr *E) {
16099 if (Info.ArrayInitIndex ==
uint64_t(-1)) {
16105 return Success(Info.ArrayInitIndex, E);
16109 bool VisitGNUNullExpr(
const GNUNullExpr *E) {
16110 return ZeroInitialization(E);
16113 bool VisitTypeTraitExpr(
const TypeTraitExpr *E) {
16122 bool VisitArrayTypeTraitExpr(
const ArrayTypeTraitExpr *E) {
16126 bool VisitExpressionTraitExpr(
const ExpressionTraitExpr *E) {
16130 bool VisitOpenACCAsteriskSizeExpr(
const OpenACCAsteriskSizeExpr *E) {
16137 bool VisitUnaryReal(
const UnaryOperator *E);
16138 bool VisitUnaryImag(
const UnaryOperator *E);
16140 bool VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E);
16141 bool VisitSizeOfPackExpr(
const SizeOfPackExpr *E);
16142 bool VisitSourceLocExpr(
const SourceLocExpr *E);
16143 bool VisitConceptSpecializationExpr(
const ConceptSpecializationExpr *E);
16148class FixedPointExprEvaluator
16149 :
public ExprEvaluatorBase<FixedPointExprEvaluator> {
16153 FixedPointExprEvaluator(EvalInfo &info,
APValue &result)
16154 : ExprEvaluatorBaseTy(
info),
Result(result) {}
16156 bool Success(
const llvm::APInt &I,
const Expr *E) {
16158 APFixedPoint(I, Info.Ctx.getFixedPointSemantics(E->
getType())), E);
16163 APFixedPoint(
Value, Info.Ctx.getFixedPointSemantics(E->
getType())), E);
16167 return Success(
V.getFixedPoint(), E);
16170 bool Success(
const APFixedPoint &
V,
const Expr *E) {
16172 assert(
V.getWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
16173 "Invalid evaluation result.");
16178 bool ZeroInitialization(
const Expr *E) {
16186 bool VisitFixedPointLiteral(
const FixedPointLiteral *E) {
16190 bool VisitCastExpr(
const CastExpr *E);
16191 bool VisitUnaryOperator(
const UnaryOperator *E);
16192 bool VisitBinaryOperator(
const BinaryOperator *E);
16208 return IntExprEvaluator(Info,
Result).Visit(E);
16216 if (!Val.
isInt()) {
16219 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
16226bool IntExprEvaluator::VisitSourceLocExpr(
const SourceLocExpr *E) {
16228 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.
getDefaultExpr());
16237 if (!FixedPointExprEvaluator(Info, Val).Visit(E))
16252 auto FXSema = Info.Ctx.getFixedPointSemantics(E->
getType());
16256 Result = APFixedPoint(Val, FXSema);
16267bool IntExprEvaluator::CheckReferencedDecl(
const Expr* E,
const Decl* D) {
16269 if (
const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(D)) {
16271 bool SameSign = (ECD->getInitVal().isSigned()
16273 bool SameWidth = (ECD->getInitVal().
getBitWidth()
16274 == Info.Ctx.getIntWidth(E->
getType()));
16275 if (SameSign && SameWidth)
16276 return Success(ECD->getInitVal(), E);
16280 llvm::APSInt Val = ECD->getInitVal();
16282 Val.setIsSigned(!ECD->getInitVal().isSigned());
16284 Val = Val.extOrTrunc(Info.Ctx.getIntWidth(E->
getType()));
16295 assert(!
T->isDependentType() &&
"unexpected dependent type");
16300#define TYPE(ID, BASE)
16301#define DEPENDENT_TYPE(ID, BASE) case Type::ID:
16302#define NON_CANONICAL_TYPE(ID, BASE) case Type::ID:
16303#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(ID, BASE) case Type::ID:
16304#include "clang/AST/TypeNodes.inc"
16306 case Type::DeducedTemplateSpecialization:
16307 llvm_unreachable(
"unexpected non-canonical or dependent type");
16309 case Type::Builtin:
16311#define BUILTIN_TYPE(ID, SINGLETON_ID)
16312#define SIGNED_TYPE(ID, SINGLETON_ID) \
16313 case BuiltinType::ID: return GCCTypeClass::Integer;
16314#define FLOATING_TYPE(ID, SINGLETON_ID) \
16315 case BuiltinType::ID: return GCCTypeClass::RealFloat;
16316#define PLACEHOLDER_TYPE(ID, SINGLETON_ID) \
16317 case BuiltinType::ID: break;
16318#include "clang/AST/BuiltinTypes.def"
16319 case BuiltinType::Void:
16322 case BuiltinType::Bool:
16325 case BuiltinType::Char_U:
16326 case BuiltinType::UChar:
16327 case BuiltinType::WChar_U:
16328 case BuiltinType::Char8:
16329 case BuiltinType::Char16:
16330 case BuiltinType::Char32:
16331 case BuiltinType::UShort:
16332 case BuiltinType::UInt:
16333 case BuiltinType::ULong:
16334 case BuiltinType::ULongLong:
16335 case BuiltinType::UInt128:
16338 case BuiltinType::UShortAccum:
16339 case BuiltinType::UAccum:
16340 case BuiltinType::ULongAccum:
16341 case BuiltinType::UShortFract:
16342 case BuiltinType::UFract:
16343 case BuiltinType::ULongFract:
16344 case BuiltinType::SatUShortAccum:
16345 case BuiltinType::SatUAccum:
16346 case BuiltinType::SatULongAccum:
16347 case BuiltinType::SatUShortFract:
16348 case BuiltinType::SatUFract:
16349 case BuiltinType::SatULongFract:
16352 case BuiltinType::NullPtr:
16354 case BuiltinType::ObjCId:
16355 case BuiltinType::ObjCClass:
16356 case BuiltinType::ObjCSel:
16357#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
16358 case BuiltinType::Id:
16359#include "clang/Basic/OpenCLImageTypes.def"
16360#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
16361 case BuiltinType::Id:
16362#include "clang/Basic/OpenCLExtensionTypes.def"
16363 case BuiltinType::OCLSampler:
16364 case BuiltinType::OCLEvent:
16365 case BuiltinType::OCLClkEvent:
16366 case BuiltinType::OCLQueue:
16367 case BuiltinType::OCLReserveID:
16368#define SVE_TYPE(Name, Id, SingletonId) \
16369 case BuiltinType::Id:
16370#include "clang/Basic/AArch64ACLETypes.def"
16371#define PPC_VECTOR_TYPE(Name, Id, Size) \
16372 case BuiltinType::Id:
16373#include "clang/Basic/PPCTypes.def"
16374#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
16375#include "clang/Basic/RISCVVTypes.def"
16376#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
16377#include "clang/Basic/WebAssemblyReferenceTypes.def"
16378#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
16379#include "clang/Basic/AMDGPUTypes.def"
16380#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
16381#include "clang/Basic/HLSLIntangibleTypes.def"
16382#define SPIRV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
16383#include "clang/Basic/SPIRVTypes.def"
16386 case BuiltinType::Dependent:
16387 llvm_unreachable(
"unexpected dependent type");
16389 llvm_unreachable(
"unexpected placeholder type");
16394 case Type::Pointer:
16395 case Type::ConstantArray:
16396 case Type::VariableArray:
16397 case Type::IncompleteArray:
16398 case Type::FunctionNoProto:
16399 case Type::FunctionProto:
16400 case Type::ArrayParameter:
16403 case Type::MemberPointer:
16408 case Type::Complex:
16421 case Type::ExtVector:
16424 case Type::BlockPointer:
16425 case Type::ConstantMatrix:
16426 case Type::ObjCObject:
16427 case Type::ObjCInterface:
16428 case Type::ObjCObjectPointer:
16430 case Type::HLSLAttributedResource:
16431 case Type::HLSLInlineSpirv:
16432 case Type::OverflowBehavior:
16440 case Type::LValueReference:
16441 case Type::RValueReference:
16442 llvm_unreachable(
"invalid type for expression");
16445 llvm_unreachable(
"unexpected type class");
16470 if (
Base.isNull()) {
16473 }
else if (
const Expr *E =
Base.dyn_cast<
const Expr *>()) {
16492 SpeculativeEvaluationRAII SpeculativeEval(Info);
16497 FoldConstant Fold(Info,
true);
16515 if (ArgType->isIntegralOrEnumerationType() || ArgType->isFloatingType() ||
16516 ArgType->isAnyComplexType() || ArgType->isPointerType() ||
16517 ArgType->isNullPtrType()) {
16520 Fold.keepDiagnostics();
16529 return V.hasValue();
16540 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
16564 const auto *Cast = dyn_cast<CastExpr>(NoParens);
16565 if (Cast ==
nullptr)
16570 auto CastKind = Cast->getCastKind();
16572 CastKind != CK_AddressSpaceConversion)
16575 const auto *SubExpr = Cast->getSubExpr();
16597 assert(!LVal.Designator.Invalid);
16599 auto IsLastOrInvalidFieldDecl = [&Ctx](
const FieldDecl *FD) {
16607 auto &
Base = LVal.getLValueBase();
16608 if (
auto *ME = dyn_cast_or_null<MemberExpr>(
Base.dyn_cast<
const Expr *>())) {
16609 if (
auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
16610 if (!IsLastOrInvalidFieldDecl(FD))
16612 }
else if (
auto *IFD = dyn_cast<IndirectFieldDecl>(ME->getMemberDecl())) {
16613 for (
auto *FD : IFD->chain()) {
16622 if (LVal.Designator.FirstEntryIsAnUnsizedArray) {
16626 if (BaseType->isIncompleteArrayType())
16632 for (
unsigned E = LVal.Designator.Entries.size(); I != E; ++I) {
16633 const auto &Entry = LVal.Designator.Entries[I];
16634 if (BaseType->isArrayType()) {
16640 uint64_t Index = Entry.getAsArrayIndex();
16644 }
else if (BaseType->isAnyComplexType()) {
16645 const auto *CT = BaseType->castAs<
ComplexType>();
16646 uint64_t Index = Entry.getAsArrayIndex();
16649 BaseType = CT->getElementType();
16650 }
else if (
auto *FD = getAsField(Entry)) {
16651 if (!IsLastOrInvalidFieldDecl(FD))
16655 assert(getAsBaseClass(Entry) &&
"Expecting cast to a base class");
16667 if (LVal.Designator.Invalid)
16670 if (!LVal.Designator.Entries.empty())
16671 return LVal.Designator.isMostDerivedAnUnsizedArray();
16673 if (!LVal.InvalidBase)
16685 const SubobjectDesignator &
Designator = LVal.Designator;
16697 auto isFlexibleArrayMember = [&] {
16699 FAMKind StrictFlexArraysLevel =
16702 if (
Designator.isMostDerivedAnUnsizedArray())
16705 if (StrictFlexArraysLevel == FAMKind::Default)
16708 if (
Designator.getMostDerivedArraySize() == 0 &&
16709 StrictFlexArraysLevel != FAMKind::IncompleteOnly)
16712 if (
Designator.getMostDerivedArraySize() == 1 &&
16713 StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete)
16719 return LVal.InvalidBase &&
16721 Designator.MostDerivedIsArrayElement && isFlexibleArrayMember() &&
16729 auto CharUnitsMax = std::numeric_limits<CharUnits::QuantityType>::max();
16730 if (Int.ugt(CharUnitsMax))
16740 if (!
T.isNull() &&
T->isStructureType() &&
16741 T->castAsRecordDecl()->hasFlexibleArrayMember())
16742 if (
const auto *
V = LV.getLValueBase().dyn_cast<
const ValueDecl *>())
16743 if (
const auto *VD = dyn_cast<VarDecl>(
V))
16755 unsigned Type,
const LValue &LVal,
16774 if (!(
Type & 1) || LVal.Designator.Invalid || DetermineForCompleteObject) {
16776 if (
Type == 3 && !DetermineForCompleteObject)
16779 llvm::APInt APEndOffset;
16780 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
16784 if (LVal.InvalidBase)
16788 const bool Ret = CheckedHandleSizeof(BaseTy, EndOffset);
16794 const SubobjectDesignator &
Designator = LVal.Designator;
16806 llvm::APInt APEndOffset;
16807 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
16819 if (!CheckedHandleSizeof(
Designator.MostDerivedType, BytesPerElem))
16825 int64_t ElemsRemaining;
16828 uint64_t ArraySize =
Designator.getMostDerivedArraySize();
16829 uint64_t ArrayIndex =
Designator.Entries.back().getAsArrayIndex();
16830 ElemsRemaining = ArraySize <= ArrayIndex ? 0 : ArraySize - ArrayIndex;
16832 ElemsRemaining =
Designator.isOnePastTheEnd() ? 0 : 1;
16835 EndOffset = LVal.getLValueOffset() + BytesPerElem * ElemsRemaining;
16845static std::optional<uint64_t>
16847 bool IsDynamic =
false) {
16855 SpeculativeEvaluationRAII SpeculativeEval(Info);
16856 IgnoreSideEffectsRAII Fold(Info);
16863 return std::nullopt;
16864 LVal.setFrom(Info.Ctx, RVal);
16867 return std::nullopt;
16872 if (LVal.getLValueOffset().isNegative())
16887 const auto *FD = ME ? dyn_cast<FieldDecl>(ME->getMemberDecl()) :
nullptr;
16889 return std::nullopt;
16894 return std::nullopt;
16898 if (EndOffset <= LVal.getLValueOffset())
16900 return (EndOffset - LVal.getLValueOffset()).
getQuantity();
16903bool IntExprEvaluator::VisitCallExpr(
const CallExpr *E) {
16904 if (!IsConstantEvaluatedBuiltinCall(E))
16905 return ExprEvaluatorBaseTy::VisitCallExpr(E);
16922 Info.FFDiag(E->
getArg(0));
16928 assert(SrcInt.getBitWidth() >= Alignment.getBitWidth() &&
16929 "Bit widths must be the same");
16936bool IntExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *E,
16937 unsigned BuiltinOp) {
16938 auto EvalTestOp = [&](llvm::function_ref<
bool(
const APInt &,
const APInt &)>
16940 APValue SourceLHS, SourceRHS;
16948 unsigned LaneWidth = Info.Ctx.getTypeSize(ElemQT);
16950 APInt AWide(LaneWidth * SourceLen, 0);
16951 APInt BWide(LaneWidth * SourceLen, 0);
16953 for (
unsigned I = 0; I != SourceLen; ++I) {
16956 if (ElemQT->isIntegerType()) {
16959 }
else if (ElemQT->isFloatingType()) {
16967 AWide.insertBits(ALane, I * LaneWidth);
16968 BWide.insertBits(BLane, I * LaneWidth);
16973 auto HandleMaskBinOp =
16986 auto HandleCRC32 = [&](
unsigned DataBytes) ->
bool {
16992 uint64_t CRCVal = CRC.getZExtValue();
16996 static const uint32_t CRC32C_POLY = 0x82F63B78;
17000 for (
unsigned I = 0; I != DataBytes; ++I) {
17001 uint8_t Byte =
static_cast<uint8_t>((DataVal >> (I * 8)) & 0xFF);
17003 for (
int J = 0; J != 8; ++J) {
17011 switch (BuiltinOp) {
17015 case X86::BI__builtin_ia32_crc32qi:
17016 return HandleCRC32(1);
17017 case X86::BI__builtin_ia32_crc32hi:
17018 return HandleCRC32(2);
17019 case X86::BI__builtin_ia32_crc32si:
17020 return HandleCRC32(4);
17021 case X86::BI__builtin_ia32_crc32di:
17022 return HandleCRC32(8);
17024 case Builtin::BI__builtin_dynamic_object_size:
17025 case Builtin::BI__builtin_object_size: {
17029 assert(
Type <= 3 &&
"unexpected type");
17031 bool IsDynamic = BuiltinOp == Builtin::BI__builtin_dynamic_object_size;
17032 if (std::optional<uint64_t> Size =
17041 switch (Info.EvalMode) {
17042 case EvaluationMode::ConstantExpression:
17043 case EvaluationMode::ConstantFold:
17044 case EvaluationMode::IgnoreSideEffects:
17047 case EvaluationMode::ConstantExpressionUnevaluated:
17052 llvm_unreachable(
"unexpected EvalMode");
17055 case Builtin::BI__builtin_os_log_format_buffer_size: {
17056 analyze_os_log::OSLogBufferLayout Layout;
17061 case Builtin::BI__builtin_is_aligned: {
17069 Ptr.setFrom(Info.Ctx, Src);
17075 assert(Alignment.isPowerOf2());
17088 Info.FFDiag(E->
getArg(0), diag::note_constexpr_alignment_compute)
17092 assert(Src.
isInt());
17093 return Success((Src.
getInt() & (Alignment - 1)) == 0 ? 1 : 0, E);
17095 case Builtin::BI__builtin_align_up: {
17103 APSInt((Src.
getInt() + (Alignment - 1)) & ~(Alignment - 1),
17104 Src.
getInt().isUnsigned());
17105 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
17106 return Success(AlignedVal, E);
17108 case Builtin::BI__builtin_align_down: {
17117 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
17118 return Success(AlignedVal, E);
17121 case Builtin::BI__builtin_bitreverseg:
17122 case Builtin::BI__builtin_bitreverse8:
17123 case Builtin::BI__builtin_bitreverse16:
17124 case Builtin::BI__builtin_bitreverse32:
17125 case Builtin::BI__builtin_bitreverse64:
17126 case Builtin::BI__builtin_elementwise_bitreverse: {
17131 return Success(Val.reverseBits(), E);
17133 case Builtin::BI__builtin_bswapg:
17134 case Builtin::BI__builtin_bswap16:
17135 case Builtin::BI__builtin_bswap32:
17136 case Builtin::BI__builtin_bswap64:
17137 case Builtin::BIstdc_memreverse8u8:
17138 case Builtin::BIstdc_memreverse8u16:
17139 case Builtin::BIstdc_memreverse8u32:
17140 case Builtin::BIstdc_memreverse8u64: {
17144 if (Val.getBitWidth() == 8 || Val.getBitWidth() == 1)
17147 return Success(Val.byteSwap(), E);
17150 case Builtin::BI__builtin_classify_type:
17153 case Builtin::BI__builtin_clrsb:
17154 case Builtin::BI__builtin_clrsbl:
17155 case Builtin::BI__builtin_clrsbll: {
17160 return Success(Val.getBitWidth() - Val.getSignificantBits(), E);
17163 case Builtin::BI__builtin_clz:
17164 case Builtin::BI__builtin_clzl:
17165 case Builtin::BI__builtin_clzll:
17166 case Builtin::BI__builtin_clzs:
17167 case Builtin::BI__builtin_clzg:
17168 case Builtin::BI__builtin_elementwise_clzg:
17169 case Builtin::BI__lzcnt16:
17170 case Builtin::BI__lzcnt:
17171 case Builtin::BI__lzcnt64: {
17182 std::optional<APSInt> Fallback;
17183 if ((BuiltinOp == Builtin::BI__builtin_clzg ||
17184 BuiltinOp == Builtin::BI__builtin_elementwise_clzg) &&
17189 Fallback = FallbackTemp;
17194 return Success(*Fallback, E);
17199 bool ZeroIsUndefined = BuiltinOp != Builtin::BI__lzcnt16 &&
17200 BuiltinOp != Builtin::BI__lzcnt &&
17201 BuiltinOp != Builtin::BI__lzcnt64;
17203 if (BuiltinOp == Builtin::BI__builtin_elementwise_clzg) {
17204 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
17208 if (ZeroIsUndefined)
17212 return Success(Val.countl_zero(), E);
17215 case Builtin::BI__builtin_constant_p: {
17216 const Expr *Arg = E->
getArg(0);
17225 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
17229 case Builtin::BI__noop:
17233 case Builtin::BI__builtin_is_constant_evaluated: {
17234 const auto *
Callee = Info.CurrentCall->getCallee();
17235 if (Info.InConstantContext && !Info.CheckingPotentialConstantExpression &&
17236 (Info.CallStackDepth == 1 ||
17237 (Info.CallStackDepth == 2 &&
Callee->isInStdNamespace() &&
17238 Callee->getIdentifier() &&
17239 Callee->getIdentifier()->isStr(
"is_constant_evaluated")))) {
17241 if (Info.EvalStatus.Diag)
17242 Info.report((Info.CallStackDepth == 1)
17244 : Info.CurrentCall->getCallRange().getBegin(),
17245 diag::warn_is_constant_evaluated_always_true_constexpr)
17246 << (Info.CallStackDepth == 1 ?
"__builtin_is_constant_evaluated"
17247 :
"std::is_constant_evaluated");
17250 return Success(Info.InConstantContext, E);
17253 case Builtin::BI__builtin_is_within_lifetime:
17254 if (
auto result = EvaluateBuiltinIsWithinLifetime(*
this, E))
17258 case Builtin::BI__builtin_ctz:
17259 case Builtin::BI__builtin_ctzl:
17260 case Builtin::BI__builtin_ctzll:
17261 case Builtin::BI__builtin_ctzs:
17262 case Builtin::BI__builtin_ctzg:
17263 case Builtin::BI__builtin_elementwise_ctzg: {
17274 std::optional<APSInt> Fallback;
17275 if ((BuiltinOp == Builtin::BI__builtin_ctzg ||
17276 BuiltinOp == Builtin::BI__builtin_elementwise_ctzg) &&
17281 Fallback = FallbackTemp;
17286 return Success(*Fallback, E);
17288 if (BuiltinOp == Builtin::BI__builtin_elementwise_ctzg) {
17289 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
17295 return Success(Val.countr_zero(), E);
17298 case Builtin::BI__builtin_eh_return_data_regno: {
17300 Operand = Info.Ctx.getTargetInfo().getEHDataRegisterNumber(Operand);
17304 case Builtin::BI__builtin_elementwise_abs: {
17309 return Success(Val.abs(), E);
17312 case Builtin::BI__builtin_expect:
17313 case Builtin::BI__builtin_expect_with_probability:
17314 return Visit(E->
getArg(0));
17316 case Builtin::BI__builtin_ptrauth_string_discriminator: {
17323 case Builtin::BI__builtin_infer_alloc_token: {
17329 E, diag::note_constexpr_infer_alloc_token_type_inference_failed);
17332 return Error(E, diag::note_constexpr_infer_alloc_token_no_metadata);
17334 Info.getLangOpts().AllocTokenMode.value_or(llvm::DefaultAllocTokenMode);
17335 uint64_t BitWidth = Info.Ctx.getTypeSize(Info.Ctx.getSizeType());
17336 auto MaxTokensOpt = Info.getLangOpts().AllocTokenMax;
17338 MaxTokensOpt.value_or(0) ? *MaxTokensOpt : (~0ULL >> (64 - BitWidth));
17339 auto MaybeToken = llvm::getAllocToken(Mode, *ATMD, MaxTokens);
17341 return Error(E, diag::note_constexpr_infer_alloc_token_stateful_mode);
17342 return Success(llvm::APInt(BitWidth, *MaybeToken), E);
17345 case Builtin::BI__builtin_ffs:
17346 case Builtin::BI__builtin_ffsl:
17347 case Builtin::BI__builtin_ffsll: {
17352 unsigned N = Val.countr_zero();
17353 return Success(N == Val.getBitWidth() ? 0 : N + 1, E);
17356 case Builtin::BI__builtin_fpclassify: {
17361 switch (Val.getCategory()) {
17362 case APFloat::fcNaN: Arg = 0;
break;
17363 case APFloat::fcInfinity: Arg = 1;
break;
17364 case APFloat::fcNormal: Arg = Val.isDenormal() ? 3 : 2;
break;
17365 case APFloat::fcZero: Arg = 4;
break;
17367 return Visit(E->
getArg(Arg));
17370 case Builtin::BI__builtin_isinf_sign: {
17373 Success(Val.isInfinity() ? (Val.isNegative() ? -1 : 1) : 0, E);
17376 case Builtin::BI__builtin_isinf: {
17379 Success(Val.isInfinity() ? 1 : 0, E);
17382 case Builtin::BI__builtin_isfinite: {
17385 Success(Val.isFinite() ? 1 : 0, E);
17388 case Builtin::BI__builtin_isnan: {
17391 Success(Val.isNaN() ? 1 : 0, E);
17394 case Builtin::BI__builtin_isnormal: {
17397 Success(Val.isNormal() ? 1 : 0, E);
17400 case Builtin::BI__builtin_issubnormal: {
17403 Success(Val.isDenormal() ? 1 : 0, E);
17406 case Builtin::BI__builtin_iszero: {
17409 Success(Val.isZero() ? 1 : 0, E);
17412 case Builtin::BI__builtin_signbit:
17413 case Builtin::BI__builtin_signbitf:
17414 case Builtin::BI__builtin_signbitl: {
17417 Success(Val.isNegative() ? 1 : 0, E);
17420 case Builtin::BI__builtin_isgreater:
17421 case Builtin::BI__builtin_isgreaterequal:
17422 case Builtin::BI__builtin_isless:
17423 case Builtin::BI__builtin_islessequal:
17424 case Builtin::BI__builtin_islessgreater:
17425 case Builtin::BI__builtin_isunordered: {
17434 switch (BuiltinOp) {
17435 case Builtin::BI__builtin_isgreater:
17437 case Builtin::BI__builtin_isgreaterequal:
17439 case Builtin::BI__builtin_isless:
17441 case Builtin::BI__builtin_islessequal:
17443 case Builtin::BI__builtin_islessgreater: {
17444 APFloat::cmpResult cmp = LHS.compare(RHS);
17445 return cmp == APFloat::cmpResult::cmpLessThan ||
17446 cmp == APFloat::cmpResult::cmpGreaterThan;
17448 case Builtin::BI__builtin_isunordered:
17449 return LHS.compare(RHS) == APFloat::cmpResult::cmpUnordered;
17451 llvm_unreachable(
"Unexpected builtin ID: Should be a floating "
17452 "point comparison function");
17460 case Builtin::BI__builtin_issignaling: {
17463 Success(Val.isSignaling() ? 1 : 0, E);
17466 case Builtin::BI__builtin_isfpclass: {
17470 unsigned Test =
static_cast<llvm::FPClassTest
>(MaskVal.getZExtValue());
17473 Success((Val.classify() & Test) ? 1 : 0, E);
17476 case Builtin::BI__builtin_parity:
17477 case Builtin::BI__builtin_parityl:
17478 case Builtin::BI__builtin_parityll: {
17483 return Success(Val.popcount() % 2, E);
17486 case Builtin::BI__builtin_abs:
17487 case Builtin::BI__builtin_labs:
17488 case Builtin::BI__builtin_llabs: {
17492 if (Val ==
APSInt(APInt::getSignedMinValue(Val.getBitWidth()),
17495 if (Val.isNegative())
17500 case Builtin::BI__builtin_popcount:
17501 case Builtin::BI__builtin_popcountl:
17502 case Builtin::BI__builtin_popcountll:
17503 case Builtin::BI__builtin_popcountg:
17504 case Builtin::BI__builtin_elementwise_popcount:
17505 case Builtin::BI__popcnt16:
17506 case Builtin::BI__popcnt:
17507 case Builtin::BI__popcnt64: {
17518 return Success(Val.popcount(), E);
17521 case Builtin::BI__builtin_rotateleft8:
17522 case Builtin::BI__builtin_rotateleft16:
17523 case Builtin::BI__builtin_rotateleft32:
17524 case Builtin::BI__builtin_rotateleft64:
17525 case Builtin::BI__builtin_rotateright8:
17526 case Builtin::BI__builtin_rotateright16:
17527 case Builtin::BI__builtin_rotateright32:
17528 case Builtin::BI__builtin_rotateright64:
17529 case Builtin::BI__builtin_stdc_rotate_left:
17530 case Builtin::BI__builtin_stdc_rotate_right:
17531 case Builtin::BIstdc_rotate_left_uc:
17532 case Builtin::BIstdc_rotate_left_us:
17533 case Builtin::BIstdc_rotate_left_ui:
17534 case Builtin::BIstdc_rotate_left_ul:
17535 case Builtin::BIstdc_rotate_left_ull:
17536 case Builtin::BIstdc_rotate_right_uc:
17537 case Builtin::BIstdc_rotate_right_us:
17538 case Builtin::BIstdc_rotate_right_ui:
17539 case Builtin::BIstdc_rotate_right_ul:
17540 case Builtin::BIstdc_rotate_right_ull:
17541 case Builtin::BI_rotl8:
17542 case Builtin::BI_rotl16:
17543 case Builtin::BI_rotl:
17544 case Builtin::BI_lrotl:
17545 case Builtin::BI_rotl64:
17546 case Builtin::BI_rotr8:
17547 case Builtin::BI_rotr16:
17548 case Builtin::BI_rotr:
17549 case Builtin::BI_lrotr:
17550 case Builtin::BI_rotr64: {
17558 switch (BuiltinOp) {
17559 case Builtin::BI__builtin_rotateright8:
17560 case Builtin::BI__builtin_rotateright16:
17561 case Builtin::BI__builtin_rotateright32:
17562 case Builtin::BI__builtin_rotateright64:
17563 case Builtin::BI__builtin_stdc_rotate_right:
17564 case Builtin::BIstdc_rotate_right_uc:
17565 case Builtin::BIstdc_rotate_right_us:
17566 case Builtin::BIstdc_rotate_right_ui:
17567 case Builtin::BIstdc_rotate_right_ul:
17568 case Builtin::BIstdc_rotate_right_ull:
17569 case Builtin::BI_rotr8:
17570 case Builtin::BI_rotr16:
17571 case Builtin::BI_rotr:
17572 case Builtin::BI_lrotr:
17573 case Builtin::BI_rotr64:
17582 case Builtin::BIstdc_leading_zeros_uc:
17583 case Builtin::BIstdc_leading_zeros_us:
17584 case Builtin::BIstdc_leading_zeros_ui:
17585 case Builtin::BIstdc_leading_zeros_ul:
17586 case Builtin::BIstdc_leading_zeros_ull:
17587 case Builtin::BIstdc_leading_ones_uc:
17588 case Builtin::BIstdc_leading_ones_us:
17589 case Builtin::BIstdc_leading_ones_ui:
17590 case Builtin::BIstdc_leading_ones_ul:
17591 case Builtin::BIstdc_leading_ones_ull:
17592 case Builtin::BIstdc_trailing_zeros_uc:
17593 case Builtin::BIstdc_trailing_zeros_us:
17594 case Builtin::BIstdc_trailing_zeros_ui:
17595 case Builtin::BIstdc_trailing_zeros_ul:
17596 case Builtin::BIstdc_trailing_zeros_ull:
17597 case Builtin::BIstdc_trailing_ones_uc:
17598 case Builtin::BIstdc_trailing_ones_us:
17599 case Builtin::BIstdc_trailing_ones_ui:
17600 case Builtin::BIstdc_trailing_ones_ul:
17601 case Builtin::BIstdc_trailing_ones_ull:
17602 case Builtin::BIstdc_first_leading_zero_uc:
17603 case Builtin::BIstdc_first_leading_zero_us:
17604 case Builtin::BIstdc_first_leading_zero_ui:
17605 case Builtin::BIstdc_first_leading_zero_ul:
17606 case Builtin::BIstdc_first_leading_zero_ull:
17607 case Builtin::BIstdc_first_leading_one_uc:
17608 case Builtin::BIstdc_first_leading_one_us:
17609 case Builtin::BIstdc_first_leading_one_ui:
17610 case Builtin::BIstdc_first_leading_one_ul:
17611 case Builtin::BIstdc_first_leading_one_ull:
17612 case Builtin::BIstdc_first_trailing_zero_uc:
17613 case Builtin::BIstdc_first_trailing_zero_us:
17614 case Builtin::BIstdc_first_trailing_zero_ui:
17615 case Builtin::BIstdc_first_trailing_zero_ul:
17616 case Builtin::BIstdc_first_trailing_zero_ull:
17617 case Builtin::BIstdc_first_trailing_one_uc:
17618 case Builtin::BIstdc_first_trailing_one_us:
17619 case Builtin::BIstdc_first_trailing_one_ui:
17620 case Builtin::BIstdc_first_trailing_one_ul:
17621 case Builtin::BIstdc_first_trailing_one_ull:
17622 case Builtin::BIstdc_count_zeros_uc:
17623 case Builtin::BIstdc_count_zeros_us:
17624 case Builtin::BIstdc_count_zeros_ui:
17625 case Builtin::BIstdc_count_zeros_ul:
17626 case Builtin::BIstdc_count_zeros_ull:
17627 case Builtin::BIstdc_count_ones_uc:
17628 case Builtin::BIstdc_count_ones_us:
17629 case Builtin::BIstdc_count_ones_ui:
17630 case Builtin::BIstdc_count_ones_ul:
17631 case Builtin::BIstdc_count_ones_ull:
17632 case Builtin::BIstdc_has_single_bit_uc:
17633 case Builtin::BIstdc_has_single_bit_us:
17634 case Builtin::BIstdc_has_single_bit_ui:
17635 case Builtin::BIstdc_has_single_bit_ul:
17636 case Builtin::BIstdc_has_single_bit_ull:
17637 case Builtin::BIstdc_bit_width_uc:
17638 case Builtin::BIstdc_bit_width_us:
17639 case Builtin::BIstdc_bit_width_ui:
17640 case Builtin::BIstdc_bit_width_ul:
17641 case Builtin::BIstdc_bit_width_ull:
17642 case Builtin::BIstdc_bit_floor_uc:
17643 case Builtin::BIstdc_bit_floor_us:
17644 case Builtin::BIstdc_bit_floor_ui:
17645 case Builtin::BIstdc_bit_floor_ul:
17646 case Builtin::BIstdc_bit_floor_ull:
17647 case Builtin::BIstdc_bit_ceil_uc:
17648 case Builtin::BIstdc_bit_ceil_us:
17649 case Builtin::BIstdc_bit_ceil_ui:
17650 case Builtin::BIstdc_bit_ceil_ul:
17651 case Builtin::BIstdc_bit_ceil_ull:
17652 case Builtin::BI__builtin_stdc_leading_zeros:
17653 case Builtin::BI__builtin_stdc_leading_ones:
17654 case Builtin::BI__builtin_stdc_trailing_zeros:
17655 case Builtin::BI__builtin_stdc_trailing_ones:
17656 case Builtin::BI__builtin_stdc_first_leading_zero:
17657 case Builtin::BI__builtin_stdc_first_leading_one:
17658 case Builtin::BI__builtin_stdc_first_trailing_zero:
17659 case Builtin::BI__builtin_stdc_first_trailing_one:
17660 case Builtin::BI__builtin_stdc_count_zeros:
17661 case Builtin::BI__builtin_stdc_count_ones:
17662 case Builtin::BI__builtin_stdc_has_single_bit:
17663 case Builtin::BI__builtin_stdc_bit_width:
17664 case Builtin::BI__builtin_stdc_bit_floor:
17665 case Builtin::BI__builtin_stdc_bit_ceil: {
17670 unsigned BitWidth = Val.getBitWidth();
17671 const unsigned ResBitWidth = Info.Ctx.getIntWidth(E->
getType());
17673 switch (BuiltinOp) {
17674 case Builtin::BIstdc_leading_zeros_uc:
17675 case Builtin::BIstdc_leading_zeros_us:
17676 case Builtin::BIstdc_leading_zeros_ui:
17677 case Builtin::BIstdc_leading_zeros_ul:
17678 case Builtin::BIstdc_leading_zeros_ull:
17679 case Builtin::BI__builtin_stdc_leading_zeros:
17680 return Success(
APInt(ResBitWidth, Val.countl_zero()), E);
17681 case Builtin::BIstdc_leading_ones_uc:
17682 case Builtin::BIstdc_leading_ones_us:
17683 case Builtin::BIstdc_leading_ones_ui:
17684 case Builtin::BIstdc_leading_ones_ul:
17685 case Builtin::BIstdc_leading_ones_ull:
17686 case Builtin::BI__builtin_stdc_leading_ones:
17687 return Success(
APInt(ResBitWidth, Val.countl_one()), E);
17688 case Builtin::BIstdc_trailing_zeros_uc:
17689 case Builtin::BIstdc_trailing_zeros_us:
17690 case Builtin::BIstdc_trailing_zeros_ui:
17691 case Builtin::BIstdc_trailing_zeros_ul:
17692 case Builtin::BIstdc_trailing_zeros_ull:
17693 case Builtin::BI__builtin_stdc_trailing_zeros:
17694 return Success(
APInt(ResBitWidth, Val.countr_zero()), E);
17695 case Builtin::BIstdc_trailing_ones_uc:
17696 case Builtin::BIstdc_trailing_ones_us:
17697 case Builtin::BIstdc_trailing_ones_ui:
17698 case Builtin::BIstdc_trailing_ones_ul:
17699 case Builtin::BIstdc_trailing_ones_ull:
17700 case Builtin::BI__builtin_stdc_trailing_ones:
17701 return Success(
APInt(ResBitWidth, Val.countr_one()), E);
17702 case Builtin::BIstdc_first_leading_zero_uc:
17703 case Builtin::BIstdc_first_leading_zero_us:
17704 case Builtin::BIstdc_first_leading_zero_ui:
17705 case Builtin::BIstdc_first_leading_zero_ul:
17706 case Builtin::BIstdc_first_leading_zero_ull:
17707 case Builtin::BI__builtin_stdc_first_leading_zero:
17709 APInt(ResBitWidth, Val.isAllOnes() ? 0 : Val.countl_one() + 1), E);
17710 case Builtin::BIstdc_first_leading_one_uc:
17711 case Builtin::BIstdc_first_leading_one_us:
17712 case Builtin::BIstdc_first_leading_one_ui:
17713 case Builtin::BIstdc_first_leading_one_ul:
17714 case Builtin::BIstdc_first_leading_one_ull:
17715 case Builtin::BI__builtin_stdc_first_leading_one:
17717 APInt(ResBitWidth, Val.isZero() ? 0 : Val.countl_zero() + 1), E);
17718 case Builtin::BIstdc_first_trailing_zero_uc:
17719 case Builtin::BIstdc_first_trailing_zero_us:
17720 case Builtin::BIstdc_first_trailing_zero_ui:
17721 case Builtin::BIstdc_first_trailing_zero_ul:
17722 case Builtin::BIstdc_first_trailing_zero_ull:
17723 case Builtin::BI__builtin_stdc_first_trailing_zero:
17725 APInt(ResBitWidth, Val.isAllOnes() ? 0 : Val.countr_one() + 1), E);
17726 case Builtin::BIstdc_first_trailing_one_uc:
17727 case Builtin::BIstdc_first_trailing_one_us:
17728 case Builtin::BIstdc_first_trailing_one_ui:
17729 case Builtin::BIstdc_first_trailing_one_ul:
17730 case Builtin::BIstdc_first_trailing_one_ull:
17731 case Builtin::BI__builtin_stdc_first_trailing_one:
17733 APInt(ResBitWidth, Val.isZero() ? 0 : Val.countr_zero() + 1), E);
17734 case Builtin::BIstdc_count_zeros_uc:
17735 case Builtin::BIstdc_count_zeros_us:
17736 case Builtin::BIstdc_count_zeros_ui:
17737 case Builtin::BIstdc_count_zeros_ul:
17738 case Builtin::BIstdc_count_zeros_ull:
17739 case Builtin::BI__builtin_stdc_count_zeros: {
17740 APInt Cnt(ResBitWidth, BitWidth - Val.popcount());
17743 case Builtin::BIstdc_count_ones_uc:
17744 case Builtin::BIstdc_count_ones_us:
17745 case Builtin::BIstdc_count_ones_ui:
17746 case Builtin::BIstdc_count_ones_ul:
17747 case Builtin::BIstdc_count_ones_ull:
17748 case Builtin::BI__builtin_stdc_count_ones: {
17749 APInt Cnt(ResBitWidth, Val.popcount());
17752 case Builtin::BIstdc_has_single_bit_uc:
17753 case Builtin::BIstdc_has_single_bit_us:
17754 case Builtin::BIstdc_has_single_bit_ui:
17755 case Builtin::BIstdc_has_single_bit_ul:
17756 case Builtin::BIstdc_has_single_bit_ull:
17757 case Builtin::BI__builtin_stdc_has_single_bit: {
17758 APInt Res(ResBitWidth, Val.popcount() == 1 ? 1 : 0);
17761 case Builtin::BIstdc_bit_width_uc:
17762 case Builtin::BIstdc_bit_width_us:
17763 case Builtin::BIstdc_bit_width_ui:
17764 case Builtin::BIstdc_bit_width_ul:
17765 case Builtin::BIstdc_bit_width_ull:
17766 case Builtin::BI__builtin_stdc_bit_width:
17767 return Success(
APInt(ResBitWidth, BitWidth - Val.countl_zero()), E);
17768 case Builtin::BIstdc_bit_floor_uc:
17769 case Builtin::BIstdc_bit_floor_us:
17770 case Builtin::BIstdc_bit_floor_ui:
17771 case Builtin::BIstdc_bit_floor_ul:
17772 case Builtin::BIstdc_bit_floor_ull:
17773 case Builtin::BI__builtin_stdc_bit_floor: {
17776 unsigned Exp = BitWidth - Val.countl_zero() - 1;
17778 APSInt(APInt::getOneBitSet(BitWidth, Exp),
true), E);
17780 case Builtin::BIstdc_bit_ceil_uc:
17781 case Builtin::BIstdc_bit_ceil_us:
17782 case Builtin::BIstdc_bit_ceil_ui:
17783 case Builtin::BIstdc_bit_ceil_ul:
17784 case Builtin::BIstdc_bit_ceil_ull:
17785 case Builtin::BI__builtin_stdc_bit_ceil: {
17788 APInt ValMinusOne = Val - 1;
17789 unsigned LZ = ValMinusOne.countl_zero();
17793 APInt Result = APInt::getOneBitSet(BitWidth, BitWidth - LZ);
17797 llvm_unreachable(
"Unknown stdc builtin");
17801 case Builtin::BI__builtin_elementwise_add_sat: {
17807 APInt Result = LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS);
17810 case Builtin::BI__builtin_elementwise_sub_sat: {
17816 APInt Result = LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
17819 case Builtin::BI__builtin_elementwise_max: {
17828 case Builtin::BI__builtin_elementwise_min: {
17837 case Builtin::BI__builtin_elementwise_clmul: {
17846 case Builtin::BI__builtin_elementwise_fshl:
17847 case Builtin::BI__builtin_elementwise_fshr: {
17854 switch (BuiltinOp) {
17855 case Builtin::BI__builtin_elementwise_fshl: {
17856 APSInt Result(llvm::APIntOps::fshl(Hi, Lo, Shift), Hi.isUnsigned());
17859 case Builtin::BI__builtin_elementwise_fshr: {
17860 APSInt Result(llvm::APIntOps::fshr(Hi, Lo, Shift), Hi.isUnsigned());
17864 llvm_unreachable(
"Fully covered switch above");
17866 case Builtin::BIstrlen:
17867 case Builtin::BIwcslen:
17869 if (Info.getLangOpts().CPlusPlus11)
17870 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
17872 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
17874 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
17876 case Builtin::BI__builtin_strlen:
17877 case Builtin::BI__builtin_wcslen: {
17880 if (std::optional<uint64_t> StrLen =
17886 case Builtin::BIstrcmp:
17887 case Builtin::BIwcscmp:
17888 case Builtin::BIstrncmp:
17889 case Builtin::BIwcsncmp:
17890 case Builtin::BImemcmp:
17891 case Builtin::BIbcmp:
17892 case Builtin::BIwmemcmp:
17894 if (Info.getLangOpts().CPlusPlus11)
17895 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
17897 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
17899 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
17901 case Builtin::BI__builtin_strcmp:
17902 case Builtin::BI__builtin_wcscmp:
17903 case Builtin::BI__builtin_strncmp:
17904 case Builtin::BI__builtin_wcsncmp:
17905 case Builtin::BI__builtin_memcmp:
17906 case Builtin::BI__builtin_bcmp:
17907 case Builtin::BI__builtin_wmemcmp: {
17908 LValue String1, String2;
17914 if (BuiltinOp != Builtin::BIstrcmp &&
17915 BuiltinOp != Builtin::BIwcscmp &&
17916 BuiltinOp != Builtin::BI__builtin_strcmp &&
17917 BuiltinOp != Builtin::BI__builtin_wcscmp) {
17921 MaxLength = N.getZExtValue();
17925 if (MaxLength == 0u)
17928 if (!String1.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
17929 !String2.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
17930 String1.Designator.Invalid || String2.Designator.Invalid)
17933 QualType CharTy1 = String1.Designator.getType(Info.Ctx);
17934 QualType CharTy2 = String2.Designator.getType(Info.Ctx);
17936 bool IsRawByte = BuiltinOp == Builtin::BImemcmp ||
17937 BuiltinOp == Builtin::BIbcmp ||
17938 BuiltinOp == Builtin::BI__builtin_memcmp ||
17939 BuiltinOp == Builtin::BI__builtin_bcmp;
17941 assert(IsRawByte ||
17942 (Info.Ctx.hasSameUnqualifiedType(
17944 Info.Ctx.hasSameUnqualifiedType(CharTy1, CharTy2)));
17951 Info.FFDiag(E, diag::note_constexpr_memcmp_unsupported)
17952 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp) << CharTy1
17957 const auto &ReadCurElems = [&](
APValue &Char1,
APValue &Char2) {
17960 Char1.
isInt() && Char2.isInt();
17962 const auto &AdvanceElems = [&] {
17968 (BuiltinOp != Builtin::BImemcmp && BuiltinOp != Builtin::BIbcmp &&
17969 BuiltinOp != Builtin::BIwmemcmp &&
17970 BuiltinOp != Builtin::BI__builtin_memcmp &&
17971 BuiltinOp != Builtin::BI__builtin_bcmp &&
17972 BuiltinOp != Builtin::BI__builtin_wmemcmp);
17973 bool IsWide = BuiltinOp == Builtin::BIwcscmp ||
17974 BuiltinOp == Builtin::BIwcsncmp ||
17975 BuiltinOp == Builtin::BIwmemcmp ||
17976 BuiltinOp == Builtin::BI__builtin_wcscmp ||
17977 BuiltinOp == Builtin::BI__builtin_wcsncmp ||
17978 BuiltinOp == Builtin::BI__builtin_wmemcmp;
17980 for (; MaxLength; --MaxLength) {
17982 if (!ReadCurElems(Char1, Char2))
17990 if (StopAtNull && !Char1.
getInt())
17992 assert(!(StopAtNull && !Char2.
getInt()));
17993 if (!AdvanceElems())
18000 case Builtin::BI__atomic_always_lock_free:
18001 case Builtin::BI__atomic_is_lock_free:
18002 case Builtin::BI__c11_atomic_is_lock_free: {
18018 if (
Size.isPowerOfTwo()) {
18020 unsigned InlineWidthBits =
18021 Info.Ctx.getTargetInfo().getMaxAtomicInlineWidth();
18022 if (Size <= Info.Ctx.toCharUnitsFromBits(InlineWidthBits)) {
18023 if (BuiltinOp == Builtin::BI__c11_atomic_is_lock_free ||
18029 const Expr *PtrArg = E->
getArg(1);
18035 IntResult.isAligned(
Size.getAsAlign()))
18039 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(PtrArg)) {
18042 if (ICE->getCastKind() == CK_BitCast)
18043 PtrArg = ICE->getSubExpr();
18046 if (
auto PtrTy = PtrArg->
getType()->
getAs<PointerType>()) {
18049 Info.Ctx.getTypeAlignInChars(PointeeType) >= Size) {
18057 return BuiltinOp == Builtin::BI__atomic_always_lock_free ?
18060 case Builtin::BI__builtin_addcb:
18061 case Builtin::BI__builtin_addcs:
18062 case Builtin::BI__builtin_addc:
18063 case Builtin::BI__builtin_addcl:
18064 case Builtin::BI__builtin_addcll:
18065 case Builtin::BI__builtin_subcb:
18066 case Builtin::BI__builtin_subcs:
18067 case Builtin::BI__builtin_subc:
18068 case Builtin::BI__builtin_subcl:
18069 case Builtin::BI__builtin_subcll: {
18070 LValue CarryOutLValue;
18082 bool FirstOverflowed =
false;
18083 bool SecondOverflowed =
false;
18084 switch (BuiltinOp) {
18086 llvm_unreachable(
"Invalid value for BuiltinOp");
18087 case Builtin::BI__builtin_addcb:
18088 case Builtin::BI__builtin_addcs:
18089 case Builtin::BI__builtin_addc:
18090 case Builtin::BI__builtin_addcl:
18091 case Builtin::BI__builtin_addcll:
18093 LHS.uadd_ov(RHS, FirstOverflowed).uadd_ov(CarryIn, SecondOverflowed);
18095 case Builtin::BI__builtin_subcb:
18096 case Builtin::BI__builtin_subcs:
18097 case Builtin::BI__builtin_subc:
18098 case Builtin::BI__builtin_subcl:
18099 case Builtin::BI__builtin_subcll:
18101 LHS.usub_ov(RHS, FirstOverflowed).usub_ov(CarryIn, SecondOverflowed);
18107 CarryOut = (
uint64_t)(FirstOverflowed | SecondOverflowed);
18113 case Builtin::BI__builtin_add_overflow:
18114 case Builtin::BI__builtin_sub_overflow:
18115 case Builtin::BI__builtin_mul_overflow:
18116 case Builtin::BI__builtin_sadd_overflow:
18117 case Builtin::BI__builtin_uadd_overflow:
18118 case Builtin::BI__builtin_uaddl_overflow:
18119 case Builtin::BI__builtin_uaddll_overflow:
18120 case Builtin::BI__builtin_usub_overflow:
18121 case Builtin::BI__builtin_usubl_overflow:
18122 case Builtin::BI__builtin_usubll_overflow:
18123 case Builtin::BI__builtin_umul_overflow:
18124 case Builtin::BI__builtin_umull_overflow:
18125 case Builtin::BI__builtin_umulll_overflow:
18126 case Builtin::BI__builtin_saddl_overflow:
18127 case Builtin::BI__builtin_saddll_overflow:
18128 case Builtin::BI__builtin_ssub_overflow:
18129 case Builtin::BI__builtin_ssubl_overflow:
18130 case Builtin::BI__builtin_ssubll_overflow:
18131 case Builtin::BI__builtin_smul_overflow:
18132 case Builtin::BI__builtin_smull_overflow:
18133 case Builtin::BI__builtin_smulll_overflow: {
18134 LValue ResultLValue;
18144 bool DidOverflow =
false;
18147 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
18148 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
18149 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
18150 bool IsSigned = LHS.isSigned() || RHS.isSigned() ||
18152 bool AllSigned = LHS.isSigned() && RHS.isSigned() &&
18154 uint64_t LHSSize = LHS.getBitWidth();
18155 uint64_t RHSSize = RHS.getBitWidth();
18156 uint64_t ResultSize = Info.Ctx.getIntWidth(ResultType);
18157 uint64_t MaxBits = std::max(std::max(LHSSize, RHSSize), ResultSize);
18163 if (IsSigned && !AllSigned)
18166 LHS =
APSInt(LHS.extOrTrunc(MaxBits), !IsSigned);
18167 RHS =
APSInt(RHS.extOrTrunc(MaxBits), !IsSigned);
18172 switch (BuiltinOp) {
18174 llvm_unreachable(
"Invalid value for BuiltinOp");
18175 case Builtin::BI__builtin_add_overflow:
18176 case Builtin::BI__builtin_sadd_overflow:
18177 case Builtin::BI__builtin_saddl_overflow:
18178 case Builtin::BI__builtin_saddll_overflow:
18179 case Builtin::BI__builtin_uadd_overflow:
18180 case Builtin::BI__builtin_uaddl_overflow:
18181 case Builtin::BI__builtin_uaddll_overflow:
18182 Result = LHS.isSigned() ? LHS.sadd_ov(RHS, DidOverflow)
18183 : LHS.uadd_ov(RHS, DidOverflow);
18185 case Builtin::BI__builtin_sub_overflow:
18186 case Builtin::BI__builtin_ssub_overflow:
18187 case Builtin::BI__builtin_ssubl_overflow:
18188 case Builtin::BI__builtin_ssubll_overflow:
18189 case Builtin::BI__builtin_usub_overflow:
18190 case Builtin::BI__builtin_usubl_overflow:
18191 case Builtin::BI__builtin_usubll_overflow:
18192 Result = LHS.isSigned() ? LHS.ssub_ov(RHS, DidOverflow)
18193 : LHS.usub_ov(RHS, DidOverflow);
18195 case Builtin::BI__builtin_mul_overflow:
18196 case Builtin::BI__builtin_smul_overflow:
18197 case Builtin::BI__builtin_smull_overflow:
18198 case Builtin::BI__builtin_smulll_overflow:
18199 case Builtin::BI__builtin_umul_overflow:
18200 case Builtin::BI__builtin_umull_overflow:
18201 case Builtin::BI__builtin_umulll_overflow:
18202 Result = LHS.isSigned() ? LHS.smul_ov(RHS, DidOverflow)
18203 : LHS.umul_ov(RHS, DidOverflow);
18212 APSInt Temp =
Result.extOrTrunc(Info.Ctx.getIntWidth(ResultType));
18217 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
18218 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
18219 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
18220 if (!APSInt::isSameValue(Temp,
Result))
18221 DidOverflow =
true;
18228 return Success(DidOverflow, E);
18231 case Builtin::BI__builtin_reduce_add:
18232 case Builtin::BI__builtin_reduce_mul:
18233 case Builtin::BI__builtin_reduce_and:
18234 case Builtin::BI__builtin_reduce_or:
18235 case Builtin::BI__builtin_reduce_xor:
18236 case Builtin::BI__builtin_reduce_min:
18237 case Builtin::BI__builtin_reduce_max: {
18244 for (
unsigned EltNum = 1; EltNum < SourceLen; ++EltNum) {
18245 switch (BuiltinOp) {
18248 case Builtin::BI__builtin_reduce_add: {
18251 Reduced.getBitWidth() + 1, std::plus<APSInt>(), Reduced))
18255 case Builtin::BI__builtin_reduce_mul: {
18258 Reduced.getBitWidth() * 2, std::multiplies<APSInt>(), Reduced))
18262 case Builtin::BI__builtin_reduce_and: {
18266 case Builtin::BI__builtin_reduce_or: {
18270 case Builtin::BI__builtin_reduce_xor: {
18274 case Builtin::BI__builtin_reduce_min: {
18278 case Builtin::BI__builtin_reduce_max: {
18288 case clang::X86::BI__builtin_ia32_addcarryx_u32:
18289 case clang::X86::BI__builtin_ia32_addcarryx_u64:
18290 case clang::X86::BI__builtin_ia32_subborrow_u32:
18291 case clang::X86::BI__builtin_ia32_subborrow_u64: {
18292 LValue ResultLValue;
18293 APSInt CarryIn, LHS, RHS;
18301 bool IsAdd = BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u32 ||
18302 BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u64;
18304 unsigned BitWidth = LHS.getBitWidth();
18305 unsigned CarryInBit = CarryIn.ugt(0) ? 1 : 0;
18308 ? (LHS.zext(BitWidth + 1) + (RHS.zext(BitWidth + 1) + CarryInBit))
18309 : (LHS.zext(BitWidth + 1) - (RHS.zext(BitWidth + 1) + CarryInBit));
18311 APInt Result = ExResult.extractBits(BitWidth, 0);
18312 uint64_t CarryOut = ExResult.extractBitsAsZExtValue(1, BitWidth);
18320 case clang::X86::BI__builtin_ia32_movmskps:
18321 case clang::X86::BI__builtin_ia32_movmskpd:
18322 case clang::X86::BI__builtin_ia32_pmovmskb128:
18323 case clang::X86::BI__builtin_ia32_pmovmskb256:
18324 case clang::X86::BI__builtin_ia32_movmskps256:
18325 case clang::X86::BI__builtin_ia32_movmskpd256: {
18332 unsigned ResultLen = Info.Ctx.getTypeSize(
18336 for (
unsigned I = 0; I != SourceLen; ++I) {
18338 if (ElemQT->isIntegerType()) {
18340 }
else if (ElemQT->isRealFloatingType()) {
18345 Result.setBitVal(I, Elem.isNegative());
18350 case clang::X86::BI__builtin_ia32_bextr_u32:
18351 case clang::X86::BI__builtin_ia32_bextr_u64:
18352 case clang::X86::BI__builtin_ia32_bextri_u32:
18353 case clang::X86::BI__builtin_ia32_bextri_u64: {
18359 unsigned BitWidth = Val.getBitWidth();
18361 uint64_t Length = Idx.extractBitsAsZExtValue(8, 8);
18362 Length = Length > BitWidth ? BitWidth : Length;
18365 if (Length == 0 || Shift >= BitWidth)
18369 Result &= llvm::maskTrailingOnes<uint64_t>(Length);
18373 case clang::X86::BI__builtin_ia32_bzhi_si:
18374 case clang::X86::BI__builtin_ia32_bzhi_di: {
18380 unsigned BitWidth = Val.getBitWidth();
18381 unsigned Index = Idx.extractBitsAsZExtValue(8, 0);
18382 if (Index < BitWidth)
18383 Val.clearHighBits(BitWidth - Index);
18387 case clang::X86::BI__builtin_ia32_ktestcqi:
18388 case clang::X86::BI__builtin_ia32_ktestchi:
18389 case clang::X86::BI__builtin_ia32_ktestcsi:
18390 case clang::X86::BI__builtin_ia32_ktestcdi: {
18396 return Success((~A & B) == 0, E);
18399 case clang::X86::BI__builtin_ia32_ktestzqi:
18400 case clang::X86::BI__builtin_ia32_ktestzhi:
18401 case clang::X86::BI__builtin_ia32_ktestzsi:
18402 case clang::X86::BI__builtin_ia32_ktestzdi: {
18408 return Success((A & B) == 0, E);
18411 case clang::X86::BI__builtin_ia32_kortestcqi:
18412 case clang::X86::BI__builtin_ia32_kortestchi:
18413 case clang::X86::BI__builtin_ia32_kortestcsi:
18414 case clang::X86::BI__builtin_ia32_kortestcdi: {
18420 return Success(~(A | B) == 0, E);
18423 case clang::X86::BI__builtin_ia32_kortestzqi:
18424 case clang::X86::BI__builtin_ia32_kortestzhi:
18425 case clang::X86::BI__builtin_ia32_kortestzsi:
18426 case clang::X86::BI__builtin_ia32_kortestzdi: {
18432 return Success((A | B) == 0, E);
18435 case clang::X86::BI__builtin_ia32_kunpckhi:
18436 case clang::X86::BI__builtin_ia32_kunpckdi:
18437 case clang::X86::BI__builtin_ia32_kunpcksi: {
18445 unsigned BW = A.getBitWidth();
18446 APSInt Result(A.trunc(BW / 2).concat(B.trunc(BW / 2)), A.isUnsigned());
18450 case clang::X86::BI__builtin_ia32_lzcnt_u16:
18451 case clang::X86::BI__builtin_ia32_lzcnt_u32:
18452 case clang::X86::BI__builtin_ia32_lzcnt_u64: {
18456 return Success(Val.countLeadingZeros(), E);
18459 case clang::X86::BI__builtin_ia32_tzcnt_u16:
18460 case clang::X86::BI__builtin_ia32_tzcnt_u32:
18461 case clang::X86::BI__builtin_ia32_tzcnt_u64: {
18465 return Success(Val.countTrailingZeros(), E);
18468 case Builtin::BI__builtin_elementwise_pdep: {
18473 return Success(llvm::APIntOps::pdep(Val, Msk), E);
18476 case Builtin::BI__builtin_elementwise_pext: {
18481 return Success(llvm::APIntOps::pext(Val, Msk), E);
18484 case X86::BI__builtin_ia32_ptestz128:
18485 case X86::BI__builtin_ia32_ptestz256:
18486 case X86::BI__builtin_ia32_vtestzps:
18487 case X86::BI__builtin_ia32_vtestzps256:
18488 case X86::BI__builtin_ia32_vtestzpd:
18489 case X86::BI__builtin_ia32_vtestzpd256: {
18491 [](
const APInt &A,
const APInt &B) {
return (A & B) == 0; });
18493 case X86::BI__builtin_ia32_ptestc128:
18494 case X86::BI__builtin_ia32_ptestc256:
18495 case X86::BI__builtin_ia32_vtestcps:
18496 case X86::BI__builtin_ia32_vtestcps256:
18497 case X86::BI__builtin_ia32_vtestcpd:
18498 case X86::BI__builtin_ia32_vtestcpd256: {
18500 [](
const APInt &A,
const APInt &B) {
return (~A & B) == 0; });
18502 case X86::BI__builtin_ia32_ptestnzc128:
18503 case X86::BI__builtin_ia32_ptestnzc256:
18504 case X86::BI__builtin_ia32_vtestnzcps:
18505 case X86::BI__builtin_ia32_vtestnzcps256:
18506 case X86::BI__builtin_ia32_vtestnzcpd:
18507 case X86::BI__builtin_ia32_vtestnzcpd256: {
18508 return EvalTestOp([](
const APInt &A,
const APInt &B) {
18509 return ((A & B) != 0) && ((~A & B) != 0);
18512 case X86::BI__builtin_ia32_kandqi:
18513 case X86::BI__builtin_ia32_kandhi:
18514 case X86::BI__builtin_ia32_kandsi:
18515 case X86::BI__builtin_ia32_kanddi: {
18516 return HandleMaskBinOp(
18517 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS & RHS; });
18520 case X86::BI__builtin_ia32_kandnqi:
18521 case X86::BI__builtin_ia32_kandnhi:
18522 case X86::BI__builtin_ia32_kandnsi:
18523 case X86::BI__builtin_ia32_kandndi: {
18524 return HandleMaskBinOp(
18525 [](
const APSInt &LHS,
const APSInt &RHS) {
return ~LHS & RHS; });
18528 case X86::BI__builtin_ia32_korqi:
18529 case X86::BI__builtin_ia32_korhi:
18530 case X86::BI__builtin_ia32_korsi:
18531 case X86::BI__builtin_ia32_kordi: {
18532 return HandleMaskBinOp(
18533 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS | RHS; });
18536 case X86::BI__builtin_ia32_kxnorqi:
18537 case X86::BI__builtin_ia32_kxnorhi:
18538 case X86::BI__builtin_ia32_kxnorsi:
18539 case X86::BI__builtin_ia32_kxnordi: {
18540 return HandleMaskBinOp(
18541 [](
const APSInt &LHS,
const APSInt &RHS) {
return ~(LHS ^ RHS); });
18544 case X86::BI__builtin_ia32_kxorqi:
18545 case X86::BI__builtin_ia32_kxorhi:
18546 case X86::BI__builtin_ia32_kxorsi:
18547 case X86::BI__builtin_ia32_kxordi: {
18548 return HandleMaskBinOp(
18549 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS ^ RHS; });
18552 case X86::BI__builtin_ia32_knotqi:
18553 case X86::BI__builtin_ia32_knothi:
18554 case X86::BI__builtin_ia32_knotsi:
18555 case X86::BI__builtin_ia32_knotdi: {
18563 case X86::BI__builtin_ia32_kaddqi:
18564 case X86::BI__builtin_ia32_kaddhi:
18565 case X86::BI__builtin_ia32_kaddsi:
18566 case X86::BI__builtin_ia32_kadddi: {
18567 return HandleMaskBinOp(
18568 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS + RHS; });
18571 case X86::BI__builtin_ia32_kmovb:
18572 case X86::BI__builtin_ia32_kmovw:
18573 case X86::BI__builtin_ia32_kmovd:
18574 case X86::BI__builtin_ia32_kmovq: {
18581 case X86::BI__builtin_ia32_kshiftliqi:
18582 case X86::BI__builtin_ia32_kshiftlihi:
18583 case X86::BI__builtin_ia32_kshiftlisi:
18584 case X86::BI__builtin_ia32_kshiftlidi: {
18585 return HandleMaskBinOp([](
const APSInt &LHS,
const APSInt &RHS) {
18586 unsigned Amt = RHS.getZExtValue() & 0xFF;
18587 if (Amt >= LHS.getBitWidth())
18588 return APSInt(APInt::getZero(LHS.getBitWidth()), LHS.isUnsigned());
18589 return APSInt(LHS.shl(Amt), LHS.isUnsigned());
18593 case X86::BI__builtin_ia32_kshiftriqi:
18594 case X86::BI__builtin_ia32_kshiftrihi:
18595 case X86::BI__builtin_ia32_kshiftrisi:
18596 case X86::BI__builtin_ia32_kshiftridi: {
18597 return HandleMaskBinOp([](
const APSInt &LHS,
const APSInt &RHS) {
18598 unsigned Amt = RHS.getZExtValue() & 0xFF;
18599 if (Amt >= LHS.getBitWidth())
18600 return APSInt(APInt::getZero(LHS.getBitWidth()), LHS.isUnsigned());
18601 return APSInt(LHS.lshr(Amt), LHS.isUnsigned());
18605 case clang::X86::BI__builtin_ia32_vec_ext_v4hi:
18606 case clang::X86::BI__builtin_ia32_vec_ext_v16qi:
18607 case clang::X86::BI__builtin_ia32_vec_ext_v8hi:
18608 case clang::X86::BI__builtin_ia32_vec_ext_v4si:
18609 case clang::X86::BI__builtin_ia32_vec_ext_v2di:
18610 case clang::X86::BI__builtin_ia32_vec_ext_v32qi:
18611 case clang::X86::BI__builtin_ia32_vec_ext_v16hi:
18612 case clang::X86::BI__builtin_ia32_vec_ext_v8si:
18613 case clang::X86::BI__builtin_ia32_vec_ext_v4di: {
18620 unsigned Idx =
static_cast<unsigned>(IdxAPS.getZExtValue() & (N - 1));
18624 case clang::X86::BI__builtin_ia32_cvtb2mask128:
18625 case clang::X86::BI__builtin_ia32_cvtb2mask256:
18626 case clang::X86::BI__builtin_ia32_cvtb2mask512:
18627 case clang::X86::BI__builtin_ia32_cvtw2mask128:
18628 case clang::X86::BI__builtin_ia32_cvtw2mask256:
18629 case clang::X86::BI__builtin_ia32_cvtw2mask512:
18630 case clang::X86::BI__builtin_ia32_cvtd2mask128:
18631 case clang::X86::BI__builtin_ia32_cvtd2mask256:
18632 case clang::X86::BI__builtin_ia32_cvtd2mask512:
18633 case clang::X86::BI__builtin_ia32_cvtq2mask128:
18634 case clang::X86::BI__builtin_ia32_cvtq2mask256:
18635 case clang::X86::BI__builtin_ia32_cvtq2mask512: {
18642 unsigned RetWidth = Info.Ctx.getIntWidth(E->
getType());
18643 llvm::APInt Bits(RetWidth, 0);
18645 for (
unsigned ElemNum = 0; ElemNum != VectorLen; ++ElemNum) {
18647 unsigned MSB = A[A.getBitWidth() - 1];
18648 Bits.setBitVal(ElemNum, MSB);
18651 APSInt RetMask(Bits,
true);
18655 case clang::X86::BI__builtin_ia32_cmpb128_mask:
18656 case clang::X86::BI__builtin_ia32_cmpw128_mask:
18657 case clang::X86::BI__builtin_ia32_cmpd128_mask:
18658 case clang::X86::BI__builtin_ia32_cmpq128_mask:
18659 case clang::X86::BI__builtin_ia32_cmpb256_mask:
18660 case clang::X86::BI__builtin_ia32_cmpw256_mask:
18661 case clang::X86::BI__builtin_ia32_cmpd256_mask:
18662 case clang::X86::BI__builtin_ia32_cmpq256_mask:
18663 case clang::X86::BI__builtin_ia32_cmpb512_mask:
18664 case clang::X86::BI__builtin_ia32_cmpw512_mask:
18665 case clang::X86::BI__builtin_ia32_cmpd512_mask:
18666 case clang::X86::BI__builtin_ia32_cmpq512_mask:
18667 case clang::X86::BI__builtin_ia32_ucmpb128_mask:
18668 case clang::X86::BI__builtin_ia32_ucmpw128_mask:
18669 case clang::X86::BI__builtin_ia32_ucmpd128_mask:
18670 case clang::X86::BI__builtin_ia32_ucmpq128_mask:
18671 case clang::X86::BI__builtin_ia32_ucmpb256_mask:
18672 case clang::X86::BI__builtin_ia32_ucmpw256_mask:
18673 case clang::X86::BI__builtin_ia32_ucmpd256_mask:
18674 case clang::X86::BI__builtin_ia32_ucmpq256_mask:
18675 case clang::X86::BI__builtin_ia32_ucmpb512_mask:
18676 case clang::X86::BI__builtin_ia32_ucmpw512_mask:
18677 case clang::X86::BI__builtin_ia32_ucmpd512_mask:
18678 case clang::X86::BI__builtin_ia32_ucmpq512_mask: {
18682 (BuiltinOp >= clang::X86::BI__builtin_ia32_ucmpb128_mask &&
18683 BuiltinOp <= clang::X86::BI__builtin_ia32_ucmpw512_mask);
18696 unsigned RetWidth = Mask.getBitWidth();
18698 APSInt RetMask(llvm::APInt(RetWidth, 0),
true);
18700 for (
unsigned ElemNum = 0; ElemNum < VectorLen; ++ElemNum) {
18705 switch (
Opcode.getExtValue() & 0x7) {
18710 Result = IsUnsigned ? A.ult(B) : A.slt(B);
18713 Result = IsUnsigned ? A.ule(B) : A.sle(B);
18722 Result = IsUnsigned ? A.uge(B) : A.sge(B);
18725 Result = IsUnsigned ? A.ugt(B) : A.sgt(B);
18732 RetMask.setBitVal(ElemNum, Mask[ElemNum] &&
Result);
18737 case X86::BI__builtin_ia32_cvtss2si:
18738 case X86::BI__builtin_ia32_cvtsd2si:
18739 case X86::BI__builtin_ia32_cvttss2si:
18740 case X86::BI__builtin_ia32_cvttsd2si:
18741 case X86::BI__builtin_ia32_cvtss2si64:
18742 case X86::BI__builtin_ia32_cvtsd2si64:
18743 case X86::BI__builtin_ia32_cvttss2si64:
18744 case X86::BI__builtin_ia32_cvttsd2si64: {
18749 assert(ArgVal.
isVector() &&
"Expected a vector argument");
18751 unsigned BitWidth = Info.Ctx.getIntWidth(E->
getType());
18754 llvm::APSInt IntResult(BitWidth,
isUnsigned);
18755 bool IsExact =
false;
18758 FloatElem.convertToInteger(IntResult, llvm::APFloat::rmTowardZero,
18763 return Success(IntResult, E);
18765 case X86::BI__builtin_ia32_vpshufbitqmb128_mask:
18766 case X86::BI__builtin_ia32_vpshufbitqmb256_mask:
18767 case X86::BI__builtin_ia32_vpshufbitqmb512_mask: {
18780 unsigned NumBytesInQWord = 8;
18781 unsigned NumBitsInByte = 8;
18783 unsigned NumQWords = NumBytes / NumBytesInQWord;
18784 unsigned RetWidth = ZeroMask.getBitWidth();
18785 APSInt RetMask(llvm::APInt(RetWidth, 0),
true);
18787 for (
unsigned QWordId = 0; QWordId != NumQWords; ++QWordId) {
18788 APInt SourceQWord(64, 0);
18789 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
18793 SourceQWord.insertBits(
APInt(8, Byte & 0xFF), ByteIdx * NumBitsInByte);
18796 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
18797 unsigned SelIdx = QWordId * NumBytesInQWord + ByteIdx;
18800 if (ZeroMask[SelIdx]) {
18801 RetMask.setBitVal(SelIdx, SourceQWord[M]);
18813 const LValue &LV) {
18816 if (!LV.getLValueBase())
18821 if (!LV.getLValueDesignator().Invalid &&
18822 !LV.getLValueDesignator().isOnePastTheEnd())
18832 if (LV.getLValueDesignator().Invalid)
18838 return LV.getLValueOffset() == Size;
18848class DataRecursiveIntBinOpEvaluator {
18849 struct EvalResult {
18851 bool Failed =
false;
18853 EvalResult() =
default;
18855 void swap(EvalResult &RHS) {
18857 Failed = RHS.Failed;
18858 RHS.Failed =
false;
18864 EvalResult LHSResult;
18865 enum { AnyExprKind, BinOpKind, BinOpVisitedLHSKind }
Kind;
18868 Job(Job &&) =
default;
18870 void startSpeculativeEval(EvalInfo &Info) {
18871 SpecEvalRAII = SpeculativeEvaluationRAII(Info);
18875 SpeculativeEvaluationRAII SpecEvalRAII;
18878 SmallVector<Job, 16> Queue;
18880 IntExprEvaluator &IntEval;
18885 DataRecursiveIntBinOpEvaluator(IntExprEvaluator &IntEval,
APValue &
Result)
18886 : IntEval(IntEval), Info(IntEval.getEvalInfo()), FinalResult(
Result) { }
18892 static bool shouldEnqueue(
const BinaryOperator *E) {
18899 bool Traverse(
const BinaryOperator *E) {
18901 EvalResult PrevResult;
18902 while (!Queue.empty())
18903 process(PrevResult);
18905 if (PrevResult.Failed)
return false;
18907 FinalResult.
swap(PrevResult.Val);
18918 bool Error(
const Expr *E) {
18919 return IntEval.Error(E);
18922 return IntEval.Error(E, D);
18925 OptionalDiagnostic CCEDiag(
const Expr *E,
diag::kind D) {
18926 return Info.CCEDiag(E, D);
18930 bool VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
18931 bool &SuppressRHSDiags);
18933 bool VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
18936 void EvaluateExpr(
const Expr *E, EvalResult &
Result) {
18942 void process(EvalResult &
Result);
18944 void enqueue(
const Expr *E) {
18946 Queue.resize(Queue.size()+1);
18947 Queue.back().E = E;
18948 Queue.back().Kind = Job::AnyExprKind;
18954bool DataRecursiveIntBinOpEvaluator::
18955 VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
18956 bool &SuppressRHSDiags) {
18959 if (LHSResult.Failed)
18960 return Info.noteSideEffect();
18969 if (LHSAsBool == (E->
getOpcode() == BO_LOr)) {
18970 Success(LHSAsBool, E, LHSResult.Val);
18974 LHSResult.Failed =
true;
18978 if (!Info.noteSideEffect())
18984 SuppressRHSDiags =
true;
18993 if (LHSResult.Failed && !Info.noteFailure())
19004 assert(!LVal.
hasLValuePath() &&
"have designator for integer lvalue");
19006 uint64_t Offset64 = Offset.getQuantity();
19007 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
19009 : Offset64 + Index64);
19012bool DataRecursiveIntBinOpEvaluator::
19013 VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
19016 if (RHSResult.Failed)
19023 bool lhsResult, rhsResult;
19038 if (rhsResult == (E->
getOpcode() == BO_LOr))
19049 if (LHSResult.Failed || RHSResult.Failed)
19052 const APValue &LHSVal = LHSResult.Val;
19053 const APValue &RHSVal = RHSResult.Val;
19077 if (!LHSExpr || !RHSExpr)
19079 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
19080 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
19081 if (!LHSAddrExpr || !RHSAddrExpr)
19106void DataRecursiveIntBinOpEvaluator::process(EvalResult &
Result) {
19107 Job &job = Queue.back();
19109 switch (job.Kind) {
19110 case Job::AnyExprKind: {
19111 if (
const BinaryOperator *Bop = dyn_cast<BinaryOperator>(job.E)) {
19112 if (shouldEnqueue(Bop)) {
19113 job.Kind = Job::BinOpKind;
19114 enqueue(Bop->getLHS());
19119 EvaluateExpr(job.E,
Result);
19124 case Job::BinOpKind: {
19126 bool SuppressRHSDiags =
false;
19127 if (!VisitBinOpLHSOnly(
Result, Bop, SuppressRHSDiags)) {
19131 if (SuppressRHSDiags)
19132 job.startSpeculativeEval(Info);
19133 job.LHSResult.swap(
Result);
19134 job.Kind = Job::BinOpVisitedLHSKind;
19139 case Job::BinOpVisitedLHSKind: {
19143 Result.Failed = !VisitBinOp(job.LHSResult, RHS, Bop,
Result.Val);
19149 llvm_unreachable(
"Invalid Job::Kind!");
19153enum class CmpResult {
19162template <
class SuccessCB,
class AfterCB>
19165 SuccessCB &&
Success, AfterCB &&DoAfter) {
19170 "unsupported binary expression evaluation");
19172 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
19186 if (!LHSOK && !Info.noteFailure())
19191 return Success(CmpResult::Less, E);
19193 return Success(CmpResult::Greater, E);
19194 return Success(CmpResult::Equal, E);
19198 APFixedPoint LHSFX(Info.Ctx.getFixedPointSemantics(LHSTy));
19199 APFixedPoint RHSFX(Info.Ctx.getFixedPointSemantics(RHSTy));
19202 if (!LHSOK && !Info.noteFailure())
19207 return Success(CmpResult::Less, E);
19209 return Success(CmpResult::Greater, E);
19210 return Success(CmpResult::Equal, E);
19214 ComplexValue LHS, RHS;
19223 LHS.makeComplexFloat();
19224 LHS.FloatImag = APFloat(LHS.FloatReal.getSemantics());
19229 if (!LHSOK && !Info.noteFailure())
19235 RHS.makeComplexFloat();
19236 RHS.FloatImag = APFloat(RHS.FloatReal.getSemantics());
19240 if (LHS.isComplexFloat()) {
19241 APFloat::cmpResult CR_r =
19242 LHS.getComplexFloatReal().compare(RHS.getComplexFloatReal());
19243 APFloat::cmpResult CR_i =
19244 LHS.getComplexFloatImag().compare(RHS.getComplexFloatImag());
19245 bool IsEqual = CR_r == APFloat::cmpEqual && CR_i == APFloat::cmpEqual;
19246 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal, E);
19248 assert(IsEquality &&
"invalid complex comparison");
19249 bool IsEqual = LHS.getComplexIntReal() == RHS.getComplexIntReal() &&
19250 LHS.getComplexIntImag() == RHS.getComplexIntImag();
19251 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal, E);
19257 APFloat RHS(0.0), LHS(0.0);
19260 if (!LHSOK && !Info.noteFailure())
19267 llvm::APFloatBase::cmpResult APFloatCmpResult = LHS.compare(RHS);
19268 if (!Info.InConstantContext &&
19269 APFloatCmpResult == APFloat::cmpUnordered &&
19272 Info.FFDiag(E, diag::note_constexpr_float_arithmetic_strict);
19275 auto GetCmpRes = [&]() {
19276 switch (APFloatCmpResult) {
19277 case APFloat::cmpEqual:
19278 return CmpResult::Equal;
19279 case APFloat::cmpLessThan:
19280 return CmpResult::Less;
19281 case APFloat::cmpGreaterThan:
19282 return CmpResult::Greater;
19283 case APFloat::cmpUnordered:
19284 return CmpResult::Unordered;
19286 llvm_unreachable(
"Unrecognised APFloat::cmpResult enum");
19288 return Success(GetCmpRes(), E);
19292 LValue LHSValue, RHSValue;
19295 if (!LHSOK && !Info.noteFailure())
19306 if (Info.checkingPotentialConstantExpression() &&
19307 (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown))
19309 auto DiagComparison = [&] (
unsigned DiagID,
bool Reversed =
false) {
19310 std::string LHS = LHSValue.toString(Info.Ctx, E->
getLHS()->
getType());
19311 std::string RHS = RHSValue.toString(Info.Ctx, E->
getRHS()->
getType());
19312 Info.FFDiag(E, DiagID)
19319 return DiagComparison(
19320 diag::note_constexpr_pointer_comparison_unspecified);
19326 if ((!LHSValue.Base && !LHSValue.Offset.
isZero()) ||
19327 (!RHSValue.Base && !RHSValue.Offset.
isZero()))
19328 return DiagComparison(diag::note_constexpr_pointer_constant_comparison,
19342 return DiagComparison(diag::note_constexpr_literal_comparison);
19344 return DiagComparison(diag::note_constexpr_opaque_call_comparison,
19349 return DiagComparison(diag::note_constexpr_pointer_weak_comparison,
19353 if (LHSValue.Base && LHSValue.Offset.
isZero() &&
19355 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
19357 if (RHSValue.Base && RHSValue.Offset.
isZero() &&
19359 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
19365 return DiagComparison(
19366 diag::note_constexpr_pointer_comparison_zero_sized);
19367 if (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown)
19368 return DiagComparison(
19369 diag::note_constexpr_pointer_comparison_unspecified);
19371 return Success(CmpResult::Unequal, E);
19374 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
19375 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
19377 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
19378 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
19388 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid && IsRelational) {
19389 bool WasArrayIndex;
19392 :
getType(LHSValue.Base).getNonReferenceType(),
19393 LHSDesignator, RHSDesignator, WasArrayIndex);
19400 if (!WasArrayIndex && Mismatch < LHSDesignator.Entries.size() &&
19401 Mismatch < RHSDesignator.Entries.size()) {
19402 const FieldDecl *LF = getAsField(LHSDesignator.Entries[Mismatch]);
19403 const FieldDecl *RF = getAsField(RHSDesignator.Entries[Mismatch]);
19405 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_classes);
19407 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
19408 << getAsBaseClass(LHSDesignator.Entries[Mismatch])
19411 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
19412 << getAsBaseClass(RHSDesignator.Entries[Mismatch])
19417 diag::note_constexpr_pointer_comparison_differing_access)
19425 unsigned PtrSize = Info.Ctx.getTypeSize(LHSTy);
19428 assert(PtrSize <= 64 &&
"Unexpected pointer width");
19429 uint64_t Mask = ~0ULL >> (64 - PtrSize);
19430 CompareLHS &= Mask;
19431 CompareRHS &= Mask;
19436 if (!LHSValue.Base.
isNull() && IsRelational) {
19440 CharUnits Size = Info.Ctx.getTypeSizeInChars(BaseTy);
19441 uint64_t OffsetLimit = Size.getQuantity();
19442 if (CompareLHS > OffsetLimit || CompareRHS > OffsetLimit)
19446 if (CompareLHS < CompareRHS)
19447 return Success(CmpResult::Less, E);
19448 if (CompareLHS > CompareRHS)
19449 return Success(CmpResult::Greater, E);
19450 return Success(CmpResult::Equal, E);
19454 assert(IsEquality &&
"unexpected member pointer operation");
19457 MemberPtr LHSValue, RHSValue;
19460 if (!LHSOK && !Info.noteFailure())
19468 if (LHSValue.getDecl() && LHSValue.getDecl()->isWeak()) {
19469 Info.FFDiag(E, diag::note_constexpr_mem_pointer_weak_comparison)
19470 << LHSValue.getDecl();
19473 if (RHSValue.getDecl() && RHSValue.getDecl()->isWeak()) {
19474 Info.FFDiag(E, diag::note_constexpr_mem_pointer_weak_comparison)
19475 << RHSValue.getDecl();
19482 if (!LHSValue.getDecl() || !RHSValue.getDecl()) {
19483 bool Equal = !LHSValue.getDecl() && !RHSValue.getDecl();
19484 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal, E);
19489 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(LHSValue.getDecl()))
19490 if (MD->isVirtual())
19491 Info.CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
19492 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(RHSValue.getDecl()))
19493 if (MD->isVirtual())
19494 Info.CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
19500 bool Equal = LHSValue == RHSValue;
19501 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal, E);
19506 assert(RHSTy->
isNullPtrType() &&
"missing pointer conversion");
19514 return Success(CmpResult::Equal, E);
19524 Info.Ctx.CompCategories.getInfoForType(E->
getType());
19533 ConstantExprKind::Normal);
19536bool RecordExprEvaluator::VisitBinCmp(
const BinaryOperator *E) {
19540 auto OnSuccess = [&](CmpResult CR,
const BinaryOperator *E) {
19543 case CmpResult::Unequal:
19544 llvm_unreachable(
"should never produce Unequal for three-way comparison");
19545 case CmpResult::Less:
19546 CCR = ComparisonCategoryResult::Less;
19548 case CmpResult::Equal:
19549 CCR = ComparisonCategoryResult::Equal;
19551 case CmpResult::Greater:
19552 CCR = ComparisonCategoryResult::Greater;
19554 case CmpResult::Unordered:
19555 CCR = ComparisonCategoryResult::Unordered;
19561 return ExprEvaluatorBaseTy::VisitBinCmp(E);
19565bool RecordExprEvaluator::VisitTypeTraitExpr(
const TypeTraitExpr *E) {
19570 "expected a strong_ordering type trait with a stored value");
19577bool RecordExprEvaluator::VisitCXXParenListInitExpr(
19578 const CXXParenListInitExpr *E) {
19579 return VisitCXXParenListOrInitListExpr(E, E->
getInitExprs());
19582bool IntExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
19587 if (!Info.noteFailure())
19591 if (DataRecursiveIntBinOpEvaluator::shouldEnqueue(E))
19592 return DataRecursiveIntBinOpEvaluator(*
this,
Result).Traverse(E);
19596 "DataRecursiveIntBinOpEvaluator should have handled integral types");
19601 auto OnSuccess = [&](CmpResult CR,
const BinaryOperator *E) {
19602 assert((CR != CmpResult::Unequal || E->
isEqualityOp()) &&
19603 "should only produce Unequal for equality comparisons");
19604 bool IsEqual = CR == CmpResult::Equal,
19605 IsLess = CR == CmpResult::Less,
19606 IsGreater = CR == CmpResult::Greater;
19610 llvm_unreachable(
"unsupported binary operator");
19613 return Success(IsEqual == (Op == BO_EQ), E);
19617 return Success(IsGreater, E);
19619 return Success(IsEqual || IsLess, E);
19621 return Success(IsEqual || IsGreater, E);
19625 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
19634 LValue LHSValue, RHSValue;
19637 if (!LHSOK && !Info.noteFailure())
19646 if (Info.checkingPotentialConstantExpression() &&
19647 (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown))
19650 const Expr *LHSExpr = LHSValue.Base.
dyn_cast<
const Expr *>();
19651 const Expr *RHSExpr = RHSValue.Base.
dyn_cast<
const Expr *>();
19653 auto DiagArith = [&](
unsigned DiagID) {
19654 std::string LHS = LHSValue.toString(Info.Ctx, E->
getLHS()->
getType());
19655 std::string RHS = RHSValue.toString(Info.Ctx, E->
getRHS()->
getType());
19656 Info.FFDiag(E, DiagID) << LHS << RHS;
19657 if (LHSExpr && LHSExpr == RHSExpr)
19659 diag::note_constexpr_repeated_literal_eval)
19664 if (!LHSExpr || !RHSExpr)
19665 return DiagArith(diag::note_constexpr_pointer_arith_unspecified);
19668 return DiagArith(diag::note_constexpr_literal_arith);
19670 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
19671 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
19672 if (!LHSAddrExpr || !RHSAddrExpr)
19680 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
19681 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
19683 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
19684 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
19690 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid &&
19693 Info.CCEDiag(E, diag::note_constexpr_pointer_subtraction_not_same_array);
19698 CharUnits ElementSize;
19705 if (ElementSize.
isZero()) {
19706 Info.FFDiag(E, diag::note_constexpr_pointer_subtraction_zero_size)
19723 APSInt TrueResult = (LHS - RHS) / ElemSize;
19726 if (
Result.extend(65) != TrueResult &&
19732 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
19737bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr(
19738 const UnaryExprOrTypeTraitExpr *E) {
19740 case UETT_PreferredAlignOf:
19741 case UETT_AlignOf: {
19750 case UETT_PtrAuthTypeDiscriminator: {
19756 case UETT_VecStep: {
19760 unsigned n = Ty->
castAs<VectorType>()->getNumElements();
19772 case UETT_DataSizeOf:
19773 case UETT_SizeOf: {
19777 if (
const ReferenceType *Ref = SrcTy->
getAs<ReferenceType>())
19788 case UETT_OpenMPRequiredSimdAlign:
19791 Info.Ctx.toCharUnitsFromBits(
19795 case UETT_VectorElements: {
19799 if (
const auto *VT = Ty->
getAs<VectorType>())
19803 if (Info.InConstantContext)
19804 Info.CCEDiag(E, diag::note_constexpr_non_const_vectorelements)
19809 case UETT_CountOf: {
19815 if (
const auto *CAT =
19825 const auto *VAT = Info.Ctx.getAsVariableArrayType(Ty);
19827 if (VAT->getElementType()->isArrayType()) {
19830 if (!VAT->getSizeExpr()) {
19835 std::optional<APSInt> Res =
19836 VAT->getSizeExpr()->getIntegerConstantExpr(Info.Ctx);
19841 static_cast<unsigned>(Info.Ctx.getTypeSize(Info.Ctx.getSizeType())),
19842 Res->getZExtValue()};
19854 llvm_unreachable(
"unknown expr/type trait");
19857bool IntExprEvaluator::VisitOffsetOfExpr(
const OffsetOfExpr *OOE) {
19858 Info.Ctx.recordOffsetOfEvaluation(OOE);
19864 for (
unsigned i = 0; i != n; ++i) {
19872 const ArrayType *AT = Info.Ctx.getAsArrayType(CurrentType);
19876 CharUnits ElementSize = Info.Ctx.getTypeSizeInChars(CurrentType);
19879 if (IdxResult.isNegative() || IdxResult.getActiveBits() > 63)
19881 int64_t IdxVal = IdxResult.getExtValue();
19884 ElemSize > std::numeric_limits<int64_t>::max() / IdxVal)
19885 return Error(OOE, diag::note_constexpr_offsetof_overflow);
19886 int64_t Offset = IdxVal * ElemSize;
19887 if (
Result.getQuantity() > std::numeric_limits<int64_t>::max() - Offset)
19888 return Error(OOE, diag::note_constexpr_offsetof_overflow);
19894 FieldDecl *MemberDecl = ON.
getField();
19899 const ASTRecordLayout &RL = Info.Ctx.getASTRecordLayout(RD);
19901 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
19908 llvm_unreachable(
"dependent __builtin_offsetof");
19911 CXXBaseSpecifier *BaseSpec = ON.
getBase();
19920 const ASTRecordLayout &RL = Info.Ctx.getASTRecordLayout(RD);
19923 CurrentType = BaseSpec->
getType();
19937bool IntExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
19957 if (Info.checkingForUndefinedBehavior())
19958 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
19959 diag::warn_integer_constant_overflow)
19987bool IntExprEvaluator::VisitCastExpr(
const CastExpr *E) {
19989 QualType DestType = E->
getType();
19990 QualType SrcType = SubExpr->
getType();
19993 case CK_BaseToDerived:
19994 case CK_DerivedToBase:
19995 case CK_UncheckedDerivedToBase:
19998 case CK_ArrayToPointerDecay:
19999 case CK_FunctionToPointerDecay:
20000 case CK_NullToPointer:
20001 case CK_NullToMemberPointer:
20002 case CK_BaseToDerivedMemberPointer:
20003 case CK_DerivedToBaseMemberPointer:
20004 case CK_ReinterpretMemberPointer:
20005 case CK_ConstructorConversion:
20006 case CK_IntegralToPointer:
20008 case CK_VectorSplat:
20009 case CK_IntegralToFloating:
20010 case CK_FloatingCast:
20011 case CK_CPointerToObjCPointerCast:
20012 case CK_BlockPointerToObjCPointerCast:
20013 case CK_AnyPointerToBlockPointerCast:
20014 case CK_ObjCObjectLValueCast:
20015 case CK_FloatingRealToComplex:
20016 case CK_FloatingComplexToReal:
20017 case CK_FloatingComplexCast:
20018 case CK_FloatingComplexToIntegralComplex:
20019 case CK_IntegralRealToComplex:
20020 case CK_IntegralComplexCast:
20021 case CK_IntegralComplexToFloatingComplex:
20022 case CK_BuiltinFnToFnPtr:
20023 case CK_ZeroToOCLOpaqueType:
20024 case CK_NonAtomicToAtomic:
20025 case CK_AddressSpaceConversion:
20026 case CK_IntToOCLSampler:
20027 case CK_FloatingToFixedPoint:
20028 case CK_FixedPointToFloating:
20029 case CK_FixedPointCast:
20030 case CK_IntegralToFixedPoint:
20031 case CK_MatrixCast:
20032 case CK_HLSLAggregateSplatCast:
20033 llvm_unreachable(
"invalid cast kind for integral value");
20037 case CK_LValueBitCast:
20038 case CK_ARCProduceObject:
20039 case CK_ARCConsumeObject:
20040 case CK_ARCReclaimReturnedObject:
20041 case CK_ARCExtendBlockObject:
20042 case CK_CopyAndAutoreleaseBlockObject:
20045 case CK_UserDefinedConversion:
20046 case CK_LValueToRValue:
20047 case CK_AtomicToNonAtomic:
20049 case CK_LValueToRValueBitCast:
20050 case CK_HLSLArrayRValue:
20051 return ExprEvaluatorBaseTy::VisitCastExpr(E);
20053 case CK_MemberPointerToBoolean:
20054 case CK_PointerToBoolean:
20055 case CK_IntegralToBoolean:
20056 case CK_FloatingToBoolean:
20057 case CK_BooleanToSignedIntegral:
20058 case CK_FloatingComplexToBoolean:
20059 case CK_IntegralComplexToBoolean: {
20064 if (BoolResult && E->
getCastKind() == CK_BooleanToSignedIntegral)
20066 return Success(IntResult, E);
20069 case CK_FixedPointToIntegral: {
20070 APFixedPoint Src(Info.Ctx.getFixedPointSemantics(SrcType));
20074 llvm::APSInt
Result = Src.convertToInt(
20075 Info.Ctx.getIntWidth(DestType),
20082 case CK_FixedPointToBoolean: {
20085 if (!
Evaluate(Val, Info, SubExpr))
20090 case CK_IntegralCast: {
20091 if (!Visit(SubExpr))
20101 if (
Result.isAddrLabelDiff()) {
20102 unsigned DestBits = Info.Ctx.getTypeSize(DestType);
20103 return DestBits >= 32 && DestBits <= Info.Ctx.getTypeSize(SrcType);
20106 return Info.Ctx.getTypeSize(DestType) == Info.Ctx.getTypeSize(SrcType);
20109 if (Info.Ctx.getLangOpts().CPlusPlus && DestType->
isEnumeralType()) {
20121 if (!ED->isFixed()) {
20125 ED->getValueRange(
Max,
Min);
20128 if (ED->getNumNegativeBits() &&
20129 (
Max.slt(
Result.getInt().getSExtValue()) ||
20130 Min.sgt(
Result.getInt().getSExtValue())))
20131 Info.CCEDiag(E, diag::note_constexpr_unscoped_enum_out_of_range)
20132 << llvm::toString(
Result.getInt(), 10) <<
Min.getSExtValue()
20133 <<
Max.getSExtValue() << ED;
20134 else if (!ED->getNumNegativeBits() &&
20135 Max.ult(
Result.getInt().getZExtValue()))
20136 Info.CCEDiag(E, diag::note_constexpr_unscoped_enum_out_of_range)
20137 << llvm::toString(
Result.getInt(), 10) <<
Min.getZExtValue()
20138 <<
Max.getZExtValue() << ED;
20146 case CK_PointerToIntegral: {
20147 CCEDiag(E, diag::note_constexpr_invalid_cast_ptrtoint)
20148 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
20155 if (LV.getLValueBase()) {
20156 CCEDiag(E, diag::note_constexpr_has_lvalue) << E->
getSourceRange();
20161 if (Info.Ctx.getTypeSize(DestType) != Info.Ctx.getTypeSize(SrcType))
20164 LV.Designator.setInvalid();
20172 if (!
V.toIntegralConstant(AsInt, SrcType, Info.Ctx))
20173 llvm_unreachable(
"Can't cast this!");
20178 case CK_IntegralComplexToReal: {
20182 return Success(
C.getComplexIntReal(), E);
20185 case CK_FloatingToIntegral: {
20195 case CK_HLSLVectorTruncation: {
20201 case CK_HLSLMatrixTruncation: {
20207 case CK_HLSLElementwiseCast: {
20220 return Success(ResultVal, E);
20224 llvm_unreachable(
"unknown cast resulting in integral value");
20227bool IntExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
20232 if (!LV.isComplexInt())
20234 return Success(LV.getComplexIntReal(), E);
20240bool IntExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
20245 if (!LV.isComplexInt())
20247 return Success(LV.getComplexIntImag(), E);
20254bool IntExprEvaluator::VisitSizeOfPackExpr(
const SizeOfPackExpr *E) {
20258bool IntExprEvaluator::VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E) {
20262bool IntExprEvaluator::VisitConceptSpecializationExpr(
20263 const ConceptSpecializationExpr *E) {
20267bool IntExprEvaluator::VisitRequiresExpr(
const RequiresExpr *E) {
20271bool FixedPointExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
20281 if (!
Result.isFixedPoint())
20284 APFixedPoint Negated =
Result.getFixedPoint().negate(&Overflowed);
20298bool FixedPointExprEvaluator::VisitCastExpr(
const CastExpr *E) {
20300 QualType DestType = E->
getType();
20302 "Expected destination type to be a fixed point type");
20303 auto DestFXSema = Info.Ctx.getFixedPointSemantics(DestType);
20306 case CK_FixedPointCast: {
20307 APFixedPoint Src(Info.Ctx.getFixedPointSemantics(SubExpr->
getType()));
20311 APFixedPoint
Result = Src.convert(DestFXSema, &Overflowed);
20313 if (Info.checkingForUndefinedBehavior())
20314 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
20315 diag::warn_fixedpoint_constant_overflow)
20322 case CK_IntegralToFixedPoint: {
20328 APFixedPoint IntResult = APFixedPoint::getFromIntValue(
20329 Src, Info.Ctx.getFixedPointSemantics(DestType), &Overflowed);
20332 if (Info.checkingForUndefinedBehavior())
20333 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
20334 diag::warn_fixedpoint_constant_overflow)
20335 << IntResult.toString() << E->
getType();
20340 return Success(IntResult, E);
20342 case CK_FloatingToFixedPoint: {
20348 APFixedPoint
Result = APFixedPoint::getFromFloatValue(
20349 Src, Info.Ctx.getFixedPointSemantics(DestType), &Overflowed);
20352 if (Info.checkingForUndefinedBehavior())
20353 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
20354 diag::warn_fixedpoint_constant_overflow)
20363 case CK_LValueToRValue:
20364 return ExprEvaluatorBaseTy::VisitCastExpr(E);
20370bool FixedPointExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
20372 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
20374 const Expr *LHS = E->
getLHS();
20375 const Expr *RHS = E->
getRHS();
20377 Info.Ctx.getFixedPointSemantics(E->
getType());
20379 APFixedPoint LHSFX(Info.Ctx.getFixedPointSemantics(LHS->
getType()));
20382 APFixedPoint RHSFX(Info.Ctx.getFixedPointSemantics(RHS->
getType()));
20386 bool OpOverflow =
false, ConversionOverflow =
false;
20387 APFixedPoint
Result(LHSFX.getSemantics());
20390 Result = LHSFX.add(RHSFX, &OpOverflow)
20391 .convert(ResultFXSema, &ConversionOverflow);
20395 Result = LHSFX.sub(RHSFX, &OpOverflow)
20396 .convert(ResultFXSema, &ConversionOverflow);
20400 Result = LHSFX.mul(RHSFX, &OpOverflow)
20401 .convert(ResultFXSema, &ConversionOverflow);
20405 if (RHSFX.getValue() == 0) {
20406 Info.FFDiag(E, diag::note_expr_divide_by_zero);
20409 Result = LHSFX.div(RHSFX, &OpOverflow)
20410 .convert(ResultFXSema, &ConversionOverflow);
20416 llvm::APSInt RHSVal = RHSFX.getValue();
20419 LHSSema.getWidth() - (unsigned)LHSSema.hasUnsignedPadding();
20420 unsigned Amt = RHSVal.getLimitedValue(ShiftBW - 1);
20424 if (RHSVal.isNegative())
20425 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHSVal;
20426 else if (Amt != RHSVal)
20427 Info.CCEDiag(E, diag::note_constexpr_large_shift)
20428 << RHSVal << E->
getType() << ShiftBW;
20431 Result = LHSFX.shl(Amt, &OpOverflow);
20433 Result = LHSFX.shr(Amt, &OpOverflow);
20439 if (OpOverflow || ConversionOverflow) {
20440 if (Info.checkingForUndefinedBehavior())
20441 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
20442 diag::warn_fixedpoint_constant_overflow)
20455class FloatExprEvaluator
20456 :
public ExprEvaluatorBase<FloatExprEvaluator> {
20459 FloatExprEvaluator(EvalInfo &info, APFloat &result)
20460 : ExprEvaluatorBaseTy(
info),
Result(result) {}
20467 bool ZeroInitialization(
const Expr *E) {
20468 Result = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(E->
getType()));
20472 bool VisitCallExpr(
const CallExpr *E);
20474 bool VisitUnaryOperator(
const UnaryOperator *E);
20475 bool VisitBinaryOperator(
const BinaryOperator *E);
20476 bool VisitFloatingLiteral(
const FloatingLiteral *E);
20477 bool VisitCastExpr(
const CastExpr *E);
20479 bool VisitUnaryReal(
const UnaryOperator *E);
20480 bool VisitUnaryImag(
const UnaryOperator *E);
20489 return FloatExprEvaluator(Info,
Result).Visit(E);
20496 llvm::APFloat &
Result) {
20501 const llvm::fltSemantics &Sem = Context.getFloatTypeSemantics(ResultTy);
20507 fill = llvm::APInt(32, 0);
20508 else if (S->
getString().getAsInteger(0, fill))
20511 if (Context.getTargetInfo().isNan2008()) {
20513 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
20515 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
20523 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
20525 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
20531bool FloatExprEvaluator::VisitCallExpr(
const CallExpr *E) {
20532 if (!IsConstantEvaluatedBuiltinCall(E))
20533 return ExprEvaluatorBaseTy::VisitCallExpr(E);
20537 switch (BuiltinOp) {
20541 case Builtin::BI__builtin_huge_val:
20542 case Builtin::BI__builtin_huge_valf:
20543 case Builtin::BI__builtin_huge_vall:
20544 case Builtin::BI__builtin_huge_valf16:
20545 case Builtin::BI__builtin_huge_valf128:
20546 case Builtin::BI__builtin_inf:
20547 case Builtin::BI__builtin_inff:
20548 case Builtin::BI__builtin_infl:
20549 case Builtin::BI__builtin_inff16:
20550 case Builtin::BI__builtin_inff128: {
20551 const llvm::fltSemantics &Sem =
20552 Info.Ctx.getFloatTypeSemantics(E->
getType());
20553 Result = llvm::APFloat::getInf(Sem);
20557 case Builtin::BI__builtin_nans:
20558 case Builtin::BI__builtin_nansf:
20559 case Builtin::BI__builtin_nansl:
20560 case Builtin::BI__builtin_nansf16:
20561 case Builtin::BI__builtin_nansf128:
20567 case Builtin::BI__builtin_nan:
20568 case Builtin::BI__builtin_nanf:
20569 case Builtin::BI__builtin_nanl:
20570 case Builtin::BI__builtin_nanf16:
20571 case Builtin::BI__builtin_nanf128:
20579 case Builtin::BI__builtin_elementwise_abs:
20580 case Builtin::BI__builtin_fabs:
20581 case Builtin::BI__builtin_fabsf:
20582 case Builtin::BI__builtin_fabsl:
20583 case Builtin::BI__builtin_fabsf128:
20592 if (
Result.isNegative())
20596 case Builtin::BI__arithmetic_fence:
20603 case Builtin::BI__builtin_copysign:
20604 case Builtin::BI__builtin_copysignf:
20605 case Builtin::BI__builtin_copysignl:
20606 case Builtin::BI__builtin_copysignf128: {
20615 case Builtin::BI__builtin_fmax:
20616 case Builtin::BI__builtin_fmaxf:
20617 case Builtin::BI__builtin_fmaxl:
20618 case Builtin::BI__builtin_fmaxf16:
20619 case Builtin::BI__builtin_fmaxf128: {
20628 case Builtin::BI__builtin_fmin:
20629 case Builtin::BI__builtin_fminf:
20630 case Builtin::BI__builtin_fminl:
20631 case Builtin::BI__builtin_fminf16:
20632 case Builtin::BI__builtin_fminf128: {
20641 case Builtin::BI__builtin_fmaximum_num:
20642 case Builtin::BI__builtin_fmaximum_numf:
20643 case Builtin::BI__builtin_fmaximum_numl:
20644 case Builtin::BI__builtin_fmaximum_numf16:
20645 case Builtin::BI__builtin_fmaximum_numf128: {
20654 case Builtin::BI__builtin_fminimum_num:
20655 case Builtin::BI__builtin_fminimum_numf:
20656 case Builtin::BI__builtin_fminimum_numl:
20657 case Builtin::BI__builtin_fminimum_numf16:
20658 case Builtin::BI__builtin_fminimum_numf128: {
20667 case Builtin::BI__builtin_elementwise_fma: {
20672 APFloat SourceY(0.), SourceZ(0.);
20678 (void)
Result.fusedMultiplyAdd(SourceY, SourceZ, RM);
20682 case clang::X86::BI__builtin_ia32_vec_ext_v4sf: {
20689 unsigned Idx =
static_cast<unsigned>(IdxAPS.getZExtValue() & (N - 1));
20695bool FloatExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
20707bool FloatExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
20717 const llvm::fltSemantics &Sem = Info.Ctx.getFloatTypeSemantics(E->
getType());
20718 Result = llvm::APFloat::getZero(Sem);
20722bool FloatExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
20724 default:
return Error(E);
20738bool FloatExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
20740 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
20744 if (!LHSOK && !Info.noteFailure())
20750bool FloatExprEvaluator::VisitFloatingLiteral(
const FloatingLiteral *E) {
20755bool FloatExprEvaluator::VisitCastExpr(
const CastExpr *E) {
20760 return ExprEvaluatorBaseTy::VisitCastExpr(E);
20762 case CK_HLSLAggregateSplatCast:
20763 llvm_unreachable(
"invalid cast kind for floating value");
20765 case CK_IntegralToFloating: {
20768 Info.Ctx.getLangOpts());
20774 case CK_FixedPointToFloating: {
20775 APFixedPoint FixResult(Info.Ctx.getFixedPointSemantics(SubExpr->
getType()));
20779 FixResult.convertToFloat(Info.Ctx.getFloatTypeSemantics(E->
getType()));
20783 case CK_FloatingCast: {
20784 if (!Visit(SubExpr))
20790 case CK_FloatingComplexToReal: {
20794 Result =
V.getComplexFloatReal();
20797 case CK_HLSLVectorTruncation: {
20803 case CK_HLSLMatrixTruncation: {
20809 case CK_HLSLElementwiseCast: {
20824 return Success(ResultVal, E);
20834class ComplexExprEvaluator
20835 :
public ExprEvaluatorBase<ComplexExprEvaluator> {
20839 ComplexExprEvaluator(EvalInfo &info, ComplexValue &
Result)
20847 bool ZeroInitialization(
const Expr *E);
20853 bool VisitImaginaryLiteral(
const ImaginaryLiteral *E);
20854 bool VisitCastExpr(
const CastExpr *E);
20855 bool VisitBinaryOperator(
const BinaryOperator *E);
20856 bool VisitUnaryOperator(
const UnaryOperator *E);
20857 bool VisitInitListExpr(
const InitListExpr *E);
20858 bool VisitCallExpr(
const CallExpr *E);
20866 return ComplexExprEvaluator(Info,
Result).Visit(E);
20869bool ComplexExprEvaluator::ZeroInitialization(
const Expr *E) {
20870 QualType ElemTy = E->
getType()->
castAs<ComplexType>()->getElementType();
20872 Result.makeComplexFloat();
20873 APFloat Zero = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(ElemTy));
20877 Result.makeComplexInt();
20878 APSInt Zero = Info.Ctx.MakeIntValue(0, ElemTy);
20885bool ComplexExprEvaluator::VisitImaginaryLiteral(
const ImaginaryLiteral *E) {
20889 Result.makeComplexFloat();
20898 "Unexpected imaginary literal.");
20900 Result.makeComplexInt();
20905 Result.IntReal =
APSInt(Imag.getBitWidth(), !Imag.isSigned());
20910bool ComplexExprEvaluator::VisitCastExpr(
const CastExpr *E) {
20914 case CK_BaseToDerived:
20915 case CK_DerivedToBase:
20916 case CK_UncheckedDerivedToBase:
20919 case CK_ArrayToPointerDecay:
20920 case CK_FunctionToPointerDecay:
20921 case CK_NullToPointer:
20922 case CK_NullToMemberPointer:
20923 case CK_BaseToDerivedMemberPointer:
20924 case CK_DerivedToBaseMemberPointer:
20925 case CK_MemberPointerToBoolean:
20926 case CK_ReinterpretMemberPointer:
20927 case CK_ConstructorConversion:
20928 case CK_IntegralToPointer:
20929 case CK_PointerToIntegral:
20930 case CK_PointerToBoolean:
20932 case CK_VectorSplat:
20933 case CK_IntegralCast:
20934 case CK_BooleanToSignedIntegral:
20935 case CK_IntegralToBoolean:
20936 case CK_IntegralToFloating:
20937 case CK_FloatingToIntegral:
20938 case CK_FloatingToBoolean:
20939 case CK_FloatingCast:
20940 case CK_CPointerToObjCPointerCast:
20941 case CK_BlockPointerToObjCPointerCast:
20942 case CK_AnyPointerToBlockPointerCast:
20943 case CK_ObjCObjectLValueCast:
20944 case CK_FloatingComplexToReal:
20945 case CK_FloatingComplexToBoolean:
20946 case CK_IntegralComplexToReal:
20947 case CK_IntegralComplexToBoolean:
20948 case CK_ARCProduceObject:
20949 case CK_ARCConsumeObject:
20950 case CK_ARCReclaimReturnedObject:
20951 case CK_ARCExtendBlockObject:
20952 case CK_CopyAndAutoreleaseBlockObject:
20953 case CK_BuiltinFnToFnPtr:
20954 case CK_ZeroToOCLOpaqueType:
20955 case CK_NonAtomicToAtomic:
20956 case CK_AddressSpaceConversion:
20957 case CK_IntToOCLSampler:
20958 case CK_FloatingToFixedPoint:
20959 case CK_FixedPointToFloating:
20960 case CK_FixedPointCast:
20961 case CK_FixedPointToBoolean:
20962 case CK_FixedPointToIntegral:
20963 case CK_IntegralToFixedPoint:
20964 case CK_MatrixCast:
20965 case CK_HLSLVectorTruncation:
20966 case CK_HLSLMatrixTruncation:
20967 case CK_HLSLElementwiseCast:
20968 case CK_HLSLAggregateSplatCast:
20969 llvm_unreachable(
"invalid cast kind for complex value");
20971 case CK_LValueToRValue:
20972 case CK_AtomicToNonAtomic:
20974 case CK_LValueToRValueBitCast:
20975 case CK_HLSLArrayRValue:
20976 return ExprEvaluatorBaseTy::VisitCastExpr(E);
20979 case CK_LValueBitCast:
20980 case CK_UserDefinedConversion:
20983 case CK_FloatingRealToComplex: {
20988 Result.makeComplexFloat();
20993 case CK_FloatingComplexCast: {
20997 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
21005 case CK_FloatingComplexToIntegralComplex: {
21009 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
21012 Result.makeComplexInt();
21019 case CK_IntegralRealToComplex: {
21024 Result.makeComplexInt();
21025 Result.IntImag =
APSInt(Real.getBitWidth(), !Real.isSigned());
21029 case CK_IntegralComplexCast: {
21033 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
21042 case CK_IntegralComplexToFloatingComplex: {
21047 Info.Ctx.getLangOpts());
21048 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
21051 Result.makeComplexFloat();
21053 To,
Result.FloatReal) &&
21059 llvm_unreachable(
"unknown cast resulting in complex value");
21065 0x00, 0x01, 0x8d, 0xf6, 0xcb, 0x52, 0x7b, 0xd1, 0xe8, 0x4f, 0x29, 0xc0,
21066 0xb0, 0xe1, 0xe5, 0xc7, 0x74, 0xb4, 0xaa, 0x4b, 0x99, 0x2b, 0x60, 0x5f,
21067 0x58, 0x3f, 0xfd, 0xcc, 0xff, 0x40, 0xee, 0xb2, 0x3a, 0x6e, 0x5a, 0xf1,
21068 0x55, 0x4d, 0xa8, 0xc9, 0xc1, 0x0a, 0x98, 0x15, 0x30, 0x44, 0xa2, 0xc2,
21069 0x2c, 0x45, 0x92, 0x6c, 0xf3, 0x39, 0x66, 0x42, 0xf2, 0x35, 0x20, 0x6f,
21070 0x77, 0xbb, 0x59, 0x19, 0x1d, 0xfe, 0x37, 0x67, 0x2d, 0x31, 0xf5, 0x69,
21071 0xa7, 0x64, 0xab, 0x13, 0x54, 0x25, 0xe9, 0x09, 0xed, 0x5c, 0x05, 0xca,
21072 0x4c, 0x24, 0x87, 0xbf, 0x18, 0x3e, 0x22, 0xf0, 0x51, 0xec, 0x61, 0x17,
21073 0x16, 0x5e, 0xaf, 0xd3, 0x49, 0xa6, 0x36, 0x43, 0xf4, 0x47, 0x91, 0xdf,
21074 0x33, 0x93, 0x21, 0x3b, 0x79, 0xb7, 0x97, 0x85, 0x10, 0xb5, 0xba, 0x3c,
21075 0xb6, 0x70, 0xd0, 0x06, 0xa1, 0xfa, 0x81, 0x82, 0x83, 0x7e, 0x7f, 0x80,
21076 0x96, 0x73, 0xbe, 0x56, 0x9b, 0x9e, 0x95, 0xd9, 0xf7, 0x02, 0xb9, 0xa4,
21077 0xde, 0x6a, 0x32, 0x6d, 0xd8, 0x8a, 0x84, 0x72, 0x2a, 0x14, 0x9f, 0x88,
21078 0xf9, 0xdc, 0x89, 0x9a, 0xfb, 0x7c, 0x2e, 0xc3, 0x8f, 0xb8, 0x65, 0x48,
21079 0x26, 0xc8, 0x12, 0x4a, 0xce, 0xe7, 0xd2, 0x62, 0x0c, 0xe0, 0x1f, 0xef,
21080 0x11, 0x75, 0x78, 0x71, 0xa5, 0x8e, 0x76, 0x3d, 0xbd, 0xbc, 0x86, 0x57,
21081 0x0b, 0x28, 0x2f, 0xa3, 0xda, 0xd4, 0xe4, 0x0f, 0xa9, 0x27, 0x53, 0x04,
21082 0x1b, 0xfc, 0xac, 0xe6, 0x7a, 0x07, 0xae, 0x63, 0xc5, 0xdb, 0xe2, 0xea,
21083 0x94, 0x8b, 0xc4, 0xd5, 0x9d, 0xf8, 0x90, 0x6b, 0xb1, 0x0d, 0xd6, 0xeb,
21084 0xc6, 0x0e, 0xcf, 0xad, 0x08, 0x4e, 0xd7, 0xe3, 0x5d, 0x50, 0x1e, 0xb3,
21085 0x5b, 0x23, 0x38, 0x34, 0x68, 0x46, 0x03, 0x8c, 0xdd, 0x9c, 0x7d, 0xa0,
21086 0xcd, 0x1a, 0x41, 0x1c};
21088 return GFInv[Byte];
21093 unsigned NumBitsInByte = 8;
21096 for (
uint32_t BitIdx = 0; BitIdx != NumBitsInByte; ++BitIdx) {
21098 AQword.lshr((7 -
static_cast<int32_t>(BitIdx)) * NumBitsInByte)
21105 Product = AByte & XByte;
21110 for (
unsigned PBitIdx = 0; PBitIdx != NumBitsInByte; ++PBitIdx) {
21111 Parity = Parity ^ ((Product >> PBitIdx) & 0x1);
21114 uint8_t Temp = Imm[BitIdx] ? 1 : 0;
21115 RetByte |= (Temp ^ Parity) << BitIdx;
21125 unsigned NumBitsInByte = 8;
21126 for (
unsigned BitIdx = 0; BitIdx != NumBitsInByte; ++BitIdx) {
21127 if ((BByte >> BitIdx) & 0x1) {
21128 TWord = TWord ^ (AByte << BitIdx);
21136 for (
int32_t BitIdx = 14; BitIdx > 7; --BitIdx) {
21137 if ((TWord >> BitIdx) & 0x1) {
21138 TWord = TWord ^ (0x11B << (BitIdx - 8));
21141 return (TWord & 0xFF);
21145 APFloat &ResR, APFloat &ResI) {
21151 APFloat AC = A *
C;
21152 APFloat BD = B * D;
21153 APFloat AD = A * D;
21154 APFloat BC = B *
C;
21157 if (ResR.isNaN() && ResI.isNaN()) {
21158 bool Recalc =
false;
21159 if (A.isInfinity() || B.isInfinity()) {
21160 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
21162 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
21165 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
21167 D = APFloat::copySign(APFloat(D.getSemantics()), D);
21170 if (
C.isInfinity() || D.isInfinity()) {
21171 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
21173 D = APFloat::copySign(APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0),
21176 A = APFloat::copySign(APFloat(A.getSemantics()), A);
21178 B = APFloat::copySign(APFloat(B.getSemantics()), B);
21181 if (!Recalc && (AC.isInfinity() || BD.isInfinity() || AD.isInfinity() ||
21182 BC.isInfinity())) {
21184 A = APFloat::copySign(APFloat(A.getSemantics()), A);
21186 B = APFloat::copySign(APFloat(B.getSemantics()), B);
21188 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
21190 D = APFloat::copySign(APFloat(D.getSemantics()), D);
21194 ResR = APFloat::getInf(A.getSemantics()) * (A *
C - B * D);
21195 ResI = APFloat::getInf(A.getSemantics()) * (A * D + B *
C);
21201 APFloat &ResR, APFloat &ResI) {
21208 APFloat MaxCD = maxnum(
abs(
C),
abs(D));
21209 if (MaxCD.isFinite()) {
21210 DenomLogB =
ilogb(MaxCD);
21211 C =
scalbn(
C, -DenomLogB, APFloat::rmNearestTiesToEven);
21212 D =
scalbn(D, -DenomLogB, APFloat::rmNearestTiesToEven);
21214 APFloat Denom =
C *
C + D * D;
21216 scalbn((A *
C + B * D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
21218 scalbn((B *
C - A * D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
21219 if (ResR.isNaN() && ResI.isNaN()) {
21220 if (Denom.isPosZero() && (!A.isNaN() || !B.isNaN())) {
21221 ResR = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * A;
21222 ResI = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * B;
21223 }
else if ((A.isInfinity() || B.isInfinity()) &&
C.isFinite() &&
21225 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
21227 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
21229 ResR = APFloat::getInf(ResR.getSemantics()) * (A *
C + B * D);
21230 ResI = APFloat::getInf(ResI.getSemantics()) * (B *
C - A * D);
21231 }
else if (MaxCD.isInfinity() && A.isFinite() && B.isFinite()) {
21232 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
21234 D = APFloat::copySign(APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0),
21236 ResR = APFloat::getZero(ResR.getSemantics()) * (A *
C + B * D);
21237 ResI = APFloat::getZero(ResI.getSemantics()) * (B *
C - A * D);
21244 APSInt NormAmt = Amount;
21245 unsigned BitWidth =
Value.getBitWidth();
21246 unsigned AmtBitWidth = NormAmt.getBitWidth();
21247 if (BitWidth == 1) {
21249 NormAmt =
APSInt(APInt(AmtBitWidth, 0), NormAmt.isUnsigned());
21250 }
else if (BitWidth == 2) {
21255 APSInt(APInt(AmtBitWidth, NormAmt[0] ? 1 : 0), NormAmt.isUnsigned());
21258 if (AmtBitWidth > BitWidth) {
21259 Divisor = llvm::APInt(AmtBitWidth, BitWidth);
21261 Divisor = llvm::APInt(BitWidth, BitWidth);
21262 if (AmtBitWidth < BitWidth) {
21263 NormAmt = NormAmt.extend(BitWidth);
21268 if (NormAmt.isSigned()) {
21269 NormAmt =
APSInt(NormAmt.srem(Divisor),
false);
21270 if (NormAmt.isNegative()) {
21271 APSInt SignedDivisor(Divisor,
false);
21272 NormAmt += SignedDivisor;
21275 NormAmt =
APSInt(NormAmt.urem(Divisor),
true);
21282bool ComplexExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
21284 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
21288 bool LHSReal =
false, RHSReal =
false;
21296 Result.makeComplexFloat();
21300 LHSOK = Visit(E->
getLHS());
21302 if (!LHSOK && !Info.noteFailure())
21308 APFloat &Real = RHS.FloatReal;
21311 RHS.makeComplexFloat();
21312 RHS.FloatImag =
APFloat(Real.getSemantics());
21316 assert(!(LHSReal && RHSReal) &&
21317 "Cannot have both operands of a complex operation be real.");
21319 default:
return Error(E);
21321 if (
Result.isComplexFloat()) {
21322 Result.getComplexFloatReal().add(RHS.getComplexFloatReal(),
21323 APFloat::rmNearestTiesToEven);
21325 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
21327 Result.getComplexFloatImag().add(RHS.getComplexFloatImag(),
21328 APFloat::rmNearestTiesToEven);
21330 Result.getComplexIntReal() += RHS.getComplexIntReal();
21331 Result.getComplexIntImag() += RHS.getComplexIntImag();
21335 if (
Result.isComplexFloat()) {
21336 Result.getComplexFloatReal().subtract(RHS.getComplexFloatReal(),
21337 APFloat::rmNearestTiesToEven);
21339 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
21340 Result.getComplexFloatImag().changeSign();
21341 }
else if (!RHSReal) {
21342 Result.getComplexFloatImag().subtract(RHS.getComplexFloatImag(),
21343 APFloat::rmNearestTiesToEven);
21346 Result.getComplexIntReal() -= RHS.getComplexIntReal();
21347 Result.getComplexIntImag() -= RHS.getComplexIntImag();
21351 if (
Result.isComplexFloat()) {
21356 ComplexValue LHS =
Result;
21357 APFloat &A = LHS.getComplexFloatReal();
21358 APFloat &B = LHS.getComplexFloatImag();
21359 APFloat &
C = RHS.getComplexFloatReal();
21360 APFloat &D = RHS.getComplexFloatImag();
21364 assert(!RHSReal &&
"Cannot have two real operands for a complex op!");
21372 }
else if (RHSReal) {
21384 ComplexValue LHS =
Result;
21385 Result.getComplexIntReal() =
21386 (LHS.getComplexIntReal() * RHS.getComplexIntReal() -
21387 LHS.getComplexIntImag() * RHS.getComplexIntImag());
21388 Result.getComplexIntImag() =
21389 (LHS.getComplexIntReal() * RHS.getComplexIntImag() +
21390 LHS.getComplexIntImag() * RHS.getComplexIntReal());
21394 if (
Result.isComplexFloat()) {
21399 ComplexValue LHS =
Result;
21400 APFloat &A = LHS.getComplexFloatReal();
21401 APFloat &B = LHS.getComplexFloatImag();
21402 APFloat &
C = RHS.getComplexFloatReal();
21403 APFloat &D = RHS.getComplexFloatImag();
21417 B = APFloat::getZero(A.getSemantics());
21422 ComplexValue LHS =
Result;
21423 APSInt Den = RHS.getComplexIntReal() * RHS.getComplexIntReal() +
21424 RHS.getComplexIntImag() * RHS.getComplexIntImag();
21426 return Error(E, diag::note_expr_divide_by_zero);
21428 Result.getComplexIntReal() =
21429 (LHS.getComplexIntReal() * RHS.getComplexIntReal() +
21430 LHS.getComplexIntImag() * RHS.getComplexIntImag()) / Den;
21431 Result.getComplexIntImag() =
21432 (LHS.getComplexIntImag() * RHS.getComplexIntReal() -
21433 LHS.getComplexIntReal() * RHS.getComplexIntImag()) / Den;
21441bool ComplexExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
21455 if (
Result.isComplexFloat()) {
21456 Result.getComplexFloatReal().changeSign();
21457 Result.getComplexFloatImag().changeSign();
21460 Result.getComplexIntReal() = -
Result.getComplexIntReal();
21461 Result.getComplexIntImag() = -
Result.getComplexIntImag();
21465 if (
Result.isComplexFloat())
21466 Result.getComplexFloatImag().changeSign();
21468 Result.getComplexIntImag() = -
Result.getComplexIntImag();
21473bool ComplexExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
21476 Result.makeComplexFloat();
21482 Result.makeComplexInt();
21490 return ExprEvaluatorBaseTy::VisitInitListExpr(E);
21493bool ComplexExprEvaluator::VisitCallExpr(
const CallExpr *E) {
21494 if (!IsConstantEvaluatedBuiltinCall(E))
21495 return ExprEvaluatorBaseTy::VisitCallExpr(E);
21498 case Builtin::BI__builtin_complex:
21499 Result.makeComplexFloat();
21517class AtomicExprEvaluator :
21518 public ExprEvaluatorBase<AtomicExprEvaluator> {
21519 const LValue *
This;
21522 AtomicExprEvaluator(EvalInfo &Info,
const LValue *This,
APValue &
Result)
21530 bool ZeroInitialization(
const Expr *E) {
21531 ImplicitValueInitExpr VIE(
21539 bool VisitCastExpr(
const CastExpr *E) {
21542 return ExprEvaluatorBaseTy::VisitCastExpr(E);
21543 case CK_NullToPointer:
21545 return ZeroInitialization(E);
21546 case CK_NonAtomicToAtomic:
21558 return AtomicExprEvaluator(Info,
This,
Result).Visit(E);
21567class VoidExprEvaluator
21568 :
public ExprEvaluatorBase<VoidExprEvaluator> {
21570 VoidExprEvaluator(EvalInfo &Info) : ExprEvaluatorBaseTy(Info) {}
21574 bool ZeroInitialization(
const Expr *E) {
return true; }
21576 bool VisitCastExpr(
const CastExpr *E) {
21579 return ExprEvaluatorBaseTy::VisitCastExpr(E);
21586 bool VisitCallExpr(
const CallExpr *E) {
21587 if (!IsConstantEvaluatedBuiltinCall(E))
21588 return ExprEvaluatorBaseTy::VisitCallExpr(E);
21591 case Builtin::BI__assume:
21592 case Builtin::BI__builtin_assume:
21596 case Builtin::BI__builtin_operator_delete:
21604 bool VisitCXXDeleteExpr(
const CXXDeleteExpr *E);
21608bool VoidExprEvaluator::VisitCXXDeleteExpr(
const CXXDeleteExpr *E) {
21610 if (Info.SpeculativeEvaluationDepth)
21614 if (!OperatorDelete
21615 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
21616 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
21626 if (
Pointer.Designator.Invalid)
21630 if (
Pointer.isNullPointer()) {
21634 if (!Info.getLangOpts().CPlusPlus20)
21635 Info.CCEDiag(E, diag::note_constexpr_new);
21643 QualType AllocType =
Pointer.Base.getDynamicAllocType();
21649 Info.FFDiag(E, diag::note_constexpr_delete_base_nonvirt_dtor)
21658 if (VirtualDelete &&
21660 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
21661 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
21668 (*Alloc)->Value, AllocType))
21671 if (!Info.HeapAllocs.erase(
Pointer.Base.dyn_cast<DynamicAllocLValue>())) {
21676 Info.FFDiag(E, diag::note_constexpr_double_delete);
21686 return VoidExprEvaluator(Info).Visit(E);
21698 if (E->
isGLValue() ||
T->isFunctionType()) {
21703 }
else if (
T->isVectorType()) {
21706 }
else if (
T->isConstantMatrixType()) {
21709 }
else if (
T->isIntegralOrEnumerationType()) {
21710 if (!IntExprEvaluator(Info,
Result).Visit(E))
21712 }
else if (
T->hasPointerRepresentation()) {
21717 }
else if (
T->isRealFloatingType()) {
21718 llvm::APFloat F(0.0);
21722 }
else if (
T->isAnyComplexType()) {
21727 }
else if (
T->isFixedPointType()) {
21728 if (!FixedPointExprEvaluator(Info,
Result).Visit(E))
return false;
21729 }
else if (
T->isMemberPointerType()) {
21735 }
else if (
T->isArrayType()) {
21738 Info.CurrentCall->createTemporary(E,
T, ScopeKind::FullExpression, LV);
21742 }
else if (
T->isRecordType()) {
21745 Info.CurrentCall->createTemporary(E,
T, ScopeKind::FullExpression, LV);
21749 }
else if (
T->isVoidType()) {
21750 if (!Info.getLangOpts().CPlusPlus11)
21751 Info.CCEDiag(E, diag::note_constexpr_nonliteral)
21755 }
else if (
T->isAtomicType()) {
21756 QualType Unqual =
T.getAtomicUnqualifiedType();
21760 E, Unqual, ScopeKind::FullExpression, LV);
21768 }
else if (Info.getLangOpts().CPlusPlus11) {
21769 Info.FFDiag(E, diag::note_constexpr_nonliteral) << E->
getType();
21772 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
21783 const Expr *E,
bool AllowNonLiteralTypes) {
21799 if (
T->isArrayType())
21801 else if (
T->isRecordType())
21803 else if (
T->isAtomicType()) {
21804 QualType Unqual =
T.getAtomicUnqualifiedType();
21825 if (Info.EnableNewConstInterp) {
21826 if (!Info.Ctx.getInterpContext().evaluateAsRValue(Info, E,
Result))
21829 ConstantExprKind::Normal);
21838 LV.setFrom(Info.Ctx,
Result);
21845 ConstantExprKind::Normal) &&
21853 if (
const auto *L = dyn_cast<IntegerLiteral>(Exp)) {
21855 APValue(
APSInt(L->getValue(), L->getType()->isUnsignedIntegerType()));
21860 if (
const auto *L = dyn_cast<CXXBoolLiteralExpr>(Exp)) {
21866 if (
const auto *FL = dyn_cast<FloatingLiteral>(Exp)) {
21872 if (
const auto *L = dyn_cast<CharacterLiteral>(Exp)) {
21878 if (
const auto *CE = dyn_cast<ConstantExpr>(Exp)) {
21879 if (CE->hasAPValueResult()) {
21880 APValue APV = CE->getAPValueResult();
21882 Result = std::move(APV);
21958 bool InConstantContext)
const {
21960 "Expression evaluator can't be called on a dependent expression.");
21961 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsRValue");
21963 Info.InConstantContext = InConstantContext;
21964 return ::EvaluateAsRValue(
this,
Result, Ctx, Info);
21968 bool InConstantContext)
const {
21970 "Expression evaluator can't be called on a dependent expression.");
21971 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsBooleanCondition");
21979 bool InConstantContext)
const {
21981 "Expression evaluator can't be called on a dependent expression.");
21982 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsInt");
21984 Info.InConstantContext = InConstantContext;
21985 return ::EvaluateAsInt(
this,
Result, Ctx, AllowSideEffects, Info);
21990 bool InConstantContext)
const {
21992 "Expression evaluator can't be called on a dependent expression.");
21993 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFixedPoint");
21995 Info.InConstantContext = InConstantContext;
21996 return ::EvaluateAsFixedPoint(
this,
Result, Ctx, AllowSideEffects, Info);
22001 bool InConstantContext)
const {
22003 "Expression evaluator can't be called on a dependent expression.");
22005 if (!
getType()->isRealFloatingType())
22008 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFloat");
22020 bool InConstantContext)
const {
22022 "Expression evaluator can't be called on a dependent expression.");
22024 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsLValue");
22026 Info.InConstantContext = InConstantContext;
22030 if (Info.EnableNewConstInterp) {
22031 if (!Info.Ctx.getInterpContext().evaluate(Info,
this,
Result.Val,
22032 ConstantExprKind::Normal))
22035 LV.setFrom(Ctx,
Result.Val);
22038 ConstantExprKind::Normal, CheckedTemps);
22041 if (!
EvaluateLValue(
this, LV, Info) || !Info.discardCleanups() ||
22042 Result.HasSideEffects ||
22045 ConstantExprKind::Normal, CheckedTemps))
22048 LV.moveInto(
Result.Val);
22055 bool IsConstantDestruction) {
22056 EvalInfo Info(Ctx, EStatus,
22059 Info.setEvaluatingDecl(
Base, DestroyedValue,
22060 EvalInfo::EvaluatingDeclKind::Dtor);
22061 Info.InConstantContext = IsConstantDestruction;
22070 if (!Info.discardCleanups())
22071 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
22079 "Expression evaluator can't be called on a dependent expression.");
22085 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsConstantExpr");
22087 EvalInfo Info(Ctx,
Result, EM);
22088 Info.InConstantContext =
true;
22090 if (Info.EnableNewConstInterp) {
22091 if (!Info.Ctx.getInterpContext().evaluate(Info,
this,
Result.Val, Kind))
22094 getStorageType(Ctx,
this),
Result.Val, Kind);
22099 if (Kind == ConstantExprKind::ClassTemplateArgument)
22115 FullExpressionRAII
Scope(Info);
22120 if (!Info.discardCleanups())
22121 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
22131 if (Kind == ConstantExprKind::ClassTemplateArgument &&
22134 Result.HasSideEffects)) {
22144 bool IsConstantInitialization)
const {
22146 "Expression evaluator can't be called on a dependent expression.");
22147 assert(VD &&
"Need a valid VarDecl");
22149 llvm::TimeTraceScope TimeScope(
"EvaluateAsInitializer", [&] {
22151 llvm::raw_string_ostream OS(Name);
22156 EvalInfo Info(Ctx, EStatus,
22157 (IsConstantInitialization &&
22161 Info.setEvaluatingDecl(VD, EStatus.
Val);
22162 Info.InConstantContext = IsConstantInitialization;
22167 if (Info.EnableNewConstInterp) {
22169 if (!InterpCtx.evaluateAsInitializer(Info, VD,
this, EStatus.
Val))
22173 ConstantExprKind::Normal);
22188 FullExpressionRAII
Scope(Info);
22197 Info.performLifetimeExtension();
22199 if (!Info.discardCleanups())
22200 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
22204 ConstantExprKind::Normal) &&
22224 EStatus.
Diag = &Notes;
22241 EvalInfo Info(Ctx, EStatus,
22244 Info.InConstantContext = IsConstantDestruction;
22246 std::move(DestroyedValue)))
22253 getLocation(), EStatus, IsConstantDestruction) ||
22265 "Expression evaluator can't be called on a dependent expression.");
22274 "Expression evaluator can't be called on a dependent expression.");
22276 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstInt");
22279 Info.InConstantContext =
true;
22283 assert(
Result &&
"Could not evaluate expression");
22284 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
22286 return EVResult.Val.getInt();
22292 "Expression evaluator can't be called on a dependent expression.");
22294 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstIntCheckOverflow");
22296 EVResult.Diag =
Diag;
22298 Info.InConstantContext =
true;
22299 Info.CheckingForUndefinedBehavior =
true;
22303 assert(
Result &&
"Could not evaluate expression");
22304 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
22306 return EVResult.Val.getInt();
22311 "Expression evaluator can't be called on a dependent expression.");
22313 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateForOverflow");
22318 Info.CheckingForUndefinedBehavior =
true;
22324 assert(
Val.isLValue());
22350 IK_ICEIfUnevaluated,
22366static ICEDiag
Worst(ICEDiag A, ICEDiag B) {
return A.Kind >= B.Kind ? A : B; }
22373 Info.InConstantContext =
true;
22382 assert(!E->
isValueDependent() &&
"Should not see value dependent exprs!");
22387#define ABSTRACT_STMT(Node)
22388#define STMT(Node, Base) case Expr::Node##Class:
22389#define EXPR(Node, Base)
22390#include "clang/AST/StmtNodes.inc"
22391 case Expr::PredefinedExprClass:
22392 case Expr::FloatingLiteralClass:
22393 case Expr::ImaginaryLiteralClass:
22394 case Expr::StringLiteralClass:
22395 case Expr::ArraySubscriptExprClass:
22396 case Expr::MatrixSingleSubscriptExprClass:
22397 case Expr::MatrixSubscriptExprClass:
22398 case Expr::ArraySectionExprClass:
22399 case Expr::OMPArrayShapingExprClass:
22400 case Expr::OMPIteratorExprClass:
22401 case Expr::CompoundAssignOperatorClass:
22402 case Expr::CompoundLiteralExprClass:
22403 case Expr::ExtVectorElementExprClass:
22404 case Expr::MatrixElementExprClass:
22405 case Expr::DesignatedInitExprClass:
22406 case Expr::ArrayInitLoopExprClass:
22407 case Expr::ArrayInitIndexExprClass:
22408 case Expr::NoInitExprClass:
22409 case Expr::DesignatedInitUpdateExprClass:
22410 case Expr::ImplicitValueInitExprClass:
22411 case Expr::ParenListExprClass:
22412 case Expr::VAArgExprClass:
22413 case Expr::AddrLabelExprClass:
22414 case Expr::StmtExprClass:
22415 case Expr::CXXMemberCallExprClass:
22416 case Expr::CUDAKernelCallExprClass:
22417 case Expr::CXXAddrspaceCastExprClass:
22418 case Expr::CXXDynamicCastExprClass:
22419 case Expr::CXXTypeidExprClass:
22420 case Expr::CXXUuidofExprClass:
22421 case Expr::MSPropertyRefExprClass:
22422 case Expr::MSPropertySubscriptExprClass:
22423 case Expr::CXXNullPtrLiteralExprClass:
22424 case Expr::UserDefinedLiteralClass:
22425 case Expr::CXXThisExprClass:
22426 case Expr::CXXThrowExprClass:
22427 case Expr::CXXNewExprClass:
22428 case Expr::CXXDeleteExprClass:
22429 case Expr::CXXPseudoDestructorExprClass:
22430 case Expr::UnresolvedLookupExprClass:
22431 case Expr::RecoveryExprClass:
22432 case Expr::DependentScopeDeclRefExprClass:
22433 case Expr::DependentTemplateIdExprClass:
22434 case Expr::CXXConstructExprClass:
22435 case Expr::CXXInheritedCtorInitExprClass:
22436 case Expr::CXXStdInitializerListExprClass:
22437 case Expr::CXXBindTemporaryExprClass:
22438 case Expr::ExprWithCleanupsClass:
22439 case Expr::CXXTemporaryObjectExprClass:
22440 case Expr::CXXUnresolvedConstructExprClass:
22441 case Expr::CXXDependentScopeMemberExprClass:
22442 case Expr::UnresolvedMemberExprClass:
22443 case Expr::ObjCStringLiteralClass:
22444 case Expr::ObjCBoxedExprClass:
22445 case Expr::ObjCArrayLiteralClass:
22446 case Expr::ObjCDictionaryLiteralClass:
22447 case Expr::ObjCEncodeExprClass:
22448 case Expr::ObjCMessageExprClass:
22449 case Expr::ObjCSelectorExprClass:
22450 case Expr::ObjCProtocolExprClass:
22451 case Expr::ObjCIvarRefExprClass:
22452 case Expr::ObjCPropertyRefExprClass:
22453 case Expr::ObjCSubscriptRefExprClass:
22454 case Expr::ObjCIsaExprClass:
22455 case Expr::ObjCAvailabilityCheckExprClass:
22456 case Expr::ShuffleVectorExprClass:
22457 case Expr::ConvertVectorExprClass:
22458 case Expr::BlockExprClass:
22460 case Expr::OpaqueValueExprClass:
22461 case Expr::PackExpansionExprClass:
22462 case Expr::SubstNonTypeTemplateParmPackExprClass:
22463 case Expr::FunctionParmPackExprClass:
22464 case Expr::AsTypeExprClass:
22465 case Expr::ObjCIndirectCopyRestoreExprClass:
22466 case Expr::MaterializeTemporaryExprClass:
22467 case Expr::PseudoObjectExprClass:
22468 case Expr::AtomicExprClass:
22469 case Expr::LambdaExprClass:
22470 case Expr::CXXFoldExprClass:
22471 case Expr::CoawaitExprClass:
22472 case Expr::DependentCoawaitExprClass:
22473 case Expr::CoyieldExprClass:
22474 case Expr::SYCLUniqueStableNameExprClass:
22475 case Expr::CXXParenListInitExprClass:
22476 case Expr::HLSLOutArgExprClass:
22477 case Expr::CXXExpansionSelectExprClass:
22480 case Expr::MemberExprClass: {
22483 while (
const auto *M = dyn_cast<MemberExpr>(ME)) {
22486 ME = M->getBase()->IgnoreParenImpCasts();
22488 const auto *DRE = dyn_cast<DeclRefExpr>(ME);
22490 if (
const auto *VD = dyn_cast<VarDecl>(DRE->getDecl());
22498 case Expr::InitListExprClass: {
22509 case Expr::SizeOfPackExprClass:
22510 case Expr::GNUNullExprClass:
22511 case Expr::SourceLocExprClass:
22512 case Expr::EmbedExprClass:
22513 case Expr::OpenACCAsteriskSizeExprClass:
22516 case Expr::PackIndexingExprClass:
22519 case Expr::SubstNonTypeTemplateParmExprClass:
22523 case Expr::ConstantExprClass:
22526 case Expr::ParenExprClass:
22528 case Expr::GenericSelectionExprClass:
22530 case Expr::IntegerLiteralClass:
22531 case Expr::FixedPointLiteralClass:
22532 case Expr::CharacterLiteralClass:
22533 case Expr::ObjCBoolLiteralExprClass:
22534 case Expr::CXXBoolLiteralExprClass:
22535 case Expr::CXXScalarValueInitExprClass:
22536 case Expr::TypeTraitExprClass:
22537 case Expr::ConceptSpecializationExprClass:
22538 case Expr::RequiresExprClass:
22539 case Expr::ArrayTypeTraitExprClass:
22540 case Expr::ExpressionTraitExprClass:
22541 case Expr::CXXNoexceptExprClass:
22542 case Expr::CXXReflectExprClass:
22544 case Expr::CallExprClass:
22545 case Expr::CXXOperatorCallExprClass: {
22554 case Expr::CXXRewrittenBinaryOperatorClass:
22557 case Expr::DeclRefExprClass: {
22571 const VarDecl *VD = dyn_cast<VarDecl>(D);
22578 case Expr::UnaryOperatorClass: {
22601 llvm_unreachable(
"invalid unary operator class");
22603 case Expr::OffsetOfExprClass: {
22612 case Expr::UnaryExprOrTypeTraitExprClass: {
22614 if ((Exp->
getKind() == UETT_SizeOf) &&
22617 if (Exp->
getKind() == UETT_CountOf) {
22624 if (VAT->getElementType()->isArrayType())
22636 case Expr::BinaryOperatorClass: {
22681 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE) {
22684 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
22685 if (REval.isSigned() && REval.isAllOnes()) {
22687 if (LEval.isMinSignedValue())
22688 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
22696 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE)
22697 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
22703 return Worst(LHSResult, RHSResult);
22709 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICEIfUnevaluated) {
22719 return Worst(LHSResult, RHSResult);
22722 llvm_unreachable(
"invalid binary operator kind");
22724 case Expr::ImplicitCastExprClass:
22725 case Expr::CStyleCastExprClass:
22726 case Expr::CXXFunctionalCastExprClass:
22727 case Expr::CXXStaticCastExprClass:
22728 case Expr::CXXReinterpretCastExprClass:
22729 case Expr::CXXConstCastExprClass:
22730 case Expr::ObjCBridgedCastExprClass: {
22737 APSInt IgnoredVal(DestWidth, !DestSigned);
22742 if (FL->getValue().convertToInteger(IgnoredVal,
22743 llvm::APFloat::rmTowardZero,
22744 &Ignored) & APFloat::opInvalidOp)
22750 case CK_LValueToRValue:
22751 case CK_AtomicToNonAtomic:
22752 case CK_NonAtomicToAtomic:
22754 case CK_IntegralToBoolean:
22755 case CK_IntegralCast:
22761 case Expr::BinaryConditionalOperatorClass: {
22764 if (CommonResult.Kind == IK_NotICE)
return CommonResult;
22766 if (FalseResult.Kind == IK_NotICE)
return FalseResult;
22767 if (CommonResult.Kind == IK_ICEIfUnevaluated)
return CommonResult;
22768 if (FalseResult.Kind == IK_ICEIfUnevaluated &&
22770 return FalseResult;
22772 case Expr::ConditionalOperatorClass: {
22780 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
22783 if (CondResult.Kind == IK_NotICE)
22789 if (TrueResult.Kind == IK_NotICE)
22791 if (FalseResult.Kind == IK_NotICE)
22792 return FalseResult;
22793 if (CondResult.Kind == IK_ICEIfUnevaluated)
22795 if (TrueResult.Kind == IK_ICE && FalseResult.Kind == IK_ICE)
22801 return FalseResult;
22804 case Expr::CXXDefaultArgExprClass:
22806 case Expr::CXXDefaultInitExprClass:
22808 case Expr::ChooseExprClass: {
22811 case Expr::BuiltinBitCastExprClass: {
22812 if (!checkBitCastConstexprEligibility(
nullptr, Ctx,
cast<CastExpr>(E)))
22818 llvm_unreachable(
"Invalid StmtClass!");
22824 llvm::APSInt *
Value,
22825 bool AllowRelaxedEval =
false) {
22842 "Expression evaluator can't be called on a dependent expression.");
22844 ExprTimeTraceScope TimeScope(
this, Ctx,
"isIntegerConstantExpr");
22850 if (D.Kind != IK_ICE)
22855std::optional<llvm::APSInt>
22857 bool AllowRelaxedEval)
const {
22860 return std::nullopt;
22868 return std::nullopt;
22872 return std::nullopt;
22881 Info.InConstantContext =
true;
22884 llvm_unreachable(
"ICE cannot be evaluated!");
22891 "Expression evaluator can't be called on a dependent expression.");
22893 return CheckICE(
this, Ctx).Kind == IK_ICE;
22897 bool AllowRelaxedEval)
const {
22899 "Expression evaluator can't be called on a dependent expression.");
22909 *
Result = std::move(Scratch);
22917 Status.ExtendedDiag = AllowRelaxedEval ? &MSRelaxedDiag :
nullptr;
22923 Info.discardCleanups() && !Status.HasSideEffects;
22925 return IsConstExpr && !Status.DiagEmitted;
22933 "Expression evaluator can't be called on a dependent expression.");
22935 llvm::TimeTraceScope TimeScope(
"EvaluateWithSubstitution", [&] {
22937 llvm::raw_string_ostream OS(Name);
22945 Info.InConstantContext =
true;
22947 if (Info.EnableNewConstInterp) {
22948 if (std::optional<bool> BoolResult =
22949 Info.Ctx.getInterpContext().evaluateWithSubstitution(
22950 Info, Callee, Args,
This,
this)) {
22958 const LValue *ThisPtr =
nullptr;
22961 auto *MD = dyn_cast<CXXMethodDecl>(Callee);
22962 assert(MD &&
"Don't provide `this` for non-methods.");
22963 assert(MD->isImplicitObjectMemberFunction() &&
22964 "Don't provide `this` for methods without an implicit object.");
22966 if (!
This->isValueDependent() &&
22968 !Info.EvalStatus.HasSideEffects)
22969 ThisPtr = &ThisVal;
22973 Info.EvalStatus.HasSideEffects =
false;
22976 CallRef
Call = Info.CurrentCall->createCall(Callee);
22979 unsigned Idx = I - Args.begin();
22980 if (Idx >= Callee->getNumParams())
22982 const ParmVarDecl *PVD = Callee->getParamDecl(Idx);
22983 if ((*I)->isValueDependent() ||
22985 Info.EvalStatus.HasSideEffects) {
22987 if (
APValue *Slot = Info.getParamSlot(
Call, PVD))
22993 Info.EvalStatus.HasSideEffects =
false;
22998 Info.discardCleanups();
22999 Info.EvalStatus.HasSideEffects =
false;
23002 CallStackFrame Frame(Info, Callee->getLocation(), Callee, ThisPtr,
This,
23005 FullExpressionRAII
Scope(Info);
23007 !Info.EvalStatus.HasSideEffects;
23019 llvm::TimeTraceScope TimeScope(
"isPotentialConstantExpr", [&] {
23021 llvm::raw_string_ostream OS(Name);
23028 Status.
Diag = &Diags;
23032 Info.InConstantContext =
true;
23033 Info.CheckingPotentialConstantExpression =
true;
23036 if (Info.EnableNewConstInterp) {
23037 Info.Ctx.getInterpContext().isPotentialConstantExpr(Info, FD);
23038 return Diags.empty();
23049 This.set({&VIE, Info.CurrentCall->Index});
23057 Info.setEvaluatingDecl(
This.getLValueBase(), Scratch);
23063 &VIE, Args, CallRef(), FD->
getBody(), Info, Scratch,
23067 return Diags.empty();
23075 "Expression evaluator can't be called on a dependent expression.");
23078 Status.
Diag = &Diags;
23082 Info.InConstantContext =
true;
23083 Info.CheckingPotentialConstantExpression =
true;
23085 if (Info.EnableNewConstInterp) {
23086 Info.Ctx.getInterpContext().isPotentialConstantExprUnevaluated(Info, E, FD);
23087 return Diags.empty();
23092 nullptr, CallRef());
23096 return Diags.empty();
23100 unsigned Type)
const {
23101 if (!
getType()->isPointerType())
23102 return std::nullopt;
23106 if (Info.EnableNewConstInterp)
23107 return Info.Ctx.getInterpContext().tryEvaluateObjectSize(
23114static std::optional<uint64_t>
23116 std::string *StringResult) {
23118 return std::nullopt;
23123 return std::nullopt;
23126 if (
const StringLiteral *S = dyn_cast_or_null<StringLiteral>(
23127 String.getLValueBase().dyn_cast<
const Expr *>())) {
23129 int64_t
Off = String.Offset.getQuantity();
23130 if (
Off >= 0 && (uint64_t)
Off <= (uint64_t)Str.size()) {
23132 if (StringResult) {
23134 Str = Str.substr(
Off, *ZeroIndex);
23135 *StringResult = Str;
23138 return ZeroIndex.
value_or(Str.size());
23145 for (uint64_t Strlen = 0; ; ++Strlen) {
23149 return std::nullopt;
23152 else if (StringResult)
23153 StringResult->push_back(Char.
getInt().getExtValue());
23155 return std::nullopt;
23162 std::string StringResult;
23164 if (Info.EnableNewConstInterp) {
23165 if (!Info.Ctx.getInterpContext().evaluateString(Info,
this, StringResult))
23166 return std::nullopt;
23167 return StringResult;
23171 return StringResult;
23172 return std::nullopt;
23175template <
typename T>
23177 const Expr *SizeExpression,
23178 const Expr *PtrExpression,
23182 Info.InConstantContext =
true;
23184 if (Info.EnableNewConstInterp)
23185 return Info.Ctx.getInterpContext().evaluateCharRange(Info, SizeExpression,
23189 FullExpressionRAII
Scope(Info);
23194 uint64_t Size = SizeValue.getZExtValue();
23197 if constexpr (std::is_same_v<APValue, T>)
23200 if (Size <
Result.max_size())
23207 for (uint64_t I = 0; I < Size; ++I) {
23213 if constexpr (std::is_same_v<APValue, T>) {
23214 Result.getArrayInitializedElt(I) = std::move(Char);
23218 assert(
C.getBitWidth() <= 8 &&
23219 "string element not representable in char");
23221 Result.push_back(
static_cast<char>(
C.getExtValue()));
23232 const Expr *SizeExpression,
23236 PtrExpression, Ctx, Status);
23240 const Expr *SizeExpression,
23244 PtrExpression, Ctx, Status);
23251 if (Info.EnableNewConstInterp)
23252 return Info.Ctx.getInterpContext().evaluateStrlen(Info,
this);
23257struct IsWithinLifetimeHandler {
23260 using result_type = std::optional<bool>;
23261 std::optional<bool> failed() {
return std::nullopt; }
23262 template <
typename T>
23263 std::optional<bool> found(
T &Subobj,
QualType SubobjType,
23267 template <
typename T>
23268 std::optional<bool> found(
T &Subobj, QualType SubobjType) {
23273std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &IEE,
23274 const CallExpr *E) {
23275 EvalInfo &Info = IEE.Info;
23280 if (!Info.InConstantContext)
23281 return std::nullopt;
23283 const Expr *Arg = E->
getArg(0);
23285 return std::nullopt;
23288 return std::nullopt;
23290 if (Val.allowConstexprUnknown())
23294 bool CalledFromStd =
false;
23295 const auto *
Callee = Info.CurrentCall->getCallee();
23296 if (Callee &&
Callee->isInStdNamespace()) {
23297 const IdentifierInfo *Identifier =
Callee->getIdentifier();
23298 CalledFromStd = Identifier && Identifier->
isStr(
"is_within_lifetime");
23300 Info.CCEDiag(CalledFromStd ? Info.CurrentCall->getCallRange().getBegin()
23302 diag::err_invalid_is_within_lifetime)
23303 << (CalledFromStd ?
"std::is_within_lifetime"
23304 :
"__builtin_is_within_lifetime")
23306 return std::nullopt;
23316 if (Val.isNullPointer() || Val.getLValueBase().isNull())
23318 QualType
T = Val.getLValueBase().getType();
23320 "Pointers to functions should have been typed as function pointers "
23321 "which would have been rejected earlier");
23324 if (Val.getLValueDesignator().isOnePastTheEnd())
23326 assert(Val.getLValueDesignator().isValidSubobject() &&
23327 "Unchecked case for valid subobject");
23331 CompleteObject CO =
23335 if (Info.EvaluatingDeclValue && CO.Value == Info.EvaluatingDeclValue)
23340 IsWithinLifetimeHandler handler{Info};
23341 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)
const Expr * ignorePointerCastsAndParens(const Expr *E)
A more selective version of E->IgnoreParenCasts for tryEvaluateBuiltinObjectSize. This ignores some c...
static bool hasUnacceptableSideEffect(Expr::EvalStatus &Result, Expr::SideEffectsKind SEK)
static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E, AccessKinds AK, const LValue &LVal, QualType LValType)
Find the complete object to which an LValue refers.
static bool evaluateLValueAsAllocSize(EvalInfo &Info, APValue::LValueBase Base, LValue &Result)
Attempts to evaluate the given LValueBase as the result of a call to a function with the alloc_size a...
static bool CheckEvaluationResult(CheckEvaluationResultKind CERK, EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value, ConstantExprKind Kind, const FieldDecl *SubobjectDecl, CheckedTemporaries &CheckedTemps, bool IsCompleteClass=true)
static const CXXMethodDecl * HandleVirtualDispatch(EvalInfo &Info, const Expr *E, LValue &This, const CXXMethodDecl *Found, llvm::SmallVectorImpl< QualType > &CovariantAdjustmentPath)
Perform virtual dispatch.
static bool EvaluateVarDecl(EvalInfo &Info, const VarDecl *VD)
static bool HandleLValueComplexElement(EvalInfo &Info, const Expr *E, LValue &LVal, QualType EltTy, bool Imag)
Update an lvalue to refer to a component of a complex number.
static bool evalPackBuiltin(const CallExpr *E, EvalInfo &Info, APValue &Result, llvm::function_ref< APInt(const APSInt &)> PackFn)
static bool 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 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 EvaluateComparisonResult(EvalInfo &Info, const Expr *E, ComparisonCategoryResult CCR, APValue &Result)
static bool EvaluateMatrix(const Expr *E, APValue &Result, EvalInfo &Info)
static const FunctionDecl * getVirtualOperatorDelete(QualType T)
static bool isDesignatorAtObjectEnd(const ASTContext &Ctx, const LValue &LVal)
Checks to see if the given LValue's Designator is at the end of the LValue's record layout....
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 GetLValueBaseAsString(const EvalInfo &Info, const LValue &LVal, LValueBaseString &AsString)
static bool HandleOperatorDeleteCall(EvalInfo &Info, const CallExpr *E)
static bool EvaluateIntegerOrLValue(const Expr *E, APValue &Result, EvalInfo &Info)
EvaluateIntegerOrLValue - Evaluate an rvalue integral-typed expression, and produce either the intege...
static bool HandleDynamicCast(EvalInfo &Info, const ExplicitCastExpr *E, LValue &Ptr)
Apply the given dynamic cast operation on the provided lvalue.
static bool HandleOperatorNewCall(EvalInfo &Info, const CallExpr *E, LValue &Result)
Perform a call to 'operator new' or to ‘__builtin_operator_new’.
static bool HandleFloatToFloatCast(EvalInfo &Info, const Expr *E, QualType SrcType, QualType DestType, APFloat &Result)
static bool MaybeHandleUnionActiveMemberChange(EvalInfo &Info, const Expr *LHSExpr, const LValue &LHS)
Handle a builtin simple-assignment or a call to a trivial assignment operator whose left-hand side mi...
uint8_t GFNIMul(uint8_t AByte, uint8_t BByte)
static bool isFormalAccess(AccessKinds AK)
Is this an access per the C++ definition?
static bool handleCompoundAssignment(EvalInfo &Info, const CompoundAssignOperator *E, const LValue &LVal, QualType LValType, QualType PromotedLValType, BinaryOperatorKind Opcode, const APValue &RVal)
Perform a compound assignment of LVal <op>= RVal.
static bool handleIncDec(EvalInfo &Info, const Expr *E, const LValue &LVal, QualType LValType, bool IsIncrement, APValue *Old)
Perform an increment or decrement on LVal.
static bool EvaluateVoid(const Expr *E, EvalInfo &Info)
static bool HandleDestruction(EvalInfo &Info, const Expr *E, const LValue &This, QualType ThisType)
Perform a destructor or pseudo-destructor call on the given object, which might in general not be a c...
static bool ArePotentiallyOverlappingStringLiterals(const EvalInfo &Info, const LValue &LHS, const LValue &RHS)
uint8_t GFNIMultiplicativeInverse(uint8_t Byte)
uint8_t GFNIAffine(uint8_t XByte, const APInt &AQword, const APSInt &Imm, bool Inverse)
APSInt NormalizeRotateAmount(const APSInt &Value, const APSInt &Amount)
Result
Implement __builtin_bit_cast and related operations.
static bool isUserWritingOffTheEnd(const ASTContext &Ctx, const Pointer &Ptr, bool InvalidBase)
Does Ptr point to the last object AND to a flexible array member?
static bool isModification(AccessKinds AK)
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
llvm::MachO::Record Record
Implements a partial diagnostic which may not be emitted.
llvm::DenseMap< Stmt *, Stmt * > MapTy
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
static QualType getPointeeType(const MemRegion *R)
Enumerates target-specific builtins in their own namespaces within namespace clang.
Defines the clang::TypeLoc interface and its subclasses.
C Language Family Type Representation.
__DEVICE__ long long abs(long long __n)
static bool hasLayout(const RecordDecl *D)
Whether layout (offset and size) information can be queried for D.
a trap message and trap category.
llvm::APInt getValue() const
unsigned getVersion() const
QualType getDynamicAllocType() const
QualType getTypeInfoType() const
static LValueBase getTypeInfo(TypeInfoLValue LV, QualType TypeInfo)
static LValueBase getDynamicAlloc(DynamicAllocLValue LV, QualType Type)
A non-discriminated union of a base, field, or array index.
BaseOrMemberType getAsBaseOrMember() const
static LValuePathEntry ArrayIndex(uint64_t Index)
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
bool hasArrayFiller() const
const LValueBase getLValueBase() const
APValue & getArrayInitializedElt(unsigned I)
void swap(APValue &RHS)
Swaps the contents of this and the given APValue.
APValue & getStructField(unsigned i)
unsigned getMatrixNumColumns() const
const FieldDecl * getUnionField() const
APSInt & getComplexIntImag()
bool isComplexInt() const
llvm::PointerIntPair< const Decl *, 1, bool > BaseOrMemberType
A FieldDecl or CXXRecordDecl, along with a flag indicating whether we mean a virtual or non-virtual b...
ValueKind getKind() const
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, llvm::FoldingSetInsertToken &InsertToken)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
Expr * getResultExpr()
Return the result expression of this controlling expression.
One of these records is kept for each identifier that is lexed.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
IfStmt - This represents an if/then/else.
bool isNonNegatedConsteval() const
VarDecl * getConditionVariable()
Retrieve the variable declared in this "if" statement, if any.
const Expr * getSubExpr() const
Represents an implicitly-generated value initialization of an object of a given type.
Represents a field injected from an anonymous union/struct into the parent scope.
ArrayRef< NamedDecl * > chain() const
Describes an C or C++ initializer list.
bool isTransparent() const
Is this a transparent initializer list (that is, an InitListExpr that is purely syntactic,...
bool isStringLiteralInit() const
Is this an initializer for an array of characters, initialized by a string literal or an @encode?
unsigned getNumInits() const
Expr * getArrayFiller()
If this initializer list initializes an array with more elements than there are initializers in the l...
const Expr * getInit(unsigned Init) const
ArrayRef< Expr * > inits() const
capture_init_iterator capture_init_end()
Retrieve the iterator pointing one past the last initialization argument for this lambda expression.
capture_init_iterator capture_init_begin()
Retrieve the first initialization argument for this lambda expression (which initializes the first ca...
CXXRecordDecl * getLambdaClass() const
Retrieve the class that corresponds to the lambda.
StrictFlexArraysLevelKind
@ FPE_Ignore
Assume that floating-point exceptions are masked.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
bool isCompatibleWith(ClangABI Version) const
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
StorageDuration getStorageDuration() const
Retrieve the storage duration for the materialized temporary.
Expr * getSubExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue.
APValue * getOrCreateValue(bool MayCreate) const
Get the storage for the constant value of a materialized temporary of static storage duration.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
void printQualifiedName(raw_ostream &OS) const
Returns a human-readable qualified name for this declaration, like A::B::i, for i being member of nam...
bool isExpressibleAsConstantInitializer() const
Expr * getIndexExpr(unsigned Idx)
const OffsetOfNode & getComponent(unsigned Idx) const
TypeSourceInfo * getTypeSourceInfo() const
unsigned getNumComponents() const
unsigned getArrayExprIndex() const
For an array element node, returns the index into the array of expressions.
FieldDecl * getField() const
For a field offsetof node, returns the field.
@ Array
An index into an array.
@ Identifier
A field in a dependent type, known only by its name.
@ Base
An implicit indirection through a C++ base class, when the field found is in a base class.
Kind getKind() const
Determine what kind of offsetof node this is.
CXXBaseSpecifier * getBase() const
For a base class node, returns the base specifier.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
Expr * getSelectedExpr() const
const Expr * getSubExpr() const
Represents a parameter to a function.
unsigned getFunctionScopeIndex() const
Returns the index of this parameter in its prototype or method scope.
bool isExplicitObjectParameter() const
PointerType - C99 6.7.5.1 - Pointer Declarators.
StringLiteral * getFunctionName()
Expr * getResultExpr()
Return the result-bearing expression, or null if there is none.
ArrayRef< Expr * > semantics()
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
QualType withConst() const
void addConst()
Add the const type qualifier to this QualType.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
void removeLocalVolatile()
void addVolatile()
Add the volatile type qualifier to this QualType.
bool isConstQualified() const
Determine whether this type is const-qualified.
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.
UnsignedOrNone findZeroCodeUnit(unsigned StartIndex=0) const
Scan the string literal contents for a code unit with value 0.
unsigned getLength() const
uint32_t getCodeUnit(size_t I) const
Return the code unit at the given position.
StringRef getBytes() const
Allow access to clients that need the byte representation, such as ASTWriterStmt::VisitStringLiteral(...
StringRef getString() const
Expr * getReplacement() const
const SwitchCase * getNextSwitchCase() const
SwitchStmt - This represents a 'switch' stmt.
VarDecl * getConditionVariable()
Retrieve the variable declared in this "switch" statement, if any.
SwitchCase * getSwitchCaseList()
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
TagDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Exposes information about the current target.
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
bool isStoredAsComparisonResult() const
const APValue & getAPValue() const
bool isStoredAsBoolean() const
The base class of the type hierarchy.
bool isBooleanType() const
bool isFunctionReferenceType() const
bool isMFloat8Type() const
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
bool isPackedVectorBoolType(const ASTContext &ctx) const
bool isLiteralType(const ASTContext &Ctx) const
Return true if this is a literal type (C++11 [basic.types]p10)
bool isIncompleteArrayType() const
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
bool isComplexType() const
isComplexType() does not include complex integers (a GCC extension).
const ArrayType * castAsArrayTypeUnsafe() const
A variant of castAs<> for array type which silently discards qualifiers from the outermost type.
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
bool isIntegralOrUnscopedEnumerationType() const
Determine whether this type is an integral or unscoped enumeration type.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isConstantArrayType() const
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isVoidPointerType() const
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6....
bool isFunctionPointerType() const
bool isCountAttributedType() const
bool isConstantMatrixType() const
bool isPointerType() const
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
OptionalUnsigned< unsigned > UnsignedOrNone
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)