58#include "llvm/ADT/APFixedPoint.h"
59#include "llvm/ADT/Sequence.h"
60#include "llvm/ADT/SmallBitVector.h"
61#include "llvm/ADT/StringExtras.h"
62#include "llvm/Support/Casting.h"
63#include "llvm/Support/Debug.h"
64#include "llvm/Support/SaveAndRestore.h"
65#include "llvm/Support/SipHash.h"
66#include "llvm/Support/TimeProfiler.h"
67#include "llvm/Support/raw_ostream.h"
73#define DEBUG_TYPE "exprconstant"
76using llvm::APFixedPoint;
80using llvm::FixedPointSemantics;
87 using SourceLocExprScopeGuard =
122 static const CallExpr *tryUnwrapAllocSizeCall(
const Expr *E) {
130 if (
const auto *FE = dyn_cast<FullExpr>(E))
133 if (
const auto *Cast = dyn_cast<CastExpr>(E))
134 E = Cast->getSubExpr()->IgnoreParens();
136 if (
const auto *CE = dyn_cast<CallExpr>(E))
137 return CE->getCalleeAllocSizeAttr() ? CE :
nullptr;
144 const auto *E =
Base.dyn_cast<
const Expr *>();
145 return E && E->getType()->isPointerType() && tryUnwrapAllocSizeCall(E);
153 case ConstantExprKind::Normal:
154 case ConstantExprKind::ClassTemplateArgument:
155 case ConstantExprKind::ImmediateInvocation:
160 case ConstantExprKind::NonClassTemplateArgument:
163 llvm_unreachable(
"unknown ConstantExprKind");
168 case ConstantExprKind::Normal:
169 case ConstantExprKind::ImmediateInvocation:
172 case ConstantExprKind::ClassTemplateArgument:
173 case ConstantExprKind::NonClassTemplateArgument:
176 llvm_unreachable(
"unknown ConstantExprKind");
182 static const uint64_t AssumedSizeForUnsizedArray =
183 std::numeric_limits<uint64_t>::max() / 2;
193 bool &FirstEntryIsUnsizedArray) {
196 assert(!isBaseAnAllocSizeCall(
Base) &&
197 "Unsized arrays shouldn't appear here");
198 unsigned MostDerivedLength = 0;
203 for (
unsigned I = 0, N = Path.size(); I != N; ++I) {
207 MostDerivedLength = I + 1;
210 if (
auto *CAT = dyn_cast<ConstantArrayType>(AT)) {
211 ArraySize = CAT->getZExtSize();
213 assert(I == 0 &&
"unexpected unsized array designator");
214 FirstEntryIsUnsizedArray =
true;
215 ArraySize = AssumedSizeForUnsizedArray;
221 MostDerivedLength = I + 1;
224 Type = VT->getElementType();
225 ArraySize = VT->getNumElements();
226 MostDerivedLength = I + 1;
228 }
else if (
const FieldDecl *FD = getAsField(Path[I])) {
229 Type = FD->getType();
231 MostDerivedLength = I + 1;
239 return MostDerivedLength;
243 struct SubobjectDesignator {
247 LLVM_PREFERRED_TYPE(
bool)
251 LLVM_PREFERRED_TYPE(
bool)
252 unsigned IsOnePastTheEnd : 1;
255 LLVM_PREFERRED_TYPE(
bool)
256 unsigned FirstEntryIsAnUnsizedArray : 1;
259 LLVM_PREFERRED_TYPE(
bool)
260 unsigned MostDerivedIsArrayElement : 1;
264 unsigned MostDerivedPathLength : 28;
273 uint64_t MostDerivedArraySize;
282 SubobjectDesignator() :
Invalid(
true) {}
285 :
Invalid(
false), IsOnePastTheEnd(
false),
286 FirstEntryIsAnUnsizedArray(
false), MostDerivedIsArrayElement(
false),
287 MostDerivedPathLength(0), MostDerivedArraySize(0),
288 MostDerivedType(
T.isNull() ?
QualType() :
T.getNonReferenceType()) {}
291 :
Invalid(!
V.isLValue() || !
V.hasLValuePath()), IsOnePastTheEnd(
false),
292 FirstEntryIsAnUnsizedArray(
false), MostDerivedIsArrayElement(
false),
293 MostDerivedPathLength(0), MostDerivedArraySize(0) {
294 assert(
V.isLValue() &&
"Non-LValue used to make an LValue designator?");
296 IsOnePastTheEnd =
V.isLValueOnePastTheEnd();
297 llvm::append_range(Entries,
V.getLValuePath());
298 if (
V.getLValueBase()) {
299 bool IsArray =
false;
300 bool FirstIsUnsizedArray =
false;
301 MostDerivedPathLength = findMostDerivedSubobject(
302 Ctx,
V.getLValueBase(),
V.getLValuePath(), MostDerivedArraySize,
303 MostDerivedType, IsArray, FirstIsUnsizedArray);
304 MostDerivedIsArrayElement = IsArray;
305 FirstEntryIsAnUnsizedArray = FirstIsUnsizedArray;
311 unsigned NewLength) {
315 assert(
Base &&
"cannot truncate path for null pointer");
316 assert(NewLength <= Entries.size() &&
"not a truncation");
318 if (NewLength == Entries.size())
320 Entries.resize(NewLength);
322 bool IsArray =
false;
323 bool FirstIsUnsizedArray =
false;
324 MostDerivedPathLength = findMostDerivedSubobject(
325 Ctx,
Base, Entries, MostDerivedArraySize, MostDerivedType, IsArray,
326 FirstIsUnsizedArray);
327 MostDerivedIsArrayElement = IsArray;
328 FirstEntryIsAnUnsizedArray = FirstIsUnsizedArray;
338 bool isMostDerivedAnUnsizedArray()
const {
339 assert(!
Invalid &&
"Calling this makes no sense on invalid designators");
340 return Entries.size() == 1 && FirstEntryIsAnUnsizedArray;
345 uint64_t getMostDerivedArraySize()
const {
346 assert(!isMostDerivedAnUnsizedArray() &&
"Unsized array has no size");
347 return MostDerivedArraySize;
351 bool isOnePastTheEnd()
const {
355 if (!isMostDerivedAnUnsizedArray() && MostDerivedIsArrayElement &&
356 Entries[MostDerivedPathLength - 1].getAsArrayIndex() ==
357 MostDerivedArraySize)
365 std::pair<uint64_t, uint64_t> validIndexAdjustments() {
366 if (
Invalid || isMostDerivedAnUnsizedArray())
372 bool IsArray = MostDerivedPathLength == Entries.size() &&
373 MostDerivedIsArrayElement;
374 uint64_t ArrayIndex = IsArray ? Entries.back().getAsArrayIndex()
375 : (uint64_t)IsOnePastTheEnd;
377 IsArray ? getMostDerivedArraySize() : (uint64_t)1;
378 return {ArrayIndex, ArraySize - ArrayIndex};
382 bool isValidSubobject()
const {
385 return !isOnePastTheEnd();
393 assert(!
Invalid &&
"invalid designator has no subobject type");
394 return MostDerivedPathLength == Entries.size()
405 MostDerivedIsArrayElement =
true;
407 MostDerivedPathLength = Entries.size();
411 void addUnsizedArrayUnchecked(
QualType ElemTy) {
414 MostDerivedType = ElemTy;
415 MostDerivedIsArrayElement =
true;
419 MostDerivedArraySize = AssumedSizeForUnsizedArray;
420 MostDerivedPathLength = Entries.size();
424 void addDeclUnchecked(
const Decl *D,
bool Virtual =
false) {
428 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
429 MostDerivedType = FD->getType();
430 MostDerivedIsArrayElement =
false;
431 MostDerivedArraySize = 0;
432 MostDerivedPathLength = Entries.size();
436 void addComplexUnchecked(
QualType EltTy,
bool Imag) {
441 MostDerivedType = EltTy;
442 MostDerivedIsArrayElement =
true;
443 MostDerivedArraySize = 2;
444 MostDerivedPathLength = Entries.size();
447 void addVectorElementUnchecked(
QualType EltTy, uint64_t Size,
450 MostDerivedType = EltTy;
451 MostDerivedPathLength = Entries.size();
452 MostDerivedArraySize = 0;
453 MostDerivedIsArrayElement =
false;
456 void diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info,
const Expr *E);
457 void diagnosePointerArithmetic(EvalInfo &Info,
const Expr *E,
460 void adjustIndex(EvalInfo &Info,
const Expr *E,
APSInt N,
const LValue &LV);
464 enum class ScopeKind {
472 CallRef() : OrigCallee(), CallIndex(0), Version() {}
473 CallRef(
const FunctionDecl *Callee,
unsigned CallIndex,
unsigned Version)
474 : OrigCallee(Callee), CallIndex(CallIndex), Version(Version) {}
476 explicit operator bool()
const {
return OrigCallee; }
502 CallStackFrame *Caller;
524 typedef std::pair<const void *, unsigned> MapKeyTy;
525 typedef std::map<MapKeyTy, APValue>
MapTy;
537 unsigned CurTempVersion = TempVersionStack.back();
539 unsigned getTempVersion()
const {
return TempVersionStack.back(); }
541 void pushTempVersion() {
542 TempVersionStack.push_back(++CurTempVersion);
545 void popTempVersion() {
546 TempVersionStack.pop_back();
550 return {Callee, Index, ++CurTempVersion};
561 llvm::DenseMap<const ValueDecl *, FieldDecl *> LambdaCaptureFields;
562 FieldDecl *LambdaThisCaptureField =
nullptr;
564 CallStackFrame(EvalInfo &Info,
SourceRange CallRange,
570 APValue *getTemporary(
const void *Key,
unsigned Version) {
571 MapKeyTy KV(Key, Version);
572 auto LB = Temporaries.lower_bound(KV);
573 if (LB != Temporaries.end() && LB->first == KV)
579 APValue *getCurrentTemporary(
const void *Key) {
580 auto UB = Temporaries.upper_bound(MapKeyTy(Key,
UINT_MAX));
581 if (UB != Temporaries.begin() && std::prev(UB)->first.first == Key)
582 return &std::prev(UB)->second;
587 unsigned getCurrentTemporaryVersion(
const void *Key)
const {
588 auto UB = Temporaries.upper_bound(MapKeyTy(Key,
UINT_MAX));
589 if (UB != Temporaries.begin() && std::prev(UB)->first.first == Key)
590 return std::prev(UB)->first.second;
598 template<
typename KeyT>
600 ScopeKind
Scope, LValue &LV);
605 void describe(llvm::raw_ostream &OS)
const override;
607 Frame *getCaller()
const override {
return Caller; }
608 SourceRange getCallRange()
const override {
return CallRange; }
611 bool isStdFunction()
const {
612 for (
const DeclContext *DC = Callee; DC; DC = DC->getParent())
613 if (DC->isStdNamespace())
620 bool CanEvalMSConstexpr =
false;
628 class ThisOverrideRAII {
630 ThisOverrideRAII(CallStackFrame &Frame,
const LValue *NewThis,
bool Enable)
631 : Frame(Frame), OldThis(Frame.This) {
633 Frame.This = NewThis;
635 ~ThisOverrideRAII() {
636 Frame.This = OldThis;
639 CallStackFrame &Frame;
640 const LValue *OldThis;
645 class ExprTimeTraceScope {
647 ExprTimeTraceScope(
const Expr *E,
const ASTContext &Ctx, StringRef Name)
648 : TimeScope(Name, [E, &Ctx] {
653 llvm::TimeTraceScope TimeScope;
658 struct MSConstexprContextRAII {
659 CallStackFrame &Frame;
661 explicit MSConstexprContextRAII(CallStackFrame &Frame,
bool Value)
662 : Frame(Frame), OldValue(Frame.CanEvalMSConstexpr) {
663 Frame.CanEvalMSConstexpr =
Value;
666 ~MSConstexprContextRAII() { Frame.CanEvalMSConstexpr = OldValue; }
679 llvm::PointerIntPair<APValue*, 2, ScopeKind> Value;
680 APValue::LValueBase Base;
684 Cleanup(
APValue *Val, APValue::LValueBase Base, QualType T,
686 : Value(Val, Scope), Base(Base), T(T) {}
690 bool isDestroyedAtEndOf(ScopeKind K)
const {
691 return (
int)Value.getInt() >= (
int)K;
693 bool endLifetime(EvalInfo &Info,
bool RunDestructors) {
694 if (RunDestructors) {
696 if (
const ValueDecl *VD = Base.dyn_cast<
const ValueDecl*>())
697 Loc = VD->getLocation();
698 else if (
const Expr *E = Base.dyn_cast<
const Expr*>())
699 Loc = E->getExprLoc();
702 *Value.getPointer() =
APValue();
706 bool hasSideEffect() {
707 return T.isDestructedType();
712 struct ObjectUnderConstruction {
713 APValue::LValueBase Base;
714 ArrayRef<APValue::LValuePathEntry> Path;
715 friend bool operator==(
const ObjectUnderConstruction &LHS,
716 const ObjectUnderConstruction &RHS) {
717 return LHS.Base == RHS.Base && LHS.Path == RHS.Path;
719 friend llvm::hash_code
hash_value(
const ObjectUnderConstruction &Obj) {
720 return llvm::hash_combine(Obj.Base, Obj.Path);
723 enum class ConstructionPhase {
734template<>
struct DenseMapInfo<ObjectUnderConstruction> {
735 using Base = DenseMapInfo<APValue::LValueBase>;
737 return {Base::getEmptyKey(), {}}; }
739 return {Base::getTombstoneKey(), {}};
744 static bool isEqual(
const ObjectUnderConstruction &LHS,
745 const ObjectUnderConstruction &RHS) {
759 const Expr *AllocExpr =
nullptr;
770 if (
auto *NE = dyn_cast<CXXNewExpr>(AllocExpr))
771 return NE->isArray() ? ArrayNew : New;
777 struct DynAllocOrder {
778 bool operator()(DynamicAllocLValue L, DynamicAllocLValue R)
const {
802 Expr::EvalStatus &EvalStatus;
805 CallStackFrame *CurrentCall;
808 unsigned CallStackDepth;
811 unsigned NextCallIndex;
820 bool EnableNewConstInterp;
824 CallStackFrame BottomFrame;
828 llvm::SmallVector<Cleanup, 16> CleanupStack;
832 APValue::LValueBase EvaluatingDecl;
834 enum class EvaluatingDeclKind {
841 EvaluatingDeclKind IsEvaluatingDecl = EvaluatingDeclKind::None;
850 SmallVector<const Stmt *> BreakContinueStack;
853 llvm::DenseMap<ObjectUnderConstruction, ConstructionPhase>
854 ObjectsUnderConstruction;
859 std::map<DynamicAllocLValue, DynAlloc, DynAllocOrder> HeapAllocs;
862 unsigned NumHeapAllocs = 0;
864 struct EvaluatingConstructorRAII {
866 ObjectUnderConstruction Object;
868 EvaluatingConstructorRAII(EvalInfo &EI, ObjectUnderConstruction Object,
870 : EI(EI), Object(Object) {
872 EI.ObjectsUnderConstruction
873 .insert({Object, HasBases ? ConstructionPhase::Bases
874 : ConstructionPhase::AfterBases})
877 void finishedConstructingBases() {
878 EI.ObjectsUnderConstruction[Object] = ConstructionPhase::AfterBases;
880 void finishedConstructingFields() {
881 EI.ObjectsUnderConstruction[Object] = ConstructionPhase::AfterFields;
883 ~EvaluatingConstructorRAII() {
884 if (DidInsert) EI.ObjectsUnderConstruction.erase(Object);
888 struct EvaluatingDestructorRAII {
890 ObjectUnderConstruction Object;
892 EvaluatingDestructorRAII(EvalInfo &EI, ObjectUnderConstruction Object)
893 : EI(EI), Object(Object) {
894 DidInsert = EI.ObjectsUnderConstruction
895 .insert({Object, ConstructionPhase::Destroying})
898 void startedDestroyingBases() {
899 EI.ObjectsUnderConstruction[Object] =
900 ConstructionPhase::DestroyingBases;
902 ~EvaluatingDestructorRAII() {
904 EI.ObjectsUnderConstruction.erase(Object);
909 isEvaluatingCtorDtor(APValue::LValueBase Base,
910 ArrayRef<APValue::LValuePathEntry> Path) {
911 return ObjectsUnderConstruction.lookup({
Base, Path});
916 unsigned SpeculativeEvaluationDepth = 0;
924 bool HasActiveDiagnostic;
928 bool HasFoldFailureDiagnostic;
930 EvalInfo(
const ASTContext &
C, Expr::EvalStatus &S,
EvaluationMode Mode)
931 : Ctx(const_cast<ASTContext &>(
C)), EvalStatus(S), CurrentCall(
nullptr),
932 CallStackDepth(0), NextCallIndex(1),
933 StepsLeft(
C.getLangOpts().ConstexprStepLimit),
934 EnableNewConstInterp(
C.getLangOpts().EnableNewConstInterp),
935 BottomFrame(*this, SourceLocation(),
nullptr,
938 EvaluatingDecl((const ValueDecl *)
nullptr),
939 EvaluatingDeclValue(
nullptr), HasActiveDiagnostic(
false),
940 HasFoldFailureDiagnostic(
false) {
948 ASTContext &getASTContext()
const override {
return Ctx; }
949 const LangOptions &getLangOpts()
const {
return Ctx.getLangOpts(); }
951 void setEvaluatingDecl(APValue::LValueBase Base,
APValue &
Value,
952 EvaluatingDeclKind EDK = EvaluatingDeclKind::Ctor) {
953 EvaluatingDecl =
Base;
954 IsEvaluatingDecl = EDK;
955 EvaluatingDeclValue = &
Value;
958 bool CheckCallLimit(SourceLocation Loc) {
961 if (checkingPotentialConstantExpression() && CallStackDepth > 1)
963 if (NextCallIndex == 0) {
965 FFDiag(Loc, diag::note_constexpr_call_limit_exceeded);
968 if (CallStackDepth <= getLangOpts().ConstexprCallDepth)
970 FFDiag(Loc, diag::note_constexpr_depth_limit_exceeded)
971 << getLangOpts().ConstexprCallDepth;
976 uint64_t ElemCount,
bool Diag) {
982 ElemCount >
uint64_t(std::numeric_limits<unsigned>::max())) {
984 FFDiag(Loc, diag::note_constexpr_new_too_large) << ElemCount;
993 uint64_t Limit = Ctx.getLangOpts().ConstexprStepLimit;
994 if (Limit != 0 && ElemCount > Limit) {
996 FFDiag(Loc, diag::note_constexpr_new_exceeds_limits)
997 << ElemCount << Limit;
1003 std::pair<CallStackFrame *, unsigned>
1004 getCallFrameAndDepth(
unsigned CallIndex) {
1005 assert(CallIndex &&
"no call index in getCallFrameAndDepth");
1008 unsigned Depth = CallStackDepth;
1009 CallStackFrame *Frame = CurrentCall;
1010 while (Frame->Index > CallIndex) {
1011 Frame = Frame->Caller;
1014 if (Frame->Index == CallIndex)
1015 return {Frame, Depth};
1016 return {
nullptr, 0};
1019 bool nextStep(
const Stmt *S) {
1020 if (Ctx.getLangOpts().ConstexprStepLimit == 0)
1024 FFDiag(S->
getBeginLoc(), diag::note_constexpr_step_limit_exceeded);
1031 APValue *createHeapAlloc(
const Expr *E, QualType
T, LValue &LV);
1033 std::optional<DynAlloc *> lookupDynamicAlloc(DynamicAllocLValue DA) {
1034 std::optional<DynAlloc *>
Result;
1035 auto It = HeapAllocs.find(DA);
1036 if (It != HeapAllocs.end())
1042 APValue *getParamSlot(CallRef
Call,
const ParmVarDecl *PVD) {
1043 CallStackFrame *Frame = getCallFrameAndDepth(
Call.CallIndex).first;
1044 return Frame ? Frame->getTemporary(
Call.getOrigParam(PVD),
Call.Version)
1049 struct StdAllocatorCaller {
1050 unsigned FrameIndex;
1053 explicit operator bool()
const {
return FrameIndex != 0; };
1056 StdAllocatorCaller getStdAllocatorCaller(StringRef FnName)
const {
1057 for (
const CallStackFrame *
Call = CurrentCall;
Call != &BottomFrame;
1059 const auto *MD = dyn_cast_or_null<CXXMethodDecl>(
Call->Callee);
1062 const IdentifierInfo *FnII = MD->getIdentifier();
1063 if (!FnII || !FnII->
isStr(FnName))
1067 dyn_cast<ClassTemplateSpecializationDecl>(MD->getParent());
1071 const IdentifierInfo *ClassII = CTSD->getIdentifier();
1072 const TemplateArgumentList &TAL = CTSD->getTemplateArgs();
1073 if (CTSD->isInStdNamespace() && ClassII &&
1074 ClassII->
isStr(
"allocator") && TAL.
size() >= 1 &&
1076 return {
Call->Index, TAL[0].getAsType(),
Call->CallExpr};
1082 void performLifetimeExtension() {
1084 llvm::erase_if(CleanupStack, [](Cleanup &
C) {
1085 return !
C.isDestroyedAtEndOf(ScopeKind::FullExpression);
1092 bool discardCleanups() {
1093 for (Cleanup &
C : CleanupStack) {
1094 if (
C.hasSideEffect() && !noteSideEffect()) {
1095 CleanupStack.clear();
1099 CleanupStack.clear();
1104 interp::Frame *getCurrentFrame()
override {
return CurrentCall; }
1105 const interp::Frame *getBottomFrame()
const override {
return &BottomFrame; }
1107 bool hasActiveDiagnostic()
override {
return HasActiveDiagnostic; }
1108 void setActiveDiagnostic(
bool Flag)
override { HasActiveDiagnostic = Flag; }
1110 void setFoldFailureDiagnostic(
bool Flag)
override {
1111 HasFoldFailureDiagnostic = Flag;
1114 Expr::EvalStatus &getEvalStatus()
const override {
return EvalStatus; }
1122 bool hasPriorDiagnostic()
override {
1123 if (!EvalStatus.Diag->empty()) {
1125 case EvaluationMode::ConstantFold:
1126 case EvaluationMode::IgnoreSideEffects:
1127 if (!HasFoldFailureDiagnostic)
1131 case EvaluationMode::ConstantExpression:
1132 case EvaluationMode::ConstantExpressionUnevaluated:
1133 setActiveDiagnostic(
false);
1140 unsigned getCallStackDepth()
override {
return CallStackDepth; }
1145 bool keepEvaluatingAfterSideEffect()
const override {
1147 case EvaluationMode::IgnoreSideEffects:
1150 case EvaluationMode::ConstantExpression:
1151 case EvaluationMode::ConstantExpressionUnevaluated:
1152 case EvaluationMode::ConstantFold:
1155 return checkingPotentialConstantExpression() ||
1156 checkingForUndefinedBehavior();
1158 llvm_unreachable(
"Missed EvalMode case");
1163 bool noteSideEffect()
override {
1164 EvalStatus.HasSideEffects =
true;
1165 return keepEvaluatingAfterSideEffect();
1169 bool keepEvaluatingAfterUndefinedBehavior() {
1171 case EvaluationMode::IgnoreSideEffects:
1172 case EvaluationMode::ConstantFold:
1175 case EvaluationMode::ConstantExpression:
1176 case EvaluationMode::ConstantExpressionUnevaluated:
1177 return checkingForUndefinedBehavior();
1179 llvm_unreachable(
"Missed EvalMode case");
1185 bool noteUndefinedBehavior()
override {
1186 EvalStatus.HasUndefinedBehavior =
true;
1187 return keepEvaluatingAfterUndefinedBehavior();
1192 bool keepEvaluatingAfterFailure()
const override {
1193 uint64_t Limit = Ctx.getLangOpts().ConstexprStepLimit;
1194 if (Limit != 0 && !StepsLeft)
1198 case EvaluationMode::ConstantExpression:
1199 case EvaluationMode::ConstantExpressionUnevaluated:
1200 case EvaluationMode::ConstantFold:
1201 case EvaluationMode::IgnoreSideEffects:
1202 return checkingPotentialConstantExpression() ||
1203 checkingForUndefinedBehavior();
1205 llvm_unreachable(
"Missed EvalMode case");
1218 [[nodiscard]]
bool noteFailure() {
1226 bool KeepGoing = keepEvaluatingAfterFailure();
1227 EvalStatus.HasSideEffects |= KeepGoing;
1231 class ArrayInitLoopIndex {
1236 ArrayInitLoopIndex(EvalInfo &Info)
1237 : Info(Info), OuterIndex(Info.ArrayInitIndex) {
1238 Info.ArrayInitIndex = 0;
1240 ~ArrayInitLoopIndex() { Info.ArrayInitIndex = OuterIndex; }
1242 operator uint64_t&() {
return Info.ArrayInitIndex; }
1247 struct FoldConstant {
1250 bool HadNoPriorDiags;
1253 explicit FoldConstant(EvalInfo &Info,
bool Enabled)
1256 HadNoPriorDiags(Info.EvalStatus.
Diag &&
1257 Info.EvalStatus.
Diag->empty() &&
1258 !Info.EvalStatus.HasSideEffects),
1259 OldMode(Info.EvalMode) {
1261 Info.EvalMode = EvaluationMode::ConstantFold;
1263 void keepDiagnostics() { Enabled =
false; }
1265 if (Enabled && HadNoPriorDiags && !Info.EvalStatus.Diag->empty() &&
1266 !Info.EvalStatus.HasSideEffects)
1267 Info.EvalStatus.Diag->clear();
1268 Info.EvalMode = OldMode;
1274 struct IgnoreSideEffectsRAII {
1277 explicit IgnoreSideEffectsRAII(EvalInfo &Info)
1278 : Info(Info), OldMode(Info.EvalMode) {
1279 Info.EvalMode = EvaluationMode::IgnoreSideEffects;
1282 ~IgnoreSideEffectsRAII() { Info.EvalMode = OldMode; }
1287 class SpeculativeEvaluationRAII {
1288 EvalInfo *Info =
nullptr;
1289 Expr::EvalStatus OldStatus;
1290 unsigned OldSpeculativeEvaluationDepth = 0;
1292 void moveFromAndCancel(SpeculativeEvaluationRAII &&
Other) {
1294 OldStatus =
Other.OldStatus;
1295 OldSpeculativeEvaluationDepth =
Other.OldSpeculativeEvaluationDepth;
1296 Other.Info =
nullptr;
1299 void maybeRestoreState() {
1303 Info->EvalStatus = OldStatus;
1304 Info->SpeculativeEvaluationDepth = OldSpeculativeEvaluationDepth;
1308 SpeculativeEvaluationRAII() =
default;
1310 SpeculativeEvaluationRAII(
1311 EvalInfo &Info, SmallVectorImpl<PartialDiagnosticAt> *NewDiag =
nullptr)
1312 : Info(&Info), OldStatus(Info.EvalStatus),
1313 OldSpeculativeEvaluationDepth(Info.SpeculativeEvaluationDepth) {
1314 Info.EvalStatus.Diag = NewDiag;
1315 Info.SpeculativeEvaluationDepth = Info.CallStackDepth + 1;
1318 SpeculativeEvaluationRAII(
const SpeculativeEvaluationRAII &
Other) =
delete;
1319 SpeculativeEvaluationRAII(SpeculativeEvaluationRAII &&
Other) {
1320 moveFromAndCancel(std::move(
Other));
1323 SpeculativeEvaluationRAII &operator=(SpeculativeEvaluationRAII &&
Other) {
1324 maybeRestoreState();
1325 moveFromAndCancel(std::move(
Other));
1329 ~SpeculativeEvaluationRAII() { maybeRestoreState(); }
1334 template<ScopeKind Kind>
1337 unsigned OldStackSize;
1339 ScopeRAII(EvalInfo &Info)
1340 : Info(Info), OldStackSize(Info.CleanupStack.size()) {
1343 Info.CurrentCall->pushTempVersion();
1345 bool destroy(
bool RunDestructors =
true) {
1346 bool OK =
cleanup(Info, RunDestructors, OldStackSize);
1347 OldStackSize = std::numeric_limits<unsigned>::max();
1351 if (OldStackSize != std::numeric_limits<unsigned>::max())
1355 Info.CurrentCall->popTempVersion();
1358 static bool cleanup(EvalInfo &Info,
bool RunDestructors,
1359 unsigned OldStackSize) {
1360 assert(OldStackSize <= Info.CleanupStack.size() &&
1361 "running cleanups out of order?");
1366 for (
unsigned I = Info.CleanupStack.size(); I > OldStackSize; --I) {
1367 if (Info.CleanupStack[I - 1].isDestroyedAtEndOf(Kind)) {
1368 if (!Info.CleanupStack[I - 1].endLifetime(Info, RunDestructors)) {
1376 auto NewEnd = Info.CleanupStack.begin() + OldStackSize;
1377 if (Kind != ScopeKind::Block)
1379 std::remove_if(NewEnd, Info.CleanupStack.end(), [](Cleanup &
C) {
1380 return C.isDestroyedAtEndOf(Kind);
1382 Info.CleanupStack.erase(NewEnd, Info.CleanupStack.end());
1386 typedef ScopeRAII<ScopeKind::Block> BlockScopeRAII;
1387 typedef ScopeRAII<ScopeKind::FullExpression> FullExpressionRAII;
1388 typedef ScopeRAII<ScopeKind::Call> CallScopeRAII;
1391bool SubobjectDesignator::checkSubobject(EvalInfo &Info,
const Expr *E,
1395 if (isOnePastTheEnd()) {
1396 Info.CCEDiag(E, diag::note_constexpr_past_end_subobject)
1407void SubobjectDesignator::diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info,
1409 Info.CCEDiag(E, diag::note_constexpr_unsized_array_indexed);
1414void SubobjectDesignator::diagnosePointerArithmetic(EvalInfo &Info,
1419 if (MostDerivedPathLength == Entries.size() && MostDerivedIsArrayElement)
1420 Info.CCEDiag(E, diag::note_constexpr_array_index)
1422 <<
static_cast<unsigned>(getMostDerivedArraySize());
1424 Info.CCEDiag(E, diag::note_constexpr_array_index)
1429CallStackFrame::CallStackFrame(EvalInfo &Info, SourceRange CallRange,
1430 const FunctionDecl *Callee,
const LValue *This,
1431 const Expr *CallExpr, CallRef Call)
1433 CallExpr(CallExpr),
Arguments(Call), CallRange(CallRange),
1434 Index(Info.NextCallIndex++) {
1435 Info.CurrentCall =
this;
1436 ++Info.CallStackDepth;
1439CallStackFrame::~CallStackFrame() {
1440 assert(Info.CurrentCall ==
this &&
"calls retired out of order");
1441 --Info.CallStackDepth;
1442 Info.CurrentCall = Caller;
1467 llvm_unreachable(
"unknown access kind");
1504 llvm_unreachable(
"unknown access kind");
1508 struct ComplexValue {
1516 ComplexValue() : FloatReal(
APFloat::Bogus()), FloatImag(
APFloat::Bogus()) {}
1518 void makeComplexFloat() { IsInt =
false; }
1519 bool isComplexFloat()
const {
return !IsInt; }
1520 APFloat &getComplexFloatReal() {
return FloatReal; }
1521 APFloat &getComplexFloatImag() {
return FloatImag; }
1523 void makeComplexInt() { IsInt =
true; }
1524 bool isComplexInt()
const {
return IsInt; }
1525 APSInt &getComplexIntReal() {
return IntReal; }
1526 APSInt &getComplexIntImag() {
return IntImag; }
1528 void moveInto(
APValue &v)
const {
1529 if (isComplexFloat())
1530 v =
APValue(FloatReal, FloatImag);
1532 v =
APValue(IntReal, IntImag);
1534 void setFrom(
const APValue &v) {
1549 APValue::LValueBase
Base;
1551 SubobjectDesignator Designator;
1553 bool InvalidBase : 1;
1555 bool AllowConstexprUnknown =
false;
1557 const APValue::LValueBase getLValueBase()
const {
return Base; }
1558 bool allowConstexprUnknown()
const {
return AllowConstexprUnknown; }
1559 CharUnits &getLValueOffset() {
return Offset; }
1560 const CharUnits &getLValueOffset()
const {
return Offset; }
1561 SubobjectDesignator &getLValueDesignator() {
return Designator; }
1562 const SubobjectDesignator &getLValueDesignator()
const {
return Designator;}
1563 bool isNullPointer()
const {
return IsNullPtr;}
1565 unsigned getLValueCallIndex()
const {
return Base.getCallIndex(); }
1566 unsigned getLValueVersion()
const {
return Base.getVersion(); }
1569 if (Designator.Invalid)
1570 V =
APValue(Base, Offset, APValue::NoLValuePath(), IsNullPtr);
1572 assert(!InvalidBase &&
"APValues can't handle invalid LValue bases");
1573 V =
APValue(Base, Offset, Designator.Entries,
1574 Designator.IsOnePastTheEnd, IsNullPtr);
1576 if (AllowConstexprUnknown)
1577 V.setConstexprUnknown();
1579 void setFrom(
const ASTContext &Ctx,
const APValue &
V) {
1580 assert(
V.isLValue() &&
"Setting LValue from a non-LValue?");
1581 Base =
V.getLValueBase();
1582 Offset =
V.getLValueOffset();
1583 InvalidBase =
false;
1584 Designator = SubobjectDesignator(Ctx,
V);
1585 IsNullPtr =
V.isNullPointer();
1586 AllowConstexprUnknown =
V.allowConstexprUnknown();
1589 void set(APValue::LValueBase B,
bool BInvalid =
false) {
1593 const auto *E = B.
get<
const Expr *>();
1595 "Unexpected type of invalid base");
1601 InvalidBase = BInvalid;
1602 Designator = SubobjectDesignator(
getType(B));
1604 AllowConstexprUnknown =
false;
1607 void setNull(ASTContext &Ctx, QualType PointerTy) {
1608 Base = (
const ValueDecl *)
nullptr;
1611 InvalidBase =
false;
1614 AllowConstexprUnknown =
false;
1617 void setInvalid(APValue::LValueBase B,
unsigned I = 0) {
1621 std::string
toString(ASTContext &Ctx, QualType
T)
const {
1623 moveInto(Printable);
1630 template <
typename GenDiagType>
1631 bool checkNullPointerDiagnosingWith(
const GenDiagType &GenDiag) {
1632 if (Designator.Invalid)
1636 Designator.setInvalid();
1643 bool checkNullPointer(EvalInfo &Info,
const Expr *E,
1645 return checkNullPointerDiagnosingWith([&Info, E, CSK] {
1646 Info.CCEDiag(E, diag::note_constexpr_null_subobject) << CSK;
1650 bool checkNullPointerForFoldAccess(EvalInfo &Info,
const Expr *E,
1652 return checkNullPointerDiagnosingWith([&Info, E, AK] {
1653 if (AK == AccessKinds::AK_Dereference)
1654 Info.FFDiag(E, diag::note_constexpr_dereferencing_null);
1656 Info.FFDiag(E, diag::note_constexpr_access_null) << AK;
1664 Designator.checkSubobject(Info, E, CSK);
1667 void addDecl(EvalInfo &Info,
const Expr *E,
1668 const Decl *D,
bool Virtual =
false) {
1670 Designator.addDeclUnchecked(D,
Virtual);
1672 void addUnsizedArray(EvalInfo &Info,
const Expr *E, QualType ElemTy) {
1673 if (!Designator.Entries.empty()) {
1674 Info.CCEDiag(E, diag::note_constexpr_unsupported_unsized_array);
1675 Designator.setInvalid();
1679 assert(
getType(Base).getNonReferenceType()->isPointerType() ||
1680 getType(Base).getNonReferenceType()->isArrayType());
1681 Designator.FirstEntryIsAnUnsizedArray =
true;
1682 Designator.addUnsizedArrayUnchecked(ElemTy);
1685 void addArray(EvalInfo &Info,
const Expr *E,
const ConstantArrayType *CAT) {
1687 Designator.addArrayUnchecked(CAT);
1689 void addComplex(EvalInfo &Info,
const Expr *E, QualType EltTy,
bool Imag) {
1691 Designator.addComplexUnchecked(EltTy, Imag);
1693 void addVectorElement(EvalInfo &Info,
const Expr *E, QualType EltTy,
1694 uint64_t Size, uint64_t Idx) {
1696 Designator.addVectorElementUnchecked(EltTy, Size, Idx);
1698 void clearIsNullPointer() {
1701 void adjustOffsetAndIndex(EvalInfo &Info,
const Expr *E,
1702 const APSInt &Index, CharUnits ElementSize) {
1713 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
1717 Designator.adjustIndex(Info, E, Index, *
this);
1718 clearIsNullPointer();
1720 void adjustOffset(CharUnits N) {
1723 clearIsNullPointer();
1729 explicit MemberPtr(
const ValueDecl *Decl)
1730 : DeclAndIsDerivedMember(
Decl,
false) {}
1734 const ValueDecl *getDecl()
const {
1735 return DeclAndIsDerivedMember.getPointer();
1738 bool isDerivedMember()
const {
1739 return DeclAndIsDerivedMember.getInt();
1742 const CXXRecordDecl *getContainingRecord()
const {
1744 DeclAndIsDerivedMember.getPointer()->getDeclContext());
1748 V =
APValue(getDecl(), isDerivedMember(), Path);
1751 assert(
V.isMemberPointer());
1752 DeclAndIsDerivedMember.setPointer(
V.getMemberPointerDecl());
1753 DeclAndIsDerivedMember.setInt(
V.isMemberPointerToDerivedMember());
1755 llvm::append_range(Path,
V.getMemberPointerPath());
1761 llvm::PointerIntPair<const ValueDecl*, 1, bool> DeclAndIsDerivedMember;
1764 SmallVector<const CXXRecordDecl*, 4> Path;
1768 bool castBack(
const CXXRecordDecl *
Class) {
1769 assert(!Path.empty());
1770 const CXXRecordDecl *Expected;
1771 if (Path.size() >= 2)
1772 Expected = Path[Path.size() - 2];
1774 Expected = getContainingRecord();
1788 bool castToDerived(
const CXXRecordDecl *Derived) {
1791 if (!isDerivedMember()) {
1792 Path.push_back(Derived);
1795 if (!castBack(Derived))
1798 DeclAndIsDerivedMember.setInt(
false);
1806 DeclAndIsDerivedMember.setInt(
true);
1807 if (isDerivedMember()) {
1808 Path.push_back(Base);
1811 return castBack(Base);
1816 static bool operator==(
const MemberPtr &LHS,
const MemberPtr &RHS) {
1817 if (!LHS.getDecl() || !RHS.getDecl())
1818 return !LHS.getDecl() && !RHS.getDecl();
1819 if (LHS.getDecl()->getCanonicalDecl() != RHS.getDecl()->getCanonicalDecl())
1821 return LHS.Path == RHS.Path;
1825void SubobjectDesignator::adjustIndex(EvalInfo &Info,
const Expr *E,
APSInt N,
1829 uint64_t TruncatedN = N.extOrTrunc(64).getZExtValue();
1830 if (isMostDerivedAnUnsizedArray()) {
1831 diagnoseUnsizedArrayPointerArithmetic(Info, E);
1836 PathEntry::ArrayIndex(Entries.back().getAsArrayIndex() + TruncatedN);
1844 MostDerivedPathLength == Entries.size() && MostDerivedIsArrayElement;
1846 IsArray ? Entries.back().getAsArrayIndex() : (
uint64_t)IsOnePastTheEnd;
1849 if (N < -(int64_t)ArrayIndex || N > ArraySize - ArrayIndex) {
1850 if (!Info.checkingPotentialConstantExpression() ||
1851 !LV.AllowConstexprUnknown) {
1854 N = N.extend(std::max<unsigned>(N.getBitWidth() + 1, 65));
1855 (llvm::APInt &)N += ArrayIndex;
1856 assert(N.ugt(ArraySize) &&
"bounds check failed for in-bounds index");
1857 diagnosePointerArithmetic(Info, E, N);
1863 ArrayIndex += TruncatedN;
1864 assert(ArrayIndex <= ArraySize &&
1865 "bounds check succeeded for out-of-bounds index");
1868 Entries.back() = PathEntry::ArrayIndex(ArrayIndex);
1870 IsOnePastTheEnd = (ArrayIndex != 0);
1875 const LValue &This,
const Expr *E,
1876 bool AllowNonLiteralTypes =
false);
1878 bool InvalidBaseOK =
false);
1880 bool InvalidBaseOK =
false);
1888static bool EvaluateComplex(
const Expr *E, ComplexValue &Res, EvalInfo &Info);
1894 std::string *StringResult =
nullptr);
1911 if (Int.isUnsigned() || Int.isMinSignedValue()) {
1912 Int = Int.extend(Int.getBitWidth() + 1);
1913 Int.setIsSigned(
true);
1918template<
typename KeyT>
1919APValue &CallStackFrame::createTemporary(
const KeyT *Key, QualType
T,
1920 ScopeKind Scope, LValue &LV) {
1921 unsigned Version = getTempVersion();
1922 APValue::LValueBase
Base(Key, Index, Version);
1924 return createLocal(Base, Key,
T, Scope);
1928APValue &CallStackFrame::createParam(CallRef Args,
const ParmVarDecl *PVD,
1930 assert(Args.CallIndex == Index &&
"creating parameter in wrong frame");
1931 APValue::LValueBase
Base(PVD, Index, Args.Version);
1936 return createLocal(Base, PVD, PVD->
getType(), ScopeKind::Call);
1939APValue &CallStackFrame::createLocal(APValue::LValueBase Base,
const void *Key,
1940 QualType
T, ScopeKind Scope) {
1941 assert(
Base.getCallIndex() == Index &&
"lvalue for wrong frame");
1942 unsigned Version =
Base.getVersion();
1944 assert(
Result.isAbsent() &&
"local created multiple times");
1950 if (Index <= Info.SpeculativeEvaluationDepth) {
1951 if (
T.isDestructedType())
1952 Info.noteSideEffect();
1954 Info.CleanupStack.push_back(Cleanup(&
Result, Base,
T, Scope));
1959APValue *EvalInfo::createHeapAlloc(
const Expr *E, QualType
T, LValue &LV) {
1961 FFDiag(E, diag::note_constexpr_heap_alloc_limit_exceeded);
1965 DynamicAllocLValue DA(NumHeapAllocs++);
1967 auto Result = HeapAllocs.emplace(std::piecewise_construct,
1968 std::forward_as_tuple(DA), std::tuple<>());
1969 assert(
Result.second &&
"reused a heap alloc index?");
1970 Result.first->second.AllocExpr = E;
1971 return &
Result.first->second.Value;
1975void CallStackFrame::describe(raw_ostream &Out)
const {
1976 bool IsMemberCall =
false;
1977 bool ExplicitInstanceParam =
false;
1978 if (
const auto *MD = dyn_cast<CXXMethodDecl>(Callee)) {
1980 ExplicitInstanceParam = MD->isExplicitObjectMemberFunction();
1987 if (This && IsMemberCall) {
1988 if (
const auto *MCE = dyn_cast_if_present<CXXMemberCallExpr>(CallExpr)) {
1989 const Expr *
Object = MCE->getImplicitObjectArgument();
1992 if (
Object->getType()->isPointerType())
1996 }
else if (
const auto *OCE =
1997 dyn_cast_if_present<CXXOperatorCallExpr>(CallExpr)) {
1998 OCE->getArg(0)->printPretty(Out,
nullptr,
2004 This->moveInto(Val);
2016 llvm::ListSeparator
Comma;
2017 for (
const ParmVarDecl *Param :
2018 Callee->parameters().slice(ExplicitInstanceParam)) {
2020 const APValue *
V = Info.getParamSlot(Arguments, Param);
2022 V->printPretty(Out, Info.Ctx, Param->getType());
2038 return Info.noteSideEffect();
2045 return (
Builtin == Builtin::BI__builtin___CFStringMakeConstantString ||
2046 Builtin == Builtin::BI__builtin___NSStringMakeConstantString ||
2047 Builtin == Builtin::BI__builtin_ptrauth_sign_constant ||
2048 Builtin == Builtin::BI__builtin_function_start);
2052 const auto *BaseExpr =
2053 llvm::dyn_cast_if_present<CallExpr>(LVal.Base.
dyn_cast<
const Expr *>());
2068 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
2069 return VD->hasGlobalStorage();
2085 case Expr::CompoundLiteralExprClass: {
2089 case Expr::MaterializeTemporaryExprClass:
2094 case Expr::StringLiteralClass:
2095 case Expr::PredefinedExprClass:
2096 case Expr::ObjCStringLiteralClass:
2097 case Expr::ObjCEncodeExprClass:
2099 case Expr::ObjCBoxedExprClass:
2101 case Expr::CallExprClass:
2104 case Expr::AddrLabelExprClass:
2108 case Expr::BlockExprClass:
2112 case Expr::SourceLocExprClass:
2114 case Expr::ImplicitValueInitExprClass:
2139 const auto *BaseExpr = LVal.Base.
dyn_cast<
const Expr *>();
2144 if (
const auto *EE = dyn_cast<ObjCEncodeExpr>(BaseExpr)) {
2153 const auto *Lit = dyn_cast<StringLiteral>(BaseExpr);
2154 if (
const auto *PE = dyn_cast<PredefinedExpr>(BaseExpr))
2155 Lit = PE->getFunctionName();
2160 AsString.
Bytes = Lit->getBytes();
2161 AsString.
CharWidth = Lit->getCharByteWidth();
2181 const LValue &RHS) {
2190 CharUnits Offset = RHS.Offset - LHS.Offset;
2191 if (Offset.isNegative()) {
2192 if (LHSString.
Bytes.size() < (
size_t)-Offset.getQuantity())
2194 LHSString.
Bytes = LHSString.
Bytes.drop_front(-Offset.getQuantity());
2196 if (RHSString.
Bytes.size() < (
size_t)Offset.getQuantity())
2198 RHSString.
Bytes = RHSString.
Bytes.drop_front(Offset.getQuantity());
2201 bool LHSIsLonger = LHSString.
Bytes.size() > RHSString.
Bytes.size();
2202 StringRef Longer = LHSIsLonger ? LHSString.
Bytes : RHSString.
Bytes;
2203 StringRef Shorter = LHSIsLonger ? RHSString.
Bytes : LHSString.
Bytes;
2204 int ShorterCharWidth = (LHSIsLonger ? RHSString : LHSString).CharWidth;
2209 for (
int NullByte : llvm::seq(ShorterCharWidth)) {
2210 if (Shorter.size() + NullByte >= Longer.size())
2212 if (Longer[Shorter.size() + NullByte])
2218 return Shorter == Longer.take_front(Shorter.size());
2228 if (isa_and_nonnull<VarDecl>(
Decl)) {
2238 if (!A.getLValueBase())
2239 return !B.getLValueBase();
2240 if (!B.getLValueBase())
2243 if (A.getLValueBase().getOpaqueValue() !=
2244 B.getLValueBase().getOpaqueValue())
2247 return A.getLValueCallIndex() == B.getLValueCallIndex() &&
2248 A.getLValueVersion() == B.getLValueVersion();
2252 assert(
Base &&
"no location for a null lvalue");
2258 if (
auto *PVD = dyn_cast_or_null<ParmVarDecl>(VD)) {
2260 for (CallStackFrame *F = Info.CurrentCall; F; F = F->Caller) {
2261 if (F->Arguments.CallIndex ==
Base.getCallIndex() &&
2262 F->Arguments.Version ==
Base.getVersion() && F->Callee &&
2263 Idx < F->Callee->getNumParams()) {
2264 VD = F->Callee->getParamDecl(Idx);
2271 Info.Note(VD->
getLocation(), diag::note_declared_at);
2273 Info.Note(E->
getExprLoc(), diag::note_constexpr_temporary_here);
2276 if (std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA))
2277 Info.Note((*Alloc)->AllocExpr->getExprLoc(),
2278 diag::note_constexpr_dynamic_alloc_here);
2311 const SubobjectDesignator &
Designator = LVal.getLValueDesignator();
2319 if (isTemplateArgument(Kind)) {
2320 int InvalidBaseKind = -1;
2323 InvalidBaseKind = 0;
2324 else if (isa_and_nonnull<StringLiteral>(BaseE))
2325 InvalidBaseKind = 1;
2326 else if (isa_and_nonnull<MaterializeTemporaryExpr>(BaseE) ||
2327 isa_and_nonnull<LifetimeExtendedTemporaryDecl>(BaseVD))
2328 InvalidBaseKind = 2;
2329 else if (
auto *PE = dyn_cast_or_null<PredefinedExpr>(BaseE)) {
2330 InvalidBaseKind = 3;
2331 Ident = PE->getIdentKindName();
2334 if (InvalidBaseKind != -1) {
2335 Info.FFDiag(Loc, diag::note_constexpr_invalid_template_arg)
2336 << IsReferenceType << !
Designator.Entries.empty() << InvalidBaseKind
2342 if (
auto *FD = dyn_cast_or_null<FunctionDecl>(BaseVD);
2343 FD && FD->isImmediateFunction()) {
2344 Info.FFDiag(Loc, diag::note_consteval_address_accessible)
2346 Info.Note(FD->getLocation(), diag::note_declared_at);
2354 if (Info.getLangOpts().CPlusPlus11) {
2355 Info.FFDiag(Loc, diag::note_constexpr_non_global, 1)
2356 << IsReferenceType << !
Designator.Entries.empty() << !!BaseVD
2358 auto *VarD = dyn_cast_or_null<VarDecl>(BaseVD);
2359 if (VarD && VarD->isConstexpr()) {
2365 Info.Note(VarD->getLocation(), diag::note_constexpr_not_static)
2377 assert((Info.checkingPotentialConstantExpression() ||
2378 LVal.getLValueCallIndex() == 0) &&
2379 "have call index for global lvalue");
2381 if (LVal.allowConstexprUnknown()) {
2383 Info.FFDiag(Loc, diag::note_constexpr_var_init_non_constant, 1) << BaseVD;
2392 Info.FFDiag(Loc, diag::note_constexpr_dynamic_alloc)
2393 << IsReferenceType << !
Designator.Entries.empty();
2399 if (
const VarDecl *Var = dyn_cast<const VarDecl>(BaseVD)) {
2401 if (Var->getTLSKind())
2409 if (!isForManglingOnly(Kind) && Var->hasAttr<DLLImportAttr>() &&
2410 !Var->isStaticLocal())
2415 if (Info.getASTContext().getLangOpts().CUDA &&
2416 Info.getASTContext().getLangOpts().CUDAIsDevice &&
2417 Info.getASTContext().CUDAConstantEvalCtx.NoWrongSidedVars) {
2418 if ((!Var->hasAttr<CUDADeviceAttr>() &&
2419 !Var->hasAttr<CUDAConstantAttr>() &&
2420 !Var->getType()->isCUDADeviceBuiltinSurfaceType() &&
2421 !Var->getType()->isCUDADeviceBuiltinTextureType()) ||
2422 Var->hasAttr<HIPManagedAttr>())
2426 if (
const auto *FD = dyn_cast<const FunctionDecl>(BaseVD)) {
2437 if (Info.getLangOpts().CPlusPlus && !isForManglingOnly(Kind) &&
2438 FD->hasAttr<DLLImportAttr>())
2442 }
else if (
const auto *MTE =
2443 dyn_cast_or_null<MaterializeTemporaryExpr>(BaseE)) {
2444 if (CheckedTemps.insert(MTE).second) {
2447 Info.FFDiag(MTE->getExprLoc(),
2448 diag::note_constexpr_unsupported_temporary_nontrivial_dtor)
2453 APValue *
V = MTE->getOrCreateValue(
false);
2454 assert(
V &&
"evasluation result refers to uninitialised temporary");
2456 Info, MTE->getExprLoc(), TempType, *
V, Kind,
2457 nullptr, CheckedTemps))
2464 if (!IsReferenceType)
2476 Info.FFDiag(Loc, diag::note_constexpr_past_end, 1)
2477 << !
Designator.Entries.empty() << !!BaseVD << BaseVD;
2492 const auto *FD = dyn_cast_or_null<CXXMethodDecl>(
Member);
2495 if (FD->isImmediateFunction()) {
2496 Info.FFDiag(Loc, diag::note_consteval_address_accessible) << 0;
2497 Info.Note(FD->getLocation(), diag::note_declared_at);
2500 return isForManglingOnly(Kind) || FD->isVirtual() ||
2501 !FD->hasAttr<DLLImportAttr>();
2507 const LValue *
This =
nullptr) {
2509 if (Info.getLangOpts().CPlusPlus23)
2528 if (
This && Info.EvaluatingDecl ==
This->getLValueBase())
2532 if (Info.getLangOpts().CPlusPlus11)
2533 Info.FFDiag(E, diag::note_constexpr_nonliteral)
2536 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
2547 if (SubobjectDecl) {
2548 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
2549 << 1 << SubobjectDecl;
2551 diag::note_constexpr_subobject_declared_here);
2553 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
2562 Type = AT->getValueType();
2567 if (
Value.isArray()) {
2569 for (
unsigned I = 0, N =
Value.getArrayInitializedElts(); I != N; ++I) {
2571 Value.getArrayInitializedElt(I), Kind,
2572 SubobjectDecl, CheckedTemps))
2575 if (!
Value.hasArrayFiller())
2578 Value.getArrayFiller(), Kind, SubobjectDecl,
2581 if (
Value.isUnion() &&
Value.getUnionField()) {
2584 Value.getUnionValue(), Kind,
Value.getUnionField(), CheckedTemps);
2586 if (
Value.isStruct()) {
2588 if (
const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {
2589 unsigned BaseIndex = 0;
2591 const APValue &BaseValue =
Value.getStructBase(BaseIndex);
2594 Info.FFDiag(TypeBeginLoc, diag::note_constexpr_uninitialized_base)
2595 << BS.getType() <<
SourceRange(TypeBeginLoc, BS.getEndLoc());
2605 for (
const auto *I : RD->fields()) {
2606 if (I->isUnnamedBitField())
2610 Value.getStructField(I->getFieldIndex()), Kind,
2616 if (
Value.isLValue() &&
2619 LVal.setFrom(Info.Ctx,
Value);
2624 if (
Value.isMemberPointer() &&
2645 nullptr, CheckedTemps);
2655 ConstantExprKind::Normal,
nullptr, CheckedTemps);
2661 if (!Info.HeapAllocs.empty()) {
2665 Info.CCEDiag(Info.HeapAllocs.begin()->second.AllocExpr,
2666 diag::note_constexpr_memory_leak)
2667 <<
unsigned(Info.HeapAllocs.size() - 1);
2675 if (!
Value.getLValueBase()) {
2677 Result = !
Value.getLValueOffset().isZero();
2695 Result = Val.
getInt().getBoolValue();
2727 llvm_unreachable(
"unknown APValue kind");
2733 assert(E->
isPRValue() &&
"missing lvalue-to-rvalue conv in bool condition");
2743 Info.CCEDiag(E, diag::note_constexpr_overflow)
2744 << SrcValue << DestType;
2745 return Info.noteUndefinedBehavior();
2751 unsigned DestWidth = Info.Ctx.
getIntWidth(DestType);
2755 Result =
APSInt(DestWidth, !DestSigned);
2757 if (
Value.convertToInteger(Result, llvm::APFloat::rmTowardZero, &ignored)
2758 & APFloat::opInvalidOp)
2769 llvm::RoundingMode RM =
2771 if (RM == llvm::RoundingMode::Dynamic)
2772 RM = llvm::RoundingMode::NearestTiesToEven;
2778 APFloat::opStatus St) {
2781 if (Info.InConstantContext)
2785 if ((St & APFloat::opInexact) &&
2789 Info.FFDiag(E, diag::note_constexpr_dynamic_rounding);
2793 if ((St != APFloat::opOK) &&
2796 FPO.getAllowFEnvAccess())) {
2797 Info.FFDiag(E, diag::note_constexpr_float_arithmetic_strict);
2801 if ((St & APFloat::opStatus::opInvalidOp) &&
2822 "HandleFloatToFloatCast has been checked with only CastExpr, "
2823 "CompoundAssignOperator and ConvertVectorExpr. Please either validate "
2824 "the new expression or address the root cause of this usage.");
2826 APFloat::opStatus St;
2827 APFloat
Value = Result;
2836 unsigned DestWidth = Info.Ctx.
getIntWidth(DestType);
2842 Result =
Value.getBoolValue();
2849 QualType DestType, APFloat &Result) {
2852 APFloat::opStatus St = Result.convertFromAPInt(
Value,
Value.isSigned(), RM);
2858 assert(FD->
isBitField() &&
"truncateBitfieldValue on non-bitfield");
2860 if (!
Value.isInt()) {
2864 assert(
Value.isLValue() &&
"integral value neither int nor lvalue?");
2870 unsigned OldBitWidth = Int.getBitWidth();
2872 if (NewBitWidth < OldBitWidth)
2873 Int = Int.trunc(NewBitWidth).extend(OldBitWidth);
2880template<
typename Operation>
2883 unsigned BitWidth, Operation Op,
2885 if (LHS.isUnsigned()) {
2886 Result = Op(LHS, RHS);
2890 APSInt Value(Op(LHS.extend(BitWidth), RHS.extend(BitWidth)),
false);
2891 Result =
Value.trunc(LHS.getBitWidth());
2892 if (Result.extend(BitWidth) !=
Value) {
2893 if (Info.checkingForUndefinedBehavior())
2895 diag::warn_integer_constant_overflow)
2896 <<
toString(Result, 10, Result.isSigned(),
false,
2908 bool HandleOverflowResult =
true;
2915 std::multiplies<APSInt>(), Result);
2918 std::plus<APSInt>(), Result);
2921 std::minus<APSInt>(), Result);
2922 case BO_And: Result = LHS & RHS;
return true;
2923 case BO_Xor: Result = LHS ^ RHS;
return true;
2924 case BO_Or: Result = LHS | RHS;
return true;
2928 Info.FFDiag(E, diag::note_expr_divide_by_zero)
2934 if (RHS.isNegative() && RHS.isAllOnes() && LHS.isSigned() &&
2935 LHS.isMinSignedValue())
2937 Info, E, -LHS.extend(LHS.getBitWidth() + 1), E->
getType());
2938 Result = (Opcode == BO_Rem ? LHS % RHS : LHS / RHS);
2939 return HandleOverflowResult;
2941 if (Info.getLangOpts().OpenCL)
2943 RHS &=
APSInt(llvm::APInt(RHS.getBitWidth(),
2944 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2946 else if (RHS.isSigned() && RHS.isNegative()) {
2949 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
2950 if (!Info.noteUndefinedBehavior())
2958 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
2960 Info.CCEDiag(E, diag::note_constexpr_large_shift)
2961 << RHS << E->
getType() << LHS.getBitWidth();
2962 if (!Info.noteUndefinedBehavior())
2964 }
else if (LHS.isSigned() && !Info.getLangOpts().CPlusPlus20) {
2969 if (LHS.isNegative()) {
2970 Info.CCEDiag(E, diag::note_constexpr_lshift_of_negative) << LHS;
2971 if (!Info.noteUndefinedBehavior())
2973 }
else if (LHS.countl_zero() < SA) {
2974 Info.CCEDiag(E, diag::note_constexpr_lshift_discards);
2975 if (!Info.noteUndefinedBehavior())
2983 if (Info.getLangOpts().OpenCL)
2985 RHS &=
APSInt(llvm::APInt(RHS.getBitWidth(),
2986 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2988 else if (RHS.isSigned() && RHS.isNegative()) {
2991 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
2992 if (!Info.noteUndefinedBehavior())
3000 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
3002 Info.CCEDiag(E, diag::note_constexpr_large_shift)
3003 << RHS << E->
getType() << LHS.getBitWidth();
3004 if (!Info.noteUndefinedBehavior())
3012 case BO_LT: Result = LHS < RHS;
return true;
3013 case BO_GT: Result = LHS > RHS;
return true;
3014 case BO_LE: Result = LHS <= RHS;
return true;
3015 case BO_GE: Result = LHS >= RHS;
return true;
3016 case BO_EQ: Result = LHS == RHS;
return true;
3017 case BO_NE: Result = LHS != RHS;
return true;
3019 llvm_unreachable(
"BO_Cmp should be handled elsewhere");
3026 const APFloat &RHS) {
3028 APFloat::opStatus St;
3034 St = LHS.multiply(RHS, RM);
3037 St = LHS.add(RHS, RM);
3040 St = LHS.subtract(RHS, RM);
3046 Info.CCEDiag(E, diag::note_expr_divide_by_zero);
3047 St = LHS.divide(RHS, RM);
3056 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << LHS.isNaN();
3057 return Info.noteUndefinedBehavior();
3065 const APInt &RHSValue, APInt &Result) {
3066 bool LHS = (LHSValue != 0);
3067 bool RHS = (RHSValue != 0);
3069 if (Opcode == BO_LAnd)
3070 Result = LHS && RHS;
3072 Result = LHS || RHS;
3077 const APFloat &RHSValue, APInt &Result) {
3078 bool LHS = !LHSValue.isZero();
3079 bool RHS = !RHSValue.isZero();
3081 if (Opcode == BO_LAnd)
3082 Result = LHS && RHS;
3084 Result = LHS || RHS;
3090 const APValue &RHSValue, APInt &Result) {
3094 RHSValue.
getInt(), Result);
3100template <
typename APTy>
3103 const APTy &RHSValue, APInt &Result) {
3106 llvm_unreachable(
"unsupported binary operator");
3108 Result = (LHSValue == RHSValue);
3111 Result = (LHSValue != RHSValue);
3114 Result = (LHSValue < RHSValue);
3117 Result = (LHSValue > RHSValue);
3120 Result = (LHSValue <= RHSValue);
3123 Result = (LHSValue >= RHSValue);
3137 const APValue &RHSValue, APInt &Result) {
3141 RHSValue.
getInt(), Result);
3152 assert(Opcode != BO_PtrMemD && Opcode != BO_PtrMemI &&
3153 "Operation not supported on vector types");
3157 QualType EltTy = VT->getElementType();
3164 "A vector result that isn't a vector OR uncalculated LValue");
3170 RHSValue.
getVectorLength() == NumElements &&
"Different vector sizes");
3174 for (
unsigned EltNum = 0; EltNum < NumElements; ++EltNum) {
3189 RHSElt.
getInt(), EltResult);
3195 ResultElements.emplace_back(EltResult);
3200 "Mismatched LHS/RHS/Result Type");
3201 APFloat LHSFloat = LHSElt.
getFloat();
3209 ResultElements.emplace_back(LHSFloat);
3213 LHSValue =
APValue(ResultElements.data(), ResultElements.size());
3221 unsigned TruncatedElements) {
3222 SubobjectDesignator &D = Result.Designator;
3225 if (TruncatedElements == D.Entries.size())
3227 assert(TruncatedElements >= D.MostDerivedPathLength &&
3228 "not casting to a derived class");
3234 for (
unsigned I = TruncatedElements, N = D.Entries.size(); I != N; ++I) {
3238 if (isVirtualBaseClass(D.Entries[I]))
3244 D.Entries.resize(TruncatedElements);
3257 Obj.addDecl(Info, E,
Base,
false);
3258 Obj.getLValueOffset() += RL->getBaseClassOffset(
Base);
3267 if (!
Base->isVirtual())
3270 SubobjectDesignator &D = Obj.Designator;
3286 Obj.addDecl(Info, E, BaseDecl,
true);
3295 PathI != PathE; ++PathI) {
3299 Type = (*PathI)->getType();
3311 llvm_unreachable(
"Class must be derived from the passed in base class!");
3330 LVal.addDecl(Info, E, FD);
3339 for (
const auto *
C : IFD->
chain())
3392 LVal.adjustOffsetAndIndex(Info, E, Adjustment, SizeOfPointee);
3398 int64_t Adjustment) {
3400 APSInt::get(Adjustment));
3415 LVal.Offset += SizeOfComponent;
3417 LVal.addComplex(Info, E, EltTy, Imag);
3423 uint64_t Size, uint64_t Idx) {
3428 LVal.Offset += SizeOfElement * Idx;
3430 LVal.addVectorElement(Info, E, EltTy, Size, Idx);
3444 const VarDecl *VD, CallStackFrame *Frame,
3445 unsigned Version,
APValue *&Result) {
3448 bool AllowConstexprUnknown =
3453 auto CheckUninitReference = [&](
bool IsLocalVariable) {
3465 if (!AllowConstexprUnknown || IsLocalVariable) {
3466 if (!Info.checkingPotentialConstantExpression())
3467 Info.FFDiag(E, diag::note_constexpr_use_uninit_reference);
3477 Result = Frame->getTemporary(VD, Version);
3479 return CheckUninitReference(
true);
3488 "missing value for local variable");
3489 if (Info.checkingPotentialConstantExpression())
3494 diag::note_unimplemented_constexpr_lambda_feature_ast)
3495 <<
"captures not currently allowed";
3502 if (Info.EvaluatingDecl ==
Base) {
3503 Result = Info.EvaluatingDeclValue;
3504 return CheckUninitReference(
false);
3512 if (AllowConstexprUnknown) {
3519 if (!Info.checkingPotentialConstantExpression() ||
3520 !Info.CurrentCall->Callee ||
3522 if (Info.getLangOpts().CPlusPlus11) {
3523 Info.FFDiag(E, diag::note_constexpr_function_param_value_unknown)
3544 if (!
Init && !AllowConstexprUnknown) {
3547 if (!Info.checkingPotentialConstantExpression()) {
3548 Info.FFDiag(E, diag::note_constexpr_var_init_unknown, 1)
3559 if (
Init &&
Init->isValueDependent()) {
3566 if (!Info.checkingPotentialConstantExpression()) {
3567 Info.FFDiag(E, Info.getLangOpts().CPlusPlus11
3568 ? diag::note_constexpr_ltor_non_constexpr
3569 : diag::note_constexpr_ltor_non_integral, 1)
3583 Info.FFDiag(E, diag::note_constexpr_var_init_non_constant, 1) << VD;
3599 !AllowConstexprUnknown) ||
3600 ((Info.getLangOpts().CPlusPlus || Info.getLangOpts().OpenCL) &&
3603 Info.CCEDiag(E, diag::note_constexpr_var_init_non_constant, 1) << VD;
3613 Info.FFDiag(E, diag::note_constexpr_var_init_weak) << VD;
3620 if (!Result && !AllowConstexprUnknown)
3623 return CheckUninitReference(
false);
3633 E = Derived->
bases_end(); I != E; ++I, ++Index) {
3634 if (I->getType()->getAsCXXRecordDecl()->getCanonicalDecl() ==
Base)
3638 llvm_unreachable(
"base class missing from derived class's bases list");
3645 "SourceLocExpr should have already been converted to a StringLiteral");
3648 if (
const auto *ObjCEnc = dyn_cast<ObjCEncodeExpr>(Lit)) {
3651 assert(Index <= Str.size() &&
"Index too large");
3652 return APSInt::getUnsigned(Str.c_str()[Index]);
3655 if (
auto PE = dyn_cast<PredefinedExpr>(Lit))
3656 Lit = PE->getFunctionName();
3660 assert(CAT &&
"string literal isn't an array");
3662 assert(CharType->
isIntegerType() &&
"unexpected character type");
3665 if (Index < S->getLength())
3678 AllocType.isNull() ? S->
getType() : AllocType);
3679 assert(CAT &&
"string literal isn't an array");
3681 assert(CharType->
isIntegerType() &&
"unexpected character type");
3688 if (Result.hasArrayFiller())
3690 for (
unsigned I = 0, N = Result.getArrayInitializedElts(); I != N; ++I) {
3698 unsigned Size = Array.getArraySize();
3699 assert(Index < Size);
3702 unsigned OldElts = Array.getArrayInitializedElts();
3703 unsigned NewElts = std::max(Index+1, OldElts * 2);
3704 NewElts = std::min(Size, std::max(NewElts, 8u));
3708 for (
unsigned I = 0; I != OldElts; ++I)
3710 for (
unsigned I = OldElts; I != NewElts; ++I)
3714 Array.
swap(NewValue);
3724 CXXRecordDecl *RD =
T->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
3735 for (
auto *Field : RD->
fields())
3736 if (!Field->isUnnamedBitField() &&
3740 for (
auto &BaseSpec : RD->
bases())
3751 CXXRecordDecl *RD =
T->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
3758 for (
auto *Field : RD->
fields()) {
3763 if (Field->isMutable() &&
3765 Info.FFDiag(E, diag::note_constexpr_access_mutable, 1) << AK << Field;
3766 Info.Note(Field->getLocation(), diag::note_declared_at);
3774 for (
auto &BaseSpec : RD->
bases())
3784 bool MutableSubobject =
false) {
3789 switch (Info.IsEvaluatingDecl) {
3790 case EvalInfo::EvaluatingDeclKind::None:
3793 case EvalInfo::EvaluatingDeclKind::Ctor:
3795 if (Info.EvaluatingDecl ==
Base)
3800 if (
auto *BaseE =
Base.dyn_cast<
const Expr *>())
3801 if (
auto *BaseMTE = dyn_cast<MaterializeTemporaryExpr>(BaseE))
3802 return Info.EvaluatingDecl == BaseMTE->getExtendingDecl();
3805 case EvalInfo::EvaluatingDeclKind::Dtor:
3810 if (MutableSubobject ||
Base != Info.EvaluatingDecl)
3816 return T.isConstQualified() ||
T->isReferenceType();
3819 llvm_unreachable(
"unknown evaluating decl kind");
3824 return Info.CheckArraySize(
3844 uint64_t IntResult = BoolResult;
3854 Result.getInt(), DestTy, Result2.
getFloat()))
3862 Result =
APValue(APFloat(0.0));
3864 DestTy, Result.getFloat());
3870 uint64_t IntResult = BoolResult;
3889 uint64_t IntResult = BoolResult;
3896 DestTy, Result.getInt());
3900 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
3913 {&Result, ResultType, 0}};
3916 while (!WorkList.empty() && ElI < Elements.size()) {
3917 auto [Res,
Type, BitWidth] = WorkList.pop_back_val();
3933 APSInt &Int = Res->getInt();
3934 unsigned OldBitWidth = Int.getBitWidth();
3935 unsigned NewBitWidth = BitWidth;
3936 if (NewBitWidth < OldBitWidth)
3937 Int = Int.trunc(NewBitWidth).extend(OldBitWidth);
3946 for (
unsigned I = 0; I < NumEl; ++I) {
3952 *Res =
APValue(Vals.data(), NumEl);
3961 for (int64_t I = Size - 1; I > -1; --I)
3962 WorkList.emplace_back(&Res->getArrayInitializedElt(I), ElTy, 0u);
3968 unsigned NumBases = 0;
3969 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
3970 NumBases = CXXRD->getNumBases();
3977 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
3978 if (CXXRD->getNumBases() > 0) {
3979 assert(CXXRD->getNumBases() == 1);
3981 ReverseList.emplace_back(&Res->getStructBase(0), BS.
getType(), 0u);
3988 if (FD->isUnnamedBitField())
3990 if (FD->isBitField()) {
3991 FDBW = FD->getBitWidthValue();
3994 ReverseList.emplace_back(&Res->getStructField(FD->getFieldIndex()),
3995 FD->getType(), FDBW);
3998 std::reverse(ReverseList.begin(), ReverseList.end());
3999 llvm::append_range(WorkList, ReverseList);
4002 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
4015 assert((Elements.size() == SrcTypes.size()) &&
4016 (Elements.size() == DestTypes.size()));
4018 for (
unsigned I = 0, ESz = Elements.size(); I < ESz; ++I) {
4019 APValue Original = Elements[I];
4023 if (!
handleScalarCast(Info, FPO, E, SourceTy, DestTy, Original, Results[I]))
4034 while (!WorkList.empty()) {
4051 for (uint64_t I = 0; I < ArrSize; ++I) {
4052 WorkList.push_back(ElTy);
4060 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4061 if (CXXRD->getNumBases() > 0) {
4062 assert(CXXRD->getNumBases() == 1);
4064 WorkList.push_back(BS.
getType());
4070 if (FD->isUnnamedBitField())
4072 WorkList.push_back(FD->getType());
4089 "Not a valid HLSLAggregateSplatCast.");
4104 unsigned Populated = 0;
4105 while (!WorkList.empty() && Populated < Size) {
4106 auto [Work,
Type] = WorkList.pop_back_val();
4108 if (Work.isFloat() || Work.isInt()) {
4109 Elements.push_back(Work);
4110 Types.push_back(
Type);
4114 if (Work.isVector()) {
4117 for (
unsigned I = 0; I < Work.getVectorLength() && Populated < Size;
4119 Elements.push_back(Work.getVectorElt(I));
4120 Types.push_back(ElTy);
4125 if (Work.isArray()) {
4129 for (int64_t I = Work.getArraySize() - 1; I > -1; --I) {
4130 WorkList.emplace_back(Work.getArrayInitializedElt(I), ElTy);
4135 if (Work.isStruct()) {
4143 if (FD->isUnnamedBitField())
4145 ReverseList.emplace_back(Work.getStructField(FD->getFieldIndex()),
4149 std::reverse(ReverseList.begin(), ReverseList.end());
4150 llvm::append_range(WorkList, ReverseList);
4153 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4154 if (CXXRD->getNumBases() > 0) {
4155 assert(CXXRD->getNumBases() == 1);
4160 if (!
Base.isStruct())
4168 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
4177struct CompleteObject {
4179 APValue::LValueBase
Base;
4189 bool mayAccessMutableMembers(EvalInfo &Info,
AccessKinds AK)
const {
4200 if (!Info.getLangOpts().CPlusPlus14 &&
4201 AK != AccessKinds::AK_IsWithinLifetime)
4206 explicit operator bool()
const {
return !
Type.isNull(); }
4211 bool IsMutable =
false) {
4225template <
typename Sub
objectHandler>
4226static typename SubobjectHandler::result_type
4228 const SubobjectDesignator &Sub, SubobjectHandler &handler) {
4231 return handler.failed();
4232 if (Sub.isOnePastTheEnd() || Sub.isMostDerivedAnUnsizedArray()) {
4233 if (Info.getLangOpts().CPlusPlus11)
4234 Info.FFDiag(E, Sub.isOnePastTheEnd()
4235 ? diag::note_constexpr_access_past_end
4236 : diag::note_constexpr_access_unsized_array)
4237 << handler.AccessKind;
4240 return handler.failed();
4246 const FieldDecl *VolatileField =
nullptr;
4249 for (
unsigned I = 0, N = Sub.Entries.size(); ; ++I) {
4260 if (!Info.checkingPotentialConstantExpression())
4261 Info.FFDiag(E, diag::note_constexpr_access_uninit)
4264 return handler.failed();
4272 Info.isEvaluatingCtorDtor(
4273 Obj.Base,
ArrayRef(Sub.Entries.begin(), Sub.Entries.begin() + I)) !=
4274 ConstructionPhase::None) {
4284 if (Info.getLangOpts().CPlusPlus) {
4288 if (VolatileField) {
4291 Decl = VolatileField;
4294 Loc = VD->getLocation();
4301 Info.FFDiag(E, diag::note_constexpr_access_volatile_obj, 1)
4302 << handler.AccessKind << DiagKind <<
Decl;
4303 Info.Note(Loc, diag::note_constexpr_volatile_here) << DiagKind;
4305 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
4307 return handler.failed();
4315 !Obj.mayAccessMutableMembers(Info, handler.AccessKind) &&
4317 return handler.failed();
4321 if (!handler.found(*O, ObjType))
4333 LastField =
nullptr;
4338 "vla in literal type?");
4339 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4340 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT);
4341 CAT && CAT->
getSize().ule(Index)) {
4344 if (Info.getLangOpts().CPlusPlus11)
4345 Info.FFDiag(E, diag::note_constexpr_access_past_end)
4346 << handler.AccessKind;
4349 return handler.failed();
4356 else if (!
isRead(handler.AccessKind)) {
4357 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT);
4359 return handler.failed();
4367 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4369 if (Info.getLangOpts().CPlusPlus11)
4370 Info.FFDiag(E, diag::note_constexpr_access_past_end)
4371 << handler.AccessKind;
4374 return handler.failed();
4380 assert(I == N - 1 &&
"extracting subobject of scalar?");
4390 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4391 unsigned NumElements = VT->getNumElements();
4392 if (Index == NumElements) {
4393 if (Info.getLangOpts().CPlusPlus11)
4394 Info.FFDiag(E, diag::note_constexpr_access_past_end)
4395 << handler.AccessKind;
4398 return handler.failed();
4401 if (Index > NumElements) {
4402 Info.CCEDiag(E, diag::note_constexpr_array_index)
4403 << Index << 0 << NumElements;
4404 return handler.failed();
4407 ObjType = VT->getElementType();
4408 assert(I == N - 1 &&
"extracting subobject of scalar?");
4410 }
else if (
const FieldDecl *Field = getAsField(Sub.Entries[I])) {
4411 if (Field->isMutable() &&
4412 !Obj.mayAccessMutableMembers(Info, handler.AccessKind)) {
4413 Info.FFDiag(E, diag::note_constexpr_access_mutable, 1)
4414 << handler.AccessKind << Field;
4415 Info.Note(Field->getLocation(), diag::note_declared_at);
4416 return handler.failed();
4425 if (I == N - 1 && handler.AccessKind ==
AK_Construct) {
4436 Info.FFDiag(E, diag::note_constexpr_access_inactive_union_member)
4437 << handler.AccessKind << Field << !UnionField << UnionField;
4438 return handler.failed();
4447 if (Field->getType().isVolatileQualified())
4448 VolatileField = Field;
4461struct ExtractSubobjectHandler {
4467 typedef bool result_type;
4468 bool failed() {
return false; }
4469 bool found(
APValue &Subobj, QualType SubobjType) {
4479 bool found(APFloat &
Value, QualType SubobjType) {
4488 const CompleteObject &Obj,
4489 const SubobjectDesignator &Sub,
APValue &Result,
4492 ExtractSubobjectHandler Handler = {Info, E, Result, AK};
4497struct ModifySubobjectHandler {
4502 typedef bool result_type;
4505 bool checkConst(QualType QT) {
4508 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
4514 bool failed() {
return false; }
4515 bool found(
APValue &Subobj, QualType SubobjType) {
4516 if (!checkConst(SubobjType))
4519 Subobj.
swap(NewVal);
4523 if (!checkConst(SubobjType))
4525 if (!NewVal.
isInt()) {
4533 bool found(APFloat &
Value, QualType SubobjType) {
4534 if (!checkConst(SubobjType))
4542const AccessKinds ModifySubobjectHandler::AccessKind;
4546 const CompleteObject &Obj,
4547 const SubobjectDesignator &Sub,
4549 ModifySubobjectHandler Handler = { Info, NewVal, E };
4556 const SubobjectDesignator &A,
4557 const SubobjectDesignator &B,
4558 bool &WasArrayIndex) {
4559 unsigned I = 0, N = std::min(A.Entries.size(), B.Entries.size());
4560 for (; I != N; ++I) {
4564 if (A.Entries[I].getAsArrayIndex() != B.Entries[I].getAsArrayIndex()) {
4565 WasArrayIndex =
true;
4573 if (A.Entries[I].getAsBaseOrMember() !=
4574 B.Entries[I].getAsBaseOrMember()) {
4575 WasArrayIndex =
false;
4578 if (
const FieldDecl *FD = getAsField(A.Entries[I]))
4580 ObjType = FD->getType();
4586 WasArrayIndex =
false;
4593 const SubobjectDesignator &A,
4594 const SubobjectDesignator &B) {
4595 if (A.Entries.size() != B.Entries.size())
4598 bool IsArray = A.MostDerivedIsArrayElement;
4599 if (IsArray && A.MostDerivedPathLength != A.Entries.size())
4608 return CommonLength >= A.Entries.size() - IsArray;
4615 if (LVal.InvalidBase) {
4617 return CompleteObject();
4622 Info.FFDiag(E, diag::note_constexpr_dereferencing_null);
4624 Info.FFDiag(E, diag::note_constexpr_access_null) << AK;
4625 return CompleteObject();
4628 CallStackFrame *Frame =
nullptr;
4630 if (LVal.getLValueCallIndex()) {
4631 std::tie(Frame, Depth) =
4632 Info.getCallFrameAndDepth(LVal.getLValueCallIndex());
4634 Info.FFDiag(E, diag::note_constexpr_access_uninit, 1)
4637 return CompleteObject();
4648 if (Info.getLangOpts().CPlusPlus)
4649 Info.FFDiag(E, diag::note_constexpr_access_volatile_type)
4653 return CompleteObject();
4660 if (Info.getLangOpts().CPlusPlus14 && LVal.Base == Info.EvaluatingDecl &&
4664 BaseVal = Info.EvaluatingDeclValue;
4667 if (
auto *GD = dyn_cast<MSGuidDecl>(D)) {
4670 Info.FFDiag(E, diag::note_constexpr_modify_global);
4671 return CompleteObject();
4675 Info.FFDiag(E, diag::note_constexpr_unsupported_layout)
4677 return CompleteObject();
4679 return CompleteObject(LVal.Base, &
V, GD->getType());
4683 if (
auto *GCD = dyn_cast<UnnamedGlobalConstantDecl>(D)) {
4685 Info.FFDiag(E, diag::note_constexpr_modify_global);
4686 return CompleteObject();
4688 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&GCD->getValue()),
4693 if (
auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
4695 Info.FFDiag(E, diag::note_constexpr_modify_global);
4696 return CompleteObject();
4698 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&TPO->getValue()),
4709 const VarDecl *VD = dyn_cast<VarDecl>(D);
4716 return CompleteObject();
4719 bool IsConstant = BaseType.isConstant(Info.Ctx);
4720 bool ConstexprVar =
false;
4721 if (
const auto *VD = dyn_cast_if_present<VarDecl>(
4733 }
else if (Info.getLangOpts().CPlusPlus14 &&
4740 Info.FFDiag(E, diag::note_constexpr_modify_global);
4741 return CompleteObject();
4744 }
else if (Info.getLangOpts().C23 && ConstexprVar) {
4746 return CompleteObject();
4747 }
else if (BaseType->isIntegralOrEnumerationType()) {
4750 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4751 if (Info.getLangOpts().CPlusPlus) {
4752 Info.FFDiag(E, diag::note_constexpr_ltor_non_const_int, 1) << VD;
4753 Info.Note(VD->
getLocation(), diag::note_declared_at);
4757 return CompleteObject();
4759 }
else if (!IsAccess) {
4760 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4761 }
else if ((IsConstant || BaseType->isReferenceType()) &&
4762 Info.checkingPotentialConstantExpression() &&
4763 BaseType->isLiteralType(Info.Ctx) && !VD->
hasDefinition()) {
4765 }
else if (IsConstant) {
4769 if (Info.getLangOpts().CPlusPlus) {
4770 Info.CCEDiag(E, Info.getLangOpts().CPlusPlus11
4771 ? diag::note_constexpr_ltor_non_constexpr
4772 : diag::note_constexpr_ltor_non_integral, 1)
4774 Info.Note(VD->
getLocation(), diag::note_declared_at);
4780 if (Info.getLangOpts().CPlusPlus) {
4781 Info.FFDiag(E, Info.getLangOpts().CPlusPlus11
4782 ? diag::note_constexpr_ltor_non_constexpr
4783 : diag::note_constexpr_ltor_non_integral, 1)
4785 Info.Note(VD->
getLocation(), diag::note_declared_at);
4789 return CompleteObject();
4798 return CompleteObject();
4803 if (!Info.checkingPotentialConstantExpression()) {
4804 Info.FFDiag(E, diag::note_constexpr_access_unknown_variable, 1)
4806 Info.Note(VD->getLocation(), diag::note_declared_at);
4808 return CompleteObject();
4811 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
4813 Info.FFDiag(E, diag::note_constexpr_access_deleted_object) << AK;
4814 return CompleteObject();
4816 return CompleteObject(LVal.Base, &(*Alloc)->Value,
4826 dyn_cast_or_null<MaterializeTemporaryExpr>(
Base)) {
4827 assert(MTE->getStorageDuration() ==
SD_Static &&
4828 "should have a frame for a non-global materialized temporary");
4855 if (!MTE->isUsableInConstantExpressions(Info.Ctx) &&
4858 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4859 Info.FFDiag(E, diag::note_constexpr_access_static_temporary, 1) << AK;
4860 Info.Note(MTE->getExprLoc(), diag::note_constexpr_temporary_here);
4861 return CompleteObject();
4864 BaseVal = MTE->getOrCreateValue(
false);
4865 assert(BaseVal &&
"got reference to unevaluated temporary");
4867 dyn_cast_or_null<CompoundLiteralExpr>(
Base)) {
4883 !CLETy.isConstant(Info.Ctx)) {
4885 Info.Note(CLE->getExprLoc(), diag::note_declared_at);
4886 return CompleteObject();
4889 BaseVal = &CLE->getStaticValue();
4892 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4895 Info.FFDiag(E, diag::note_constexpr_access_unreadable_object)
4900 return CompleteObject();
4904 assert(BaseVal &&
"missing value for temporary");
4915 unsigned VisibleDepth = Depth;
4916 if (llvm::isa_and_nonnull<ParmVarDecl>(
4919 if ((Frame && Info.getLangOpts().CPlusPlus14 &&
4921 (
isModification(AK) && VisibleDepth < Info.SpeculativeEvaluationDepth))
4922 return CompleteObject();
4924 return CompleteObject(LVal.getLValueBase(), BaseVal, BaseType);
4943 const LValue &LVal,
APValue &RVal,
4944 bool WantObjectRepresentation =
false) {
4945 if (LVal.Designator.Invalid)
4954 if (
Base && !LVal.getLValueCallIndex() && !
Type.isVolatileQualified()) {
4958 assert(LVal.Designator.Entries.size() <= 1 &&
4959 "Can only read characters from string literals");
4960 if (LVal.Designator.Entries.empty()) {
4967 if (LVal.Designator.isOnePastTheEnd()) {
4968 if (Info.getLangOpts().CPlusPlus11)
4969 Info.FFDiag(Conv, diag::note_constexpr_access_past_end) << AK;
4974 uint64_t CharIndex = LVal.Designator.Entries[0].getAsArrayIndex();
4981 return Obj &&
extractSubobject(Info, Conv, Obj, LVal.Designator, RVal, AK);
4995 LVal.setFrom(Info.Ctx, Val);
5011 if (LVal.Designator.Invalid)
5014 if (!Info.getLangOpts().CPlusPlus14) {
5024struct CompoundAssignSubobjectHandler {
5026 const CompoundAssignOperator *E;
5027 QualType PromotedLHSType;
5033 typedef bool result_type;
5035 bool checkConst(QualType QT) {
5038 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
5044 bool failed() {
return false; }
5045 bool found(
APValue &Subobj, QualType SubobjType) {
5048 return found(Subobj.
getInt(), SubobjType);
5050 return found(Subobj.
getFloat(), SubobjType);
5057 return foundPointer(Subobj, SubobjType);
5059 return foundVector(Subobj, SubobjType);
5061 Info.FFDiag(E, diag::note_constexpr_access_uninit)
5072 bool foundVector(
APValue &
Value, QualType SubobjType) {
5073 if (!checkConst(SubobjType))
5084 if (!checkConst(SubobjType))
5106 PromotedLHSType, FValue) &&
5115 bool found(APFloat &
Value, QualType SubobjType) {
5116 return checkConst(SubobjType) &&
5122 bool foundPointer(
APValue &Subobj, QualType SubobjType) {
5123 if (!checkConst(SubobjType))
5126 QualType PointeeType;
5127 if (
const PointerType *PT = SubobjType->
getAs<PointerType>())
5131 (Opcode != BO_Add && Opcode != BO_Sub)) {
5137 if (Opcode == BO_Sub)
5141 LVal.setFrom(Info.Ctx, Subobj);
5144 LVal.moveInto(Subobj);
5150const AccessKinds CompoundAssignSubobjectHandler::AccessKind;
5155 const LValue &LVal,
QualType LValType,
5159 if (LVal.Designator.Invalid)
5162 if (!Info.getLangOpts().CPlusPlus14) {
5168 CompoundAssignSubobjectHandler Handler = { Info, E, PromotedLValType, Opcode,
5170 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
5174struct IncDecSubobjectHandler {
5176 const UnaryOperator *E;
5180 typedef bool result_type;
5182 bool checkConst(QualType QT) {
5185 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
5191 bool failed() {
return false; }
5192 bool found(
APValue &Subobj, QualType SubobjType) {
5202 return found(Subobj.
getInt(), SubobjType);
5204 return found(Subobj.
getFloat(), SubobjType);
5207 SubobjType->
castAs<ComplexType>()->getElementType()
5211 SubobjType->
castAs<ComplexType>()->getElementType()
5214 return foundPointer(Subobj, SubobjType);
5222 if (!checkConst(SubobjType))
5244 bool WasNegative =
Value.isNegative();
5256 unsigned BitWidth =
Value.getBitWidth();
5257 APSInt ActualValue(
Value.sext(BitWidth + 1),
false);
5258 ActualValue.setBit(BitWidth);
5264 bool found(APFloat &
Value, QualType SubobjType) {
5265 if (!checkConst(SubobjType))
5272 APFloat::opStatus St;
5274 St =
Value.add(One, RM);
5276 St =
Value.subtract(One, RM);
5279 bool foundPointer(
APValue &Subobj, QualType SubobjType) {
5280 if (!checkConst(SubobjType))
5283 QualType PointeeType;
5284 if (
const PointerType *PT = SubobjType->
getAs<PointerType>())
5292 LVal.setFrom(Info.Ctx, Subobj);
5296 LVal.moveInto(Subobj);
5305 if (LVal.Designator.Invalid)
5308 if (!Info.getLangOpts().CPlusPlus14) {
5316 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
5322 if (Object->getType()->isPointerType() && Object->isPRValue())
5325 if (Object->isGLValue())
5328 if (Object->getType()->isLiteralType(Info.Ctx))
5331 if (Object->getType()->isRecordType() && Object->isPRValue())
5334 Info.FFDiag(Object, diag::note_constexpr_nonliteral) << Object->getType();
5353 bool IncludeMember =
true) {
5360 if (!MemPtr.getDecl()) {
5366 if (MemPtr.isDerivedMember()) {
5373 if (LV.Designator.MostDerivedPathLength + MemPtr.Path.size() >
5374 LV.Designator.Entries.size()) {
5378 unsigned PathLengthToMember =
5379 LV.Designator.Entries.size() - MemPtr.Path.size();
5380 for (
unsigned I = 0, N = MemPtr.Path.size(); I != N; ++I) {
5382 LV.Designator.Entries[PathLengthToMember + I]);
5399 (PathLengthToMember > LV.Designator.MostDerivedPathLength)
5400 ? getAsBaseClass(LV.Designator.Entries[PathLengthToMember - 1])
5402 const CXXRecordDecl *LastMPDecl = MemPtr.getContainingRecord();
5410 PathLengthToMember))
5412 }
else if (!MemPtr.Path.empty()) {
5414 LV.Designator.Entries.reserve(LV.Designator.Entries.size() +
5415 MemPtr.Path.size() + IncludeMember);
5421 assert(RD &&
"member pointer access on non-class-type expression");
5423 for (
unsigned I = 1, N = MemPtr.Path.size(); I != N; ++I) {
5431 MemPtr.getContainingRecord()))
5436 if (IncludeMember) {
5437 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(MemPtr.getDecl())) {
5441 dyn_cast<IndirectFieldDecl>(MemPtr.getDecl())) {
5445 llvm_unreachable(
"can't construct reference to bound member function");
5449 return MemPtr.getDecl();
5455 bool IncludeMember =
true) {
5459 if (Info.noteFailure()) {
5467 BO->
getRHS(), IncludeMember);
5474 SubobjectDesignator &D = Result.Designator;
5475 if (D.Invalid || !Result.checkNullPointer(Info, E,
CSK_Derived))
5482 auto InvalidCast = [&]() {
5483 if (!Info.checkingPotentialConstantExpression() ||
5484 !Result.AllowConstexprUnknown) {
5485 Info.CCEDiag(E, diag::note_constexpr_invalid_downcast)
5486 << D.MostDerivedType << TargetQT;
5492 if (D.MostDerivedPathLength + E->
path_size() > D.Entries.size())
5493 return InvalidCast();
5497 unsigned NewEntriesSize = D.Entries.size() - E->
path_size();
5500 if (NewEntriesSize == D.MostDerivedPathLength)
5503 FinalType = getAsBaseClass(D.Entries[NewEntriesSize - 1]);
5505 return InvalidCast();
5517 if (!Result.isAbsent())
5520 if (
auto *RD =
T->getAsCXXRecordDecl()) {
5521 if (RD->isInvalidDecl()) {
5525 if (RD->isUnion()) {
5534 End = RD->bases_end();
5535 I != End; ++I, ++Index)
5539 for (
const auto *I : RD->fields()) {
5540 if (I->isUnnamedBitField())
5543 I->getType(), Result.getStructField(I->getFieldIndex()));
5549 dyn_cast_or_null<ConstantArrayType>(
T->getAsArrayTypeUnsafe())) {
5551 if (Result.hasArrayFiller())
5563enum EvalStmtResult {
5592 if (!Result.Designator.Invalid && Result.Designator.isOnePastTheEnd()) {
5598 Result.moveInto(Val);
5610 APValue &Val = Info.CurrentCall->createTemporary(VD, VD->
getType(),
5611 ScopeKind::Block, Result);
5616 return Info.noteSideEffect();
5637 const DecompositionDecl *DD);
5640 bool EvaluateConditionDecl =
false) {
5642 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
5646 EvaluateConditionDecl && DD)
5656 if (
auto *VD = BD->getHoldingVar())
5664 if (
auto *DD = dyn_cast_if_present<DecompositionDecl>(VD)) {
5673 if (Info.noteSideEffect())
5675 assert(E->
containsErrors() &&
"valid value-dependent expression should never "
5676 "reach invalid code path.");
5683 if (
Cond->isValueDependent())
5685 FullExpressionRAII
Scope(Info);
5692 return Scope.destroy();
5705struct TempVersionRAII {
5706 CallStackFrame &Frame;
5708 TempVersionRAII(CallStackFrame &Frame) : Frame(Frame) {
5709 Frame.pushTempVersion();
5712 ~TempVersionRAII() {
5713 Frame.popTempVersion();
5721 const SwitchCase *SC =
nullptr);
5727 const Stmt *LoopOrSwitch,
5729 EvalStmtResult &ESR) {
5733 if (!IsSwitch && ESR == ESR_Succeeded) {
5738 if (ESR != ESR_Break && ESR != ESR_Continue)
5742 bool CanBreakOrContinue = !IsSwitch || ESR == ESR_Break;
5743 const Stmt *StackTop = Info.BreakContinueStack.back();
5744 if (CanBreakOrContinue && (StackTop ==
nullptr || StackTop == LoopOrSwitch)) {
5745 Info.BreakContinueStack.pop_back();
5746 if (ESR == ESR_Break)
5747 ESR = ESR_Succeeded;
5752 for (BlockScopeRAII *S : Scopes) {
5753 if (!S->destroy()) {
5765 BlockScopeRAII
Scope(Info);
5767 EvalStmtResult ESR =
EvaluateStmt(Result, Info, Body, Case);
5768 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5777 BlockScopeRAII
Scope(Info);
5784 if (ESR != ESR_Succeeded) {
5785 if (ESR != ESR_Failed && !
Scope.destroy())
5791 FullExpressionRAII CondScope(Info);
5806 if (!CondScope.destroy())
5827 if (LHSValue <=
Value &&
Value <= RHSValue) {
5834 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5838 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5845 llvm_unreachable(
"Should have been converted to Succeeded");
5851 case ESR_CaseNotFound:
5854 Info.FFDiag(
Found->getBeginLoc(),
5855 diag::note_constexpr_stmt_expr_unsupported);
5858 llvm_unreachable(
"Invalid EvalStmtResult!");
5868 Info.CCEDiag(VD->
getLocation(), diag::note_constexpr_static_local)
5878 if (!Info.nextStep(S))
5885 case Stmt::CompoundStmtClass:
5889 case Stmt::LabelStmtClass:
5890 case Stmt::AttributedStmtClass:
5891 case Stmt::DoStmtClass:
5894 case Stmt::CaseStmtClass:
5895 case Stmt::DefaultStmtClass:
5900 case Stmt::IfStmtClass: {
5907 BlockScopeRAII
Scope(Info);
5913 if (ESR != ESR_CaseNotFound) {
5914 assert(ESR != ESR_Succeeded);
5925 if (ESR == ESR_Failed)
5927 if (ESR != ESR_CaseNotFound)
5928 return Scope.destroy() ? ESR : ESR_Failed;
5930 return ESR_CaseNotFound;
5933 if (ESR == ESR_Failed)
5935 if (ESR != ESR_CaseNotFound)
5936 return Scope.destroy() ? ESR : ESR_Failed;
5937 return ESR_CaseNotFound;
5940 case Stmt::WhileStmtClass: {
5941 EvalStmtResult ESR =
5945 if (ESR != ESR_Continue)
5950 case Stmt::ForStmtClass: {
5952 BlockScopeRAII
Scope(Info);
5958 if (ESR != ESR_CaseNotFound) {
5959 assert(ESR != ESR_Succeeded);
5964 EvalStmtResult ESR =
5968 if (ESR != ESR_Continue)
5970 if (
const auto *Inc = FS->
getInc()) {
5971 if (Inc->isValueDependent()) {
5975 FullExpressionRAII IncScope(Info);
5983 case Stmt::DeclStmtClass: {
5987 for (
const auto *D : DS->
decls()) {
5988 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
5991 if (VD->hasLocalStorage() && !VD->getInit())
5999 return ESR_CaseNotFound;
6003 return ESR_CaseNotFound;
6009 if (
const Expr *E = dyn_cast<Expr>(S)) {
6018 FullExpressionRAII
Scope(Info);
6022 return ESR_Succeeded;
6028 case Stmt::NullStmtClass:
6029 return ESR_Succeeded;
6031 case Stmt::DeclStmtClass: {
6033 for (
const auto *D : DS->
decls()) {
6034 const VarDecl *VD = dyn_cast_or_null<VarDecl>(D);
6038 FullExpressionRAII
Scope(Info);
6040 !Info.noteFailure())
6042 if (!
Scope.destroy())
6045 return ESR_Succeeded;
6048 case Stmt::ReturnStmtClass: {
6050 FullExpressionRAII
Scope(Info);
6059 :
Evaluate(Result.Value, Info, RetExpr)))
6061 return Scope.destroy() ? ESR_Returned : ESR_Failed;
6064 case Stmt::CompoundStmtClass: {
6065 BlockScopeRAII
Scope(Info);
6068 for (
const auto *BI : CS->
body()) {
6069 EvalStmtResult ESR =
EvaluateStmt(Result, Info, BI, Case);
6070 if (ESR == ESR_Succeeded)
6072 else if (ESR != ESR_CaseNotFound) {
6073 if (ESR != ESR_Failed && !
Scope.destroy())
6079 return ESR_CaseNotFound;
6080 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
6083 case Stmt::IfStmtClass: {
6087 BlockScopeRAII
Scope(Info);
6090 if (ESR != ESR_Succeeded) {
6091 if (ESR != ESR_Failed && !
Scope.destroy())
6101 if (!Info.InConstantContext)
6108 EvalStmtResult ESR =
EvaluateStmt(Result, Info, SubStmt);
6109 if (ESR != ESR_Succeeded) {
6110 if (ESR != ESR_Failed && !
Scope.destroy())
6115 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
6118 case Stmt::WhileStmtClass: {
6121 BlockScopeRAII
Scope(Info);
6133 if (ESR != ESR_Continue) {
6134 if (ESR != ESR_Failed && !
Scope.destroy())
6138 if (!
Scope.destroy())
6141 return ESR_Succeeded;
6144 case Stmt::DoStmtClass: {
6151 if (ESR != ESR_Continue)
6160 FullExpressionRAII CondScope(Info);
6162 !CondScope.destroy())
6165 return ESR_Succeeded;
6168 case Stmt::ForStmtClass: {
6170 BlockScopeRAII ForScope(Info);
6173 if (ESR != ESR_Succeeded) {
6174 if (ESR != ESR_Failed && !ForScope.destroy())
6180 BlockScopeRAII IterScope(Info);
6181 bool Continue =
true;
6187 if (!IterScope.destroy())
6195 if (ESR != ESR_Continue) {
6196 if (ESR != ESR_Failed && (!IterScope.destroy() || !ForScope.destroy()))
6201 if (
const auto *Inc = FS->
getInc()) {
6202 if (Inc->isValueDependent()) {
6206 FullExpressionRAII IncScope(Info);
6212 if (!IterScope.destroy())
6215 return ForScope.destroy() ? ESR_Succeeded : ESR_Failed;
6218 case Stmt::CXXForRangeStmtClass: {
6220 BlockScopeRAII
Scope(Info);
6225 if (ESR != ESR_Succeeded) {
6226 if (ESR != ESR_Failed && !
Scope.destroy())
6234 if (ESR != ESR_Succeeded) {
6235 if (ESR != ESR_Failed && !
Scope.destroy())
6247 if (ESR != ESR_Succeeded) {
6248 if (ESR != ESR_Failed && !
Scope.destroy())
6253 if (ESR != ESR_Succeeded) {
6254 if (ESR != ESR_Failed && !
Scope.destroy())
6267 bool Continue =
true;
6268 FullExpressionRAII CondExpr(Info);
6276 BlockScopeRAII InnerScope(Info);
6278 if (ESR != ESR_Succeeded) {
6279 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
6288 if (ESR != ESR_Continue) {
6289 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
6302 if (!InnerScope.destroy())
6306 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
6309 case Stmt::SwitchStmtClass:
6312 case Stmt::ContinueStmtClass:
6313 case Stmt::BreakStmtClass: {
6315 Info.BreakContinueStack.push_back(B->getNamedLoopOrSwitch());
6319 case Stmt::LabelStmtClass:
6322 case Stmt::AttributedStmtClass: {
6324 const auto *SS = AS->getSubStmt();
6325 MSConstexprContextRAII ConstexprContext(
6329 auto LO = Info.getASTContext().getLangOpts();
6330 if (LO.CXXAssumptions && !LO.MSVCCompat) {
6331 for (
auto *
Attr : AS->getAttrs()) {
6332 auto *AA = dyn_cast<CXXAssumeAttr>(
Attr);
6336 auto *Assumption = AA->getAssumption();
6337 if (Assumption->isValueDependent())
6340 if (Assumption->HasSideEffects(Info.getASTContext()))
6347 Info.CCEDiag(Assumption->getExprLoc(),
6348 diag::note_constexpr_assumption_failed);
6357 case Stmt::CaseStmtClass:
6358 case Stmt::DefaultStmtClass:
6360 case Stmt::CXXTryStmtClass:
6372 bool IsValueInitialization) {
6379 if (!CD->
isConstexpr() && !IsValueInitialization) {
6380 if (Info.getLangOpts().CPlusPlus11) {
6383 Info.CCEDiag(Loc, diag::note_constexpr_invalid_function, 1)
6385 Info.Note(CD->
getLocation(), diag::note_declared_at);
6387 Info.CCEDiag(Loc, diag::note_invalid_subexpr_in_const_expr);
6401 if (Info.checkingPotentialConstantExpression() && !
Definition &&
6409 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6418 Info.CCEDiag(CallLoc, diag::note_constexpr_virtual_call);
6421 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6427 (
Definition->isConstexpr() || (Info.CurrentCall->CanEvalMSConstexpr &&
6437 StringRef Name = DiagDecl->
getName();
6439 Name ==
"__assert_rtn" || Name ==
"__assert_fail" || Name ==
"_wassert";
6441 Info.FFDiag(CallLoc, diag::note_constexpr_assert_failed);
6446 if (Info.getLangOpts().CPlusPlus11) {
6449 auto *CD = dyn_cast<CXXConstructorDecl>(DiagDecl);
6450 if (CD && CD->isInheritingConstructor()) {
6451 auto *Inherited = CD->getInheritedConstructor().getConstructor();
6452 if (!Inherited->isConstexpr())
6453 DiagDecl = CD = Inherited;
6459 if (CD && CD->isInheritingConstructor())
6460 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_inhctor, 1)
6461 << CD->getInheritedConstructor().getConstructor()->getParent();
6463 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_function, 1)
6465 Info.Note(DiagDecl->
getLocation(), diag::note_declared_at);
6467 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6473struct CheckDynamicTypeHandler {
6475 typedef bool result_type;
6476 bool failed() {
return false; }
6477 bool found(
APValue &Subobj, QualType SubobjType) {
return true; }
6478 bool found(
APSInt &
Value, QualType SubobjType) {
return true; }
6479 bool found(APFloat &
Value, QualType SubobjType) {
return true; }
6487 if (
This.Designator.Invalid)
6499 if (
This.Designator.isOnePastTheEnd() ||
6500 This.Designator.isMostDerivedAnUnsizedArray()) {
6501 Info.FFDiag(E,
This.Designator.isOnePastTheEnd()
6502 ? diag::note_constexpr_access_past_end
6503 : diag::note_constexpr_access_unsized_array)
6506 }
else if (Polymorphic) {
6509 if (!Info.checkingPotentialConstantExpression() ||
6510 !
This.AllowConstexprUnknown) {
6515 Info.FFDiag(E, diag::note_constexpr_polymorphic_unknown_dynamic_type)
6523 CheckDynamicTypeHandler Handler{AK};
6546 unsigned PathLength) {
6547 assert(PathLength >=
Designator.MostDerivedPathLength && PathLength <=
6548 Designator.Entries.size() &&
"invalid path length");
6549 return (PathLength ==
Designator.MostDerivedPathLength)
6550 ?
Designator.MostDerivedType->getAsCXXRecordDecl()
6551 : getAsBaseClass(
Designator.Entries[PathLength - 1]);
6564 return std::nullopt;
6566 if (
This.Designator.Invalid)
6567 return std::nullopt;
6576 This.Designator.MostDerivedType->getAsCXXRecordDecl();
6577 if (!Class || Class->getNumVBases()) {
6579 return std::nullopt;
6587 for (
unsigned PathLength =
This.Designator.MostDerivedPathLength;
6588 PathLength <= Path.size(); ++PathLength) {
6589 switch (Info.isEvaluatingCtorDtor(
This.getLValueBase(),
6590 Path.slice(0, PathLength))) {
6591 case ConstructionPhase::Bases:
6592 case ConstructionPhase::DestroyingBases:
6597 case ConstructionPhase::None:
6598 case ConstructionPhase::AfterBases:
6599 case ConstructionPhase::AfterFields:
6600 case ConstructionPhase::Destroying:
6612 return std::nullopt;
6630 unsigned PathLength = DynType->PathLength;
6631 for (; PathLength <=
This.Designator.Entries.size(); ++PathLength) {
6634 Found->getCorrespondingMethodDeclaredInClass(Class,
false);
6644 if (Callee->isPureVirtual()) {
6645 Info.FFDiag(E, diag::note_constexpr_pure_virtual_call, 1) << Callee;
6646 Info.Note(Callee->getLocation(), diag::note_declared_at);
6653 Found->getReturnType())) {
6654 CovariantAdjustmentPath.push_back(Callee->getReturnType());
6655 for (
unsigned CovariantPathLength = PathLength + 1;
6656 CovariantPathLength !=
This.Designator.Entries.size();
6657 ++CovariantPathLength) {
6661 Found->getCorrespondingMethodDeclaredInClass(NextClass,
false);
6663 Next->getReturnType(), CovariantAdjustmentPath.back()))
6664 CovariantAdjustmentPath.push_back(
Next->getReturnType());
6667 CovariantAdjustmentPath.back()))
6668 CovariantAdjustmentPath.push_back(
Found->getReturnType());
6684 assert(Result.isLValue() &&
6685 "unexpected kind of APValue for covariant return");
6686 if (Result.isNullPointer())
6690 LVal.setFrom(Info.Ctx, Result);
6692 const CXXRecordDecl *OldClass = Path[0]->getPointeeCXXRecordDecl();
6693 for (
unsigned I = 1; I != Path.size(); ++I) {
6694 const CXXRecordDecl *NewClass = Path[I]->getPointeeCXXRecordDecl();
6695 assert(OldClass && NewClass &&
"unexpected kind of covariant return");
6696 if (OldClass != NewClass &&
6699 OldClass = NewClass;
6702 LVal.moveInto(Result);
6711 auto *BaseClass = BaseSpec.getType()->getAsCXXRecordDecl();
6713 return BaseSpec.getAccessSpecifier() ==
AS_public;
6715 llvm_unreachable(
"Base is not a direct base of Derived");
6725 SubobjectDesignator &D = Ptr.Designator;
6731 if (Ptr.isNullPointer() && !E->
isGLValue())
6737 std::optional<DynamicType> DynType =
6749 assert(
C &&
"dynamic_cast target is not void pointer nor class");
6757 Ptr.setNull(Info.Ctx, E->
getType());
6764 DynType->Type->isDerivedFrom(
C)))
6766 else if (!Paths || Paths->begin() == Paths->end())
6768 else if (Paths->isAmbiguous(CQT))
6771 assert(Paths->front().Access !=
AS_public &&
"why did the cast fail?");
6774 Info.FFDiag(E, diag::note_constexpr_dynamic_cast_to_reference_failed)
6775 << DiagKind << Ptr.Designator.getType(Info.Ctx)
6784 for (
int PathLength = Ptr.Designator.Entries.size();
6785 PathLength >= (
int)DynType->PathLength; --PathLength) {
6790 if (PathLength > (
int)DynType->PathLength &&
6793 return RuntimeCheckFailed(
nullptr);
6800 if (DynType->Type->isDerivedFrom(
C, Paths) && !Paths.
isAmbiguous(CQT) &&
6813 return RuntimeCheckFailed(&Paths);
6817struct StartLifetimeOfUnionMemberHandler {
6819 const Expr *LHSExpr;
6820 const FieldDecl *
Field;
6822 bool Failed =
false;
6825 typedef bool result_type;
6826 bool failed() {
return Failed; }
6827 bool found(
APValue &Subobj, QualType SubobjType) {
6842 }
else if (DuringInit) {
6846 Info.FFDiag(LHSExpr,
6847 diag::note_constexpr_union_member_change_during_init);
6856 llvm_unreachable(
"wrong value kind for union object");
6858 bool found(APFloat &
Value, QualType SubobjType) {
6859 llvm_unreachable(
"wrong value kind for union object");
6864const AccessKinds StartLifetimeOfUnionMemberHandler::AccessKind;
6871 const Expr *LHSExpr,
6872 const LValue &LHS) {
6873 if (LHS.InvalidBase || LHS.Designator.Invalid)
6879 unsigned PathLength = LHS.Designator.Entries.size();
6880 for (
const Expr *E = LHSExpr; E !=
nullptr;) {
6882 if (
auto *ME = dyn_cast<MemberExpr>(E)) {
6883 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
6886 if (!FD || FD->getType()->isReferenceType())
6890 if (FD->getParent()->isUnion()) {
6895 FD->getType()->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
6896 if (!RD || RD->hasTrivialDefaultConstructor())
6897 UnionPathLengths.push_back({PathLength - 1, FD});
6903 LHS.Designator.Entries[PathLength]
6904 .getAsBaseOrMember().getPointer()));
6908 }
else if (
auto *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
6910 auto *
Base = ASE->getBase()->IgnoreImplicit();
6911 if (!
Base->getType()->isArrayType())
6917 }
else if (
auto *ICE = dyn_cast<ImplicitCastExpr>(E)) {
6920 if (ICE->getCastKind() == CK_NoOp)
6922 if (ICE->getCastKind() != CK_DerivedToBase &&
6923 ICE->getCastKind() != CK_UncheckedDerivedToBase)
6927 if (Elt->isVirtual()) {
6936 LHS.Designator.Entries[PathLength]
6937 .getAsBaseOrMember().getPointer()));
6947 if (UnionPathLengths.empty())
6952 CompleteObject Obj =
6956 for (std::pair<unsigned, const FieldDecl *> LengthAndField :
6957 llvm::reverse(UnionPathLengths)) {
6959 SubobjectDesignator D = LHS.Designator;
6960 D.truncate(Info.Ctx, LHS.Base, LengthAndField.first);
6962 bool DuringInit = Info.isEvaluatingCtorDtor(LHS.Base, D.Entries) ==
6963 ConstructionPhase::AfterBases;
6964 StartLifetimeOfUnionMemberHandler StartLifetime{
6965 Info, LHSExpr, LengthAndField.second, DuringInit};
6974 CallRef
Call, EvalInfo &Info,
bool NonNull =
false,
6975 APValue **EvaluatedArg =
nullptr) {
6982 APValue &
V = PVD ? Info.CurrentCall->createParam(
Call, PVD, LV)
6983 : Info.CurrentCall->createTemporary(Arg, Arg->
getType(),
6984 ScopeKind::Call, LV);
6990 if (
NonNull &&
V.isLValue() &&
V.isNullPointer()) {
6991 Info.CCEDiag(Arg, diag::note_non_null_attribute_failed);
7004 bool RightToLeft =
false,
7005 LValue *ObjectArg =
nullptr) {
7007 llvm::SmallBitVector ForbiddenNullArgs;
7008 if (Callee->hasAttr<NonNullAttr>()) {
7009 ForbiddenNullArgs.resize(Args.size());
7010 for (
const auto *
Attr : Callee->specific_attrs<NonNullAttr>()) {
7011 if (!
Attr->args_size()) {
7012 ForbiddenNullArgs.set();
7015 for (
auto Idx :
Attr->args()) {
7016 unsigned ASTIdx = Idx.getASTIndex();
7017 if (ASTIdx >= Args.size())
7019 ForbiddenNullArgs[ASTIdx] =
true;
7023 for (
unsigned I = 0; I < Args.size(); I++) {
7024 unsigned Idx = RightToLeft ? Args.size() - I - 1 : I;
7026 Idx < Callee->getNumParams() ? Callee->getParamDecl(Idx) :
nullptr;
7027 bool NonNull = !ForbiddenNullArgs.empty() && ForbiddenNullArgs[Idx];
7032 if (!Info.noteFailure())
7037 ObjectArg->setFrom(Info.Ctx, *That);
7046 bool CopyObjectRepresentation) {
7048 CallStackFrame *Frame = Info.CurrentCall;
7049 APValue *RefValue = Info.getParamSlot(Frame->Arguments, Param);
7057 RefLValue.setFrom(Info.Ctx, *RefValue);
7060 CopyObjectRepresentation);
7066 const LValue *ObjectArg,
const Expr *E,
7068 const Stmt *Body, EvalInfo &Info,
7069 APValue &Result,
const LValue *ResultSlot) {
7070 if (!Info.CheckCallLimit(CallLoc))
7099 ObjectArg->moveInto(Result);
7108 if (!Info.checkingPotentialConstantExpression())
7110 Frame.LambdaThisCaptureField);
7113 StmtResult Ret = {Result, ResultSlot};
7115 if (ESR == ESR_Succeeded) {
7116 if (Callee->getReturnType()->isVoidType())
7118 Info.FFDiag(Callee->getEndLoc(), diag::note_constexpr_no_return);
7120 return ESR == ESR_Returned;
7127 EvalInfo &Info,
APValue &Result) {
7129 if (!Info.CheckCallLimit(CallLoc))
7134 Info.FFDiag(CallLoc, diag::note_constexpr_virtual_base) << RD;
7138 EvalInfo::EvaluatingConstructorRAII EvalObj(
7140 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries},
7147 StmtResult Ret = {RetVal,
nullptr};
7152 if ((*I)->getInit()->isValueDependent()) {
7156 FullExpressionRAII InitScope(Info);
7158 !InitScope.destroy())
7181 if (!Result.hasValue()) {
7194 BlockScopeRAII LifetimeExtendedScope(Info);
7197 unsigned BasesSeen = 0;
7202 auto SkipToField = [&](
FieldDecl *FD,
bool Indirect) {
7207 assert(Indirect &&
"fields out of order?");
7213 assert(FieldIt != RD->
field_end() &&
"missing field?");
7214 if (!FieldIt->isUnnamedBitField())
7217 Result.getStructField(FieldIt->getFieldIndex()));
7222 LValue Subobject =
This;
7223 LValue SubobjectParent =
This;
7228 if (I->isBaseInitializer()) {
7229 QualType BaseType(I->getBaseClass(), 0);
7233 assert(!BaseIt->
isVirtual() &&
"virtual base for literal type");
7235 "base class initializers not in expected order");
7239 BaseType->getAsCXXRecordDecl(), &Layout))
7241 Value = &Result.getStructBase(BasesSeen++);
7242 }
else if ((FD = I->getMember())) {
7247 Value = &Result.getUnionValue();
7249 SkipToField(FD,
false);
7255 auto IndirectFieldChain = IFD->chain();
7256 for (
auto *
C : IndirectFieldChain) {
7265 (
Value->isUnion() &&
7278 if (
C == IndirectFieldChain.back())
7279 SubobjectParent = Subobject;
7285 if (
C == IndirectFieldChain.front() && !RD->
isUnion())
7286 SkipToField(FD,
true);
7291 llvm_unreachable(
"unknown base initializer kind");
7298 if (
Init->isValueDependent()) {
7302 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &SubobjectParent,
7304 FullExpressionRAII InitScope(Info);
7310 if (!Info.noteFailure())
7319 if (!Info.noteFailure())
7327 if (I->isBaseInitializer() && BasesSeen == RD->
getNumBases())
7328 EvalObj.finishedConstructingBases();
7333 for (; FieldIt != RD->
field_end(); ++FieldIt) {
7334 if (!FieldIt->isUnnamedBitField())
7337 Result.getStructField(FieldIt->getFieldIndex()));
7341 EvalObj.finishedConstructingFields();
7345 LifetimeExtendedScope.destroy();
7351 EvalInfo &Info,
APValue &Result) {
7352 CallScopeRAII CallScope(Info);
7358 CallScope.destroy();
7368 if (
Value.isAbsent() && !
T->isNullPtrType()) {
7370 This.moveInto(Printable);
7372 diag::note_constexpr_destroy_out_of_lifetime)
7389 LValue ElemLV =
This;
7390 ElemLV.addArray(Info, &LocE, CAT);
7397 if (Size && Size >
Value.getArrayInitializedElts())
7402 for (Size =
Value.getArraySize(); Size != 0; --Size) {
7403 APValue &Elem =
Value.getArrayInitializedElt(Size - 1);
7416 if (
T.isDestructedType()) {
7418 diag::note_constexpr_unsupported_destruction)
7428 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_virtual_base) << RD;
7453 if (!Info.CheckCallLimit(CallRange.
getBegin()))
7462 CallStackFrame Frame(Info, CallRange,
Definition, &
This,
nullptr,
7467 EvalInfo::EvaluatingDestructorRAII EvalObj(
7469 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries});
7470 if (!EvalObj.DidInsert) {
7477 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_double_destroy);
7484 StmtResult Ret = {RetVal,
nullptr};
7497 for (
const FieldDecl *FD : llvm::reverse(Fields)) {
7498 if (FD->isUnnamedBitField())
7501 LValue Subobject =
This;
7505 APValue *SubobjectValue = &
Value.getStructField(FD->getFieldIndex());
7512 EvalObj.startedDestroyingBases();
7519 LValue Subobject =
This;
7521 BaseType->getAsCXXRecordDecl(), &Layout))
7524 APValue *SubobjectValue = &
Value.getStructBase(BasesLeft);
7529 assert(BasesLeft == 0 &&
"NumBases was wrong?");
7537struct DestroyObjectHandler {
7543 typedef bool result_type;
7544 bool failed() {
return false; }
7545 bool found(
APValue &Subobj, QualType SubobjType) {
7550 Info.FFDiag(E, diag::note_constexpr_destroy_complex_elem);
7553 bool found(APFloat &
Value, QualType SubobjType) {
7554 Info.FFDiag(E, diag::note_constexpr_destroy_complex_elem);
7586 if (Info.checkingPotentialConstantExpression() ||
7587 Info.SpeculativeEvaluationDepth)
7591 auto Caller = Info.getStdAllocatorCaller(
"allocate");
7593 Info.FFDiag(E->
getExprLoc(), Info.getLangOpts().CPlusPlus20
7594 ? diag::note_constexpr_new_untyped
7595 : diag::note_constexpr_new);
7599 QualType ElemType = Caller.ElemType;
7602 diag::note_constexpr_new_not_complete_object_type)
7610 bool IsNothrow =
false;
7611 for (
unsigned I = 1, N = E->
getNumArgs(); I != N; ++I) {
7619 APInt Size, Remainder;
7620 APInt ElemSizeAP(ByteSize.getBitWidth(), ElemSize.
getQuantity());
7621 APInt::udivrem(ByteSize, ElemSizeAP, Size, Remainder);
7622 if (Remainder != 0) {
7624 Info.FFDiag(E->
getExprLoc(), diag::note_constexpr_operator_new_bad_size)
7625 << ByteSize <<
APSInt(ElemSizeAP,
true) << ElemType;
7629 if (!Info.CheckArraySize(E->
getBeginLoc(), ByteSize.getActiveBits(),
7630 Size.getZExtValue(), !IsNothrow)) {
7632 Result.setNull(Info.Ctx, E->
getType());
7640 APValue *Val = Info.createHeapAlloc(Caller.Call, AllocType, Result);
7649 return DD->isVirtual();
7656 return DD->isVirtual() ? DD->getOperatorDelete() :
nullptr;
7667 DynAlloc::Kind DeallocKind) {
7668 auto PointerAsString = [&] {
7674 Info.FFDiag(E, diag::note_constexpr_delete_not_heap_alloc)
7675 << PointerAsString();
7678 return std::nullopt;
7681 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
7683 Info.FFDiag(E, diag::note_constexpr_double_delete);
7684 return std::nullopt;
7687 if (DeallocKind != (*Alloc)->getKind()) {
7689 Info.FFDiag(E, diag::note_constexpr_new_delete_mismatch)
7690 << DeallocKind << (*Alloc)->getKind() << AllocType;
7692 return std::nullopt;
7695 bool Subobject =
false;
7696 if (DeallocKind == DynAlloc::New) {
7697 Subobject =
Pointer.Designator.MostDerivedPathLength != 0 ||
7698 Pointer.Designator.isOnePastTheEnd();
7700 Subobject =
Pointer.Designator.Entries.size() != 1 ||
7701 Pointer.Designator.Entries[0].getAsArrayIndex() != 0;
7704 Info.FFDiag(E, diag::note_constexpr_delete_subobject)
7705 << PointerAsString() <<
Pointer.Designator.isOnePastTheEnd();
7706 return std::nullopt;
7714 if (Info.checkingPotentialConstantExpression() ||
7715 Info.SpeculativeEvaluationDepth)
7719 if (!Info.getStdAllocatorCaller(
"deallocate")) {
7727 for (
unsigned I = 1, N = E->
getNumArgs(); I != N; ++I)
7730 if (
Pointer.Designator.Invalid)
7735 if (
Pointer.isNullPointer()) {
7736 Info.CCEDiag(E->
getExprLoc(), diag::note_constexpr_deallocate_null);
7752class BitCastBuffer {
7758 SmallVector<std::optional<unsigned char>, 32> Bytes;
7760 static_assert(std::numeric_limits<unsigned char>::digits >= 8,
7761 "Need at least 8 bit unsigned char");
7763 bool TargetIsLittleEndian;
7766 BitCastBuffer(CharUnits Width,
bool TargetIsLittleEndian)
7767 : Bytes(Width.getQuantity()),
7768 TargetIsLittleEndian(TargetIsLittleEndian) {}
7770 [[nodiscard]]
bool readObject(CharUnits Offset, CharUnits Width,
7771 SmallVectorImpl<unsigned char> &Output)
const {
7772 for (CharUnits I = Offset, E = Offset + Width; I != E; ++I) {
7775 if (!Bytes[I.getQuantity()])
7777 Output.push_back(*Bytes[I.getQuantity()]);
7779 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
7780 std::reverse(Output.begin(), Output.end());
7784 void writeObject(CharUnits Offset, SmallVectorImpl<unsigned char> &Input) {
7785 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
7786 std::reverse(Input.begin(), Input.end());
7789 for (
unsigned char Byte : Input) {
7790 assert(!Bytes[Offset.
getQuantity() + Index] &&
"overwriting a byte?");
7796 size_t size() {
return Bytes.size(); }
7801class APValueToBufferConverter {
7803 BitCastBuffer Buffer;
7806 APValueToBufferConverter(EvalInfo &Info, CharUnits ObjectWidth,
7809 Buffer(ObjectWidth, Info.Ctx.getTargetInfo().isLittleEndian()),
7812 bool visit(
const APValue &Val, QualType Ty) {
7817 bool visit(
const APValue &Val, QualType Ty, CharUnits Offset) {
7818 assert((
size_t)Offset.
getQuantity() <= Buffer.size());
7831 return visitInt(Val.
getInt(), Ty, Offset);
7833 return visitFloat(Val.
getFloat(), Ty, Offset);
7835 return visitArray(Val, Ty, Offset);
7837 return visitRecord(Val, Ty, Offset);
7839 return visitVector(Val, Ty, Offset);
7843 return visitComplex(Val, Ty, Offset);
7851 diag::note_constexpr_bit_cast_unsupported_type)
7857 llvm_unreachable(
"LValue subobject in bit_cast?");
7859 llvm_unreachable(
"Unhandled APValue::ValueKind");
7862 bool visitRecord(
const APValue &Val, QualType Ty, CharUnits Offset) {
7867 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
7868 for (
size_t I = 0, E = CXXRD->getNumBases(); I != E; ++I) {
7869 const CXXBaseSpecifier &BS = CXXRD->bases_begin()[I];
7874 if (!
Base.isStruct())
7877 if (!visitRecord(Base, BS.
getType(),
7884 unsigned FieldIdx = 0;
7885 for (FieldDecl *FD : RD->
fields()) {
7886 if (FD->isBitField()) {
7888 diag::note_constexpr_bit_cast_unsupported_bitfield);
7894 assert(FieldOffsetBits % Info.Ctx.
getCharWidth() == 0 &&
7895 "only bit-fields can have sub-char alignment");
7896 CharUnits FieldOffset =
7898 QualType FieldTy = FD->getType();
7907 bool visitArray(
const APValue &Val, QualType Ty, CharUnits Offset) {
7917 for (
unsigned I = 0; I != NumInitializedElts; ++I) {
7919 if (!visit(SubObj, CAT->
getElementType(), Offset + I * ElemWidth))
7926 for (
unsigned I = NumInitializedElts; I != ArraySize; ++I) {
7927 if (!visit(Filler, CAT->
getElementType(), Offset + I * ElemWidth))
7935 bool visitComplex(
const APValue &Val, QualType Ty, CharUnits Offset) {
7936 const ComplexType *ComplexTy = Ty->
castAs<ComplexType>();
7943 Offset + (0 * EltSizeChars)))
7946 Offset + (1 * EltSizeChars)))
7950 Offset + (0 * EltSizeChars)))
7953 Offset + (1 * EltSizeChars)))
7960 bool visitVector(
const APValue &Val, QualType Ty, CharUnits Offset) {
7961 const VectorType *VTy = Ty->
castAs<VectorType>();
7976 llvm::APInt Res = llvm::APInt::getZero(NElts);
7977 for (
unsigned I = 0; I < NElts; ++I) {
7979 assert(EltAsInt.isUnsigned() && EltAsInt.getBitWidth() == 1 &&
7980 "bool vector element must be 1-bit unsigned integer!");
7982 Res.insertBits(EltAsInt, BigEndian ? (NElts - I - 1) : I);
7985 SmallVector<uint8_t, 8> Bytes(NElts / 8);
7986 llvm::StoreIntToMemory(Res, &*Bytes.begin(), NElts / 8);
7987 Buffer.writeObject(Offset, Bytes);
7992 for (
unsigned I = 0; I < NElts; ++I) {
7993 if (!visit(Val.
getVectorElt(I), EltTy, Offset + I * EltSizeChars))
8001 bool visitInt(
const APSInt &Val, QualType Ty, CharUnits Offset) {
8002 APSInt AdjustedVal = Val;
8003 unsigned Width = AdjustedVal.getBitWidth();
8006 AdjustedVal = AdjustedVal.extend(Width);
8009 SmallVector<uint8_t, 8> Bytes(Width / 8);
8010 llvm::StoreIntToMemory(AdjustedVal, &*Bytes.begin(), Width / 8);
8011 Buffer.writeObject(Offset, Bytes);
8015 bool visitFloat(
const APFloat &Val, QualType Ty, CharUnits Offset) {
8016 APSInt AsInt(Val.bitcastToAPInt());
8017 return visitInt(AsInt, Ty, Offset);
8021 static std::optional<BitCastBuffer>
8024 APValueToBufferConverter Converter(Info, DstSize, BCE);
8026 return std::nullopt;
8027 return Converter.Buffer;
8032class BufferToAPValueConverter {
8034 const BitCastBuffer &Buffer;
8037 BufferToAPValueConverter(EvalInfo &Info,
const BitCastBuffer &Buffer,
8039 : Info(Info), Buffer(Buffer), BCE(BCE) {}
8044 std::nullopt_t unsupportedType(QualType Ty) {
8046 diag::note_constexpr_bit_cast_unsupported_type)
8048 return std::nullopt;
8051 std::nullopt_t unrepresentableValue(QualType Ty,
const APSInt &Val) {
8053 diag::note_constexpr_bit_cast_unrepresentable_value)
8055 return std::nullopt;
8058 std::optional<APValue> visit(
const BuiltinType *
T, CharUnits Offset,
8059 const EnumType *EnumSugar =
nullptr) {
8062 return APValue((Expr *)
nullptr,
8064 APValue::NoLValuePath{},
true);
8073 const llvm::fltSemantics &Semantics =
8075 unsigned NumBits = llvm::APFloatBase::getSizeInBits(Semantics);
8076 assert(NumBits % 8 == 0);
8082 SmallVector<uint8_t, 8> Bytes;
8083 if (!Buffer.readObject(Offset,
SizeOf, Bytes)) {
8086 bool IsStdByte = EnumSugar && EnumSugar->isStdByteType();
8090 if (!IsStdByte && !IsUChar) {
8091 QualType DisplayType(EnumSugar ? (
const Type *)EnumSugar :
T, 0);
8093 diag::note_constexpr_bit_cast_indet_dest)
8094 << DisplayType << Info.Ctx.
getLangOpts().CharIsSigned;
8095 return std::nullopt;
8102 llvm::LoadIntFromMemory(Val, &*Bytes.begin(), Bytes.size());
8107 unsigned IntWidth = Info.Ctx.
getIntWidth(QualType(
T, 0));
8108 if (IntWidth != Val.getBitWidth()) {
8109 APSInt Truncated = Val.trunc(IntWidth);
8110 if (Truncated.extend(Val.getBitWidth()) != Val)
8111 return unrepresentableValue(QualType(
T, 0), Val);
8119 const llvm::fltSemantics &Semantics =
8124 return unsupportedType(QualType(
T, 0));
8127 std::optional<APValue> visit(
const RecordType *RTy, CharUnits Offset) {
8128 const RecordDecl *RD = RTy->getAsRecordDecl();
8131 unsigned NumBases = 0;
8132 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
8133 NumBases = CXXRD->getNumBases();
8138 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
8139 for (
size_t I = 0, E = CXXRD->getNumBases(); I != E; ++I) {
8140 const CXXBaseSpecifier &BS = CXXRD->bases_begin()[I];
8143 std::optional<APValue> SubObj = visitType(
8146 return std::nullopt;
8147 ResultVal.getStructBase(I) = *SubObj;
8152 unsigned FieldIdx = 0;
8153 for (FieldDecl *FD : RD->
fields()) {
8156 if (FD->isBitField()) {
8158 diag::note_constexpr_bit_cast_unsupported_bitfield);
8159 return std::nullopt;
8163 assert(FieldOffsetBits % Info.Ctx.
getCharWidth() == 0);
8165 CharUnits FieldOffset =
8168 QualType FieldTy = FD->getType();
8169 std::optional<APValue> SubObj = visitType(FieldTy, FieldOffset);
8171 return std::nullopt;
8172 ResultVal.getStructField(FieldIdx) = *SubObj;
8179 std::optional<APValue> visit(
const EnumType *Ty, CharUnits Offset) {
8180 QualType RepresentationType =
8181 Ty->getDecl()->getDefinitionOrSelf()->getIntegerType();
8182 assert(!RepresentationType.
isNull() &&
8183 "enum forward decl should be caught by Sema");
8184 const auto *AsBuiltin =
8188 return visit(AsBuiltin, Offset, Ty);
8191 std::optional<APValue> visit(
const ConstantArrayType *Ty, CharUnits Offset) {
8195 APValue ArrayValue(APValue::UninitArray(), Size, Size);
8196 for (
size_t I = 0; I !=
Size; ++I) {
8197 std::optional<APValue> ElementValue =
8200 return std::nullopt;
8201 ArrayValue.getArrayInitializedElt(I) = std::move(*ElementValue);
8207 std::optional<APValue> visit(
const ComplexType *Ty, CharUnits Offset) {
8212 std::optional<APValue> Values[2];
8213 for (
unsigned I = 0; I != 2; ++I) {
8214 Values[I] = visitType(Ty->
getElementType(), Offset + I * ElementWidth);
8216 return std::nullopt;
8220 return APValue(Values[0]->getInt(), Values[1]->getInt());
8221 return APValue(Values[0]->getFloat(), Values[1]->getFloat());
8224 std::optional<APValue> visit(
const VectorType *VTy, CharUnits Offset) {
8230 SmallVector<APValue, 4> Elts;
8231 Elts.reserve(NElts);
8243 SmallVector<uint8_t, 8> Bytes;
8244 Bytes.reserve(NElts / 8);
8246 return std::nullopt;
8248 APSInt SValInt(NElts,
true);
8249 llvm::LoadIntFromMemory(SValInt, &*Bytes.begin(), Bytes.size());
8251 for (
unsigned I = 0; I < NElts; ++I) {
8253 SValInt.extractBits(1, (BigEndian ? NElts - I - 1 : I) * EltSize);
8261 for (
unsigned I = 0; I < NElts; ++I) {
8262 std::optional<APValue> EltValue =
8263 visitType(EltTy, Offset + I * EltSizeChars);
8265 return std::nullopt;
8266 Elts.push_back(std::move(*EltValue));
8270 return APValue(Elts.data(), Elts.size());
8273 std::optional<APValue> visit(
const Type *Ty, CharUnits Offset) {
8274 return unsupportedType(QualType(Ty, 0));
8277 std::optional<APValue> visitType(QualType Ty, CharUnits Offset) {
8281#define TYPE(Class, Base) \
8283 return visit(cast<Class##Type>(Can.getTypePtr()), Offset);
8284#define ABSTRACT_TYPE(Class, Base)
8285#define NON_CANONICAL_TYPE(Class, Base) \
8287 llvm_unreachable("non-canonical type should be impossible!");
8288#define DEPENDENT_TYPE(Class, Base) \
8291 "dependent types aren't supported in the constant evaluator!");
8292#define NON_CANONICAL_UNLESS_DEPENDENT(Class, Base) \
8294 llvm_unreachable("either dependent or not canonical!");
8295#include "clang/AST/TypeNodes.inc"
8297 llvm_unreachable(
"Unhandled Type::TypeClass");
8302 static std::optional<APValue> convert(EvalInfo &Info, BitCastBuffer &Buffer,
8304 BufferToAPValueConverter Converter(Info, Buffer, BCE);
8309static bool checkBitCastConstexprEligibilityType(SourceLocation Loc,
8310 QualType Ty, EvalInfo *Info,
8311 const ASTContext &Ctx,
8312 bool CheckingDest) {
8315 auto diag = [&](
int Reason) {
8317 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_invalid_type)
8318 << CheckingDest << (Reason == 4) << Reason;
8321 auto note = [&](
int Construct, QualType NoteTy, SourceLocation NoteLoc) {
8323 Info->Note(NoteLoc, diag::note_constexpr_bit_cast_invalid_subtype)
8324 << NoteTy << Construct << Ty;
8338 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(
Record)) {
8339 for (CXXBaseSpecifier &BS : CXXRD->bases())
8340 if (!checkBitCastConstexprEligibilityType(Loc, BS.
getType(), Info, Ctx,
8344 for (FieldDecl *FD :
Record->fields()) {
8345 if (FD->getType()->isReferenceType())
8347 if (!checkBitCastConstexprEligibilityType(Loc, FD->getType(), Info, Ctx,
8349 return note(0, FD->getType(), FD->getBeginLoc());
8355 Info, Ctx, CheckingDest))
8358 if (
const auto *VTy = Ty->
getAs<VectorType>()) {
8370 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_invalid_vector)
8371 << QualType(VTy, 0) << EltSize << NElts << Ctx.
getCharWidth();
8381 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_unsupported_type)
8390static bool checkBitCastConstexprEligibility(EvalInfo *Info,
8391 const ASTContext &Ctx,
8393 bool DestOK = checkBitCastConstexprEligibilityType(
8395 bool SourceOK = DestOK && checkBitCastConstexprEligibilityType(
8401static bool handleRValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
8405 "no host or target supports non 8-bit chars");
8407 if (!checkBitCastConstexprEligibility(&Info, Info.Ctx, BCE))
8411 std::optional<BitCastBuffer> Buffer =
8412 APValueToBufferConverter::convert(Info, SourceRValue, BCE);
8417 std::optional<APValue> MaybeDestValue =
8418 BufferToAPValueConverter::convert(Info, *Buffer, BCE);
8419 if (!MaybeDestValue)
8422 DestValue = std::move(*MaybeDestValue);
8426static bool handleLValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
8430 "no host or target supports non 8-bit chars");
8432 "LValueToRValueBitcast requires an lvalue operand!");
8434 LValue SourceLValue;
8436 SourceLValue.setFrom(Info.Ctx, SourceValue);
8439 SourceRValue,
true))
8442 return handleRValueToRValueBitCast(Info, DestValue, SourceRValue, BCE);
8445template <
class Derived>
8446class ExprEvaluatorBase
8447 :
public ConstStmtVisitor<Derived, bool> {
8449 Derived &getDerived() {
return static_cast<Derived&
>(*this); }
8450 bool DerivedSuccess(
const APValue &
V,
const Expr *E) {
8451 return getDerived().Success(
V, E);
8453 bool DerivedZeroInitialization(
const Expr *E) {
8454 return getDerived().ZeroInitialization(E);
8460 template<
typename ConditionalOperator>
8461 void CheckPotentialConstantConditional(
const ConditionalOperator *E) {
8462 assert(Info.checkingPotentialConstantExpression());
8465 SmallVector<PartialDiagnosticAt, 8>
Diag;
8467 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
8474 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
8481 Error(E, diag::note_constexpr_conditional_never_const);
8485 template<
typename ConditionalOperator>
8486 bool HandleConditionalOperator(
const ConditionalOperator *E) {
8489 if (Info.checkingPotentialConstantExpression() && Info.noteFailure()) {
8490 CheckPotentialConstantConditional(E);
8493 if (Info.noteFailure()) {
8501 return StmtVisitorTy::Visit(EvalExpr);
8506 typedef ConstStmtVisitor<Derived, bool> StmtVisitorTy;
8507 typedef ExprEvaluatorBase ExprEvaluatorBaseTy;
8509 OptionalDiagnostic CCEDiag(
const Expr *E,
diag::kind D) {
8510 return Info.CCEDiag(E, D);
8513 bool ZeroInitialization(
const Expr *E) {
return Error(E); }
8515 bool IsConstantEvaluatedBuiltinCall(
const CallExpr *E) {
8517 return BuiltinOp != 0 &&
8522 ExprEvaluatorBase(EvalInfo &Info) : Info(Info) {}
8524 EvalInfo &getEvalInfo() {
return Info; }
8532 bool Error(
const Expr *E) {
8533 return Error(E, diag::note_invalid_subexpr_in_const_expr);
8536 bool VisitStmt(
const Stmt *) {
8537 llvm_unreachable(
"Expression evaluator should not be called on stmts");
8539 bool VisitExpr(
const Expr *E) {
8543 bool VisitEmbedExpr(
const EmbedExpr *E) {
8544 const auto It = E->
begin();
8545 return StmtVisitorTy::Visit(*It);
8548 bool VisitPredefinedExpr(
const PredefinedExpr *E) {
8551 bool VisitConstantExpr(
const ConstantExpr *E) {
8555 return StmtVisitorTy::Visit(E->
getSubExpr());
8558 bool VisitParenExpr(
const ParenExpr *E)
8559 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8560 bool VisitUnaryExtension(
const UnaryOperator *E)
8561 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8562 bool VisitUnaryPlus(
const UnaryOperator *E)
8563 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8564 bool VisitChooseExpr(
const ChooseExpr *E)
8566 bool VisitGenericSelectionExpr(
const GenericSelectionExpr *E)
8568 bool VisitSubstNonTypeTemplateParmExpr(
const SubstNonTypeTemplateParmExpr *E)
8570 bool VisitCXXDefaultArgExpr(
const CXXDefaultArgExpr *E) {
8571 TempVersionRAII RAII(*Info.CurrentCall);
8572 SourceLocExprScopeGuard Guard(E, Info.CurrentCall->CurSourceLocExprScope);
8573 return StmtVisitorTy::Visit(E->
getExpr());
8575 bool VisitCXXDefaultInitExpr(
const CXXDefaultInitExpr *E) {
8576 TempVersionRAII RAII(*Info.CurrentCall);
8580 SourceLocExprScopeGuard Guard(E, Info.CurrentCall->CurSourceLocExprScope);
8581 return StmtVisitorTy::Visit(E->
getExpr());
8584 bool VisitExprWithCleanups(
const ExprWithCleanups *E) {
8585 FullExpressionRAII Scope(Info);
8586 return StmtVisitorTy::Visit(E->
getSubExpr()) && Scope.destroy();
8591 bool VisitCXXBindTemporaryExpr(
const CXXBindTemporaryExpr *E) {
8592 return StmtVisitorTy::Visit(E->
getSubExpr());
8595 bool VisitCXXReinterpretCastExpr(
const CXXReinterpretCastExpr *E) {
8596 CCEDiag(E, diag::note_constexpr_invalid_cast)
8597 << diag::ConstexprInvalidCastKind::Reinterpret;
8598 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8600 bool VisitCXXDynamicCastExpr(
const CXXDynamicCastExpr *E) {
8602 CCEDiag(E, diag::note_constexpr_invalid_cast)
8603 << diag::ConstexprInvalidCastKind::Dynamic;
8604 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8606 bool VisitBuiltinBitCastExpr(
const BuiltinBitCastExpr *E) {
8607 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8610 bool VisitBinaryOperator(
const BinaryOperator *E) {
8616 VisitIgnoredValue(E->
getLHS());
8617 return StmtVisitorTy::Visit(E->
getRHS());
8627 return DerivedSuccess(
Result, E);
8632 bool VisitCXXRewrittenBinaryOperator(
const CXXRewrittenBinaryOperator *E) {
8636 bool VisitBinaryConditionalOperator(
const BinaryConditionalOperator *E) {
8640 if (!
Evaluate(Info.CurrentCall->createTemporary(
8643 ScopeKind::FullExpression, CommonLV),
8647 return HandleConditionalOperator(E);
8650 bool VisitConditionalOperator(
const ConditionalOperator *E) {
8651 bool IsBcpCall =
false;
8656 if (
const CallExpr *CallCE =
8658 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
8665 if (Info.checkingPotentialConstantExpression() && IsBcpCall)
8668 FoldConstant Fold(Info, IsBcpCall);
8669 if (!HandleConditionalOperator(E)) {
8670 Fold.keepDiagnostics();
8677 bool VisitOpaqueValueExpr(
const OpaqueValueExpr *E) {
8678 if (
APValue *
Value = Info.CurrentCall->getCurrentTemporary(E);
8680 return DerivedSuccess(*
Value, E);
8686 assert(0 &&
"OpaqueValueExpr recursively refers to itself");
8689 return StmtVisitorTy::Visit(Source);
8692 bool VisitPseudoObjectExpr(
const PseudoObjectExpr *E) {
8693 for (
const Expr *SemE : E->
semantics()) {
8694 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
8703 if (OVE->isUnique())
8707 if (!
Evaluate(Info.CurrentCall->createTemporary(
8708 OVE, getStorageType(Info.Ctx, OVE),
8709 ScopeKind::FullExpression, LV),
8710 Info, OVE->getSourceExpr()))
8713 if (!StmtVisitorTy::Visit(SemE))
8723 bool VisitCallExpr(
const CallExpr *E) {
8725 if (!handleCallExpr(E,
Result,
nullptr))
8727 return DerivedSuccess(
Result, E);
8731 const LValue *ResultSlot) {
8732 CallScopeRAII CallScope(Info);
8735 QualType CalleeType =
Callee->getType();
8737 const FunctionDecl *FD =
nullptr;
8738 LValue *
This =
nullptr, ObjectArg;
8740 bool HasQualifier =
false;
8746 const CXXMethodDecl *
Member =
nullptr;
8747 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(Callee)) {
8751 Member = dyn_cast<CXXMethodDecl>(ME->getMemberDecl());
8753 return Error(Callee);
8755 HasQualifier = ME->hasQualifier();
8756 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(Callee)) {
8758 const ValueDecl *D =
8762 Member = dyn_cast<CXXMethodDecl>(D);
8764 return Error(Callee);
8766 }
else if (
const auto *PDE = dyn_cast<CXXPseudoDestructorExpr>(Callee)) {
8767 if (!Info.getLangOpts().CPlusPlus20)
8768 Info.CCEDiag(PDE, diag::note_constexpr_pseudo_destructor);
8772 return Error(Callee);
8779 if (!CalleeLV.getLValueOffset().isZero())
8780 return Error(Callee);
8781 if (CalleeLV.isNullPointer()) {
8782 Info.FFDiag(Callee, diag::note_constexpr_null_callee)
8783 <<
const_cast<Expr *
>(
Callee);
8786 FD = dyn_cast_or_null<FunctionDecl>(
8787 CalleeLV.getLValueBase().dyn_cast<
const ValueDecl *>());
8789 return Error(Callee);
8799 auto *OCE = dyn_cast<CXXOperatorCallExpr>(E);
8800 if (OCE && OCE->isAssignmentOp()) {
8801 assert(Args.size() == 2 &&
"wrong number of arguments in assignment");
8802 Call = Info.CurrentCall->createCall(FD);
8803 bool HasThis =
false;
8804 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FD))
8805 HasThis = MD->isImplicitObjectMemberFunction();
8813 const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD);
8833 if (Info.getLangOpts().CPlusPlus20 && OCE &&
8834 OCE->getOperator() == OO_Equal && MD->
isTrivial() &&
8838 Args = Args.slice(1);
8844 const CXXRecordDecl *ClosureClass = MD->
getParent();
8846 ClosureClass->
captures().empty() &&
8847 "Number of captures must be zero for conversion to function-ptr");
8849 const CXXMethodDecl *LambdaCallOp =
8858 "A generic lambda's static-invoker function must be a "
8859 "template specialization");
8861 FunctionTemplateDecl *CallOpTemplate =
8863 void *InsertPos =
nullptr;
8864 FunctionDecl *CorrespondingCallOpSpecialization =
8866 assert(CorrespondingCallOpSpecialization &&
8867 "We must always have a function call operator specialization "
8868 "that corresponds to our static invoker specialization");
8870 FD = CorrespondingCallOpSpecialization;
8879 return CallScope.destroy();
8889 Call = Info.CurrentCall->createCall(FD);
8895 SmallVector<QualType, 4> CovariantAdjustmentPath;
8897 auto *NamedMember = dyn_cast<CXXMethodDecl>(FD);
8898 if (NamedMember && NamedMember->isVirtual() && !HasQualifier) {
8901 CovariantAdjustmentPath);
8904 }
else if (NamedMember && NamedMember->isImplicitObjectMemberFunction()) {
8914 if (
auto *DD = dyn_cast<CXXDestructorDecl>(FD)) {
8915 assert(This &&
"no 'this' pointer for destructor call");
8918 CallScope.destroy();
8935 if (!CovariantAdjustmentPath.empty() &&
8937 CovariantAdjustmentPath))
8940 return CallScope.destroy();
8943 bool VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E) {
8946 bool VisitInitListExpr(
const InitListExpr *E) {
8948 return DerivedZeroInitialization(E);
8950 return StmtVisitorTy::Visit(E->
getInit(0));
8953 bool VisitImplicitValueInitExpr(
const ImplicitValueInitExpr *E) {
8954 return DerivedZeroInitialization(E);
8956 bool VisitCXXScalarValueInitExpr(
const CXXScalarValueInitExpr *E) {
8957 return DerivedZeroInitialization(E);
8959 bool VisitCXXNullPtrLiteralExpr(
const CXXNullPtrLiteralExpr *E) {
8960 return DerivedZeroInitialization(E);
8964 bool VisitMemberExpr(
const MemberExpr *E) {
8966 "missing temporary materialization conversion");
8967 assert(!E->
isArrow() &&
"missing call to bound member function?");
8975 const FieldDecl *FD = dyn_cast<FieldDecl>(E->
getMemberDecl());
8976 if (!FD)
return Error(E);
8980 "record / field mismatch");
8985 CompleteObject Obj(APValue::LValueBase(), &Val, BaseTy);
8986 SubobjectDesignator Designator(BaseTy);
8987 Designator.addDeclUnchecked(FD);
8991 DerivedSuccess(
Result, E);
8994 bool VisitExtVectorElementExpr(
const ExtVectorElementExpr *E) {
9000 SmallVector<uint32_t, 4> Indices;
9002 if (Indices.size() == 1) {
9004 return DerivedSuccess(Val.
getVectorElt(Indices[0]), E);
9007 SmallVector<APValue, 4> Elts;
9008 for (
unsigned I = 0; I < Indices.size(); ++I) {
9011 APValue VecResult(Elts.data(), Indices.size());
9012 return DerivedSuccess(VecResult, E);
9019 bool VisitCastExpr(
const CastExpr *E) {
9024 case CK_AtomicToNonAtomic: {
9031 return DerivedSuccess(AtomicVal, E);
9035 case CK_UserDefinedConversion:
9036 return StmtVisitorTy::Visit(E->
getSubExpr());
9038 case CK_HLSLArrayRValue: {
9044 return DerivedSuccess(Val, E);
9055 return DerivedSuccess(RVal, E);
9057 case CK_LValueToRValue: {
9066 return DerivedSuccess(RVal, E);
9068 case CK_LValueToRValueBitCast: {
9069 APValue DestValue, SourceValue;
9072 if (!handleLValueToRValueBitCast(Info, DestValue, SourceValue, E))
9074 return DerivedSuccess(DestValue, E);
9077 case CK_AddressSpaceConversion: {
9081 return DerivedSuccess(
Value, E);
9088 bool VisitUnaryPostInc(
const UnaryOperator *UO) {
9089 return VisitUnaryPostIncDec(UO);
9091 bool VisitUnaryPostDec(
const UnaryOperator *UO) {
9092 return VisitUnaryPostIncDec(UO);
9094 bool VisitUnaryPostIncDec(
const UnaryOperator *UO) {
9095 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9105 return DerivedSuccess(RVal, UO);
9108 bool VisitStmtExpr(
const StmtExpr *E) {
9111 llvm::SaveAndRestore NotCheckingForUB(Info.CheckingForUndefinedBehavior,
9118 BlockScopeRAII Scope(Info);
9123 const Expr *FinalExpr = dyn_cast<Expr>(*BI);
9125 Info.FFDiag((*BI)->getBeginLoc(),
9126 diag::note_constexpr_stmt_expr_unsupported);
9129 return this->Visit(FinalExpr) && Scope.destroy();
9135 if (ESR != ESR_Succeeded) {
9139 if (ESR != ESR_Failed)
9140 Info.FFDiag((*BI)->getBeginLoc(),
9141 diag::note_constexpr_stmt_expr_unsupported);
9146 llvm_unreachable(
"Return from function from the loop above.");
9149 bool VisitPackIndexingExpr(
const PackIndexingExpr *E) {
9154 void VisitIgnoredValue(
const Expr *E) {
9159 void VisitIgnoredBaseExpression(
const Expr *E) {
9162 if (Info.getLangOpts().MSVCCompat && !E->
HasSideEffects(Info.Ctx))
9164 VisitIgnoredValue(E);
9174template<
class Derived>
9175class LValueExprEvaluatorBase
9176 :
public ExprEvaluatorBase<Derived> {
9180 typedef LValueExprEvaluatorBase LValueExprEvaluatorBaseTy;
9181 typedef ExprEvaluatorBase<Derived> ExprEvaluatorBaseTy;
9183 bool Success(APValue::LValueBase B) {
9188 bool evaluatePointer(
const Expr *E, LValue &
Result) {
9193 LValueExprEvaluatorBase(EvalInfo &Info, LValue &
Result,
bool InvalidBaseOK)
9195 InvalidBaseOK(InvalidBaseOK) {}
9198 Result.setFrom(this->Info.Ctx,
V);
9202 bool VisitMemberExpr(
const MemberExpr *E) {
9214 EvalOK = this->Visit(E->
getBase());
9225 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(E->
getMemberDecl())) {
9228 "record / field mismatch");
9232 }
else if (
const IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(MD)) {
9236 return this->
Error(E);
9248 bool VisitBinaryOperator(
const BinaryOperator *E) {
9251 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
9259 bool VisitCastExpr(
const CastExpr *E) {
9262 return ExprEvaluatorBaseTy::VisitCastExpr(E);
9264 case CK_DerivedToBase:
9265 case CK_UncheckedDerivedToBase:
9312class LValueExprEvaluator
9313 :
public LValueExprEvaluatorBase<LValueExprEvaluator> {
9315 LValueExprEvaluator(EvalInfo &Info, LValue &
Result,
bool InvalidBaseOK) :
9316 LValueExprEvaluatorBaseTy(Info,
Result, InvalidBaseOK) {}
9318 bool VisitVarDecl(
const Expr *E,
const VarDecl *VD);
9319 bool VisitUnaryPreIncDec(
const UnaryOperator *UO);
9321 bool VisitCallExpr(
const CallExpr *E);
9322 bool VisitDeclRefExpr(
const DeclRefExpr *E);
9323 bool VisitPredefinedExpr(
const PredefinedExpr *E) {
return Success(E); }
9324 bool VisitMaterializeTemporaryExpr(
const MaterializeTemporaryExpr *E);
9325 bool VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E);
9326 bool VisitMemberExpr(
const MemberExpr *E);
9327 bool VisitStringLiteral(
const StringLiteral *E) {
9328 return Success(APValue::LValueBase(
9329 E, 0, Info.getASTContext().getNextStringLiteralVersion()));
9331 bool VisitObjCEncodeExpr(
const ObjCEncodeExpr *E) {
return Success(E); }
9332 bool VisitCXXTypeidExpr(
const CXXTypeidExpr *E);
9333 bool VisitCXXUuidofExpr(
const CXXUuidofExpr *E);
9334 bool VisitArraySubscriptExpr(
const ArraySubscriptExpr *E);
9335 bool VisitExtVectorElementExpr(
const ExtVectorElementExpr *E);
9336 bool VisitUnaryDeref(
const UnaryOperator *E);
9337 bool VisitUnaryReal(
const UnaryOperator *E);
9338 bool VisitUnaryImag(
const UnaryOperator *E);
9339 bool VisitUnaryPreInc(
const UnaryOperator *UO) {
9340 return VisitUnaryPreIncDec(UO);
9342 bool VisitUnaryPreDec(
const UnaryOperator *UO) {
9343 return VisitUnaryPreIncDec(UO);
9345 bool VisitBinAssign(
const BinaryOperator *BO);
9346 bool VisitCompoundAssignOperator(
const CompoundAssignOperator *CAO);
9348 bool VisitCastExpr(
const CastExpr *E) {
9351 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
9353 case CK_LValueBitCast:
9354 this->CCEDiag(E, diag::note_constexpr_invalid_cast)
9355 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
9359 Result.Designator.setInvalid();
9362 case CK_BaseToDerived:
9379 bool LValueToRValueConversion) {
9383 assert(Info.CurrentCall->This ==
nullptr &&
9384 "This should not be set for a static call operator");
9392 if (
Self->getType()->isReferenceType()) {
9393 APValue *RefValue = Info.getParamSlot(Info.CurrentCall->Arguments,
Self);
9395 Result.setFrom(Info.Ctx, *RefValue);
9397 const ParmVarDecl *VD = Info.CurrentCall->Arguments.getOrigParam(
Self);
9398 CallStackFrame *Frame =
9399 Info.getCallFrameAndDepth(Info.CurrentCall->Arguments.CallIndex)
9401 unsigned Version = Info.CurrentCall->Arguments.Version;
9402 Result.set({VD, Frame->Index, Version});
9405 Result = *Info.CurrentCall->This;
9415 if (LValueToRValueConversion) {
9419 Result.setFrom(Info.Ctx, RVal);
9430 bool InvalidBaseOK) {
9434 return LValueExprEvaluator(Info, Result, InvalidBaseOK).Visit(E);
9437bool LValueExprEvaluator::VisitDeclRefExpr(
const DeclRefExpr *E) {
9438 const ValueDecl *D = E->
getDecl();
9450 if (Info.checkingPotentialConstantExpression())
9453 if (
auto *FD = Info.CurrentCall->LambdaCaptureFields.lookup(D)) {
9460 if (
isa<FunctionDecl, MSGuidDecl, TemplateParamObjectDecl,
9461 UnnamedGlobalConstantDecl>(D))
9463 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
9464 return VisitVarDecl(E, VD);
9465 if (
const BindingDecl *BD = dyn_cast<BindingDecl>(D))
9466 return Visit(BD->getBinding());
9470bool LValueExprEvaluator::VisitVarDecl(
const Expr *E,
const VarDecl *VD) {
9471 CallStackFrame *Frame =
nullptr;
9472 unsigned Version = 0;
9480 CallStackFrame *CurrFrame = Info.CurrentCall;
9485 if (
auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
9486 if (CurrFrame->Arguments) {
9487 VD = CurrFrame->Arguments.getOrigParam(PVD);
9489 Info.getCallFrameAndDepth(CurrFrame->Arguments.CallIndex).first;
9490 Version = CurrFrame->Arguments.Version;
9494 Version = CurrFrame->getCurrentTemporaryVersion(VD);
9501 Result.set({VD, Frame->Index, Version});
9507 if (!Info.getLangOpts().CPlusPlus11) {
9508 Info.CCEDiag(E, diag::note_constexpr_ltor_non_integral, 1)
9510 Info.Note(VD->
getLocation(), diag::note_declared_at);
9519 Result.AllowConstexprUnknown =
true;
9526bool LValueExprEvaluator::VisitCallExpr(
const CallExpr *E) {
9527 if (!IsConstantEvaluatedBuiltinCall(E))
9528 return ExprEvaluatorBaseTy::VisitCallExpr(E);
9533 case Builtin::BIas_const:
9534 case Builtin::BIforward:
9535 case Builtin::BIforward_like:
9536 case Builtin::BImove:
9537 case Builtin::BImove_if_noexcept:
9539 return Visit(E->
getArg(0));
9543 return ExprEvaluatorBaseTy::VisitCallExpr(E);
9546bool LValueExprEvaluator::VisitMaterializeTemporaryExpr(
9547 const MaterializeTemporaryExpr *E) {
9555 for (
const Expr *E : CommaLHSs)
9564 if (Info.EvalMode == EvaluationMode::ConstantFold)
9571 Value = &Info.CurrentCall->createTemporary(
9587 for (
unsigned I = Adjustments.size(); I != 0; ) {
9589 switch (Adjustments[I].Kind) {
9594 Type = Adjustments[I].DerivedToBase.BasePath->getType();
9600 Type = Adjustments[I].Field->getType();
9605 Adjustments[I].Ptr.RHS))
9607 Type = Adjustments[I].Ptr.MPT->getPointeeType();
9616LValueExprEvaluator::VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E) {
9617 assert((!Info.getLangOpts().CPlusPlus || E->
isFileScope()) &&
9618 "lvalue compound literal in c++?");
9630 assert(!Info.getLangOpts().CPlusPlus);
9632 ScopeKind::Block,
Result);
9644bool LValueExprEvaluator::VisitCXXTypeidExpr(
const CXXTypeidExpr *E) {
9645 TypeInfoLValue TypeInfo;
9654 Info.CCEDiag(E, diag::note_constexpr_typeid_polymorphic)
9662 std::optional<DynamicType> DynType =
9667 TypeInfo = TypeInfoLValue(
9674bool LValueExprEvaluator::VisitCXXUuidofExpr(
const CXXUuidofExpr *E) {
9678bool LValueExprEvaluator::VisitMemberExpr(
const MemberExpr *E) {
9680 if (
const VarDecl *VD = dyn_cast<VarDecl>(E->
getMemberDecl())) {
9681 VisitIgnoredBaseExpression(E->
getBase());
9682 return VisitVarDecl(E, VD);
9686 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(E->
getMemberDecl())) {
9687 if (MD->isStatic()) {
9688 VisitIgnoredBaseExpression(E->
getBase());
9694 return LValueExprEvaluatorBaseTy::VisitMemberExpr(E);
9697bool LValueExprEvaluator::VisitExtVectorElementExpr(
9698 const ExtVectorElementExpr *E) {
9703 if (!Info.noteFailure())
9711 if (Indices.size() > 1)
9715 Result.setFrom(Info.Ctx, Val);
9719 const auto *VT = BaseType->
castAs<VectorType>();
9721 VT->getNumElements(), Indices[0]);
9727bool LValueExprEvaluator::VisitArraySubscriptExpr(
const ArraySubscriptExpr *E) {
9737 if (!Info.noteFailure())
9743 if (!Info.noteFailure())
9749 Result.setFrom(Info.Ctx, Val);
9751 VT->getNumElements(), Index.getExtValue());
9759 for (
const Expr *SubExpr : {E->
getLHS(), E->
getRHS()}) {
9760 if (SubExpr == E->
getBase() ? !evaluatePointer(SubExpr,
Result)
9762 if (!Info.noteFailure())
9772bool LValueExprEvaluator::VisitUnaryDeref(
const UnaryOperator *E) {
9783 Info.noteUndefinedBehavior();
9786bool LValueExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
9795bool LValueExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
9797 "lvalue __imag__ on scalar?");
9804bool LValueExprEvaluator::VisitUnaryPreIncDec(
const UnaryOperator *UO) {
9805 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9816bool LValueExprEvaluator::VisitCompoundAssignOperator(
9817 const CompoundAssignOperator *CAO) {
9818 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9826 if (!Info.noteFailure())
9841bool LValueExprEvaluator::VisitBinAssign(
const BinaryOperator *E) {
9842 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9850 if (!Info.noteFailure())
9858 if (Info.getLangOpts().CPlusPlus20 &&
9874 llvm::APInt &Result) {
9875 assert(isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
9876 "Can't get the size of a non alloc_size function");
9877 const auto *
Base = LVal.getLValueBase().get<
const Expr *>();
9879 std::optional<llvm::APInt> Size =
9880 CE->evaluateBytesReturnedByAllocSizeCall(Ctx);
9884 Result = std::move(*Size);
9903 dyn_cast_or_null<VarDecl>(
Base.dyn_cast<
const ValueDecl *>());
9908 if (!
Init ||
Init->getType().isNull())
9911 const Expr *E =
Init->IgnoreParens();
9912 if (!tryUnwrapAllocSizeCall(E))
9917 Result.setInvalid(E);
9920 Result.addUnsizedArray(Info, E, Pointee);
9925class PointerExprEvaluator
9926 :
public ExprEvaluatorBase<PointerExprEvaluator> {
9935 bool evaluateLValue(
const Expr *E, LValue &
Result) {
9939 bool evaluatePointer(
const Expr *E, LValue &
Result) {
9943 bool visitNonBuiltinCallExpr(
const CallExpr *E);
9946 PointerExprEvaluator(EvalInfo &info, LValue &
Result,
bool InvalidBaseOK)
9948 InvalidBaseOK(InvalidBaseOK) {}
9954 bool ZeroInitialization(
const Expr *E) {
9959 bool VisitBinaryOperator(
const BinaryOperator *E);
9960 bool VisitCastExpr(
const CastExpr* E);
9961 bool VisitUnaryAddrOf(
const UnaryOperator *E);
9962 bool VisitObjCStringLiteral(
const ObjCStringLiteral *E)
9964 bool VisitObjCBoxedExpr(
const ObjCBoxedExpr *E) {
9967 if (Info.noteFailure())
9971 bool VisitAddrLabelExpr(
const AddrLabelExpr *E)
9973 bool VisitCallExpr(
const CallExpr *E);
9974 bool VisitBuiltinCallExpr(
const CallExpr *E,
unsigned BuiltinOp);
9975 bool VisitBlockExpr(
const BlockExpr *E) {
9980 bool VisitCXXThisExpr(
const CXXThisExpr *E) {
9981 auto DiagnoseInvalidUseOfThis = [&] {
9982 if (Info.getLangOpts().CPlusPlus11)
9983 Info.FFDiag(E, diag::note_constexpr_this) << E->
isImplicit();
9989 if (Info.checkingPotentialConstantExpression())
9992 bool IsExplicitLambda =
9994 if (!IsExplicitLambda) {
9995 if (!Info.CurrentCall->This) {
9996 DiagnoseInvalidUseOfThis();
10000 Result = *Info.CurrentCall->This;
10008 if (!Info.CurrentCall->LambdaThisCaptureField) {
10009 if (IsExplicitLambda && !Info.CurrentCall->This) {
10010 DiagnoseInvalidUseOfThis();
10019 Info, E,
Result, MD, Info.CurrentCall->LambdaThisCaptureField,
10025 bool VisitCXXNewExpr(
const CXXNewExpr *E);
10027 bool VisitSourceLocExpr(
const SourceLocExpr *E) {
10028 assert(!E->
isIntType() &&
"SourceLocExpr isn't a pointer type?");
10030 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.
getDefaultExpr());
10031 Result.setFrom(Info.Ctx, LValResult);
10035 bool VisitEmbedExpr(
const EmbedExpr *E) {
10036 llvm::report_fatal_error(
"Not yet implemented for ExprConstant.cpp");
10040 bool VisitSYCLUniqueStableNameExpr(
const SYCLUniqueStableNameExpr *E) {
10041 std::string ResultStr = E->
ComputeName(Info.Ctx);
10045 ResultStr.size() + 1);
10047 CharTy, Size,
nullptr, ArraySizeModifier::Normal, 0);
10049 StringLiteral *SL =
10050 StringLiteral::Create(Info.Ctx, ResultStr, StringLiteralKind::Ordinary,
10053 evaluateLValue(SL,
Result);
10063 bool InvalidBaseOK) {
10066 return PointerExprEvaluator(Info, Result, InvalidBaseOK).Visit(E);
10069bool PointerExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
10072 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
10074 const Expr *PExp = E->
getLHS();
10075 const Expr *IExp = E->
getRHS();
10077 std::swap(PExp, IExp);
10079 bool EvalPtrOK = evaluatePointer(PExp,
Result);
10080 if (!EvalPtrOK && !Info.noteFailure())
10083 llvm::APSInt Offset;
10094bool PointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
10103 if (!FnII || !FnII->
isStr(
"current"))
10106 const auto *RD = dyn_cast<RecordDecl>(FD->
getParent());
10114bool PointerExprEvaluator::VisitCastExpr(
const CastExpr *E) {
10121 case CK_CPointerToObjCPointerCast:
10122 case CK_BlockPointerToObjCPointerCast:
10123 case CK_AnyPointerToBlockPointerCast:
10124 case CK_AddressSpaceConversion:
10125 if (!Visit(SubExpr))
10131 CCEDiag(E, diag::note_constexpr_invalid_cast)
10132 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
10134 Result.Designator.setInvalid();
10142 bool HasValidResult = !
Result.InvalidBase && !
Result.Designator.Invalid &&
10144 bool VoidPtrCastMaybeOK =
10156 if (VoidPtrCastMaybeOK &&
10157 (Info.getStdAllocatorCaller(
"allocate") ||
10159 Info.getLangOpts().CPlusPlus26)) {
10163 Info.getLangOpts().CPlusPlus) {
10164 if (HasValidResult)
10165 CCEDiag(E, diag::note_constexpr_invalid_void_star_cast)
10166 << SubExpr->
getType() << Info.getLangOpts().CPlusPlus26
10167 <<
Result.Designator.getType(Info.Ctx).getCanonicalType()
10170 CCEDiag(E, diag::note_constexpr_invalid_cast)
10171 << diag::ConstexprInvalidCastKind::CastFrom
10174 CCEDiag(E, diag::note_constexpr_invalid_cast)
10175 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
10177 Result.Designator.setInvalid();
10181 ZeroInitialization(E);
10184 case CK_DerivedToBase:
10185 case CK_UncheckedDerivedToBase:
10197 case CK_BaseToDerived:
10209 case CK_NullToPointer:
10211 return ZeroInitialization(E);
10213 case CK_IntegralToPointer: {
10214 CCEDiag(E, diag::note_constexpr_invalid_cast)
10215 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
10222 if (
Value.isInt()) {
10224 uint64_t N =
Value.getInt().extOrTrunc(Size).getZExtValue();
10228 Result.Base = (Expr *)
nullptr;
10229 Result.InvalidBase =
false;
10231 Result.Designator.setInvalid();
10232 Result.IsNullPtr =
false;
10240 if (!
Value.isLValue())
10249 case CK_ArrayToPointerDecay: {
10251 if (!evaluateLValue(SubExpr,
Result))
10255 SubExpr, SubExpr->
getType(), ScopeKind::FullExpression,
Result);
10261 if (
auto *CAT = dyn_cast<ConstantArrayType>(AT))
10262 Result.addArray(Info, E, CAT);
10264 Result.addUnsizedArray(Info, E, AT->getElementType());
10268 case CK_FunctionToPointerDecay:
10269 return evaluateLValue(SubExpr,
Result);
10271 case CK_LValueToRValue: {
10280 return InvalidBaseOK &&
10286 return ExprEvaluatorBaseTy::VisitCastExpr(E);
10294 T =
T.getNonReferenceType();
10296 if (
T.getQualifiers().hasUnaligned())
10299 const bool AlignOfReturnsPreferred =
10300 Ctx.
getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver7;
10305 if (ExprKind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
10308 else if (ExprKind == UETT_AlignOf)
10311 llvm_unreachable(
"GetAlignOfType on a non-alignment ExprKind");
10324 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
10328 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(E))
10338 if (
const auto *E =
Value.Base.dyn_cast<
const Expr *>())
10346 EvalInfo &Info,
APSInt &Alignment) {
10349 if (Alignment < 0 || !Alignment.isPowerOf2()) {
10350 Info.FFDiag(E, diag::note_constexpr_invalid_alignment) << Alignment;
10353 unsigned SrcWidth = Info.Ctx.
getIntWidth(ForType);
10354 APSInt MaxValue(APInt::getOneBitSet(SrcWidth, SrcWidth - 1));
10355 if (APSInt::compareValues(Alignment, MaxValue) > 0) {
10356 Info.FFDiag(E, diag::note_constexpr_alignment_too_big)
10357 << MaxValue << ForType << Alignment;
10363 APSInt(Alignment.zextOrTrunc(SrcWidth),
true);
10364 assert(APSInt::compareValues(Alignment, ExtAlignment) == 0 &&
10365 "Alignment should not be changed by ext/trunc");
10366 Alignment = ExtAlignment;
10367 assert(Alignment.getBitWidth() == SrcWidth);
10372bool PointerExprEvaluator::visitNonBuiltinCallExpr(
const CallExpr *E) {
10373 if (ExprEvaluatorBaseTy::VisitCallExpr(E))
10381 Result.addUnsizedArray(Info, E, PointeeTy);
10385bool PointerExprEvaluator::VisitCallExpr(
const CallExpr *E) {
10386 if (!IsConstantEvaluatedBuiltinCall(E))
10387 return visitNonBuiltinCallExpr(E);
10394 return T->isCharType() ||
T->isChar8Type();
10397bool PointerExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *E,
10398 unsigned BuiltinOp) {
10402 switch (BuiltinOp) {
10403 case Builtin::BIaddressof:
10404 case Builtin::BI__addressof:
10405 case Builtin::BI__builtin_addressof:
10407 case Builtin::BI__builtin_assume_aligned: {
10414 LValue OffsetResult(
Result);
10426 int64_t AdditionalOffset = -Offset.getZExtValue();
10431 if (OffsetResult.Base) {
10434 if (BaseAlignment < Align) {
10435 Result.Designator.setInvalid();
10436 CCEDiag(E->
getArg(0), diag::note_constexpr_baa_insufficient_alignment)
10443 if (OffsetResult.Offset.alignTo(Align) != OffsetResult.Offset) {
10444 Result.Designator.setInvalid();
10448 diag::note_constexpr_baa_insufficient_alignment)
10451 diag::note_constexpr_baa_value_insufficient_alignment))
10452 << OffsetResult.Offset.getQuantity() << Align.
getQuantity();
10458 case Builtin::BI__builtin_align_up:
10459 case Builtin::BI__builtin_align_down: {
10479 assert(Alignment.getBitWidth() <= 64 &&
10480 "Cannot handle > 64-bit address-space");
10481 uint64_t Alignment64 = Alignment.getZExtValue();
10483 BuiltinOp == Builtin::BI__builtin_align_down
10484 ? llvm::alignDown(
Result.Offset.getQuantity(), Alignment64)
10485 : llvm::alignTo(
Result.Offset.getQuantity(), Alignment64));
10491 Info.FFDiag(E->
getArg(0), diag::note_constexpr_alignment_adjust)
10495 case Builtin::BI__builtin_operator_new:
10497 case Builtin::BI__builtin_launder:
10499 case Builtin::BIstrchr:
10500 case Builtin::BIwcschr:
10501 case Builtin::BImemchr:
10502 case Builtin::BIwmemchr:
10503 if (Info.getLangOpts().CPlusPlus11)
10504 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
10508 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
10510 case Builtin::BI__builtin_strchr:
10511 case Builtin::BI__builtin_wcschr:
10512 case Builtin::BI__builtin_memchr:
10513 case Builtin::BI__builtin_char_memchr:
10514 case Builtin::BI__builtin_wmemchr: {
10515 if (!Visit(E->
getArg(0)))
10521 if (BuiltinOp != Builtin::BIstrchr &&
10522 BuiltinOp != Builtin::BIwcschr &&
10523 BuiltinOp != Builtin::BI__builtin_strchr &&
10524 BuiltinOp != Builtin::BI__builtin_wcschr) {
10528 MaxLength = N.getZExtValue();
10531 if (MaxLength == 0u)
10532 return ZeroInitialization(E);
10533 if (!
Result.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
10534 Result.Designator.Invalid)
10536 QualType CharTy =
Result.Designator.getType(Info.Ctx);
10537 bool IsRawByte = BuiltinOp == Builtin::BImemchr ||
10538 BuiltinOp == Builtin::BI__builtin_memchr;
10539 assert(IsRawByte ||
10544 Info.FFDiag(E, diag::note_constexpr_ltor_incomplete_type) << CharTy;
10550 Info.FFDiag(E, diag::note_constexpr_memchr_unsupported)
10557 bool StopAtNull =
false;
10558 switch (BuiltinOp) {
10559 case Builtin::BIstrchr:
10560 case Builtin::BI__builtin_strchr:
10567 return ZeroInitialization(E);
10570 case Builtin::BImemchr:
10571 case Builtin::BI__builtin_memchr:
10572 case Builtin::BI__builtin_char_memchr:
10576 DesiredVal = Desired.trunc(Info.Ctx.
getCharWidth()).getZExtValue();
10579 case Builtin::BIwcschr:
10580 case Builtin::BI__builtin_wcschr:
10583 case Builtin::BIwmemchr:
10584 case Builtin::BI__builtin_wmemchr:
10586 DesiredVal = Desired.getZExtValue();
10590 for (; MaxLength; --MaxLength) {
10595 if (Char.
getInt().getZExtValue() == DesiredVal)
10597 if (StopAtNull && !Char.
getInt())
10603 return ZeroInitialization(E);
10606 case Builtin::BImemcpy:
10607 case Builtin::BImemmove:
10608 case Builtin::BIwmemcpy:
10609 case Builtin::BIwmemmove:
10610 if (Info.getLangOpts().CPlusPlus11)
10611 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
10615 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
10617 case Builtin::BI__builtin_memcpy:
10618 case Builtin::BI__builtin_memmove:
10619 case Builtin::BI__builtin_wmemcpy:
10620 case Builtin::BI__builtin_wmemmove: {
10621 bool WChar = BuiltinOp == Builtin::BIwmemcpy ||
10622 BuiltinOp == Builtin::BIwmemmove ||
10623 BuiltinOp == Builtin::BI__builtin_wmemcpy ||
10624 BuiltinOp == Builtin::BI__builtin_wmemmove;
10625 bool Move = BuiltinOp == Builtin::BImemmove ||
10626 BuiltinOp == Builtin::BIwmemmove ||
10627 BuiltinOp == Builtin::BI__builtin_memmove ||
10628 BuiltinOp == Builtin::BI__builtin_wmemmove;
10631 if (!Visit(E->
getArg(0)))
10642 assert(!N.isSigned() &&
"memcpy and friends take an unsigned size");
10652 if (!Src.Base || !Dest.Base) {
10654 (!Src.Base ? Src : Dest).moveInto(Val);
10655 Info.FFDiag(E, diag::note_constexpr_memcpy_null)
10656 <<
Move << WChar << !!Src.Base
10660 if (Src.Designator.Invalid || Dest.Designator.Invalid)
10666 QualType
T = Dest.Designator.getType(Info.Ctx);
10667 QualType SrcT = Src.Designator.getType(Info.Ctx);
10670 Info.FFDiag(E, diag::note_constexpr_memcpy_type_pun) <<
Move << SrcT <<
T;
10674 Info.FFDiag(E, diag::note_constexpr_memcpy_incomplete_type) <<
Move <<
T;
10677 if (!
T.isTriviallyCopyableType(Info.Ctx)) {
10678 Info.FFDiag(E, diag::note_constexpr_memcpy_nontrivial) <<
Move <<
T;
10688 llvm::APInt OrigN = N;
10689 llvm::APInt::udivrem(OrigN, TSize, N, Remainder);
10691 Info.FFDiag(E, diag::note_constexpr_memcpy_unsupported)
10693 << (unsigned)TSize;
10701 uint64_t RemainingSrcSize = Src.Designator.validIndexAdjustments().second;
10702 uint64_t RemainingDestSize = Dest.Designator.validIndexAdjustments().second;
10703 if (N.ugt(RemainingSrcSize) || N.ugt(RemainingDestSize)) {
10704 Info.FFDiag(E, diag::note_constexpr_memcpy_unsupported)
10705 <<
Move << WChar << (N.ugt(RemainingSrcSize) ? 1 : 2) <<
T
10709 uint64_t NElems = N.getZExtValue();
10715 uint64_t SrcOffset = Src.getLValueOffset().getQuantity();
10716 uint64_t DestOffset = Dest.getLValueOffset().getQuantity();
10717 if (DestOffset >= SrcOffset && DestOffset - SrcOffset < NBytes) {
10720 Info.FFDiag(E, diag::note_constexpr_memcpy_overlap) << WChar;
10728 }
else if (!Move && SrcOffset >= DestOffset &&
10729 SrcOffset - DestOffset < NBytes) {
10731 Info.FFDiag(E, diag::note_constexpr_memcpy_overlap) << WChar;
10760 QualType AllocType);
10763 const CXXConstructExpr *CCE,
10764 QualType AllocType);
10766bool PointerExprEvaluator::VisitCXXNewExpr(
const CXXNewExpr *E) {
10767 if (!Info.getLangOpts().CPlusPlus20)
10768 Info.CCEDiag(E, diag::note_constexpr_new);
10771 if (Info.SpeculativeEvaluationDepth)
10776 QualType TargetType = AllocType;
10778 bool IsNothrow =
false;
10779 bool IsPlacement =
false;
10797 }
else if (OperatorNew->isReservedGlobalPlacementOperator()) {
10798 if (Info.CurrentCall->isStdFunction() || Info.getLangOpts().CPlusPlus26 ||
10799 (Info.CurrentCall->CanEvalMSConstexpr &&
10800 OperatorNew->hasAttr<MSConstexprAttr>())) {
10803 if (
Result.Designator.Invalid)
10806 IsPlacement =
true;
10808 Info.FFDiag(E, diag::note_constexpr_new_placement)
10813 Info.FFDiag(E, diag::note_constexpr_new_placement)
10816 }
else if (!OperatorNew
10817 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
10818 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
10824 const InitListExpr *ResizedArrayILE =
nullptr;
10825 const CXXConstructExpr *ResizedArrayCCE =
nullptr;
10826 bool ValueInit =
false;
10828 if (std::optional<const Expr *> ArraySize = E->
getArraySize()) {
10829 const Expr *Stripped = *ArraySize;
10830 for (;
auto *ICE = dyn_cast<ImplicitCastExpr>(Stripped);
10831 Stripped = ICE->getSubExpr())
10832 if (ICE->getCastKind() != CK_NoOp &&
10833 ICE->getCastKind() != CK_IntegralCast)
10846 return ZeroInitialization(E);
10848 Info.FFDiag(*ArraySize, diag::note_constexpr_new_negative)
10849 <<
ArrayBound << (*ArraySize)->getSourceRange();
10855 if (!Info.CheckArraySize(ArraySize.value()->getExprLoc(),
10860 return ZeroInitialization(E);
10872 }
else if (
auto *CCE = dyn_cast<CXXConstructExpr>(
Init)) {
10873 ResizedArrayCCE = CCE;
10876 assert(CAT &&
"unexpected type for array initializer");
10880 llvm::APInt InitBound = CAT->
getSize().zext(Bits);
10881 llvm::APInt AllocBound =
ArrayBound.zext(Bits);
10882 if (InitBound.ugt(AllocBound)) {
10884 return ZeroInitialization(E);
10886 Info.FFDiag(*ArraySize, diag::note_constexpr_new_too_small)
10887 <<
toString(AllocBound, 10,
false)
10889 << (*ArraySize)->getSourceRange();
10895 if (InitBound != AllocBound)
10900 ArraySizeModifier::Normal, 0);
10903 "array allocation with non-array new");
10909 struct FindObjectHandler {
10912 QualType AllocType;
10916 typedef bool result_type;
10917 bool failed() {
return false; }
10918 bool checkConst(QualType QT) {
10920 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
10925 bool found(
APValue &Subobj, QualType SubobjType) {
10926 if (!checkConst(SubobjType))
10930 unsigned SubobjectSize = 1;
10931 unsigned AllocSize = 1;
10932 if (
auto *CAT = dyn_cast<ConstantArrayType>(AllocType))
10934 if (
auto *CAT = dyn_cast<ConstantArrayType>(SubobjType))
10936 if (SubobjectSize < AllocSize ||
10939 Info.FFDiag(E, diag::note_constexpr_placement_new_wrong_type)
10940 << SubobjType << AllocType;
10947 Info.FFDiag(E, diag::note_constexpr_construct_complex_elem);
10950 bool found(APFloat &
Value, QualType SubobjType) {
10951 Info.FFDiag(E, diag::note_constexpr_construct_complex_elem);
10954 } Handler = {Info, E, AllocType, AK,
nullptr};
10960 Val = Handler.Value;
10969 Val = Info.createHeapAlloc(E, AllocType,
Result);
10975 ImplicitValueInitExpr VIE(AllocType);
10978 }
else if (ResizedArrayILE) {
10982 }
else if (ResizedArrayCCE) {
11005class MemberPointerExprEvaluator
11006 :
public ExprEvaluatorBase<MemberPointerExprEvaluator> {
11009 bool Success(
const ValueDecl *D) {
11015 MemberPointerExprEvaluator(EvalInfo &Info, MemberPtr &
Result)
11022 bool ZeroInitialization(
const Expr *E) {
11023 return Success((
const ValueDecl*)
nullptr);
11026 bool VisitCastExpr(
const CastExpr *E);
11027 bool VisitUnaryAddrOf(
const UnaryOperator *E);
11035 return MemberPointerExprEvaluator(Info, Result).Visit(E);
11038bool MemberPointerExprEvaluator::VisitCastExpr(
const CastExpr *E) {
11041 return ExprEvaluatorBaseTy::VisitCastExpr(E);
11043 case CK_NullToMemberPointer:
11045 return ZeroInitialization(E);
11047 case CK_BaseToDerivedMemberPointer: {
11055 typedef std::reverse_iterator<CastExpr::path_const_iterator> ReverseIter;
11057 PathI != PathE; ++PathI) {
11058 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
11059 const CXXRecordDecl *Derived = (*PathI)->getType()->getAsCXXRecordDecl();
11060 if (!
Result.castToDerived(Derived))
11064 ->
castAs<MemberPointerType>()
11065 ->getMostRecentCXXRecordDecl()))
11070 case CK_DerivedToBaseMemberPointer:
11074 PathE = E->
path_end(); PathI != PathE; ++PathI) {
11075 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
11076 const CXXRecordDecl *
Base = (*PathI)->getType()->getAsCXXRecordDecl();
11077 if (!
Result.castToBase(Base))
11084bool MemberPointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
11095 class RecordExprEvaluator
11096 :
public ExprEvaluatorBase<RecordExprEvaluator> {
11097 const LValue &
This;
11101 RecordExprEvaluator(EvalInfo &info,
const LValue &This,
APValue &
Result)
11108 bool ZeroInitialization(
const Expr *E) {
11109 return ZeroInitialization(E, E->
getType());
11111 bool ZeroInitialization(
const Expr *E, QualType
T);
11113 bool VisitCallExpr(
const CallExpr *E) {
11114 return handleCallExpr(E,
Result, &This);
11116 bool VisitCastExpr(
const CastExpr *E);
11117 bool VisitInitListExpr(
const InitListExpr *E);
11118 bool VisitCXXConstructExpr(
const CXXConstructExpr *E) {
11119 return VisitCXXConstructExpr(E, E->
getType());
11122 bool VisitCXXInheritedCtorInitExpr(
const CXXInheritedCtorInitExpr *E);
11123 bool VisitCXXConstructExpr(
const CXXConstructExpr *E, QualType
T);
11124 bool VisitCXXStdInitializerListExpr(
const CXXStdInitializerListExpr *E);
11125 bool VisitBinCmp(
const BinaryOperator *E);
11126 bool VisitCXXParenListInitExpr(
const CXXParenListInitExpr *E);
11127 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
11128 ArrayRef<Expr *> Args);
11142 assert(!RD->
isUnion() &&
"Expected non-union class type");
11151 unsigned Index = 0;
11153 End = CD->
bases_end(); I != End; ++I, ++Index) {
11155 LValue Subobject =
This;
11159 Result.getStructBase(Index)))
11164 for (
const auto *I : RD->
fields()) {
11166 if (I->isUnnamedBitField() || I->getType()->isReferenceType())
11169 LValue Subobject =
This;
11175 Result.getStructField(I->getFieldIndex()), Info, Subobject, &VIE))
11182bool RecordExprEvaluator::ZeroInitialization(
const Expr *E, QualType
T) {
11189 while (I != RD->
field_end() && (*I)->isUnnamedBitField())
11196 LValue Subobject =
This;
11200 ImplicitValueInitExpr VIE(I->getType());
11205 Info.FFDiag(E, diag::note_constexpr_virtual_base) << RD;
11212bool RecordExprEvaluator::VisitCastExpr(
const CastExpr *E) {
11215 return ExprEvaluatorBaseTy::VisitCastExpr(E);
11217 case CK_ConstructorConversion:
11220 case CK_DerivedToBase:
11221 case CK_UncheckedDerivedToBase: {
11232 PathE = E->
path_end(); PathI != PathE; ++PathI) {
11233 assert(!(*PathI)->isVirtual() &&
"record rvalue with virtual base");
11234 const CXXRecordDecl *
Base = (*PathI)->getType()->getAsCXXRecordDecl();
11241 case CK_HLSLAggregateSplatCast: {
11261 case CK_HLSLElementwiseCast: {
11280bool RecordExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
11283 return VisitCXXParenListOrInitListExpr(E, E->
inits());
11286bool RecordExprEvaluator::VisitCXXParenListOrInitListExpr(
11291 auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
11293 EvalInfo::EvaluatingConstructorRAII EvalObj(
11295 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries},
11296 CXXRD && CXXRD->getNumBases());
11299 const FieldDecl *
Field;
11300 if (
auto *ILE = dyn_cast<InitListExpr>(ExprToVisit)) {
11301 Field = ILE->getInitializedFieldInUnion();
11302 }
else if (
auto *PLIE = dyn_cast<CXXParenListInitExpr>(ExprToVisit)) {
11303 Field = PLIE->getInitializedFieldInUnion();
11306 "Expression is neither an init list nor a C++ paren list");
11318 ImplicitValueInitExpr VIE(
Field->getType());
11319 const Expr *InitExpr = Args.empty() ? &VIE : Args[0];
11321 LValue Subobject =
This;
11326 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
11330 if (
Field->isBitField())
11340 Result =
APValue(APValue::UninitStruct(), CXXRD ? CXXRD->getNumBases() : 0,
11342 unsigned ElementNo = 0;
11346 if (CXXRD && CXXRD->getNumBases()) {
11347 for (
const auto &Base : CXXRD->bases()) {
11348 assert(ElementNo < Args.size() &&
"missing init for base class");
11349 const Expr *
Init = Args[ElementNo];
11351 LValue Subobject =
This;
11357 if (!Info.noteFailure())
11364 EvalObj.finishedConstructingBases();
11368 for (
const auto *Field : RD->
fields()) {
11371 if (
Field->isUnnamedBitField())
11374 LValue Subobject =
This;
11376 bool HaveInit = ElementNo < Args.size();
11381 Subobject, Field, &Layout))
11386 ImplicitValueInitExpr VIE(HaveInit ? Info.Ctx.
IntTy :
Field->getType());
11387 const Expr *
Init = HaveInit ? Args[ElementNo++] : &VIE;
11389 if (
Field->getType()->isIncompleteArrayType()) {
11394 Info.FFDiag(
Init, diag::note_constexpr_unsupported_flexible_array);
11401 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
11405 if (
Field->getType()->isReferenceType()) {
11409 if (!Info.noteFailure())
11414 (
Field->isBitField() &&
11416 if (!Info.noteFailure())
11422 EvalObj.finishedConstructingFields();
11427bool RecordExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E,
11437 return ZeroInitialization(E,
T);
11455 const Expr *SrcObj = E->
getArg(0);
11458 if (
const MaterializeTemporaryExpr *ME =
11459 dyn_cast<MaterializeTemporaryExpr>(SrcObj))
11460 return Visit(ME->getSubExpr());
11463 if (ZeroInit && !ZeroInitialization(E,
T))
11472bool RecordExprEvaluator::VisitCXXInheritedCtorInitExpr(
11473 const CXXInheritedCtorInitExpr *E) {
11474 if (!Info.CurrentCall) {
11475 assert(Info.checkingPotentialConstantExpression());
11494bool RecordExprEvaluator::VisitCXXStdInitializerListExpr(
11495 const CXXStdInitializerListExpr *E) {
11496 const ConstantArrayType *ArrayType =
11503 assert(ArrayType &&
"unexpected type for array initializer");
11506 Array.addArray(Info, E, ArrayType);
11510 Array.moveInto(
Result.getStructField(0));
11514 assert(Field !=
Record->field_end() &&
11517 "Expected std::initializer_list first field to be const E *");
11519 assert(Field !=
Record->field_end() &&
11520 "Expected std::initializer_list to have two fields");
11529 "Expected std::initializer_list second field to be const E *");
11534 Array.moveInto(
Result.getStructField(1));
11537 assert(++Field ==
Record->field_end() &&
11538 "Expected std::initializer_list to only have two fields");
11543bool RecordExprEvaluator::VisitLambdaExpr(
const LambdaExpr *E) {
11548 const size_t NumFields = ClosureClass->
getNumFields();
11552 "The number of lambda capture initializers should equal the number of "
11553 "fields within the closure type");
11561 for (
const auto *Field : ClosureClass->
fields()) {
11564 Expr *
const CurFieldInit = *CaptureInitIt++;
11571 LValue Subobject =
This;
11578 if (!Info.keepEvaluatingAfterFailure())
11587 APValue &Result, EvalInfo &Info) {
11590 "can't evaluate expression as a record rvalue");
11591 return RecordExprEvaluator(Info,
This, Result).Visit(E);
11602class TemporaryExprEvaluator
11603 :
public LValueExprEvaluatorBase<TemporaryExprEvaluator> {
11605 TemporaryExprEvaluator(EvalInfo &Info, LValue &
Result) :
11606 LValueExprEvaluatorBaseTy(Info,
Result,
false) {}
11609 bool VisitConstructExpr(
const Expr *E) {
11615 bool VisitCastExpr(
const CastExpr *E) {
11618 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
11620 case CK_ConstructorConversion:
11624 bool VisitInitListExpr(
const InitListExpr *E) {
11625 return VisitConstructExpr(E);
11627 bool VisitCXXConstructExpr(
const CXXConstructExpr *E) {
11628 return VisitConstructExpr(E);
11630 bool VisitCallExpr(
const CallExpr *E) {
11631 return VisitConstructExpr(E);
11633 bool VisitCXXStdInitializerListExpr(
const CXXStdInitializerListExpr *E) {
11634 return VisitConstructExpr(E);
11637 return VisitConstructExpr(E);
11646 return TemporaryExprEvaluator(Info, Result).Visit(E);
11654 class VectorExprEvaluator
11655 :
public ExprEvaluatorBase<VectorExprEvaluator> {
11662 bool Success(ArrayRef<APValue>
V,
const Expr *E) {
11663 assert(
V.size() == E->
getType()->
castAs<VectorType>()->getNumElements());
11669 assert(
V.isVector());
11673 bool ZeroInitialization(
const Expr *E);
11675 bool VisitUnaryReal(
const UnaryOperator *E)
11677 bool VisitCastExpr(
const CastExpr* E);
11678 bool VisitInitListExpr(
const InitListExpr *E);
11679 bool VisitUnaryImag(
const UnaryOperator *E);
11680 bool VisitBinaryOperator(
const BinaryOperator *E);
11681 bool VisitUnaryOperator(
const UnaryOperator *E);
11682 bool VisitCallExpr(
const CallExpr *E);
11683 bool VisitConvertVectorExpr(
const ConvertVectorExpr *E);
11684 bool VisitShuffleVectorExpr(
const ShuffleVectorExpr *E);
11693 "not a vector prvalue");
11694 return VectorExprEvaluator(Info, Result).Visit(E);
11698 assert(Val.
isVector() &&
"expected vector APValue");
11702 llvm::APInt
Result(NumElts, 0);
11704 for (
unsigned I = 0; I < NumElts; ++I) {
11706 assert(Elt.
isInt() &&
"expected integer element in bool vector");
11708 if (Elt.
getInt().getBoolValue())
11715bool VectorExprEvaluator::VisitCastExpr(
const CastExpr *E) {
11716 const VectorType *VTy = E->
getType()->
castAs<VectorType>();
11720 QualType SETy = SE->
getType();
11723 case CK_VectorSplat: {
11729 Val =
APValue(std::move(IntResult));
11734 Val =
APValue(std::move(FloatResult));
11751 Info.FFDiag(E, diag::note_constexpr_invalid_cast)
11752 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
11757 if (!handleRValueToRValueBitCast(Info,
Result, SVal, E))
11762 case CK_HLSLVectorTruncation: {
11767 for (
unsigned I = 0; I < NElts; I++)
11771 case CK_HLSLMatrixTruncation: {
11775 case CK_HLSLAggregateSplatCast: {
11792 case CK_HLSLElementwiseCast: {
11805 return Success(ResultEls, E);
11808 return ExprEvaluatorBaseTy::VisitCastExpr(E);
11813VectorExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
11830 unsigned CountInits = 0, CountElts = 0;
11831 while (CountElts < NumElements) {
11833 if (CountInits < NumInits
11839 for (
unsigned j = 0; j < vlen; j++)
11843 llvm::APSInt sInt(32);
11844 if (CountInits < NumInits) {
11849 Elements.push_back(
APValue(sInt));
11852 llvm::APFloat f(0.0);
11853 if (CountInits < NumInits) {
11858 Elements.push_back(
APValue(f));
11867VectorExprEvaluator::ZeroInitialization(
const Expr *E) {
11871 if (EltTy->isIntegerType())
11881bool VectorExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
11883 return ZeroInitialization(E);
11886bool VectorExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
11888 assert(Op != BO_PtrMemD && Op != BO_PtrMemI && Op != BO_Cmp &&
11889 "Operation not supported on vector types");
11891 if (Op == BO_Comma)
11892 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
11894 Expr *LHS = E->
getLHS();
11895 Expr *RHS = E->
getRHS();
11898 "Must both be vector types");
11901 assert(LHS->
getType()->
castAs<VectorType>()->getNumElements() ==
11905 "All operands must be the same size.");
11909 bool LHSOK =
Evaluate(LHSValue, Info, LHS);
11910 if (!LHSOK && !Info.noteFailure())
11912 if (!
Evaluate(RHSValue, Info, RHS) || !LHSOK)
11934 "Vector can only be int or float type");
11942 "Vector operator ~ can only be int");
11943 Elt.
getInt().flipAllBits();
11953 "Vector can only be int or float type");
11959 EltResult.setAllBits();
11961 EltResult.clearAllBits();
11967 return std::nullopt;
11971bool VectorExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
11977 const QualType ResultEltTy = VD->getElementType();
11981 if (!
Evaluate(SubExprValue, Info, SubExpr))
11994 "Vector length doesn't match type?");
11997 for (
unsigned EltNum = 0; EltNum < VD->getNumElements(); ++EltNum) {
11999 Info.Ctx, ResultEltTy, Op, SubExprValue.
getVectorElt(EltNum));
12002 ResultElements.push_back(*Elt);
12004 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12013 Result =
APValue(APFloat(0.0));
12015 DestTy, Result.getFloat());
12026 Result.getFloat());
12031 DestTy, Result.getInt());
12035 Info.FFDiag(E, diag::err_convertvector_constexpr_unsupported_vector_cast)
12036 << SourceTy << DestTy;
12041 llvm::function_ref<APInt(
const APSInt &)> PackFn) {
12050 assert(LHSVecLen != 0 && LHSVecLen == RHSVecLen &&
12051 "pack builtin LHSVecLen must equal to RHSVecLen");
12060 const unsigned SrcPerLane = 128 / SrcBits;
12061 const unsigned Lanes = LHSVecLen * SrcBits / 128;
12064 Out.reserve(LHSVecLen + RHSVecLen);
12066 for (
unsigned Lane = 0; Lane != Lanes; ++Lane) {
12067 unsigned base = Lane * SrcPerLane;
12068 for (
unsigned I = 0; I != SrcPerLane; ++I)
12071 for (
unsigned I = 0; I != SrcPerLane; ++I)
12076 Result =
APValue(Out.data(), Out.size());
12082 llvm::function_ref<std::pair<unsigned, int>(
unsigned,
unsigned)>
12089 unsigned ShuffleMask = 0;
12091 bool IsVectorMask =
false;
12092 bool IsSingleOperand = (
Call->getNumArgs() == 2);
12094 if (IsSingleOperand) {
12097 IsVectorMask =
true;
12106 ShuffleMask =
static_cast<unsigned>(MaskImm.getZExtValue());
12116 IsVectorMask =
true;
12125 ShuffleMask =
static_cast<unsigned>(MaskImm.getZExtValue());
12136 ResultElements.reserve(NumElts);
12138 for (
unsigned DstIdx = 0; DstIdx != NumElts; ++DstIdx) {
12139 if (IsVectorMask) {
12140 ShuffleMask =
static_cast<unsigned>(
12141 MaskVector.getVectorElt(DstIdx).getInt().getZExtValue());
12143 auto [SrcVecIdx, SrcIdx] = GetSourceIndex(DstIdx, ShuffleMask);
12149 ResultElements.push_back(
12156 ResultElements.push_back(
APValue());
12159 const APValue &Src = (SrcVecIdx == 0) ? A : B;
12164 Out =
APValue(ResultElements.data(), ResultElements.size());
12168 APFloat OrigVal,
APValue &Result) {
12170 if (OrigVal.isInfinity()) {
12171 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << 0;
12174 if (OrigVal.isNaN()) {
12175 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << 1;
12179 APFloat Val = OrigVal;
12180 bool LosesInfo =
false;
12181 APFloat::opStatus Status = Val.convert(
12182 APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven, &LosesInfo);
12184 if (LosesInfo || Val.isDenormal()) {
12185 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic_strict);
12189 if (Status != APFloat::opOK) {
12190 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
12199 llvm::function_ref<APInt(
const APInt &, uint64_t)> ShiftOp,
12200 llvm::function_ref<APInt(
const APInt &,
unsigned)> OverflowOp) {
12207 assert(
Call->getNumArgs() == 2);
12211 Call->getArg(1)->getType()->isVectorType());
12214 unsigned DestEltWidth = Source.getVectorElt(0).getInt().getBitWidth();
12215 unsigned DestLen = Source.getVectorLength();
12218 unsigned NumBitsInQWord = 64;
12219 unsigned NumCountElts = NumBitsInQWord / CountEltWidth;
12221 Result.reserve(DestLen);
12223 uint64_t CountLQWord = 0;
12224 for (
unsigned EltIdx = 0; EltIdx != NumCountElts; ++EltIdx) {
12226 CountLQWord |= (Elt << (EltIdx * CountEltWidth));
12229 for (
unsigned EltIdx = 0; EltIdx != DestLen; ++EltIdx) {
12230 APInt Elt = Source.getVectorElt(EltIdx).getInt();
12231 if (CountLQWord < DestEltWidth) {
12233 APValue(
APSInt(ShiftOp(Elt, CountLQWord), IsDestUnsigned)));
12236 APValue(
APSInt(OverflowOp(Elt, DestEltWidth), IsDestUnsigned)));
12239 Out =
APValue(Result.data(), Result.size());
12243bool VectorExprEvaluator::VisitCallExpr(
const CallExpr *E) {
12244 if (!IsConstantEvaluatedBuiltinCall(E))
12245 return ExprEvaluatorBaseTy::VisitCallExpr(E);
12247 auto EvaluateBinOpExpr =
12249 APValue SourceLHS, SourceRHS;
12255 QualType DestEltTy = DestTy->getElementType();
12256 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
12259 ResultElements.reserve(SourceLen);
12261 if (SourceRHS.
isInt()) {
12263 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12265 ResultElements.push_back(
12269 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12272 ResultElements.push_back(
12279 auto EvaluateFpBinOpExpr =
12280 [&](llvm::function_ref<std::optional<APFloat>(
12281 const APFloat &,
const APFloat &, std::optional<APSInt>)>
12292 std::optional<APSInt> RoundingMode;
12297 RoundingMode = Imm;
12302 ResultElements.reserve(NumElems);
12304 for (
unsigned EltNum = 0; EltNum < NumElems; ++EltNum) {
12307 std::optional<APFloat>
Result =
Fn(EltA, EltB, RoundingMode);
12315 auto EvalSelectScalar = [&](
unsigned Len) ->
bool {
12323 bool TakeA0 = (Mask.getZExtValue() & 1u) != 0;
12327 for (
unsigned I = 1; I < Len; ++I)
12329 APValue V(Res.data(), Res.size());
12336 case Builtin::BI__builtin_elementwise_popcount:
12337 case Builtin::BI__builtin_elementwise_bitreverse: {
12342 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12345 ResultElements.reserve(SourceLen);
12347 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12350 case Builtin::BI__builtin_elementwise_popcount:
12351 ResultElements.push_back(
APValue(
12355 case Builtin::BI__builtin_elementwise_bitreverse:
12356 ResultElements.push_back(
12363 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12365 case Builtin::BI__builtin_elementwise_abs: {
12370 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12373 ResultElements.reserve(SourceLen);
12375 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12380 CurrentEle.getInt().
abs(),
12381 DestEltTy->isUnsignedIntegerOrEnumerationType()));
12382 ResultElements.push_back(Val);
12385 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12388 case Builtin::BI__builtin_elementwise_add_sat:
12389 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12390 return LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS);
12393 case Builtin::BI__builtin_elementwise_sub_sat:
12394 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12395 return LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
12398 case X86::BI__builtin_ia32_extract128i256:
12399 case X86::BI__builtin_ia32_vextractf128_pd256:
12400 case X86::BI__builtin_ia32_vextractf128_ps256:
12401 case X86::BI__builtin_ia32_vextractf128_si256: {
12402 APValue SourceVec, SourceImm;
12411 unsigned RetLen = RetVT->getNumElements();
12412 unsigned Idx = SourceImm.
getInt().getZExtValue() & 1;
12415 ResultElements.reserve(RetLen);
12417 for (
unsigned I = 0; I < RetLen; I++)
12418 ResultElements.push_back(SourceVec.
getVectorElt(Idx * RetLen + I));
12423 case clang::X86::BI__builtin_ia32_cvtmask2b128:
12424 case clang::X86::BI__builtin_ia32_cvtmask2b256:
12425 case clang::X86::BI__builtin_ia32_cvtmask2b512:
12426 case clang::X86::BI__builtin_ia32_cvtmask2w128:
12427 case clang::X86::BI__builtin_ia32_cvtmask2w256:
12428 case clang::X86::BI__builtin_ia32_cvtmask2w512:
12429 case clang::X86::BI__builtin_ia32_cvtmask2d128:
12430 case clang::X86::BI__builtin_ia32_cvtmask2d256:
12431 case clang::X86::BI__builtin_ia32_cvtmask2d512:
12432 case clang::X86::BI__builtin_ia32_cvtmask2q128:
12433 case clang::X86::BI__builtin_ia32_cvtmask2q256:
12434 case clang::X86::BI__builtin_ia32_cvtmask2q512: {
12440 QualType VecTy = E->
getType();
12441 const VectorType *VT = VecTy->
castAs<VectorType>();
12444 unsigned ElemWidth = Info.Ctx.
getTypeSize(ElemTy);
12447 for (
unsigned I = 0; I != VectorLen; ++I) {
12448 bool BitSet = Mask[I];
12449 APSInt ElemVal(ElemWidth,
false);
12451 ElemVal.setAllBits();
12453 Elems.push_back(
APValue(ElemVal));
12458 case X86::BI__builtin_ia32_extracti32x4_256_mask:
12459 case X86::BI__builtin_ia32_extractf32x4_256_mask:
12460 case X86::BI__builtin_ia32_extracti32x4_mask:
12461 case X86::BI__builtin_ia32_extractf32x4_mask:
12462 case X86::BI__builtin_ia32_extracti32x8_mask:
12463 case X86::BI__builtin_ia32_extractf32x8_mask:
12464 case X86::BI__builtin_ia32_extracti64x2_256_mask:
12465 case X86::BI__builtin_ia32_extractf64x2_256_mask:
12466 case X86::BI__builtin_ia32_extracti64x2_512_mask:
12467 case X86::BI__builtin_ia32_extractf64x2_512_mask:
12468 case X86::BI__builtin_ia32_extracti64x4_mask:
12469 case X86::BI__builtin_ia32_extractf64x4_mask: {
12480 unsigned RetLen = RetVT->getNumElements();
12485 unsigned Lanes = SrcLen / RetLen;
12486 unsigned Lane =
static_cast<unsigned>(Imm.getZExtValue() % Lanes);
12487 unsigned Base = Lane * RetLen;
12490 ResultElements.reserve(RetLen);
12491 for (
unsigned I = 0; I < RetLen; ++I) {
12493 ResultElements.push_back(SourceVec.
getVectorElt(Base + I));
12497 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12500 case clang::X86::BI__builtin_ia32_pavgb128:
12501 case clang::X86::BI__builtin_ia32_pavgw128:
12502 case clang::X86::BI__builtin_ia32_pavgb256:
12503 case clang::X86::BI__builtin_ia32_pavgw256:
12504 case clang::X86::BI__builtin_ia32_pavgb512:
12505 case clang::X86::BI__builtin_ia32_pavgw512:
12506 return EvaluateBinOpExpr(llvm::APIntOps::avgCeilU);
12508 case clang::X86::BI__builtin_ia32_pmulhrsw128:
12509 case clang::X86::BI__builtin_ia32_pmulhrsw256:
12510 case clang::X86::BI__builtin_ia32_pmulhrsw512:
12511 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12512 return (llvm::APIntOps::mulsExtended(LHS, RHS).ashr(14) + 1)
12513 .extractBits(16, 1);
12516 case clang::X86::BI__builtin_ia32_pmaddubsw128:
12517 case clang::X86::BI__builtin_ia32_pmaddubsw256:
12518 case clang::X86::BI__builtin_ia32_pmaddubsw512:
12519 case clang::X86::BI__builtin_ia32_pmaddwd128:
12520 case clang::X86::BI__builtin_ia32_pmaddwd256:
12521 case clang::X86::BI__builtin_ia32_pmaddwd512: {
12522 APValue SourceLHS, SourceRHS;
12528 QualType DestEltTy = DestTy->getElementType();
12530 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
12532 ResultElements.reserve(SourceLen / 2);
12534 for (
unsigned EltNum = 0; EltNum < SourceLen; EltNum += 2) {
12539 unsigned BitWidth = 2 * LoLHS.getBitWidth();
12542 case clang::X86::BI__builtin_ia32_pmaddubsw128:
12543 case clang::X86::BI__builtin_ia32_pmaddubsw256:
12544 case clang::X86::BI__builtin_ia32_pmaddubsw512:
12545 ResultElements.push_back(
APValue(
12546 APSInt((LoLHS.zext(BitWidth) * LoRHS.sext(BitWidth))
12547 .sadd_sat((HiLHS.zext(BitWidth) * HiRHS.sext(BitWidth))),
12550 case clang::X86::BI__builtin_ia32_pmaddwd128:
12551 case clang::X86::BI__builtin_ia32_pmaddwd256:
12552 case clang::X86::BI__builtin_ia32_pmaddwd512:
12553 ResultElements.push_back(
12554 APValue(
APSInt((LoLHS.sext(BitWidth) * LoRHS.sext(BitWidth)) +
12555 (HiLHS.sext(BitWidth) * HiRHS.sext(BitWidth)),
12561 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12564 case clang::X86::BI__builtin_ia32_pmulhuw128:
12565 case clang::X86::BI__builtin_ia32_pmulhuw256:
12566 case clang::X86::BI__builtin_ia32_pmulhuw512:
12567 return EvaluateBinOpExpr(llvm::APIntOps::mulhu);
12569 case clang::X86::BI__builtin_ia32_pmulhw128:
12570 case clang::X86::BI__builtin_ia32_pmulhw256:
12571 case clang::X86::BI__builtin_ia32_pmulhw512:
12572 return EvaluateBinOpExpr(llvm::APIntOps::mulhs);
12574 case clang::X86::BI__builtin_ia32_psllv2di:
12575 case clang::X86::BI__builtin_ia32_psllv4di:
12576 case clang::X86::BI__builtin_ia32_psllv4si:
12577 case clang::X86::BI__builtin_ia32_psllv8di:
12578 case clang::X86::BI__builtin_ia32_psllv8hi:
12579 case clang::X86::BI__builtin_ia32_psllv8si:
12580 case clang::X86::BI__builtin_ia32_psllv16hi:
12581 case clang::X86::BI__builtin_ia32_psllv16si:
12582 case clang::X86::BI__builtin_ia32_psllv32hi:
12583 case clang::X86::BI__builtin_ia32_psllwi128:
12584 case clang::X86::BI__builtin_ia32_pslldi128:
12585 case clang::X86::BI__builtin_ia32_psllqi128:
12586 case clang::X86::BI__builtin_ia32_psllwi256:
12587 case clang::X86::BI__builtin_ia32_pslldi256:
12588 case clang::X86::BI__builtin_ia32_psllqi256:
12589 case clang::X86::BI__builtin_ia32_psllwi512:
12590 case clang::X86::BI__builtin_ia32_pslldi512:
12591 case clang::X86::BI__builtin_ia32_psllqi512:
12592 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12593 if (RHS.uge(LHS.getBitWidth())) {
12594 return APInt::getZero(LHS.getBitWidth());
12596 return LHS.shl(RHS.getZExtValue());
12599 case clang::X86::BI__builtin_ia32_psrav4si:
12600 case clang::X86::BI__builtin_ia32_psrav8di:
12601 case clang::X86::BI__builtin_ia32_psrav8hi:
12602 case clang::X86::BI__builtin_ia32_psrav8si:
12603 case clang::X86::BI__builtin_ia32_psrav16hi:
12604 case clang::X86::BI__builtin_ia32_psrav16si:
12605 case clang::X86::BI__builtin_ia32_psrav32hi:
12606 case clang::X86::BI__builtin_ia32_psravq128:
12607 case clang::X86::BI__builtin_ia32_psravq256:
12608 case clang::X86::BI__builtin_ia32_psrawi128:
12609 case clang::X86::BI__builtin_ia32_psradi128:
12610 case clang::X86::BI__builtin_ia32_psraqi128:
12611 case clang::X86::BI__builtin_ia32_psrawi256:
12612 case clang::X86::BI__builtin_ia32_psradi256:
12613 case clang::X86::BI__builtin_ia32_psraqi256:
12614 case clang::X86::BI__builtin_ia32_psrawi512:
12615 case clang::X86::BI__builtin_ia32_psradi512:
12616 case clang::X86::BI__builtin_ia32_psraqi512:
12617 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12618 if (RHS.uge(LHS.getBitWidth())) {
12619 return LHS.ashr(LHS.getBitWidth() - 1);
12621 return LHS.ashr(RHS.getZExtValue());
12624 case clang::X86::BI__builtin_ia32_psrlv2di:
12625 case clang::X86::BI__builtin_ia32_psrlv4di:
12626 case clang::X86::BI__builtin_ia32_psrlv4si:
12627 case clang::X86::BI__builtin_ia32_psrlv8di:
12628 case clang::X86::BI__builtin_ia32_psrlv8hi:
12629 case clang::X86::BI__builtin_ia32_psrlv8si:
12630 case clang::X86::BI__builtin_ia32_psrlv16hi:
12631 case clang::X86::BI__builtin_ia32_psrlv16si:
12632 case clang::X86::BI__builtin_ia32_psrlv32hi:
12633 case clang::X86::BI__builtin_ia32_psrlwi128:
12634 case clang::X86::BI__builtin_ia32_psrldi128:
12635 case clang::X86::BI__builtin_ia32_psrlqi128:
12636 case clang::X86::BI__builtin_ia32_psrlwi256:
12637 case clang::X86::BI__builtin_ia32_psrldi256:
12638 case clang::X86::BI__builtin_ia32_psrlqi256:
12639 case clang::X86::BI__builtin_ia32_psrlwi512:
12640 case clang::X86::BI__builtin_ia32_psrldi512:
12641 case clang::X86::BI__builtin_ia32_psrlqi512:
12642 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12643 if (RHS.uge(LHS.getBitWidth())) {
12644 return APInt::getZero(LHS.getBitWidth());
12646 return LHS.lshr(RHS.getZExtValue());
12648 case X86::BI__builtin_ia32_packsswb128:
12649 case X86::BI__builtin_ia32_packsswb256:
12650 case X86::BI__builtin_ia32_packsswb512:
12651 case X86::BI__builtin_ia32_packssdw128:
12652 case X86::BI__builtin_ia32_packssdw256:
12653 case X86::BI__builtin_ia32_packssdw512:
12655 return APSInt(Src).truncSSat(Src.getBitWidth() / 2);
12657 case X86::BI__builtin_ia32_packusdw128:
12658 case X86::BI__builtin_ia32_packusdw256:
12659 case X86::BI__builtin_ia32_packusdw512:
12660 case X86::BI__builtin_ia32_packuswb128:
12661 case X86::BI__builtin_ia32_packuswb256:
12662 case X86::BI__builtin_ia32_packuswb512:
12664 return APSInt(Src).truncSSatU(Src.getBitWidth() / 2);
12666 case clang::X86::BI__builtin_ia32_selectss_128:
12667 return EvalSelectScalar(4);
12668 case clang::X86::BI__builtin_ia32_selectsd_128:
12669 return EvalSelectScalar(2);
12670 case clang::X86::BI__builtin_ia32_selectsh_128:
12671 case clang::X86::BI__builtin_ia32_selectsbf_128:
12672 return EvalSelectScalar(8);
12673 case clang::X86::BI__builtin_ia32_pmuldq128:
12674 case clang::X86::BI__builtin_ia32_pmuldq256:
12675 case clang::X86::BI__builtin_ia32_pmuldq512:
12676 case clang::X86::BI__builtin_ia32_pmuludq128:
12677 case clang::X86::BI__builtin_ia32_pmuludq256:
12678 case clang::X86::BI__builtin_ia32_pmuludq512: {
12679 APValue SourceLHS, SourceRHS;
12686 ResultElements.reserve(SourceLen / 2);
12688 for (
unsigned EltNum = 0; EltNum < SourceLen; EltNum += 2) {
12693 case clang::X86::BI__builtin_ia32_pmuludq128:
12694 case clang::X86::BI__builtin_ia32_pmuludq256:
12695 case clang::X86::BI__builtin_ia32_pmuludq512:
12696 ResultElements.push_back(
12697 APValue(
APSInt(llvm::APIntOps::muluExtended(LHS, RHS),
true)));
12699 case clang::X86::BI__builtin_ia32_pmuldq128:
12700 case clang::X86::BI__builtin_ia32_pmuldq256:
12701 case clang::X86::BI__builtin_ia32_pmuldq512:
12702 ResultElements.push_back(
12703 APValue(
APSInt(llvm::APIntOps::mulsExtended(LHS, RHS),
false)));
12708 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12711 case X86::BI__builtin_ia32_vpmadd52luq128:
12712 case X86::BI__builtin_ia32_vpmadd52luq256:
12713 case X86::BI__builtin_ia32_vpmadd52luq512: {
12722 ResultElements.reserve(ALen);
12724 for (
unsigned EltNum = 0; EltNum < ALen; EltNum += 1) {
12727 APInt CElt =
C.getVectorElt(EltNum).getInt().trunc(52);
12728 APSInt ResElt(AElt + (BElt * CElt).zext(64),
false);
12729 ResultElements.push_back(
APValue(ResElt));
12732 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12734 case X86::BI__builtin_ia32_vpmadd52huq128:
12735 case X86::BI__builtin_ia32_vpmadd52huq256:
12736 case X86::BI__builtin_ia32_vpmadd52huq512: {
12745 ResultElements.reserve(ALen);
12747 for (
unsigned EltNum = 0; EltNum < ALen; EltNum += 1) {
12750 APInt CElt =
C.getVectorElt(EltNum).getInt().trunc(52);
12751 APSInt ResElt(AElt + llvm::APIntOps::mulhu(BElt, CElt).zext(64),
false);
12752 ResultElements.push_back(
APValue(ResElt));
12755 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12758 case clang::X86::BI__builtin_ia32_vprotbi:
12759 case clang::X86::BI__builtin_ia32_vprotdi:
12760 case clang::X86::BI__builtin_ia32_vprotqi:
12761 case clang::X86::BI__builtin_ia32_vprotwi:
12762 case clang::X86::BI__builtin_ia32_prold128:
12763 case clang::X86::BI__builtin_ia32_prold256:
12764 case clang::X86::BI__builtin_ia32_prold512:
12765 case clang::X86::BI__builtin_ia32_prolq128:
12766 case clang::X86::BI__builtin_ia32_prolq256:
12767 case clang::X86::BI__builtin_ia32_prolq512:
12768 return EvaluateBinOpExpr(
12769 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS.rotl(RHS); });
12771 case clang::X86::BI__builtin_ia32_prord128:
12772 case clang::X86::BI__builtin_ia32_prord256:
12773 case clang::X86::BI__builtin_ia32_prord512:
12774 case clang::X86::BI__builtin_ia32_prorq128:
12775 case clang::X86::BI__builtin_ia32_prorq256:
12776 case clang::X86::BI__builtin_ia32_prorq512:
12777 return EvaluateBinOpExpr(
12778 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS.rotr(RHS); });
12780 case Builtin::BI__builtin_elementwise_max:
12781 case Builtin::BI__builtin_elementwise_min: {
12782 APValue SourceLHS, SourceRHS;
12787 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12794 ResultElements.reserve(SourceLen);
12796 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12800 case Builtin::BI__builtin_elementwise_max:
12801 ResultElements.push_back(
12805 case Builtin::BI__builtin_elementwise_min:
12806 ResultElements.push_back(
12813 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12815 case X86::BI__builtin_ia32_vpshldd128:
12816 case X86::BI__builtin_ia32_vpshldd256:
12817 case X86::BI__builtin_ia32_vpshldd512:
12818 case X86::BI__builtin_ia32_vpshldq128:
12819 case X86::BI__builtin_ia32_vpshldq256:
12820 case X86::BI__builtin_ia32_vpshldq512:
12821 case X86::BI__builtin_ia32_vpshldw128:
12822 case X86::BI__builtin_ia32_vpshldw256:
12823 case X86::BI__builtin_ia32_vpshldw512: {
12824 APValue SourceHi, SourceLo, SourceAmt;
12830 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12833 ResultElements.reserve(SourceLen);
12836 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12839 APInt R = llvm::APIntOps::fshl(Hi, Lo, Amt);
12840 ResultElements.push_back(
12844 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12846 case X86::BI__builtin_ia32_vpshrdd128:
12847 case X86::BI__builtin_ia32_vpshrdd256:
12848 case X86::BI__builtin_ia32_vpshrdd512:
12849 case X86::BI__builtin_ia32_vpshrdq128:
12850 case X86::BI__builtin_ia32_vpshrdq256:
12851 case X86::BI__builtin_ia32_vpshrdq512:
12852 case X86::BI__builtin_ia32_vpshrdw128:
12853 case X86::BI__builtin_ia32_vpshrdw256:
12854 case X86::BI__builtin_ia32_vpshrdw512: {
12856 APValue SourceHi, SourceLo, SourceAmt;
12862 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12865 ResultElements.reserve(SourceLen);
12868 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12871 APInt R = llvm::APIntOps::fshr(Hi, Lo, Amt);
12872 ResultElements.push_back(
12876 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12878 case X86::BI__builtin_ia32_vpconflictsi_128:
12879 case X86::BI__builtin_ia32_vpconflictsi_256:
12880 case X86::BI__builtin_ia32_vpconflictsi_512:
12881 case X86::BI__builtin_ia32_vpconflictdi_128:
12882 case X86::BI__builtin_ia32_vpconflictdi_256:
12883 case X86::BI__builtin_ia32_vpconflictdi_512: {
12891 ResultElements.reserve(SourceLen);
12894 bool DestUnsigned =
12895 VecT->getElementType()->isUnsignedIntegerOrEnumerationType();
12897 for (
unsigned I = 0; I != SourceLen; ++I) {
12900 APInt ConflictMask(EltI.
getInt().getBitWidth(), 0);
12901 for (
unsigned J = 0; J != I; ++J) {
12903 ConflictMask.setBitVal(J, EltI.
getInt() == EltJ.
getInt());
12905 ResultElements.push_back(
APValue(
APSInt(ConflictMask, DestUnsigned)));
12907 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12909 case X86::BI__builtin_ia32_blendpd:
12910 case X86::BI__builtin_ia32_blendpd256:
12911 case X86::BI__builtin_ia32_blendps:
12912 case X86::BI__builtin_ia32_blendps256:
12913 case X86::BI__builtin_ia32_pblendw128:
12914 case X86::BI__builtin_ia32_pblendw256:
12915 case X86::BI__builtin_ia32_pblendd128:
12916 case X86::BI__builtin_ia32_pblendd256: {
12917 APValue SourceF, SourceT, SourceC;
12926 ResultElements.reserve(SourceLen);
12927 for (
unsigned EltNum = 0; EltNum != SourceLen; ++EltNum) {
12930 ResultElements.push_back(
C[EltNum % 8] ?
T : F);
12933 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12936 case X86::BI__builtin_ia32_psignb128:
12937 case X86::BI__builtin_ia32_psignb256:
12938 case X86::BI__builtin_ia32_psignw128:
12939 case X86::BI__builtin_ia32_psignw256:
12940 case X86::BI__builtin_ia32_psignd128:
12941 case X86::BI__builtin_ia32_psignd256:
12942 return EvaluateBinOpExpr([](
const APInt &AElem,
const APInt &BElem) {
12943 if (BElem.isZero())
12944 return APInt::getZero(AElem.getBitWidth());
12945 if (BElem.isNegative())
12950 case X86::BI__builtin_ia32_blendvpd:
12951 case X86::BI__builtin_ia32_blendvpd256:
12952 case X86::BI__builtin_ia32_blendvps:
12953 case X86::BI__builtin_ia32_blendvps256:
12954 case X86::BI__builtin_ia32_pblendvb128:
12955 case X86::BI__builtin_ia32_pblendvb256: {
12957 APValue SourceF, SourceT, SourceC;
12965 ResultElements.reserve(SourceLen);
12967 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12971 APInt M =
C.isInt() ? (
APInt)
C.getInt() :
C.getFloat().bitcastToAPInt();
12972 ResultElements.push_back(M.isNegative() ?
T : F);
12975 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12977 case X86::BI__builtin_ia32_selectb_128:
12978 case X86::BI__builtin_ia32_selectb_256:
12979 case X86::BI__builtin_ia32_selectb_512:
12980 case X86::BI__builtin_ia32_selectw_128:
12981 case X86::BI__builtin_ia32_selectw_256:
12982 case X86::BI__builtin_ia32_selectw_512:
12983 case X86::BI__builtin_ia32_selectd_128:
12984 case X86::BI__builtin_ia32_selectd_256:
12985 case X86::BI__builtin_ia32_selectd_512:
12986 case X86::BI__builtin_ia32_selectq_128:
12987 case X86::BI__builtin_ia32_selectq_256:
12988 case X86::BI__builtin_ia32_selectq_512:
12989 case X86::BI__builtin_ia32_selectph_128:
12990 case X86::BI__builtin_ia32_selectph_256:
12991 case X86::BI__builtin_ia32_selectph_512:
12992 case X86::BI__builtin_ia32_selectpbf_128:
12993 case X86::BI__builtin_ia32_selectpbf_256:
12994 case X86::BI__builtin_ia32_selectpbf_512:
12995 case X86::BI__builtin_ia32_selectps_128:
12996 case X86::BI__builtin_ia32_selectps_256:
12997 case X86::BI__builtin_ia32_selectps_512:
12998 case X86::BI__builtin_ia32_selectpd_128:
12999 case X86::BI__builtin_ia32_selectpd_256:
13000 case X86::BI__builtin_ia32_selectpd_512: {
13002 APValue SourceMask, SourceLHS, SourceRHS;
13011 ResultElements.reserve(SourceLen);
13013 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13016 ResultElements.push_back(Mask[EltNum] ? LHS : RHS);
13019 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13022 case X86::BI__builtin_ia32_cvtsd2ss: {
13035 Elements.push_back(ResultVal);
13038 for (
unsigned I = 1; I < NumEltsA; ++I) {
13044 case X86::BI__builtin_ia32_cvtsd2ss_round_mask: {
13045 APValue VecA, VecB, VecSrc, MaskValue;
13053 unsigned Mask = MaskValue.
getInt().getZExtValue();
13061 Elements.push_back(ResultVal);
13067 for (
unsigned I = 1; I < NumEltsA; ++I) {
13073 case X86::BI__builtin_ia32_cvtpd2ps:
13074 case X86::BI__builtin_ia32_cvtpd2ps256:
13075 case X86::BI__builtin_ia32_cvtpd2ps_mask:
13076 case X86::BI__builtin_ia32_cvtpd2ps512_mask: {
13079 bool IsMasked = (BuiltinID == X86::BI__builtin_ia32_cvtpd2ps_mask ||
13080 BuiltinID == X86::BI__builtin_ia32_cvtpd2ps512_mask);
13087 unsigned Mask = 0xFFFFFFFF;
13088 bool NeedsMerge =
false;
13093 Mask = MaskValue.
getInt().getZExtValue();
13094 auto NumEltsResult = E->
getType()->
getAs<VectorType>()->getNumElements();
13095 for (
unsigned I = 0; I < NumEltsResult; ++I) {
13096 if (!((Mask >> I) & 1)) {
13107 unsigned NumEltsResult =
13111 for (
unsigned I = 0; I < NumEltsResult; ++I) {
13112 if (IsMasked && !((Mask >> I) & 1)) {
13120 if (I >= NumEltsInput) {
13121 Elements.push_back(
APValue(APFloat::getZero(APFloat::IEEEsingle())));
13130 Elements.push_back(ResultVal);
13135 case X86::BI__builtin_ia32_shufps:
13136 case X86::BI__builtin_ia32_shufps256:
13137 case X86::BI__builtin_ia32_shufps512: {
13141 [](
unsigned DstIdx,
13142 unsigned ShuffleMask) -> std::pair<unsigned, int> {
13143 constexpr unsigned LaneBits = 128u;
13144 unsigned NumElemPerLane = LaneBits / 32;
13145 unsigned NumSelectableElems = NumElemPerLane / 2;
13146 unsigned BitsPerElem = 2;
13147 unsigned IndexMask = (1u << BitsPerElem) - 1;
13148 unsigned MaskBits = 8;
13149 unsigned Lane = DstIdx / NumElemPerLane;
13150 unsigned ElemInLane = DstIdx % NumElemPerLane;
13151 unsigned LaneOffset = Lane * NumElemPerLane;
13152 unsigned BitIndex = (DstIdx * BitsPerElem) % MaskBits;
13153 unsigned SrcIdx = (ElemInLane < NumSelectableElems) ? 0 : 1;
13154 unsigned Index = (ShuffleMask >> BitIndex) & IndexMask;
13155 return {SrcIdx,
static_cast<int>(LaneOffset + Index)};
13160 case X86::BI__builtin_ia32_shufpd:
13161 case X86::BI__builtin_ia32_shufpd256:
13162 case X86::BI__builtin_ia32_shufpd512: {
13166 [](
unsigned DstIdx,
13167 unsigned ShuffleMask) -> std::pair<unsigned, int> {
13168 constexpr unsigned LaneBits = 128u;
13169 unsigned NumElemPerLane = LaneBits / 64;
13170 unsigned NumSelectableElems = NumElemPerLane / 2;
13171 unsigned BitsPerElem = 1;
13172 unsigned IndexMask = (1u << BitsPerElem) - 1;
13173 unsigned MaskBits = 8;
13174 unsigned Lane = DstIdx / NumElemPerLane;
13175 unsigned ElemInLane = DstIdx % NumElemPerLane;
13176 unsigned LaneOffset = Lane * NumElemPerLane;
13177 unsigned BitIndex = (DstIdx * BitsPerElem) % MaskBits;
13178 unsigned SrcIdx = (ElemInLane < NumSelectableElems) ? 0 : 1;
13179 unsigned Index = (ShuffleMask >> BitIndex) & IndexMask;
13180 return {SrcIdx,
static_cast<int>(LaneOffset + Index)};
13185 case X86::BI__builtin_ia32_insertps128: {
13189 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13191 if ((Mask & (1 << DstIdx)) != 0) {
13196 unsigned SrcElem = (Mask >> 6) & 0x3;
13197 unsigned DstElem = (Mask >> 4) & 0x3;
13198 if (DstIdx == DstElem) {
13200 return {1,
static_cast<int>(SrcElem)};
13203 return {0,
static_cast<int>(DstIdx)};
13209 case X86::BI__builtin_ia32_pshufb128:
13210 case X86::BI__builtin_ia32_pshufb256:
13211 case X86::BI__builtin_ia32_pshufb512: {
13215 [](
unsigned DstIdx,
13216 unsigned ShuffleMask) -> std::pair<unsigned, int> {
13217 uint8_t Ctlb =
static_cast<uint8_t
>(ShuffleMask);
13219 return std::make_pair(0, -1);
13221 unsigned LaneBase = (DstIdx / 16) * 16;
13222 unsigned SrcOffset = Ctlb & 0x0F;
13223 unsigned SrcIdx = LaneBase + SrcOffset;
13224 return std::make_pair(0,
static_cast<int>(SrcIdx));
13230 case X86::BI__builtin_ia32_pshuflw:
13231 case X86::BI__builtin_ia32_pshuflw256:
13232 case X86::BI__builtin_ia32_pshuflw512: {
13236 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13237 constexpr unsigned LaneBits = 128u;
13238 constexpr unsigned ElemBits = 16u;
13239 constexpr unsigned LaneElts = LaneBits / ElemBits;
13240 constexpr unsigned HalfSize = 4;
13241 unsigned LaneBase = (DstIdx / LaneElts) * LaneElts;
13242 unsigned LaneIdx = DstIdx % LaneElts;
13243 if (LaneIdx < HalfSize) {
13244 unsigned Sel = (Mask >> (2 * LaneIdx)) & 0x3;
13245 return std::make_pair(0,
static_cast<int>(LaneBase + Sel));
13247 return std::make_pair(0,
static_cast<int>(DstIdx));
13253 case X86::BI__builtin_ia32_pshufhw:
13254 case X86::BI__builtin_ia32_pshufhw256:
13255 case X86::BI__builtin_ia32_pshufhw512: {
13259 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13260 constexpr unsigned LaneBits = 128u;
13261 constexpr unsigned ElemBits = 16u;
13262 constexpr unsigned LaneElts = LaneBits / ElemBits;
13263 constexpr unsigned HalfSize = 4;
13264 unsigned LaneBase = (DstIdx / LaneElts) * LaneElts;
13265 unsigned LaneIdx = DstIdx % LaneElts;
13266 if (LaneIdx >= HalfSize) {
13267 unsigned Rel = LaneIdx - HalfSize;
13268 unsigned Sel = (Mask >> (2 * Rel)) & 0x3;
13269 return std::make_pair(
13270 0,
static_cast<int>(LaneBase + HalfSize + Sel));
13272 return std::make_pair(0,
static_cast<int>(DstIdx));
13278 case X86::BI__builtin_ia32_pshufd:
13279 case X86::BI__builtin_ia32_pshufd256:
13280 case X86::BI__builtin_ia32_pshufd512:
13281 case X86::BI__builtin_ia32_vpermilps:
13282 case X86::BI__builtin_ia32_vpermilps256:
13283 case X86::BI__builtin_ia32_vpermilps512: {
13287 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13288 constexpr unsigned LaneBits = 128u;
13289 constexpr unsigned ElemBits = 32u;
13290 constexpr unsigned LaneElts = LaneBits / ElemBits;
13291 unsigned LaneBase = (DstIdx / LaneElts) * LaneElts;
13292 unsigned LaneIdx = DstIdx % LaneElts;
13293 unsigned Sel = (Mask >> (2 * LaneIdx)) & 0x3;
13294 return std::make_pair(0,
static_cast<int>(LaneBase + Sel));
13300 case X86::BI__builtin_ia32_vpermilvarpd:
13301 case X86::BI__builtin_ia32_vpermilvarpd256:
13302 case X86::BI__builtin_ia32_vpermilvarpd512: {
13306 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13307 unsigned NumElemPerLane = 2;
13308 unsigned Lane = DstIdx / NumElemPerLane;
13309 unsigned Offset = Mask & 0b10 ? 1 : 0;
13310 return std::make_pair(
13311 0,
static_cast<int>(Lane * NumElemPerLane + Offset));
13317 case X86::BI__builtin_ia32_vpermilpd:
13318 case X86::BI__builtin_ia32_vpermilpd256:
13319 case X86::BI__builtin_ia32_vpermilpd512: {
13322 unsigned NumElemPerLane = 2;
13323 unsigned BitsPerElem = 1;
13324 unsigned MaskBits = 8;
13325 unsigned IndexMask = 0x1;
13326 unsigned Lane = DstIdx / NumElemPerLane;
13327 unsigned LaneOffset = Lane * NumElemPerLane;
13328 unsigned BitIndex = (DstIdx * BitsPerElem) % MaskBits;
13329 unsigned Index = (Control >> BitIndex) & IndexMask;
13330 return std::make_pair(0,
static_cast<int>(LaneOffset + Index));
13336 case X86::BI__builtin_ia32_permdf256:
13337 case X86::BI__builtin_ia32_permdi256: {
13342 unsigned Index = (Control >> (2 * DstIdx)) & 0x3;
13343 return std::make_pair(0,
static_cast<int>(Index));
13349 case X86::BI__builtin_ia32_vpermilvarps:
13350 case X86::BI__builtin_ia32_vpermilvarps256:
13351 case X86::BI__builtin_ia32_vpermilvarps512: {
13355 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13356 unsigned NumElemPerLane = 4;
13357 unsigned Lane = DstIdx / NumElemPerLane;
13358 unsigned Offset = Mask & 0b11;
13359 return std::make_pair(
13360 0,
static_cast<int>(Lane * NumElemPerLane + Offset));
13366 case X86::BI__builtin_ia32_vpmultishiftqb128:
13367 case X86::BI__builtin_ia32_vpmultishiftqb256:
13368 case X86::BI__builtin_ia32_vpmultishiftqb512: {
13376 unsigned NumBytesInQWord = 8;
13377 unsigned NumBitsInByte = 8;
13379 unsigned NumQWords = NumBytes / NumBytesInQWord;
13381 Result.reserve(NumBytes);
13383 for (
unsigned QWordId = 0; QWordId != NumQWords; ++QWordId) {
13384 APInt BQWord(64, 0);
13385 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
13386 unsigned Idx = QWordId * NumBytesInQWord + ByteIdx;
13388 BQWord.insertBits(
APInt(8, Byte & 0xFF), ByteIdx * NumBitsInByte);
13391 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
13392 unsigned Idx = QWordId * NumBytesInQWord + ByteIdx;
13396 for (
unsigned BitIdx = 0; BitIdx != NumBitsInByte; ++BitIdx) {
13397 Byte.setBitVal(BitIdx, BQWord[(Ctrl + BitIdx) & 0x3F]);
13405 case X86::BI__builtin_ia32_phminposuw128: {
13412 unsigned ElemBitWidth = Info.Ctx.
getTypeSize(ElemQT);
13414 APInt MinIndex(ElemBitWidth, 0);
13416 for (
unsigned I = 1; I != SourceLen; ++I) {
13418 if (MinVal.ugt(Val)) {
13427 ->isUnsignedIntegerOrEnumerationType();
13430 Result.reserve(SourceLen);
13432 Result.emplace_back(
APSInt(MinIndex, ResultUnsigned));
13433 for (
unsigned I = 0; I != SourceLen - 2; ++I) {
13439 case X86::BI__builtin_ia32_psraq128:
13440 case X86::BI__builtin_ia32_psraq256:
13441 case X86::BI__builtin_ia32_psraq512:
13442 case X86::BI__builtin_ia32_psrad128:
13443 case X86::BI__builtin_ia32_psrad256:
13444 case X86::BI__builtin_ia32_psrad512:
13445 case X86::BI__builtin_ia32_psraw128:
13446 case X86::BI__builtin_ia32_psraw256:
13447 case X86::BI__builtin_ia32_psraw512: {
13451 [](
const APInt &Elt, uint64_t Count) {
return Elt.ashr(Count); },
13452 [](
const APInt &Elt,
unsigned Width) {
13453 return Elt.ashr(Width - 1);
13459 case X86::BI__builtin_ia32_psllq128:
13460 case X86::BI__builtin_ia32_psllq256:
13461 case X86::BI__builtin_ia32_psllq512:
13462 case X86::BI__builtin_ia32_pslld128:
13463 case X86::BI__builtin_ia32_pslld256:
13464 case X86::BI__builtin_ia32_pslld512:
13465 case X86::BI__builtin_ia32_psllw128:
13466 case X86::BI__builtin_ia32_psllw256:
13467 case X86::BI__builtin_ia32_psllw512: {
13471 [](
const APInt &Elt, uint64_t Count) {
return Elt.shl(Count); },
13472 [](
const APInt &Elt,
unsigned Width) {
13473 return APInt::getZero(Width);
13479 case X86::BI__builtin_ia32_psrlq128:
13480 case X86::BI__builtin_ia32_psrlq256:
13481 case X86::BI__builtin_ia32_psrlq512:
13482 case X86::BI__builtin_ia32_psrld128:
13483 case X86::BI__builtin_ia32_psrld256:
13484 case X86::BI__builtin_ia32_psrld512:
13485 case X86::BI__builtin_ia32_psrlw128:
13486 case X86::BI__builtin_ia32_psrlw256:
13487 case X86::BI__builtin_ia32_psrlw512: {
13491 [](
const APInt &Elt, uint64_t Count) {
return Elt.lshr(Count); },
13492 [](
const APInt &Elt,
unsigned Width) {
13493 return APInt::getZero(Width);
13499 case X86::BI__builtin_ia32_pternlogd128_mask:
13500 case X86::BI__builtin_ia32_pternlogd256_mask:
13501 case X86::BI__builtin_ia32_pternlogd512_mask:
13502 case X86::BI__builtin_ia32_pternlogq128_mask:
13503 case X86::BI__builtin_ia32_pternlogq256_mask:
13504 case X86::BI__builtin_ia32_pternlogq512_mask: {
13505 APValue AValue, BValue, CValue, ImmValue, UValue;
13513 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13519 ResultElements.reserve(ResultLen);
13521 for (
unsigned EltNum = 0; EltNum < ResultLen; ++EltNum) {
13527 unsigned BitWidth = ALane.getBitWidth();
13528 APInt ResLane(BitWidth, 0);
13530 for (
unsigned Bit = 0; Bit < BitWidth; ++Bit) {
13531 unsigned ABit = ALane[Bit];
13532 unsigned BBit = BLane[Bit];
13533 unsigned CBit = CLane[Bit];
13535 unsigned Idx = (ABit << 2) | (BBit << 1) | CBit;
13536 ResLane.setBitVal(Bit, Imm[Idx]);
13538 ResultElements.push_back(
APValue(
APSInt(ResLane, DestUnsigned)));
13540 ResultElements.push_back(
APValue(
APSInt(ALane, DestUnsigned)));
13543 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13545 case X86::BI__builtin_ia32_pternlogd128_maskz:
13546 case X86::BI__builtin_ia32_pternlogd256_maskz:
13547 case X86::BI__builtin_ia32_pternlogd512_maskz:
13548 case X86::BI__builtin_ia32_pternlogq128_maskz:
13549 case X86::BI__builtin_ia32_pternlogq256_maskz:
13550 case X86::BI__builtin_ia32_pternlogq512_maskz: {
13551 APValue AValue, BValue, CValue, ImmValue, UValue;
13559 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13565 ResultElements.reserve(ResultLen);
13567 for (
unsigned EltNum = 0; EltNum < ResultLen; ++EltNum) {
13572 unsigned BitWidth = ALane.getBitWidth();
13573 APInt ResLane(BitWidth, 0);
13576 for (
unsigned Bit = 0; Bit < BitWidth; ++Bit) {
13577 unsigned ABit = ALane[Bit];
13578 unsigned BBit = BLane[Bit];
13579 unsigned CBit = CLane[Bit];
13581 unsigned Idx = (ABit << 2) | (BBit << 1) | CBit;
13582 ResLane.setBitVal(Bit, Imm[Idx]);
13585 ResultElements.push_back(
APValue(
APSInt(ResLane, DestUnsigned)));
13587 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13590 case Builtin::BI__builtin_elementwise_clzg:
13591 case Builtin::BI__builtin_elementwise_ctzg: {
13593 std::optional<APValue> Fallback;
13600 Fallback = FallbackTmp;
13603 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13606 ResultElements.reserve(SourceLen);
13608 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13613 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
13615 Builtin::BI__builtin_elementwise_ctzg);
13618 ResultElements.push_back(Fallback->getVectorElt(EltNum));
13622 case Builtin::BI__builtin_elementwise_clzg:
13623 ResultElements.push_back(
APValue(
13627 case Builtin::BI__builtin_elementwise_ctzg:
13628 ResultElements.push_back(
APValue(
13635 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13638 case Builtin::BI__builtin_elementwise_fma: {
13639 APValue SourceX, SourceY, SourceZ;
13647 ResultElements.reserve(SourceLen);
13649 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13654 (void)
Result.fusedMultiplyAdd(Y, Z, RM);
13657 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13660 case clang::X86::BI__builtin_ia32_phaddw128:
13661 case clang::X86::BI__builtin_ia32_phaddw256:
13662 case clang::X86::BI__builtin_ia32_phaddd128:
13663 case clang::X86::BI__builtin_ia32_phaddd256:
13664 case clang::X86::BI__builtin_ia32_phaddsw128:
13665 case clang::X86::BI__builtin_ia32_phaddsw256:
13667 case clang::X86::BI__builtin_ia32_phsubw128:
13668 case clang::X86::BI__builtin_ia32_phsubw256:
13669 case clang::X86::BI__builtin_ia32_phsubd128:
13670 case clang::X86::BI__builtin_ia32_phsubd256:
13671 case clang::X86::BI__builtin_ia32_phsubsw128:
13672 case clang::X86::BI__builtin_ia32_phsubsw256: {
13673 APValue SourceLHS, SourceRHS;
13677 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13681 unsigned EltBits = Info.Ctx.
getIntWidth(DestEltTy);
13682 unsigned EltsPerLane = 128 / EltBits;
13684 ResultElements.reserve(NumElts);
13686 for (
unsigned LaneStart = 0; LaneStart != NumElts;
13687 LaneStart += EltsPerLane) {
13688 for (
unsigned I = 0; I != EltsPerLane; I += 2) {
13692 case clang::X86::BI__builtin_ia32_phaddw128:
13693 case clang::X86::BI__builtin_ia32_phaddw256:
13694 case clang::X86::BI__builtin_ia32_phaddd128:
13695 case clang::X86::BI__builtin_ia32_phaddd256: {
13696 APSInt Res(LHSA + LHSB, DestUnsigned);
13697 ResultElements.push_back(
APValue(Res));
13700 case clang::X86::BI__builtin_ia32_phaddsw128:
13701 case clang::X86::BI__builtin_ia32_phaddsw256: {
13702 APSInt Res(LHSA.sadd_sat(LHSB));
13703 ResultElements.push_back(
APValue(Res));
13706 case clang::X86::BI__builtin_ia32_phsubw128:
13707 case clang::X86::BI__builtin_ia32_phsubw256:
13708 case clang::X86::BI__builtin_ia32_phsubd128:
13709 case clang::X86::BI__builtin_ia32_phsubd256: {
13710 APSInt Res(LHSA - LHSB, DestUnsigned);
13711 ResultElements.push_back(
APValue(Res));
13714 case clang::X86::BI__builtin_ia32_phsubsw128:
13715 case clang::X86::BI__builtin_ia32_phsubsw256: {
13716 APSInt Res(LHSA.ssub_sat(LHSB));
13717 ResultElements.push_back(
APValue(Res));
13722 for (
unsigned I = 0; I != EltsPerLane; I += 2) {
13726 case clang::X86::BI__builtin_ia32_phaddw128:
13727 case clang::X86::BI__builtin_ia32_phaddw256:
13728 case clang::X86::BI__builtin_ia32_phaddd128:
13729 case clang::X86::BI__builtin_ia32_phaddd256: {
13730 APSInt Res(RHSA + RHSB, DestUnsigned);
13731 ResultElements.push_back(
APValue(Res));
13734 case clang::X86::BI__builtin_ia32_phaddsw128:
13735 case clang::X86::BI__builtin_ia32_phaddsw256: {
13736 APSInt Res(RHSA.sadd_sat(RHSB));
13737 ResultElements.push_back(
APValue(Res));
13740 case clang::X86::BI__builtin_ia32_phsubw128:
13741 case clang::X86::BI__builtin_ia32_phsubw256:
13742 case clang::X86::BI__builtin_ia32_phsubd128:
13743 case clang::X86::BI__builtin_ia32_phsubd256: {
13744 APSInt Res(RHSA - RHSB, DestUnsigned);
13745 ResultElements.push_back(
APValue(Res));
13748 case clang::X86::BI__builtin_ia32_phsubsw128:
13749 case clang::X86::BI__builtin_ia32_phsubsw256: {
13750 APSInt Res(RHSA.ssub_sat(RHSB));
13751 ResultElements.push_back(
APValue(Res));
13757 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13759 case clang::X86::BI__builtin_ia32_haddpd:
13760 case clang::X86::BI__builtin_ia32_haddps:
13761 case clang::X86::BI__builtin_ia32_haddps256:
13762 case clang::X86::BI__builtin_ia32_haddpd256:
13763 case clang::X86::BI__builtin_ia32_hsubpd:
13764 case clang::X86::BI__builtin_ia32_hsubps:
13765 case clang::X86::BI__builtin_ia32_hsubps256:
13766 case clang::X86::BI__builtin_ia32_hsubpd256: {
13767 APValue SourceLHS, SourceRHS;
13773 ResultElements.reserve(NumElts);
13775 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13776 unsigned EltBits = Info.Ctx.
getTypeSize(DestEltTy);
13777 unsigned NumLanes = NumElts * EltBits / 128;
13778 unsigned NumElemsPerLane = NumElts / NumLanes;
13779 unsigned HalfElemsPerLane = NumElemsPerLane / 2;
13781 for (
unsigned L = 0; L != NumElts; L += NumElemsPerLane) {
13782 for (
unsigned I = 0; I != HalfElemsPerLane; ++I) {
13786 case clang::X86::BI__builtin_ia32_haddpd:
13787 case clang::X86::BI__builtin_ia32_haddps:
13788 case clang::X86::BI__builtin_ia32_haddps256:
13789 case clang::X86::BI__builtin_ia32_haddpd256:
13790 LHSA.add(LHSB, RM);
13792 case clang::X86::BI__builtin_ia32_hsubpd:
13793 case clang::X86::BI__builtin_ia32_hsubps:
13794 case clang::X86::BI__builtin_ia32_hsubps256:
13795 case clang::X86::BI__builtin_ia32_hsubpd256:
13796 LHSA.subtract(LHSB, RM);
13799 ResultElements.push_back(
APValue(LHSA));
13801 for (
unsigned I = 0; I != HalfElemsPerLane; ++I) {
13805 case clang::X86::BI__builtin_ia32_haddpd:
13806 case clang::X86::BI__builtin_ia32_haddps:
13807 case clang::X86::BI__builtin_ia32_haddps256:
13808 case clang::X86::BI__builtin_ia32_haddpd256:
13809 RHSA.add(RHSB, RM);
13811 case clang::X86::BI__builtin_ia32_hsubpd:
13812 case clang::X86::BI__builtin_ia32_hsubps:
13813 case clang::X86::BI__builtin_ia32_hsubps256:
13814 case clang::X86::BI__builtin_ia32_hsubpd256:
13815 RHSA.subtract(RHSB, RM);
13818 ResultElements.push_back(
APValue(RHSA));
13821 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13823 case clang::X86::BI__builtin_ia32_addsubpd:
13824 case clang::X86::BI__builtin_ia32_addsubps:
13825 case clang::X86::BI__builtin_ia32_addsubpd256:
13826 case clang::X86::BI__builtin_ia32_addsubps256: {
13829 APValue SourceLHS, SourceRHS;
13835 ResultElements.reserve(NumElems);
13838 for (
unsigned I = 0; I != NumElems; ++I) {
13843 LHS.subtract(RHS, RM);
13848 ResultElements.push_back(
APValue(LHS));
13850 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13852 case clang::X86::BI__builtin_ia32_pclmulqdq128:
13853 case clang::X86::BI__builtin_ia32_pclmulqdq256:
13854 case clang::X86::BI__builtin_ia32_pclmulqdq512: {
13858 APValue SourceLHS, SourceRHS;
13868 bool SelectUpperA = (Imm8 & 0x01) != 0;
13869 bool SelectUpperB = (Imm8 & 0x10) != 0;
13873 ResultElements.reserve(NumElems);
13874 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13878 for (
unsigned Lane = 0; Lane < NumElems; Lane += 2) {
13887 APInt A = SelectUpperA ? A1 : A0;
13888 APInt B = SelectUpperB ? B1 : B0;
13891 APInt A128 = A.zext(128);
13892 APInt B128 = B.zext(128);
13895 APInt Result = llvm::APIntOps::clmul(A128, B128);
13898 APSInt ResultLow(
Result.extractBits(64, 0), DestUnsigned);
13899 APSInt ResultHigh(
Result.extractBits(64, 64), DestUnsigned);
13901 ResultElements.push_back(
APValue(ResultLow));
13902 ResultElements.push_back(
APValue(ResultHigh));
13905 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13907 case Builtin::BI__builtin_elementwise_fshl:
13908 case Builtin::BI__builtin_elementwise_fshr: {
13909 APValue SourceHi, SourceLo, SourceShift;
13915 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13921 ResultElements.reserve(SourceLen);
13922 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13927 case Builtin::BI__builtin_elementwise_fshl:
13928 ResultElements.push_back(
APValue(
13929 APSInt(llvm::APIntOps::fshl(Hi, Lo, Shift), Hi.isUnsigned())));
13931 case Builtin::BI__builtin_elementwise_fshr:
13932 ResultElements.push_back(
APValue(
13933 APSInt(llvm::APIntOps::fshr(Hi, Lo, Shift), Hi.isUnsigned())));
13938 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13941 case X86::BI__builtin_ia32_shuf_f32x4_256:
13942 case X86::BI__builtin_ia32_shuf_i32x4_256:
13943 case X86::BI__builtin_ia32_shuf_f64x2_256:
13944 case X86::BI__builtin_ia32_shuf_i64x2_256:
13945 case X86::BI__builtin_ia32_shuf_f32x4:
13946 case X86::BI__builtin_ia32_shuf_i32x4:
13947 case X86::BI__builtin_ia32_shuf_f64x2:
13948 case X86::BI__builtin_ia32_shuf_i64x2: {
13962 unsigned ElemBits = Info.Ctx.
getTypeSize(ElemQT);
13963 unsigned LaneBits = 128u;
13964 unsigned NumLanes = (NumElems * ElemBits) / LaneBits;
13965 unsigned NumElemsPerLane = LaneBits / ElemBits;
13969 ResultElements.reserve(DstLen);
13974 [NumLanes, NumElemsPerLane](
unsigned DstIdx,
unsigned ShuffleMask)
13975 -> std::pair<unsigned, int> {
13977 unsigned BitsPerElem = NumLanes / 2;
13978 unsigned IndexMask = (1u << BitsPerElem) - 1;
13979 unsigned Lane = DstIdx / NumElemsPerLane;
13980 unsigned SrcIdx = (Lane < NumLanes / 2) ? 0 : 1;
13981 unsigned BitIdx = BitsPerElem * Lane;
13982 unsigned SrcLaneIdx = (ShuffleMask >> BitIdx) & IndexMask;
13983 unsigned ElemInLane = DstIdx % NumElemsPerLane;
13984 unsigned IdxToPick = SrcLaneIdx * NumElemsPerLane + ElemInLane;
13985 return {SrcIdx, IdxToPick};
13991 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v16qi:
13992 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v32qi:
13993 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v64qi:
13994 case X86::BI__builtin_ia32_vgf2p8affineqb_v16qi:
13995 case X86::BI__builtin_ia32_vgf2p8affineqb_v32qi:
13996 case X86::BI__builtin_ia32_vgf2p8affineqb_v64qi: {
14008 bool IsInverse =
false;
14010 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v16qi:
14011 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v32qi:
14012 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v64qi: {
14017 unsigned NumBitsInByte = 8;
14018 unsigned NumBytesInQWord = 8;
14019 unsigned NumBitsInQWord = 64;
14021 unsigned NumQWords = NumBytes / NumBytesInQWord;
14023 Result.reserve(NumBytes);
14026 for (
unsigned QWordIdx = 0; QWordIdx != NumQWords; ++QWordIdx) {
14028 APInt XQWord(NumBitsInQWord, 0);
14029 APInt AQWord(NumBitsInQWord, 0);
14030 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
14031 unsigned Idx = QWordIdx * NumBytesInQWord + ByteIdx;
14032 APInt XByte =
X.getVectorElt(Idx).getInt();
14034 XQWord.insertBits(XByte, ByteIdx * NumBitsInByte);
14035 AQWord.insertBits(AByte, ByteIdx * NumBitsInByte);
14038 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
14040 XQWord.lshr(ByteIdx * NumBitsInByte).getLoBits(8).getZExtValue();
14049 case X86::BI__builtin_ia32_vgf2p8mulb_v16qi:
14050 case X86::BI__builtin_ia32_vgf2p8mulb_v32qi:
14051 case X86::BI__builtin_ia32_vgf2p8mulb_v64qi: {
14062 Result.reserve(NumBytes);
14064 for (
unsigned ByteIdx = 0; ByteIdx != NumBytes; ++ByteIdx) {
14074 case X86::BI__builtin_ia32_insertf32x4_256:
14075 case X86::BI__builtin_ia32_inserti32x4_256:
14076 case X86::BI__builtin_ia32_insertf64x2_256:
14077 case X86::BI__builtin_ia32_inserti64x2_256:
14078 case X86::BI__builtin_ia32_insertf32x4:
14079 case X86::BI__builtin_ia32_inserti32x4:
14080 case X86::BI__builtin_ia32_insertf64x2_512:
14081 case X86::BI__builtin_ia32_inserti64x2_512:
14082 case X86::BI__builtin_ia32_insertf32x8:
14083 case X86::BI__builtin_ia32_inserti32x8:
14084 case X86::BI__builtin_ia32_insertf64x4:
14085 case X86::BI__builtin_ia32_inserti64x4:
14086 case X86::BI__builtin_ia32_vinsertf128_ps256:
14087 case X86::BI__builtin_ia32_vinsertf128_pd256:
14088 case X86::BI__builtin_ia32_vinsertf128_si256:
14089 case X86::BI__builtin_ia32_insert128i256: {
14090 APValue SourceDst, SourceSub;
14102 assert(SubLen != 0 && DstLen != 0 && (DstLen % SubLen) == 0);
14103 unsigned NumLanes = DstLen / SubLen;
14104 unsigned LaneIdx = (Imm.getZExtValue() % NumLanes) * SubLen;
14107 ResultElements.reserve(DstLen);
14109 for (
unsigned EltNum = 0; EltNum < DstLen; ++EltNum) {
14110 if (EltNum >= LaneIdx && EltNum < LaneIdx + SubLen)
14111 ResultElements.push_back(SourceSub.
getVectorElt(EltNum - LaneIdx));
14113 ResultElements.push_back(SourceDst.
getVectorElt(EltNum));
14116 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14119 case clang::X86::BI__builtin_ia32_vec_set_v4hi:
14120 case clang::X86::BI__builtin_ia32_vec_set_v16qi:
14121 case clang::X86::BI__builtin_ia32_vec_set_v8hi:
14122 case clang::X86::BI__builtin_ia32_vec_set_v4si:
14123 case clang::X86::BI__builtin_ia32_vec_set_v2di:
14124 case clang::X86::BI__builtin_ia32_vec_set_v32qi:
14125 case clang::X86::BI__builtin_ia32_vec_set_v16hi:
14126 case clang::X86::BI__builtin_ia32_vec_set_v8si:
14127 case clang::X86::BI__builtin_ia32_vec_set_v4di: {
14135 QualType ElemTy = E->
getType()->
castAs<VectorType>()->getElementType();
14136 unsigned ElemWidth = Info.Ctx.
getIntWidth(ElemTy);
14138 Scalar.setIsUnsigned(ElemUnsigned);
14144 static_cast<unsigned>(IndexAPS.getZExtValue() & (NumElems - 1));
14147 Elems.reserve(NumElems);
14148 for (
unsigned ElemNum = 0; ElemNum != NumElems; ++ElemNum)
14149 Elems.push_back(ElemNum == Index ? ElemAV : VecVal.
getVectorElt(ElemNum));
14154 case X86::BI__builtin_ia32_pslldqi128_byteshift:
14155 case X86::BI__builtin_ia32_pslldqi256_byteshift:
14156 case X86::BI__builtin_ia32_pslldqi512_byteshift: {
14160 [](
unsigned DstIdx,
unsigned Shift) -> std::pair<unsigned, int> {
14161 unsigned LaneBase = (DstIdx / 16) * 16;
14162 unsigned LaneIdx = DstIdx % 16;
14163 if (LaneIdx < Shift)
14164 return std::make_pair(0, -1);
14166 return std::make_pair(
14167 0,
static_cast<int>(LaneBase + LaneIdx - Shift));
14173 case X86::BI__builtin_ia32_psrldqi128_byteshift:
14174 case X86::BI__builtin_ia32_psrldqi256_byteshift:
14175 case X86::BI__builtin_ia32_psrldqi512_byteshift: {
14179 [](
unsigned DstIdx,
unsigned Shift) -> std::pair<unsigned, int> {
14180 unsigned LaneBase = (DstIdx / 16) * 16;
14181 unsigned LaneIdx = DstIdx % 16;
14182 if (LaneIdx + Shift < 16)
14183 return std::make_pair(
14184 0,
static_cast<int>(LaneBase + LaneIdx + Shift));
14186 return std::make_pair(0, -1);
14192 case X86::BI__builtin_ia32_palignr128:
14193 case X86::BI__builtin_ia32_palignr256:
14194 case X86::BI__builtin_ia32_palignr512: {
14198 unsigned VecIdx = 1;
14201 int Lane = DstIdx / 16;
14202 int Offset = DstIdx % 16;
14205 unsigned ShiftedIdx = Offset + (
Shift & 0xFF);
14206 if (ShiftedIdx < 16) {
14207 ElemIdx = ShiftedIdx + (Lane * 16);
14208 }
else if (ShiftedIdx < 32) {
14210 ElemIdx = (ShiftedIdx - 16) + (Lane * 16);
14213 return std::pair<unsigned, int>{VecIdx, ElemIdx};
14218 case X86::BI__builtin_ia32_alignd128:
14219 case X86::BI__builtin_ia32_alignd256:
14220 case X86::BI__builtin_ia32_alignd512:
14221 case X86::BI__builtin_ia32_alignq128:
14222 case X86::BI__builtin_ia32_alignq256:
14223 case X86::BI__builtin_ia32_alignq512: {
14225 unsigned NumElems = E->
getType()->
castAs<VectorType>()->getNumElements();
14227 [NumElems](
unsigned DstIdx,
unsigned Shift) {
14228 unsigned Imm =
Shift & 0xFF;
14229 unsigned EffectiveShift = Imm & (NumElems - 1);
14230 unsigned SourcePos = DstIdx + EffectiveShift;
14231 unsigned VecIdx = SourcePos < NumElems ? 1 : 0;
14232 unsigned ElemIdx = SourcePos & (NumElems - 1);
14234 return std::pair<unsigned, int>{
14235 VecIdx,
static_cast<int>(ElemIdx)};
14240 case X86::BI__builtin_ia32_permvarsi256:
14241 case X86::BI__builtin_ia32_permvarsf256:
14242 case X86::BI__builtin_ia32_permvardf512:
14243 case X86::BI__builtin_ia32_permvardi512:
14244 case X86::BI__builtin_ia32_permvarhi128: {
14247 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14248 int Offset = ShuffleMask & 0x7;
14249 return std::pair<unsigned, int>{0, Offset};
14254 case X86::BI__builtin_ia32_permvarqi128:
14255 case X86::BI__builtin_ia32_permvarhi256:
14256 case X86::BI__builtin_ia32_permvarsi512:
14257 case X86::BI__builtin_ia32_permvarsf512: {
14260 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14261 int Offset = ShuffleMask & 0xF;
14262 return std::pair<unsigned, int>{0, Offset};
14267 case X86::BI__builtin_ia32_permvardi256:
14268 case X86::BI__builtin_ia32_permvardf256: {
14271 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14272 int Offset = ShuffleMask & 0x3;
14273 return std::pair<unsigned, int>{0, Offset};
14278 case X86::BI__builtin_ia32_permvarqi256:
14279 case X86::BI__builtin_ia32_permvarhi512: {
14282 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14283 int Offset = ShuffleMask & 0x1F;
14284 return std::pair<unsigned, int>{0, Offset};
14289 case X86::BI__builtin_ia32_permvarqi512: {
14292 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14293 int Offset = ShuffleMask & 0x3F;
14294 return std::pair<unsigned, int>{0, Offset};
14299 case X86::BI__builtin_ia32_vpermi2varq128:
14300 case X86::BI__builtin_ia32_vpermi2varpd128: {
14303 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14304 int Offset = ShuffleMask & 0x1;
14305 unsigned SrcIdx = (ShuffleMask >> 1) & 0x1;
14306 return std::pair<unsigned, int>{SrcIdx, Offset};
14311 case X86::BI__builtin_ia32_vpermi2vard128:
14312 case X86::BI__builtin_ia32_vpermi2varps128:
14313 case X86::BI__builtin_ia32_vpermi2varq256:
14314 case X86::BI__builtin_ia32_vpermi2varpd256: {
14317 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14318 int Offset = ShuffleMask & 0x3;
14319 unsigned SrcIdx = (ShuffleMask >> 2) & 0x1;
14320 return std::pair<unsigned, int>{SrcIdx, Offset};
14325 case X86::BI__builtin_ia32_vpermi2varhi128:
14326 case X86::BI__builtin_ia32_vpermi2vard256:
14327 case X86::BI__builtin_ia32_vpermi2varps256:
14328 case X86::BI__builtin_ia32_vpermi2varq512:
14329 case X86::BI__builtin_ia32_vpermi2varpd512: {
14332 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14333 int Offset = ShuffleMask & 0x7;
14334 unsigned SrcIdx = (ShuffleMask >> 3) & 0x1;
14335 return std::pair<unsigned, int>{SrcIdx, Offset};
14340 case X86::BI__builtin_ia32_vpermi2varqi128:
14341 case X86::BI__builtin_ia32_vpermi2varhi256:
14342 case X86::BI__builtin_ia32_vpermi2vard512:
14343 case X86::BI__builtin_ia32_vpermi2varps512: {
14346 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14347 int Offset = ShuffleMask & 0xF;
14348 unsigned SrcIdx = (ShuffleMask >> 4) & 0x1;
14349 return std::pair<unsigned, int>{SrcIdx, Offset};
14354 case X86::BI__builtin_ia32_vpermi2varqi256:
14355 case X86::BI__builtin_ia32_vpermi2varhi512: {
14358 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14359 int Offset = ShuffleMask & 0x1F;
14360 unsigned SrcIdx = (ShuffleMask >> 5) & 0x1;
14361 return std::pair<unsigned, int>{SrcIdx, Offset};
14366 case X86::BI__builtin_ia32_vpermi2varqi512: {
14369 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14370 int Offset = ShuffleMask & 0x3F;
14371 unsigned SrcIdx = (ShuffleMask >> 6) & 0x1;
14372 return std::pair<unsigned, int>{SrcIdx, Offset};
14378 case clang::X86::BI__builtin_ia32_minps:
14379 case clang::X86::BI__builtin_ia32_minpd:
14380 case clang::X86::BI__builtin_ia32_minps256:
14381 case clang::X86::BI__builtin_ia32_minpd256:
14382 case clang::X86::BI__builtin_ia32_minps512:
14383 case clang::X86::BI__builtin_ia32_minpd512:
14384 case clang::X86::BI__builtin_ia32_minph128:
14385 case clang::X86::BI__builtin_ia32_minph256:
14386 case clang::X86::BI__builtin_ia32_minph512:
14387 return EvaluateFpBinOpExpr(
14388 [](
const APFloat &A,
const APFloat &B,
14389 std::optional<APSInt>) -> std::optional<APFloat> {
14390 if (A.isNaN() || A.isInfinity() || A.isDenormal() || B.isNaN() ||
14391 B.isInfinity() || B.isDenormal())
14392 return std::nullopt;
14393 if (A.isZero() && B.isZero())
14395 return llvm::minimum(A, B);
14398 case clang::X86::BI__builtin_ia32_maxps:
14399 case clang::X86::BI__builtin_ia32_maxpd:
14400 case clang::X86::BI__builtin_ia32_maxps256:
14401 case clang::X86::BI__builtin_ia32_maxpd256:
14402 case clang::X86::BI__builtin_ia32_maxps512:
14403 case clang::X86::BI__builtin_ia32_maxpd512:
14404 case clang::X86::BI__builtin_ia32_maxph128:
14405 case clang::X86::BI__builtin_ia32_maxph256:
14406 case clang::X86::BI__builtin_ia32_maxph512:
14407 return EvaluateFpBinOpExpr(
14408 [](
const APFloat &A,
const APFloat &B,
14409 std::optional<APSInt>) -> std::optional<APFloat> {
14410 if (A.isNaN() || A.isInfinity() || A.isDenormal() || B.isNaN() ||
14411 B.isInfinity() || B.isDenormal())
14412 return std::nullopt;
14413 if (A.isZero() && B.isZero())
14415 return llvm::maximum(A, B);
14418 case clang::X86::BI__builtin_ia32_vcvtps2ph:
14419 case clang::X86::BI__builtin_ia32_vcvtps2ph256: {
14429 unsigned SrcNumElems = SrcVTy->getNumElements();
14431 unsigned DstNumElems = DstVTy->getNumElements();
14432 QualType DstElemTy = DstVTy->getElementType();
14434 const llvm::fltSemantics &HalfSem =
14437 int ImmVal = Imm.getZExtValue();
14438 bool UseMXCSR = (ImmVal & 4) != 0;
14439 bool IsFPConstrained =
14442 llvm::RoundingMode RM;
14444 switch (ImmVal & 3) {
14446 RM = llvm::RoundingMode::NearestTiesToEven;
14449 RM = llvm::RoundingMode::TowardNegative;
14452 RM = llvm::RoundingMode::TowardPositive;
14455 RM = llvm::RoundingMode::TowardZero;
14458 llvm_unreachable(
"Invalid immediate rounding mode");
14461 RM = llvm::RoundingMode::NearestTiesToEven;
14465 ResultElements.reserve(DstNumElems);
14467 for (
unsigned I = 0; I < SrcNumElems; ++I) {
14471 APFloat::opStatus St = SrcVal.convert(HalfSem, RM, &LostInfo);
14473 if (UseMXCSR && IsFPConstrained && St != APFloat::opOK) {
14474 Info.FFDiag(E, diag::note_constexpr_dynamic_rounding);
14478 APSInt DstInt(SrcVal.bitcastToAPInt(),
14480 ResultElements.push_back(
APValue(DstInt));
14483 if (DstNumElems > SrcNumElems) {
14485 for (
unsigned I = SrcNumElems; I < DstNumElems; ++I) {
14490 return Success(ResultElements, E);
14492 case X86::BI__builtin_ia32_vperm2f128_pd256:
14493 case X86::BI__builtin_ia32_vperm2f128_ps256:
14494 case X86::BI__builtin_ia32_vperm2f128_si256:
14495 case X86::BI__builtin_ia32_permti256: {
14496 unsigned NumElements =
14498 unsigned PreservedBitsCnt = NumElements >> 2;
14502 [PreservedBitsCnt](
unsigned DstIdx,
unsigned ShuffleMask) {
14503 unsigned ControlBitsCnt = DstIdx >> PreservedBitsCnt << 2;
14504 unsigned ControlBits = ShuffleMask >> ControlBitsCnt;
14506 if (ControlBits & 0b1000)
14507 return std::make_pair(0u, -1);
14509 unsigned SrcVecIdx = (ControlBits & 0b10) >> 1;
14510 unsigned PreservedBitsMask = (1 << PreservedBitsCnt) - 1;
14511 int SrcIdx = ((ControlBits & 0b1) << PreservedBitsCnt) |
14512 (DstIdx & PreservedBitsMask);
14513 return std::make_pair(SrcVecIdx, SrcIdx);
14521bool VectorExprEvaluator::VisitConvertVectorExpr(
const ConvertVectorExpr *E) {
14527 QualType DestTy = E->
getType()->
castAs<VectorType>()->getElementType();
14528 QualType SourceTy = SourceVecType->
castAs<VectorType>()->getElementType();
14534 ResultElements.reserve(SourceLen);
14535 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
14540 ResultElements.push_back(std::move(Elt));
14543 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14548 APValue const &VecVal2,
unsigned EltNum,
14550 unsigned const TotalElementsInInputVector1 = VecVal1.
getVectorLength();
14551 unsigned const TotalElementsInInputVector2 = VecVal2.
getVectorLength();
14554 int64_t
index = IndexVal.getExtValue();
14561 E, diag::err_shufflevector_minus_one_is_undefined_behavior_constexpr)
14567 index >= TotalElementsInInputVector1 + TotalElementsInInputVector2)
14568 llvm_unreachable(
"Out of bounds shuffle index");
14570 if (
index >= TotalElementsInInputVector1)
14577bool VectorExprEvaluator::VisitShuffleVectorExpr(
const ShuffleVectorExpr *E) {
14582 const Expr *Vec1 = E->
getExpr(0);
14586 const Expr *Vec2 = E->
getExpr(1);
14590 VectorType
const *DestVecTy = E->
getType()->
castAs<VectorType>();
14596 ResultElements.reserve(TotalElementsInOutputVector);
14597 for (
unsigned EltNum = 0; EltNum < TotalElementsInOutputVector; ++EltNum) {
14601 ResultElements.push_back(std::move(Elt));
14604 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14612 class ArrayExprEvaluator
14613 :
public ExprEvaluatorBase<ArrayExprEvaluator> {
14614 const LValue &
This;
14618 ArrayExprEvaluator(EvalInfo &Info,
const LValue &This,
APValue &
Result)
14622 assert(
V.isArray() &&
"expected array");
14627 bool ZeroInitialization(
const Expr *E) {
14628 const ConstantArrayType *CAT =
14643 if (!
Result.hasArrayFiller())
14647 LValue Subobject =
This;
14648 Subobject.addArray(Info, E, CAT);
14653 bool VisitCallExpr(
const CallExpr *E) {
14654 return handleCallExpr(E,
Result, &This);
14656 bool VisitCastExpr(
const CastExpr *E);
14657 bool VisitInitListExpr(
const InitListExpr *E,
14658 QualType AllocType = QualType());
14659 bool VisitArrayInitLoopExpr(
const ArrayInitLoopExpr *E);
14660 bool VisitCXXConstructExpr(
const CXXConstructExpr *E);
14661 bool VisitCXXConstructExpr(
const CXXConstructExpr *E,
14662 const LValue &Subobject,
14664 bool VisitStringLiteral(
const StringLiteral *E,
14665 QualType AllocType = QualType()) {
14669 bool VisitCXXParenListInitExpr(
const CXXParenListInitExpr *E);
14670 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
14671 ArrayRef<Expr *> Args,
14672 const Expr *ArrayFiller,
14673 QualType AllocType = QualType());
14678 APValue &Result, EvalInfo &Info) {
14681 "not an array prvalue");
14682 return ArrayExprEvaluator(Info,
This, Result).Visit(E);
14690 "not an array prvalue");
14691 return ArrayExprEvaluator(Info,
This, Result)
14692 .VisitInitListExpr(ILE, AllocType);
14701 "not an array prvalue");
14702 return ArrayExprEvaluator(Info,
This, Result)
14703 .VisitCXXConstructExpr(CCE,
This, &Result, AllocType);
14712 if (
const InitListExpr *ILE = dyn_cast<InitListExpr>(FillerExpr)) {
14713 for (
unsigned I = 0, E = ILE->
getNumInits(); I != E; ++I) {
14718 if (ILE->hasArrayFiller() &&
14727bool ArrayExprEvaluator::VisitCastExpr(
const CastExpr *E) {
14732 return ExprEvaluatorBaseTy::VisitCastExpr(E);
14733 case CK_HLSLAggregateSplatCast: {
14753 case CK_HLSLElementwiseCast: {
14770bool ArrayExprEvaluator::VisitInitListExpr(
const InitListExpr *E,
14771 QualType AllocType) {
14785 return VisitStringLiteral(SL, AllocType);
14790 "transparent array list initialization is not string literal init?");
14796bool ArrayExprEvaluator::VisitCXXParenListOrInitListExpr(
14798 QualType AllocType) {
14804 assert((!
Result.isArray() ||
Result.getArrayInitializedElts() == 0) &&
14805 "zero-initialized array shouldn't have any initialized elts");
14810 unsigned NumEltsToInit = Args.size();
14815 if (NumEltsToInit != NumElts &&
14817 NumEltsToInit = NumElts;
14819 for (
auto *
Init : Args) {
14820 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts()))
14821 NumEltsToInit += EmbedS->getDataElementCount() - 1;
14823 if (NumEltsToInit > NumElts)
14824 NumEltsToInit = NumElts;
14827 LLVM_DEBUG(llvm::dbgs() <<
"The number of elements to initialize: "
14828 << NumEltsToInit <<
".\n");
14830 Result =
APValue(APValue::UninitArray(), NumEltsToInit, NumElts);
14835 for (
unsigned I = 0, E =
Result.getArrayInitializedElts(); I != E; ++I)
14836 Result.getArrayInitializedElt(I) = Filler;
14837 if (
Result.hasArrayFiller())
14841 LValue Subobject =
This;
14842 Subobject.addArray(Info, ExprToVisit, CAT);
14843 auto Eval = [&](
const Expr *
Init,
unsigned ArrayIndex) {
14844 if (
Init->isValueDependent())
14848 Subobject,
Init) ||
14851 if (!Info.noteFailure())
14857 unsigned ArrayIndex = 0;
14860 for (
unsigned Index = 0; Index != NumEltsToInit; ++Index) {
14861 const Expr *
Init = Index < Args.size() ? Args[Index] : ArrayFiller;
14862 if (ArrayIndex >= NumEltsToInit)
14864 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
14865 StringLiteral *SL = EmbedS->getDataStringLiteral();
14866 for (
unsigned I = EmbedS->getStartingElementPos(),
14867 N = EmbedS->getDataElementCount();
14868 I != EmbedS->getStartingElementPos() + N; ++I) {
14874 const FPOptions FPO =
14880 Result.getArrayInitializedElt(ArrayIndex) =
APValue(FValue);
14885 if (!Eval(
Init, ArrayIndex))
14891 if (!
Result.hasArrayFiller())
14896 assert(ArrayFiller &&
"no array filler for incomplete init list");
14902bool ArrayExprEvaluator::VisitArrayInitLoopExpr(
const ArrayInitLoopExpr *E) {
14905 !
Evaluate(Info.CurrentCall->createTemporary(
14908 ScopeKind::FullExpression, CommonLV),
14915 Result =
APValue(APValue::UninitArray(), Elements, Elements);
14917 LValue Subobject =
This;
14918 Subobject.addArray(Info, E, CAT);
14921 for (EvalInfo::ArrayInitLoopIndex Index(Info); Index != Elements; ++Index) {
14930 FullExpressionRAII Scope(Info);
14936 if (!Info.noteFailure())
14948bool ArrayExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E) {
14949 return VisitCXXConstructExpr(E, This, &
Result, E->
getType());
14952bool ArrayExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E,
14953 const LValue &Subobject,
14956 bool HadZeroInit =
Value->hasValue();
14963 HadZeroInit &&
Value->hasArrayFiller() ?
Value->getArrayFiller()
14966 *
Value =
APValue(APValue::UninitArray(), 0, FinalSize);
14967 if (FinalSize == 0)
14973 LValue ArrayElt = Subobject;
14974 ArrayElt.addArray(Info, E, CAT);
14980 for (
const unsigned N : {1u, FinalSize}) {
14981 unsigned OldElts =
Value->getArrayInitializedElts();
14986 APValue NewValue(APValue::UninitArray(), N, FinalSize);
14987 for (
unsigned I = 0; I < OldElts; ++I)
14988 NewValue.getArrayInitializedElt(I).swap(
14989 Value->getArrayInitializedElt(I));
14990 Value->swap(NewValue);
14993 for (
unsigned I = OldElts; I < N; ++I)
14994 Value->getArrayInitializedElt(I) = Filler;
14996 if (HasTrivialConstructor && N == FinalSize && FinalSize != 1) {
14999 APValue &FirstResult =
Value->getArrayInitializedElt(0);
15000 for (
unsigned I = OldElts; I < FinalSize; ++I)
15001 Value->getArrayInitializedElt(I) = FirstResult;
15003 for (
unsigned I = OldElts; I < N; ++I) {
15004 if (!VisitCXXConstructExpr(E, ArrayElt,
15005 &
Value->getArrayInitializedElt(I),
15012 if (Info.EvalStatus.
Diag && !Info.EvalStatus.
Diag->empty() &&
15013 !Info.keepEvaluatingAfterFailure())
15022 if (!
Type->isRecordType())
15025 return RecordExprEvaluator(Info, Subobject, *
Value)
15026 .VisitCXXConstructExpr(E,
Type);
15029bool ArrayExprEvaluator::VisitCXXParenListInitExpr(
15030 const CXXParenListInitExpr *E) {
15032 "Expression result is not a constant array type");
15034 return VisitCXXParenListOrInitListExpr(E, E->
getInitExprs(),
15047class IntExprEvaluator
15048 :
public ExprEvaluatorBase<IntExprEvaluator> {
15051 IntExprEvaluator(EvalInfo &info,
APValue &result)
15052 : ExprEvaluatorBaseTy(info),
Result(result) {}
15056 "Invalid evaluation result.");
15058 "Invalid evaluation result.");
15060 "Invalid evaluation result.");
15064 bool Success(
const llvm::APSInt &SI,
const Expr *E) {
15070 "Invalid evaluation result.");
15072 "Invalid evaluation result.");
15074 Result.getInt().setIsUnsigned(
15078 bool Success(
const llvm::APInt &I,
const Expr *E) {
15084 "Invalid evaluation result.");
15092 bool Success(CharUnits Size,
const Expr *E) {
15099 if (
V.isLValue() ||
V.isAddrLabelDiff() ||
V.isIndeterminate() ||
15100 V.allowConstexprUnknown()) {
15107 bool ZeroInitialization(
const Expr *E) {
return Success(0, E); }
15109 friend std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &,
15116 bool VisitIntegerLiteral(
const IntegerLiteral *E) {
15119 bool VisitCharacterLiteral(
const CharacterLiteral *E) {
15123 bool CheckReferencedDecl(
const Expr *E,
const Decl *D);
15124 bool VisitDeclRefExpr(
const DeclRefExpr *E) {
15125 if (CheckReferencedDecl(E, E->
getDecl()))
15128 return ExprEvaluatorBaseTy::VisitDeclRefExpr(E);
15130 bool VisitMemberExpr(
const MemberExpr *E) {
15132 VisitIgnoredBaseExpression(E->
getBase());
15136 return ExprEvaluatorBaseTy::VisitMemberExpr(E);
15139 bool VisitCallExpr(
const CallExpr *E);
15140 bool VisitBuiltinCallExpr(
const CallExpr *E,
unsigned BuiltinOp);
15141 bool VisitBinaryOperator(
const BinaryOperator *E);
15142 bool VisitOffsetOfExpr(
const OffsetOfExpr *E);
15143 bool VisitUnaryOperator(
const UnaryOperator *E);
15145 bool VisitCastExpr(
const CastExpr* E);
15146 bool VisitUnaryExprOrTypeTraitExpr(
const UnaryExprOrTypeTraitExpr *E);
15148 bool VisitCXXBoolLiteralExpr(
const CXXBoolLiteralExpr *E) {
15152 bool VisitObjCBoolLiteralExpr(
const ObjCBoolLiteralExpr *E) {
15156 bool VisitArrayInitIndexExpr(
const ArrayInitIndexExpr *E) {
15157 if (Info.ArrayInitIndex ==
uint64_t(-1)) {
15163 return Success(Info.ArrayInitIndex, E);
15167 bool VisitGNUNullExpr(
const GNUNullExpr *E) {
15168 return ZeroInitialization(E);
15171 bool VisitTypeTraitExpr(
const TypeTraitExpr *E) {
15180 bool VisitArrayTypeTraitExpr(
const ArrayTypeTraitExpr *E) {
15184 bool VisitExpressionTraitExpr(
const ExpressionTraitExpr *E) {
15188 bool VisitOpenACCAsteriskSizeExpr(
const OpenACCAsteriskSizeExpr *E) {
15195 bool VisitUnaryReal(
const UnaryOperator *E);
15196 bool VisitUnaryImag(
const UnaryOperator *E);
15198 bool VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E);
15199 bool VisitSizeOfPackExpr(
const SizeOfPackExpr *E);
15200 bool VisitSourceLocExpr(
const SourceLocExpr *E);
15201 bool VisitConceptSpecializationExpr(
const ConceptSpecializationExpr *E);
15206class FixedPointExprEvaluator
15207 :
public ExprEvaluatorBase<FixedPointExprEvaluator> {
15211 FixedPointExprEvaluator(EvalInfo &info,
APValue &result)
15212 : ExprEvaluatorBaseTy(info),
Result(result) {}
15214 bool Success(
const llvm::APInt &I,
const Expr *E) {
15225 return Success(
V.getFixedPoint(), E);
15228 bool Success(
const APFixedPoint &
V,
const Expr *E) {
15231 "Invalid evaluation result.");
15236 bool ZeroInitialization(
const Expr *E) {
15244 bool VisitFixedPointLiteral(
const FixedPointLiteral *E) {
15248 bool VisitCastExpr(
const CastExpr *E);
15249 bool VisitUnaryOperator(
const UnaryOperator *E);
15250 bool VisitBinaryOperator(
const BinaryOperator *E);
15266 return IntExprEvaluator(Info, Result).Visit(E);
15274 if (!Val.
isInt()) {
15277 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
15284bool IntExprEvaluator::VisitSourceLocExpr(
const SourceLocExpr *E) {
15286 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.
getDefaultExpr());
15295 if (!FixedPointExprEvaluator(Info, Val).Visit(E))
15314 Result = APFixedPoint(Val, FXSema);
15325bool IntExprEvaluator::CheckReferencedDecl(
const Expr* E,
const Decl* D) {
15327 if (
const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(D)) {
15329 bool SameSign = (ECD->getInitVal().isSigned()
15331 bool SameWidth = (ECD->getInitVal().
getBitWidth()
15333 if (SameSign && SameWidth)
15334 return Success(ECD->getInitVal(), E);
15338 llvm::APSInt Val = ECD->getInitVal();
15340 Val.setIsSigned(!ECD->getInitVal().isSigned());
15353 assert(!
T->isDependentType() &&
"unexpected dependent type");
15358#define TYPE(ID, BASE)
15359#define DEPENDENT_TYPE(ID, BASE) case Type::ID:
15360#define NON_CANONICAL_TYPE(ID, BASE) case Type::ID:
15361#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(ID, BASE) case Type::ID:
15362#include "clang/AST/TypeNodes.inc"
15364 case Type::DeducedTemplateSpecialization:
15365 llvm_unreachable(
"unexpected non-canonical or dependent type");
15367 case Type::Builtin:
15369#define BUILTIN_TYPE(ID, SINGLETON_ID)
15370#define SIGNED_TYPE(ID, SINGLETON_ID) \
15371 case BuiltinType::ID: return GCCTypeClass::Integer;
15372#define FLOATING_TYPE(ID, SINGLETON_ID) \
15373 case BuiltinType::ID: return GCCTypeClass::RealFloat;
15374#define PLACEHOLDER_TYPE(ID, SINGLETON_ID) \
15375 case BuiltinType::ID: break;
15376#include "clang/AST/BuiltinTypes.def"
15377 case BuiltinType::Void:
15380 case BuiltinType::Bool:
15383 case BuiltinType::Char_U:
15384 case BuiltinType::UChar:
15385 case BuiltinType::WChar_U:
15386 case BuiltinType::Char8:
15387 case BuiltinType::Char16:
15388 case BuiltinType::Char32:
15389 case BuiltinType::UShort:
15390 case BuiltinType::UInt:
15391 case BuiltinType::ULong:
15392 case BuiltinType::ULongLong:
15393 case BuiltinType::UInt128:
15396 case BuiltinType::UShortAccum:
15397 case BuiltinType::UAccum:
15398 case BuiltinType::ULongAccum:
15399 case BuiltinType::UShortFract:
15400 case BuiltinType::UFract:
15401 case BuiltinType::ULongFract:
15402 case BuiltinType::SatUShortAccum:
15403 case BuiltinType::SatUAccum:
15404 case BuiltinType::SatULongAccum:
15405 case BuiltinType::SatUShortFract:
15406 case BuiltinType::SatUFract:
15407 case BuiltinType::SatULongFract:
15410 case BuiltinType::NullPtr:
15412 case BuiltinType::ObjCId:
15413 case BuiltinType::ObjCClass:
15414 case BuiltinType::ObjCSel:
15415#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
15416 case BuiltinType::Id:
15417#include "clang/Basic/OpenCLImageTypes.def"
15418#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
15419 case BuiltinType::Id:
15420#include "clang/Basic/OpenCLExtensionTypes.def"
15421 case BuiltinType::OCLSampler:
15422 case BuiltinType::OCLEvent:
15423 case BuiltinType::OCLClkEvent:
15424 case BuiltinType::OCLQueue:
15425 case BuiltinType::OCLReserveID:
15426#define SVE_TYPE(Name, Id, SingletonId) \
15427 case BuiltinType::Id:
15428#include "clang/Basic/AArch64ACLETypes.def"
15429#define PPC_VECTOR_TYPE(Name, Id, Size) \
15430 case BuiltinType::Id:
15431#include "clang/Basic/PPCTypes.def"
15432#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
15433#include "clang/Basic/RISCVVTypes.def"
15434#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
15435#include "clang/Basic/WebAssemblyReferenceTypes.def"
15436#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
15437#include "clang/Basic/AMDGPUTypes.def"
15438#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
15439#include "clang/Basic/HLSLIntangibleTypes.def"
15442 case BuiltinType::Dependent:
15443 llvm_unreachable(
"unexpected dependent type");
15445 llvm_unreachable(
"unexpected placeholder type");
15450 case Type::Pointer:
15451 case Type::ConstantArray:
15452 case Type::VariableArray:
15453 case Type::IncompleteArray:
15454 case Type::FunctionNoProto:
15455 case Type::FunctionProto:
15456 case Type::ArrayParameter:
15459 case Type::MemberPointer:
15464 case Type::Complex:
15477 case Type::ExtVector:
15480 case Type::BlockPointer:
15481 case Type::ConstantMatrix:
15482 case Type::ObjCObject:
15483 case Type::ObjCInterface:
15484 case Type::ObjCObjectPointer:
15486 case Type::HLSLAttributedResource:
15487 case Type::HLSLInlineSpirv:
15495 case Type::LValueReference:
15496 case Type::RValueReference:
15497 llvm_unreachable(
"invalid type for expression");
15500 llvm_unreachable(
"unexpected type class");
15525 if (
Base.isNull()) {
15528 }
else if (
const Expr *E =
Base.dyn_cast<
const Expr *>()) {
15547 SpeculativeEvaluationRAII SpeculativeEval(Info);
15552 FoldConstant Fold(Info,
true);
15570 if (ArgType->isIntegralOrEnumerationType() || ArgType->isFloatingType() ||
15571 ArgType->isAnyComplexType() || ArgType->isPointerType() ||
15572 ArgType->isNullPtrType()) {
15575 Fold.keepDiagnostics();
15584 return V.hasValue();
15595 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
15619 const auto *Cast = dyn_cast<CastExpr>(NoParens);
15620 if (Cast ==
nullptr)
15625 auto CastKind = Cast->getCastKind();
15627 CastKind != CK_AddressSpaceConversion)
15630 const auto *SubExpr = Cast->getSubExpr();
15652 assert(!LVal.Designator.Invalid);
15654 auto IsLastOrInvalidFieldDecl = [&Ctx](
const FieldDecl *FD) {
15662 auto &
Base = LVal.getLValueBase();
15663 if (
auto *ME = dyn_cast_or_null<MemberExpr>(
Base.dyn_cast<
const Expr *>())) {
15664 if (
auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
15665 if (!IsLastOrInvalidFieldDecl(FD))
15667 }
else if (
auto *IFD = dyn_cast<IndirectFieldDecl>(ME->getMemberDecl())) {
15668 for (
auto *FD : IFD->chain()) {
15677 if (LVal.Designator.FirstEntryIsAnUnsizedArray) {
15681 if (BaseType->isIncompleteArrayType())
15687 for (
unsigned E = LVal.Designator.Entries.size(); I != E; ++I) {
15688 const auto &Entry = LVal.Designator.Entries[I];
15689 if (BaseType->isArrayType()) {
15695 uint64_t Index = Entry.getAsArrayIndex();
15699 }
else if (BaseType->isAnyComplexType()) {
15700 const auto *CT = BaseType->castAs<
ComplexType>();
15701 uint64_t Index = Entry.getAsArrayIndex();
15704 BaseType = CT->getElementType();
15705 }
else if (
auto *FD = getAsField(Entry)) {
15706 if (!IsLastOrInvalidFieldDecl(FD))
15710 assert(getAsBaseClass(Entry) &&
"Expecting cast to a base class");
15722 if (LVal.Designator.Invalid)
15725 if (!LVal.Designator.Entries.empty())
15726 return LVal.Designator.isMostDerivedAnUnsizedArray();
15728 if (!LVal.InvalidBase)
15740 const SubobjectDesignator &
Designator = LVal.Designator;
15752 auto isFlexibleArrayMember = [&] {
15754 FAMKind StrictFlexArraysLevel =
15757 if (
Designator.isMostDerivedAnUnsizedArray())
15760 if (StrictFlexArraysLevel == FAMKind::Default)
15763 if (
Designator.getMostDerivedArraySize() == 0 &&
15764 StrictFlexArraysLevel != FAMKind::IncompleteOnly)
15767 if (
Designator.getMostDerivedArraySize() == 1 &&
15768 StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete)
15774 return LVal.InvalidBase &&
15776 Designator.MostDerivedIsArrayElement && isFlexibleArrayMember() &&
15784 auto CharUnitsMax = std::numeric_limits<CharUnits::QuantityType>::max();
15785 if (Int.ugt(CharUnitsMax))
15795 if (!
T.isNull() &&
T->isStructureType() &&
15796 T->castAsRecordDecl()->hasFlexibleArrayMember())
15797 if (
const auto *
V = LV.getLValueBase().dyn_cast<
const ValueDecl *>())
15798 if (
const auto *VD = dyn_cast<VarDecl>(
V))
15810 unsigned Type,
const LValue &LVal,
15829 if (!(
Type & 1) || LVal.Designator.Invalid || DetermineForCompleteObject) {
15831 if (
Type == 3 && !DetermineForCompleteObject)
15834 llvm::APInt APEndOffset;
15835 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
15839 if (LVal.InvalidBase)
15843 const bool Ret = CheckedHandleSizeof(BaseTy, EndOffset);
15849 const SubobjectDesignator &
Designator = LVal.Designator;
15861 llvm::APInt APEndOffset;
15862 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
15874 if (!CheckedHandleSizeof(
Designator.MostDerivedType, BytesPerElem))
15880 int64_t ElemsRemaining;
15883 uint64_t ArraySize =
Designator.getMostDerivedArraySize();
15884 uint64_t ArrayIndex =
Designator.Entries.back().getAsArrayIndex();
15885 ElemsRemaining = ArraySize <= ArrayIndex ? 0 : ArraySize - ArrayIndex;
15887 ElemsRemaining =
Designator.isOnePastTheEnd() ? 0 : 1;
15890 EndOffset = LVal.getLValueOffset() + BytesPerElem * ElemsRemaining;
15900 EvalInfo &Info, uint64_t &Size) {
15907 SpeculativeEvaluationRAII SpeculativeEval(Info);
15908 IgnoreSideEffectsRAII Fold(Info);
15916 LVal.setFrom(Info.Ctx, RVal);
15924 if (LVal.getLValueOffset().isNegative()) {
15935 if (EndOffset <= LVal.getLValueOffset())
15938 Size = (EndOffset - LVal.getLValueOffset()).getQuantity();
15942bool IntExprEvaluator::VisitCallExpr(
const CallExpr *E) {
15943 if (!IsConstantEvaluatedBuiltinCall(E))
15944 return ExprEvaluatorBaseTy::VisitCallExpr(E);
15961 Info.FFDiag(E->
getArg(0));
15967 assert(SrcInt.getBitWidth() >= Alignment.getBitWidth() &&
15968 "Bit widths must be the same");
15975bool IntExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *E,
15976 unsigned BuiltinOp) {
15977 auto EvalTestOp = [&](llvm::function_ref<
bool(
const APInt &,
const APInt &)>
15979 APValue SourceLHS, SourceRHS;
15987 unsigned LaneWidth = Info.Ctx.
getTypeSize(ElemQT);
15989 APInt AWide(LaneWidth * SourceLen, 0);
15990 APInt BWide(LaneWidth * SourceLen, 0);
15992 for (
unsigned I = 0; I != SourceLen; ++I) {
15995 if (ElemQT->isIntegerType()) {
15998 }
else if (ElemQT->isFloatingType()) {
16006 AWide.insertBits(ALane, I * LaneWidth);
16007 BWide.insertBits(BLane, I * LaneWidth);
16012 auto HandleMaskBinOp =
16025 auto HandleCRC32 = [&](
unsigned DataBytes) ->
bool {
16031 uint64_t CRCVal = CRC.getZExtValue();
16035 static const uint32_t CRC32C_POLY = 0x82F63B78;
16039 for (
unsigned I = 0; I != DataBytes; ++I) {
16040 uint8_t Byte =
static_cast<uint8_t
>((DataVal >> (I * 8)) & 0xFF);
16042 for (
int J = 0; J != 8; ++J) {
16050 switch (BuiltinOp) {
16054 case X86::BI__builtin_ia32_crc32qi:
16055 return HandleCRC32(1);
16056 case X86::BI__builtin_ia32_crc32hi:
16057 return HandleCRC32(2);
16058 case X86::BI__builtin_ia32_crc32si:
16059 return HandleCRC32(4);
16060 case X86::BI__builtin_ia32_crc32di:
16061 return HandleCRC32(8);
16063 case Builtin::BI__builtin_dynamic_object_size:
16064 case Builtin::BI__builtin_object_size: {
16068 assert(
Type <= 3 &&
"unexpected type");
16079 switch (Info.EvalMode) {
16080 case EvaluationMode::ConstantExpression:
16081 case EvaluationMode::ConstantFold:
16082 case EvaluationMode::IgnoreSideEffects:
16085 case EvaluationMode::ConstantExpressionUnevaluated:
16090 llvm_unreachable(
"unexpected EvalMode");
16093 case Builtin::BI__builtin_os_log_format_buffer_size: {
16094 analyze_os_log::OSLogBufferLayout Layout;
16099 case Builtin::BI__builtin_is_aligned: {
16107 Ptr.setFrom(Info.Ctx, Src);
16113 assert(Alignment.isPowerOf2());
16126 Info.FFDiag(E->
getArg(0), diag::note_constexpr_alignment_compute)
16130 assert(Src.
isInt());
16131 return Success((Src.
getInt() & (Alignment - 1)) == 0 ? 1 : 0, E);
16133 case Builtin::BI__builtin_align_up: {
16141 APSInt((Src.
getInt() + (Alignment - 1)) & ~(Alignment - 1),
16142 Src.
getInt().isUnsigned());
16143 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
16144 return Success(AlignedVal, E);
16146 case Builtin::BI__builtin_align_down: {
16155 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
16156 return Success(AlignedVal, E);
16159 case Builtin::BI__builtin_bitreverse8:
16160 case Builtin::BI__builtin_bitreverse16:
16161 case Builtin::BI__builtin_bitreverse32:
16162 case Builtin::BI__builtin_bitreverse64:
16163 case Builtin::BI__builtin_elementwise_bitreverse: {
16168 return Success(Val.reverseBits(), E);
16170 case Builtin::BI__builtin_bswapg:
16171 case Builtin::BI__builtin_bswap16:
16172 case Builtin::BI__builtin_bswap32:
16173 case Builtin::BI__builtin_bswap64: {
16177 if (Val.getBitWidth() == 8)
16180 return Success(Val.byteSwap(), E);
16183 case Builtin::BI__builtin_classify_type:
16186 case Builtin::BI__builtin_clrsb:
16187 case Builtin::BI__builtin_clrsbl:
16188 case Builtin::BI__builtin_clrsbll: {
16193 return Success(Val.getBitWidth() - Val.getSignificantBits(), E);
16196 case Builtin::BI__builtin_clz:
16197 case Builtin::BI__builtin_clzl:
16198 case Builtin::BI__builtin_clzll:
16199 case Builtin::BI__builtin_clzs:
16200 case Builtin::BI__builtin_clzg:
16201 case Builtin::BI__builtin_elementwise_clzg:
16202 case Builtin::BI__lzcnt16:
16203 case Builtin::BI__lzcnt:
16204 case Builtin::BI__lzcnt64: {
16215 std::optional<APSInt> Fallback;
16216 if ((BuiltinOp == Builtin::BI__builtin_clzg ||
16217 BuiltinOp == Builtin::BI__builtin_elementwise_clzg) &&
16222 Fallback = FallbackTemp;
16227 return Success(*Fallback, E);
16232 bool ZeroIsUndefined = BuiltinOp != Builtin::BI__lzcnt16 &&
16233 BuiltinOp != Builtin::BI__lzcnt &&
16234 BuiltinOp != Builtin::BI__lzcnt64;
16236 if (BuiltinOp == Builtin::BI__builtin_elementwise_clzg) {
16237 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
16241 if (ZeroIsUndefined)
16245 return Success(Val.countl_zero(), E);
16248 case Builtin::BI__builtin_constant_p: {
16249 const Expr *Arg = E->
getArg(0);
16258 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
16262 case Builtin::BI__noop:
16266 case Builtin::BI__builtin_is_constant_evaluated: {
16267 const auto *
Callee = Info.CurrentCall->getCallee();
16268 if (Info.InConstantContext && !Info.CheckingPotentialConstantExpression &&
16269 (Info.CallStackDepth == 1 ||
16270 (Info.CallStackDepth == 2 &&
Callee->isInStdNamespace() &&
16271 Callee->getIdentifier() &&
16272 Callee->getIdentifier()->isStr(
"is_constant_evaluated")))) {
16274 if (Info.EvalStatus.
Diag)
16275 Info.report((Info.CallStackDepth == 1)
16277 : Info.CurrentCall->getCallRange().getBegin(),
16278 diag::warn_is_constant_evaluated_always_true_constexpr)
16279 << (Info.CallStackDepth == 1 ?
"__builtin_is_constant_evaluated"
16280 :
"std::is_constant_evaluated");
16283 return Success(Info.InConstantContext, E);
16286 case Builtin::BI__builtin_is_within_lifetime:
16287 if (
auto result = EvaluateBuiltinIsWithinLifetime(*
this, E))
16291 case Builtin::BI__builtin_ctz:
16292 case Builtin::BI__builtin_ctzl:
16293 case Builtin::BI__builtin_ctzll:
16294 case Builtin::BI__builtin_ctzs:
16295 case Builtin::BI__builtin_ctzg:
16296 case Builtin::BI__builtin_elementwise_ctzg: {
16307 std::optional<APSInt> Fallback;
16308 if ((BuiltinOp == Builtin::BI__builtin_ctzg ||
16309 BuiltinOp == Builtin::BI__builtin_elementwise_ctzg) &&
16314 Fallback = FallbackTemp;
16319 return Success(*Fallback, E);
16321 if (BuiltinOp == Builtin::BI__builtin_elementwise_ctzg) {
16322 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
16328 return Success(Val.countr_zero(), E);
16331 case Builtin::BI__builtin_eh_return_data_regno: {
16337 case Builtin::BI__builtin_elementwise_abs: {
16342 return Success(Val.abs(), E);
16345 case Builtin::BI__builtin_expect:
16346 case Builtin::BI__builtin_expect_with_probability:
16347 return Visit(E->
getArg(0));
16349 case Builtin::BI__builtin_ptrauth_string_discriminator: {
16356 case Builtin::BI__builtin_infer_alloc_token: {
16362 E, diag::note_constexpr_infer_alloc_token_type_inference_failed);
16365 return Error(E, diag::note_constexpr_infer_alloc_token_no_metadata);
16367 Info.getLangOpts().AllocTokenMode.value_or(llvm::DefaultAllocTokenMode);
16369 auto MaxTokensOpt = Info.getLangOpts().AllocTokenMax;
16371 MaxTokensOpt.value_or(0) ? *MaxTokensOpt : (~0ULL >> (64 - BitWidth));
16372 auto MaybeToken = llvm::getAllocToken(Mode, *ATMD, MaxTokens);
16374 return Error(E, diag::note_constexpr_infer_alloc_token_stateful_mode);
16375 return Success(llvm::APInt(BitWidth, *MaybeToken), E);
16378 case Builtin::BI__builtin_ffs:
16379 case Builtin::BI__builtin_ffsl:
16380 case Builtin::BI__builtin_ffsll: {
16385 unsigned N = Val.countr_zero();
16386 return Success(N == Val.getBitWidth() ? 0 : N + 1, E);
16389 case Builtin::BI__builtin_fpclassify: {
16394 switch (Val.getCategory()) {
16395 case APFloat::fcNaN: Arg = 0;
break;
16396 case APFloat::fcInfinity: Arg = 1;
break;
16397 case APFloat::fcNormal: Arg = Val.isDenormal() ? 3 : 2;
break;
16398 case APFloat::fcZero: Arg = 4;
break;
16400 return Visit(E->
getArg(Arg));
16403 case Builtin::BI__builtin_isinf_sign: {
16406 Success(Val.isInfinity() ? (Val.isNegative() ? -1 : 1) : 0, E);
16409 case Builtin::BI__builtin_isinf: {
16412 Success(Val.isInfinity() ? 1 : 0, E);
16415 case Builtin::BI__builtin_isfinite: {
16418 Success(Val.isFinite() ? 1 : 0, E);
16421 case Builtin::BI__builtin_isnan: {
16424 Success(Val.isNaN() ? 1 : 0, E);
16427 case Builtin::BI__builtin_isnormal: {
16430 Success(Val.isNormal() ? 1 : 0, E);
16433 case Builtin::BI__builtin_issubnormal: {
16436 Success(Val.isDenormal() ? 1 : 0, E);
16439 case Builtin::BI__builtin_iszero: {
16442 Success(Val.isZero() ? 1 : 0, E);
16445 case Builtin::BI__builtin_signbit:
16446 case Builtin::BI__builtin_signbitf:
16447 case Builtin::BI__builtin_signbitl: {
16450 Success(Val.isNegative() ? 1 : 0, E);
16453 case Builtin::BI__builtin_isgreater:
16454 case Builtin::BI__builtin_isgreaterequal:
16455 case Builtin::BI__builtin_isless:
16456 case Builtin::BI__builtin_islessequal:
16457 case Builtin::BI__builtin_islessgreater:
16458 case Builtin::BI__builtin_isunordered: {
16467 switch (BuiltinOp) {
16468 case Builtin::BI__builtin_isgreater:
16470 case Builtin::BI__builtin_isgreaterequal:
16472 case Builtin::BI__builtin_isless:
16474 case Builtin::BI__builtin_islessequal:
16476 case Builtin::BI__builtin_islessgreater: {
16477 APFloat::cmpResult cmp = LHS.compare(RHS);
16478 return cmp == APFloat::cmpResult::cmpLessThan ||
16479 cmp == APFloat::cmpResult::cmpGreaterThan;
16481 case Builtin::BI__builtin_isunordered:
16482 return LHS.compare(RHS) == APFloat::cmpResult::cmpUnordered;
16484 llvm_unreachable(
"Unexpected builtin ID: Should be a floating "
16485 "point comparison function");
16493 case Builtin::BI__builtin_issignaling: {
16496 Success(Val.isSignaling() ? 1 : 0, E);
16499 case Builtin::BI__builtin_isfpclass: {
16503 unsigned Test =
static_cast<llvm::FPClassTest
>(MaskVal.getZExtValue());
16506 Success((Val.classify() & Test) ? 1 : 0, E);
16509 case Builtin::BI__builtin_parity:
16510 case Builtin::BI__builtin_parityl:
16511 case Builtin::BI__builtin_parityll: {
16516 return Success(Val.popcount() % 2, E);
16519 case Builtin::BI__builtin_abs:
16520 case Builtin::BI__builtin_labs:
16521 case Builtin::BI__builtin_llabs: {
16525 if (Val ==
APSInt(APInt::getSignedMinValue(Val.getBitWidth()),
16528 if (Val.isNegative())
16533 case Builtin::BI__builtin_popcount:
16534 case Builtin::BI__builtin_popcountl:
16535 case Builtin::BI__builtin_popcountll:
16536 case Builtin::BI__builtin_popcountg:
16537 case Builtin::BI__builtin_elementwise_popcount:
16538 case Builtin::BI__popcnt16:
16539 case Builtin::BI__popcnt:
16540 case Builtin::BI__popcnt64: {
16551 return Success(Val.popcount(), E);
16554 case Builtin::BI__builtin_rotateleft8:
16555 case Builtin::BI__builtin_rotateleft16:
16556 case Builtin::BI__builtin_rotateleft32:
16557 case Builtin::BI__builtin_rotateleft64:
16558 case Builtin::BI__builtin_rotateright8:
16559 case Builtin::BI__builtin_rotateright16:
16560 case Builtin::BI__builtin_rotateright32:
16561 case Builtin::BI__builtin_rotateright64:
16562 case Builtin::BI__builtin_stdc_rotate_left:
16563 case Builtin::BI__builtin_stdc_rotate_right:
16564 case Builtin::BI_rotl8:
16565 case Builtin::BI_rotl16:
16566 case Builtin::BI_rotl:
16567 case Builtin::BI_lrotl:
16568 case Builtin::BI_rotl64:
16569 case Builtin::BI_rotr8:
16570 case Builtin::BI_rotr16:
16571 case Builtin::BI_rotr:
16572 case Builtin::BI_lrotr:
16573 case Builtin::BI_rotr64: {
16581 switch (BuiltinOp) {
16582 case Builtin::BI__builtin_rotateright8:
16583 case Builtin::BI__builtin_rotateright16:
16584 case Builtin::BI__builtin_rotateright32:
16585 case Builtin::BI__builtin_rotateright64:
16586 case Builtin::BI__builtin_stdc_rotate_right:
16587 case Builtin::BI_rotr8:
16588 case Builtin::BI_rotr16:
16589 case Builtin::BI_rotr:
16590 case Builtin::BI_lrotr:
16591 case Builtin::BI_rotr64:
16600 case Builtin::BI__builtin_elementwise_add_sat: {
16606 APInt Result = LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS);
16609 case Builtin::BI__builtin_elementwise_sub_sat: {
16615 APInt Result = LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
16618 case Builtin::BI__builtin_elementwise_max: {
16627 case Builtin::BI__builtin_elementwise_min: {
16636 case Builtin::BI__builtin_elementwise_fshl:
16637 case Builtin::BI__builtin_elementwise_fshr: {
16644 switch (BuiltinOp) {
16645 case Builtin::BI__builtin_elementwise_fshl: {
16646 APSInt Result(llvm::APIntOps::fshl(Hi, Lo, Shift), Hi.isUnsigned());
16649 case Builtin::BI__builtin_elementwise_fshr: {
16650 APSInt Result(llvm::APIntOps::fshr(Hi, Lo, Shift), Hi.isUnsigned());
16654 llvm_unreachable(
"Fully covered switch above");
16656 case Builtin::BIstrlen:
16657 case Builtin::BIwcslen:
16659 if (Info.getLangOpts().CPlusPlus11)
16660 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
16664 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
16666 case Builtin::BI__builtin_strlen:
16667 case Builtin::BI__builtin_wcslen: {
16676 case Builtin::BIstrcmp:
16677 case Builtin::BIwcscmp:
16678 case Builtin::BIstrncmp:
16679 case Builtin::BIwcsncmp:
16680 case Builtin::BImemcmp:
16681 case Builtin::BIbcmp:
16682 case Builtin::BIwmemcmp:
16684 if (Info.getLangOpts().CPlusPlus11)
16685 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
16689 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
16691 case Builtin::BI__builtin_strcmp:
16692 case Builtin::BI__builtin_wcscmp:
16693 case Builtin::BI__builtin_strncmp:
16694 case Builtin::BI__builtin_wcsncmp:
16695 case Builtin::BI__builtin_memcmp:
16696 case Builtin::BI__builtin_bcmp:
16697 case Builtin::BI__builtin_wmemcmp: {
16698 LValue String1, String2;
16704 if (BuiltinOp != Builtin::BIstrcmp &&
16705 BuiltinOp != Builtin::BIwcscmp &&
16706 BuiltinOp != Builtin::BI__builtin_strcmp &&
16707 BuiltinOp != Builtin::BI__builtin_wcscmp) {
16711 MaxLength = N.getZExtValue();
16715 if (MaxLength == 0u)
16718 if (!String1.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
16719 !String2.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
16720 String1.Designator.Invalid || String2.Designator.Invalid)
16723 QualType CharTy1 = String1.Designator.getType(Info.Ctx);
16724 QualType CharTy2 = String2.Designator.getType(Info.Ctx);
16726 bool IsRawByte = BuiltinOp == Builtin::BImemcmp ||
16727 BuiltinOp == Builtin::BIbcmp ||
16728 BuiltinOp == Builtin::BI__builtin_memcmp ||
16729 BuiltinOp == Builtin::BI__builtin_bcmp;
16731 assert(IsRawByte ||
16741 Info.FFDiag(E, diag::note_constexpr_memcmp_unsupported)
16747 const auto &ReadCurElems = [&](
APValue &Char1,
APValue &Char2) {
16750 Char1.
isInt() && Char2.isInt();
16752 const auto &AdvanceElems = [&] {
16758 (BuiltinOp != Builtin::BImemcmp && BuiltinOp != Builtin::BIbcmp &&
16759 BuiltinOp != Builtin::BIwmemcmp &&
16760 BuiltinOp != Builtin::BI__builtin_memcmp &&
16761 BuiltinOp != Builtin::BI__builtin_bcmp &&
16762 BuiltinOp != Builtin::BI__builtin_wmemcmp);
16763 bool IsWide = BuiltinOp == Builtin::BIwcscmp ||
16764 BuiltinOp == Builtin::BIwcsncmp ||
16765 BuiltinOp == Builtin::BIwmemcmp ||
16766 BuiltinOp == Builtin::BI__builtin_wcscmp ||
16767 BuiltinOp == Builtin::BI__builtin_wcsncmp ||
16768 BuiltinOp == Builtin::BI__builtin_wmemcmp;
16770 for (; MaxLength; --MaxLength) {
16772 if (!ReadCurElems(Char1, Char2))
16780 if (StopAtNull && !Char1.
getInt())
16782 assert(!(StopAtNull && !Char2.
getInt()));
16783 if (!AdvanceElems())
16790 case Builtin::BI__atomic_always_lock_free:
16791 case Builtin::BI__atomic_is_lock_free:
16792 case Builtin::BI__c11_atomic_is_lock_free: {
16808 if (
Size.isPowerOfTwo()) {
16810 unsigned InlineWidthBits =
16813 if (BuiltinOp == Builtin::BI__c11_atomic_is_lock_free ||
16819 const Expr *PtrArg = E->
getArg(1);
16825 IntResult.isAligned(
Size.getAsAlign()))
16829 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(PtrArg)) {
16832 if (ICE->getCastKind() == CK_BitCast)
16833 PtrArg = ICE->getSubExpr();
16836 if (
auto PtrTy = PtrArg->
getType()->
getAs<PointerType>()) {
16847 return BuiltinOp == Builtin::BI__atomic_always_lock_free ?
16850 case Builtin::BI__builtin_addcb:
16851 case Builtin::BI__builtin_addcs:
16852 case Builtin::BI__builtin_addc:
16853 case Builtin::BI__builtin_addcl:
16854 case Builtin::BI__builtin_addcll:
16855 case Builtin::BI__builtin_subcb:
16856 case Builtin::BI__builtin_subcs:
16857 case Builtin::BI__builtin_subc:
16858 case Builtin::BI__builtin_subcl:
16859 case Builtin::BI__builtin_subcll: {
16860 LValue CarryOutLValue;
16872 bool FirstOverflowed =
false;
16873 bool SecondOverflowed =
false;
16874 switch (BuiltinOp) {
16876 llvm_unreachable(
"Invalid value for BuiltinOp");
16877 case Builtin::BI__builtin_addcb:
16878 case Builtin::BI__builtin_addcs:
16879 case Builtin::BI__builtin_addc:
16880 case Builtin::BI__builtin_addcl:
16881 case Builtin::BI__builtin_addcll:
16883 LHS.uadd_ov(RHS, FirstOverflowed).uadd_ov(CarryIn, SecondOverflowed);
16885 case Builtin::BI__builtin_subcb:
16886 case Builtin::BI__builtin_subcs:
16887 case Builtin::BI__builtin_subc:
16888 case Builtin::BI__builtin_subcl:
16889 case Builtin::BI__builtin_subcll:
16891 LHS.usub_ov(RHS, FirstOverflowed).usub_ov(CarryIn, SecondOverflowed);
16897 CarryOut = (
uint64_t)(FirstOverflowed | SecondOverflowed);
16903 case Builtin::BI__builtin_add_overflow:
16904 case Builtin::BI__builtin_sub_overflow:
16905 case Builtin::BI__builtin_mul_overflow:
16906 case Builtin::BI__builtin_sadd_overflow:
16907 case Builtin::BI__builtin_uadd_overflow:
16908 case Builtin::BI__builtin_uaddl_overflow:
16909 case Builtin::BI__builtin_uaddll_overflow:
16910 case Builtin::BI__builtin_usub_overflow:
16911 case Builtin::BI__builtin_usubl_overflow:
16912 case Builtin::BI__builtin_usubll_overflow:
16913 case Builtin::BI__builtin_umul_overflow:
16914 case Builtin::BI__builtin_umull_overflow:
16915 case Builtin::BI__builtin_umulll_overflow:
16916 case Builtin::BI__builtin_saddl_overflow:
16917 case Builtin::BI__builtin_saddll_overflow:
16918 case Builtin::BI__builtin_ssub_overflow:
16919 case Builtin::BI__builtin_ssubl_overflow:
16920 case Builtin::BI__builtin_ssubll_overflow:
16921 case Builtin::BI__builtin_smul_overflow:
16922 case Builtin::BI__builtin_smull_overflow:
16923 case Builtin::BI__builtin_smulll_overflow: {
16924 LValue ResultLValue;
16934 bool DidOverflow =
false;
16937 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
16938 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
16939 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
16940 bool IsSigned = LHS.isSigned() || RHS.isSigned() ||
16942 bool AllSigned = LHS.isSigned() && RHS.isSigned() &&
16944 uint64_t LHSSize = LHS.getBitWidth();
16945 uint64_t RHSSize = RHS.getBitWidth();
16947 uint64_t MaxBits = std::max(std::max(LHSSize, RHSSize), ResultSize);
16953 if (IsSigned && !AllSigned)
16956 LHS =
APSInt(LHS.extOrTrunc(MaxBits), !IsSigned);
16957 RHS =
APSInt(RHS.extOrTrunc(MaxBits), !IsSigned);
16962 switch (BuiltinOp) {
16964 llvm_unreachable(
"Invalid value for BuiltinOp");
16965 case Builtin::BI__builtin_add_overflow:
16966 case Builtin::BI__builtin_sadd_overflow:
16967 case Builtin::BI__builtin_saddl_overflow:
16968 case Builtin::BI__builtin_saddll_overflow:
16969 case Builtin::BI__builtin_uadd_overflow:
16970 case Builtin::BI__builtin_uaddl_overflow:
16971 case Builtin::BI__builtin_uaddll_overflow:
16972 Result = LHS.isSigned() ? LHS.sadd_ov(RHS, DidOverflow)
16973 : LHS.uadd_ov(RHS, DidOverflow);
16975 case Builtin::BI__builtin_sub_overflow:
16976 case Builtin::BI__builtin_ssub_overflow:
16977 case Builtin::BI__builtin_ssubl_overflow:
16978 case Builtin::BI__builtin_ssubll_overflow:
16979 case Builtin::BI__builtin_usub_overflow:
16980 case Builtin::BI__builtin_usubl_overflow:
16981 case Builtin::BI__builtin_usubll_overflow:
16982 Result = LHS.isSigned() ? LHS.ssub_ov(RHS, DidOverflow)
16983 : LHS.usub_ov(RHS, DidOverflow);
16985 case Builtin::BI__builtin_mul_overflow:
16986 case Builtin::BI__builtin_smul_overflow:
16987 case Builtin::BI__builtin_smull_overflow:
16988 case Builtin::BI__builtin_smulll_overflow:
16989 case Builtin::BI__builtin_umul_overflow:
16990 case Builtin::BI__builtin_umull_overflow:
16991 case Builtin::BI__builtin_umulll_overflow:
16992 Result = LHS.isSigned() ? LHS.smul_ov(RHS, DidOverflow)
16993 : LHS.umul_ov(RHS, DidOverflow);
16999 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
17000 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
17001 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
17010 if (!APSInt::isSameValue(Temp,
Result))
17011 DidOverflow =
true;
17018 return Success(DidOverflow, E);
17021 case Builtin::BI__builtin_reduce_add:
17022 case Builtin::BI__builtin_reduce_mul:
17023 case Builtin::BI__builtin_reduce_and:
17024 case Builtin::BI__builtin_reduce_or:
17025 case Builtin::BI__builtin_reduce_xor:
17026 case Builtin::BI__builtin_reduce_min:
17027 case Builtin::BI__builtin_reduce_max: {
17034 for (
unsigned EltNum = 1; EltNum < SourceLen; ++EltNum) {
17035 switch (BuiltinOp) {
17038 case Builtin::BI__builtin_reduce_add: {
17041 Reduced.getBitWidth() + 1, std::plus<APSInt>(), Reduced))
17045 case Builtin::BI__builtin_reduce_mul: {
17048 Reduced.getBitWidth() * 2, std::multiplies<APSInt>(), Reduced))
17052 case Builtin::BI__builtin_reduce_and: {
17056 case Builtin::BI__builtin_reduce_or: {
17060 case Builtin::BI__builtin_reduce_xor: {
17064 case Builtin::BI__builtin_reduce_min: {
17068 case Builtin::BI__builtin_reduce_max: {
17078 case clang::X86::BI__builtin_ia32_addcarryx_u32:
17079 case clang::X86::BI__builtin_ia32_addcarryx_u64:
17080 case clang::X86::BI__builtin_ia32_subborrow_u32:
17081 case clang::X86::BI__builtin_ia32_subborrow_u64: {
17082 LValue ResultLValue;
17083 APSInt CarryIn, LHS, RHS;
17091 bool IsAdd = BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u32 ||
17092 BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u64;
17094 unsigned BitWidth = LHS.getBitWidth();
17095 unsigned CarryInBit = CarryIn.ugt(0) ? 1 : 0;
17098 ? (LHS.zext(BitWidth + 1) + (RHS.zext(BitWidth + 1) + CarryInBit))
17099 : (LHS.zext(BitWidth + 1) - (RHS.zext(BitWidth + 1) + CarryInBit));
17101 APInt Result = ExResult.extractBits(BitWidth, 0);
17102 uint64_t CarryOut = ExResult.extractBitsAsZExtValue(1, BitWidth);
17110 case clang::X86::BI__builtin_ia32_movmskps:
17111 case clang::X86::BI__builtin_ia32_movmskpd:
17112 case clang::X86::BI__builtin_ia32_pmovmskb128:
17113 case clang::X86::BI__builtin_ia32_pmovmskb256:
17114 case clang::X86::BI__builtin_ia32_movmskps256:
17115 case clang::X86::BI__builtin_ia32_movmskpd256: {
17126 for (
unsigned I = 0; I != SourceLen; ++I) {
17128 if (ElemQT->isIntegerType()) {
17130 }
else if (ElemQT->isRealFloatingType()) {
17135 Result.setBitVal(I, Elem.isNegative());
17140 case clang::X86::BI__builtin_ia32_bextr_u32:
17141 case clang::X86::BI__builtin_ia32_bextr_u64:
17142 case clang::X86::BI__builtin_ia32_bextri_u32:
17143 case clang::X86::BI__builtin_ia32_bextri_u64: {
17149 unsigned BitWidth = Val.getBitWidth();
17151 uint64_t Length = Idx.extractBitsAsZExtValue(8, 8);
17152 Length = Length > BitWidth ? BitWidth : Length;
17155 if (Length == 0 || Shift >= BitWidth)
17159 Result &= llvm::maskTrailingOnes<uint64_t>(Length);
17163 case clang::X86::BI__builtin_ia32_bzhi_si:
17164 case clang::X86::BI__builtin_ia32_bzhi_di: {
17170 unsigned BitWidth = Val.getBitWidth();
17171 unsigned Index = Idx.extractBitsAsZExtValue(8, 0);
17172 if (Index < BitWidth)
17173 Val.clearHighBits(BitWidth - Index);
17177 case clang::X86::BI__builtin_ia32_ktestcqi:
17178 case clang::X86::BI__builtin_ia32_ktestchi:
17179 case clang::X86::BI__builtin_ia32_ktestcsi:
17180 case clang::X86::BI__builtin_ia32_ktestcdi: {
17186 return Success((~A & B) == 0, E);
17189 case clang::X86::BI__builtin_ia32_ktestzqi:
17190 case clang::X86::BI__builtin_ia32_ktestzhi:
17191 case clang::X86::BI__builtin_ia32_ktestzsi:
17192 case clang::X86::BI__builtin_ia32_ktestzdi: {
17198 return Success((A & B) == 0, E);
17201 case clang::X86::BI__builtin_ia32_kortestcqi:
17202 case clang::X86::BI__builtin_ia32_kortestchi:
17203 case clang::X86::BI__builtin_ia32_kortestcsi:
17204 case clang::X86::BI__builtin_ia32_kortestcdi: {
17210 return Success(~(A | B) == 0, E);
17213 case clang::X86::BI__builtin_ia32_kortestzqi:
17214 case clang::X86::BI__builtin_ia32_kortestzhi:
17215 case clang::X86::BI__builtin_ia32_kortestzsi:
17216 case clang::X86::BI__builtin_ia32_kortestzdi: {
17222 return Success((A | B) == 0, E);
17225 case clang::X86::BI__builtin_ia32_kunpckhi:
17226 case clang::X86::BI__builtin_ia32_kunpckdi:
17227 case clang::X86::BI__builtin_ia32_kunpcksi: {
17235 unsigned BW = A.getBitWidth();
17236 APSInt Result(A.trunc(BW / 2).concat(B.trunc(BW / 2)), A.isUnsigned());
17240 case clang::X86::BI__builtin_ia32_lzcnt_u16:
17241 case clang::X86::BI__builtin_ia32_lzcnt_u32:
17242 case clang::X86::BI__builtin_ia32_lzcnt_u64: {
17246 return Success(Val.countLeadingZeros(), E);
17249 case clang::X86::BI__builtin_ia32_tzcnt_u16:
17250 case clang::X86::BI__builtin_ia32_tzcnt_u32:
17251 case clang::X86::BI__builtin_ia32_tzcnt_u64: {
17255 return Success(Val.countTrailingZeros(), E);
17258 case clang::X86::BI__builtin_ia32_pdep_si:
17259 case clang::X86::BI__builtin_ia32_pdep_di: {
17265 unsigned BitWidth = Val.getBitWidth();
17267 for (
unsigned I = 0, P = 0; I != BitWidth; ++I)
17269 Result.setBitVal(I, Val[P++]);
17273 case clang::X86::BI__builtin_ia32_pext_si:
17274 case clang::X86::BI__builtin_ia32_pext_di: {
17280 unsigned BitWidth = Val.getBitWidth();
17282 for (
unsigned I = 0, P = 0; I != BitWidth; ++I)
17284 Result.setBitVal(P++, Val[I]);
17287 case X86::BI__builtin_ia32_ptestz128:
17288 case X86::BI__builtin_ia32_ptestz256:
17289 case X86::BI__builtin_ia32_vtestzps:
17290 case X86::BI__builtin_ia32_vtestzps256:
17291 case X86::BI__builtin_ia32_vtestzpd:
17292 case X86::BI__builtin_ia32_vtestzpd256: {
17294 [](
const APInt &A,
const APInt &B) {
return (A & B) == 0; });
17296 case X86::BI__builtin_ia32_ptestc128:
17297 case X86::BI__builtin_ia32_ptestc256:
17298 case X86::BI__builtin_ia32_vtestcps:
17299 case X86::BI__builtin_ia32_vtestcps256:
17300 case X86::BI__builtin_ia32_vtestcpd:
17301 case X86::BI__builtin_ia32_vtestcpd256: {
17303 [](
const APInt &A,
const APInt &B) {
return (~A & B) == 0; });
17305 case X86::BI__builtin_ia32_ptestnzc128:
17306 case X86::BI__builtin_ia32_ptestnzc256:
17307 case X86::BI__builtin_ia32_vtestnzcps:
17308 case X86::BI__builtin_ia32_vtestnzcps256:
17309 case X86::BI__builtin_ia32_vtestnzcpd:
17310 case X86::BI__builtin_ia32_vtestnzcpd256: {
17311 return EvalTestOp([](
const APInt &A,
const APInt &B) {
17312 return ((A & B) != 0) && ((~A & B) != 0);
17315 case X86::BI__builtin_ia32_kandqi:
17316 case X86::BI__builtin_ia32_kandhi:
17317 case X86::BI__builtin_ia32_kandsi:
17318 case X86::BI__builtin_ia32_kanddi: {
17319 return HandleMaskBinOp(
17320 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS & RHS; });
17323 case X86::BI__builtin_ia32_kandnqi:
17324 case X86::BI__builtin_ia32_kandnhi:
17325 case X86::BI__builtin_ia32_kandnsi:
17326 case X86::BI__builtin_ia32_kandndi: {
17327 return HandleMaskBinOp(
17328 [](
const APSInt &LHS,
const APSInt &RHS) {
return ~LHS & RHS; });
17331 case X86::BI__builtin_ia32_korqi:
17332 case X86::BI__builtin_ia32_korhi:
17333 case X86::BI__builtin_ia32_korsi:
17334 case X86::BI__builtin_ia32_kordi: {
17335 return HandleMaskBinOp(
17336 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS | RHS; });
17339 case X86::BI__builtin_ia32_kxnorqi:
17340 case X86::BI__builtin_ia32_kxnorhi:
17341 case X86::BI__builtin_ia32_kxnorsi:
17342 case X86::BI__builtin_ia32_kxnordi: {
17343 return HandleMaskBinOp(
17344 [](
const APSInt &LHS,
const APSInt &RHS) {
return ~(LHS ^ RHS); });
17347 case X86::BI__builtin_ia32_kxorqi:
17348 case X86::BI__builtin_ia32_kxorhi:
17349 case X86::BI__builtin_ia32_kxorsi:
17350 case X86::BI__builtin_ia32_kxordi: {
17351 return HandleMaskBinOp(
17352 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS ^ RHS; });
17355 case X86::BI__builtin_ia32_knotqi:
17356 case X86::BI__builtin_ia32_knothi:
17357 case X86::BI__builtin_ia32_knotsi:
17358 case X86::BI__builtin_ia32_knotdi: {
17366 case X86::BI__builtin_ia32_kaddqi:
17367 case X86::BI__builtin_ia32_kaddhi:
17368 case X86::BI__builtin_ia32_kaddsi:
17369 case X86::BI__builtin_ia32_kadddi: {
17370 return HandleMaskBinOp(
17371 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS + RHS; });
17374 case X86::BI__builtin_ia32_kmovb:
17375 case X86::BI__builtin_ia32_kmovw:
17376 case X86::BI__builtin_ia32_kmovd:
17377 case X86::BI__builtin_ia32_kmovq: {
17384 case X86::BI__builtin_ia32_kshiftliqi:
17385 case X86::BI__builtin_ia32_kshiftlihi:
17386 case X86::BI__builtin_ia32_kshiftlisi:
17387 case X86::BI__builtin_ia32_kshiftlidi: {
17388 return HandleMaskBinOp([](
const APSInt &LHS,
const APSInt &RHS) {
17389 unsigned Amt = RHS.getZExtValue() & 0xFF;
17390 if (Amt >= LHS.getBitWidth())
17391 return APSInt(APInt::getZero(LHS.getBitWidth()), LHS.isUnsigned());
17392 return APSInt(LHS.shl(Amt), LHS.isUnsigned());
17396 case X86::BI__builtin_ia32_kshiftriqi:
17397 case X86::BI__builtin_ia32_kshiftrihi:
17398 case X86::BI__builtin_ia32_kshiftrisi:
17399 case X86::BI__builtin_ia32_kshiftridi: {
17400 return HandleMaskBinOp([](
const APSInt &LHS,
const APSInt &RHS) {
17401 unsigned Amt = RHS.getZExtValue() & 0xFF;
17402 if (Amt >= LHS.getBitWidth())
17403 return APSInt(APInt::getZero(LHS.getBitWidth()), LHS.isUnsigned());
17404 return APSInt(LHS.lshr(Amt), LHS.isUnsigned());
17408 case clang::X86::BI__builtin_ia32_vec_ext_v4hi:
17409 case clang::X86::BI__builtin_ia32_vec_ext_v16qi:
17410 case clang::X86::BI__builtin_ia32_vec_ext_v8hi:
17411 case clang::X86::BI__builtin_ia32_vec_ext_v4si:
17412 case clang::X86::BI__builtin_ia32_vec_ext_v2di:
17413 case clang::X86::BI__builtin_ia32_vec_ext_v32qi:
17414 case clang::X86::BI__builtin_ia32_vec_ext_v16hi:
17415 case clang::X86::BI__builtin_ia32_vec_ext_v8si:
17416 case clang::X86::BI__builtin_ia32_vec_ext_v4di: {
17423 unsigned Idx =
static_cast<unsigned>(IdxAPS.getZExtValue() & (N - 1));
17427 case clang::X86::BI__builtin_ia32_cvtb2mask128:
17428 case clang::X86::BI__builtin_ia32_cvtb2mask256:
17429 case clang::X86::BI__builtin_ia32_cvtb2mask512:
17430 case clang::X86::BI__builtin_ia32_cvtw2mask128:
17431 case clang::X86::BI__builtin_ia32_cvtw2mask256:
17432 case clang::X86::BI__builtin_ia32_cvtw2mask512:
17433 case clang::X86::BI__builtin_ia32_cvtd2mask128:
17434 case clang::X86::BI__builtin_ia32_cvtd2mask256:
17435 case clang::X86::BI__builtin_ia32_cvtd2mask512:
17436 case clang::X86::BI__builtin_ia32_cvtq2mask128:
17437 case clang::X86::BI__builtin_ia32_cvtq2mask256:
17438 case clang::X86::BI__builtin_ia32_cvtq2mask512: {
17446 llvm::APInt Bits(RetWidth, 0);
17448 for (
unsigned ElemNum = 0; ElemNum != VectorLen; ++ElemNum) {
17450 unsigned MSB = A[A.getBitWidth() - 1];
17451 Bits.setBitVal(ElemNum, MSB);
17454 APSInt RetMask(Bits,
true);
17458 case clang::X86::BI__builtin_ia32_cmpb128_mask:
17459 case clang::X86::BI__builtin_ia32_cmpw128_mask:
17460 case clang::X86::BI__builtin_ia32_cmpd128_mask:
17461 case clang::X86::BI__builtin_ia32_cmpq128_mask:
17462 case clang::X86::BI__builtin_ia32_cmpb256_mask:
17463 case clang::X86::BI__builtin_ia32_cmpw256_mask:
17464 case clang::X86::BI__builtin_ia32_cmpd256_mask:
17465 case clang::X86::BI__builtin_ia32_cmpq256_mask:
17466 case clang::X86::BI__builtin_ia32_cmpb512_mask:
17467 case clang::X86::BI__builtin_ia32_cmpw512_mask:
17468 case clang::X86::BI__builtin_ia32_cmpd512_mask:
17469 case clang::X86::BI__builtin_ia32_cmpq512_mask:
17470 case clang::X86::BI__builtin_ia32_ucmpb128_mask:
17471 case clang::X86::BI__builtin_ia32_ucmpw128_mask:
17472 case clang::X86::BI__builtin_ia32_ucmpd128_mask:
17473 case clang::X86::BI__builtin_ia32_ucmpq128_mask:
17474 case clang::X86::BI__builtin_ia32_ucmpb256_mask:
17475 case clang::X86::BI__builtin_ia32_ucmpw256_mask:
17476 case clang::X86::BI__builtin_ia32_ucmpd256_mask:
17477 case clang::X86::BI__builtin_ia32_ucmpq256_mask:
17478 case clang::X86::BI__builtin_ia32_ucmpb512_mask:
17479 case clang::X86::BI__builtin_ia32_ucmpw512_mask:
17480 case clang::X86::BI__builtin_ia32_ucmpd512_mask:
17481 case clang::X86::BI__builtin_ia32_ucmpq512_mask: {
17485 (BuiltinOp >= clang::X86::BI__builtin_ia32_ucmpb128_mask &&
17486 BuiltinOp <= clang::X86::BI__builtin_ia32_ucmpw512_mask);
17499 unsigned RetWidth = Mask.getBitWidth();
17501 APSInt RetMask(llvm::APInt(RetWidth, 0),
true);
17503 for (
unsigned ElemNum = 0; ElemNum < VectorLen; ++ElemNum) {
17508 switch (
Opcode.getExtValue() & 0x7) {
17513 Result = IsUnsigned ? A.ult(B) : A.slt(B);
17516 Result = IsUnsigned ? A.ule(B) : A.sle(B);
17525 Result = IsUnsigned ? A.uge(B) : A.sge(B);
17528 Result = IsUnsigned ? A.ugt(B) : A.sgt(B);
17535 RetMask.setBitVal(ElemNum, Mask[ElemNum] &&
Result);
17540 case X86::BI__builtin_ia32_vpshufbitqmb128_mask:
17541 case X86::BI__builtin_ia32_vpshufbitqmb256_mask:
17542 case X86::BI__builtin_ia32_vpshufbitqmb512_mask: {
17555 unsigned NumBytesInQWord = 8;
17556 unsigned NumBitsInByte = 8;
17558 unsigned NumQWords = NumBytes / NumBytesInQWord;
17559 unsigned RetWidth = ZeroMask.getBitWidth();
17560 APSInt RetMask(llvm::APInt(RetWidth, 0),
true);
17562 for (
unsigned QWordId = 0; QWordId != NumQWords; ++QWordId) {
17563 APInt SourceQWord(64, 0);
17564 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
17568 SourceQWord.insertBits(
APInt(8, Byte & 0xFF), ByteIdx * NumBitsInByte);
17571 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
17572 unsigned SelIdx = QWordId * NumBytesInQWord + ByteIdx;
17575 if (ZeroMask[SelIdx]) {
17576 RetMask.setBitVal(SelIdx, SourceQWord[M]);
17588 const LValue &LV) {
17591 if (!LV.getLValueBase())
17596 if (!LV.getLValueDesignator().Invalid &&
17597 !LV.getLValueDesignator().isOnePastTheEnd())
17607 if (LV.getLValueDesignator().Invalid)
17613 return LV.getLValueOffset() == Size;
17623class DataRecursiveIntBinOpEvaluator {
17624 struct EvalResult {
17626 bool Failed =
false;
17628 EvalResult() =
default;
17630 void swap(EvalResult &RHS) {
17632 Failed = RHS.Failed;
17633 RHS.Failed =
false;
17639 EvalResult LHSResult;
17640 enum { AnyExprKind, BinOpKind, BinOpVisitedLHSKind }
Kind;
17643 Job(Job &&) =
default;
17645 void startSpeculativeEval(EvalInfo &Info) {
17646 SpecEvalRAII = SpeculativeEvaluationRAII(Info);
17650 SpeculativeEvaluationRAII SpecEvalRAII;
17653 SmallVector<Job, 16> Queue;
17655 IntExprEvaluator &IntEval;
17660 DataRecursiveIntBinOpEvaluator(IntExprEvaluator &IntEval,
APValue &
Result)
17661 : IntEval(IntEval), Info(IntEval.getEvalInfo()), FinalResult(
Result) { }
17667 static bool shouldEnqueue(
const BinaryOperator *E) {
17674 bool Traverse(
const BinaryOperator *E) {
17676 EvalResult PrevResult;
17677 while (!Queue.empty())
17678 process(PrevResult);
17680 if (PrevResult.Failed)
return false;
17682 FinalResult.
swap(PrevResult.Val);
17693 bool Error(
const Expr *E) {
17694 return IntEval.Error(E);
17697 return IntEval.Error(E, D);
17700 OptionalDiagnostic CCEDiag(
const Expr *E,
diag::kind D) {
17701 return Info.CCEDiag(E, D);
17705 bool VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
17706 bool &SuppressRHSDiags);
17708 bool VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
17711 void EvaluateExpr(
const Expr *E, EvalResult &
Result) {
17717 void process(EvalResult &
Result);
17719 void enqueue(
const Expr *E) {
17721 Queue.resize(Queue.size()+1);
17722 Queue.back().E = E;
17723 Queue.back().Kind = Job::AnyExprKind;
17729bool DataRecursiveIntBinOpEvaluator::
17730 VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
17731 bool &SuppressRHSDiags) {
17734 if (LHSResult.Failed)
17735 return Info.noteSideEffect();
17744 if (LHSAsBool == (E->
getOpcode() == BO_LOr)) {
17745 Success(LHSAsBool, E, LHSResult.Val);
17749 LHSResult.Failed =
true;
17753 if (!Info.noteSideEffect())
17759 SuppressRHSDiags =
true;
17768 if (LHSResult.Failed && !Info.noteFailure())
17779 assert(!LVal.
hasLValuePath() &&
"have designator for integer lvalue");
17781 uint64_t Offset64 = Offset.getQuantity();
17782 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
17784 : Offset64 + Index64);
17787bool DataRecursiveIntBinOpEvaluator::
17788 VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
17791 if (RHSResult.Failed)
17798 bool lhsResult, rhsResult;
17813 if (rhsResult == (E->
getOpcode() == BO_LOr))
17824 if (LHSResult.Failed || RHSResult.Failed)
17827 const APValue &LHSVal = LHSResult.Val;
17828 const APValue &RHSVal = RHSResult.Val;
17852 if (!LHSExpr || !RHSExpr)
17854 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
17855 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
17856 if (!LHSAddrExpr || !RHSAddrExpr)
17881void DataRecursiveIntBinOpEvaluator::process(EvalResult &
Result) {
17882 Job &job = Queue.back();
17884 switch (job.Kind) {
17885 case Job::AnyExprKind: {
17886 if (
const BinaryOperator *Bop = dyn_cast<BinaryOperator>(job.E)) {
17887 if (shouldEnqueue(Bop)) {
17888 job.Kind = Job::BinOpKind;
17889 enqueue(Bop->getLHS());
17894 EvaluateExpr(job.E,
Result);
17899 case Job::BinOpKind: {
17901 bool SuppressRHSDiags =
false;
17902 if (!VisitBinOpLHSOnly(
Result, Bop, SuppressRHSDiags)) {
17906 if (SuppressRHSDiags)
17907 job.startSpeculativeEval(Info);
17908 job.LHSResult.swap(
Result);
17909 job.Kind = Job::BinOpVisitedLHSKind;
17914 case Job::BinOpVisitedLHSKind: {
17918 Result.Failed = !VisitBinOp(job.LHSResult, RHS, Bop,
Result.Val);
17924 llvm_unreachable(
"Invalid Job::Kind!");
17928enum class CmpResult {
17937template <
class SuccessCB,
class AfterCB>
17940 SuccessCB &&
Success, AfterCB &&DoAfter) {
17945 "unsupported binary expression evaluation");
17947 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
17961 if (!LHSOK && !Info.noteFailure())
17966 return Success(CmpResult::Less, E);
17968 return Success(CmpResult::Greater, E);
17969 return Success(CmpResult::Equal, E);
17977 if (!LHSOK && !Info.noteFailure())
17982 return Success(CmpResult::Less, E);
17984 return Success(CmpResult::Greater, E);
17985 return Success(CmpResult::Equal, E);
17989 ComplexValue LHS, RHS;
17998 LHS.makeComplexFloat();
17999 LHS.FloatImag = APFloat(LHS.FloatReal.getSemantics());
18004 if (!LHSOK && !Info.noteFailure())
18010 RHS.makeComplexFloat();
18011 RHS.FloatImag = APFloat(RHS.FloatReal.getSemantics());
18015 if (LHS.isComplexFloat()) {
18016 APFloat::cmpResult CR_r =
18017 LHS.getComplexFloatReal().compare(RHS.getComplexFloatReal());
18018 APFloat::cmpResult CR_i =
18019 LHS.getComplexFloatImag().compare(RHS.getComplexFloatImag());
18020 bool IsEqual = CR_r == APFloat::cmpEqual && CR_i == APFloat::cmpEqual;
18021 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal, E);
18023 assert(IsEquality &&
"invalid complex comparison");
18024 bool IsEqual = LHS.getComplexIntReal() == RHS.getComplexIntReal() &&
18025 LHS.getComplexIntImag() == RHS.getComplexIntImag();
18026 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal, E);
18032 APFloat RHS(0.0), LHS(0.0);
18035 if (!LHSOK && !Info.noteFailure())
18042 llvm::APFloatBase::cmpResult APFloatCmpResult = LHS.compare(RHS);
18043 if (!Info.InConstantContext &&
18044 APFloatCmpResult == APFloat::cmpUnordered &&
18047 Info.FFDiag(E, diag::note_constexpr_float_arithmetic_strict);
18050 auto GetCmpRes = [&]() {
18051 switch (APFloatCmpResult) {
18052 case APFloat::cmpEqual:
18053 return CmpResult::Equal;
18054 case APFloat::cmpLessThan:
18055 return CmpResult::Less;
18056 case APFloat::cmpGreaterThan:
18057 return CmpResult::Greater;
18058 case APFloat::cmpUnordered:
18059 return CmpResult::Unordered;
18061 llvm_unreachable(
"Unrecognised APFloat::cmpResult enum");
18063 return Success(GetCmpRes(), E);
18067 LValue LHSValue, RHSValue;
18070 if (!LHSOK && !Info.noteFailure())
18081 if (Info.checkingPotentialConstantExpression() &&
18082 (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown))
18084 auto DiagComparison = [&] (
unsigned DiagID,
bool Reversed =
false) {
18085 std::string LHS = LHSValue.toString(Info.Ctx, E->
getLHS()->
getType());
18086 std::string RHS = RHSValue.toString(Info.Ctx, E->
getRHS()->
getType());
18087 Info.FFDiag(E, DiagID)
18094 return DiagComparison(
18095 diag::note_constexpr_pointer_comparison_unspecified);
18101 if ((!LHSValue.Base && !LHSValue.Offset.
isZero()) ||
18102 (!RHSValue.Base && !RHSValue.Offset.
isZero()))
18103 return DiagComparison(diag::note_constexpr_pointer_constant_comparison,
18117 return DiagComparison(diag::note_constexpr_literal_comparison);
18119 return DiagComparison(diag::note_constexpr_opaque_call_comparison,
18124 return DiagComparison(diag::note_constexpr_pointer_weak_comparison,
18128 if (LHSValue.Base && LHSValue.Offset.
isZero() &&
18130 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
18132 if (RHSValue.Base && RHSValue.Offset.
isZero() &&
18134 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
18140 return DiagComparison(
18141 diag::note_constexpr_pointer_comparison_zero_sized);
18142 if (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown)
18143 return DiagComparison(
18144 diag::note_constexpr_pointer_comparison_unspecified);
18146 return Success(CmpResult::Unequal, E);
18149 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
18150 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
18152 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
18153 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
18163 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid && IsRelational) {
18164 bool WasArrayIndex;
18167 :
getType(LHSValue.Base).getNonReferenceType(),
18168 LHSDesignator, RHSDesignator, WasArrayIndex);
18175 if (!WasArrayIndex && Mismatch < LHSDesignator.Entries.size() &&
18176 Mismatch < RHSDesignator.Entries.size()) {
18177 const FieldDecl *LF = getAsField(LHSDesignator.Entries[Mismatch]);
18178 const FieldDecl *RF = getAsField(RHSDesignator.Entries[Mismatch]);
18180 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_classes);
18182 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
18183 << getAsBaseClass(LHSDesignator.Entries[Mismatch])
18186 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
18187 << getAsBaseClass(RHSDesignator.Entries[Mismatch])
18192 diag::note_constexpr_pointer_comparison_differing_access)
18203 assert(PtrSize <= 64 &&
"Unexpected pointer width");
18204 uint64_t Mask = ~0ULL >> (64 - PtrSize);
18205 CompareLHS &= Mask;
18206 CompareRHS &= Mask;
18211 if (!LHSValue.Base.
isNull() && IsRelational) {
18216 uint64_t OffsetLimit = Size.getQuantity();
18217 if (CompareLHS > OffsetLimit || CompareRHS > OffsetLimit)
18221 if (CompareLHS < CompareRHS)
18222 return Success(CmpResult::Less, E);
18223 if (CompareLHS > CompareRHS)
18224 return Success(CmpResult::Greater, E);
18225 return Success(CmpResult::Equal, E);
18229 assert(IsEquality &&
"unexpected member pointer operation");
18232 MemberPtr LHSValue, RHSValue;
18235 if (!LHSOK && !Info.noteFailure())
18243 if (LHSValue.getDecl() && LHSValue.getDecl()->isWeak()) {
18244 Info.FFDiag(E, diag::note_constexpr_mem_pointer_weak_comparison)
18245 << LHSValue.getDecl();
18248 if (RHSValue.getDecl() && RHSValue.getDecl()->isWeak()) {
18249 Info.FFDiag(E, diag::note_constexpr_mem_pointer_weak_comparison)
18250 << RHSValue.getDecl();
18257 if (!LHSValue.getDecl() || !RHSValue.getDecl()) {
18258 bool Equal = !LHSValue.getDecl() && !RHSValue.getDecl();
18259 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal, E);
18264 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(LHSValue.getDecl()))
18265 if (MD->isVirtual())
18266 Info.CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
18267 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(RHSValue.getDecl()))
18268 if (MD->isVirtual())
18269 Info.CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
18275 bool Equal = LHSValue == RHSValue;
18276 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal, E);
18281 assert(RHSTy->
isNullPtrType() &&
"missing pointer conversion");
18289 return Success(CmpResult::Equal, E);
18295bool RecordExprEvaluator::VisitBinCmp(
const BinaryOperator *E) {
18299 auto OnSuccess = [&](CmpResult CR,
const BinaryOperator *E) {
18302 case CmpResult::Unequal:
18303 llvm_unreachable(
"should never produce Unequal for three-way comparison");
18304 case CmpResult::Less:
18305 CCR = ComparisonCategoryResult::Less;
18307 case CmpResult::Equal:
18308 CCR = ComparisonCategoryResult::Equal;
18310 case CmpResult::Greater:
18311 CCR = ComparisonCategoryResult::Greater;
18313 case CmpResult::Unordered:
18314 CCR = ComparisonCategoryResult::Unordered;
18319 const ComparisonCategoryInfo &CmpInfo =
18328 ConstantExprKind::Normal);
18331 return ExprEvaluatorBaseTy::VisitBinCmp(E);
18335bool RecordExprEvaluator::VisitCXXParenListInitExpr(
18336 const CXXParenListInitExpr *E) {
18337 return VisitCXXParenListOrInitListExpr(E, E->
getInitExprs());
18340bool IntExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
18345 if (!Info.noteFailure())
18349 if (DataRecursiveIntBinOpEvaluator::shouldEnqueue(E))
18350 return DataRecursiveIntBinOpEvaluator(*
this,
Result).Traverse(E);
18354 "DataRecursiveIntBinOpEvaluator should have handled integral types");
18359 auto OnSuccess = [&](CmpResult CR,
const BinaryOperator *E) {
18360 assert((CR != CmpResult::Unequal || E->
isEqualityOp()) &&
18361 "should only produce Unequal for equality comparisons");
18362 bool IsEqual = CR == CmpResult::Equal,
18363 IsLess = CR == CmpResult::Less,
18364 IsGreater = CR == CmpResult::Greater;
18368 llvm_unreachable(
"unsupported binary operator");
18371 return Success(IsEqual == (Op == BO_EQ), E);
18375 return Success(IsGreater, E);
18377 return Success(IsEqual || IsLess, E);
18379 return Success(IsEqual || IsGreater, E);
18383 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
18392 LValue LHSValue, RHSValue;
18395 if (!LHSOK && !Info.noteFailure())
18404 if (Info.checkingPotentialConstantExpression() &&
18405 (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown))
18408 const Expr *LHSExpr = LHSValue.Base.
dyn_cast<
const Expr *>();
18409 const Expr *RHSExpr = RHSValue.Base.
dyn_cast<
const Expr *>();
18411 auto DiagArith = [&](
unsigned DiagID) {
18412 std::string LHS = LHSValue.toString(Info.Ctx, E->
getLHS()->
getType());
18413 std::string RHS = RHSValue.toString(Info.Ctx, E->
getRHS()->
getType());
18414 Info.FFDiag(E, DiagID) << LHS << RHS;
18415 if (LHSExpr && LHSExpr == RHSExpr)
18417 diag::note_constexpr_repeated_literal_eval)
18422 if (!LHSExpr || !RHSExpr)
18423 return DiagArith(diag::note_constexpr_pointer_arith_unspecified);
18426 return DiagArith(diag::note_constexpr_literal_arith);
18428 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
18429 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
18430 if (!LHSAddrExpr || !RHSAddrExpr)
18438 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
18439 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
18441 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
18442 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
18448 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid &&
18451 Info.CCEDiag(E, diag::note_constexpr_pointer_subtraction_not_same_array);
18456 CharUnits ElementSize;
18463 if (ElementSize.
isZero()) {
18464 Info.FFDiag(E, diag::note_constexpr_pointer_subtraction_zero_size)
18481 APSInt TrueResult = (LHS - RHS) / ElemSize;
18484 if (
Result.extend(65) != TrueResult &&
18490 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
18495bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr(
18496 const UnaryExprOrTypeTraitExpr *E) {
18498 case UETT_PreferredAlignOf:
18499 case UETT_AlignOf: {
18508 case UETT_PtrAuthTypeDiscriminator: {
18514 case UETT_VecStep: {
18518 unsigned n = Ty->
castAs<VectorType>()->getNumElements();
18530 case UETT_DataSizeOf:
18531 case UETT_SizeOf: {
18535 if (
const ReferenceType *Ref = SrcTy->
getAs<ReferenceType>())
18546 case UETT_OpenMPRequiredSimdAlign:
18553 case UETT_VectorElements: {
18557 if (
const auto *VT = Ty->
getAs<VectorType>())
18561 if (Info.InConstantContext)
18562 Info.CCEDiag(E, diag::note_constexpr_non_const_vectorelements)
18567 case UETT_CountOf: {
18573 if (
const auto *CAT =
18585 if (VAT->getElementType()->isArrayType()) {
18588 if (!VAT->getSizeExpr()) {
18593 std::optional<APSInt> Res =
18594 VAT->getSizeExpr()->getIntegerConstantExpr(Info.Ctx);
18600 Res->getZExtValue()};
18612 llvm_unreachable(
"unknown expr/type trait");
18615bool IntExprEvaluator::VisitOffsetOfExpr(
const OffsetOfExpr *OOE) {
18621 for (
unsigned i = 0; i != n; ++i) {
18634 Result += IdxResult.getSExtValue() * ElementSize;
18639 FieldDecl *MemberDecl = ON.
getField();
18646 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
18653 llvm_unreachable(
"dependent __builtin_offsetof");
18656 CXXBaseSpecifier *BaseSpec = ON.
getBase();
18668 CurrentType = BaseSpec->
getType();
18682bool IntExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
18701 if (Info.checkingForUndefinedBehavior())
18703 diag::warn_integer_constant_overflow)
18731bool IntExprEvaluator::VisitCastExpr(
const CastExpr *E) {
18733 QualType DestType = E->
getType();
18734 QualType SrcType = SubExpr->
getType();
18737 case CK_BaseToDerived:
18738 case CK_DerivedToBase:
18739 case CK_UncheckedDerivedToBase:
18742 case CK_ArrayToPointerDecay:
18743 case CK_FunctionToPointerDecay:
18744 case CK_NullToPointer:
18745 case CK_NullToMemberPointer:
18746 case CK_BaseToDerivedMemberPointer:
18747 case CK_DerivedToBaseMemberPointer:
18748 case CK_ReinterpretMemberPointer:
18749 case CK_ConstructorConversion:
18750 case CK_IntegralToPointer:
18752 case CK_VectorSplat:
18753 case CK_IntegralToFloating:
18754 case CK_FloatingCast:
18755 case CK_CPointerToObjCPointerCast:
18756 case CK_BlockPointerToObjCPointerCast:
18757 case CK_AnyPointerToBlockPointerCast:
18758 case CK_ObjCObjectLValueCast:
18759 case CK_FloatingRealToComplex:
18760 case CK_FloatingComplexToReal:
18761 case CK_FloatingComplexCast:
18762 case CK_FloatingComplexToIntegralComplex:
18763 case CK_IntegralRealToComplex:
18764 case CK_IntegralComplexCast:
18765 case CK_IntegralComplexToFloatingComplex:
18766 case CK_BuiltinFnToFnPtr:
18767 case CK_ZeroToOCLOpaqueType:
18768 case CK_NonAtomicToAtomic:
18769 case CK_AddressSpaceConversion:
18770 case CK_IntToOCLSampler:
18771 case CK_FloatingToFixedPoint:
18772 case CK_FixedPointToFloating:
18773 case CK_FixedPointCast:
18774 case CK_IntegralToFixedPoint:
18775 case CK_MatrixCast:
18776 case CK_HLSLAggregateSplatCast:
18777 llvm_unreachable(
"invalid cast kind for integral value");
18781 case CK_LValueBitCast:
18782 case CK_ARCProduceObject:
18783 case CK_ARCConsumeObject:
18784 case CK_ARCReclaimReturnedObject:
18785 case CK_ARCExtendBlockObject:
18786 case CK_CopyAndAutoreleaseBlockObject:
18789 case CK_UserDefinedConversion:
18790 case CK_LValueToRValue:
18791 case CK_AtomicToNonAtomic:
18793 case CK_LValueToRValueBitCast:
18794 case CK_HLSLArrayRValue:
18795 return ExprEvaluatorBaseTy::VisitCastExpr(E);
18797 case CK_MemberPointerToBoolean:
18798 case CK_PointerToBoolean:
18799 case CK_IntegralToBoolean:
18800 case CK_FloatingToBoolean:
18801 case CK_BooleanToSignedIntegral:
18802 case CK_FloatingComplexToBoolean:
18803 case CK_IntegralComplexToBoolean: {
18808 if (BoolResult && E->
getCastKind() == CK_BooleanToSignedIntegral)
18810 return Success(IntResult, E);
18813 case CK_FixedPointToIntegral: {
18818 llvm::APSInt
Result = Src.convertToInt(
18826 case CK_FixedPointToBoolean: {
18829 if (!
Evaluate(Val, Info, SubExpr))
18834 case CK_IntegralCast: {
18835 if (!Visit(SubExpr))
18845 if (
Result.isAddrLabelDiff()) {
18846 unsigned DestBits = Info.Ctx.
getTypeSize(DestType);
18847 return DestBits >= 32 && DestBits <= Info.Ctx.
getTypeSize(SrcType);
18865 if (!ED->isFixed()) {
18869 ED->getValueRange(
Max,
Min);
18872 if (ED->getNumNegativeBits() &&
18873 (
Max.slt(
Result.getInt().getSExtValue()) ||
18874 Min.sgt(
Result.getInt().getSExtValue())))
18875 Info.CCEDiag(E, diag::note_constexpr_unscoped_enum_out_of_range)
18876 << llvm::toString(
Result.getInt(), 10) <<
Min.getSExtValue()
18877 <<
Max.getSExtValue() << ED;
18878 else if (!ED->getNumNegativeBits() &&
18879 Max.ult(
Result.getInt().getZExtValue()))
18880 Info.CCEDiag(E, diag::note_constexpr_unscoped_enum_out_of_range)
18881 << llvm::toString(
Result.getInt(), 10) <<
Min.getZExtValue()
18882 <<
Max.getZExtValue() << ED;
18890 case CK_PointerToIntegral: {
18891 CCEDiag(E, diag::note_constexpr_invalid_cast)
18892 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
18899 if (LV.getLValueBase()) {
18907 LV.Designator.setInvalid();
18915 if (!
V.toIntegralConstant(AsInt, SrcType, Info.Ctx))
18916 llvm_unreachable(
"Can't cast this!");
18921 case CK_IntegralComplexToReal: {
18925 return Success(
C.getComplexIntReal(), E);
18928 case CK_FloatingToIntegral: {
18938 case CK_HLSLVectorTruncation: {
18944 case CK_HLSLMatrixTruncation: {
18948 case CK_HLSLElementwiseCast: {
18961 return Success(ResultVal, E);
18965 llvm_unreachable(
"unknown cast resulting in integral value");
18968bool IntExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
18973 if (!LV.isComplexInt())
18975 return Success(LV.getComplexIntReal(), E);
18981bool IntExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
18986 if (!LV.isComplexInt())
18988 return Success(LV.getComplexIntImag(), E);
18995bool IntExprEvaluator::VisitSizeOfPackExpr(
const SizeOfPackExpr *E) {
18999bool IntExprEvaluator::VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E) {
19003bool IntExprEvaluator::VisitConceptSpecializationExpr(
19004 const ConceptSpecializationExpr *E) {
19008bool IntExprEvaluator::VisitRequiresExpr(
const RequiresExpr *E) {
19012bool FixedPointExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
19022 if (!
Result.isFixedPoint())
19025 APFixedPoint Negated =
Result.getFixedPoint().negate(&Overflowed);
19039bool FixedPointExprEvaluator::VisitCastExpr(
const CastExpr *E) {
19041 QualType DestType = E->
getType();
19043 "Expected destination type to be a fixed point type");
19047 case CK_FixedPointCast: {
19052 APFixedPoint
Result = Src.convert(DestFXSema, &Overflowed);
19054 if (Info.checkingForUndefinedBehavior())
19056 diag::warn_fixedpoint_constant_overflow)
19063 case CK_IntegralToFixedPoint: {
19069 APFixedPoint IntResult = APFixedPoint::getFromIntValue(
19073 if (Info.checkingForUndefinedBehavior())
19075 diag::warn_fixedpoint_constant_overflow)
19076 << IntResult.toString() << E->
getType();
19081 return Success(IntResult, E);
19083 case CK_FloatingToFixedPoint: {
19089 APFixedPoint
Result = APFixedPoint::getFromFloatValue(
19093 if (Info.checkingForUndefinedBehavior())
19095 diag::warn_fixedpoint_constant_overflow)
19104 case CK_LValueToRValue:
19105 return ExprEvaluatorBaseTy::VisitCastExpr(E);
19111bool FixedPointExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
19113 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
19115 const Expr *LHS = E->
getLHS();
19116 const Expr *RHS = E->
getRHS();
19127 bool OpOverflow =
false, ConversionOverflow =
false;
19128 APFixedPoint
Result(LHSFX.getSemantics());
19131 Result = LHSFX.add(RHSFX, &OpOverflow)
19132 .convert(ResultFXSema, &ConversionOverflow);
19136 Result = LHSFX.sub(RHSFX, &OpOverflow)
19137 .convert(ResultFXSema, &ConversionOverflow);
19141 Result = LHSFX.mul(RHSFX, &OpOverflow)
19142 .convert(ResultFXSema, &ConversionOverflow);
19146 if (RHSFX.getValue() == 0) {
19147 Info.FFDiag(E, diag::note_expr_divide_by_zero);
19150 Result = LHSFX.div(RHSFX, &OpOverflow)
19151 .convert(ResultFXSema, &ConversionOverflow);
19157 llvm::APSInt RHSVal = RHSFX.getValue();
19160 LHSSema.getWidth() - (unsigned)LHSSema.hasUnsignedPadding();
19161 unsigned Amt = RHSVal.getLimitedValue(ShiftBW - 1);
19165 if (RHSVal.isNegative())
19166 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHSVal;
19167 else if (Amt != RHSVal)
19168 Info.CCEDiag(E, diag::note_constexpr_large_shift)
19169 << RHSVal << E->
getType() << ShiftBW;
19172 Result = LHSFX.shl(Amt, &OpOverflow);
19174 Result = LHSFX.shr(Amt, &OpOverflow);
19180 if (OpOverflow || ConversionOverflow) {
19181 if (Info.checkingForUndefinedBehavior())
19183 diag::warn_fixedpoint_constant_overflow)
19196class FloatExprEvaluator
19197 :
public ExprEvaluatorBase<FloatExprEvaluator> {
19200 FloatExprEvaluator(EvalInfo &info, APFloat &result)
19201 : ExprEvaluatorBaseTy(info),
Result(result) {}
19208 bool ZeroInitialization(
const Expr *E) {
19213 bool VisitCallExpr(
const CallExpr *E);
19215 bool VisitUnaryOperator(
const UnaryOperator *E);
19216 bool VisitBinaryOperator(
const BinaryOperator *E);
19217 bool VisitFloatingLiteral(
const FloatingLiteral *E);
19218 bool VisitCastExpr(
const CastExpr *E);
19220 bool VisitUnaryReal(
const UnaryOperator *E);
19221 bool VisitUnaryImag(
const UnaryOperator *E);
19230 return FloatExprEvaluator(Info, Result).Visit(E);
19237 llvm::APFloat &Result) {
19239 if (!S)
return false;
19241 const llvm::fltSemantics &Sem = Context.getFloatTypeSemantics(ResultTy);
19247 fill = llvm::APInt(32, 0);
19248 else if (S->
getString().getAsInteger(0, fill))
19251 if (Context.getTargetInfo().isNan2008()) {
19253 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
19255 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
19263 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
19265 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
19271bool FloatExprEvaluator::VisitCallExpr(
const CallExpr *E) {
19272 if (!IsConstantEvaluatedBuiltinCall(E))
19273 return ExprEvaluatorBaseTy::VisitCallExpr(E);
19279 case Builtin::BI__builtin_huge_val:
19280 case Builtin::BI__builtin_huge_valf:
19281 case Builtin::BI__builtin_huge_vall:
19282 case Builtin::BI__builtin_huge_valf16:
19283 case Builtin::BI__builtin_huge_valf128:
19284 case Builtin::BI__builtin_inf:
19285 case Builtin::BI__builtin_inff:
19286 case Builtin::BI__builtin_infl:
19287 case Builtin::BI__builtin_inff16:
19288 case Builtin::BI__builtin_inff128: {
19289 const llvm::fltSemantics &Sem =
19291 Result = llvm::APFloat::getInf(Sem);
19295 case Builtin::BI__builtin_nans:
19296 case Builtin::BI__builtin_nansf:
19297 case Builtin::BI__builtin_nansl:
19298 case Builtin::BI__builtin_nansf16:
19299 case Builtin::BI__builtin_nansf128:
19305 case Builtin::BI__builtin_nan:
19306 case Builtin::BI__builtin_nanf:
19307 case Builtin::BI__builtin_nanl:
19308 case Builtin::BI__builtin_nanf16:
19309 case Builtin::BI__builtin_nanf128:
19317 case Builtin::BI__builtin_elementwise_abs:
19318 case Builtin::BI__builtin_fabs:
19319 case Builtin::BI__builtin_fabsf:
19320 case Builtin::BI__builtin_fabsl:
19321 case Builtin::BI__builtin_fabsf128:
19330 if (
Result.isNegative())
19334 case Builtin::BI__arithmetic_fence:
19341 case Builtin::BI__builtin_copysign:
19342 case Builtin::BI__builtin_copysignf:
19343 case Builtin::BI__builtin_copysignl:
19344 case Builtin::BI__builtin_copysignf128: {
19353 case Builtin::BI__builtin_fmax:
19354 case Builtin::BI__builtin_fmaxf:
19355 case Builtin::BI__builtin_fmaxl:
19356 case Builtin::BI__builtin_fmaxf16:
19357 case Builtin::BI__builtin_fmaxf128: {
19366 case Builtin::BI__builtin_fmin:
19367 case Builtin::BI__builtin_fminf:
19368 case Builtin::BI__builtin_fminl:
19369 case Builtin::BI__builtin_fminf16:
19370 case Builtin::BI__builtin_fminf128: {
19379 case Builtin::BI__builtin_fmaximum_num:
19380 case Builtin::BI__builtin_fmaximum_numf:
19381 case Builtin::BI__builtin_fmaximum_numl:
19382 case Builtin::BI__builtin_fmaximum_numf16:
19383 case Builtin::BI__builtin_fmaximum_numf128: {
19392 case Builtin::BI__builtin_fminimum_num:
19393 case Builtin::BI__builtin_fminimum_numf:
19394 case Builtin::BI__builtin_fminimum_numl:
19395 case Builtin::BI__builtin_fminimum_numf16:
19396 case Builtin::BI__builtin_fminimum_numf128: {
19405 case Builtin::BI__builtin_elementwise_fma: {
19410 APFloat SourceY(0.), SourceZ(0.);
19416 (void)
Result.fusedMultiplyAdd(SourceY, SourceZ, RM);
19420 case clang::X86::BI__builtin_ia32_vec_ext_v4sf: {
19427 unsigned Idx =
static_cast<unsigned>(IdxAPS.getZExtValue() & (N - 1));
19433bool FloatExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
19445bool FloatExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
19456 Result = llvm::APFloat::getZero(Sem);
19460bool FloatExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
19462 default:
return Error(E);
19476bool FloatExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
19478 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
19482 if (!LHSOK && !Info.noteFailure())
19488bool FloatExprEvaluator::VisitFloatingLiteral(
const FloatingLiteral *E) {
19493bool FloatExprEvaluator::VisitCastExpr(
const CastExpr *E) {
19498 return ExprEvaluatorBaseTy::VisitCastExpr(E);
19500 case CK_HLSLAggregateSplatCast:
19501 llvm_unreachable(
"invalid cast kind for floating value");
19503 case CK_IntegralToFloating: {
19512 case CK_FixedPointToFloating: {
19521 case CK_FloatingCast: {
19522 if (!Visit(SubExpr))
19528 case CK_FloatingComplexToReal: {
19532 Result =
V.getComplexFloatReal();
19535 case CK_HLSLVectorTruncation: {
19541 case CK_HLSLMatrixTruncation: {
19545 case CK_HLSLElementwiseCast: {
19560 return Success(ResultVal, E);
19570class ComplexExprEvaluator
19571 :
public ExprEvaluatorBase<ComplexExprEvaluator> {
19575 ComplexExprEvaluator(EvalInfo &info, ComplexValue &
Result)
19583 bool ZeroInitialization(
const Expr *E);
19589 bool VisitImaginaryLiteral(
const ImaginaryLiteral *E);
19590 bool VisitCastExpr(
const CastExpr *E);
19591 bool VisitBinaryOperator(
const BinaryOperator *E);
19592 bool VisitUnaryOperator(
const UnaryOperator *E);
19593 bool VisitInitListExpr(
const InitListExpr *E);
19594 bool VisitCallExpr(
const CallExpr *E);
19602 return ComplexExprEvaluator(Info, Result).Visit(E);
19605bool ComplexExprEvaluator::ZeroInitialization(
const Expr *E) {
19606 QualType ElemTy = E->
getType()->
castAs<ComplexType>()->getElementType();
19608 Result.makeComplexFloat();
19613 Result.makeComplexInt();
19621bool ComplexExprEvaluator::VisitImaginaryLiteral(
const ImaginaryLiteral *E) {
19625 Result.makeComplexFloat();
19634 "Unexpected imaginary literal.");
19636 Result.makeComplexInt();
19641 Result.IntReal =
APSInt(Imag.getBitWidth(), !Imag.isSigned());
19646bool ComplexExprEvaluator::VisitCastExpr(
const CastExpr *E) {
19650 case CK_BaseToDerived:
19651 case CK_DerivedToBase:
19652 case CK_UncheckedDerivedToBase:
19655 case CK_ArrayToPointerDecay:
19656 case CK_FunctionToPointerDecay:
19657 case CK_NullToPointer:
19658 case CK_NullToMemberPointer:
19659 case CK_BaseToDerivedMemberPointer:
19660 case CK_DerivedToBaseMemberPointer:
19661 case CK_MemberPointerToBoolean:
19662 case CK_ReinterpretMemberPointer:
19663 case CK_ConstructorConversion:
19664 case CK_IntegralToPointer:
19665 case CK_PointerToIntegral:
19666 case CK_PointerToBoolean:
19668 case CK_VectorSplat:
19669 case CK_IntegralCast:
19670 case CK_BooleanToSignedIntegral:
19671 case CK_IntegralToBoolean:
19672 case CK_IntegralToFloating:
19673 case CK_FloatingToIntegral:
19674 case CK_FloatingToBoolean:
19675 case CK_FloatingCast:
19676 case CK_CPointerToObjCPointerCast:
19677 case CK_BlockPointerToObjCPointerCast:
19678 case CK_AnyPointerToBlockPointerCast:
19679 case CK_ObjCObjectLValueCast:
19680 case CK_FloatingComplexToReal:
19681 case CK_FloatingComplexToBoolean:
19682 case CK_IntegralComplexToReal:
19683 case CK_IntegralComplexToBoolean:
19684 case CK_ARCProduceObject:
19685 case CK_ARCConsumeObject:
19686 case CK_ARCReclaimReturnedObject:
19687 case CK_ARCExtendBlockObject:
19688 case CK_CopyAndAutoreleaseBlockObject:
19689 case CK_BuiltinFnToFnPtr:
19690 case CK_ZeroToOCLOpaqueType:
19691 case CK_NonAtomicToAtomic:
19692 case CK_AddressSpaceConversion:
19693 case CK_IntToOCLSampler:
19694 case CK_FloatingToFixedPoint:
19695 case CK_FixedPointToFloating:
19696 case CK_FixedPointCast:
19697 case CK_FixedPointToBoolean:
19698 case CK_FixedPointToIntegral:
19699 case CK_IntegralToFixedPoint:
19700 case CK_MatrixCast:
19701 case CK_HLSLVectorTruncation:
19702 case CK_HLSLMatrixTruncation:
19703 case CK_HLSLElementwiseCast:
19704 case CK_HLSLAggregateSplatCast:
19705 llvm_unreachable(
"invalid cast kind for complex value");
19707 case CK_LValueToRValue:
19708 case CK_AtomicToNonAtomic:
19710 case CK_LValueToRValueBitCast:
19711 case CK_HLSLArrayRValue:
19712 return ExprEvaluatorBaseTy::VisitCastExpr(E);
19715 case CK_LValueBitCast:
19716 case CK_UserDefinedConversion:
19719 case CK_FloatingRealToComplex: {
19724 Result.makeComplexFloat();
19729 case CK_FloatingComplexCast: {
19733 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
19741 case CK_FloatingComplexToIntegralComplex: {
19745 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
19748 Result.makeComplexInt();
19755 case CK_IntegralRealToComplex: {
19760 Result.makeComplexInt();
19761 Result.IntImag =
APSInt(Real.getBitWidth(), !Real.isSigned());
19765 case CK_IntegralComplexCast: {
19769 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
19778 case CK_IntegralComplexToFloatingComplex: {
19784 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
19787 Result.makeComplexFloat();
19789 To,
Result.FloatReal) &&
19795 llvm_unreachable(
"unknown cast resulting in complex value");
19800 const uint8_t GFInv[256] = {
19801 0x00, 0x01, 0x8d, 0xf6, 0xcb, 0x52, 0x7b, 0xd1, 0xe8, 0x4f, 0x29, 0xc0,
19802 0xb0, 0xe1, 0xe5, 0xc7, 0x74, 0xb4, 0xaa, 0x4b, 0x99, 0x2b, 0x60, 0x5f,
19803 0x58, 0x3f, 0xfd, 0xcc, 0xff, 0x40, 0xee, 0xb2, 0x3a, 0x6e, 0x5a, 0xf1,
19804 0x55, 0x4d, 0xa8, 0xc9, 0xc1, 0x0a, 0x98, 0x15, 0x30, 0x44, 0xa2, 0xc2,
19805 0x2c, 0x45, 0x92, 0x6c, 0xf3, 0x39, 0x66, 0x42, 0xf2, 0x35, 0x20, 0x6f,
19806 0x77, 0xbb, 0x59, 0x19, 0x1d, 0xfe, 0x37, 0x67, 0x2d, 0x31, 0xf5, 0x69,
19807 0xa7, 0x64, 0xab, 0x13, 0x54, 0x25, 0xe9, 0x09, 0xed, 0x5c, 0x05, 0xca,
19808 0x4c, 0x24, 0x87, 0xbf, 0x18, 0x3e, 0x22, 0xf0, 0x51, 0xec, 0x61, 0x17,
19809 0x16, 0x5e, 0xaf, 0xd3, 0x49, 0xa6, 0x36, 0x43, 0xf4, 0x47, 0x91, 0xdf,
19810 0x33, 0x93, 0x21, 0x3b, 0x79, 0xb7, 0x97, 0x85, 0x10, 0xb5, 0xba, 0x3c,
19811 0xb6, 0x70, 0xd0, 0x06, 0xa1, 0xfa, 0x81, 0x82, 0x83, 0x7e, 0x7f, 0x80,
19812 0x96, 0x73, 0xbe, 0x56, 0x9b, 0x9e, 0x95, 0xd9, 0xf7, 0x02, 0xb9, 0xa4,
19813 0xde, 0x6a, 0x32, 0x6d, 0xd8, 0x8a, 0x84, 0x72, 0x2a, 0x14, 0x9f, 0x88,
19814 0xf9, 0xdc, 0x89, 0x9a, 0xfb, 0x7c, 0x2e, 0xc3, 0x8f, 0xb8, 0x65, 0x48,
19815 0x26, 0xc8, 0x12, 0x4a, 0xce, 0xe7, 0xd2, 0x62, 0x0c, 0xe0, 0x1f, 0xef,
19816 0x11, 0x75, 0x78, 0x71, 0xa5, 0x8e, 0x76, 0x3d, 0xbd, 0xbc, 0x86, 0x57,
19817 0x0b, 0x28, 0x2f, 0xa3, 0xda, 0xd4, 0xe4, 0x0f, 0xa9, 0x27, 0x53, 0x04,
19818 0x1b, 0xfc, 0xac, 0xe6, 0x7a, 0x07, 0xae, 0x63, 0xc5, 0xdb, 0xe2, 0xea,
19819 0x94, 0x8b, 0xc4, 0xd5, 0x9d, 0xf8, 0x90, 0x6b, 0xb1, 0x0d, 0xd6, 0xeb,
19820 0xc6, 0x0e, 0xcf, 0xad, 0x08, 0x4e, 0xd7, 0xe3, 0x5d, 0x50, 0x1e, 0xb3,
19821 0x5b, 0x23, 0x38, 0x34, 0x68, 0x46, 0x03, 0x8c, 0xdd, 0x9c, 0x7d, 0xa0,
19822 0xcd, 0x1a, 0x41, 0x1c};
19824 return GFInv[Byte];
19829 unsigned NumBitsInByte = 8;
19831 uint8_t RetByte = 0;
19832 for (uint32_t BitIdx = 0; BitIdx != NumBitsInByte; ++BitIdx) {
19834 AQword.lshr((7 -
static_cast<int32_t
>(BitIdx)) * NumBitsInByte)
19841 Product = AByte & XByte;
19843 uint8_t Parity = 0;
19846 for (
unsigned PBitIdx = 0; PBitIdx != NumBitsInByte; ++PBitIdx) {
19847 Parity = Parity ^ ((Product >> PBitIdx) & 0x1);
19850 uint8_t Temp = Imm[BitIdx] ? 1 : 0;
19851 RetByte |= (Temp ^ Parity) << BitIdx;
19860 uint16_t TWord = 0;
19861 unsigned NumBitsInByte = 8;
19862 for (
unsigned BitIdx = 0; BitIdx != NumBitsInByte; ++BitIdx) {
19863 if ((BByte >> BitIdx) & 0x1) {
19864 TWord = TWord ^ (AByte << BitIdx);
19872 for (int32_t BitIdx = 14; BitIdx > 7; --BitIdx) {
19873 if ((TWord >> BitIdx) & 0x1) {
19874 TWord = TWord ^ (0x11B << (BitIdx - 8));
19877 return (TWord & 0xFF);
19881 APFloat &ResR, APFloat &ResI) {
19887 APFloat AC = A *
C;
19888 APFloat BD = B * D;
19889 APFloat AD = A * D;
19890 APFloat BC = B *
C;
19893 if (ResR.isNaN() && ResI.isNaN()) {
19894 bool Recalc =
false;
19895 if (A.isInfinity() || B.isInfinity()) {
19896 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
19898 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
19901 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
19903 D = APFloat::copySign(APFloat(D.getSemantics()), D);
19906 if (
C.isInfinity() || D.isInfinity()) {
19907 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
19909 D = APFloat::copySign(APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0),
19912 A = APFloat::copySign(APFloat(A.getSemantics()), A);
19914 B = APFloat::copySign(APFloat(B.getSemantics()), B);
19917 if (!Recalc && (AC.isInfinity() || BD.isInfinity() || AD.isInfinity() ||
19918 BC.isInfinity())) {
19920 A = APFloat::copySign(APFloat(A.getSemantics()), A);
19922 B = APFloat::copySign(APFloat(B.getSemantics()), B);
19924 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
19926 D = APFloat::copySign(APFloat(D.getSemantics()), D);
19930 ResR = APFloat::getInf(A.getSemantics()) * (A *
C - B * D);
19931 ResI = APFloat::getInf(A.getSemantics()) * (A * D + B *
C);
19937 APFloat &ResR, APFloat &ResI) {
19944 APFloat MaxCD = maxnum(
abs(
C),
abs(D));
19945 if (MaxCD.isFinite()) {
19946 DenomLogB =
ilogb(MaxCD);
19947 C =
scalbn(
C, -DenomLogB, APFloat::rmNearestTiesToEven);
19948 D =
scalbn(D, -DenomLogB, APFloat::rmNearestTiesToEven);
19950 APFloat Denom =
C *
C + D * D;
19952 scalbn((A *
C + B * D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
19954 scalbn((B *
C - A * D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
19955 if (ResR.isNaN() && ResI.isNaN()) {
19956 if (Denom.isPosZero() && (!A.isNaN() || !B.isNaN())) {
19957 ResR = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * A;
19958 ResI = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * B;
19959 }
else if ((A.isInfinity() || B.isInfinity()) &&
C.isFinite() &&
19961 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
19963 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
19965 ResR = APFloat::getInf(ResR.getSemantics()) * (A *
C + B * D);
19966 ResI = APFloat::getInf(ResI.getSemantics()) * (B *
C - A * D);
19967 }
else if (MaxCD.isInfinity() && A.isFinite() && B.isFinite()) {
19968 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
19970 D = APFloat::copySign(APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0),
19972 ResR = APFloat::getZero(ResR.getSemantics()) * (A *
C + B * D);
19973 ResI = APFloat::getZero(ResI.getSemantics()) * (B *
C - A * D);
19980 APSInt NormAmt = Amount;
19981 unsigned BitWidth =
Value.getBitWidth();
19982 unsigned AmtBitWidth = NormAmt.getBitWidth();
19983 if (BitWidth == 1) {
19985 NormAmt =
APSInt(APInt(AmtBitWidth, 0), NormAmt.isUnsigned());
19986 }
else if (BitWidth == 2) {
19991 APSInt(APInt(AmtBitWidth, NormAmt[0] ? 1 : 0), NormAmt.isUnsigned());
19994 if (AmtBitWidth > BitWidth) {
19995 Divisor = llvm::APInt(AmtBitWidth, BitWidth);
19997 Divisor = llvm::APInt(BitWidth, BitWidth);
19998 if (AmtBitWidth < BitWidth) {
19999 NormAmt = NormAmt.extend(BitWidth);
20004 if (NormAmt.isSigned()) {
20005 NormAmt =
APSInt(NormAmt.srem(Divisor),
false);
20006 if (NormAmt.isNegative()) {
20007 APSInt SignedDivisor(Divisor,
false);
20008 NormAmt += SignedDivisor;
20011 NormAmt =
APSInt(NormAmt.urem(Divisor),
true);
20018bool ComplexExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
20020 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
20024 bool LHSReal =
false, RHSReal =
false;
20032 Result.makeComplexFloat();
20036 LHSOK = Visit(E->
getLHS());
20038 if (!LHSOK && !Info.noteFailure())
20044 APFloat &Real = RHS.FloatReal;
20047 RHS.makeComplexFloat();
20048 RHS.FloatImag =
APFloat(Real.getSemantics());
20052 assert(!(LHSReal && RHSReal) &&
20053 "Cannot have both operands of a complex operation be real.");
20055 default:
return Error(E);
20057 if (
Result.isComplexFloat()) {
20058 Result.getComplexFloatReal().add(RHS.getComplexFloatReal(),
20059 APFloat::rmNearestTiesToEven);
20061 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
20063 Result.getComplexFloatImag().add(RHS.getComplexFloatImag(),
20064 APFloat::rmNearestTiesToEven);
20066 Result.getComplexIntReal() += RHS.getComplexIntReal();
20067 Result.getComplexIntImag() += RHS.getComplexIntImag();
20071 if (
Result.isComplexFloat()) {
20072 Result.getComplexFloatReal().subtract(RHS.getComplexFloatReal(),
20073 APFloat::rmNearestTiesToEven);
20075 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
20076 Result.getComplexFloatImag().changeSign();
20077 }
else if (!RHSReal) {
20078 Result.getComplexFloatImag().subtract(RHS.getComplexFloatImag(),
20079 APFloat::rmNearestTiesToEven);
20082 Result.getComplexIntReal() -= RHS.getComplexIntReal();
20083 Result.getComplexIntImag() -= RHS.getComplexIntImag();
20087 if (
Result.isComplexFloat()) {
20092 ComplexValue LHS =
Result;
20093 APFloat &A = LHS.getComplexFloatReal();
20094 APFloat &B = LHS.getComplexFloatImag();
20095 APFloat &
C = RHS.getComplexFloatReal();
20096 APFloat &D = RHS.getComplexFloatImag();
20100 assert(!RHSReal &&
"Cannot have two real operands for a complex op!");
20108 }
else if (RHSReal) {
20120 ComplexValue LHS =
Result;
20121 Result.getComplexIntReal() =
20122 (LHS.getComplexIntReal() * RHS.getComplexIntReal() -
20123 LHS.getComplexIntImag() * RHS.getComplexIntImag());
20124 Result.getComplexIntImag() =
20125 (LHS.getComplexIntReal() * RHS.getComplexIntImag() +
20126 LHS.getComplexIntImag() * RHS.getComplexIntReal());
20130 if (
Result.isComplexFloat()) {
20135 ComplexValue LHS =
Result;
20136 APFloat &A = LHS.getComplexFloatReal();
20137 APFloat &B = LHS.getComplexFloatImag();
20138 APFloat &
C = RHS.getComplexFloatReal();
20139 APFloat &D = RHS.getComplexFloatImag();
20153 B = APFloat::getZero(A.getSemantics());
20158 ComplexValue LHS =
Result;
20159 APSInt Den = RHS.getComplexIntReal() * RHS.getComplexIntReal() +
20160 RHS.getComplexIntImag() * RHS.getComplexIntImag();
20162 return Error(E, diag::note_expr_divide_by_zero);
20164 Result.getComplexIntReal() =
20165 (LHS.getComplexIntReal() * RHS.getComplexIntReal() +
20166 LHS.getComplexIntImag() * RHS.getComplexIntImag()) / Den;
20167 Result.getComplexIntImag() =
20168 (LHS.getComplexIntImag() * RHS.getComplexIntReal() -
20169 LHS.getComplexIntReal() * RHS.getComplexIntImag()) / Den;
20177bool ComplexExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
20191 if (
Result.isComplexFloat()) {
20192 Result.getComplexFloatReal().changeSign();
20193 Result.getComplexFloatImag().changeSign();
20196 Result.getComplexIntReal() = -
Result.getComplexIntReal();
20197 Result.getComplexIntImag() = -
Result.getComplexIntImag();
20201 if (
Result.isComplexFloat())
20202 Result.getComplexFloatImag().changeSign();
20204 Result.getComplexIntImag() = -
Result.getComplexIntImag();
20209bool ComplexExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
20212 Result.makeComplexFloat();
20218 Result.makeComplexInt();
20226 return ExprEvaluatorBaseTy::VisitInitListExpr(E);
20229bool ComplexExprEvaluator::VisitCallExpr(
const CallExpr *E) {
20230 if (!IsConstantEvaluatedBuiltinCall(E))
20231 return ExprEvaluatorBaseTy::VisitCallExpr(E);
20234 case Builtin::BI__builtin_complex:
20235 Result.makeComplexFloat();
20253class AtomicExprEvaluator :
20254 public ExprEvaluatorBase<AtomicExprEvaluator> {
20255 const LValue *
This;
20258 AtomicExprEvaluator(EvalInfo &Info,
const LValue *This,
APValue &
Result)
20266 bool ZeroInitialization(
const Expr *E) {
20267 ImplicitValueInitExpr VIE(
20275 bool VisitCastExpr(
const CastExpr *E) {
20278 return ExprEvaluatorBaseTy::VisitCastExpr(E);
20279 case CK_NullToPointer:
20281 return ZeroInitialization(E);
20282 case CK_NonAtomicToAtomic:
20294 return AtomicExprEvaluator(Info,
This, Result).Visit(E);
20303class VoidExprEvaluator
20304 :
public ExprEvaluatorBase<VoidExprEvaluator> {
20306 VoidExprEvaluator(EvalInfo &Info) : ExprEvaluatorBaseTy(Info) {}
20310 bool ZeroInitialization(
const Expr *E) {
return true; }
20312 bool VisitCastExpr(
const CastExpr *E) {
20315 return ExprEvaluatorBaseTy::VisitCastExpr(E);
20322 bool VisitCallExpr(
const CallExpr *E) {
20323 if (!IsConstantEvaluatedBuiltinCall(E))
20324 return ExprEvaluatorBaseTy::VisitCallExpr(E);
20327 case Builtin::BI__assume:
20328 case Builtin::BI__builtin_assume:
20332 case Builtin::BI__builtin_operator_delete:
20340 bool VisitCXXDeleteExpr(
const CXXDeleteExpr *E);
20344bool VoidExprEvaluator::VisitCXXDeleteExpr(
const CXXDeleteExpr *E) {
20346 if (Info.SpeculativeEvaluationDepth)
20350 if (!OperatorDelete
20351 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
20352 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
20362 if (
Pointer.Designator.Invalid)
20366 if (
Pointer.isNullPointer()) {
20370 if (!Info.getLangOpts().CPlusPlus20)
20371 Info.CCEDiag(E, diag::note_constexpr_new);
20379 QualType AllocType =
Pointer.Base.getDynamicAllocType();
20385 Info.FFDiag(E, diag::note_constexpr_delete_base_nonvirt_dtor)
20394 if (VirtualDelete &&
20396 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
20397 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
20404 (*Alloc)->Value, AllocType))
20407 if (!Info.HeapAllocs.erase(
Pointer.Base.dyn_cast<DynamicAllocLValue>())) {
20412 Info.FFDiag(E, diag::note_constexpr_double_delete);
20422 return VoidExprEvaluator(Info).Visit(E);
20434 if (E->
isGLValue() ||
T->isFunctionType()) {
20438 LV.moveInto(Result);
20439 }
else if (
T->isVectorType()) {
20442 }
else if (
T->isIntegralOrEnumerationType()) {
20443 if (!IntExprEvaluator(Info, Result).Visit(E))
20445 }
else if (
T->hasPointerRepresentation()) {
20449 LV.moveInto(Result);
20450 }
else if (
T->isRealFloatingType()) {
20451 llvm::APFloat F(0.0);
20455 }
else if (
T->isAnyComplexType()) {
20459 C.moveInto(Result);
20460 }
else if (
T->isFixedPointType()) {
20461 if (!FixedPointExprEvaluator(Info, Result).Visit(E))
return false;
20462 }
else if (
T->isMemberPointerType()) {
20466 P.moveInto(Result);
20468 }
else if (
T->isArrayType()) {
20471 Info.CurrentCall->createTemporary(E,
T, ScopeKind::FullExpression, LV);
20475 }
else if (
T->isRecordType()) {
20478 Info.CurrentCall->createTemporary(E,
T, ScopeKind::FullExpression, LV);
20482 }
else if (
T->isVoidType()) {
20483 if (!Info.getLangOpts().CPlusPlus11)
20484 Info.CCEDiag(E, diag::note_constexpr_nonliteral)
20488 }
else if (
T->isAtomicType()) {
20489 QualType Unqual =
T.getAtomicUnqualifiedType();
20493 E, Unqual, ScopeKind::FullExpression, LV);
20501 }
else if (Info.getLangOpts().CPlusPlus11) {
20502 Info.FFDiag(E, diag::note_constexpr_nonliteral) << E->
getType();
20505 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
20516 const Expr *E,
bool AllowNonLiteralTypes) {
20532 if (
T->isArrayType())
20534 else if (
T->isRecordType())
20536 else if (
T->isAtomicType()) {
20537 QualType Unqual =
T.getAtomicUnqualifiedType();
20558 if (Info.EnableNewConstInterp) {
20562 ConstantExprKind::Normal);
20571 LV.setFrom(Info.Ctx, Result);
20578 ConstantExprKind::Normal) &&
20586 if (
const auto *L = dyn_cast<IntegerLiteral>(Exp)) {
20588 APValue(
APSInt(L->getValue(), L->getType()->isUnsignedIntegerType()));
20593 if (
const auto *L = dyn_cast<CXXBoolLiteralExpr>(Exp)) {
20599 if (
const auto *FL = dyn_cast<FloatingLiteral>(Exp)) {
20600 Result =
APValue(FL->getValue());
20605 if (
const auto *L = dyn_cast<CharacterLiteral>(Exp)) {
20611 if (
const auto *CE = dyn_cast<ConstantExpr>(Exp)) {
20612 if (CE->hasAPValueResult()) {
20613 APValue APV = CE->getAPValueResult();
20615 Result = std::move(APV);
20691 bool InConstantContext)
const {
20693 "Expression evaluator can't be called on a dependent expression.");
20694 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsRValue");
20696 Info.InConstantContext = InConstantContext;
20697 return ::EvaluateAsRValue(
this,
Result, Ctx, Info);
20701 bool InConstantContext)
const {
20703 "Expression evaluator can't be called on a dependent expression.");
20704 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsBooleanCondition");
20712 bool InConstantContext)
const {
20714 "Expression evaluator can't be called on a dependent expression.");
20715 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsInt");
20717 Info.InConstantContext = InConstantContext;
20718 return ::EvaluateAsInt(
this,
Result, Ctx, AllowSideEffects, Info);
20723 bool InConstantContext)
const {
20725 "Expression evaluator can't be called on a dependent expression.");
20726 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFixedPoint");
20728 Info.InConstantContext = InConstantContext;
20729 return ::EvaluateAsFixedPoint(
this,
Result, Ctx, AllowSideEffects, Info);
20734 bool InConstantContext)
const {
20736 "Expression evaluator can't be called on a dependent expression.");
20738 if (!
getType()->isRealFloatingType())
20741 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFloat");
20753 bool InConstantContext)
const {
20755 "Expression evaluator can't be called on a dependent expression.");
20757 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsLValue");
20759 Info.InConstantContext = InConstantContext;
20763 if (Info.EnableNewConstInterp) {
20765 ConstantExprKind::Normal))
20768 LV.setFrom(Ctx,
Result.Val);
20771 ConstantExprKind::Normal, CheckedTemps);
20774 if (!
EvaluateLValue(
this, LV, Info) || !Info.discardCleanups() ||
20775 Result.HasSideEffects ||
20778 ConstantExprKind::Normal, CheckedTemps))
20781 LV.moveInto(
Result.Val);
20788 bool IsConstantDestruction) {
20789 EvalInfo Info(Ctx, EStatus,
20792 Info.setEvaluatingDecl(
Base, DestroyedValue,
20793 EvalInfo::EvaluatingDeclKind::Dtor);
20794 Info.InConstantContext = IsConstantDestruction;
20803 if (!Info.discardCleanups())
20804 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
20812 "Expression evaluator can't be called on a dependent expression.");
20818 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsConstantExpr");
20820 EvalInfo Info(Ctx,
Result, EM);
20821 Info.InConstantContext =
true;
20823 if (Info.EnableNewConstInterp) {
20827 getStorageType(Ctx,
this),
Result.Val, Kind);
20832 if (Kind == ConstantExprKind::ClassTemplateArgument)
20848 FullExpressionRAII
Scope(Info);
20853 if (!Info.discardCleanups())
20854 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
20864 if (Kind == ConstantExprKind::ClassTemplateArgument &&
20867 Result.HasSideEffects)) {
20879 bool IsConstantInitialization)
const {
20881 "Expression evaluator can't be called on a dependent expression.");
20882 assert(VD &&
"Need a valid VarDecl");
20884 llvm::TimeTraceScope TimeScope(
"EvaluateAsInitializer", [&] {
20886 llvm::raw_string_ostream OS(Name);
20892 EStatus.
Diag = &Notes;
20894 EvalInfo Info(Ctx, EStatus,
20895 (IsConstantInitialization &&
20899 Info.setEvaluatingDecl(VD,
Value);
20900 Info.InConstantContext = IsConstantInitialization;
20905 if (Info.EnableNewConstInterp) {
20906 auto &InterpCtx =
const_cast<ASTContext &
>(Ctx).getInterpContext();
20907 if (!InterpCtx.evaluateAsInitializer(Info, VD,
this,
Value))
20911 ConstantExprKind::Normal);
20926 FullExpressionRAII
Scope(Info);
20929 EStatus.HasSideEffects)
20935 Info.performLifetimeExtension();
20937 if (!Info.discardCleanups())
20938 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
20942 ConstantExprKind::Normal) &&
20949 EStatus.
Diag = &Notes;
20966 IsConstantDestruction) ||
20978 "Expression evaluator can't be called on a dependent expression.");
20987 "Expression evaluator can't be called on a dependent expression.");
20989 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstInt");
20992 Info.InConstantContext =
true;
20996 assert(
Result &&
"Could not evaluate expression");
20997 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
20999 return EVResult.Val.getInt();
21005 "Expression evaluator can't be called on a dependent expression.");
21007 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstIntCheckOverflow");
21009 EVResult.Diag =
Diag;
21011 Info.InConstantContext =
true;
21012 Info.CheckingForUndefinedBehavior =
true;
21016 assert(
Result &&
"Could not evaluate expression");
21017 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
21019 return EVResult.Val.getInt();
21024 "Expression evaluator can't be called on a dependent expression.");
21026 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateForOverflow");
21031 Info.CheckingForUndefinedBehavior =
true;
21037 assert(
Val.isLValue());
21063 IK_ICEIfUnevaluated,
21079static ICEDiag
Worst(ICEDiag A, ICEDiag B) {
return A.Kind >= B.Kind ? A : B; }
21086 Info.InConstantContext =
true;
21095 assert(!E->
isValueDependent() &&
"Should not see value dependent exprs!");
21100#define ABSTRACT_STMT(Node)
21101#define STMT(Node, Base) case Expr::Node##Class:
21102#define EXPR(Node, Base)
21103#include "clang/AST/StmtNodes.inc"
21104 case Expr::PredefinedExprClass:
21105 case Expr::FloatingLiteralClass:
21106 case Expr::ImaginaryLiteralClass:
21107 case Expr::StringLiteralClass:
21108 case Expr::ArraySubscriptExprClass:
21109 case Expr::MatrixSingleSubscriptExprClass:
21110 case Expr::MatrixSubscriptExprClass:
21111 case Expr::ArraySectionExprClass:
21112 case Expr::OMPArrayShapingExprClass:
21113 case Expr::OMPIteratorExprClass:
21114 case Expr::MemberExprClass:
21115 case Expr::CompoundAssignOperatorClass:
21116 case Expr::CompoundLiteralExprClass:
21117 case Expr::ExtVectorElementExprClass:
21118 case Expr::DesignatedInitExprClass:
21119 case Expr::ArrayInitLoopExprClass:
21120 case Expr::ArrayInitIndexExprClass:
21121 case Expr::NoInitExprClass:
21122 case Expr::DesignatedInitUpdateExprClass:
21123 case Expr::ImplicitValueInitExprClass:
21124 case Expr::ParenListExprClass:
21125 case Expr::VAArgExprClass:
21126 case Expr::AddrLabelExprClass:
21127 case Expr::StmtExprClass:
21128 case Expr::CXXMemberCallExprClass:
21129 case Expr::CUDAKernelCallExprClass:
21130 case Expr::CXXAddrspaceCastExprClass:
21131 case Expr::CXXDynamicCastExprClass:
21132 case Expr::CXXTypeidExprClass:
21133 case Expr::CXXUuidofExprClass:
21134 case Expr::MSPropertyRefExprClass:
21135 case Expr::MSPropertySubscriptExprClass:
21136 case Expr::CXXNullPtrLiteralExprClass:
21137 case Expr::UserDefinedLiteralClass:
21138 case Expr::CXXThisExprClass:
21139 case Expr::CXXThrowExprClass:
21140 case Expr::CXXNewExprClass:
21141 case Expr::CXXDeleteExprClass:
21142 case Expr::CXXPseudoDestructorExprClass:
21143 case Expr::UnresolvedLookupExprClass:
21144 case Expr::RecoveryExprClass:
21145 case Expr::DependentScopeDeclRefExprClass:
21146 case Expr::CXXConstructExprClass:
21147 case Expr::CXXInheritedCtorInitExprClass:
21148 case Expr::CXXStdInitializerListExprClass:
21149 case Expr::CXXBindTemporaryExprClass:
21150 case Expr::ExprWithCleanupsClass:
21151 case Expr::CXXTemporaryObjectExprClass:
21152 case Expr::CXXUnresolvedConstructExprClass:
21153 case Expr::CXXDependentScopeMemberExprClass:
21154 case Expr::UnresolvedMemberExprClass:
21155 case Expr::ObjCStringLiteralClass:
21156 case Expr::ObjCBoxedExprClass:
21157 case Expr::ObjCArrayLiteralClass:
21158 case Expr::ObjCDictionaryLiteralClass:
21159 case Expr::ObjCEncodeExprClass:
21160 case Expr::ObjCMessageExprClass:
21161 case Expr::ObjCSelectorExprClass:
21162 case Expr::ObjCProtocolExprClass:
21163 case Expr::ObjCIvarRefExprClass:
21164 case Expr::ObjCPropertyRefExprClass:
21165 case Expr::ObjCSubscriptRefExprClass:
21166 case Expr::ObjCIsaExprClass:
21167 case Expr::ObjCAvailabilityCheckExprClass:
21168 case Expr::ShuffleVectorExprClass:
21169 case Expr::ConvertVectorExprClass:
21170 case Expr::BlockExprClass:
21172 case Expr::OpaqueValueExprClass:
21173 case Expr::PackExpansionExprClass:
21174 case Expr::SubstNonTypeTemplateParmPackExprClass:
21175 case Expr::FunctionParmPackExprClass:
21176 case Expr::AsTypeExprClass:
21177 case Expr::ObjCIndirectCopyRestoreExprClass:
21178 case Expr::MaterializeTemporaryExprClass:
21179 case Expr::PseudoObjectExprClass:
21180 case Expr::AtomicExprClass:
21181 case Expr::LambdaExprClass:
21182 case Expr::CXXFoldExprClass:
21183 case Expr::CoawaitExprClass:
21184 case Expr::DependentCoawaitExprClass:
21185 case Expr::CoyieldExprClass:
21186 case Expr::SYCLUniqueStableNameExprClass:
21187 case Expr::CXXParenListInitExprClass:
21188 case Expr::HLSLOutArgExprClass:
21191 case Expr::InitListExprClass: {
21202 case Expr::SizeOfPackExprClass:
21203 case Expr::GNUNullExprClass:
21204 case Expr::SourceLocExprClass:
21205 case Expr::EmbedExprClass:
21206 case Expr::OpenACCAsteriskSizeExprClass:
21209 case Expr::PackIndexingExprClass:
21212 case Expr::SubstNonTypeTemplateParmExprClass:
21216 case Expr::ConstantExprClass:
21219 case Expr::ParenExprClass:
21221 case Expr::GenericSelectionExprClass:
21223 case Expr::IntegerLiteralClass:
21224 case Expr::FixedPointLiteralClass:
21225 case Expr::CharacterLiteralClass:
21226 case Expr::ObjCBoolLiteralExprClass:
21227 case Expr::CXXBoolLiteralExprClass:
21228 case Expr::CXXScalarValueInitExprClass:
21229 case Expr::TypeTraitExprClass:
21230 case Expr::ConceptSpecializationExprClass:
21231 case Expr::RequiresExprClass:
21232 case Expr::ArrayTypeTraitExprClass:
21233 case Expr::ExpressionTraitExprClass:
21234 case Expr::CXXNoexceptExprClass:
21236 case Expr::CallExprClass:
21237 case Expr::CXXOperatorCallExprClass: {
21246 case Expr::CXXRewrittenBinaryOperatorClass:
21249 case Expr::DeclRefExprClass: {
21263 const VarDecl *VD = dyn_cast<VarDecl>(D);
21270 case Expr::UnaryOperatorClass: {
21293 llvm_unreachable(
"invalid unary operator class");
21295 case Expr::OffsetOfExprClass: {
21304 case Expr::UnaryExprOrTypeTraitExprClass: {
21306 if ((Exp->
getKind() == UETT_SizeOf) &&
21309 if (Exp->
getKind() == UETT_CountOf) {
21316 if (VAT->getElementType()->isArrayType())
21328 case Expr::BinaryOperatorClass: {
21373 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE) {
21376 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
21377 if (REval.isSigned() && REval.isAllOnes()) {
21379 if (LEval.isMinSignedValue())
21380 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
21388 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE)
21389 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
21395 return Worst(LHSResult, RHSResult);
21401 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICEIfUnevaluated) {
21411 return Worst(LHSResult, RHSResult);
21414 llvm_unreachable(
"invalid binary operator kind");
21416 case Expr::ImplicitCastExprClass:
21417 case Expr::CStyleCastExprClass:
21418 case Expr::CXXFunctionalCastExprClass:
21419 case Expr::CXXStaticCastExprClass:
21420 case Expr::CXXReinterpretCastExprClass:
21421 case Expr::CXXConstCastExprClass:
21422 case Expr::ObjCBridgedCastExprClass: {
21429 APSInt IgnoredVal(DestWidth, !DestSigned);
21434 if (FL->getValue().convertToInteger(IgnoredVal,
21435 llvm::APFloat::rmTowardZero,
21436 &Ignored) & APFloat::opInvalidOp)
21442 case CK_LValueToRValue:
21443 case CK_AtomicToNonAtomic:
21444 case CK_NonAtomicToAtomic:
21446 case CK_IntegralToBoolean:
21447 case CK_IntegralCast:
21453 case Expr::BinaryConditionalOperatorClass: {
21456 if (CommonResult.Kind == IK_NotICE)
return CommonResult;
21458 if (FalseResult.Kind == IK_NotICE)
return FalseResult;
21459 if (CommonResult.Kind == IK_ICEIfUnevaluated)
return CommonResult;
21460 if (FalseResult.Kind == IK_ICEIfUnevaluated &&
21462 return FalseResult;
21464 case Expr::ConditionalOperatorClass: {
21472 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
21475 if (CondResult.Kind == IK_NotICE)
21481 if (TrueResult.Kind == IK_NotICE)
21483 if (FalseResult.Kind == IK_NotICE)
21484 return FalseResult;
21485 if (CondResult.Kind == IK_ICEIfUnevaluated)
21487 if (TrueResult.Kind == IK_ICE && FalseResult.Kind == IK_ICE)
21493 return FalseResult;
21496 case Expr::CXXDefaultArgExprClass:
21498 case Expr::CXXDefaultInitExprClass:
21500 case Expr::ChooseExprClass: {
21503 case Expr::BuiltinBitCastExprClass: {
21504 if (!checkBitCastConstexprEligibility(
nullptr, Ctx,
cast<CastExpr>(E)))
21510 llvm_unreachable(
"Invalid StmtClass!");
21516 llvm::APSInt *
Value) {
21524 if (!Result.isInt())
21533 "Expression evaluator can't be called on a dependent expression.");
21535 ExprTimeTraceScope TimeScope(
this, Ctx,
"isIntegerConstantExpr");
21541 if (D.Kind != IK_ICE)
21546std::optional<llvm::APSInt>
21550 return std::nullopt;
21557 return std::nullopt;
21561 return std::nullopt;
21570 Info.InConstantContext =
true;
21573 llvm_unreachable(
"ICE cannot be evaluated!");
21580 "Expression evaluator can't be called on a dependent expression.");
21582 return CheckICE(
this, Ctx).Kind == IK_ICE;
21587 "Expression evaluator can't be called on a dependent expression.");
21604 Status.Diag = &Diags;
21611 Info.discardCleanups() && !Status.HasSideEffects;
21613 return IsConstExpr && Diags.empty();
21621 "Expression evaluator can't be called on a dependent expression.");
21623 llvm::TimeTraceScope TimeScope(
"EvaluateWithSubstitution", [&] {
21625 llvm::raw_string_ostream OS(Name);
21633 Info.InConstantContext =
true;
21636 const LValue *ThisPtr =
nullptr;
21639 auto *MD = dyn_cast<CXXMethodDecl>(Callee);
21640 assert(MD &&
"Don't provide `this` for non-methods.");
21641 assert(MD->isImplicitObjectMemberFunction() &&
21642 "Don't provide `this` for methods without an implicit object.");
21644 if (!
This->isValueDependent() &&
21647 ThisPtr = &ThisVal;
21654 CallRef
Call = Info.CurrentCall->createCall(Callee);
21657 unsigned Idx = I - Args.begin();
21658 if (Idx >= Callee->getNumParams())
21660 const ParmVarDecl *PVD = Callee->getParamDecl(Idx);
21661 if ((*I)->isValueDependent() ||
21665 if (
APValue *Slot = Info.getParamSlot(
Call, PVD))
21676 Info.discardCleanups();
21680 CallStackFrame Frame(Info, Callee->getLocation(), Callee, ThisPtr,
This,
21683 FullExpressionRAII
Scope(Info);
21697 llvm::TimeTraceScope TimeScope(
"isPotentialConstantExpr", [&] {
21699 llvm::raw_string_ostream OS(Name);
21706 Status.
Diag = &Diags;
21710 Info.InConstantContext =
true;
21711 Info.CheckingPotentialConstantExpression =
true;
21714 if (Info.EnableNewConstInterp) {
21716 return Diags.empty();
21727 This.set({&VIE, Info.CurrentCall->Index});
21735 Info.setEvaluatingDecl(
This.getLValueBase(), Scratch);
21741 &VIE, Args, CallRef(), FD->
getBody(), Info, Scratch,
21745 return Diags.empty();
21753 "Expression evaluator can't be called on a dependent expression.");
21756 Status.
Diag = &Diags;
21760 Info.InConstantContext =
true;
21761 Info.CheckingPotentialConstantExpression =
true;
21763 if (Info.EnableNewConstInterp) {
21765 return Diags.empty();
21770 nullptr, CallRef());
21774 return Diags.empty();
21778 unsigned Type)
const {
21779 if (!
getType()->isPointerType())
21788 EvalInfo &Info, std::string *StringResult) {
21800 if (
const StringLiteral *S = dyn_cast_or_null<StringLiteral>(
21801 String.getLValueBase().dyn_cast<
const Expr *>())) {
21804 if (Off >= 0 && (uint64_t)Off <= (uint64_t)Str.size() &&
21808 Str = Str.substr(Off);
21810 StringRef::size_type Pos = Str.find(0);
21811 if (Pos != StringRef::npos)
21812 Str = Str.substr(0, Pos);
21814 Result = Str.size();
21816 *StringResult = Str;
21824 for (uint64_t Strlen = 0; ; ++Strlen) {
21832 }
else if (StringResult)
21833 StringResult->push_back(Char.
getInt().getExtValue());
21843 std::string StringResult;
21845 if (Info.EnableNewConstInterp) {
21847 return std::nullopt;
21848 return StringResult;
21852 return StringResult;
21853 return std::nullopt;
21856template <
typename T>
21858 const Expr *SizeExpression,
21859 const Expr *PtrExpression,
21863 Info.InConstantContext =
true;
21865 if (Info.EnableNewConstInterp)
21867 PtrExpression, Result);
21870 FullExpressionRAII
Scope(Info);
21875 uint64_t Size = SizeValue.getZExtValue();
21878 if constexpr (std::is_same_v<APValue, T>)
21881 if (Size < Result.max_size())
21882 Result.reserve(Size);
21888 for (uint64_t I = 0; I < Size; ++I) {
21894 if constexpr (std::is_same_v<APValue, T>) {
21895 Result.getArrayInitializedElt(I) = std::move(Char);
21899 assert(
C.getBitWidth() <= 8 &&
21900 "string element not representable in char");
21902 Result.push_back(
static_cast<char>(
C.getExtValue()));
21913 const Expr *SizeExpression,
21917 PtrExpression, Ctx, Status);
21921 const Expr *SizeExpression,
21925 PtrExpression, Ctx, Status);
21932 if (Info.EnableNewConstInterp)
21939struct IsWithinLifetimeHandler {
21942 using result_type = std::optional<bool>;
21943 std::optional<bool> failed() {
return std::nullopt; }
21944 template <
typename T>
21945 std::optional<bool> found(
T &Subobj,
QualType SubobjType) {
21950std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &IEE,
21951 const CallExpr *E) {
21952 EvalInfo &Info = IEE.Info;
21957 if (!Info.InConstantContext)
21958 return std::nullopt;
21960 const Expr *Arg = E->
getArg(0);
21962 return std::nullopt;
21965 return std::nullopt;
21967 if (Val.allowConstexprUnknown())
21971 bool CalledFromStd =
false;
21972 const auto *
Callee = Info.CurrentCall->getCallee();
21973 if (Callee &&
Callee->isInStdNamespace()) {
21974 const IdentifierInfo *Identifier =
Callee->getIdentifier();
21975 CalledFromStd = Identifier && Identifier->
isStr(
"is_within_lifetime");
21977 Info.CCEDiag(CalledFromStd ? Info.CurrentCall->getCallRange().getBegin()
21979 diag::err_invalid_is_within_lifetime)
21980 << (CalledFromStd ?
"std::is_within_lifetime"
21981 :
"__builtin_is_within_lifetime")
21983 return std::nullopt;
21993 if (Val.isNullPointer() || Val.getLValueBase().isNull())
21995 QualType
T = Val.getLValueBase().getType();
21997 "Pointers to functions should have been typed as function pointers "
21998 "which would have been rejected earlier");
22001 if (Val.getLValueDesignator().isOnePastTheEnd())
22003 assert(Val.getLValueDesignator().isValidSubobject() &&
22004 "Unchecked case for valid subobject");
22008 CompleteObject CO =
22012 if (Info.EvaluatingDeclValue && CO.Value == Info.EvaluatingDeclValue)
22017 IsWithinLifetimeHandler handler{Info};
22018 return findSubobject(Info, E, CO, Val.getLValueDesignator(), handler);
Defines the clang::ASTContext interface.
This file provides some common utility functions for processing Lambda related AST Constructs.
Defines enum values for all the target-independent builtin functions.
static Address castToBase(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy, Address OriginalBaseAddress, llvm::Value *Addr)
static uint32_t getBitWidth(const Expr *E)
static Decl::Kind getKind(const Decl *D)
GCCTypeClass
Values returned by __builtin_classify_type, chosen to match the values produced by GCC's builtin.
@ PointerToMemberFunction
static bool isRead(AccessKinds AK)
static bool EvaluateCharRangeAsStringImpl(const Expr *, T &Result, const Expr *SizeExpression, const Expr *PtrExpression, ASTContext &Ctx, Expr::EvalResult &Status)
static bool EvaluateBuiltinStrLen(const Expr *E, uint64_t &Result, EvalInfo &Info, std::string *StringResult=nullptr)
static bool isValidIndeterminateAccess(AccessKinds AK)
Is this kind of access valid on an indeterminate object value?
static unsigned elementwiseSize(EvalInfo &Info, QualType BaseTy)
static bool EvaluateMemberPointer(const Expr *E, MemberPtr &Result, EvalInfo &Info)
static bool hasUnacceptableSideEffect(Expr::EvalStatus &Result, Expr::SideEffectsKind SEK)
static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E, AccessKinds AK, const LValue &LVal, QualType LValType)
Find the complete object to which an LValue refers.
static bool evaluateLValueAsAllocSize(EvalInfo &Info, APValue::LValueBase Base, LValue &Result)
Attempts to evaluate the given LValueBase as the result of a call to a function with the alloc_size a...
static const CXXMethodDecl * HandleVirtualDispatch(EvalInfo &Info, const Expr *E, LValue &This, const CXXMethodDecl *Found, llvm::SmallVectorImpl< QualType > &CovariantAdjustmentPath)
Perform virtual dispatch.
static bool EvaluateVarDecl(EvalInfo &Info, const VarDecl *VD)
static bool CheckEvaluationResult(CheckEvaluationResultKind CERK, EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value, ConstantExprKind Kind, const FieldDecl *SubobjectDecl, CheckedTemporaries &CheckedTemps)
static bool HandleLValueComplexElement(EvalInfo &Info, const Expr *E, LValue &LVal, QualType EltTy, bool Imag)
Update an lvalue to refer to a component of a complex number.
static bool evalPackBuiltin(const CallExpr *E, EvalInfo &Info, APValue &Result, llvm::function_ref< APInt(const APSInt &)> PackFn)
static bool HandleSizeof(EvalInfo &Info, SourceLocation Loc, QualType Type, CharUnits &Size, SizeOfType SOT=SizeOfType::SizeOf)
Get the size of the given type in char units.
static bool HandleConstructorCall(const Expr *E, const LValue &This, CallRef Call, const CXXConstructorDecl *Definition, EvalInfo &Info, APValue &Result)
Evaluate a constructor call.
static bool hlslElementwiseCastHelper(EvalInfo &Info, const Expr *E, QualType DestTy, SmallVectorImpl< APValue > &SrcVals, SmallVectorImpl< QualType > &SrcTypes)
static bool ShouldPropagateBreakContinue(EvalInfo &Info, const Stmt *LoopOrSwitch, ArrayRef< BlockScopeRAII * > Scopes, EvalStmtResult &ESR)
Helper to implement named break/continue.
static EvalStmtResult EvaluateLoopBody(StmtResult &Result, EvalInfo &Info, const Stmt *Body, const SwitchCase *Case=nullptr)
Evaluate the body of a loop, and translate the result as appropriate.
static bool EvaluatePointer(const Expr *E, LValue &Result, EvalInfo &Info, bool InvalidBaseOK=false)
static bool CheckTrivialDefaultConstructor(EvalInfo &Info, SourceLocation Loc, const CXXConstructorDecl *CD, bool IsValueInitialization)
CheckTrivialDefaultConstructor - Check whether a constructor is a trivial default constructor.
static bool EvaluateVector(const Expr *E, APValue &Result, EvalInfo &Info)
static const ValueDecl * GetLValueBaseDecl(const LValue &LVal)
static bool TryEvaluateBuiltinNaN(const ASTContext &Context, QualType ResultTy, const Expr *Arg, bool SNaN, llvm::APFloat &Result)
static const Expr * ignorePointerCastsAndParens(const Expr *E)
A more selective version of E->IgnoreParenCasts for tryEvaluateBuiltinObjectSize. This ignores some c...
static bool isAnyAccess(AccessKinds AK)
static bool EvaluateComparisonBinaryOperator(EvalInfo &Info, const BinaryOperator *E, SuccessCB &&Success, AfterCB &&DoAfter)
static bool HandleClassZeroInitialization(EvalInfo &Info, const Expr *E, const RecordDecl *RD, const LValue &This, APValue &Result)
Perform zero-initialization on an object of non-union class type. C++11 [dcl.init]p5: To zero-initial...
static bool EvaluateComplex(const Expr *E, ComplexValue &Res, EvalInfo &Info)
static bool CheckMemoryLeaks(EvalInfo &Info)
Enforce C++2a [expr.const]/4.17, which disallows new-expressions unless "the allocated storage is dea...
static bool handleScalarCast(EvalInfo &Info, const FPOptions FPO, const Expr *E, QualType SourceTy, QualType DestTy, APValue const &Original, APValue &Result)
static ICEDiag CheckEvalInICE(const Expr *E, const ASTContext &Ctx)
static llvm::APInt ConvertBoolVectorToInt(const APValue &Val)
static bool flattenAPValue(EvalInfo &Info, const Expr *E, APValue Value, QualType BaseTy, SmallVectorImpl< APValue > &Elements, SmallVectorImpl< QualType > &Types, unsigned Size)
static bool hlslAggSplatHelper(EvalInfo &Info, const Expr *E, APValue &SrcVal, QualType &SrcTy)
static bool isBaseClassPublic(const CXXRecordDecl *Derived, const CXXRecordDecl *Base)
Determine whether Base, which is known to be a direct base class of Derived, is a public base class.
static bool hasVirtualDestructor(QualType T)
static bool HandleOverflow(EvalInfo &Info, const Expr *E, const T &SrcValue, QualType DestType)
static CharUnits getBaseAlignment(EvalInfo &Info, const LValue &Value)
static bool HandleLValueIndirectMember(EvalInfo &Info, const Expr *E, LValue &LVal, const IndirectFieldDecl *IFD)
Update LVal to refer to the given indirect field.
static bool ConvertDoubleToFloatStrict(EvalInfo &Info, const Expr *E, APFloat OrigVal, APValue &Result)
static ICEDiag Worst(ICEDiag A, ICEDiag B)
static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E, const VarDecl *VD, CallStackFrame *Frame, unsigned Version, APValue *&Result)
Try to evaluate the initializer for a variable declaration.
static bool handleDefaultInitValue(QualType T, APValue &Result)
Get the value to use for a default-initialized object of type T.
static bool HandleLValueVectorElement(EvalInfo &Info, const Expr *E, LValue &LVal, QualType EltTy, uint64_t Size, uint64_t Idx)
static void NoteLValueLocation(EvalInfo &Info, APValue::LValueBase Base)
static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc, QualType Type, const LValue &LVal, ConstantExprKind Kind, CheckedTemporaries &CheckedTemps)
Check that this reference or pointer core constant expression is a valid value for an address or refe...
static bool CheckedIntArithmetic(EvalInfo &Info, const Expr *E, const APSInt &LHS, const APSInt &RHS, unsigned BitWidth, Operation Op, APSInt &Result)
Perform the given integer operation, which is known to need at most BitWidth bits,...
static bool EvaluateTemporary(const Expr *E, LValue &Result, EvalInfo &Info)
Evaluate an expression of record type as a temporary.
static bool EvaluateArray(const Expr *E, const LValue &This, APValue &Result, EvalInfo &Info)
static bool truncateBitfieldValue(EvalInfo &Info, const Expr *E, APValue &Value, const FieldDecl *FD)
static bool handleVectorShuffle(EvalInfo &Info, const ShuffleVectorExpr *E, QualType ElemType, APValue const &VecVal1, APValue const &VecVal2, unsigned EltNum, APValue &Result)
static bool handleVectorElementCast(EvalInfo &Info, const FPOptions FPO, const Expr *E, QualType SourceTy, QualType DestTy, APValue const &Original, APValue &Result)
static const ValueDecl * HandleMemberPointerAccess(EvalInfo &Info, QualType LVType, LValue &LV, const Expr *RHS, bool IncludeMember=true)
HandleMemberPointerAccess - Evaluate a member access operation and build an lvalue referring to the r...
static bool HandleBaseToDerivedCast(EvalInfo &Info, const CastExpr *E, LValue &Result)
HandleBaseToDerivedCast - Apply the given base-to-derived cast operation on the provided lvalue,...
static bool EvaluateFloat(const Expr *E, APFloat &Result, EvalInfo &Info)
static bool IsOpaqueConstantCall(const CallExpr *E)
Should this call expression be treated as forming an opaque constant?
static bool CheckMemberPointerConstantExpression(EvalInfo &Info, SourceLocation Loc, QualType Type, const APValue &Value, ConstantExprKind Kind)
Member pointers are constant expressions unless they point to a non-virtual dllimport member function...
static bool EvaluateAsInt(const Expr *E, Expr::EvalResult &ExprResult, const ASTContext &Ctx, Expr::SideEffectsKind AllowSideEffects, EvalInfo &Info)
static bool handleLValueToRValueConversion(EvalInfo &Info, const Expr *Conv, QualType Type, const LValue &LVal, APValue &RVal, bool WantObjectRepresentation=false)
Perform an lvalue-to-rvalue conversion on the given glvalue.
static bool handleElementwiseCast(EvalInfo &Info, const Expr *E, const FPOptions FPO, SmallVectorImpl< APValue > &Elements, SmallVectorImpl< QualType > &SrcTypes, SmallVectorImpl< QualType > &DestTypes, SmallVectorImpl< APValue > &Results)
static bool refersToCompleteObject(const LValue &LVal)
Tests to see if the LValue has a user-specified designator (that isn't necessarily valid)....
static bool AreElementsOfSameArray(QualType ObjType, const SubobjectDesignator &A, const SubobjectDesignator &B)
Determine whether the given subobject designators refer to elements of the same array object.
static bool EvaluateDecompositionDeclInit(EvalInfo &Info, const DecompositionDecl *DD)
static bool IsWeakLValue(const LValue &Value)
static bool EvaluateArrayNewConstructExpr(EvalInfo &Info, LValue &This, APValue &Result, const CXXConstructExpr *CCE, QualType AllocType)
static bool EvaluateRecord(const Expr *E, const LValue &This, APValue &Result, EvalInfo &Info)
static bool handleAssignment(EvalInfo &Info, const Expr *E, const LValue &LVal, QualType LValType, APValue &Val)
Perform an assignment of Val to LVal. Takes ownership of Val.
static bool CastToDerivedClass(EvalInfo &Info, const Expr *E, LValue &Result, const RecordDecl *TruncatedType, unsigned TruncatedElements)
Cast an lvalue referring to a base subobject to a derived class, by truncating the lvalue's path to t...
static bool EvaluateIgnoredValue(EvalInfo &Info, const Expr *E)
Evaluate an expression to see if it had side-effects, and discard its result.
static bool constructAggregate(EvalInfo &Info, const FPOptions FPO, const Expr *E, APValue &Result, QualType ResultType, SmallVectorImpl< APValue > &Elements, SmallVectorImpl< QualType > &ElTypes)
static void addFlexibleArrayMemberInitSize(EvalInfo &Info, const QualType &T, const LValue &LV, CharUnits &Size)
If we're evaluating the object size of an instance of a struct that contains a flexible array member,...
static bool HandleLValueBasePath(EvalInfo &Info, const CastExpr *E, QualType Type, LValue &Result)
static bool evalShuffleGeneric(EvalInfo &Info, const CallExpr *Call, APValue &Out, llvm::function_ref< std::pair< unsigned, int >(unsigned, unsigned)> GetSourceIndex)
static QualType getSubobjectType(QualType ObjType, QualType SubobjType, bool IsMutable=false)
static bool EvaluateFixedPointOrInteger(const Expr *E, APFixedPoint &Result, EvalInfo &Info)
Evaluate an integer or fixed point expression into an APResult.
static bool HandleIntToFloatCast(EvalInfo &Info, const Expr *E, const FPOptions FPO, QualType SrcType, const APSInt &Value, QualType DestType, APFloat &Result)
static const CXXRecordDecl * getBaseClassType(SubobjectDesignator &Designator, unsigned PathLength)
static bool CastToBaseClass(EvalInfo &Info, const Expr *E, LValue &Result, const CXXRecordDecl *DerivedRD, const CXXRecordDecl *BaseRD)
Cast an lvalue referring to a derived class to a known base subobject.
static bool HandleLValueBase(EvalInfo &Info, const Expr *E, LValue &Obj, const CXXRecordDecl *DerivedDecl, const CXXBaseSpecifier *Base)
static bool HandleConversionToBool(const APValue &Val, bool &Result)
CharUnits GetAlignOfExpr(const ASTContext &Ctx, const Expr *E, UnaryExprOrTypeTrait ExprKind)
static bool isModification(AccessKinds AK)
static bool handleCompareOpForVector(const APValue &LHSValue, BinaryOperatorKind Opcode, const APValue &RHSValue, APInt &Result)
static bool MaybeElementDependentArrayFiller(const Expr *FillerExpr)
static bool EvaluateObjectArgument(EvalInfo &Info, const Expr *Object, LValue &This)
Build an lvalue for the object argument of a member function call.
static bool CheckLiteralType(EvalInfo &Info, const Expr *E, const LValue *This=nullptr)
Check that this core constant expression is of literal type, and if not, produce an appropriate diagn...
static bool EvaluateInteger(const Expr *E, APSInt &Result, EvalInfo &Info)
CheckEvaluationResultKind
static bool isZeroSized(const LValue &Value)
static APSInt extractStringLiteralCharacter(EvalInfo &Info, const Expr *Lit, uint64_t Index)
Extract the value of a character from a string literal.
static bool modifySubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, const SubobjectDesignator &Sub, APValue &NewVal)
Update the designated sub-object of an rvalue to the given value.
static bool EvaluateCPlusPlus11IntegralConstantExpr(const ASTContext &Ctx, const Expr *E, llvm::APSInt *Value)
Evaluate an expression as a C++11 integral constant expression.
static CharUnits GetAlignOfType(const ASTContext &Ctx, QualType T, UnaryExprOrTypeTrait ExprKind)
static bool getBuiltinAlignArguments(const CallExpr *E, EvalInfo &Info, APValue &Val, APSInt &Alignment)
static bool HandleLValueArrayAdjustment(EvalInfo &Info, const Expr *E, LValue &LVal, QualType EltTy, APSInt Adjustment)
Update a pointer value to model pointer arithmetic.
static bool extractSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, const SubobjectDesignator &Sub, APValue &Result, AccessKinds AK=AK_Read)
Extract the designated sub-object of an rvalue.
static bool HandleLValueMember(EvalInfo &Info, const Expr *E, LValue &LVal, const FieldDecl *FD, const ASTRecordLayout *RL=nullptr)
Update LVal to refer to the given field, which must be a member of the type currently described by LV...
static void addOrSubLValueAsInteger(APValue &LVal, const APSInt &Index, bool IsSub)
static bool IsDeclSourceLocationCurrent(const FunctionDecl *FD)
void HandleComplexComplexDiv(APFloat A, APFloat B, APFloat C, APFloat D, APFloat &ResR, APFloat &ResI)
static bool handleTrivialCopy(EvalInfo &Info, const ParmVarDecl *Param, const Expr *E, APValue &Result, bool CopyObjectRepresentation)
Perform a trivial copy from Param, which is the parameter of a copy or move constructor or assignment...
static bool checkFloatingPointResult(EvalInfo &Info, const Expr *E, APFloat::opStatus St)
Check if the given evaluation result is allowed for constant evaluation.
static bool EvaluateBuiltinConstantPForLValue(const APValue &LV)
EvaluateBuiltinConstantPForLValue - Determine the result of __builtin_constant_p when applied to the ...
static bool EvaluateBuiltinConstantP(EvalInfo &Info, const Expr *Arg)
EvaluateBuiltinConstantP - Evaluate __builtin_constant_p as similarly to GCC as we can manage.
static bool checkNonVirtualMemberCallThisPointer(EvalInfo &Info, const Expr *E, const LValue &This, const CXXMethodDecl *NamedMember)
Check that the pointee of the 'this' pointer in a member function call is either within its lifetime ...
static bool CheckConstantExpression(EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value, ConstantExprKind Kind)
Check that this core constant expression value is a valid value for a constant expression.
static bool EvaluateAsBooleanCondition(const Expr *E, bool &Result, EvalInfo &Info)
static std::optional< DynamicType > ComputeDynamicType(EvalInfo &Info, const Expr *E, LValue &This, AccessKinds AK)
Determine the dynamic type of an object.
static bool EvaluateDecl(EvalInfo &Info, const Decl *D, bool EvaluateConditionDecl=false)
static void expandArray(APValue &Array, unsigned Index)
static bool handleLogicalOpForVector(const APInt &LHSValue, BinaryOperatorKind Opcode, const APInt &RHSValue, APInt &Result)
static unsigned FindDesignatorMismatch(QualType ObjType, const SubobjectDesignator &A, const SubobjectDesignator &B, bool &WasArrayIndex)
Find the position where two subobject designators diverge, or equivalently the length of the common i...
static bool isOnePastTheEndOfCompleteObject(const ASTContext &Ctx, const LValue &LV)
Determine whether this is a pointer past the end of the complete object referred to by the lvalue.
static unsigned getBaseIndex(const CXXRecordDecl *Derived, const CXXRecordDecl *Base)
Get the base index of the given base class within an APValue representing the given derived class.
static bool EvaluateFixedPoint(const Expr *E, APFixedPoint &Result, EvalInfo &Info)
Evaluate only a fixed point expression into an APResult.
void HandleComplexComplexMul(APFloat A, APFloat B, APFloat C, APFloat D, APFloat &ResR, APFloat &ResI)
static bool tryEvaluateBuiltinObjectSize(const Expr *E, unsigned Type, EvalInfo &Info, uint64_t &Size)
Tries to evaluate the __builtin_object_size for E. If successful, returns true and stores the result ...
static bool EvalPointerValueAsBool(const APValue &Value, bool &Result)
static bool handleVectorVectorBinOp(EvalInfo &Info, const BinaryOperator *E, BinaryOperatorKind Opcode, APValue &LHSValue, const APValue &RHSValue)
static const FunctionDecl * getVirtualOperatorDelete(QualType T)
static bool isDesignatorAtObjectEnd(const ASTContext &Ctx, const LValue &LVal)
Checks to see if the given LValue's Designator is at the end of the LValue's record layout....
static bool CheckArraySize(EvalInfo &Info, const ConstantArrayType *CAT, SourceLocation CallLoc={})
static bool EvaluateInPlace(APValue &Result, EvalInfo &Info, const LValue &This, const Expr *E, bool AllowNonLiteralTypes=false)
EvaluateInPlace - Evaluate an expression in-place in an APValue. In some cases, the in-place evaluati...
static bool handleFloatFloatBinOp(EvalInfo &Info, const BinaryOperator *E, APFloat &LHS, BinaryOperatorKind Opcode, const APFloat &RHS)
Perform the given binary floating-point operation, in-place, on LHS.
static std::optional< DynAlloc * > CheckDeleteKind(EvalInfo &Info, const Expr *E, const LValue &Pointer, DynAlloc::Kind DeallocKind)
Check that the given object is a suitable pointer to a heap allocation that still exists and is of th...
static bool EvaluateLValue(const Expr *E, LValue &Result, EvalInfo &Info, bool InvalidBaseOK=false)
Evaluate an expression as an lvalue. This can be legitimately called on expressions which are not glv...
static bool FastEvaluateAsRValue(const Expr *Exp, APValue &Result, const ASTContext &Ctx, bool &IsConst)
static bool HandleCovariantReturnAdjustment(EvalInfo &Info, const Expr *E, APValue &Result, ArrayRef< QualType > Path)
Perform the adjustment from a value returned by a virtual function to a value of the statically expec...
static bool evalShiftWithCount(EvalInfo &Info, const CallExpr *Call, APValue &Out, llvm::function_ref< APInt(const APInt &, uint64_t)> ShiftOp, llvm::function_ref< APInt(const APInt &, unsigned)> OverflowOp)
static EvalStmtResult EvaluateSwitch(StmtResult &Result, EvalInfo &Info, const SwitchStmt *SS)
Evaluate a switch statement.
static void expandStringLiteral(EvalInfo &Info, const StringLiteral *S, APValue &Result, QualType AllocType=QualType())
static bool EvaluateArgs(ArrayRef< const Expr * > Args, CallRef Call, EvalInfo &Info, const FunctionDecl *Callee, bool RightToLeft=false, LValue *ObjectArg=nullptr)
Evaluate the arguments to a function call.
static bool EvaluateAtomic(const Expr *E, const LValue *This, APValue &Result, EvalInfo &Info)
static bool getBytesReturnedByAllocSizeCall(const ASTContext &Ctx, const LValue &LVal, llvm::APInt &Result)
Convenience function. LVal's base must be a call to an alloc_size function.
static bool handleIntIntBinOp(EvalInfo &Info, const BinaryOperator *E, const APSInt &LHS, BinaryOperatorKind Opcode, APSInt RHS, APSInt &Result)
Perform the given binary integer operation.
static bool EvaluateInitForDeclOfReferenceType(EvalInfo &Info, const ValueDecl *D, const Expr *Init, LValue &Result, APValue &Val)
Evaluates the initializer of a reference.
static bool checkDynamicType(EvalInfo &Info, const Expr *E, const LValue &This, AccessKinds AK, bool Polymorphic)
Check that we can access the notional vptr of an object / determine its dynamic type.
static bool HandleFloatToIntCast(EvalInfo &Info, const Expr *E, QualType SrcType, const APFloat &Value, QualType DestType, APSInt &Result)
static bool getAlignmentArgument(const Expr *E, QualType ForType, EvalInfo &Info, APSInt &Alignment)
Evaluate the value of the alignment argument to __builtin_align_{up,down}, __builtin_is_aligned and _...
static bool CheckFullyInitialized(EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value)
Check that this evaluated value is fully-initialized and can be loaded by an lvalue-to-rvalue convers...
static SubobjectHandler::result_type findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, const SubobjectDesignator &Sub, SubobjectHandler &handler)
Find the designated sub-object of an rvalue.
static bool determineEndOffset(EvalInfo &Info, SourceLocation ExprLoc, unsigned Type, const LValue &LVal, CharUnits &EndOffset)
Helper for tryEvaluateBuiltinObjectSize – Given an LValue, this will determine how many bytes exist f...
static bool convertUnsignedAPIntToCharUnits(const llvm::APInt &Int, CharUnits &Result)
Converts the given APInt to CharUnits, assuming the APInt is unsigned. Fails if the conversion would ...
static bool EvaluateCallArg(const ParmVarDecl *PVD, const Expr *Arg, CallRef Call, EvalInfo &Info, bool NonNull=false, APValue **EvaluatedArg=nullptr)
llvm::SmallPtrSet< const MaterializeTemporaryExpr *, 8 > CheckedTemporaries
Materialized temporaries that we've already checked to determine if they're initializsed by a constan...
GCCTypeClass EvaluateBuiltinClassifyType(QualType T, const LangOptions &LangOpts)
EvaluateBuiltinClassifyType - Evaluate __builtin_classify_type the same way as GCC.
static bool EvaluateDependentExpr(const Expr *E, EvalInfo &Info)
static bool MaybeEvaluateDeferredVarDeclInit(EvalInfo &Info, const VarDecl *VD)
static APSInt HandleIntToIntCast(EvalInfo &Info, const Expr *E, QualType DestType, QualType SrcType, const APSInt &Value)
static std::optional< APValue > handleVectorUnaryOperator(ASTContext &Ctx, QualType ResultTy, UnaryOperatorKind Op, APValue Elt)
static bool lifetimeStartedInEvaluation(EvalInfo &Info, APValue::LValueBase Base, bool MutableSubobject=false)
static bool isOneByteCharacterType(QualType T)
static bool HandleLambdaCapture(EvalInfo &Info, const Expr *E, LValue &Result, const CXXMethodDecl *MD, const FieldDecl *FD, bool LValueToRValueConversion)
Get an lvalue to a field of a lambda's closure type.
static bool EvaluateCond(EvalInfo &Info, const VarDecl *CondDecl, const Expr *Cond, bool &Result)
Evaluate a condition (either a variable declaration or an expression).
static bool EvaluateAsFixedPoint(const Expr *E, Expr::EvalResult &ExprResult, const ASTContext &Ctx, Expr::SideEffectsKind AllowSideEffects, EvalInfo &Info)
static bool EvaluateAsRValue(EvalInfo &Info, const Expr *E, APValue &Result)
EvaluateAsRValue - Try to evaluate this expression, performing an implicit lvalue-to-rvalue cast if i...
static bool diagnoseMutableFields(EvalInfo &Info, const Expr *E, AccessKinds AK, QualType T)
Diagnose an attempt to read from any unreadable field within the specified type, which might be a cla...
static ICEDiag CheckICE(const Expr *E, const ASTContext &Ctx)
static bool CheckConstexprFunction(EvalInfo &Info, SourceLocation CallLoc, const FunctionDecl *Declaration, const FunctionDecl *Definition, const Stmt *Body)
CheckConstexprFunction - Check that a function can be called in a constant expression.
static bool EvaluateDestruction(const ASTContext &Ctx, APValue::LValueBase Base, APValue DestroyedValue, QualType Type, SourceLocation Loc, Expr::EvalStatus &EStatus, bool IsConstantDestruction)
static EvalStmtResult EvaluateStmt(StmtResult &Result, EvalInfo &Info, const Stmt *S, const SwitchCase *SC=nullptr)
static bool EvaluateArrayNewInitList(EvalInfo &Info, LValue &This, APValue &Result, const InitListExpr *ILE, QualType AllocType)
static bool HasSameBase(const LValue &A, const LValue &B)
static bool CheckLocalVariableDeclaration(EvalInfo &Info, const VarDecl *VD)
static bool HandleLValueDirectBase(EvalInfo &Info, const Expr *E, LValue &Obj, const CXXRecordDecl *Derived, const CXXRecordDecl *Base, const ASTRecordLayout *RL=nullptr)
static bool IsGlobalLValue(APValue::LValueBase B)
static llvm::RoundingMode getActiveRoundingMode(EvalInfo &Info, const Expr *E)
Get rounding mode to use in evaluation of the specified expression.
static QualType getObjectType(APValue::LValueBase B)
Retrieves the "underlying object type" of the given expression, as used by __builtin_object_size.
static bool handleCompareOpForVectorHelper(const APTy &LHSValue, BinaryOperatorKind Opcode, const APTy &RHSValue, APInt &Result)
static bool Evaluate(APValue &Result, EvalInfo &Info, const Expr *E)
static bool isReadByLvalueToRvalueConversion(const CXXRecordDecl *RD)
Determine whether a type would actually be read by an lvalue-to-rvalue conversion.
static void negateAsSigned(APSInt &Int)
Negate an APSInt in place, converting it to a signed form if necessary, and preserving its value (by ...
static bool HandleFunctionCall(SourceLocation CallLoc, const FunctionDecl *Callee, const LValue *ObjectArg, const Expr *E, ArrayRef< const Expr * > Args, CallRef Call, const Stmt *Body, EvalInfo &Info, APValue &Result, const LValue *ResultSlot)
Evaluate a function call.
static bool isUserWritingOffTheEnd(const ASTContext &Ctx, const LValue &LVal)
Attempts to detect a user writing into a piece of memory that's impossible to figure out the size of ...
static bool GetLValueBaseAsString(const EvalInfo &Info, const LValue &LVal, LValueBaseString &AsString)
static bool HandleOperatorDeleteCall(EvalInfo &Info, const CallExpr *E)
static bool EvaluateIntegerOrLValue(const Expr *E, APValue &Result, EvalInfo &Info)
EvaluateIntegerOrLValue - Evaluate an rvalue integral-typed expression, and produce either the intege...
static bool HandleDynamicCast(EvalInfo &Info, const ExplicitCastExpr *E, LValue &Ptr)
Apply the given dynamic cast operation on the provided lvalue.
static bool HandleOperatorNewCall(EvalInfo &Info, const CallExpr *E, LValue &Result)
Perform a call to 'operator new' or to ‘__builtin_operator_new’.
static bool HandleFloatToFloatCast(EvalInfo &Info, const Expr *E, QualType SrcType, QualType DestType, APFloat &Result)
static bool MaybeHandleUnionActiveMemberChange(EvalInfo &Info, const Expr *LHSExpr, const LValue &LHS)
Handle a builtin simple-assignment or a call to a trivial assignment operator whose left-hand side mi...
uint8_t GFNIMul(uint8_t AByte, uint8_t BByte)
static bool isFormalAccess(AccessKinds AK)
Is this an access per the C++ definition?
static bool handleCompoundAssignment(EvalInfo &Info, const CompoundAssignOperator *E, const LValue &LVal, QualType LValType, QualType PromotedLValType, BinaryOperatorKind Opcode, const APValue &RVal)
Perform a compound assignment of LVal <op>= RVal.
static bool handleIncDec(EvalInfo &Info, const Expr *E, const LValue &LVal, QualType LValType, bool IsIncrement, APValue *Old)
Perform an increment or decrement on LVal.
static bool EvaluateVoid(const Expr *E, EvalInfo &Info)
static bool HandleDestruction(EvalInfo &Info, const Expr *E, const LValue &This, QualType ThisType)
Perform a destructor or pseudo-destructor call on the given object, which might in general not be a c...
static bool HandleDestructionImpl(EvalInfo &Info, SourceRange CallRange, const LValue &This, APValue &Value, QualType T)
static bool ArePotentiallyOverlappingStringLiterals(const EvalInfo &Info, const LValue &LHS, const LValue &RHS)
uint8_t GFNIMultiplicativeInverse(uint8_t Byte)
uint8_t GFNIAffine(uint8_t XByte, const APInt &AQword, const APSInt &Imm, bool Inverse)
APSInt NormalizeRotateAmount(const APSInt &Value, const APSInt &Amount)
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
llvm::MachO::Record Record
Implements a partial diagnostic which may not be emitted.
llvm::DenseMap< Stmt *, Stmt * > MapTy
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
Expr * getExpr()
Get 'expr' part of the associated expression/statement.
static QualType getPointeeType(const MemRegion *R)
Enumerates target-specific builtins in their own namespaces within namespace clang.
Defines the clang::TypeLoc interface and its subclasses.
C Language Family Type Representation.
__DEVICE__ long long abs(long long __n)
a trap message and trap category.
llvm::APInt getValue() const
unsigned getVersion() const
QualType getDynamicAllocType() const
QualType getTypeInfoType() const
static LValueBase getTypeInfo(TypeInfoLValue LV, QualType TypeInfo)
static LValueBase getDynamicAlloc(DynamicAllocLValue LV, QualType Type)
A non-discriminated union of a base, field, or array index.
BaseOrMemberType getAsBaseOrMember() const
static LValuePathEntry ArrayIndex(uint64_t Index)
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
bool hasArrayFiller() const
const LValueBase getLValueBase() const
APValue & getArrayInitializedElt(unsigned I)
void swap(APValue &RHS)
Swaps the contents of this and the given APValue.
APValue & getStructField(unsigned i)
const FieldDecl * getUnionField() const
APSInt & getComplexIntImag()
bool isComplexInt() const
llvm::PointerIntPair< const Decl *, 1, bool > BaseOrMemberType
A FieldDecl or CXXRecordDecl, along with a flag indicating whether we mean a virtual or non-virtual b...
ValueKind getKind() const
unsigned getArrayInitializedElts() const
static APValue IndeterminateValue()
APFixedPoint & getFixedPoint()
bool hasLValuePath() const
const ValueDecl * getMemberPointerDecl() const
APValue & getUnionValue()
CharUnits & getLValueOffset()
void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const
bool isComplexFloat() const
APValue & getVectorElt(unsigned I)
APValue & getArrayFiller()
unsigned getVectorLength() const
void setUnion(const FieldDecl *Field, const APValue &Value)
bool isIndeterminate() const
unsigned getArraySize() const
bool allowConstexprUnknown() const
std::string getAsString(const ASTContext &Ctx, QualType Ty) const
bool isFixedPoint() const
@ 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()
const ConstantArrayType * getAsConstantArrayType(QualType T) const
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.
static CanQualType getCanonicalType(QualType T)
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
void getObjCEncodingForType(QualType T, std::string &S, const FieldDecl *Field=nullptr, QualType *NotEncodedT=nullptr) const
Emit the Objective-CC type encoding for the given type T into S.
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.
bool hasSameFunctionTypeIgnoringExceptionSpec(QualType T, QualType U) const
Determine whether two function types are the same, ignoring exception specifications in cases where t...
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
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, const Expr *SizeExpr, ArraySizeModifier ASM, unsigned IndexTypeQuals) const
Return the unique reference to the type for a constant array of the specified element type.
const LangOptions & getLangOpts() const
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
ComparisonCategories CompCategories
Types and expressions required to build C++2a three-way comparisons using operator<=>,...
QualType getIntTypeForBitwidth(unsigned DestWidth, unsigned Signed) const
getIntTypeForBitwidth - sets integer QualTy according to specified details: bitwidth,...
unsigned getOpenMPDefaultSimdAlign(QualType T) const
Get default simd alignment of the specified complete type in bits.
TypeInfoChars getTypeInfoDataSizeInChars(QualType T) const
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
llvm::FixedPointSemantics getFixedPointSemantics(QualType Ty) 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.
static bool hasSameType(QualType T1, QualType T2)
Determine whether the given types T1 and T2 are equivalent.
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
bool hasSimilarType(QualType T1, QualType T2) const
Determine if two types are similar, according to the C++ rules.
DiagnosticsEngine & getDiagnostics() const
interp::Context & getInterpContext()
Returns the clang bytecode interpreter context.
QualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
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
static bool hasSameUnqualifiedType(QualType T1, QualType T2)
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
uint16_t getPointerAuthTypeDiscriminator(QualType T)
Return the "other" type-specific discriminator for the given type.
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
std::string getQuotedName(unsigned ID) const
Return the identifier name for the specified builtin inside single quotes for a diagnostic,...
bool isConstantEvaluated(unsigned ID) const
Return true if this function can be constant evaluated by Clang frontend.
AccessSpecifier Access
The access along this inheritance path.
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
bool isAmbiguous(CanQualType BaseType) const
Determine whether the path from the most-derived type to the given base type is ambiguous (i....
Represents a base class of a C++ class.
SourceLocation getBeginLoc() const LLVM_READONLY
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
QualType getType() const
Retrieves the type of the base class.
const Expr * getSubExpr() const
Represents a call to a C++ constructor.
bool isElidable() const
Whether this construction is elidable.
Expr * getArg(unsigned Arg)
Return the specified argument.
bool requiresZeroInitialization() const
Whether this construction first requires zero-initialization before the initializer is called.
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
unsigned getNumArgs() const
Return the number of arguments to the constructor call.
Represents a C++ constructor within a class.
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
CXXCtorInitializer *const * init_const_iterator
Iterates through the member/base initializer list.
Expr * getExpr()
Get the initialization expression that will be used.
FunctionDecl * getOperatorDelete() const
bool isGlobalDelete() const
Represents a C++ destructor within a class.
CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for statement, represented as 'for (ra...
DeclStmt * getBeginStmt()
DeclStmt * getLoopVarStmt()
DeclStmt * getRangeStmt()
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will call.
Represents a static or instance method of a struct/union/class.
bool isExplicitObjectMemberFunction() const
[C++2b][dcl.fct]/p7 An explicit object member function is a non-static member function with an explic...
bool isImplicitObjectMemberFunction() const
[C++2b][dcl.fct]/p7 An implicit object member function is a non-static member function without an exp...
QualType getFunctionObjectParameterReferenceType() const
Return the type of the object pointed by this.
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
bool isMoveAssignmentOperator() const
Determine whether this is a move assignment operator.
bool isCopyAssignmentOperator() const
Determine whether this is a copy-assignment operator, regardless of whether it was declared implicitl...
bool isLambdaStaticInvoker() const
Determine whether this is a lambda closure type's static member function that is used for the result ...
QualType getAllocatedType() const
std::optional< Expr * > getArraySize()
This might return std::nullopt even if isArray() returns true, since there might not be an array size...
Expr * getPlacementArg(unsigned I)
unsigned getNumPlacementArgs() const
SourceRange getSourceRange() const
FunctionDecl * getOperatorNew() const
Expr * getInitializer()
The initializer of this new-expression.
MutableArrayRef< Expr * > getInitExprs()
Represents a C++ struct/union/class.
bool hasMutableFields() const
Determine whether this class, or any of its class subobjects, contains a mutable field.
bool isGenericLambda() const
Determine whether this class describes a generic lambda function object (i.e.
base_class_iterator bases_end()
bool hasTrivialDestructor() const
Determine whether this class has a trivial destructor (C++ [class.dtor]p3)
void getCaptureFields(llvm::DenseMap< const ValueDecl *, FieldDecl * > &Captures, FieldDecl *&ThisCapture) const
For a closure type, retrieve the mapping from captured variables and this to the non-static data memb...
unsigned getNumBases() const
Retrieves the number of base classes of this class.
base_class_iterator bases_begin()
const CXXBaseSpecifier * base_class_const_iterator
Iterator that traverses the base classes of a class.
capture_const_range captures() const
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
CXXMethodDecl * getLambdaCallOperator() const
Retrieve the lambda call operator of the closure type if this is a closure type.
CXXRecordDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
bool isDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is derived from the class Base.
Expr * getSemanticForm()
Get an equivalent semantic form for this expression.
bool isTypeOperand() const
QualType getTypeOperand(const ASTContext &Context) const
Retrieves the type operand of this typeid() expression after various required adjustments (removing r...
Expr * getExprOperand() const
bool isPotentiallyEvaluated() const
Determine whether this typeid has a type operand which is potentially evaluated, per C++11 [expr....
MSGuidDecl * getGuidDecl() const
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
SourceLocation getBeginLoc() const
const AllocSizeAttr * getCalleeAllocSizeAttr() const
Try to get the alloc_size attribute of the callee. May return null.
unsigned getBuiltinCallee() const
getBuiltinCallee - If this is a call to a builtin, return the builtin ID of the callee.
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
Expr ** getArgs()
Retrieve the call arguments.
QualType getCallReturnType(const ASTContext &Ctx) const
getCallReturnType - Get the return type of the call expr.
QualType withConst() const
Retrieves a version of this type with const applied.
const T * getTypePtr() const
Retrieve the underlying type pointer, which refers to a canonical type.
CaseStmt - Represent a case statement.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
path_iterator path_begin()
unsigned path_size() const
CastKind getCastKind() const
const CXXBaseSpecifier *const * path_const_iterator
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operation.
CharUnits - This is an opaque type for sizes expressed in character units.
bool isPowerOfTwo() const
isPowerOfTwo - Test whether the quantity is a power of two.
CharUnits alignmentAtOffset(CharUnits offset) const
Given that this is a non-zero alignment value, what is the alignment at the given offset?
bool isZero() const
isZero - Test whether the quantity equals zero.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
unsigned getValue() const
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
const ComparisonCategoryInfo & getInfoForType(QualType Ty) const
Return the comparison category information as specified by getCategoryForType(Ty).
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
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
Represents the current source location and context used to determine the value of the source location...
const Expr * getDefaultExpr() const
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool Equals(const DeclContext *DC) const
Determine whether this declaration context is equivalent to the declaration context DC.
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
A reference to a declared variable, function, enum, etc.
bool refersToEnclosingVariableOrCapture() const
Does this DeclRefExpr refer to an enclosing local or a captured variable?
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Decl - This represents one declaration (or definition), e.g.
bool isInStdNamespace() const
ASTContext & getASTContext() const LLVM_READONLY
bool isInvalidDecl() const
SourceLocation getLocation() const
DeclContext * getDeclContext()
AccessSpecifier getAccess() const
bool isAnyOperatorNew() const
A decomposition declaration.
auto flat_bindings() const
Designator - A designator in a C99 designated initializer.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
DoStmt - This represents a 'do/while' stmt.
Symbolic representation of a dynamic allocation.
static unsigned getMaxIndex()
ChildElementIter< false > begin()
ExplicitCastExpr - An explicit cast written in the source code.
QualType getTypeAsWritten() const
getTypeAsWritten - Returns the type that this expression is casting to, as written in the source code...
This represents one expression.
const Expr * skipRValueSubobjectAdjustments(SmallVectorImpl< const Expr * > &CommaLHS, SmallVectorImpl< SubobjectAdjustment > &Adjustments) const
Walk outwards from an expression we want to bind a reference to and find the expression whose lifetim...
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
static bool isPotentialConstantExpr(const FunctionDecl *FD, SmallVectorImpl< PartialDiagnosticAt > &Diags)
isPotentialConstantExpr - Return true if this function's definition might be usable in a constant exp...
bool isIntegerConstantExpr(const ASTContext &Ctx) const
static bool isPotentialConstantExprUnevaluated(Expr *E, const FunctionDecl *FD, SmallVectorImpl< PartialDiagnosticAt > &Diags)
isPotentialConstantExprUnevaluated - Return true if this expression might be usable in a constant exp...
@ SE_AllowSideEffects
Allow any unmodeled side effect.
@ SE_AllowUndefinedBehavior
Allow UB that we can give a value, but not arbitrary unmodeled side effects.
bool isCXX11ConstantExpr(const ASTContext &Ctx, APValue *Result=nullptr) const
isCXX11ConstantExpr - Return true if this expression is a constant expression in C++11.
bool EvaluateCharRangeAsString(std::string &Result, const Expr *SizeExpression, const Expr *PtrExpression, ASTContext &Ctx, EvalResult &Status) const
llvm::APSInt EvaluateKnownConstIntCheckOverflow(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
bool isValueDependent() const
Determines whether the value of this expression depends on.
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
bool tryEvaluateStrLen(uint64_t &Result, ASTContext &Ctx) const
If the current Expr is a pointer, this will try to statically determine the strlen of the string poin...
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Returns the set of floating point options that apply to this expression.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
bool containsErrors() const
Whether this expression contains subexpressions which had errors.
bool EvaluateAsFloat(llvm::APFloat &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsFloat - Return true if this is a constant which we can fold and convert to a floating point...
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsLValue - Evaluate an expression to see if we can fold it to an lvalue with link time known ...
bool EvaluateAsFixedPoint(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsFixedPoint - Return true if this is a constant which we can fold and convert to a fixed poi...
bool isEvaluatable(const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
isEvaluatable - Call EvaluateAsRValue to see if this expression can be constant folded without side-e...
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language.
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...
bool HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects=true) const
HasSideEffects - This routine returns true for all those expressions which have any effect other than...
bool EvaluateAsConstantExpr(EvalResult &Result, const ASTContext &Ctx, ConstantExprKind Kind=ConstantExprKind::Normal) const
Evaluate an expression that is required to be a constant expression.
std::optional< std::string > tryEvaluateString(ASTContext &Ctx) const
If the current Expr can be evaluated to a pointer to a null-terminated constant string,...
bool EvaluateAsBooleanCondition(bool &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsBooleanCondition - Return true if this is a constant which we can fold and convert to a boo...
bool isTemporaryObject(ASTContext &Ctx, const CXXRecordDecl *TempTy) const
Determine whether the result of this expression is a temporary object of the given class type.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
bool tryEvaluateObjectSize(uint64_t &Result, ASTContext &Ctx, unsigned Type) const
If the current Expr is a pointer, this will try to statically determine the number of bytes available...
bool isCXX98IntegralConstantExpr(const ASTContext &Ctx) const
isCXX98IntegralConstantExpr - Return true if this expression is an integral constant expression in C+...
bool EvaluateWithSubstitution(APValue &Value, ASTContext &Ctx, const FunctionDecl *Callee, ArrayRef< const Expr * > Args, const Expr *This=nullptr) const
EvaluateWithSubstitution - Evaluate an expression as if from the context of a call to the given funct...
bool EvaluateAsInitializer(APValue &Result, const ASTContext &Ctx, const VarDecl *VD, SmallVectorImpl< PartialDiagnosticAt > &Notes, bool IsConstantInitializer) const
EvaluateAsInitializer - Evaluate an expression as if it were the initializer of the given declaration...
void EvaluateForOverflow(const ASTContext &Ctx) const
bool isArrow() const
isArrow - Return true if the base expression is a pointer to vector, return false if the base express...
void getEncodedElementAccess(SmallVectorImpl< uint32_t > &Elts) const
getEncodedElementAccess - Encode the elements accessed into an llvm aggregate Constant of ConstantInt...
const Expr * getBase() const
bool isFPConstrained() const
LangOptions::FPExceptionModeKind getExceptionMode() const
RoundingMode getRoundingMode() const
Represents a member of a struct/union/class.
bool isBitField() const
Determines whether this field is a bitfield.
unsigned getBitWidthValue() const
Computes the bit width of this field, if this is a bit field.
unsigned getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
FieldDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this field.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
llvm::APInt getValue() const
Returns an internal integer representation of the literal.
llvm::APFloat getValue() const
ForStmt - This represents a 'for (init;cond;inc)' stmt.
VarDecl * getConditionVariable() const
Retrieve the variable declared in this "for" statement, if any.
const Expr * getSubExpr() const
Represents a function declaration or definition.
const ParmVarDecl * getParamDecl(unsigned i) const
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
bool isFunctionTemplateSpecialization() const
Determine whether this function is a function template specialization.
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
bool hasCXXExplicitFunctionObjectParameter() const
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
bool isConstexpr() const
Whether this is a (C++11) constexpr function or constexpr constructor.
bool isUsableAsGlobalAllocationFunctionInConstantEvaluation(UnsignedOrNone *AlignmentParam=nullptr, bool *IsNothrow=nullptr) const
Determines whether this function is one of the replaceable global allocation functions described in i...
bool isDefaulted() const
Whether this function is defaulted.
void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override
Appends a human-readable name for this declaration into the given stream.
FunctionDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
Expr * getResultExpr()
Return the result expression of this controlling expression.
One of these records is kept for each identifier that is lexed.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
IfStmt - This represents an if/then/else.
bool isNonNegatedConsteval() const
VarDecl * getConditionVariable()
Retrieve the variable declared in this "if" statement, if any.
const Expr * getSubExpr() const
Represents an implicitly-generated value initialization of an object of a given type.
Represents a field injected from an anonymous union/struct into the parent scope.
ArrayRef< NamedDecl * > chain() const
Describes an C or C++ initializer list.
bool isTransparent() const
Is this a transparent initializer list (that is, an InitListExpr that is purely syntactic,...
bool isStringLiteralInit() const
Is this an initializer for an array of characters, initialized by a string literal or an @encode?
unsigned getNumInits() const
Expr * getArrayFiller()
If this initializer list initializes an array with more elements than there are initializers in the l...
const Expr * getInit(unsigned Init) const
ArrayRef< Expr * > inits()
capture_init_iterator capture_init_end()
Retrieve the iterator pointing one past the last initialization argument for this lambda expression.
capture_init_iterator capture_init_begin()
Retrieve the first initialization argument for this lambda expression (which initializes the first ca...
CXXRecordDecl * getLambdaClass() const
Retrieve the class that corresponds to the lambda.
StrictFlexArraysLevelKind
@ FPE_Ignore
Assume that floating-point exceptions are masked.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
StorageDuration getStorageDuration() const
Retrieve the storage duration for the materialized temporary.
Expr * getSubExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue.
APValue * getOrCreateValue(bool MayCreate) const
Get the storage for the constant value of a materialized temporary of static storage duration.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
void printQualifiedName(raw_ostream &OS) const
Returns a human-readable qualified name for this declaration, like A::B::i, for i being member of nam...
bool isExpressibleAsConstantInitializer() const
Expr * getIndexExpr(unsigned Idx)
const OffsetOfNode & getComponent(unsigned Idx) const
TypeSourceInfo * getTypeSourceInfo() const
unsigned getNumComponents() const
unsigned getArrayExprIndex() const
For an array element node, returns the index into the array of expressions.
FieldDecl * getField() const
For a field offsetof node, returns the field.
@ Array
An index into an array.
@ Identifier
A field in a dependent type, known only by its name.
@ Base
An implicit indirection through a C++ base class, when the field found is in a base class.
Kind getKind() const
Determine what kind of offsetof node this is.
CXXBaseSpecifier * getBase() const
For a base class node, returns the base specifier.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
Expr * getSelectedExpr() const
const Expr * getSubExpr() const
Represents a parameter to a function.
unsigned getFunctionScopeIndex() const
Returns the index of this parameter in its prototype or method scope.
bool isExplicitObjectParameter() const
PointerType - C99 6.7.5.1 - Pointer Declarators.
StringLiteral * getFunctionName()
Expr * getResultExpr()
Return the result-bearing expression, or null if there is none.
ArrayRef< Expr * > semantics()
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
QualType withConst() const
void addConst()
Add the const type qualifier to this QualType.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
void removeLocalVolatile()
void addVolatile()
Add the volatile type qualifier to this QualType.
bool isConstQualified() const
Determine whether this type is const-qualified.
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.
Represents a struct/union/class.
unsigned getNumFields() const
Returns the number of fields (non-static data members) in this record.
field_iterator field_end() const
field_range fields() const
specific_decl_iterator< FieldDecl > field_iterator
bool isAnonymousStructOrUnion() const
Whether this is an anonymous struct or union.
field_iterator field_begin() const
bool isSatisfied() const
Whether or not the requires clause is satisfied.
SourceLocation getLocation() const
std::string ComputeName(ASTContext &Context) const
Scope - A scope is a transient data structure that is used while parsing the program.
ShuffleVectorExpr - clang-specific builtin-in function __builtin_shufflevector.
llvm::APSInt getShuffleMaskIdx(unsigned N) const
unsigned getNumSubExprs() const
getNumSubExprs - Return the size of the SubExprs array.
Expr * getExpr(unsigned Index)
getExpr - Return the Expr at the specified index.
unsigned getPackLength() const
Retrieve the length of the parameter pack.
APValue EvaluateInContext(const ASTContext &Ctx, const Expr *DefaultExpr) const
Return the result of evaluating this SourceLocExpr in the specified (and possibly null) default argum...
Encodes a location in the source.
A trivial tuple used to represent a source range.
SourceLocation getBegin() const
std::string printToString(const SourceManager &SM) const
CompoundStmt * getSubStmt()
Stmt - This represents one statement.
StmtClass getStmtClass() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
SourceLocation getBeginLoc() const LLVM_READONLY
StringLiteral - This represents a string literal expression, e.g.
unsigned getLength() const
StringRef getBytes() const
Allow access to clients that need the byte representation, such as ASTWriterStmt::VisitStringLiteral(...
uint32_t getCodeUnit(size_t i) const
StringRef getString() const
unsigned getCharByteWidth() const
Expr * getReplacement() const
const SwitchCase * getNextSwitchCase() const
SwitchStmt - This represents a 'switch' stmt.
VarDecl * getConditionVariable()
Retrieve the variable declared in this "switch" statement, if any.
SwitchCase * getSwitchCaseList()
TagDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
unsigned getMaxAtomicInlineWidth() const
Return the maximum width lock-free atomic operation which can be inlined given the supported features...
virtual int getEHDataRegisterNumber(unsigned RegNo) const
Return the register number that __builtin_eh_return_regno would return with the specified argument.
unsigned getCharWidth() const
unsigned size() const
Retrieve the number of template arguments in this template argument list.
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
@ Type
The template argument is a type.
Symbolic representation of typeid(T) for some type T.
QualType getType() const
Return the type wrapped by this type source info.
bool getBoolValue() const
const APValue & getAPValue() const
bool isStoredAsBoolean() const
The base class of the type hierarchy.
bool isBooleanType() const
bool isFunctionReferenceType() const
bool isMFloat8Type() const
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
bool isPackedVectorBoolType(const ASTContext &ctx) const
bool isLiteralType(const ASTContext &Ctx) const
Return true if this is a literal type (C++11 [basic.types]p10)
bool isIncompleteArrayType() const
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
bool isComplexType() const
isComplexType() does not include complex integers (a GCC extension).
const ArrayType * castAsArrayTypeUnsafe() const
A variant of castAs<> for array type which silently discards qualifiers from the outermost type.
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
bool isIntegralOrUnscopedEnumerationType() const
Determine whether this type is an integral or unscoped enumeration type.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isConstantArrayType() const
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isVoidPointerType() const
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6....
bool isFunctionPointerType() const
bool isPointerType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isEnumeralType() const
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
bool isVariableArrayType() const
bool isSveVLSBuiltinType() const
Determines if this is a sizeless type supported by the 'arm_sve_vector_bits' type attribute,...
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
bool isExtVectorBoolType() const
bool isMemberDataPointerType() const
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
RecordDecl * castAsRecordDecl() const
bool isAnyComplexType() const
bool isFixedPointType() const
Return true if this is a fixed point type according to ISO/IEC JTC1 SC22 WG14 N1169.
bool isMemberPointerType() const
bool isAtomicType() const
bool isComplexIntegerType() const
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isObjectType() const
Determine whether this type is an object type.
EnumDecl * getAsEnumDecl() const
Retrieves the EnumDecl this type refers to.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
bool isFunctionType() const
bool isVectorType() const
bool isRealFloatingType() const
Floating point categories.
bool isFloatingType() const
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
const T * castAsCanonical() const
Return this type's canonical type cast to the specified type.
bool isAnyPointerType() const
TypeClass getTypeClass() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isNullPtrType() const
bool isRecordType() const
bool isSizelessVectorType() const
Returns true for all scalable vector types.
bool hasPointerRepresentation() const
Whether this type is represented natively as a pointer.
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
QualType getArgumentType() const
SourceLocation getBeginLoc() const LLVM_READONLY
QualType getTypeOfArgument() const
Gets the argument type, or the type of the argument expression, whichever is appropriate.
bool isArgumentType() const
UnaryExprOrTypeTrait getKind() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
SourceLocation getExprLoc() const
Expr * getSubExpr() const
static bool isIncrementOp(Opcode Op)
bool canOverflow() const
Returns true if the unary operator can cause an overflow.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
bool isWeak() const
Determine whether this symbol is weakly-imported, or declared with the weak or weak-ref attr.
Represents a variable declaration or definition.
bool isConstexpr() const
Whether this variable is (C++11) constexpr.
bool hasICEInitializer(const ASTContext &Context) const
Determine whether the initializer of this variable is an integer constant expression.
bool isInitCapture() const
Whether this variable is the implicit variable for a lambda init-capture.
APValue * evaluateValue() const
Attempt to evaluate the value of the initializer attached to this declaration, and produce notes expl...
CharUnits getFlexibleArrayInitChars(const ASTContext &Ctx) const
If hasFlexibleArrayInit is true, compute the number of additional bytes necessary to store those elem...
bool hasConstantInitialization() const
Determine whether this variable has constant initialization.
VarDecl * getDefinition(ASTContext &)
Get the real (not just tentative) definition for this declaration.
bool mightBeUsableInConstantExpressions(const ASTContext &C) const
Determine whether this variable's value might be usable in a constant expression, according to the re...
EvaluatedStmt * ensureEvaluatedStmt() const
Convert the initializer for this declaration to the elaborated EvaluatedStmt form,...
bool evaluateDestruction(SmallVectorImpl< PartialDiagnosticAt > &Notes) const
Evaluate the destruction of this variable to determine if it constitutes constant destruction.
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
ThreadStorageClassSpecifier getTSCSpec() const
const Expr * getInit() const
APValue * getEvaluatedValue() const
Return the already-evaluated value of this variable's initializer, or NULL if the value is not yet kn...
bool hasLocalStorage() const
Returns true if a variable with function scope is a non-static local variable.
DefinitionKind hasDefinition(ASTContext &) const
Check whether this variable is defined in this translation unit.
bool isLocalVarDecl() const
Returns true for local variable declarations other than parameters.
bool isUsableInConstantExpressions(const ASTContext &C) const
Determine whether this variable's value can be used in a constant expression, according to the releva...
const Expr * getAnyInitializer() const
Get the initializer for this variable, no matter which declaration it is attached to.
Expr * getSizeExpr() const
Represents a GCC generic vector type.
unsigned getNumElements() const
QualType getElementType() const
WhileStmt - This represents a 'while' stmt.
VarDecl * getConditionVariable()
Retrieve the variable declared in this "while" statement, if any.
bool evaluateCharRange(State &Parent, const Expr *SizeExpr, const Expr *PtrExpr, APValue &Result)
bool evaluateString(State &Parent, const Expr *E, std::string &Result)
Evaluate.
bool evaluateStrlen(State &Parent, const Expr *E, uint64_t &Result)
Evalute.
void isPotentialConstantExprUnevaluated(State &Parent, const Expr *E, const FunctionDecl *FD)
bool isPotentialConstantExpr(State &Parent, const FunctionDecl *FD)
Checks if a function is a potential constant expression.
bool evaluateAsRValue(State &Parent, const Expr *E, APValue &Result)
Evaluates a toplevel expression as an rvalue.
bool evaluate(State &Parent, const Expr *E, APValue &Result, ConstantExprKind Kind)
Like evaluateAsRvalue(), but does no implicit lvalue-to-rvalue conversion.
Base class for stack frames, shared between VM and walker.
Interface for the VM to interact with the AST walker's context.
Defines the clang::TargetInfo interface.
bool computeOSLogBufferLayout(clang::ASTContext &Ctx, const clang::CallExpr *E, OSLogBufferLayout &layout)
static const FunctionDecl * getCallee(const CXXConstructExpr &D)
uint32_t Literal
Literals are represented as positive integers.
unsigned kind
All of the diagnostics that can be emitted by the frontend.
std::optional< llvm::AllocTokenMetadata > getAllocTokenMetadata(QualType T, const ASTContext &Ctx)
Get the information required for construction of an allocation token ID.
QualType inferPossibleType(const CallExpr *E, const ASTContext &Ctx, const CastExpr *CastE)
Infer the possible allocated type from an allocation call expression.
bool NE(InterpState &S, CodePtr OpPC)
llvm::FixedPointSemantics FixedPointSemantics
bool This(InterpState &S, CodePtr OpPC)
bool Alloc(InterpState &S, CodePtr OpPC, const Descriptor *Desc)
std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl
All declarations that can appear in a module declaration.
AccessKind
This enum distinguishes between different ways to access (read or write) a variable.
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
bool isa(CodeGen::Address addr)
bool hasSpecificAttr(const Container &container)
@ NonNull
Values of this type can never be null.
@ Success
Annotation was successful.
Expr::ConstantExprKind ConstantExprKind
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
bool operator==(const CallGraphNode::CallRecord &LHS, const CallGraphNode::CallRecord &RHS)
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
bool isLambdaCallWithExplicitObjectParameter(const DeclContext *DC)
UnaryExprOrTypeTrait
Names for the "expression or type" traits.
ComparisonCategoryResult
An enumeration representing the possible results of a three-way comparison.
CheckSubobjectKind
The order of this enum is important for diagnostics.
@ SD_Static
Static storage duration.
@ SD_FullExpression
Full-expression storage duration (for temporaries).
bool isLambdaCallOperator(const CXXMethodDecl *MD)
@ Result
The result type of a method or function.
AccessKinds
Kinds of access we can perform on an object, for diagnostics.
@ AK_ReadObjectRepresentation
const FunctionProtoType * T
@ Type
The name was classified as a type.
CastKind
CastKind - The kind of operation required for a conversion.
llvm::hash_code hash_value(const CustomizableOptional< T > &O)
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs.
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
@ ConstantFold
Fold the expression to a constant.
@ ConstantExpressionUnevaluated
Evaluate as a constant expression.
@ ConstantExpression
Evaluate as a constant expression.
@ IgnoreSideEffects
Evaluate in any way we know how.
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
U cast(CodeGen::Address addr)
@ None
The alignment was not explicit in code.
@ ArrayBound
Array bound in array declarator or new-expression.
@ Class
The "class" keyword introduces the elaborated-type-specifier.
ActionResult< Expr * > ExprResult
@ Other
Other implicit parameter.
ActionResult< Stmt * > StmtResult
Diagnostic wrappers for TextAPI types for error reporting.
hash_code hash_value(const clang::dependencies::ModuleID &ID)
unsigned PathLength
The corresponding path length in the lvalue.
const CXXRecordDecl * Type
The dynamic class type of the object.
std::string ObjCEncodeStorage
Represents an element in a path from a derived class to a base class.
EvalResult is a struct with detailed info about an evaluated expression.
APValue Val
Val - This is the value the expression can be folded to.
bool isGlobalLValue() const
Return true if the evaluated lvalue expression is global.
EvalStatus is a struct with detailed info about an evaluation in progress.
SmallVectorImpl< PartialDiagnosticAt > * Diag
Diag - If this is non-null, it will be filled in with a stack of notes indicating why evaluation fail...
bool HasSideEffects
Whether the evaluated expression has side effects.
@ DerivedToBaseAdjustment
@ MemberPointerAdjustment
static ObjectUnderConstruction getTombstoneKey()
DenseMapInfo< APValue::LValueBase > Base
static ObjectUnderConstruction getEmptyKey()
static unsigned getHashValue(const ObjectUnderConstruction &Object)
static bool isEqual(const ObjectUnderConstruction &LHS, const ObjectUnderConstruction &RHS)