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 unsigned ArgIndex = 0;
1985 if (This && IsMemberCall) {
1986 if (
const auto *MCE = dyn_cast_if_present<CXXMemberCallExpr>(CallExpr)) {
1987 const Expr *
Object = MCE->getImplicitObjectArgument();
1990 if (
Object->getType()->isPointerType())
1994 }
else if (
const auto *OCE =
1995 dyn_cast_if_present<CXXOperatorCallExpr>(CallExpr)) {
1996 OCE->getArg(0)->printPretty(Out,
nullptr,
2002 This->moveInto(Val);
2010 IsMemberCall =
false;
2016 E =
Callee->param_end(); I != E; ++I, ++ArgIndex) {
2017 if (ArgIndex > (
unsigned)IsMemberCall)
2020 const ParmVarDecl *Param = *I;
2021 APValue *
V = Info.getParamSlot(Arguments, Param);
2023 V->printPretty(Out, Info.Ctx, Param->
getType());
2027 if (ArgIndex == 0 && IsMemberCall)
2042 return Info.noteSideEffect();
2049 return (
Builtin == Builtin::BI__builtin___CFStringMakeConstantString ||
2050 Builtin == Builtin::BI__builtin___NSStringMakeConstantString ||
2051 Builtin == Builtin::BI__builtin_ptrauth_sign_constant ||
2052 Builtin == Builtin::BI__builtin_function_start);
2056 const auto *BaseExpr =
2057 llvm::dyn_cast_if_present<CallExpr>(LVal.Base.
dyn_cast<
const Expr *>());
2072 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
2073 return VD->hasGlobalStorage();
2089 case Expr::CompoundLiteralExprClass: {
2093 case Expr::MaterializeTemporaryExprClass:
2098 case Expr::StringLiteralClass:
2099 case Expr::PredefinedExprClass:
2100 case Expr::ObjCStringLiteralClass:
2101 case Expr::ObjCEncodeExprClass:
2103 case Expr::ObjCBoxedExprClass:
2105 case Expr::CallExprClass:
2108 case Expr::AddrLabelExprClass:
2112 case Expr::BlockExprClass:
2116 case Expr::SourceLocExprClass:
2118 case Expr::ImplicitValueInitExprClass:
2143 const auto *BaseExpr = LVal.Base.
dyn_cast<
const Expr *>();
2148 if (
const auto *EE = dyn_cast<ObjCEncodeExpr>(BaseExpr)) {
2157 const auto *Lit = dyn_cast<StringLiteral>(BaseExpr);
2158 if (
const auto *PE = dyn_cast<PredefinedExpr>(BaseExpr))
2159 Lit = PE->getFunctionName();
2164 AsString.
Bytes = Lit->getBytes();
2165 AsString.
CharWidth = Lit->getCharByteWidth();
2185 const LValue &RHS) {
2194 CharUnits Offset = RHS.Offset - LHS.Offset;
2195 if (Offset.isNegative()) {
2196 if (LHSString.
Bytes.size() < (
size_t)-Offset.getQuantity())
2198 LHSString.
Bytes = LHSString.
Bytes.drop_front(-Offset.getQuantity());
2200 if (RHSString.
Bytes.size() < (
size_t)Offset.getQuantity())
2202 RHSString.
Bytes = RHSString.
Bytes.drop_front(Offset.getQuantity());
2205 bool LHSIsLonger = LHSString.
Bytes.size() > RHSString.
Bytes.size();
2206 StringRef Longer = LHSIsLonger ? LHSString.
Bytes : RHSString.
Bytes;
2207 StringRef Shorter = LHSIsLonger ? RHSString.
Bytes : LHSString.
Bytes;
2208 int ShorterCharWidth = (LHSIsLonger ? RHSString : LHSString).CharWidth;
2213 for (
int NullByte : llvm::seq(ShorterCharWidth)) {
2214 if (Shorter.size() + NullByte >= Longer.size())
2216 if (Longer[Shorter.size() + NullByte])
2222 return Shorter == Longer.take_front(Shorter.size());
2232 if (isa_and_nonnull<VarDecl>(
Decl)) {
2242 if (!A.getLValueBase())
2243 return !B.getLValueBase();
2244 if (!B.getLValueBase())
2247 if (A.getLValueBase().getOpaqueValue() !=
2248 B.getLValueBase().getOpaqueValue())
2251 return A.getLValueCallIndex() == B.getLValueCallIndex() &&
2252 A.getLValueVersion() == B.getLValueVersion();
2256 assert(
Base &&
"no location for a null lvalue");
2262 if (
auto *PVD = dyn_cast_or_null<ParmVarDecl>(VD)) {
2264 for (CallStackFrame *F = Info.CurrentCall; F; F = F->Caller) {
2265 if (F->Arguments.CallIndex ==
Base.getCallIndex() &&
2266 F->Arguments.Version ==
Base.getVersion() && F->Callee &&
2267 Idx < F->Callee->getNumParams()) {
2268 VD = F->Callee->getParamDecl(Idx);
2275 Info.Note(VD->
getLocation(), diag::note_declared_at);
2277 Info.Note(E->
getExprLoc(), diag::note_constexpr_temporary_here);
2280 if (std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA))
2281 Info.Note((*Alloc)->AllocExpr->getExprLoc(),
2282 diag::note_constexpr_dynamic_alloc_here);
2315 const SubobjectDesignator &
Designator = LVal.getLValueDesignator();
2323 if (isTemplateArgument(Kind)) {
2324 int InvalidBaseKind = -1;
2327 InvalidBaseKind = 0;
2328 else if (isa_and_nonnull<StringLiteral>(BaseE))
2329 InvalidBaseKind = 1;
2330 else if (isa_and_nonnull<MaterializeTemporaryExpr>(BaseE) ||
2331 isa_and_nonnull<LifetimeExtendedTemporaryDecl>(BaseVD))
2332 InvalidBaseKind = 2;
2333 else if (
auto *PE = dyn_cast_or_null<PredefinedExpr>(BaseE)) {
2334 InvalidBaseKind = 3;
2335 Ident = PE->getIdentKindName();
2338 if (InvalidBaseKind != -1) {
2339 Info.FFDiag(Loc, diag::note_constexpr_invalid_template_arg)
2340 << IsReferenceType << !
Designator.Entries.empty() << InvalidBaseKind
2346 if (
auto *FD = dyn_cast_or_null<FunctionDecl>(BaseVD);
2347 FD && FD->isImmediateFunction()) {
2348 Info.FFDiag(Loc, diag::note_consteval_address_accessible)
2350 Info.Note(FD->getLocation(), diag::note_declared_at);
2358 if (Info.getLangOpts().CPlusPlus11) {
2359 Info.FFDiag(Loc, diag::note_constexpr_non_global, 1)
2360 << IsReferenceType << !
Designator.Entries.empty() << !!BaseVD
2362 auto *VarD = dyn_cast_or_null<VarDecl>(BaseVD);
2363 if (VarD && VarD->isConstexpr()) {
2369 Info.Note(VarD->getLocation(), diag::note_constexpr_not_static)
2381 assert((Info.checkingPotentialConstantExpression() ||
2382 LVal.getLValueCallIndex() == 0) &&
2383 "have call index for global lvalue");
2385 if (LVal.allowConstexprUnknown()) {
2387 Info.FFDiag(Loc, diag::note_constexpr_var_init_non_constant, 1) << BaseVD;
2396 Info.FFDiag(Loc, diag::note_constexpr_dynamic_alloc)
2397 << IsReferenceType << !
Designator.Entries.empty();
2403 if (
const VarDecl *Var = dyn_cast<const VarDecl>(BaseVD)) {
2405 if (Var->getTLSKind())
2411 if (!isForManglingOnly(Kind) && Var->hasAttr<DLLImportAttr>())
2417 if (Info.getASTContext().getLangOpts().CUDA &&
2418 Info.getASTContext().getLangOpts().CUDAIsDevice &&
2419 Info.getASTContext().CUDAConstantEvalCtx.NoWrongSidedVars) {
2420 if ((!Var->hasAttr<CUDADeviceAttr>() &&
2421 !Var->hasAttr<CUDAConstantAttr>() &&
2422 !Var->getType()->isCUDADeviceBuiltinSurfaceType() &&
2423 !Var->getType()->isCUDADeviceBuiltinTextureType()) ||
2424 Var->hasAttr<HIPManagedAttr>())
2428 if (
const auto *FD = dyn_cast<const FunctionDecl>(BaseVD)) {
2439 if (Info.getLangOpts().CPlusPlus && !isForManglingOnly(Kind) &&
2440 FD->hasAttr<DLLImportAttr>())
2444 }
else if (
const auto *MTE =
2445 dyn_cast_or_null<MaterializeTemporaryExpr>(BaseE)) {
2446 if (CheckedTemps.insert(MTE).second) {
2449 Info.FFDiag(MTE->getExprLoc(),
2450 diag::note_constexpr_unsupported_temporary_nontrivial_dtor)
2455 APValue *
V = MTE->getOrCreateValue(
false);
2456 assert(
V &&
"evasluation result refers to uninitialised temporary");
2458 Info, MTE->getExprLoc(), TempType, *
V, Kind,
2459 nullptr, CheckedTemps))
2466 if (!IsReferenceType)
2478 Info.FFDiag(Loc, diag::note_constexpr_past_end, 1)
2479 << !
Designator.Entries.empty() << !!BaseVD << BaseVD;
2494 const auto *FD = dyn_cast_or_null<CXXMethodDecl>(
Member);
2497 if (FD->isImmediateFunction()) {
2498 Info.FFDiag(Loc, diag::note_consteval_address_accessible) << 0;
2499 Info.Note(FD->getLocation(), diag::note_declared_at);
2502 return isForManglingOnly(Kind) || FD->isVirtual() ||
2503 !FD->hasAttr<DLLImportAttr>();
2509 const LValue *
This =
nullptr) {
2511 if (Info.getLangOpts().CPlusPlus23)
2530 if (
This && Info.EvaluatingDecl ==
This->getLValueBase())
2534 if (Info.getLangOpts().CPlusPlus11)
2535 Info.FFDiag(E, diag::note_constexpr_nonliteral)
2538 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
2549 if (SubobjectDecl) {
2550 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
2551 << 1 << SubobjectDecl;
2553 diag::note_constexpr_subobject_declared_here);
2555 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
2564 Type = AT->getValueType();
2569 if (
Value.isArray()) {
2571 for (
unsigned I = 0, N =
Value.getArrayInitializedElts(); I != N; ++I) {
2573 Value.getArrayInitializedElt(I), Kind,
2574 SubobjectDecl, CheckedTemps))
2577 if (!
Value.hasArrayFiller())
2580 Value.getArrayFiller(), Kind, SubobjectDecl,
2583 if (
Value.isUnion() &&
Value.getUnionField()) {
2586 Value.getUnionValue(), Kind,
Value.getUnionField(), CheckedTemps);
2588 if (
Value.isStruct()) {
2590 if (
const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {
2591 unsigned BaseIndex = 0;
2593 const APValue &BaseValue =
Value.getStructBase(BaseIndex);
2596 Info.FFDiag(TypeBeginLoc, diag::note_constexpr_uninitialized_base)
2597 << BS.getType() <<
SourceRange(TypeBeginLoc, BS.getEndLoc());
2607 for (
const auto *I : RD->fields()) {
2608 if (I->isUnnamedBitField())
2612 Value.getStructField(I->getFieldIndex()), Kind,
2618 if (
Value.isLValue() &&
2621 LVal.setFrom(Info.Ctx,
Value);
2626 if (
Value.isMemberPointer() &&
2647 nullptr, CheckedTemps);
2657 ConstantExprKind::Normal,
nullptr, CheckedTemps);
2663 if (!Info.HeapAllocs.empty()) {
2667 Info.CCEDiag(Info.HeapAllocs.begin()->second.AllocExpr,
2668 diag::note_constexpr_memory_leak)
2669 <<
unsigned(Info.HeapAllocs.size() - 1);
2677 if (!
Value.getLValueBase()) {
2679 Result = !
Value.getLValueOffset().isZero();
2697 Result = Val.
getInt().getBoolValue();
2729 llvm_unreachable(
"unknown APValue kind");
2735 assert(E->
isPRValue() &&
"missing lvalue-to-rvalue conv in bool condition");
2745 Info.CCEDiag(E, diag::note_constexpr_overflow)
2746 << SrcValue << DestType;
2747 return Info.noteUndefinedBehavior();
2753 unsigned DestWidth = Info.Ctx.
getIntWidth(DestType);
2757 Result =
APSInt(DestWidth, !DestSigned);
2759 if (
Value.convertToInteger(Result, llvm::APFloat::rmTowardZero, &ignored)
2760 & APFloat::opInvalidOp)
2771 llvm::RoundingMode RM =
2773 if (RM == llvm::RoundingMode::Dynamic)
2774 RM = llvm::RoundingMode::NearestTiesToEven;
2780 APFloat::opStatus St) {
2783 if (Info.InConstantContext)
2787 if ((St & APFloat::opInexact) &&
2791 Info.FFDiag(E, diag::note_constexpr_dynamic_rounding);
2795 if ((St != APFloat::opOK) &&
2798 FPO.getAllowFEnvAccess())) {
2799 Info.FFDiag(E, diag::note_constexpr_float_arithmetic_strict);
2803 if ((St & APFloat::opStatus::opInvalidOp) &&
2824 "HandleFloatToFloatCast has been checked with only CastExpr, "
2825 "CompoundAssignOperator and ConvertVectorExpr. Please either validate "
2826 "the new expression or address the root cause of this usage.");
2828 APFloat::opStatus St;
2829 APFloat
Value = Result;
2838 unsigned DestWidth = Info.Ctx.
getIntWidth(DestType);
2844 Result =
Value.getBoolValue();
2851 QualType DestType, APFloat &Result) {
2854 APFloat::opStatus St = Result.convertFromAPInt(
Value,
Value.isSigned(), RM);
2860 assert(FD->
isBitField() &&
"truncateBitfieldValue on non-bitfield");
2862 if (!
Value.isInt()) {
2866 assert(
Value.isLValue() &&
"integral value neither int nor lvalue?");
2872 unsigned OldBitWidth = Int.getBitWidth();
2874 if (NewBitWidth < OldBitWidth)
2875 Int = Int.trunc(NewBitWidth).extend(OldBitWidth);
2882template<
typename Operation>
2885 unsigned BitWidth, Operation Op,
2887 if (LHS.isUnsigned()) {
2888 Result = Op(LHS, RHS);
2892 APSInt Value(Op(LHS.extend(BitWidth), RHS.extend(BitWidth)),
false);
2893 Result =
Value.trunc(LHS.getBitWidth());
2894 if (Result.extend(BitWidth) !=
Value) {
2895 if (Info.checkingForUndefinedBehavior())
2897 diag::warn_integer_constant_overflow)
2898 <<
toString(Result, 10, Result.isSigned(),
false,
2910 bool HandleOverflowResult =
true;
2917 std::multiplies<APSInt>(), Result);
2920 std::plus<APSInt>(), Result);
2923 std::minus<APSInt>(), Result);
2924 case BO_And: Result = LHS & RHS;
return true;
2925 case BO_Xor: Result = LHS ^ RHS;
return true;
2926 case BO_Or: Result = LHS | RHS;
return true;
2930 Info.FFDiag(E, diag::note_expr_divide_by_zero)
2936 if (RHS.isNegative() && RHS.isAllOnes() && LHS.isSigned() &&
2937 LHS.isMinSignedValue())
2939 Info, E, -LHS.extend(LHS.getBitWidth() + 1), E->
getType());
2940 Result = (Opcode == BO_Rem ? LHS % RHS : LHS / RHS);
2941 return HandleOverflowResult;
2943 if (Info.getLangOpts().OpenCL)
2945 RHS &=
APSInt(llvm::APInt(RHS.getBitWidth(),
2946 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2948 else if (RHS.isSigned() && RHS.isNegative()) {
2951 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
2952 if (!Info.noteUndefinedBehavior())
2960 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
2962 Info.CCEDiag(E, diag::note_constexpr_large_shift)
2963 << RHS << E->
getType() << LHS.getBitWidth();
2964 if (!Info.noteUndefinedBehavior())
2966 }
else if (LHS.isSigned() && !Info.getLangOpts().CPlusPlus20) {
2971 if (LHS.isNegative()) {
2972 Info.CCEDiag(E, diag::note_constexpr_lshift_of_negative) << LHS;
2973 if (!Info.noteUndefinedBehavior())
2975 }
else if (LHS.countl_zero() < SA) {
2976 Info.CCEDiag(E, diag::note_constexpr_lshift_discards);
2977 if (!Info.noteUndefinedBehavior())
2985 if (Info.getLangOpts().OpenCL)
2987 RHS &=
APSInt(llvm::APInt(RHS.getBitWidth(),
2988 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2990 else if (RHS.isSigned() && RHS.isNegative()) {
2993 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
2994 if (!Info.noteUndefinedBehavior())
3002 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
3004 Info.CCEDiag(E, diag::note_constexpr_large_shift)
3005 << RHS << E->
getType() << LHS.getBitWidth();
3006 if (!Info.noteUndefinedBehavior())
3014 case BO_LT: Result = LHS < RHS;
return true;
3015 case BO_GT: Result = LHS > RHS;
return true;
3016 case BO_LE: Result = LHS <= RHS;
return true;
3017 case BO_GE: Result = LHS >= RHS;
return true;
3018 case BO_EQ: Result = LHS == RHS;
return true;
3019 case BO_NE: Result = LHS != RHS;
return true;
3021 llvm_unreachable(
"BO_Cmp should be handled elsewhere");
3028 const APFloat &RHS) {
3030 APFloat::opStatus St;
3036 St = LHS.multiply(RHS, RM);
3039 St = LHS.add(RHS, RM);
3042 St = LHS.subtract(RHS, RM);
3048 Info.CCEDiag(E, diag::note_expr_divide_by_zero);
3049 St = LHS.divide(RHS, RM);
3058 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << LHS.isNaN();
3059 return Info.noteUndefinedBehavior();
3067 const APInt &RHSValue, APInt &Result) {
3068 bool LHS = (LHSValue != 0);
3069 bool RHS = (RHSValue != 0);
3071 if (Opcode == BO_LAnd)
3072 Result = LHS && RHS;
3074 Result = LHS || RHS;
3079 const APFloat &RHSValue, APInt &Result) {
3080 bool LHS = !LHSValue.isZero();
3081 bool RHS = !RHSValue.isZero();
3083 if (Opcode == BO_LAnd)
3084 Result = LHS && RHS;
3086 Result = LHS || RHS;
3092 const APValue &RHSValue, APInt &Result) {
3096 RHSValue.
getInt(), Result);
3102template <
typename APTy>
3105 const APTy &RHSValue, APInt &Result) {
3108 llvm_unreachable(
"unsupported binary operator");
3110 Result = (LHSValue == RHSValue);
3113 Result = (LHSValue != RHSValue);
3116 Result = (LHSValue < RHSValue);
3119 Result = (LHSValue > RHSValue);
3122 Result = (LHSValue <= RHSValue);
3125 Result = (LHSValue >= RHSValue);
3139 const APValue &RHSValue, APInt &Result) {
3143 RHSValue.
getInt(), Result);
3154 assert(Opcode != BO_PtrMemD && Opcode != BO_PtrMemI &&
3155 "Operation not supported on vector types");
3159 QualType EltTy = VT->getElementType();
3166 "A vector result that isn't a vector OR uncalculated LValue");
3172 RHSValue.
getVectorLength() == NumElements &&
"Different vector sizes");
3176 for (
unsigned EltNum = 0; EltNum < NumElements; ++EltNum) {
3191 RHSElt.
getInt(), EltResult);
3197 ResultElements.emplace_back(EltResult);
3202 "Mismatched LHS/RHS/Result Type");
3203 APFloat LHSFloat = LHSElt.
getFloat();
3211 ResultElements.emplace_back(LHSFloat);
3215 LHSValue =
APValue(ResultElements.data(), ResultElements.size());
3223 unsigned TruncatedElements) {
3224 SubobjectDesignator &D = Result.Designator;
3227 if (TruncatedElements == D.Entries.size())
3229 assert(TruncatedElements >= D.MostDerivedPathLength &&
3230 "not casting to a derived class");
3236 for (
unsigned I = TruncatedElements, N = D.Entries.size(); I != N; ++I) {
3240 if (isVirtualBaseClass(D.Entries[I]))
3246 D.Entries.resize(TruncatedElements);
3259 Obj.addDecl(Info, E,
Base,
false);
3260 Obj.getLValueOffset() += RL->getBaseClassOffset(
Base);
3269 if (!
Base->isVirtual())
3272 SubobjectDesignator &D = Obj.Designator;
3288 Obj.addDecl(Info, E, BaseDecl,
true);
3297 PathI != PathE; ++PathI) {
3301 Type = (*PathI)->getType();
3313 llvm_unreachable(
"Class must be derived from the passed in base class!");
3332 LVal.addDecl(Info, E, FD);
3341 for (
const auto *
C : IFD->
chain())
3394 LVal.adjustOffsetAndIndex(Info, E, Adjustment, SizeOfPointee);
3400 int64_t Adjustment) {
3402 APSInt::get(Adjustment));
3417 LVal.Offset += SizeOfComponent;
3419 LVal.addComplex(Info, E, EltTy, Imag);
3425 uint64_t Size, uint64_t Idx) {
3430 LVal.Offset += SizeOfElement * Idx;
3432 LVal.addVectorElement(Info, E, EltTy, Size, Idx);
3446 const VarDecl *VD, CallStackFrame *Frame,
3447 unsigned Version,
APValue *&Result) {
3450 bool AllowConstexprUnknown =
3455 auto CheckUninitReference = [&](
bool IsLocalVariable) {
3467 if (!AllowConstexprUnknown || IsLocalVariable) {
3468 if (!Info.checkingPotentialConstantExpression())
3469 Info.FFDiag(E, diag::note_constexpr_use_uninit_reference);
3479 Result = Frame->getTemporary(VD, Version);
3481 return CheckUninitReference(
true);
3490 "missing value for local variable");
3491 if (Info.checkingPotentialConstantExpression())
3496 diag::note_unimplemented_constexpr_lambda_feature_ast)
3497 <<
"captures not currently allowed";
3504 if (Info.EvaluatingDecl ==
Base) {
3505 Result = Info.EvaluatingDeclValue;
3506 return CheckUninitReference(
false);
3514 if (AllowConstexprUnknown) {
3521 if (!Info.checkingPotentialConstantExpression() ||
3522 !Info.CurrentCall->Callee ||
3524 if (Info.getLangOpts().CPlusPlus11) {
3525 Info.FFDiag(E, diag::note_constexpr_function_param_value_unknown)
3546 if (!
Init && !AllowConstexprUnknown) {
3549 if (!Info.checkingPotentialConstantExpression()) {
3550 Info.FFDiag(E, diag::note_constexpr_var_init_unknown, 1)
3561 if (
Init &&
Init->isValueDependent()) {
3568 if (!Info.checkingPotentialConstantExpression()) {
3569 Info.FFDiag(E, Info.getLangOpts().CPlusPlus11
3570 ? diag::note_constexpr_ltor_non_constexpr
3571 : diag::note_constexpr_ltor_non_integral, 1)
3585 Info.FFDiag(E, diag::note_constexpr_var_init_non_constant, 1) << VD;
3601 !AllowConstexprUnknown) ||
3602 ((Info.getLangOpts().CPlusPlus || Info.getLangOpts().OpenCL) &&
3605 Info.CCEDiag(E, diag::note_constexpr_var_init_non_constant, 1) << VD;
3615 Info.FFDiag(E, diag::note_constexpr_var_init_weak) << VD;
3622 if (!Result && !AllowConstexprUnknown)
3625 return CheckUninitReference(
false);
3635 E = Derived->
bases_end(); I != E; ++I, ++Index) {
3636 if (I->getType()->getAsCXXRecordDecl()->getCanonicalDecl() ==
Base)
3640 llvm_unreachable(
"base class missing from derived class's bases list");
3647 "SourceLocExpr should have already been converted to a StringLiteral");
3650 if (
const auto *ObjCEnc = dyn_cast<ObjCEncodeExpr>(Lit)) {
3653 assert(Index <= Str.size() &&
"Index too large");
3654 return APSInt::getUnsigned(Str.c_str()[Index]);
3657 if (
auto PE = dyn_cast<PredefinedExpr>(Lit))
3658 Lit = PE->getFunctionName();
3662 assert(CAT &&
"string literal isn't an array");
3664 assert(CharType->
isIntegerType() &&
"unexpected character type");
3667 if (Index < S->getLength())
3680 AllocType.isNull() ? S->
getType() : AllocType);
3681 assert(CAT &&
"string literal isn't an array");
3683 assert(CharType->
isIntegerType() &&
"unexpected character type");
3690 if (Result.hasArrayFiller())
3692 for (
unsigned I = 0, N = Result.getArrayInitializedElts(); I != N; ++I) {
3700 unsigned Size = Array.getArraySize();
3701 assert(Index < Size);
3704 unsigned OldElts = Array.getArrayInitializedElts();
3705 unsigned NewElts = std::max(Index+1, OldElts * 2);
3706 NewElts = std::min(Size, std::max(NewElts, 8u));
3710 for (
unsigned I = 0; I != OldElts; ++I)
3712 for (
unsigned I = OldElts; I != NewElts; ++I)
3716 Array.
swap(NewValue);
3726 CXXRecordDecl *RD =
T->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
3737 for (
auto *Field : RD->
fields())
3738 if (!Field->isUnnamedBitField() &&
3742 for (
auto &BaseSpec : RD->
bases())
3753 CXXRecordDecl *RD =
T->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
3760 for (
auto *Field : RD->
fields()) {
3765 if (Field->isMutable() &&
3767 Info.FFDiag(E, diag::note_constexpr_access_mutable, 1) << AK << Field;
3768 Info.Note(Field->getLocation(), diag::note_declared_at);
3776 for (
auto &BaseSpec : RD->
bases())
3786 bool MutableSubobject =
false) {
3791 switch (Info.IsEvaluatingDecl) {
3792 case EvalInfo::EvaluatingDeclKind::None:
3795 case EvalInfo::EvaluatingDeclKind::Ctor:
3797 if (Info.EvaluatingDecl ==
Base)
3802 if (
auto *BaseE =
Base.dyn_cast<
const Expr *>())
3803 if (
auto *BaseMTE = dyn_cast<MaterializeTemporaryExpr>(BaseE))
3804 return Info.EvaluatingDecl == BaseMTE->getExtendingDecl();
3807 case EvalInfo::EvaluatingDeclKind::Dtor:
3812 if (MutableSubobject ||
Base != Info.EvaluatingDecl)
3818 return T.isConstQualified() ||
T->isReferenceType();
3821 llvm_unreachable(
"unknown evaluating decl kind");
3826 return Info.CheckArraySize(
3846 uint64_t IntResult = BoolResult;
3856 Result.getInt(), DestTy, Result2.
getFloat()))
3864 Result =
APValue(APFloat(0.0));
3866 DestTy, Result.getFloat());
3872 uint64_t IntResult = BoolResult;
3891 uint64_t IntResult = BoolResult;
3898 DestTy, Result.getInt());
3902 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
3915 {&Result, ResultType, 0}};
3918 while (!WorkList.empty() && ElI < Elements.size()) {
3919 auto [Res,
Type, BitWidth] = WorkList.pop_back_val();
3935 APSInt &Int = Res->getInt();
3936 unsigned OldBitWidth = Int.getBitWidth();
3937 unsigned NewBitWidth = BitWidth;
3938 if (NewBitWidth < OldBitWidth)
3939 Int = Int.trunc(NewBitWidth).extend(OldBitWidth);
3948 for (
unsigned I = 0; I < NumEl; ++I) {
3954 *Res =
APValue(Vals.data(), NumEl);
3963 for (int64_t I = Size - 1; I > -1; --I)
3964 WorkList.emplace_back(&Res->getArrayInitializedElt(I), ElTy, 0u);
3970 unsigned NumBases = 0;
3971 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
3972 NumBases = CXXRD->getNumBases();
3979 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
3980 if (CXXRD->getNumBases() > 0) {
3981 assert(CXXRD->getNumBases() == 1);
3983 ReverseList.emplace_back(&Res->getStructBase(0), BS.
getType(), 0u);
3990 if (FD->isUnnamedBitField())
3992 if (FD->isBitField()) {
3993 FDBW = FD->getBitWidthValue();
3996 ReverseList.emplace_back(&Res->getStructField(FD->getFieldIndex()),
3997 FD->getType(), FDBW);
4000 std::reverse(ReverseList.begin(), ReverseList.end());
4001 llvm::append_range(WorkList, ReverseList);
4004 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
4017 assert((Elements.size() == SrcTypes.size()) &&
4018 (Elements.size() == DestTypes.size()));
4020 for (
unsigned I = 0, ESz = Elements.size(); I < ESz; ++I) {
4021 APValue Original = Elements[I];
4025 if (!
handleScalarCast(Info, FPO, E, SourceTy, DestTy, Original, Results[I]))
4036 while (!WorkList.empty()) {
4053 for (uint64_t I = 0; I < ArrSize; ++I) {
4054 WorkList.push_back(ElTy);
4062 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4063 if (CXXRD->getNumBases() > 0) {
4064 assert(CXXRD->getNumBases() == 1);
4066 WorkList.push_back(BS.
getType());
4072 if (FD->isUnnamedBitField())
4074 WorkList.push_back(FD->getType());
4091 "Not a valid HLSLAggregateSplatCast.");
4106 unsigned Populated = 0;
4107 while (!WorkList.empty() && Populated < Size) {
4108 auto [Work,
Type] = WorkList.pop_back_val();
4110 if (Work.isFloat() || Work.isInt()) {
4111 Elements.push_back(Work);
4112 Types.push_back(
Type);
4116 if (Work.isVector()) {
4119 for (
unsigned I = 0; I < Work.getVectorLength() && Populated < Size;
4121 Elements.push_back(Work.getVectorElt(I));
4122 Types.push_back(ElTy);
4127 if (Work.isArray()) {
4131 for (int64_t I = Work.getArraySize() - 1; I > -1; --I) {
4132 WorkList.emplace_back(Work.getArrayInitializedElt(I), ElTy);
4137 if (Work.isStruct()) {
4145 if (FD->isUnnamedBitField())
4147 ReverseList.emplace_back(Work.getStructField(FD->getFieldIndex()),
4151 std::reverse(ReverseList.begin(), ReverseList.end());
4152 llvm::append_range(WorkList, ReverseList);
4155 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4156 if (CXXRD->getNumBases() > 0) {
4157 assert(CXXRD->getNumBases() == 1);
4162 if (!
Base.isStruct())
4170 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
4179struct CompleteObject {
4181 APValue::LValueBase
Base;
4191 bool mayAccessMutableMembers(EvalInfo &Info,
AccessKinds AK)
const {
4202 if (!Info.getLangOpts().CPlusPlus14 &&
4203 AK != AccessKinds::AK_IsWithinLifetime)
4208 explicit operator bool()
const {
return !
Type.isNull(); }
4213 bool IsMutable =
false) {
4227template <
typename Sub
objectHandler>
4228static typename SubobjectHandler::result_type
4230 const SubobjectDesignator &Sub, SubobjectHandler &handler) {
4233 return handler.failed();
4234 if (Sub.isOnePastTheEnd() || Sub.isMostDerivedAnUnsizedArray()) {
4235 if (Info.getLangOpts().CPlusPlus11)
4236 Info.FFDiag(E, Sub.isOnePastTheEnd()
4237 ? diag::note_constexpr_access_past_end
4238 : diag::note_constexpr_access_unsized_array)
4239 << handler.AccessKind;
4242 return handler.failed();
4248 const FieldDecl *VolatileField =
nullptr;
4251 for (
unsigned I = 0, N = Sub.Entries.size(); ; ++I) {
4262 if (!Info.checkingPotentialConstantExpression())
4263 Info.FFDiag(E, diag::note_constexpr_access_uninit)
4266 return handler.failed();
4274 Info.isEvaluatingCtorDtor(
4275 Obj.Base,
ArrayRef(Sub.Entries.begin(), Sub.Entries.begin() + I)) !=
4276 ConstructionPhase::None) {
4286 if (Info.getLangOpts().CPlusPlus) {
4290 if (VolatileField) {
4293 Decl = VolatileField;
4296 Loc = VD->getLocation();
4303 Info.FFDiag(E, diag::note_constexpr_access_volatile_obj, 1)
4304 << handler.AccessKind << DiagKind <<
Decl;
4305 Info.Note(Loc, diag::note_constexpr_volatile_here) << DiagKind;
4307 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
4309 return handler.failed();
4317 !Obj.mayAccessMutableMembers(Info, handler.AccessKind) &&
4319 return handler.failed();
4323 if (!handler.found(*O, ObjType))
4335 LastField =
nullptr;
4340 "vla in literal type?");
4341 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4342 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT);
4343 CAT && CAT->
getSize().ule(Index)) {
4346 if (Info.getLangOpts().CPlusPlus11)
4347 Info.FFDiag(E, diag::note_constexpr_access_past_end)
4348 << handler.AccessKind;
4351 return handler.failed();
4358 else if (!
isRead(handler.AccessKind)) {
4359 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT);
4361 return handler.failed();
4369 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4371 if (Info.getLangOpts().CPlusPlus11)
4372 Info.FFDiag(E, diag::note_constexpr_access_past_end)
4373 << handler.AccessKind;
4376 return handler.failed();
4382 assert(I == N - 1 &&
"extracting subobject of scalar?");
4392 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4393 unsigned NumElements = VT->getNumElements();
4394 if (Index == NumElements) {
4395 if (Info.getLangOpts().CPlusPlus11)
4396 Info.FFDiag(E, diag::note_constexpr_access_past_end)
4397 << handler.AccessKind;
4400 return handler.failed();
4403 if (Index > NumElements) {
4404 Info.CCEDiag(E, diag::note_constexpr_array_index)
4405 << Index << 0 << NumElements;
4406 return handler.failed();
4409 ObjType = VT->getElementType();
4410 assert(I == N - 1 &&
"extracting subobject of scalar?");
4412 }
else if (
const FieldDecl *Field = getAsField(Sub.Entries[I])) {
4413 if (Field->isMutable() &&
4414 !Obj.mayAccessMutableMembers(Info, handler.AccessKind)) {
4415 Info.FFDiag(E, diag::note_constexpr_access_mutable, 1)
4416 << handler.AccessKind << Field;
4417 Info.Note(Field->getLocation(), diag::note_declared_at);
4418 return handler.failed();
4427 if (I == N - 1 && handler.AccessKind ==
AK_Construct) {
4438 Info.FFDiag(E, diag::note_constexpr_access_inactive_union_member)
4439 << handler.AccessKind << Field << !UnionField << UnionField;
4440 return handler.failed();
4449 if (Field->getType().isVolatileQualified())
4450 VolatileField = Field;
4463struct ExtractSubobjectHandler {
4469 typedef bool result_type;
4470 bool failed() {
return false; }
4471 bool found(
APValue &Subobj, QualType SubobjType) {
4481 bool found(APFloat &
Value, QualType SubobjType) {
4490 const CompleteObject &Obj,
4491 const SubobjectDesignator &Sub,
APValue &Result,
4494 ExtractSubobjectHandler Handler = {Info, E, Result, AK};
4499struct ModifySubobjectHandler {
4504 typedef bool result_type;
4507 bool checkConst(QualType QT) {
4510 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
4516 bool failed() {
return false; }
4517 bool found(
APValue &Subobj, QualType SubobjType) {
4518 if (!checkConst(SubobjType))
4521 Subobj.
swap(NewVal);
4525 if (!checkConst(SubobjType))
4527 if (!NewVal.
isInt()) {
4535 bool found(APFloat &
Value, QualType SubobjType) {
4536 if (!checkConst(SubobjType))
4544const AccessKinds ModifySubobjectHandler::AccessKind;
4548 const CompleteObject &Obj,
4549 const SubobjectDesignator &Sub,
4551 ModifySubobjectHandler Handler = { Info, NewVal, E };
4558 const SubobjectDesignator &A,
4559 const SubobjectDesignator &B,
4560 bool &WasArrayIndex) {
4561 unsigned I = 0, N = std::min(A.Entries.size(), B.Entries.size());
4562 for (; I != N; ++I) {
4566 if (A.Entries[I].getAsArrayIndex() != B.Entries[I].getAsArrayIndex()) {
4567 WasArrayIndex =
true;
4575 if (A.Entries[I].getAsBaseOrMember() !=
4576 B.Entries[I].getAsBaseOrMember()) {
4577 WasArrayIndex =
false;
4580 if (
const FieldDecl *FD = getAsField(A.Entries[I]))
4582 ObjType = FD->getType();
4588 WasArrayIndex =
false;
4595 const SubobjectDesignator &A,
4596 const SubobjectDesignator &B) {
4597 if (A.Entries.size() != B.Entries.size())
4600 bool IsArray = A.MostDerivedIsArrayElement;
4601 if (IsArray && A.MostDerivedPathLength != A.Entries.size())
4610 return CommonLength >= A.Entries.size() - IsArray;
4617 if (LVal.InvalidBase) {
4619 return CompleteObject();
4624 Info.FFDiag(E, diag::note_constexpr_dereferencing_null);
4626 Info.FFDiag(E, diag::note_constexpr_access_null) << AK;
4627 return CompleteObject();
4630 CallStackFrame *Frame =
nullptr;
4632 if (LVal.getLValueCallIndex()) {
4633 std::tie(Frame, Depth) =
4634 Info.getCallFrameAndDepth(LVal.getLValueCallIndex());
4636 Info.FFDiag(E, diag::note_constexpr_lifetime_ended, 1)
4639 return CompleteObject();
4650 if (Info.getLangOpts().CPlusPlus)
4651 Info.FFDiag(E, diag::note_constexpr_access_volatile_type)
4655 return CompleteObject();
4662 if (Info.getLangOpts().CPlusPlus14 && LVal.Base == Info.EvaluatingDecl &&
4666 BaseVal = Info.EvaluatingDeclValue;
4669 if (
auto *GD = dyn_cast<MSGuidDecl>(D)) {
4672 Info.FFDiag(E, diag::note_constexpr_modify_global);
4673 return CompleteObject();
4677 Info.FFDiag(E, diag::note_constexpr_unsupported_layout)
4679 return CompleteObject();
4681 return CompleteObject(LVal.Base, &
V, GD->getType());
4685 if (
auto *GCD = dyn_cast<UnnamedGlobalConstantDecl>(D)) {
4687 Info.FFDiag(E, diag::note_constexpr_modify_global);
4688 return CompleteObject();
4690 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&GCD->getValue()),
4695 if (
auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
4697 Info.FFDiag(E, diag::note_constexpr_modify_global);
4698 return CompleteObject();
4700 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&TPO->getValue()),
4711 const VarDecl *VD = dyn_cast<VarDecl>(D);
4718 return CompleteObject();
4721 bool IsConstant = BaseType.isConstant(Info.Ctx);
4722 bool ConstexprVar =
false;
4723 if (
const auto *VD = dyn_cast_if_present<VarDecl>(
4735 }
else if (Info.getLangOpts().CPlusPlus14 &&
4742 Info.FFDiag(E, diag::note_constexpr_modify_global);
4743 return CompleteObject();
4746 }
else if (Info.getLangOpts().C23 && ConstexprVar) {
4748 return CompleteObject();
4749 }
else if (BaseType->isIntegralOrEnumerationType()) {
4752 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4753 if (Info.getLangOpts().CPlusPlus) {
4754 Info.FFDiag(E, diag::note_constexpr_ltor_non_const_int, 1) << VD;
4755 Info.Note(VD->
getLocation(), diag::note_declared_at);
4759 return CompleteObject();
4761 }
else if (!IsAccess) {
4762 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4763 }
else if ((IsConstant || BaseType->isReferenceType()) &&
4764 Info.checkingPotentialConstantExpression() &&
4765 BaseType->isLiteralType(Info.Ctx) && !VD->
hasDefinition()) {
4767 }
else if (IsConstant) {
4771 if (Info.getLangOpts().CPlusPlus) {
4772 Info.CCEDiag(E, Info.getLangOpts().CPlusPlus11
4773 ? diag::note_constexpr_ltor_non_constexpr
4774 : diag::note_constexpr_ltor_non_integral, 1)
4776 Info.Note(VD->
getLocation(), diag::note_declared_at);
4782 if (Info.getLangOpts().CPlusPlus) {
4783 Info.FFDiag(E, Info.getLangOpts().CPlusPlus11
4784 ? diag::note_constexpr_ltor_non_constexpr
4785 : diag::note_constexpr_ltor_non_integral, 1)
4787 Info.Note(VD->
getLocation(), diag::note_declared_at);
4791 return CompleteObject();
4800 return CompleteObject();
4805 if (!Info.checkingPotentialConstantExpression()) {
4806 Info.FFDiag(E, diag::note_constexpr_access_unknown_variable, 1)
4808 Info.Note(VD->getLocation(), diag::note_declared_at);
4810 return CompleteObject();
4813 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
4815 Info.FFDiag(E, diag::note_constexpr_access_deleted_object) << AK;
4816 return CompleteObject();
4818 return CompleteObject(LVal.Base, &(*Alloc)->Value,
4828 dyn_cast_or_null<MaterializeTemporaryExpr>(
Base)) {
4829 assert(MTE->getStorageDuration() ==
SD_Static &&
4830 "should have a frame for a non-global materialized temporary");
4857 if (!MTE->isUsableInConstantExpressions(Info.Ctx) &&
4860 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4861 Info.FFDiag(E, diag::note_constexpr_access_static_temporary, 1) << AK;
4862 Info.Note(MTE->getExprLoc(), diag::note_constexpr_temporary_here);
4863 return CompleteObject();
4866 BaseVal = MTE->getOrCreateValue(
false);
4867 assert(BaseVal &&
"got reference to unevaluated temporary");
4869 dyn_cast_or_null<CompoundLiteralExpr>(
Base)) {
4885 !CLETy.isConstant(Info.Ctx)) {
4887 Info.Note(CLE->getExprLoc(), diag::note_declared_at);
4888 return CompleteObject();
4891 BaseVal = &CLE->getStaticValue();
4894 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4897 Info.FFDiag(E, diag::note_constexpr_access_unreadable_object)
4902 return CompleteObject();
4906 assert(BaseVal &&
"missing value for temporary");
4917 unsigned VisibleDepth = Depth;
4918 if (llvm::isa_and_nonnull<ParmVarDecl>(
4921 if ((Frame && Info.getLangOpts().CPlusPlus14 &&
4923 (
isModification(AK) && VisibleDepth < Info.SpeculativeEvaluationDepth))
4924 return CompleteObject();
4926 return CompleteObject(LVal.getLValueBase(), BaseVal, BaseType);
4945 const LValue &LVal,
APValue &RVal,
4946 bool WantObjectRepresentation =
false) {
4947 if (LVal.Designator.Invalid)
4956 if (
Base && !LVal.getLValueCallIndex() && !
Type.isVolatileQualified()) {
4960 assert(LVal.Designator.Entries.size() <= 1 &&
4961 "Can only read characters from string literals");
4962 if (LVal.Designator.Entries.empty()) {
4969 if (LVal.Designator.isOnePastTheEnd()) {
4970 if (Info.getLangOpts().CPlusPlus11)
4971 Info.FFDiag(Conv, diag::note_constexpr_access_past_end) << AK;
4976 uint64_t CharIndex = LVal.Designator.Entries[0].getAsArrayIndex();
4983 return Obj &&
extractSubobject(Info, Conv, Obj, LVal.Designator, RVal, AK);
4997 LVal.setFrom(Info.Ctx, Val);
5013 if (LVal.Designator.Invalid)
5016 if (!Info.getLangOpts().CPlusPlus14) {
5026struct CompoundAssignSubobjectHandler {
5028 const CompoundAssignOperator *E;
5029 QualType PromotedLHSType;
5035 typedef bool result_type;
5037 bool checkConst(QualType QT) {
5040 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
5046 bool failed() {
return false; }
5047 bool found(
APValue &Subobj, QualType SubobjType) {
5050 return found(Subobj.
getInt(), SubobjType);
5052 return found(Subobj.
getFloat(), SubobjType);
5059 return foundPointer(Subobj, SubobjType);
5061 return foundVector(Subobj, SubobjType);
5063 Info.FFDiag(E, diag::note_constexpr_access_uninit)
5074 bool foundVector(
APValue &
Value, QualType SubobjType) {
5075 if (!checkConst(SubobjType))
5086 if (!checkConst(SubobjType))
5108 PromotedLHSType, FValue) &&
5117 bool found(APFloat &
Value, QualType SubobjType) {
5118 return checkConst(SubobjType) &&
5124 bool foundPointer(
APValue &Subobj, QualType SubobjType) {
5125 if (!checkConst(SubobjType))
5128 QualType PointeeType;
5129 if (
const PointerType *PT = SubobjType->
getAs<PointerType>())
5133 (Opcode != BO_Add && Opcode != BO_Sub)) {
5139 if (Opcode == BO_Sub)
5143 LVal.setFrom(Info.Ctx, Subobj);
5146 LVal.moveInto(Subobj);
5152const AccessKinds CompoundAssignSubobjectHandler::AccessKind;
5157 const LValue &LVal,
QualType LValType,
5161 if (LVal.Designator.Invalid)
5164 if (!Info.getLangOpts().CPlusPlus14) {
5170 CompoundAssignSubobjectHandler Handler = { Info, E, PromotedLValType, Opcode,
5172 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
5176struct IncDecSubobjectHandler {
5178 const UnaryOperator *E;
5182 typedef bool result_type;
5184 bool checkConst(QualType QT) {
5187 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
5193 bool failed() {
return false; }
5194 bool found(
APValue &Subobj, QualType SubobjType) {
5204 return found(Subobj.
getInt(), SubobjType);
5206 return found(Subobj.
getFloat(), SubobjType);
5209 SubobjType->
castAs<ComplexType>()->getElementType()
5213 SubobjType->
castAs<ComplexType>()->getElementType()
5216 return foundPointer(Subobj, SubobjType);
5224 if (!checkConst(SubobjType))
5246 bool WasNegative =
Value.isNegative();
5258 unsigned BitWidth =
Value.getBitWidth();
5259 APSInt ActualValue(
Value.sext(BitWidth + 1),
false);
5260 ActualValue.setBit(BitWidth);
5266 bool found(APFloat &
Value, QualType SubobjType) {
5267 if (!checkConst(SubobjType))
5274 APFloat::opStatus St;
5276 St =
Value.add(One, RM);
5278 St =
Value.subtract(One, RM);
5281 bool foundPointer(
APValue &Subobj, QualType SubobjType) {
5282 if (!checkConst(SubobjType))
5285 QualType PointeeType;
5286 if (
const PointerType *PT = SubobjType->
getAs<PointerType>())
5294 LVal.setFrom(Info.Ctx, Subobj);
5298 LVal.moveInto(Subobj);
5307 if (LVal.Designator.Invalid)
5310 if (!Info.getLangOpts().CPlusPlus14) {
5318 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
5324 if (Object->getType()->isPointerType() && Object->isPRValue())
5327 if (Object->isGLValue())
5330 if (Object->getType()->isLiteralType(Info.Ctx))
5333 if (Object->getType()->isRecordType() && Object->isPRValue())
5336 Info.FFDiag(Object, diag::note_constexpr_nonliteral) << Object->getType();
5355 bool IncludeMember =
true) {
5362 if (!MemPtr.getDecl()) {
5368 if (MemPtr.isDerivedMember()) {
5375 if (LV.Designator.MostDerivedPathLength + MemPtr.Path.size() >
5376 LV.Designator.Entries.size()) {
5380 unsigned PathLengthToMember =
5381 LV.Designator.Entries.size() - MemPtr.Path.size();
5382 for (
unsigned I = 0, N = MemPtr.Path.size(); I != N; ++I) {
5384 LV.Designator.Entries[PathLengthToMember + I]);
5401 (PathLengthToMember > LV.Designator.MostDerivedPathLength)
5402 ? getAsBaseClass(LV.Designator.Entries[PathLengthToMember - 1])
5404 const CXXRecordDecl *LastMPDecl = MemPtr.getContainingRecord();
5412 PathLengthToMember))
5414 }
else if (!MemPtr.Path.empty()) {
5416 LV.Designator.Entries.reserve(LV.Designator.Entries.size() +
5417 MemPtr.Path.size() + IncludeMember);
5423 assert(RD &&
"member pointer access on non-class-type expression");
5425 for (
unsigned I = 1, N = MemPtr.Path.size(); I != N; ++I) {
5433 MemPtr.getContainingRecord()))
5438 if (IncludeMember) {
5439 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(MemPtr.getDecl())) {
5443 dyn_cast<IndirectFieldDecl>(MemPtr.getDecl())) {
5447 llvm_unreachable(
"can't construct reference to bound member function");
5451 return MemPtr.getDecl();
5457 bool IncludeMember =
true) {
5461 if (Info.noteFailure()) {
5469 BO->
getRHS(), IncludeMember);
5476 SubobjectDesignator &D = Result.Designator;
5477 if (D.Invalid || !Result.checkNullPointer(Info, E,
CSK_Derived))
5484 auto InvalidCast = [&]() {
5485 if (!Info.checkingPotentialConstantExpression() ||
5486 !Result.AllowConstexprUnknown) {
5487 Info.CCEDiag(E, diag::note_constexpr_invalid_downcast)
5488 << D.MostDerivedType << TargetQT;
5494 if (D.MostDerivedPathLength + E->
path_size() > D.Entries.size())
5495 return InvalidCast();
5499 unsigned NewEntriesSize = D.Entries.size() - E->
path_size();
5502 if (NewEntriesSize == D.MostDerivedPathLength)
5505 FinalType = getAsBaseClass(D.Entries[NewEntriesSize - 1]);
5507 return InvalidCast();
5519 if (!Result.isAbsent())
5522 if (
auto *RD =
T->getAsCXXRecordDecl()) {
5523 if (RD->isInvalidDecl()) {
5527 if (RD->isUnion()) {
5536 End = RD->bases_end();
5537 I != End; ++I, ++Index)
5541 for (
const auto *I : RD->fields()) {
5542 if (I->isUnnamedBitField())
5545 I->getType(), Result.getStructField(I->getFieldIndex()));
5551 dyn_cast_or_null<ConstantArrayType>(
T->getAsArrayTypeUnsafe())) {
5553 if (Result.hasArrayFiller())
5565enum EvalStmtResult {
5594 if (!Result.Designator.Invalid && Result.Designator.isOnePastTheEnd()) {
5600 Result.moveInto(Val);
5612 APValue &Val = Info.CurrentCall->createTemporary(VD, VD->
getType(),
5613 ScopeKind::Block, Result);
5618 return Info.noteSideEffect();
5639 const DecompositionDecl *DD);
5642 bool EvaluateConditionDecl =
false) {
5644 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
5648 EvaluateConditionDecl && DD)
5658 if (
auto *VD = BD->getHoldingVar())
5666 if (
auto *DD = dyn_cast_if_present<DecompositionDecl>(VD)) {
5675 if (Info.noteSideEffect())
5677 assert(E->
containsErrors() &&
"valid value-dependent expression should never "
5678 "reach invalid code path.");
5685 if (
Cond->isValueDependent())
5687 FullExpressionRAII
Scope(Info);
5694 return Scope.destroy();
5707struct TempVersionRAII {
5708 CallStackFrame &Frame;
5710 TempVersionRAII(CallStackFrame &Frame) : Frame(Frame) {
5711 Frame.pushTempVersion();
5714 ~TempVersionRAII() {
5715 Frame.popTempVersion();
5723 const SwitchCase *SC =
nullptr);
5729 const Stmt *LoopOrSwitch,
5731 EvalStmtResult &ESR) {
5735 if (!IsSwitch && ESR == ESR_Succeeded) {
5740 if (ESR != ESR_Break && ESR != ESR_Continue)
5744 bool CanBreakOrContinue = !IsSwitch || ESR == ESR_Break;
5745 const Stmt *StackTop = Info.BreakContinueStack.back();
5746 if (CanBreakOrContinue && (StackTop ==
nullptr || StackTop == LoopOrSwitch)) {
5747 Info.BreakContinueStack.pop_back();
5748 if (ESR == ESR_Break)
5749 ESR = ESR_Succeeded;
5754 for (BlockScopeRAII *S : Scopes) {
5755 if (!S->destroy()) {
5767 BlockScopeRAII
Scope(Info);
5769 EvalStmtResult ESR =
EvaluateStmt(Result, Info, Body, Case);
5770 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5779 BlockScopeRAII
Scope(Info);
5786 if (ESR != ESR_Succeeded) {
5787 if (ESR != ESR_Failed && !
Scope.destroy())
5793 FullExpressionRAII CondScope(Info);
5808 if (!CondScope.destroy())
5829 if (LHSValue <=
Value &&
Value <= RHSValue) {
5836 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5840 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5847 llvm_unreachable(
"Should have been converted to Succeeded");
5853 case ESR_CaseNotFound:
5856 Info.FFDiag(
Found->getBeginLoc(),
5857 diag::note_constexpr_stmt_expr_unsupported);
5860 llvm_unreachable(
"Invalid EvalStmtResult!");
5870 Info.CCEDiag(VD->
getLocation(), diag::note_constexpr_static_local)
5880 if (!Info.nextStep(S))
5887 case Stmt::CompoundStmtClass:
5891 case Stmt::LabelStmtClass:
5892 case Stmt::AttributedStmtClass:
5893 case Stmt::DoStmtClass:
5896 case Stmt::CaseStmtClass:
5897 case Stmt::DefaultStmtClass:
5902 case Stmt::IfStmtClass: {
5909 BlockScopeRAII
Scope(Info);
5915 if (ESR != ESR_CaseNotFound) {
5916 assert(ESR != ESR_Succeeded);
5927 if (ESR == ESR_Failed)
5929 if (ESR != ESR_CaseNotFound)
5930 return Scope.destroy() ? ESR : ESR_Failed;
5932 return ESR_CaseNotFound;
5935 if (ESR == ESR_Failed)
5937 if (ESR != ESR_CaseNotFound)
5938 return Scope.destroy() ? ESR : ESR_Failed;
5939 return ESR_CaseNotFound;
5942 case Stmt::WhileStmtClass: {
5943 EvalStmtResult ESR =
5947 if (ESR != ESR_Continue)
5952 case Stmt::ForStmtClass: {
5954 BlockScopeRAII
Scope(Info);
5960 if (ESR != ESR_CaseNotFound) {
5961 assert(ESR != ESR_Succeeded);
5966 EvalStmtResult ESR =
5970 if (ESR != ESR_Continue)
5972 if (
const auto *Inc = FS->
getInc()) {
5973 if (Inc->isValueDependent()) {
5977 FullExpressionRAII IncScope(Info);
5985 case Stmt::DeclStmtClass: {
5989 for (
const auto *D : DS->
decls()) {
5990 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
5993 if (VD->hasLocalStorage() && !VD->getInit())
6001 return ESR_CaseNotFound;
6005 return ESR_CaseNotFound;
6011 if (
const Expr *E = dyn_cast<Expr>(S)) {
6020 FullExpressionRAII
Scope(Info);
6024 return ESR_Succeeded;
6030 case Stmt::NullStmtClass:
6031 return ESR_Succeeded;
6033 case Stmt::DeclStmtClass: {
6035 for (
const auto *D : DS->
decls()) {
6036 const VarDecl *VD = dyn_cast_or_null<VarDecl>(D);
6040 FullExpressionRAII
Scope(Info);
6042 !Info.noteFailure())
6044 if (!
Scope.destroy())
6047 return ESR_Succeeded;
6050 case Stmt::ReturnStmtClass: {
6052 FullExpressionRAII
Scope(Info);
6061 :
Evaluate(Result.Value, Info, RetExpr)))
6063 return Scope.destroy() ? ESR_Returned : ESR_Failed;
6066 case Stmt::CompoundStmtClass: {
6067 BlockScopeRAII
Scope(Info);
6070 for (
const auto *BI : CS->
body()) {
6071 EvalStmtResult ESR =
EvaluateStmt(Result, Info, BI, Case);
6072 if (ESR == ESR_Succeeded)
6074 else if (ESR != ESR_CaseNotFound) {
6075 if (ESR != ESR_Failed && !
Scope.destroy())
6081 return ESR_CaseNotFound;
6082 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
6085 case Stmt::IfStmtClass: {
6089 BlockScopeRAII
Scope(Info);
6092 if (ESR != ESR_Succeeded) {
6093 if (ESR != ESR_Failed && !
Scope.destroy())
6103 if (!Info.InConstantContext)
6110 EvalStmtResult ESR =
EvaluateStmt(Result, Info, SubStmt);
6111 if (ESR != ESR_Succeeded) {
6112 if (ESR != ESR_Failed && !
Scope.destroy())
6117 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
6120 case Stmt::WhileStmtClass: {
6123 BlockScopeRAII
Scope(Info);
6135 if (ESR != ESR_Continue) {
6136 if (ESR != ESR_Failed && !
Scope.destroy())
6140 if (!
Scope.destroy())
6143 return ESR_Succeeded;
6146 case Stmt::DoStmtClass: {
6153 if (ESR != ESR_Continue)
6162 FullExpressionRAII CondScope(Info);
6164 !CondScope.destroy())
6167 return ESR_Succeeded;
6170 case Stmt::ForStmtClass: {
6172 BlockScopeRAII ForScope(Info);
6175 if (ESR != ESR_Succeeded) {
6176 if (ESR != ESR_Failed && !ForScope.destroy())
6182 BlockScopeRAII IterScope(Info);
6183 bool Continue =
true;
6189 if (!IterScope.destroy())
6197 if (ESR != ESR_Continue) {
6198 if (ESR != ESR_Failed && (!IterScope.destroy() || !ForScope.destroy()))
6203 if (
const auto *Inc = FS->
getInc()) {
6204 if (Inc->isValueDependent()) {
6208 FullExpressionRAII IncScope(Info);
6214 if (!IterScope.destroy())
6217 return ForScope.destroy() ? ESR_Succeeded : ESR_Failed;
6220 case Stmt::CXXForRangeStmtClass: {
6222 BlockScopeRAII
Scope(Info);
6227 if (ESR != ESR_Succeeded) {
6228 if (ESR != ESR_Failed && !
Scope.destroy())
6236 if (ESR != ESR_Succeeded) {
6237 if (ESR != ESR_Failed && !
Scope.destroy())
6249 if (ESR != ESR_Succeeded) {
6250 if (ESR != ESR_Failed && !
Scope.destroy())
6255 if (ESR != ESR_Succeeded) {
6256 if (ESR != ESR_Failed && !
Scope.destroy())
6269 bool Continue =
true;
6270 FullExpressionRAII CondExpr(Info);
6278 BlockScopeRAII InnerScope(Info);
6280 if (ESR != ESR_Succeeded) {
6281 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
6290 if (ESR != ESR_Continue) {
6291 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
6304 if (!InnerScope.destroy())
6308 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
6311 case Stmt::SwitchStmtClass:
6314 case Stmt::ContinueStmtClass:
6315 case Stmt::BreakStmtClass: {
6317 Info.BreakContinueStack.push_back(B->getNamedLoopOrSwitch());
6321 case Stmt::LabelStmtClass:
6324 case Stmt::AttributedStmtClass: {
6326 const auto *SS = AS->getSubStmt();
6327 MSConstexprContextRAII ConstexprContext(
6331 auto LO = Info.getASTContext().getLangOpts();
6332 if (LO.CXXAssumptions && !LO.MSVCCompat) {
6333 for (
auto *
Attr : AS->getAttrs()) {
6334 auto *AA = dyn_cast<CXXAssumeAttr>(
Attr);
6338 auto *Assumption = AA->getAssumption();
6339 if (Assumption->isValueDependent())
6342 if (Assumption->HasSideEffects(Info.getASTContext()))
6349 Info.CCEDiag(Assumption->getExprLoc(),
6350 diag::note_constexpr_assumption_failed);
6359 case Stmt::CaseStmtClass:
6360 case Stmt::DefaultStmtClass:
6362 case Stmt::CXXTryStmtClass:
6374 bool IsValueInitialization) {
6381 if (!CD->
isConstexpr() && !IsValueInitialization) {
6382 if (Info.getLangOpts().CPlusPlus11) {
6385 Info.CCEDiag(Loc, diag::note_constexpr_invalid_function, 1)
6387 Info.Note(CD->
getLocation(), diag::note_declared_at);
6389 Info.CCEDiag(Loc, diag::note_invalid_subexpr_in_const_expr);
6403 if (Info.checkingPotentialConstantExpression() && !
Definition &&
6411 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6420 Info.CCEDiag(CallLoc, diag::note_constexpr_virtual_call);
6423 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6429 (
Definition->isConstexpr() || (Info.CurrentCall->CanEvalMSConstexpr &&
6439 StringRef Name = DiagDecl->
getName();
6441 Name ==
"__assert_rtn" || Name ==
"__assert_fail" || Name ==
"_wassert";
6443 Info.FFDiag(CallLoc, diag::note_constexpr_assert_failed);
6448 if (Info.getLangOpts().CPlusPlus11) {
6451 auto *CD = dyn_cast<CXXConstructorDecl>(DiagDecl);
6452 if (CD && CD->isInheritingConstructor()) {
6453 auto *Inherited = CD->getInheritedConstructor().getConstructor();
6454 if (!Inherited->isConstexpr())
6455 DiagDecl = CD = Inherited;
6461 if (CD && CD->isInheritingConstructor())
6462 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_inhctor, 1)
6463 << CD->getInheritedConstructor().getConstructor()->getParent();
6465 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_function, 1)
6467 Info.Note(DiagDecl->
getLocation(), diag::note_declared_at);
6469 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6475struct CheckDynamicTypeHandler {
6477 typedef bool result_type;
6478 bool failed() {
return false; }
6479 bool found(
APValue &Subobj, QualType SubobjType) {
return true; }
6480 bool found(
APSInt &
Value, QualType SubobjType) {
return true; }
6481 bool found(APFloat &
Value, QualType SubobjType) {
return true; }
6489 if (
This.Designator.Invalid)
6501 if (
This.Designator.isOnePastTheEnd() ||
6502 This.Designator.isMostDerivedAnUnsizedArray()) {
6503 Info.FFDiag(E,
This.Designator.isOnePastTheEnd()
6504 ? diag::note_constexpr_access_past_end
6505 : diag::note_constexpr_access_unsized_array)
6508 }
else if (Polymorphic) {
6511 if (!Info.checkingPotentialConstantExpression() ||
6512 !
This.AllowConstexprUnknown) {
6517 Info.FFDiag(E, diag::note_constexpr_polymorphic_unknown_dynamic_type)
6525 CheckDynamicTypeHandler Handler{AK};
6548 unsigned PathLength) {
6549 assert(PathLength >=
Designator.MostDerivedPathLength && PathLength <=
6550 Designator.Entries.size() &&
"invalid path length");
6551 return (PathLength ==
Designator.MostDerivedPathLength)
6552 ?
Designator.MostDerivedType->getAsCXXRecordDecl()
6553 : getAsBaseClass(
Designator.Entries[PathLength - 1]);
6566 return std::nullopt;
6568 if (
This.Designator.Invalid)
6569 return std::nullopt;
6578 This.Designator.MostDerivedType->getAsCXXRecordDecl();
6579 if (!Class || Class->getNumVBases()) {
6581 return std::nullopt;
6589 for (
unsigned PathLength =
This.Designator.MostDerivedPathLength;
6590 PathLength <= Path.size(); ++PathLength) {
6591 switch (Info.isEvaluatingCtorDtor(
This.getLValueBase(),
6592 Path.slice(0, PathLength))) {
6593 case ConstructionPhase::Bases:
6594 case ConstructionPhase::DestroyingBases:
6599 case ConstructionPhase::None:
6600 case ConstructionPhase::AfterBases:
6601 case ConstructionPhase::AfterFields:
6602 case ConstructionPhase::Destroying:
6614 return std::nullopt;
6632 unsigned PathLength = DynType->PathLength;
6633 for (; PathLength <=
This.Designator.Entries.size(); ++PathLength) {
6636 Found->getCorrespondingMethodDeclaredInClass(Class,
false);
6646 if (Callee->isPureVirtual()) {
6647 Info.FFDiag(E, diag::note_constexpr_pure_virtual_call, 1) << Callee;
6648 Info.Note(Callee->getLocation(), diag::note_declared_at);
6655 Found->getReturnType())) {
6656 CovariantAdjustmentPath.push_back(Callee->getReturnType());
6657 for (
unsigned CovariantPathLength = PathLength + 1;
6658 CovariantPathLength !=
This.Designator.Entries.size();
6659 ++CovariantPathLength) {
6663 Found->getCorrespondingMethodDeclaredInClass(NextClass,
false);
6665 Next->getReturnType(), CovariantAdjustmentPath.back()))
6666 CovariantAdjustmentPath.push_back(
Next->getReturnType());
6669 CovariantAdjustmentPath.back()))
6670 CovariantAdjustmentPath.push_back(
Found->getReturnType());
6686 assert(Result.isLValue() &&
6687 "unexpected kind of APValue for covariant return");
6688 if (Result.isNullPointer())
6692 LVal.setFrom(Info.Ctx, Result);
6694 const CXXRecordDecl *OldClass = Path[0]->getPointeeCXXRecordDecl();
6695 for (
unsigned I = 1; I != Path.size(); ++I) {
6696 const CXXRecordDecl *NewClass = Path[I]->getPointeeCXXRecordDecl();
6697 assert(OldClass && NewClass &&
"unexpected kind of covariant return");
6698 if (OldClass != NewClass &&
6701 OldClass = NewClass;
6704 LVal.moveInto(Result);
6713 auto *BaseClass = BaseSpec.getType()->getAsCXXRecordDecl();
6715 return BaseSpec.getAccessSpecifier() ==
AS_public;
6717 llvm_unreachable(
"Base is not a direct base of Derived");
6727 SubobjectDesignator &D = Ptr.Designator;
6733 if (Ptr.isNullPointer() && !E->
isGLValue())
6739 std::optional<DynamicType> DynType =
6751 assert(
C &&
"dynamic_cast target is not void pointer nor class");
6759 Ptr.setNull(Info.Ctx, E->
getType());
6766 DynType->Type->isDerivedFrom(
C)))
6768 else if (!Paths || Paths->begin() == Paths->end())
6770 else if (Paths->isAmbiguous(CQT))
6773 assert(Paths->front().Access !=
AS_public &&
"why did the cast fail?");
6776 Info.FFDiag(E, diag::note_constexpr_dynamic_cast_to_reference_failed)
6777 << DiagKind << Ptr.Designator.getType(Info.Ctx)
6786 for (
int PathLength = Ptr.Designator.Entries.size();
6787 PathLength >= (
int)DynType->PathLength; --PathLength) {
6792 if (PathLength > (
int)DynType->PathLength &&
6795 return RuntimeCheckFailed(
nullptr);
6802 if (DynType->Type->isDerivedFrom(
C, Paths) && !Paths.
isAmbiguous(CQT) &&
6815 return RuntimeCheckFailed(&Paths);
6819struct StartLifetimeOfUnionMemberHandler {
6821 const Expr *LHSExpr;
6822 const FieldDecl *
Field;
6824 bool Failed =
false;
6827 typedef bool result_type;
6828 bool failed() {
return Failed; }
6829 bool found(
APValue &Subobj, QualType SubobjType) {
6844 }
else if (DuringInit) {
6848 Info.FFDiag(LHSExpr,
6849 diag::note_constexpr_union_member_change_during_init);
6858 llvm_unreachable(
"wrong value kind for union object");
6860 bool found(APFloat &
Value, QualType SubobjType) {
6861 llvm_unreachable(
"wrong value kind for union object");
6866const AccessKinds StartLifetimeOfUnionMemberHandler::AccessKind;
6873 const Expr *LHSExpr,
6874 const LValue &LHS) {
6875 if (LHS.InvalidBase || LHS.Designator.Invalid)
6881 unsigned PathLength = LHS.Designator.Entries.size();
6882 for (
const Expr *E = LHSExpr; E !=
nullptr;) {
6884 if (
auto *ME = dyn_cast<MemberExpr>(E)) {
6885 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
6888 if (!FD || FD->getType()->isReferenceType())
6892 if (FD->getParent()->isUnion()) {
6897 FD->getType()->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
6898 if (!RD || RD->hasTrivialDefaultConstructor())
6899 UnionPathLengths.push_back({PathLength - 1, FD});
6905 LHS.Designator.Entries[PathLength]
6906 .getAsBaseOrMember().getPointer()));
6910 }
else if (
auto *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
6912 auto *
Base = ASE->getBase()->IgnoreImplicit();
6913 if (!
Base->getType()->isArrayType())
6919 }
else if (
auto *ICE = dyn_cast<ImplicitCastExpr>(E)) {
6922 if (ICE->getCastKind() == CK_NoOp)
6924 if (ICE->getCastKind() != CK_DerivedToBase &&
6925 ICE->getCastKind() != CK_UncheckedDerivedToBase)
6929 if (Elt->isVirtual()) {
6938 LHS.Designator.Entries[PathLength]
6939 .getAsBaseOrMember().getPointer()));
6949 if (UnionPathLengths.empty())
6954 CompleteObject Obj =
6958 for (std::pair<unsigned, const FieldDecl *> LengthAndField :
6959 llvm::reverse(UnionPathLengths)) {
6961 SubobjectDesignator D = LHS.Designator;
6962 D.truncate(Info.Ctx, LHS.Base, LengthAndField.first);
6964 bool DuringInit = Info.isEvaluatingCtorDtor(LHS.Base, D.Entries) ==
6965 ConstructionPhase::AfterBases;
6966 StartLifetimeOfUnionMemberHandler StartLifetime{
6967 Info, LHSExpr, LengthAndField.second, DuringInit};
6976 CallRef
Call, EvalInfo &Info,
bool NonNull =
false,
6977 APValue **EvaluatedArg =
nullptr) {
6984 APValue &
V = PVD ? Info.CurrentCall->createParam(
Call, PVD, LV)
6985 : Info.CurrentCall->createTemporary(Arg, Arg->
getType(),
6986 ScopeKind::Call, LV);
6992 if (
NonNull &&
V.isLValue() &&
V.isNullPointer()) {
6993 Info.CCEDiag(Arg, diag::note_non_null_attribute_failed);
7006 bool RightToLeft =
false,
7007 LValue *ObjectArg =
nullptr) {
7009 llvm::SmallBitVector ForbiddenNullArgs;
7010 if (Callee->hasAttr<NonNullAttr>()) {
7011 ForbiddenNullArgs.resize(Args.size());
7012 for (
const auto *
Attr : Callee->specific_attrs<NonNullAttr>()) {
7013 if (!
Attr->args_size()) {
7014 ForbiddenNullArgs.set();
7017 for (
auto Idx :
Attr->args()) {
7018 unsigned ASTIdx = Idx.getASTIndex();
7019 if (ASTIdx >= Args.size())
7021 ForbiddenNullArgs[ASTIdx] =
true;
7025 for (
unsigned I = 0; I < Args.size(); I++) {
7026 unsigned Idx = RightToLeft ? Args.size() - I - 1 : I;
7028 Idx < Callee->getNumParams() ? Callee->getParamDecl(Idx) :
nullptr;
7029 bool NonNull = !ForbiddenNullArgs.empty() && ForbiddenNullArgs[Idx];
7034 if (!Info.noteFailure())
7039 ObjectArg->setFrom(Info.Ctx, *That);
7048 bool CopyObjectRepresentation) {
7050 CallStackFrame *Frame = Info.CurrentCall;
7051 APValue *RefValue = Info.getParamSlot(Frame->Arguments, Param);
7059 RefLValue.setFrom(Info.Ctx, *RefValue);
7062 CopyObjectRepresentation);
7068 const LValue *ObjectArg,
const Expr *E,
7070 const Stmt *Body, EvalInfo &Info,
7071 APValue &Result,
const LValue *ResultSlot) {
7072 if (!Info.CheckCallLimit(CallLoc))
7101 ObjectArg->moveInto(Result);
7110 if (!Info.checkingPotentialConstantExpression())
7112 Frame.LambdaThisCaptureField);
7115 StmtResult Ret = {Result, ResultSlot};
7117 if (ESR == ESR_Succeeded) {
7118 if (Callee->getReturnType()->isVoidType())
7120 Info.FFDiag(Callee->getEndLoc(), diag::note_constexpr_no_return);
7122 return ESR == ESR_Returned;
7129 EvalInfo &Info,
APValue &Result) {
7131 if (!Info.CheckCallLimit(CallLoc))
7136 Info.FFDiag(CallLoc, diag::note_constexpr_virtual_base) << RD;
7140 EvalInfo::EvaluatingConstructorRAII EvalObj(
7142 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries},
7149 StmtResult Ret = {RetVal,
nullptr};
7154 if ((*I)->getInit()->isValueDependent()) {
7158 FullExpressionRAII InitScope(Info);
7160 !InitScope.destroy())
7183 if (!Result.hasValue()) {
7196 BlockScopeRAII LifetimeExtendedScope(Info);
7199 unsigned BasesSeen = 0;
7204 auto SkipToField = [&](
FieldDecl *FD,
bool Indirect) {
7209 assert(Indirect &&
"fields out of order?");
7215 assert(FieldIt != RD->
field_end() &&
"missing field?");
7216 if (!FieldIt->isUnnamedBitField())
7219 Result.getStructField(FieldIt->getFieldIndex()));
7224 LValue Subobject =
This;
7225 LValue SubobjectParent =
This;
7230 if (I->isBaseInitializer()) {
7231 QualType BaseType(I->getBaseClass(), 0);
7235 assert(!BaseIt->
isVirtual() &&
"virtual base for literal type");
7237 "base class initializers not in expected order");
7241 BaseType->getAsCXXRecordDecl(), &Layout))
7243 Value = &Result.getStructBase(BasesSeen++);
7244 }
else if ((FD = I->getMember())) {
7249 Value = &Result.getUnionValue();
7251 SkipToField(FD,
false);
7257 auto IndirectFieldChain = IFD->chain();
7258 for (
auto *
C : IndirectFieldChain) {
7267 (
Value->isUnion() &&
7280 if (
C == IndirectFieldChain.back())
7281 SubobjectParent = Subobject;
7287 if (
C == IndirectFieldChain.front() && !RD->
isUnion())
7288 SkipToField(FD,
true);
7293 llvm_unreachable(
"unknown base initializer kind");
7300 if (
Init->isValueDependent()) {
7304 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &SubobjectParent,
7306 FullExpressionRAII InitScope(Info);
7312 if (!Info.noteFailure())
7321 if (!Info.noteFailure())
7329 if (I->isBaseInitializer() && BasesSeen == RD->
getNumBases())
7330 EvalObj.finishedConstructingBases();
7335 for (; FieldIt != RD->
field_end(); ++FieldIt) {
7336 if (!FieldIt->isUnnamedBitField())
7339 Result.getStructField(FieldIt->getFieldIndex()));
7343 EvalObj.finishedConstructingFields();
7347 LifetimeExtendedScope.destroy();
7353 EvalInfo &Info,
APValue &Result) {
7354 CallScopeRAII CallScope(Info);
7360 CallScope.destroy();
7370 if (
Value.isAbsent() && !
T->isNullPtrType()) {
7372 This.moveInto(Printable);
7374 diag::note_constexpr_destroy_out_of_lifetime)
7391 LValue ElemLV =
This;
7392 ElemLV.addArray(Info, &LocE, CAT);
7399 if (Size && Size >
Value.getArrayInitializedElts())
7404 for (Size =
Value.getArraySize(); Size != 0; --Size) {
7405 APValue &Elem =
Value.getArrayInitializedElt(Size - 1);
7418 if (
T.isDestructedType()) {
7420 diag::note_constexpr_unsupported_destruction)
7430 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_virtual_base) << RD;
7455 if (!Info.CheckCallLimit(CallRange.
getBegin()))
7464 CallStackFrame Frame(Info, CallRange,
Definition, &
This,
nullptr,
7469 EvalInfo::EvaluatingDestructorRAII EvalObj(
7471 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries});
7472 if (!EvalObj.DidInsert) {
7479 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_double_destroy);
7486 StmtResult Ret = {RetVal,
nullptr};
7499 for (
const FieldDecl *FD : llvm::reverse(Fields)) {
7500 if (FD->isUnnamedBitField())
7503 LValue Subobject =
This;
7507 APValue *SubobjectValue = &
Value.getStructField(FD->getFieldIndex());
7514 EvalObj.startedDestroyingBases();
7521 LValue Subobject =
This;
7523 BaseType->getAsCXXRecordDecl(), &Layout))
7526 APValue *SubobjectValue = &
Value.getStructBase(BasesLeft);
7531 assert(BasesLeft == 0 &&
"NumBases was wrong?");
7539struct DestroyObjectHandler {
7545 typedef bool result_type;
7546 bool failed() {
return false; }
7547 bool found(
APValue &Subobj, QualType SubobjType) {
7552 Info.FFDiag(E, diag::note_constexpr_destroy_complex_elem);
7555 bool found(APFloat &
Value, QualType SubobjType) {
7556 Info.FFDiag(E, diag::note_constexpr_destroy_complex_elem);
7588 if (Info.checkingPotentialConstantExpression() ||
7589 Info.SpeculativeEvaluationDepth)
7593 auto Caller = Info.getStdAllocatorCaller(
"allocate");
7595 Info.FFDiag(E->
getExprLoc(), Info.getLangOpts().CPlusPlus20
7596 ? diag::note_constexpr_new_untyped
7597 : diag::note_constexpr_new);
7601 QualType ElemType = Caller.ElemType;
7604 diag::note_constexpr_new_not_complete_object_type)
7612 bool IsNothrow =
false;
7613 for (
unsigned I = 1, N = E->
getNumArgs(); I != N; ++I) {
7621 APInt Size, Remainder;
7622 APInt ElemSizeAP(ByteSize.getBitWidth(), ElemSize.
getQuantity());
7623 APInt::udivrem(ByteSize, ElemSizeAP, Size, Remainder);
7624 if (Remainder != 0) {
7626 Info.FFDiag(E->
getExprLoc(), diag::note_constexpr_operator_new_bad_size)
7627 << ByteSize <<
APSInt(ElemSizeAP,
true) << ElemType;
7631 if (!Info.CheckArraySize(E->
getBeginLoc(), ByteSize.getActiveBits(),
7632 Size.getZExtValue(), !IsNothrow)) {
7634 Result.setNull(Info.Ctx, E->
getType());
7642 APValue *Val = Info.createHeapAlloc(Caller.Call, AllocType, Result);
7651 return DD->isVirtual();
7658 return DD->isVirtual() ? DD->getOperatorDelete() :
nullptr;
7669 DynAlloc::Kind DeallocKind) {
7670 auto PointerAsString = [&] {
7676 Info.FFDiag(E, diag::note_constexpr_delete_not_heap_alloc)
7677 << PointerAsString();
7680 return std::nullopt;
7683 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
7685 Info.FFDiag(E, diag::note_constexpr_double_delete);
7686 return std::nullopt;
7689 if (DeallocKind != (*Alloc)->getKind()) {
7691 Info.FFDiag(E, diag::note_constexpr_new_delete_mismatch)
7692 << DeallocKind << (*Alloc)->getKind() << AllocType;
7694 return std::nullopt;
7697 bool Subobject =
false;
7698 if (DeallocKind == DynAlloc::New) {
7699 Subobject =
Pointer.Designator.MostDerivedPathLength != 0 ||
7700 Pointer.Designator.isOnePastTheEnd();
7702 Subobject =
Pointer.Designator.Entries.size() != 1 ||
7703 Pointer.Designator.Entries[0].getAsArrayIndex() != 0;
7706 Info.FFDiag(E, diag::note_constexpr_delete_subobject)
7707 << PointerAsString() <<
Pointer.Designator.isOnePastTheEnd();
7708 return std::nullopt;
7716 if (Info.checkingPotentialConstantExpression() ||
7717 Info.SpeculativeEvaluationDepth)
7721 if (!Info.getStdAllocatorCaller(
"deallocate")) {
7729 for (
unsigned I = 1, N = E->
getNumArgs(); I != N; ++I)
7732 if (
Pointer.Designator.Invalid)
7737 if (
Pointer.isNullPointer()) {
7738 Info.CCEDiag(E->
getExprLoc(), diag::note_constexpr_deallocate_null);
7754class BitCastBuffer {
7760 SmallVector<std::optional<unsigned char>, 32> Bytes;
7762 static_assert(std::numeric_limits<unsigned char>::digits >= 8,
7763 "Need at least 8 bit unsigned char");
7765 bool TargetIsLittleEndian;
7768 BitCastBuffer(CharUnits Width,
bool TargetIsLittleEndian)
7769 : Bytes(Width.getQuantity()),
7770 TargetIsLittleEndian(TargetIsLittleEndian) {}
7772 [[nodiscard]]
bool readObject(CharUnits Offset, CharUnits Width,
7773 SmallVectorImpl<unsigned char> &Output)
const {
7774 for (CharUnits I = Offset, E = Offset + Width; I != E; ++I) {
7777 if (!Bytes[I.getQuantity()])
7779 Output.push_back(*Bytes[I.getQuantity()]);
7781 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
7782 std::reverse(Output.begin(), Output.end());
7786 void writeObject(CharUnits Offset, SmallVectorImpl<unsigned char> &Input) {
7787 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
7788 std::reverse(Input.begin(), Input.end());
7791 for (
unsigned char Byte : Input) {
7792 assert(!Bytes[Offset.
getQuantity() + Index] &&
"overwriting a byte?");
7798 size_t size() {
return Bytes.size(); }
7803class APValueToBufferConverter {
7805 BitCastBuffer Buffer;
7808 APValueToBufferConverter(EvalInfo &Info, CharUnits ObjectWidth,
7811 Buffer(ObjectWidth, Info.Ctx.getTargetInfo().isLittleEndian()),
7814 bool visit(
const APValue &Val, QualType Ty) {
7819 bool visit(
const APValue &Val, QualType Ty, CharUnits Offset) {
7820 assert((
size_t)Offset.
getQuantity() <= Buffer.size());
7833 return visitInt(Val.
getInt(), Ty, Offset);
7835 return visitFloat(Val.
getFloat(), Ty, Offset);
7837 return visitArray(Val, Ty, Offset);
7839 return visitRecord(Val, Ty, Offset);
7841 return visitVector(Val, Ty, Offset);
7845 return visitComplex(Val, Ty, Offset);
7853 diag::note_constexpr_bit_cast_unsupported_type)
7859 llvm_unreachable(
"LValue subobject in bit_cast?");
7861 llvm_unreachable(
"Unhandled APValue::ValueKind");
7864 bool visitRecord(
const APValue &Val, QualType Ty, CharUnits Offset) {
7869 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
7870 for (
size_t I = 0, E = CXXRD->getNumBases(); I != E; ++I) {
7871 const CXXBaseSpecifier &BS = CXXRD->bases_begin()[I];
7876 if (!
Base.isStruct())
7879 if (!visitRecord(Base, BS.
getType(),
7886 unsigned FieldIdx = 0;
7887 for (FieldDecl *FD : RD->
fields()) {
7888 if (FD->isBitField()) {
7890 diag::note_constexpr_bit_cast_unsupported_bitfield);
7896 assert(FieldOffsetBits % Info.Ctx.
getCharWidth() == 0 &&
7897 "only bit-fields can have sub-char alignment");
7898 CharUnits FieldOffset =
7900 QualType FieldTy = FD->getType();
7909 bool visitArray(
const APValue &Val, QualType Ty, CharUnits Offset) {
7919 for (
unsigned I = 0; I != NumInitializedElts; ++I) {
7921 if (!visit(SubObj, CAT->
getElementType(), Offset + I * ElemWidth))
7928 for (
unsigned I = NumInitializedElts; I != ArraySize; ++I) {
7929 if (!visit(Filler, CAT->
getElementType(), Offset + I * ElemWidth))
7937 bool visitComplex(
const APValue &Val, QualType Ty, CharUnits Offset) {
7938 const ComplexType *ComplexTy = Ty->
castAs<ComplexType>();
7945 Offset + (0 * EltSizeChars)))
7948 Offset + (1 * EltSizeChars)))
7952 Offset + (0 * EltSizeChars)))
7955 Offset + (1 * EltSizeChars)))
7962 bool visitVector(
const APValue &Val, QualType Ty, CharUnits Offset) {
7963 const VectorType *VTy = Ty->
castAs<VectorType>();
7978 llvm::APInt Res = llvm::APInt::getZero(NElts);
7979 for (
unsigned I = 0; I < NElts; ++I) {
7981 assert(EltAsInt.isUnsigned() && EltAsInt.getBitWidth() == 1 &&
7982 "bool vector element must be 1-bit unsigned integer!");
7984 Res.insertBits(EltAsInt, BigEndian ? (NElts - I - 1) : I);
7987 SmallVector<uint8_t, 8> Bytes(NElts / 8);
7988 llvm::StoreIntToMemory(Res, &*Bytes.begin(), NElts / 8);
7989 Buffer.writeObject(Offset, Bytes);
7994 for (
unsigned I = 0; I < NElts; ++I) {
7995 if (!visit(Val.
getVectorElt(I), EltTy, Offset + I * EltSizeChars))
8003 bool visitInt(
const APSInt &Val, QualType Ty, CharUnits Offset) {
8004 APSInt AdjustedVal = Val;
8005 unsigned Width = AdjustedVal.getBitWidth();
8008 AdjustedVal = AdjustedVal.extend(Width);
8011 SmallVector<uint8_t, 8> Bytes(Width / 8);
8012 llvm::StoreIntToMemory(AdjustedVal, &*Bytes.begin(), Width / 8);
8013 Buffer.writeObject(Offset, Bytes);
8017 bool visitFloat(
const APFloat &Val, QualType Ty, CharUnits Offset) {
8018 APSInt AsInt(Val.bitcastToAPInt());
8019 return visitInt(AsInt, Ty, Offset);
8023 static std::optional<BitCastBuffer>
8026 APValueToBufferConverter Converter(Info, DstSize, BCE);
8028 return std::nullopt;
8029 return Converter.Buffer;
8034class BufferToAPValueConverter {
8036 const BitCastBuffer &Buffer;
8039 BufferToAPValueConverter(EvalInfo &Info,
const BitCastBuffer &Buffer,
8041 : Info(Info), Buffer(Buffer), BCE(BCE) {}
8046 std::nullopt_t unsupportedType(QualType Ty) {
8048 diag::note_constexpr_bit_cast_unsupported_type)
8050 return std::nullopt;
8053 std::nullopt_t unrepresentableValue(QualType Ty,
const APSInt &Val) {
8055 diag::note_constexpr_bit_cast_unrepresentable_value)
8057 return std::nullopt;
8060 std::optional<APValue> visit(
const BuiltinType *
T, CharUnits Offset,
8061 const EnumType *EnumSugar =
nullptr) {
8064 return APValue((Expr *)
nullptr,
8066 APValue::NoLValuePath{},
true);
8075 const llvm::fltSemantics &Semantics =
8077 unsigned NumBits = llvm::APFloatBase::getSizeInBits(Semantics);
8078 assert(NumBits % 8 == 0);
8084 SmallVector<uint8_t, 8> Bytes;
8085 if (!Buffer.readObject(Offset,
SizeOf, Bytes)) {
8088 bool IsStdByte = EnumSugar && EnumSugar->isStdByteType();
8092 if (!IsStdByte && !IsUChar) {
8093 QualType DisplayType(EnumSugar ? (
const Type *)EnumSugar :
T, 0);
8095 diag::note_constexpr_bit_cast_indet_dest)
8096 << DisplayType << Info.Ctx.
getLangOpts().CharIsSigned;
8097 return std::nullopt;
8104 llvm::LoadIntFromMemory(Val, &*Bytes.begin(), Bytes.size());
8109 unsigned IntWidth = Info.Ctx.
getIntWidth(QualType(
T, 0));
8110 if (IntWidth != Val.getBitWidth()) {
8111 APSInt Truncated = Val.trunc(IntWidth);
8112 if (Truncated.extend(Val.getBitWidth()) != Val)
8113 return unrepresentableValue(QualType(
T, 0), Val);
8121 const llvm::fltSemantics &Semantics =
8126 return unsupportedType(QualType(
T, 0));
8129 std::optional<APValue> visit(
const RecordType *RTy, CharUnits Offset) {
8130 const RecordDecl *RD = RTy->getAsRecordDecl();
8133 unsigned NumBases = 0;
8134 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
8135 NumBases = CXXRD->getNumBases();
8140 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
8141 for (
size_t I = 0, E = CXXRD->getNumBases(); I != E; ++I) {
8142 const CXXBaseSpecifier &BS = CXXRD->bases_begin()[I];
8145 std::optional<APValue> SubObj = visitType(
8148 return std::nullopt;
8149 ResultVal.getStructBase(I) = *SubObj;
8154 unsigned FieldIdx = 0;
8155 for (FieldDecl *FD : RD->
fields()) {
8158 if (FD->isBitField()) {
8160 diag::note_constexpr_bit_cast_unsupported_bitfield);
8161 return std::nullopt;
8165 assert(FieldOffsetBits % Info.Ctx.
getCharWidth() == 0);
8167 CharUnits FieldOffset =
8170 QualType FieldTy = FD->getType();
8171 std::optional<APValue> SubObj = visitType(FieldTy, FieldOffset);
8173 return std::nullopt;
8174 ResultVal.getStructField(FieldIdx) = *SubObj;
8181 std::optional<APValue> visit(
const EnumType *Ty, CharUnits Offset) {
8182 QualType RepresentationType =
8183 Ty->getDecl()->getDefinitionOrSelf()->getIntegerType();
8184 assert(!RepresentationType.
isNull() &&
8185 "enum forward decl should be caught by Sema");
8186 const auto *AsBuiltin =
8190 return visit(AsBuiltin, Offset, Ty);
8193 std::optional<APValue> visit(
const ConstantArrayType *Ty, CharUnits Offset) {
8197 APValue ArrayValue(APValue::UninitArray(), Size, Size);
8198 for (
size_t I = 0; I !=
Size; ++I) {
8199 std::optional<APValue> ElementValue =
8202 return std::nullopt;
8203 ArrayValue.getArrayInitializedElt(I) = std::move(*ElementValue);
8209 std::optional<APValue> visit(
const ComplexType *Ty, CharUnits Offset) {
8214 std::optional<APValue> Values[2];
8215 for (
unsigned I = 0; I != 2; ++I) {
8216 Values[I] = visitType(Ty->
getElementType(), Offset + I * ElementWidth);
8218 return std::nullopt;
8222 return APValue(Values[0]->getInt(), Values[1]->getInt());
8223 return APValue(Values[0]->getFloat(), Values[1]->getFloat());
8226 std::optional<APValue> visit(
const VectorType *VTy, CharUnits Offset) {
8232 SmallVector<APValue, 4> Elts;
8233 Elts.reserve(NElts);
8245 SmallVector<uint8_t, 8> Bytes;
8246 Bytes.reserve(NElts / 8);
8248 return std::nullopt;
8250 APSInt SValInt(NElts,
true);
8251 llvm::LoadIntFromMemory(SValInt, &*Bytes.begin(), Bytes.size());
8253 for (
unsigned I = 0; I < NElts; ++I) {
8255 SValInt.extractBits(1, (BigEndian ? NElts - I - 1 : I) * EltSize);
8263 for (
unsigned I = 0; I < NElts; ++I) {
8264 std::optional<APValue> EltValue =
8265 visitType(EltTy, Offset + I * EltSizeChars);
8267 return std::nullopt;
8268 Elts.push_back(std::move(*EltValue));
8272 return APValue(Elts.data(), Elts.size());
8275 std::optional<APValue> visit(
const Type *Ty, CharUnits Offset) {
8276 return unsupportedType(QualType(Ty, 0));
8279 std::optional<APValue> visitType(QualType Ty, CharUnits Offset) {
8283#define TYPE(Class, Base) \
8285 return visit(cast<Class##Type>(Can.getTypePtr()), Offset);
8286#define ABSTRACT_TYPE(Class, Base)
8287#define NON_CANONICAL_TYPE(Class, Base) \
8289 llvm_unreachable("non-canonical type should be impossible!");
8290#define DEPENDENT_TYPE(Class, Base) \
8293 "dependent types aren't supported in the constant evaluator!");
8294#define NON_CANONICAL_UNLESS_DEPENDENT(Class, Base) \
8296 llvm_unreachable("either dependent or not canonical!");
8297#include "clang/AST/TypeNodes.inc"
8299 llvm_unreachable(
"Unhandled Type::TypeClass");
8304 static std::optional<APValue> convert(EvalInfo &Info, BitCastBuffer &Buffer,
8306 BufferToAPValueConverter Converter(Info, Buffer, BCE);
8311static bool checkBitCastConstexprEligibilityType(SourceLocation Loc,
8312 QualType Ty, EvalInfo *Info,
8313 const ASTContext &Ctx,
8314 bool CheckingDest) {
8317 auto diag = [&](
int Reason) {
8319 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_invalid_type)
8320 << CheckingDest << (Reason == 4) << Reason;
8323 auto note = [&](
int Construct, QualType NoteTy, SourceLocation NoteLoc) {
8325 Info->Note(NoteLoc, diag::note_constexpr_bit_cast_invalid_subtype)
8326 << NoteTy << Construct << Ty;
8340 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(
Record)) {
8341 for (CXXBaseSpecifier &BS : CXXRD->bases())
8342 if (!checkBitCastConstexprEligibilityType(Loc, BS.
getType(), Info, Ctx,
8346 for (FieldDecl *FD :
Record->fields()) {
8347 if (FD->getType()->isReferenceType())
8349 if (!checkBitCastConstexprEligibilityType(Loc, FD->getType(), Info, Ctx,
8351 return note(0, FD->getType(), FD->getBeginLoc());
8357 Info, Ctx, CheckingDest))
8360 if (
const auto *VTy = Ty->
getAs<VectorType>()) {
8372 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_invalid_vector)
8373 << QualType(VTy, 0) << EltSize << NElts << Ctx.
getCharWidth();
8383 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_unsupported_type)
8392static bool checkBitCastConstexprEligibility(EvalInfo *Info,
8393 const ASTContext &Ctx,
8395 bool DestOK = checkBitCastConstexprEligibilityType(
8397 bool SourceOK = DestOK && checkBitCastConstexprEligibilityType(
8403static bool handleRValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
8407 "no host or target supports non 8-bit chars");
8409 if (!checkBitCastConstexprEligibility(&Info, Info.Ctx, BCE))
8413 std::optional<BitCastBuffer> Buffer =
8414 APValueToBufferConverter::convert(Info, SourceRValue, BCE);
8419 std::optional<APValue> MaybeDestValue =
8420 BufferToAPValueConverter::convert(Info, *Buffer, BCE);
8421 if (!MaybeDestValue)
8424 DestValue = std::move(*MaybeDestValue);
8428static bool handleLValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
8432 "no host or target supports non 8-bit chars");
8434 "LValueToRValueBitcast requires an lvalue operand!");
8436 LValue SourceLValue;
8438 SourceLValue.setFrom(Info.Ctx, SourceValue);
8441 SourceRValue,
true))
8444 return handleRValueToRValueBitCast(Info, DestValue, SourceRValue, BCE);
8447template <
class Derived>
8448class ExprEvaluatorBase
8449 :
public ConstStmtVisitor<Derived, bool> {
8451 Derived &getDerived() {
return static_cast<Derived&
>(*this); }
8452 bool DerivedSuccess(
const APValue &
V,
const Expr *E) {
8453 return getDerived().Success(
V, E);
8455 bool DerivedZeroInitialization(
const Expr *E) {
8456 return getDerived().ZeroInitialization(E);
8462 template<
typename ConditionalOperator>
8463 void CheckPotentialConstantConditional(
const ConditionalOperator *E) {
8464 assert(Info.checkingPotentialConstantExpression());
8467 SmallVector<PartialDiagnosticAt, 8>
Diag;
8469 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
8476 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
8483 Error(E, diag::note_constexpr_conditional_never_const);
8487 template<
typename ConditionalOperator>
8488 bool HandleConditionalOperator(
const ConditionalOperator *E) {
8491 if (Info.checkingPotentialConstantExpression() && Info.noteFailure()) {
8492 CheckPotentialConstantConditional(E);
8495 if (Info.noteFailure()) {
8503 return StmtVisitorTy::Visit(EvalExpr);
8508 typedef ConstStmtVisitor<Derived, bool> StmtVisitorTy;
8509 typedef ExprEvaluatorBase ExprEvaluatorBaseTy;
8511 OptionalDiagnostic CCEDiag(
const Expr *E,
diag::kind D) {
8512 return Info.CCEDiag(E, D);
8515 bool ZeroInitialization(
const Expr *E) {
return Error(E); }
8517 bool IsConstantEvaluatedBuiltinCall(
const CallExpr *E) {
8519 return BuiltinOp != 0 &&
8524 ExprEvaluatorBase(EvalInfo &Info) : Info(Info) {}
8526 EvalInfo &getEvalInfo() {
return Info; }
8534 bool Error(
const Expr *E) {
8535 return Error(E, diag::note_invalid_subexpr_in_const_expr);
8538 bool VisitStmt(
const Stmt *) {
8539 llvm_unreachable(
"Expression evaluator should not be called on stmts");
8541 bool VisitExpr(
const Expr *E) {
8545 bool VisitEmbedExpr(
const EmbedExpr *E) {
8546 const auto It = E->
begin();
8547 return StmtVisitorTy::Visit(*It);
8550 bool VisitPredefinedExpr(
const PredefinedExpr *E) {
8553 bool VisitConstantExpr(
const ConstantExpr *E) {
8557 return StmtVisitorTy::Visit(E->
getSubExpr());
8560 bool VisitParenExpr(
const ParenExpr *E)
8561 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8562 bool VisitUnaryExtension(
const UnaryOperator *E)
8563 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8564 bool VisitUnaryPlus(
const UnaryOperator *E)
8565 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8566 bool VisitChooseExpr(
const ChooseExpr *E)
8568 bool VisitGenericSelectionExpr(
const GenericSelectionExpr *E)
8570 bool VisitSubstNonTypeTemplateParmExpr(
const SubstNonTypeTemplateParmExpr *E)
8572 bool VisitCXXDefaultArgExpr(
const CXXDefaultArgExpr *E) {
8573 TempVersionRAII RAII(*Info.CurrentCall);
8574 SourceLocExprScopeGuard Guard(E, Info.CurrentCall->CurSourceLocExprScope);
8575 return StmtVisitorTy::Visit(E->
getExpr());
8577 bool VisitCXXDefaultInitExpr(
const CXXDefaultInitExpr *E) {
8578 TempVersionRAII RAII(*Info.CurrentCall);
8582 SourceLocExprScopeGuard Guard(E, Info.CurrentCall->CurSourceLocExprScope);
8583 return StmtVisitorTy::Visit(E->
getExpr());
8586 bool VisitExprWithCleanups(
const ExprWithCleanups *E) {
8587 FullExpressionRAII Scope(Info);
8588 return StmtVisitorTy::Visit(E->
getSubExpr()) && Scope.destroy();
8593 bool VisitCXXBindTemporaryExpr(
const CXXBindTemporaryExpr *E) {
8594 return StmtVisitorTy::Visit(E->
getSubExpr());
8597 bool VisitCXXReinterpretCastExpr(
const CXXReinterpretCastExpr *E) {
8598 CCEDiag(E, diag::note_constexpr_invalid_cast)
8599 << diag::ConstexprInvalidCastKind::Reinterpret;
8600 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8602 bool VisitCXXDynamicCastExpr(
const CXXDynamicCastExpr *E) {
8604 CCEDiag(E, diag::note_constexpr_invalid_cast)
8605 << diag::ConstexprInvalidCastKind::Dynamic;
8606 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8608 bool VisitBuiltinBitCastExpr(
const BuiltinBitCastExpr *E) {
8609 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8612 bool VisitBinaryOperator(
const BinaryOperator *E) {
8618 VisitIgnoredValue(E->
getLHS());
8619 return StmtVisitorTy::Visit(E->
getRHS());
8629 return DerivedSuccess(
Result, E);
8634 bool VisitCXXRewrittenBinaryOperator(
const CXXRewrittenBinaryOperator *E) {
8638 bool VisitBinaryConditionalOperator(
const BinaryConditionalOperator *E) {
8642 if (!
Evaluate(Info.CurrentCall->createTemporary(
8645 ScopeKind::FullExpression, CommonLV),
8649 return HandleConditionalOperator(E);
8652 bool VisitConditionalOperator(
const ConditionalOperator *E) {
8653 bool IsBcpCall =
false;
8658 if (
const CallExpr *CallCE =
8660 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
8667 if (Info.checkingPotentialConstantExpression() && IsBcpCall)
8670 FoldConstant Fold(Info, IsBcpCall);
8671 if (!HandleConditionalOperator(E)) {
8672 Fold.keepDiagnostics();
8679 bool VisitOpaqueValueExpr(
const OpaqueValueExpr *E) {
8680 if (
APValue *
Value = Info.CurrentCall->getCurrentTemporary(E);
8682 return DerivedSuccess(*
Value, E);
8688 assert(0 &&
"OpaqueValueExpr recursively refers to itself");
8691 return StmtVisitorTy::Visit(Source);
8694 bool VisitPseudoObjectExpr(
const PseudoObjectExpr *E) {
8695 for (
const Expr *SemE : E->
semantics()) {
8696 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
8705 if (OVE->isUnique())
8709 if (!
Evaluate(Info.CurrentCall->createTemporary(
8710 OVE, getStorageType(Info.Ctx, OVE),
8711 ScopeKind::FullExpression, LV),
8712 Info, OVE->getSourceExpr()))
8715 if (!StmtVisitorTy::Visit(SemE))
8725 bool VisitCallExpr(
const CallExpr *E) {
8727 if (!handleCallExpr(E,
Result,
nullptr))
8729 return DerivedSuccess(
Result, E);
8733 const LValue *ResultSlot) {
8734 CallScopeRAII CallScope(Info);
8737 QualType CalleeType =
Callee->getType();
8739 const FunctionDecl *FD =
nullptr;
8740 LValue *
This =
nullptr, ObjectArg;
8742 bool HasQualifier =
false;
8748 const CXXMethodDecl *
Member =
nullptr;
8749 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(Callee)) {
8753 Member = dyn_cast<CXXMethodDecl>(ME->getMemberDecl());
8755 return Error(Callee);
8757 HasQualifier = ME->hasQualifier();
8758 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(Callee)) {
8760 const ValueDecl *D =
8764 Member = dyn_cast<CXXMethodDecl>(D);
8766 return Error(Callee);
8768 }
else if (
const auto *PDE = dyn_cast<CXXPseudoDestructorExpr>(Callee)) {
8769 if (!Info.getLangOpts().CPlusPlus20)
8770 Info.CCEDiag(PDE, diag::note_constexpr_pseudo_destructor);
8774 return Error(Callee);
8781 if (!CalleeLV.getLValueOffset().isZero())
8782 return Error(Callee);
8783 if (CalleeLV.isNullPointer()) {
8784 Info.FFDiag(Callee, diag::note_constexpr_null_callee)
8785 <<
const_cast<Expr *
>(
Callee);
8788 FD = dyn_cast_or_null<FunctionDecl>(
8789 CalleeLV.getLValueBase().dyn_cast<
const ValueDecl *>());
8791 return Error(Callee);
8801 auto *OCE = dyn_cast<CXXOperatorCallExpr>(E);
8802 if (OCE && OCE->isAssignmentOp()) {
8803 assert(Args.size() == 2 &&
"wrong number of arguments in assignment");
8804 Call = Info.CurrentCall->createCall(FD);
8805 bool HasThis =
false;
8806 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FD))
8807 HasThis = MD->isImplicitObjectMemberFunction();
8815 const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD);
8835 if (Info.getLangOpts().CPlusPlus20 && OCE &&
8836 OCE->getOperator() == OO_Equal && MD->
isTrivial() &&
8840 Args = Args.slice(1);
8846 const CXXRecordDecl *ClosureClass = MD->
getParent();
8848 ClosureClass->
captures().empty() &&
8849 "Number of captures must be zero for conversion to function-ptr");
8851 const CXXMethodDecl *LambdaCallOp =
8860 "A generic lambda's static-invoker function must be a "
8861 "template specialization");
8863 FunctionTemplateDecl *CallOpTemplate =
8865 void *InsertPos =
nullptr;
8866 FunctionDecl *CorrespondingCallOpSpecialization =
8868 assert(CorrespondingCallOpSpecialization &&
8869 "We must always have a function call operator specialization "
8870 "that corresponds to our static invoker specialization");
8872 FD = CorrespondingCallOpSpecialization;
8881 return CallScope.destroy();
8891 Call = Info.CurrentCall->createCall(FD);
8897 SmallVector<QualType, 4> CovariantAdjustmentPath;
8899 auto *NamedMember = dyn_cast<CXXMethodDecl>(FD);
8900 if (NamedMember && NamedMember->isVirtual() && !HasQualifier) {
8903 CovariantAdjustmentPath);
8906 }
else if (NamedMember && NamedMember->isImplicitObjectMemberFunction()) {
8916 if (
auto *DD = dyn_cast<CXXDestructorDecl>(FD)) {
8917 assert(This &&
"no 'this' pointer for destructor call");
8920 CallScope.destroy();
8937 if (!CovariantAdjustmentPath.empty() &&
8939 CovariantAdjustmentPath))
8942 return CallScope.destroy();
8945 bool VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E) {
8948 bool VisitInitListExpr(
const InitListExpr *E) {
8950 return DerivedZeroInitialization(E);
8952 return StmtVisitorTy::Visit(E->
getInit(0));
8955 bool VisitImplicitValueInitExpr(
const ImplicitValueInitExpr *E) {
8956 return DerivedZeroInitialization(E);
8958 bool VisitCXXScalarValueInitExpr(
const CXXScalarValueInitExpr *E) {
8959 return DerivedZeroInitialization(E);
8961 bool VisitCXXNullPtrLiteralExpr(
const CXXNullPtrLiteralExpr *E) {
8962 return DerivedZeroInitialization(E);
8966 bool VisitMemberExpr(
const MemberExpr *E) {
8968 "missing temporary materialization conversion");
8969 assert(!E->
isArrow() &&
"missing call to bound member function?");
8977 const FieldDecl *FD = dyn_cast<FieldDecl>(E->
getMemberDecl());
8978 if (!FD)
return Error(E);
8982 "record / field mismatch");
8987 CompleteObject Obj(APValue::LValueBase(), &Val, BaseTy);
8988 SubobjectDesignator Designator(BaseTy);
8989 Designator.addDeclUnchecked(FD);
8993 DerivedSuccess(
Result, E);
8996 bool VisitExtVectorElementExpr(
const ExtVectorElementExpr *E) {
9002 SmallVector<uint32_t, 4> Indices;
9004 if (Indices.size() == 1) {
9006 return DerivedSuccess(Val.
getVectorElt(Indices[0]), E);
9009 SmallVector<APValue, 4> Elts;
9010 for (
unsigned I = 0; I < Indices.size(); ++I) {
9013 APValue VecResult(Elts.data(), Indices.size());
9014 return DerivedSuccess(VecResult, E);
9021 bool VisitCastExpr(
const CastExpr *E) {
9026 case CK_AtomicToNonAtomic: {
9033 return DerivedSuccess(AtomicVal, E);
9037 case CK_UserDefinedConversion:
9038 return StmtVisitorTy::Visit(E->
getSubExpr());
9040 case CK_HLSLArrayRValue: {
9046 return DerivedSuccess(Val, E);
9057 return DerivedSuccess(RVal, E);
9059 case CK_LValueToRValue: {
9068 return DerivedSuccess(RVal, E);
9070 case CK_LValueToRValueBitCast: {
9071 APValue DestValue, SourceValue;
9074 if (!handleLValueToRValueBitCast(Info, DestValue, SourceValue, E))
9076 return DerivedSuccess(DestValue, E);
9079 case CK_AddressSpaceConversion: {
9083 return DerivedSuccess(
Value, E);
9090 bool VisitUnaryPostInc(
const UnaryOperator *UO) {
9091 return VisitUnaryPostIncDec(UO);
9093 bool VisitUnaryPostDec(
const UnaryOperator *UO) {
9094 return VisitUnaryPostIncDec(UO);
9096 bool VisitUnaryPostIncDec(
const UnaryOperator *UO) {
9097 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9107 return DerivedSuccess(RVal, UO);
9110 bool VisitStmtExpr(
const StmtExpr *E) {
9113 llvm::SaveAndRestore NotCheckingForUB(Info.CheckingForUndefinedBehavior,
9120 BlockScopeRAII Scope(Info);
9125 const Expr *FinalExpr = dyn_cast<Expr>(*BI);
9127 Info.FFDiag((*BI)->getBeginLoc(),
9128 diag::note_constexpr_stmt_expr_unsupported);
9131 return this->Visit(FinalExpr) && Scope.destroy();
9137 if (ESR != ESR_Succeeded) {
9141 if (ESR != ESR_Failed)
9142 Info.FFDiag((*BI)->getBeginLoc(),
9143 diag::note_constexpr_stmt_expr_unsupported);
9148 llvm_unreachable(
"Return from function from the loop above.");
9151 bool VisitPackIndexingExpr(
const PackIndexingExpr *E) {
9156 void VisitIgnoredValue(
const Expr *E) {
9161 void VisitIgnoredBaseExpression(
const Expr *E) {
9164 if (Info.getLangOpts().MSVCCompat && !E->
HasSideEffects(Info.Ctx))
9166 VisitIgnoredValue(E);
9176template<
class Derived>
9177class LValueExprEvaluatorBase
9178 :
public ExprEvaluatorBase<Derived> {
9182 typedef LValueExprEvaluatorBase LValueExprEvaluatorBaseTy;
9183 typedef ExprEvaluatorBase<Derived> ExprEvaluatorBaseTy;
9185 bool Success(APValue::LValueBase B) {
9190 bool evaluatePointer(
const Expr *E, LValue &
Result) {
9195 LValueExprEvaluatorBase(EvalInfo &Info, LValue &
Result,
bool InvalidBaseOK)
9197 InvalidBaseOK(InvalidBaseOK) {}
9200 Result.setFrom(this->Info.Ctx,
V);
9204 bool VisitMemberExpr(
const MemberExpr *E) {
9216 EvalOK = this->Visit(E->
getBase());
9227 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(E->
getMemberDecl())) {
9230 "record / field mismatch");
9234 }
else if (
const IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(MD)) {
9238 return this->
Error(E);
9250 bool VisitBinaryOperator(
const BinaryOperator *E) {
9253 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
9261 bool VisitCastExpr(
const CastExpr *E) {
9264 return ExprEvaluatorBaseTy::VisitCastExpr(E);
9266 case CK_DerivedToBase:
9267 case CK_UncheckedDerivedToBase:
9314class LValueExprEvaluator
9315 :
public LValueExprEvaluatorBase<LValueExprEvaluator> {
9317 LValueExprEvaluator(EvalInfo &Info, LValue &
Result,
bool InvalidBaseOK) :
9318 LValueExprEvaluatorBaseTy(Info,
Result, InvalidBaseOK) {}
9320 bool VisitVarDecl(
const Expr *E,
const VarDecl *VD);
9321 bool VisitUnaryPreIncDec(
const UnaryOperator *UO);
9323 bool VisitCallExpr(
const CallExpr *E);
9324 bool VisitDeclRefExpr(
const DeclRefExpr *E);
9325 bool VisitPredefinedExpr(
const PredefinedExpr *E) {
return Success(E); }
9326 bool VisitMaterializeTemporaryExpr(
const MaterializeTemporaryExpr *E);
9327 bool VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E);
9328 bool VisitMemberExpr(
const MemberExpr *E);
9329 bool VisitStringLiteral(
const StringLiteral *E) {
9330 return Success(APValue::LValueBase(
9331 E, 0, Info.getASTContext().getNextStringLiteralVersion()));
9333 bool VisitObjCEncodeExpr(
const ObjCEncodeExpr *E) {
return Success(E); }
9334 bool VisitCXXTypeidExpr(
const CXXTypeidExpr *E);
9335 bool VisitCXXUuidofExpr(
const CXXUuidofExpr *E);
9336 bool VisitArraySubscriptExpr(
const ArraySubscriptExpr *E);
9337 bool VisitExtVectorElementExpr(
const ExtVectorElementExpr *E);
9338 bool VisitUnaryDeref(
const UnaryOperator *E);
9339 bool VisitUnaryReal(
const UnaryOperator *E);
9340 bool VisitUnaryImag(
const UnaryOperator *E);
9341 bool VisitUnaryPreInc(
const UnaryOperator *UO) {
9342 return VisitUnaryPreIncDec(UO);
9344 bool VisitUnaryPreDec(
const UnaryOperator *UO) {
9345 return VisitUnaryPreIncDec(UO);
9347 bool VisitBinAssign(
const BinaryOperator *BO);
9348 bool VisitCompoundAssignOperator(
const CompoundAssignOperator *CAO);
9350 bool VisitCastExpr(
const CastExpr *E) {
9353 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
9355 case CK_LValueBitCast:
9356 this->CCEDiag(E, diag::note_constexpr_invalid_cast)
9357 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
9361 Result.Designator.setInvalid();
9364 case CK_BaseToDerived:
9381 bool LValueToRValueConversion) {
9385 assert(Info.CurrentCall->This ==
nullptr &&
9386 "This should not be set for a static call operator");
9394 if (
Self->getType()->isReferenceType()) {
9395 APValue *RefValue = Info.getParamSlot(Info.CurrentCall->Arguments,
Self);
9397 Result.setFrom(Info.Ctx, *RefValue);
9399 const ParmVarDecl *VD = Info.CurrentCall->Arguments.getOrigParam(
Self);
9400 CallStackFrame *Frame =
9401 Info.getCallFrameAndDepth(Info.CurrentCall->Arguments.CallIndex)
9403 unsigned Version = Info.CurrentCall->Arguments.Version;
9404 Result.set({VD, Frame->Index, Version});
9407 Result = *Info.CurrentCall->This;
9417 if (LValueToRValueConversion) {
9421 Result.setFrom(Info.Ctx, RVal);
9432 bool InvalidBaseOK) {
9436 return LValueExprEvaluator(Info, Result, InvalidBaseOK).Visit(E);
9439bool LValueExprEvaluator::VisitDeclRefExpr(
const DeclRefExpr *E) {
9440 const ValueDecl *D = E->
getDecl();
9452 if (Info.checkingPotentialConstantExpression())
9455 if (
auto *FD = Info.CurrentCall->LambdaCaptureFields.lookup(D)) {
9462 if (
isa<FunctionDecl, MSGuidDecl, TemplateParamObjectDecl,
9463 UnnamedGlobalConstantDecl>(D))
9465 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
9466 return VisitVarDecl(E, VD);
9467 if (
const BindingDecl *BD = dyn_cast<BindingDecl>(D))
9468 return Visit(BD->getBinding());
9472bool LValueExprEvaluator::VisitVarDecl(
const Expr *E,
const VarDecl *VD) {
9473 CallStackFrame *Frame =
nullptr;
9474 unsigned Version = 0;
9482 CallStackFrame *CurrFrame = Info.CurrentCall;
9487 if (
auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
9488 if (CurrFrame->Arguments) {
9489 VD = CurrFrame->Arguments.getOrigParam(PVD);
9491 Info.getCallFrameAndDepth(CurrFrame->Arguments.CallIndex).first;
9492 Version = CurrFrame->Arguments.Version;
9496 Version = CurrFrame->getCurrentTemporaryVersion(VD);
9503 Result.set({VD, Frame->Index, Version});
9509 if (!Info.getLangOpts().CPlusPlus11) {
9510 Info.CCEDiag(E, diag::note_constexpr_ltor_non_integral, 1)
9512 Info.Note(VD->
getLocation(), diag::note_declared_at);
9521 Result.AllowConstexprUnknown =
true;
9528bool LValueExprEvaluator::VisitCallExpr(
const CallExpr *E) {
9529 if (!IsConstantEvaluatedBuiltinCall(E))
9530 return ExprEvaluatorBaseTy::VisitCallExpr(E);
9535 case Builtin::BIas_const:
9536 case Builtin::BIforward:
9537 case Builtin::BIforward_like:
9538 case Builtin::BImove:
9539 case Builtin::BImove_if_noexcept:
9541 return Visit(E->
getArg(0));
9545 return ExprEvaluatorBaseTy::VisitCallExpr(E);
9548bool LValueExprEvaluator::VisitMaterializeTemporaryExpr(
9549 const MaterializeTemporaryExpr *E) {
9557 for (
const Expr *E : CommaLHSs)
9566 if (Info.EvalMode == EvaluationMode::ConstantFold)
9573 Value = &Info.CurrentCall->createTemporary(
9589 for (
unsigned I = Adjustments.size(); I != 0; ) {
9591 switch (Adjustments[I].Kind) {
9596 Type = Adjustments[I].DerivedToBase.BasePath->getType();
9602 Type = Adjustments[I].Field->getType();
9607 Adjustments[I].Ptr.RHS))
9609 Type = Adjustments[I].Ptr.MPT->getPointeeType();
9618LValueExprEvaluator::VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E) {
9619 assert((!Info.getLangOpts().CPlusPlus || E->
isFileScope()) &&
9620 "lvalue compound literal in c++?");
9632 assert(!Info.getLangOpts().CPlusPlus);
9634 ScopeKind::Block,
Result);
9646bool LValueExprEvaluator::VisitCXXTypeidExpr(
const CXXTypeidExpr *E) {
9647 TypeInfoLValue TypeInfo;
9656 Info.CCEDiag(E, diag::note_constexpr_typeid_polymorphic)
9664 std::optional<DynamicType> DynType =
9669 TypeInfo = TypeInfoLValue(
9676bool LValueExprEvaluator::VisitCXXUuidofExpr(
const CXXUuidofExpr *E) {
9680bool LValueExprEvaluator::VisitMemberExpr(
const MemberExpr *E) {
9682 if (
const VarDecl *VD = dyn_cast<VarDecl>(E->
getMemberDecl())) {
9683 VisitIgnoredBaseExpression(E->
getBase());
9684 return VisitVarDecl(E, VD);
9688 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(E->
getMemberDecl())) {
9689 if (MD->isStatic()) {
9690 VisitIgnoredBaseExpression(E->
getBase());
9696 return LValueExprEvaluatorBaseTy::VisitMemberExpr(E);
9699bool LValueExprEvaluator::VisitExtVectorElementExpr(
9700 const ExtVectorElementExpr *E) {
9705 if (!Info.noteFailure())
9713 if (Indices.size() > 1)
9717 Result.setFrom(Info.Ctx, Val);
9721 const auto *VT = BaseType->
castAs<VectorType>();
9723 VT->getNumElements(), Indices[0]);
9729bool LValueExprEvaluator::VisitArraySubscriptExpr(
const ArraySubscriptExpr *E) {
9739 if (!Info.noteFailure())
9745 if (!Info.noteFailure())
9751 Result.setFrom(Info.Ctx, Val);
9753 VT->getNumElements(), Index.getExtValue());
9761 for (
const Expr *SubExpr : {E->
getLHS(), E->
getRHS()}) {
9762 if (SubExpr == E->
getBase() ? !evaluatePointer(SubExpr,
Result)
9764 if (!Info.noteFailure())
9774bool LValueExprEvaluator::VisitUnaryDeref(
const UnaryOperator *E) {
9785 Info.noteUndefinedBehavior();
9788bool LValueExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
9797bool LValueExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
9799 "lvalue __imag__ on scalar?");
9806bool LValueExprEvaluator::VisitUnaryPreIncDec(
const UnaryOperator *UO) {
9807 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9818bool LValueExprEvaluator::VisitCompoundAssignOperator(
9819 const CompoundAssignOperator *CAO) {
9820 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9828 if (!Info.noteFailure())
9843bool LValueExprEvaluator::VisitBinAssign(
const BinaryOperator *E) {
9844 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9852 if (!Info.noteFailure())
9860 if (Info.getLangOpts().CPlusPlus20 &&
9876 llvm::APInt &Result) {
9877 assert(isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
9878 "Can't get the size of a non alloc_size function");
9879 const auto *
Base = LVal.getLValueBase().get<
const Expr *>();
9881 std::optional<llvm::APInt> Size =
9882 CE->evaluateBytesReturnedByAllocSizeCall(Ctx);
9886 Result = std::move(*Size);
9905 dyn_cast_or_null<VarDecl>(
Base.dyn_cast<
const ValueDecl *>());
9910 if (!
Init ||
Init->getType().isNull())
9913 const Expr *E =
Init->IgnoreParens();
9914 if (!tryUnwrapAllocSizeCall(E))
9919 Result.setInvalid(E);
9922 Result.addUnsizedArray(Info, E, Pointee);
9927class PointerExprEvaluator
9928 :
public ExprEvaluatorBase<PointerExprEvaluator> {
9937 bool evaluateLValue(
const Expr *E, LValue &
Result) {
9941 bool evaluatePointer(
const Expr *E, LValue &
Result) {
9945 bool visitNonBuiltinCallExpr(
const CallExpr *E);
9948 PointerExprEvaluator(EvalInfo &info, LValue &
Result,
bool InvalidBaseOK)
9950 InvalidBaseOK(InvalidBaseOK) {}
9956 bool ZeroInitialization(
const Expr *E) {
9961 bool VisitBinaryOperator(
const BinaryOperator *E);
9962 bool VisitCastExpr(
const CastExpr* E);
9963 bool VisitUnaryAddrOf(
const UnaryOperator *E);
9964 bool VisitObjCStringLiteral(
const ObjCStringLiteral *E)
9966 bool VisitObjCBoxedExpr(
const ObjCBoxedExpr *E) {
9969 if (Info.noteFailure())
9973 bool VisitAddrLabelExpr(
const AddrLabelExpr *E)
9975 bool VisitCallExpr(
const CallExpr *E);
9976 bool VisitBuiltinCallExpr(
const CallExpr *E,
unsigned BuiltinOp);
9977 bool VisitBlockExpr(
const BlockExpr *E) {
9982 bool VisitCXXThisExpr(
const CXXThisExpr *E) {
9983 auto DiagnoseInvalidUseOfThis = [&] {
9984 if (Info.getLangOpts().CPlusPlus11)
9985 Info.FFDiag(E, diag::note_constexpr_this) << E->
isImplicit();
9991 if (Info.checkingPotentialConstantExpression())
9994 bool IsExplicitLambda =
9996 if (!IsExplicitLambda) {
9997 if (!Info.CurrentCall->This) {
9998 DiagnoseInvalidUseOfThis();
10002 Result = *Info.CurrentCall->This;
10010 if (!Info.CurrentCall->LambdaThisCaptureField) {
10011 if (IsExplicitLambda && !Info.CurrentCall->This) {
10012 DiagnoseInvalidUseOfThis();
10021 Info, E,
Result, MD, Info.CurrentCall->LambdaThisCaptureField,
10027 bool VisitCXXNewExpr(
const CXXNewExpr *E);
10029 bool VisitSourceLocExpr(
const SourceLocExpr *E) {
10030 assert(!E->
isIntType() &&
"SourceLocExpr isn't a pointer type?");
10032 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.
getDefaultExpr());
10033 Result.setFrom(Info.Ctx, LValResult);
10037 bool VisitEmbedExpr(
const EmbedExpr *E) {
10038 llvm::report_fatal_error(
"Not yet implemented for ExprConstant.cpp");
10042 bool VisitSYCLUniqueStableNameExpr(
const SYCLUniqueStableNameExpr *E) {
10043 std::string ResultStr = E->
ComputeName(Info.Ctx);
10047 ResultStr.size() + 1);
10049 CharTy, Size,
nullptr, ArraySizeModifier::Normal, 0);
10051 StringLiteral *SL =
10052 StringLiteral::Create(Info.Ctx, ResultStr, StringLiteralKind::Ordinary,
10055 evaluateLValue(SL,
Result);
10065 bool InvalidBaseOK) {
10068 return PointerExprEvaluator(Info, Result, InvalidBaseOK).Visit(E);
10071bool PointerExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
10074 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
10076 const Expr *PExp = E->
getLHS();
10077 const Expr *IExp = E->
getRHS();
10079 std::swap(PExp, IExp);
10081 bool EvalPtrOK = evaluatePointer(PExp,
Result);
10082 if (!EvalPtrOK && !Info.noteFailure())
10085 llvm::APSInt Offset;
10096bool PointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
10105 if (!FnII || !FnII->
isStr(
"current"))
10108 const auto *RD = dyn_cast<RecordDecl>(FD->
getParent());
10116bool PointerExprEvaluator::VisitCastExpr(
const CastExpr *E) {
10123 case CK_CPointerToObjCPointerCast:
10124 case CK_BlockPointerToObjCPointerCast:
10125 case CK_AnyPointerToBlockPointerCast:
10126 case CK_AddressSpaceConversion:
10127 if (!Visit(SubExpr))
10133 CCEDiag(E, diag::note_constexpr_invalid_cast)
10134 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
10136 Result.Designator.setInvalid();
10144 bool HasValidResult = !
Result.InvalidBase && !
Result.Designator.Invalid &&
10146 bool VoidPtrCastMaybeOK =
10158 if (VoidPtrCastMaybeOK &&
10159 (Info.getStdAllocatorCaller(
"allocate") ||
10161 Info.getLangOpts().CPlusPlus26)) {
10165 Info.getLangOpts().CPlusPlus) {
10166 if (HasValidResult)
10167 CCEDiag(E, diag::note_constexpr_invalid_void_star_cast)
10168 << SubExpr->
getType() << Info.getLangOpts().CPlusPlus26
10169 <<
Result.Designator.getType(Info.Ctx).getCanonicalType()
10172 CCEDiag(E, diag::note_constexpr_invalid_cast)
10173 << diag::ConstexprInvalidCastKind::CastFrom
10176 CCEDiag(E, diag::note_constexpr_invalid_cast)
10177 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
10179 Result.Designator.setInvalid();
10183 ZeroInitialization(E);
10186 case CK_DerivedToBase:
10187 case CK_UncheckedDerivedToBase:
10199 case CK_BaseToDerived:
10211 case CK_NullToPointer:
10213 return ZeroInitialization(E);
10215 case CK_IntegralToPointer: {
10216 CCEDiag(E, diag::note_constexpr_invalid_cast)
10217 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
10224 if (
Value.isInt()) {
10226 uint64_t N =
Value.getInt().extOrTrunc(Size).getZExtValue();
10230 Result.Base = (Expr *)
nullptr;
10231 Result.InvalidBase =
false;
10233 Result.Designator.setInvalid();
10234 Result.IsNullPtr =
false;
10242 if (!
Value.isLValue())
10251 case CK_ArrayToPointerDecay: {
10253 if (!evaluateLValue(SubExpr,
Result))
10257 SubExpr, SubExpr->
getType(), ScopeKind::FullExpression,
Result);
10263 if (
auto *CAT = dyn_cast<ConstantArrayType>(AT))
10264 Result.addArray(Info, E, CAT);
10266 Result.addUnsizedArray(Info, E, AT->getElementType());
10270 case CK_FunctionToPointerDecay:
10271 return evaluateLValue(SubExpr,
Result);
10273 case CK_LValueToRValue: {
10282 return InvalidBaseOK &&
10288 return ExprEvaluatorBaseTy::VisitCastExpr(E);
10296 T =
T.getNonReferenceType();
10298 if (
T.getQualifiers().hasUnaligned())
10301 const bool AlignOfReturnsPreferred =
10302 Ctx.
getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver7;
10307 if (ExprKind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
10310 else if (ExprKind == UETT_AlignOf)
10313 llvm_unreachable(
"GetAlignOfType on a non-alignment ExprKind");
10326 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
10330 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(E))
10340 if (
const auto *E =
Value.Base.dyn_cast<
const Expr *>())
10348 EvalInfo &Info,
APSInt &Alignment) {
10351 if (Alignment < 0 || !Alignment.isPowerOf2()) {
10352 Info.FFDiag(E, diag::note_constexpr_invalid_alignment) << Alignment;
10355 unsigned SrcWidth = Info.Ctx.
getIntWidth(ForType);
10356 APSInt MaxValue(APInt::getOneBitSet(SrcWidth, SrcWidth - 1));
10357 if (APSInt::compareValues(Alignment, MaxValue) > 0) {
10358 Info.FFDiag(E, diag::note_constexpr_alignment_too_big)
10359 << MaxValue << ForType << Alignment;
10365 APSInt(Alignment.zextOrTrunc(SrcWidth),
true);
10366 assert(APSInt::compareValues(Alignment, ExtAlignment) == 0 &&
10367 "Alignment should not be changed by ext/trunc");
10368 Alignment = ExtAlignment;
10369 assert(Alignment.getBitWidth() == SrcWidth);
10374bool PointerExprEvaluator::visitNonBuiltinCallExpr(
const CallExpr *E) {
10375 if (ExprEvaluatorBaseTy::VisitCallExpr(E))
10383 Result.addUnsizedArray(Info, E, PointeeTy);
10387bool PointerExprEvaluator::VisitCallExpr(
const CallExpr *E) {
10388 if (!IsConstantEvaluatedBuiltinCall(E))
10389 return visitNonBuiltinCallExpr(E);
10396 return T->isCharType() ||
T->isChar8Type();
10399bool PointerExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *E,
10400 unsigned BuiltinOp) {
10404 switch (BuiltinOp) {
10405 case Builtin::BIaddressof:
10406 case Builtin::BI__addressof:
10407 case Builtin::BI__builtin_addressof:
10409 case Builtin::BI__builtin_assume_aligned: {
10416 LValue OffsetResult(
Result);
10428 int64_t AdditionalOffset = -Offset.getZExtValue();
10433 if (OffsetResult.Base) {
10436 if (BaseAlignment < Align) {
10437 Result.Designator.setInvalid();
10438 CCEDiag(E->
getArg(0), diag::note_constexpr_baa_insufficient_alignment)
10445 if (OffsetResult.Offset.alignTo(Align) != OffsetResult.Offset) {
10446 Result.Designator.setInvalid();
10450 diag::note_constexpr_baa_insufficient_alignment)
10453 diag::note_constexpr_baa_value_insufficient_alignment))
10454 << OffsetResult.Offset.getQuantity() << Align.
getQuantity();
10460 case Builtin::BI__builtin_align_up:
10461 case Builtin::BI__builtin_align_down: {
10481 assert(Alignment.getBitWidth() <= 64 &&
10482 "Cannot handle > 64-bit address-space");
10483 uint64_t Alignment64 = Alignment.getZExtValue();
10485 BuiltinOp == Builtin::BI__builtin_align_down
10486 ? llvm::alignDown(
Result.Offset.getQuantity(), Alignment64)
10487 : llvm::alignTo(
Result.Offset.getQuantity(), Alignment64));
10493 Info.FFDiag(E->
getArg(0), diag::note_constexpr_alignment_adjust)
10497 case Builtin::BI__builtin_operator_new:
10499 case Builtin::BI__builtin_launder:
10501 case Builtin::BIstrchr:
10502 case Builtin::BIwcschr:
10503 case Builtin::BImemchr:
10504 case Builtin::BIwmemchr:
10505 if (Info.getLangOpts().CPlusPlus11)
10506 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
10510 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
10512 case Builtin::BI__builtin_strchr:
10513 case Builtin::BI__builtin_wcschr:
10514 case Builtin::BI__builtin_memchr:
10515 case Builtin::BI__builtin_char_memchr:
10516 case Builtin::BI__builtin_wmemchr: {
10517 if (!Visit(E->
getArg(0)))
10523 if (BuiltinOp != Builtin::BIstrchr &&
10524 BuiltinOp != Builtin::BIwcschr &&
10525 BuiltinOp != Builtin::BI__builtin_strchr &&
10526 BuiltinOp != Builtin::BI__builtin_wcschr) {
10530 MaxLength = N.getZExtValue();
10533 if (MaxLength == 0u)
10534 return ZeroInitialization(E);
10535 if (!
Result.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
10536 Result.Designator.Invalid)
10538 QualType CharTy =
Result.Designator.getType(Info.Ctx);
10539 bool IsRawByte = BuiltinOp == Builtin::BImemchr ||
10540 BuiltinOp == Builtin::BI__builtin_memchr;
10541 assert(IsRawByte ||
10546 Info.FFDiag(E, diag::note_constexpr_ltor_incomplete_type) << CharTy;
10552 Info.FFDiag(E, diag::note_constexpr_memchr_unsupported)
10559 bool StopAtNull =
false;
10560 switch (BuiltinOp) {
10561 case Builtin::BIstrchr:
10562 case Builtin::BI__builtin_strchr:
10569 return ZeroInitialization(E);
10572 case Builtin::BImemchr:
10573 case Builtin::BI__builtin_memchr:
10574 case Builtin::BI__builtin_char_memchr:
10578 DesiredVal = Desired.trunc(Info.Ctx.
getCharWidth()).getZExtValue();
10581 case Builtin::BIwcschr:
10582 case Builtin::BI__builtin_wcschr:
10585 case Builtin::BIwmemchr:
10586 case Builtin::BI__builtin_wmemchr:
10588 DesiredVal = Desired.getZExtValue();
10592 for (; MaxLength; --MaxLength) {
10597 if (Char.
getInt().getZExtValue() == DesiredVal)
10599 if (StopAtNull && !Char.
getInt())
10605 return ZeroInitialization(E);
10608 case Builtin::BImemcpy:
10609 case Builtin::BImemmove:
10610 case Builtin::BIwmemcpy:
10611 case Builtin::BIwmemmove:
10612 if (Info.getLangOpts().CPlusPlus11)
10613 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
10617 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
10619 case Builtin::BI__builtin_memcpy:
10620 case Builtin::BI__builtin_memmove:
10621 case Builtin::BI__builtin_wmemcpy:
10622 case Builtin::BI__builtin_wmemmove: {
10623 bool WChar = BuiltinOp == Builtin::BIwmemcpy ||
10624 BuiltinOp == Builtin::BIwmemmove ||
10625 BuiltinOp == Builtin::BI__builtin_wmemcpy ||
10626 BuiltinOp == Builtin::BI__builtin_wmemmove;
10627 bool Move = BuiltinOp == Builtin::BImemmove ||
10628 BuiltinOp == Builtin::BIwmemmove ||
10629 BuiltinOp == Builtin::BI__builtin_memmove ||
10630 BuiltinOp == Builtin::BI__builtin_wmemmove;
10633 if (!Visit(E->
getArg(0)))
10644 assert(!N.isSigned() &&
"memcpy and friends take an unsigned size");
10654 if (!Src.Base || !Dest.Base) {
10656 (!Src.Base ? Src : Dest).moveInto(Val);
10657 Info.FFDiag(E, diag::note_constexpr_memcpy_null)
10658 <<
Move << WChar << !!Src.Base
10662 if (Src.Designator.Invalid || Dest.Designator.Invalid)
10668 QualType
T = Dest.Designator.getType(Info.Ctx);
10669 QualType SrcT = Src.Designator.getType(Info.Ctx);
10672 Info.FFDiag(E, diag::note_constexpr_memcpy_type_pun) <<
Move << SrcT <<
T;
10676 Info.FFDiag(E, diag::note_constexpr_memcpy_incomplete_type) <<
Move <<
T;
10679 if (!
T.isTriviallyCopyableType(Info.Ctx)) {
10680 Info.FFDiag(E, diag::note_constexpr_memcpy_nontrivial) <<
Move <<
T;
10690 llvm::APInt OrigN = N;
10691 llvm::APInt::udivrem(OrigN, TSize, N, Remainder);
10693 Info.FFDiag(E, diag::note_constexpr_memcpy_unsupported)
10695 << (unsigned)TSize;
10703 uint64_t RemainingSrcSize = Src.Designator.validIndexAdjustments().second;
10704 uint64_t RemainingDestSize = Dest.Designator.validIndexAdjustments().second;
10705 if (N.ugt(RemainingSrcSize) || N.ugt(RemainingDestSize)) {
10706 Info.FFDiag(E, diag::note_constexpr_memcpy_unsupported)
10707 <<
Move << WChar << (N.ugt(RemainingSrcSize) ? 1 : 2) <<
T
10711 uint64_t NElems = N.getZExtValue();
10717 uint64_t SrcOffset = Src.getLValueOffset().getQuantity();
10718 uint64_t DestOffset = Dest.getLValueOffset().getQuantity();
10719 if (DestOffset >= SrcOffset && DestOffset - SrcOffset < NBytes) {
10722 Info.FFDiag(E, diag::note_constexpr_memcpy_overlap) << WChar;
10730 }
else if (!Move && SrcOffset >= DestOffset &&
10731 SrcOffset - DestOffset < NBytes) {
10733 Info.FFDiag(E, diag::note_constexpr_memcpy_overlap) << WChar;
10762 QualType AllocType);
10765 const CXXConstructExpr *CCE,
10766 QualType AllocType);
10768bool PointerExprEvaluator::VisitCXXNewExpr(
const CXXNewExpr *E) {
10769 if (!Info.getLangOpts().CPlusPlus20)
10770 Info.CCEDiag(E, diag::note_constexpr_new);
10773 if (Info.SpeculativeEvaluationDepth)
10778 QualType TargetType = AllocType;
10780 bool IsNothrow =
false;
10781 bool IsPlacement =
false;
10799 }
else if (OperatorNew->isReservedGlobalPlacementOperator()) {
10800 if (Info.CurrentCall->isStdFunction() || Info.getLangOpts().CPlusPlus26 ||
10801 (Info.CurrentCall->CanEvalMSConstexpr &&
10802 OperatorNew->hasAttr<MSConstexprAttr>())) {
10805 if (
Result.Designator.Invalid)
10808 IsPlacement =
true;
10810 Info.FFDiag(E, diag::note_constexpr_new_placement)
10815 Info.FFDiag(E, diag::note_constexpr_new_placement)
10818 }
else if (!OperatorNew
10819 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
10820 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
10826 const InitListExpr *ResizedArrayILE =
nullptr;
10827 const CXXConstructExpr *ResizedArrayCCE =
nullptr;
10828 bool ValueInit =
false;
10830 if (std::optional<const Expr *> ArraySize = E->
getArraySize()) {
10831 const Expr *Stripped = *ArraySize;
10832 for (;
auto *ICE = dyn_cast<ImplicitCastExpr>(Stripped);
10833 Stripped = ICE->getSubExpr())
10834 if (ICE->getCastKind() != CK_NoOp &&
10835 ICE->getCastKind() != CK_IntegralCast)
10848 return ZeroInitialization(E);
10850 Info.FFDiag(*ArraySize, diag::note_constexpr_new_negative)
10851 <<
ArrayBound << (*ArraySize)->getSourceRange();
10857 if (!Info.CheckArraySize(ArraySize.value()->getExprLoc(),
10862 return ZeroInitialization(E);
10874 }
else if (
auto *CCE = dyn_cast<CXXConstructExpr>(
Init)) {
10875 ResizedArrayCCE = CCE;
10878 assert(CAT &&
"unexpected type for array initializer");
10882 llvm::APInt InitBound = CAT->
getSize().zext(Bits);
10883 llvm::APInt AllocBound =
ArrayBound.zext(Bits);
10884 if (InitBound.ugt(AllocBound)) {
10886 return ZeroInitialization(E);
10888 Info.FFDiag(*ArraySize, diag::note_constexpr_new_too_small)
10889 <<
toString(AllocBound, 10,
false)
10891 << (*ArraySize)->getSourceRange();
10897 if (InitBound != AllocBound)
10902 ArraySizeModifier::Normal, 0);
10905 "array allocation with non-array new");
10911 struct FindObjectHandler {
10914 QualType AllocType;
10918 typedef bool result_type;
10919 bool failed() {
return false; }
10920 bool checkConst(QualType QT) {
10922 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
10927 bool found(
APValue &Subobj, QualType SubobjType) {
10928 if (!checkConst(SubobjType))
10932 unsigned SubobjectSize = 1;
10933 unsigned AllocSize = 1;
10934 if (
auto *CAT = dyn_cast<ConstantArrayType>(AllocType))
10936 if (
auto *CAT = dyn_cast<ConstantArrayType>(SubobjType))
10938 if (SubobjectSize < AllocSize ||
10941 Info.FFDiag(E, diag::note_constexpr_placement_new_wrong_type)
10942 << SubobjType << AllocType;
10949 Info.FFDiag(E, diag::note_constexpr_construct_complex_elem);
10952 bool found(APFloat &
Value, QualType SubobjType) {
10953 Info.FFDiag(E, diag::note_constexpr_construct_complex_elem);
10956 } Handler = {Info, E, AllocType, AK,
nullptr};
10962 Val = Handler.Value;
10971 Val = Info.createHeapAlloc(E, AllocType,
Result);
10977 ImplicitValueInitExpr VIE(AllocType);
10980 }
else if (ResizedArrayILE) {
10984 }
else if (ResizedArrayCCE) {
11007class MemberPointerExprEvaluator
11008 :
public ExprEvaluatorBase<MemberPointerExprEvaluator> {
11011 bool Success(
const ValueDecl *D) {
11017 MemberPointerExprEvaluator(EvalInfo &Info, MemberPtr &
Result)
11024 bool ZeroInitialization(
const Expr *E) {
11025 return Success((
const ValueDecl*)
nullptr);
11028 bool VisitCastExpr(
const CastExpr *E);
11029 bool VisitUnaryAddrOf(
const UnaryOperator *E);
11037 return MemberPointerExprEvaluator(Info, Result).Visit(E);
11040bool MemberPointerExprEvaluator::VisitCastExpr(
const CastExpr *E) {
11043 return ExprEvaluatorBaseTy::VisitCastExpr(E);
11045 case CK_NullToMemberPointer:
11047 return ZeroInitialization(E);
11049 case CK_BaseToDerivedMemberPointer: {
11057 typedef std::reverse_iterator<CastExpr::path_const_iterator> ReverseIter;
11059 PathI != PathE; ++PathI) {
11060 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
11061 const CXXRecordDecl *Derived = (*PathI)->getType()->getAsCXXRecordDecl();
11062 if (!
Result.castToDerived(Derived))
11066 ->
castAs<MemberPointerType>()
11067 ->getMostRecentCXXRecordDecl()))
11072 case CK_DerivedToBaseMemberPointer:
11076 PathE = E->
path_end(); PathI != PathE; ++PathI) {
11077 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
11078 const CXXRecordDecl *
Base = (*PathI)->getType()->getAsCXXRecordDecl();
11079 if (!
Result.castToBase(Base))
11086bool MemberPointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
11097 class RecordExprEvaluator
11098 :
public ExprEvaluatorBase<RecordExprEvaluator> {
11099 const LValue &
This;
11103 RecordExprEvaluator(EvalInfo &info,
const LValue &This,
APValue &
Result)
11110 bool ZeroInitialization(
const Expr *E) {
11111 return ZeroInitialization(E, E->
getType());
11113 bool ZeroInitialization(
const Expr *E, QualType
T);
11115 bool VisitCallExpr(
const CallExpr *E) {
11116 return handleCallExpr(E,
Result, &This);
11118 bool VisitCastExpr(
const CastExpr *E);
11119 bool VisitInitListExpr(
const InitListExpr *E);
11120 bool VisitCXXConstructExpr(
const CXXConstructExpr *E) {
11121 return VisitCXXConstructExpr(E, E->
getType());
11124 bool VisitCXXInheritedCtorInitExpr(
const CXXInheritedCtorInitExpr *E);
11125 bool VisitCXXConstructExpr(
const CXXConstructExpr *E, QualType
T);
11126 bool VisitCXXStdInitializerListExpr(
const CXXStdInitializerListExpr *E);
11127 bool VisitBinCmp(
const BinaryOperator *E);
11128 bool VisitCXXParenListInitExpr(
const CXXParenListInitExpr *E);
11129 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
11130 ArrayRef<Expr *> Args);
11144 assert(!RD->
isUnion() &&
"Expected non-union class type");
11153 unsigned Index = 0;
11155 End = CD->
bases_end(); I != End; ++I, ++Index) {
11157 LValue Subobject =
This;
11161 Result.getStructBase(Index)))
11166 for (
const auto *I : RD->
fields()) {
11168 if (I->isUnnamedBitField() || I->getType()->isReferenceType())
11171 LValue Subobject =
This;
11177 Result.getStructField(I->getFieldIndex()), Info, Subobject, &VIE))
11184bool RecordExprEvaluator::ZeroInitialization(
const Expr *E, QualType
T) {
11191 while (I != RD->
field_end() && (*I)->isUnnamedBitField())
11198 LValue Subobject =
This;
11202 ImplicitValueInitExpr VIE(I->getType());
11207 Info.FFDiag(E, diag::note_constexpr_virtual_base) << RD;
11214bool RecordExprEvaluator::VisitCastExpr(
const CastExpr *E) {
11217 return ExprEvaluatorBaseTy::VisitCastExpr(E);
11219 case CK_ConstructorConversion:
11222 case CK_DerivedToBase:
11223 case CK_UncheckedDerivedToBase: {
11234 PathE = E->
path_end(); PathI != PathE; ++PathI) {
11235 assert(!(*PathI)->isVirtual() &&
"record rvalue with virtual base");
11236 const CXXRecordDecl *
Base = (*PathI)->getType()->getAsCXXRecordDecl();
11243 case CK_HLSLAggregateSplatCast: {
11263 case CK_HLSLElementwiseCast: {
11282bool RecordExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
11285 return VisitCXXParenListOrInitListExpr(E, E->
inits());
11288bool RecordExprEvaluator::VisitCXXParenListOrInitListExpr(
11293 auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
11295 EvalInfo::EvaluatingConstructorRAII EvalObj(
11297 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries},
11298 CXXRD && CXXRD->getNumBases());
11301 const FieldDecl *
Field;
11302 if (
auto *ILE = dyn_cast<InitListExpr>(ExprToVisit)) {
11303 Field = ILE->getInitializedFieldInUnion();
11304 }
else if (
auto *PLIE = dyn_cast<CXXParenListInitExpr>(ExprToVisit)) {
11305 Field = PLIE->getInitializedFieldInUnion();
11308 "Expression is neither an init list nor a C++ paren list");
11320 ImplicitValueInitExpr VIE(
Field->getType());
11321 const Expr *InitExpr = Args.empty() ? &VIE : Args[0];
11323 LValue Subobject =
This;
11328 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
11332 if (
Field->isBitField())
11342 Result =
APValue(APValue::UninitStruct(), CXXRD ? CXXRD->getNumBases() : 0,
11344 unsigned ElementNo = 0;
11348 if (CXXRD && CXXRD->getNumBases()) {
11349 for (
const auto &Base : CXXRD->bases()) {
11350 assert(ElementNo < Args.size() &&
"missing init for base class");
11351 const Expr *
Init = Args[ElementNo];
11353 LValue Subobject =
This;
11359 if (!Info.noteFailure())
11366 EvalObj.finishedConstructingBases();
11370 for (
const auto *Field : RD->
fields()) {
11373 if (
Field->isUnnamedBitField())
11376 LValue Subobject =
This;
11378 bool HaveInit = ElementNo < Args.size();
11383 Subobject, Field, &Layout))
11388 ImplicitValueInitExpr VIE(HaveInit ? Info.Ctx.
IntTy :
Field->getType());
11389 const Expr *
Init = HaveInit ? Args[ElementNo++] : &VIE;
11391 if (
Field->getType()->isIncompleteArrayType()) {
11396 Info.FFDiag(
Init, diag::note_constexpr_unsupported_flexible_array);
11403 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
11407 if (
Field->getType()->isReferenceType()) {
11411 if (!Info.noteFailure())
11416 (
Field->isBitField() &&
11418 if (!Info.noteFailure())
11424 EvalObj.finishedConstructingFields();
11429bool RecordExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E,
11439 return ZeroInitialization(E,
T);
11457 const Expr *SrcObj = E->
getArg(0);
11460 if (
const MaterializeTemporaryExpr *ME =
11461 dyn_cast<MaterializeTemporaryExpr>(SrcObj))
11462 return Visit(ME->getSubExpr());
11465 if (ZeroInit && !ZeroInitialization(E,
T))
11474bool RecordExprEvaluator::VisitCXXInheritedCtorInitExpr(
11475 const CXXInheritedCtorInitExpr *E) {
11476 if (!Info.CurrentCall) {
11477 assert(Info.checkingPotentialConstantExpression());
11496bool RecordExprEvaluator::VisitCXXStdInitializerListExpr(
11497 const CXXStdInitializerListExpr *E) {
11498 const ConstantArrayType *ArrayType =
11505 assert(ArrayType &&
"unexpected type for array initializer");
11508 Array.addArray(Info, E, ArrayType);
11512 Array.moveInto(
Result.getStructField(0));
11516 assert(Field !=
Record->field_end() &&
11519 "Expected std::initializer_list first field to be const E *");
11521 assert(Field !=
Record->field_end() &&
11522 "Expected std::initializer_list to have two fields");
11531 "Expected std::initializer_list second field to be const E *");
11536 Array.moveInto(
Result.getStructField(1));
11539 assert(++Field ==
Record->field_end() &&
11540 "Expected std::initializer_list to only have two fields");
11545bool RecordExprEvaluator::VisitLambdaExpr(
const LambdaExpr *E) {
11550 const size_t NumFields = ClosureClass->
getNumFields();
11554 "The number of lambda capture initializers should equal the number of "
11555 "fields within the closure type");
11563 for (
const auto *Field : ClosureClass->
fields()) {
11566 Expr *
const CurFieldInit = *CaptureInitIt++;
11573 LValue Subobject =
This;
11580 if (!Info.keepEvaluatingAfterFailure())
11589 APValue &Result, EvalInfo &Info) {
11592 "can't evaluate expression as a record rvalue");
11593 return RecordExprEvaluator(Info,
This, Result).Visit(E);
11604class TemporaryExprEvaluator
11605 :
public LValueExprEvaluatorBase<TemporaryExprEvaluator> {
11607 TemporaryExprEvaluator(EvalInfo &Info, LValue &
Result) :
11608 LValueExprEvaluatorBaseTy(Info,
Result,
false) {}
11611 bool VisitConstructExpr(
const Expr *E) {
11617 bool VisitCastExpr(
const CastExpr *E) {
11620 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
11622 case CK_ConstructorConversion:
11626 bool VisitInitListExpr(
const InitListExpr *E) {
11627 return VisitConstructExpr(E);
11629 bool VisitCXXConstructExpr(
const CXXConstructExpr *E) {
11630 return VisitConstructExpr(E);
11632 bool VisitCallExpr(
const CallExpr *E) {
11633 return VisitConstructExpr(E);
11635 bool VisitCXXStdInitializerListExpr(
const CXXStdInitializerListExpr *E) {
11636 return VisitConstructExpr(E);
11639 return VisitConstructExpr(E);
11648 return TemporaryExprEvaluator(Info, Result).Visit(E);
11656 class VectorExprEvaluator
11657 :
public ExprEvaluatorBase<VectorExprEvaluator> {
11664 bool Success(ArrayRef<APValue>
V,
const Expr *E) {
11665 assert(
V.size() == E->
getType()->
castAs<VectorType>()->getNumElements());
11671 assert(
V.isVector());
11675 bool ZeroInitialization(
const Expr *E);
11677 bool VisitUnaryReal(
const UnaryOperator *E)
11679 bool VisitCastExpr(
const CastExpr* E);
11680 bool VisitInitListExpr(
const InitListExpr *E);
11681 bool VisitUnaryImag(
const UnaryOperator *E);
11682 bool VisitBinaryOperator(
const BinaryOperator *E);
11683 bool VisitUnaryOperator(
const UnaryOperator *E);
11684 bool VisitCallExpr(
const CallExpr *E);
11685 bool VisitConvertVectorExpr(
const ConvertVectorExpr *E);
11686 bool VisitShuffleVectorExpr(
const ShuffleVectorExpr *E);
11695 "not a vector prvalue");
11696 return VectorExprEvaluator(Info, Result).Visit(E);
11700 assert(Val.
isVector() &&
"expected vector APValue");
11704 llvm::APInt
Result(NumElts, 0);
11706 for (
unsigned I = 0; I < NumElts; ++I) {
11708 assert(Elt.
isInt() &&
"expected integer element in bool vector");
11710 if (Elt.
getInt().getBoolValue())
11717bool VectorExprEvaluator::VisitCastExpr(
const CastExpr *E) {
11718 const VectorType *VTy = E->
getType()->
castAs<VectorType>();
11722 QualType SETy = SE->
getType();
11725 case CK_VectorSplat: {
11731 Val =
APValue(std::move(IntResult));
11736 Val =
APValue(std::move(FloatResult));
11753 Info.FFDiag(E, diag::note_constexpr_invalid_cast)
11754 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
11759 if (!handleRValueToRValueBitCast(Info,
Result, SVal, E))
11764 case CK_HLSLVectorTruncation: {
11769 for (
unsigned I = 0; I < NElts; I++)
11773 case CK_HLSLMatrixTruncation: {
11777 case CK_HLSLAggregateSplatCast: {
11794 case CK_HLSLElementwiseCast: {
11807 return Success(ResultEls, E);
11810 return ExprEvaluatorBaseTy::VisitCastExpr(E);
11815VectorExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
11832 unsigned CountInits = 0, CountElts = 0;
11833 while (CountElts < NumElements) {
11835 if (CountInits < NumInits
11841 for (
unsigned j = 0; j < vlen; j++)
11845 llvm::APSInt sInt(32);
11846 if (CountInits < NumInits) {
11851 Elements.push_back(
APValue(sInt));
11854 llvm::APFloat f(0.0);
11855 if (CountInits < NumInits) {
11860 Elements.push_back(
APValue(f));
11869VectorExprEvaluator::ZeroInitialization(
const Expr *E) {
11873 if (EltTy->isIntegerType())
11883bool VectorExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
11885 return ZeroInitialization(E);
11888bool VectorExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
11890 assert(Op != BO_PtrMemD && Op != BO_PtrMemI && Op != BO_Cmp &&
11891 "Operation not supported on vector types");
11893 if (Op == BO_Comma)
11894 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
11896 Expr *LHS = E->
getLHS();
11897 Expr *RHS = E->
getRHS();
11900 "Must both be vector types");
11903 assert(LHS->
getType()->
castAs<VectorType>()->getNumElements() ==
11907 "All operands must be the same size.");
11911 bool LHSOK =
Evaluate(LHSValue, Info, LHS);
11912 if (!LHSOK && !Info.noteFailure())
11914 if (!
Evaluate(RHSValue, Info, RHS) || !LHSOK)
11936 "Vector can only be int or float type");
11944 "Vector operator ~ can only be int");
11945 Elt.
getInt().flipAllBits();
11955 "Vector can only be int or float type");
11961 EltResult.setAllBits();
11963 EltResult.clearAllBits();
11969 return std::nullopt;
11973bool VectorExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
11979 const QualType ResultEltTy = VD->getElementType();
11983 if (!
Evaluate(SubExprValue, Info, SubExpr))
11996 "Vector length doesn't match type?");
11999 for (
unsigned EltNum = 0; EltNum < VD->getNumElements(); ++EltNum) {
12001 Info.Ctx, ResultEltTy, Op, SubExprValue.
getVectorElt(EltNum));
12004 ResultElements.push_back(*Elt);
12006 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12015 Result =
APValue(APFloat(0.0));
12017 DestTy, Result.getFloat());
12028 Result.getFloat());
12033 DestTy, Result.getInt());
12037 Info.FFDiag(E, diag::err_convertvector_constexpr_unsupported_vector_cast)
12038 << SourceTy << DestTy;
12043 llvm::function_ref<APInt(
const APSInt &)> PackFn) {
12052 assert(LHSVecLen != 0 && LHSVecLen == RHSVecLen &&
12053 "pack builtin LHSVecLen must equal to RHSVecLen");
12062 const unsigned SrcPerLane = 128 / SrcBits;
12063 const unsigned Lanes = LHSVecLen * SrcBits / 128;
12066 Out.reserve(LHSVecLen + RHSVecLen);
12068 for (
unsigned Lane = 0; Lane != Lanes; ++Lane) {
12069 unsigned base = Lane * SrcPerLane;
12070 for (
unsigned I = 0; I != SrcPerLane; ++I)
12073 for (
unsigned I = 0; I != SrcPerLane; ++I)
12078 Result =
APValue(Out.data(), Out.size());
12084 llvm::function_ref<std::pair<unsigned, int>(
unsigned,
unsigned)>
12091 unsigned ShuffleMask = 0;
12093 bool IsVectorMask =
false;
12094 bool IsSingleOperand = (
Call->getNumArgs() == 2);
12096 if (IsSingleOperand) {
12099 IsVectorMask =
true;
12108 ShuffleMask =
static_cast<unsigned>(MaskImm.getZExtValue());
12118 IsVectorMask =
true;
12127 ShuffleMask =
static_cast<unsigned>(MaskImm.getZExtValue());
12138 ResultElements.reserve(NumElts);
12140 for (
unsigned DstIdx = 0; DstIdx != NumElts; ++DstIdx) {
12141 if (IsVectorMask) {
12142 ShuffleMask =
static_cast<unsigned>(
12143 MaskVector.getVectorElt(DstIdx).getInt().getZExtValue());
12145 auto [SrcVecIdx, SrcIdx] = GetSourceIndex(DstIdx, ShuffleMask);
12151 ResultElements.push_back(
12158 ResultElements.push_back(
APValue());
12161 const APValue &Src = (SrcVecIdx == 0) ? A : B;
12166 Out =
APValue(ResultElements.data(), ResultElements.size());
12170 APFloat OrigVal,
APValue &Result) {
12172 if (OrigVal.isInfinity()) {
12173 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << 0;
12176 if (OrigVal.isNaN()) {
12177 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << 1;
12181 APFloat Val = OrigVal;
12182 bool LosesInfo =
false;
12183 APFloat::opStatus Status = Val.convert(
12184 APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven, &LosesInfo);
12186 if (LosesInfo || Val.isDenormal()) {
12187 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic_strict);
12191 if (Status != APFloat::opOK) {
12192 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
12201 llvm::function_ref<APInt(
const APInt &, uint64_t)> ShiftOp,
12202 llvm::function_ref<APInt(
const APInt &,
unsigned)> OverflowOp) {
12209 assert(
Call->getNumArgs() == 2);
12213 Call->getArg(1)->getType()->isVectorType());
12216 unsigned DestEltWidth = Source.getVectorElt(0).getInt().getBitWidth();
12217 unsigned DestLen = Source.getVectorLength();
12220 unsigned NumBitsInQWord = 64;
12221 unsigned NumCountElts = NumBitsInQWord / CountEltWidth;
12223 Result.reserve(DestLen);
12225 uint64_t CountLQWord = 0;
12226 for (
unsigned EltIdx = 0; EltIdx != NumCountElts; ++EltIdx) {
12228 CountLQWord |= (Elt << (EltIdx * CountEltWidth));
12231 for (
unsigned EltIdx = 0; EltIdx != DestLen; ++EltIdx) {
12232 APInt Elt = Source.getVectorElt(EltIdx).getInt();
12233 if (CountLQWord < DestEltWidth) {
12235 APValue(
APSInt(ShiftOp(Elt, CountLQWord), IsDestUnsigned)));
12238 APValue(
APSInt(OverflowOp(Elt, DestEltWidth), IsDestUnsigned)));
12241 Out =
APValue(Result.data(), Result.size());
12245bool VectorExprEvaluator::VisitCallExpr(
const CallExpr *E) {
12246 if (!IsConstantEvaluatedBuiltinCall(E))
12247 return ExprEvaluatorBaseTy::VisitCallExpr(E);
12249 auto EvaluateBinOpExpr =
12251 APValue SourceLHS, SourceRHS;
12257 QualType DestEltTy = DestTy->getElementType();
12258 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
12261 ResultElements.reserve(SourceLen);
12263 if (SourceRHS.
isInt()) {
12265 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12267 ResultElements.push_back(
12271 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12274 ResultElements.push_back(
12281 auto EvalSelectScalar = [&](
unsigned Len) ->
bool {
12289 bool TakeA0 = (Mask.getZExtValue() & 1u) != 0;
12293 for (
unsigned I = 1; I < Len; ++I)
12295 APValue V(Res.data(), Res.size());
12302 case Builtin::BI__builtin_elementwise_popcount:
12303 case Builtin::BI__builtin_elementwise_bitreverse: {
12308 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12311 ResultElements.reserve(SourceLen);
12313 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12316 case Builtin::BI__builtin_elementwise_popcount:
12317 ResultElements.push_back(
APValue(
12321 case Builtin::BI__builtin_elementwise_bitreverse:
12322 ResultElements.push_back(
12329 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12331 case Builtin::BI__builtin_elementwise_abs: {
12336 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12339 ResultElements.reserve(SourceLen);
12341 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12346 CurrentEle.getInt().
abs(),
12347 DestEltTy->isUnsignedIntegerOrEnumerationType()));
12348 ResultElements.push_back(Val);
12351 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12354 case Builtin::BI__builtin_elementwise_add_sat:
12355 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12356 return LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS);
12359 case Builtin::BI__builtin_elementwise_sub_sat:
12360 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12361 return LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
12364 case X86::BI__builtin_ia32_extract128i256:
12365 case X86::BI__builtin_ia32_vextractf128_pd256:
12366 case X86::BI__builtin_ia32_vextractf128_ps256:
12367 case X86::BI__builtin_ia32_vextractf128_si256: {
12368 APValue SourceVec, SourceImm;
12377 unsigned RetLen = RetVT->getNumElements();
12378 unsigned Idx = SourceImm.
getInt().getZExtValue() & 1;
12381 ResultElements.reserve(RetLen);
12383 for (
unsigned I = 0; I < RetLen; I++)
12384 ResultElements.push_back(SourceVec.
getVectorElt(Idx * RetLen + I));
12389 case X86::BI__builtin_ia32_extracti32x4_256_mask:
12390 case X86::BI__builtin_ia32_extractf32x4_256_mask:
12391 case X86::BI__builtin_ia32_extracti32x4_mask:
12392 case X86::BI__builtin_ia32_extractf32x4_mask:
12393 case X86::BI__builtin_ia32_extracti32x8_mask:
12394 case X86::BI__builtin_ia32_extractf32x8_mask:
12395 case X86::BI__builtin_ia32_extracti64x2_256_mask:
12396 case X86::BI__builtin_ia32_extractf64x2_256_mask:
12397 case X86::BI__builtin_ia32_extracti64x2_512_mask:
12398 case X86::BI__builtin_ia32_extractf64x2_512_mask:
12399 case X86::BI__builtin_ia32_extracti64x4_mask:
12400 case X86::BI__builtin_ia32_extractf64x4_mask: {
12411 unsigned RetLen = RetVT->getNumElements();
12416 unsigned Lanes = SrcLen / RetLen;
12417 unsigned Lane =
static_cast<unsigned>(Imm.getZExtValue() % Lanes);
12418 unsigned Base = Lane * RetLen;
12421 ResultElements.reserve(RetLen);
12422 for (
unsigned I = 0; I < RetLen; ++I) {
12424 ResultElements.push_back(SourceVec.
getVectorElt(Base + I));
12428 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12431 case clang::X86::BI__builtin_ia32_pavgb128:
12432 case clang::X86::BI__builtin_ia32_pavgw128:
12433 case clang::X86::BI__builtin_ia32_pavgb256:
12434 case clang::X86::BI__builtin_ia32_pavgw256:
12435 case clang::X86::BI__builtin_ia32_pavgb512:
12436 case clang::X86::BI__builtin_ia32_pavgw512:
12437 return EvaluateBinOpExpr(llvm::APIntOps::avgCeilU);
12439 case clang::X86::BI__builtin_ia32_pmulhrsw128:
12440 case clang::X86::BI__builtin_ia32_pmulhrsw256:
12441 case clang::X86::BI__builtin_ia32_pmulhrsw512:
12442 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12443 return (llvm::APIntOps::mulsExtended(LHS, RHS).ashr(14) + 1)
12444 .extractBits(16, 1);
12447 case clang::X86::BI__builtin_ia32_pmaddubsw128:
12448 case clang::X86::BI__builtin_ia32_pmaddubsw256:
12449 case clang::X86::BI__builtin_ia32_pmaddubsw512:
12450 case clang::X86::BI__builtin_ia32_pmaddwd128:
12451 case clang::X86::BI__builtin_ia32_pmaddwd256:
12452 case clang::X86::BI__builtin_ia32_pmaddwd512: {
12453 APValue SourceLHS, SourceRHS;
12459 QualType DestEltTy = DestTy->getElementType();
12461 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
12463 ResultElements.reserve(SourceLen / 2);
12465 for (
unsigned EltNum = 0; EltNum < SourceLen; EltNum += 2) {
12470 unsigned BitWidth = 2 * LoLHS.getBitWidth();
12473 case clang::X86::BI__builtin_ia32_pmaddubsw128:
12474 case clang::X86::BI__builtin_ia32_pmaddubsw256:
12475 case clang::X86::BI__builtin_ia32_pmaddubsw512:
12476 ResultElements.push_back(
APValue(
12477 APSInt((LoLHS.zext(BitWidth) * LoRHS.sext(BitWidth))
12478 .sadd_sat((HiLHS.zext(BitWidth) * HiRHS.sext(BitWidth))),
12481 case clang::X86::BI__builtin_ia32_pmaddwd128:
12482 case clang::X86::BI__builtin_ia32_pmaddwd256:
12483 case clang::X86::BI__builtin_ia32_pmaddwd512:
12484 ResultElements.push_back(
12485 APValue(
APSInt((LoLHS.sext(BitWidth) * LoRHS.sext(BitWidth)) +
12486 (HiLHS.sext(BitWidth) * HiRHS.sext(BitWidth)),
12492 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12495 case clang::X86::BI__builtin_ia32_pmulhuw128:
12496 case clang::X86::BI__builtin_ia32_pmulhuw256:
12497 case clang::X86::BI__builtin_ia32_pmulhuw512:
12498 return EvaluateBinOpExpr(llvm::APIntOps::mulhu);
12500 case clang::X86::BI__builtin_ia32_pmulhw128:
12501 case clang::X86::BI__builtin_ia32_pmulhw256:
12502 case clang::X86::BI__builtin_ia32_pmulhw512:
12503 return EvaluateBinOpExpr(llvm::APIntOps::mulhs);
12505 case clang::X86::BI__builtin_ia32_psllv2di:
12506 case clang::X86::BI__builtin_ia32_psllv4di:
12507 case clang::X86::BI__builtin_ia32_psllv4si:
12508 case clang::X86::BI__builtin_ia32_psllv8di:
12509 case clang::X86::BI__builtin_ia32_psllv8hi:
12510 case clang::X86::BI__builtin_ia32_psllv8si:
12511 case clang::X86::BI__builtin_ia32_psllv16hi:
12512 case clang::X86::BI__builtin_ia32_psllv16si:
12513 case clang::X86::BI__builtin_ia32_psllv32hi:
12514 case clang::X86::BI__builtin_ia32_psllwi128:
12515 case clang::X86::BI__builtin_ia32_pslldi128:
12516 case clang::X86::BI__builtin_ia32_psllqi128:
12517 case clang::X86::BI__builtin_ia32_psllwi256:
12518 case clang::X86::BI__builtin_ia32_pslldi256:
12519 case clang::X86::BI__builtin_ia32_psllqi256:
12520 case clang::X86::BI__builtin_ia32_psllwi512:
12521 case clang::X86::BI__builtin_ia32_pslldi512:
12522 case clang::X86::BI__builtin_ia32_psllqi512:
12523 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12524 if (RHS.uge(LHS.getBitWidth())) {
12525 return APInt::getZero(LHS.getBitWidth());
12527 return LHS.shl(RHS.getZExtValue());
12530 case clang::X86::BI__builtin_ia32_psrav4si:
12531 case clang::X86::BI__builtin_ia32_psrav8di:
12532 case clang::X86::BI__builtin_ia32_psrav8hi:
12533 case clang::X86::BI__builtin_ia32_psrav8si:
12534 case clang::X86::BI__builtin_ia32_psrav16hi:
12535 case clang::X86::BI__builtin_ia32_psrav16si:
12536 case clang::X86::BI__builtin_ia32_psrav32hi:
12537 case clang::X86::BI__builtin_ia32_psravq128:
12538 case clang::X86::BI__builtin_ia32_psravq256:
12539 case clang::X86::BI__builtin_ia32_psrawi128:
12540 case clang::X86::BI__builtin_ia32_psradi128:
12541 case clang::X86::BI__builtin_ia32_psraqi128:
12542 case clang::X86::BI__builtin_ia32_psrawi256:
12543 case clang::X86::BI__builtin_ia32_psradi256:
12544 case clang::X86::BI__builtin_ia32_psraqi256:
12545 case clang::X86::BI__builtin_ia32_psrawi512:
12546 case clang::X86::BI__builtin_ia32_psradi512:
12547 case clang::X86::BI__builtin_ia32_psraqi512:
12548 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12549 if (RHS.uge(LHS.getBitWidth())) {
12550 return LHS.ashr(LHS.getBitWidth() - 1);
12552 return LHS.ashr(RHS.getZExtValue());
12555 case clang::X86::BI__builtin_ia32_psrlv2di:
12556 case clang::X86::BI__builtin_ia32_psrlv4di:
12557 case clang::X86::BI__builtin_ia32_psrlv4si:
12558 case clang::X86::BI__builtin_ia32_psrlv8di:
12559 case clang::X86::BI__builtin_ia32_psrlv8hi:
12560 case clang::X86::BI__builtin_ia32_psrlv8si:
12561 case clang::X86::BI__builtin_ia32_psrlv16hi:
12562 case clang::X86::BI__builtin_ia32_psrlv16si:
12563 case clang::X86::BI__builtin_ia32_psrlv32hi:
12564 case clang::X86::BI__builtin_ia32_psrlwi128:
12565 case clang::X86::BI__builtin_ia32_psrldi128:
12566 case clang::X86::BI__builtin_ia32_psrlqi128:
12567 case clang::X86::BI__builtin_ia32_psrlwi256:
12568 case clang::X86::BI__builtin_ia32_psrldi256:
12569 case clang::X86::BI__builtin_ia32_psrlqi256:
12570 case clang::X86::BI__builtin_ia32_psrlwi512:
12571 case clang::X86::BI__builtin_ia32_psrldi512:
12572 case clang::X86::BI__builtin_ia32_psrlqi512:
12573 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12574 if (RHS.uge(LHS.getBitWidth())) {
12575 return APInt::getZero(LHS.getBitWidth());
12577 return LHS.lshr(RHS.getZExtValue());
12579 case X86::BI__builtin_ia32_packsswb128:
12580 case X86::BI__builtin_ia32_packsswb256:
12581 case X86::BI__builtin_ia32_packsswb512:
12582 case X86::BI__builtin_ia32_packssdw128:
12583 case X86::BI__builtin_ia32_packssdw256:
12584 case X86::BI__builtin_ia32_packssdw512:
12586 return APSInt(Src).truncSSat(Src.getBitWidth() / 2);
12588 case X86::BI__builtin_ia32_packusdw128:
12589 case X86::BI__builtin_ia32_packusdw256:
12590 case X86::BI__builtin_ia32_packusdw512:
12591 case X86::BI__builtin_ia32_packuswb128:
12592 case X86::BI__builtin_ia32_packuswb256:
12593 case X86::BI__builtin_ia32_packuswb512:
12595 unsigned DstBits = Src.getBitWidth() / 2;
12596 if (Src.isNegative())
12597 return APInt::getZero(DstBits);
12598 if (Src.isIntN(DstBits))
12600 return APInt::getAllOnes(DstBits);
12602 case clang::X86::BI__builtin_ia32_selectss_128:
12603 return EvalSelectScalar(4);
12604 case clang::X86::BI__builtin_ia32_selectsd_128:
12605 return EvalSelectScalar(2);
12606 case clang::X86::BI__builtin_ia32_selectsh_128:
12607 case clang::X86::BI__builtin_ia32_selectsbf_128:
12608 return EvalSelectScalar(8);
12609 case clang::X86::BI__builtin_ia32_pmuldq128:
12610 case clang::X86::BI__builtin_ia32_pmuldq256:
12611 case clang::X86::BI__builtin_ia32_pmuldq512:
12612 case clang::X86::BI__builtin_ia32_pmuludq128:
12613 case clang::X86::BI__builtin_ia32_pmuludq256:
12614 case clang::X86::BI__builtin_ia32_pmuludq512: {
12615 APValue SourceLHS, SourceRHS;
12622 ResultElements.reserve(SourceLen / 2);
12624 for (
unsigned EltNum = 0; EltNum < SourceLen; EltNum += 2) {
12629 case clang::X86::BI__builtin_ia32_pmuludq128:
12630 case clang::X86::BI__builtin_ia32_pmuludq256:
12631 case clang::X86::BI__builtin_ia32_pmuludq512:
12632 ResultElements.push_back(
12633 APValue(
APSInt(llvm::APIntOps::muluExtended(LHS, RHS),
true)));
12635 case clang::X86::BI__builtin_ia32_pmuldq128:
12636 case clang::X86::BI__builtin_ia32_pmuldq256:
12637 case clang::X86::BI__builtin_ia32_pmuldq512:
12638 ResultElements.push_back(
12639 APValue(
APSInt(llvm::APIntOps::mulsExtended(LHS, RHS),
false)));
12644 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12647 case X86::BI__builtin_ia32_vpmadd52luq128:
12648 case X86::BI__builtin_ia32_vpmadd52luq256:
12649 case X86::BI__builtin_ia32_vpmadd52luq512: {
12658 ResultElements.reserve(ALen);
12660 for (
unsigned EltNum = 0; EltNum < ALen; EltNum += 1) {
12663 APInt CElt =
C.getVectorElt(EltNum).getInt().trunc(52);
12664 APSInt ResElt(AElt + (BElt * CElt).zext(64),
false);
12665 ResultElements.push_back(
APValue(ResElt));
12668 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12670 case X86::BI__builtin_ia32_vpmadd52huq128:
12671 case X86::BI__builtin_ia32_vpmadd52huq256:
12672 case X86::BI__builtin_ia32_vpmadd52huq512: {
12681 ResultElements.reserve(ALen);
12683 for (
unsigned EltNum = 0; EltNum < ALen; EltNum += 1) {
12686 APInt CElt =
C.getVectorElt(EltNum).getInt().trunc(52);
12687 APSInt ResElt(AElt + llvm::APIntOps::mulhu(BElt, CElt).zext(64),
false);
12688 ResultElements.push_back(
APValue(ResElt));
12691 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12694 case clang::X86::BI__builtin_ia32_vprotbi:
12695 case clang::X86::BI__builtin_ia32_vprotdi:
12696 case clang::X86::BI__builtin_ia32_vprotqi:
12697 case clang::X86::BI__builtin_ia32_vprotwi:
12698 case clang::X86::BI__builtin_ia32_prold128:
12699 case clang::X86::BI__builtin_ia32_prold256:
12700 case clang::X86::BI__builtin_ia32_prold512:
12701 case clang::X86::BI__builtin_ia32_prolq128:
12702 case clang::X86::BI__builtin_ia32_prolq256:
12703 case clang::X86::BI__builtin_ia32_prolq512:
12704 return EvaluateBinOpExpr(
12705 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS.rotl(RHS); });
12707 case clang::X86::BI__builtin_ia32_prord128:
12708 case clang::X86::BI__builtin_ia32_prord256:
12709 case clang::X86::BI__builtin_ia32_prord512:
12710 case clang::X86::BI__builtin_ia32_prorq128:
12711 case clang::X86::BI__builtin_ia32_prorq256:
12712 case clang::X86::BI__builtin_ia32_prorq512:
12713 return EvaluateBinOpExpr(
12714 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS.rotr(RHS); });
12716 case Builtin::BI__builtin_elementwise_max:
12717 case Builtin::BI__builtin_elementwise_min: {
12718 APValue SourceLHS, SourceRHS;
12723 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12730 ResultElements.reserve(SourceLen);
12732 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12736 case Builtin::BI__builtin_elementwise_max:
12737 ResultElements.push_back(
12741 case Builtin::BI__builtin_elementwise_min:
12742 ResultElements.push_back(
12749 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12751 case X86::BI__builtin_ia32_vpshldd128:
12752 case X86::BI__builtin_ia32_vpshldd256:
12753 case X86::BI__builtin_ia32_vpshldd512:
12754 case X86::BI__builtin_ia32_vpshldq128:
12755 case X86::BI__builtin_ia32_vpshldq256:
12756 case X86::BI__builtin_ia32_vpshldq512:
12757 case X86::BI__builtin_ia32_vpshldw128:
12758 case X86::BI__builtin_ia32_vpshldw256:
12759 case X86::BI__builtin_ia32_vpshldw512: {
12760 APValue SourceHi, SourceLo, SourceAmt;
12766 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12769 ResultElements.reserve(SourceLen);
12772 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12775 APInt R = llvm::APIntOps::fshl(Hi, Lo, Amt);
12776 ResultElements.push_back(
12780 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12782 case X86::BI__builtin_ia32_vpshrdd128:
12783 case X86::BI__builtin_ia32_vpshrdd256:
12784 case X86::BI__builtin_ia32_vpshrdd512:
12785 case X86::BI__builtin_ia32_vpshrdq128:
12786 case X86::BI__builtin_ia32_vpshrdq256:
12787 case X86::BI__builtin_ia32_vpshrdq512:
12788 case X86::BI__builtin_ia32_vpshrdw128:
12789 case X86::BI__builtin_ia32_vpshrdw256:
12790 case X86::BI__builtin_ia32_vpshrdw512: {
12792 APValue SourceHi, SourceLo, SourceAmt;
12798 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12801 ResultElements.reserve(SourceLen);
12804 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12807 APInt R = llvm::APIntOps::fshr(Hi, Lo, Amt);
12808 ResultElements.push_back(
12812 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12814 case X86::BI__builtin_ia32_vpconflictsi_128:
12815 case X86::BI__builtin_ia32_vpconflictsi_256:
12816 case X86::BI__builtin_ia32_vpconflictsi_512:
12817 case X86::BI__builtin_ia32_vpconflictdi_128:
12818 case X86::BI__builtin_ia32_vpconflictdi_256:
12819 case X86::BI__builtin_ia32_vpconflictdi_512: {
12827 ResultElements.reserve(SourceLen);
12830 bool DestUnsigned =
12831 VecT->getElementType()->isUnsignedIntegerOrEnumerationType();
12833 for (
unsigned I = 0; I != SourceLen; ++I) {
12836 APInt ConflictMask(EltI.
getInt().getBitWidth(), 0);
12837 for (
unsigned J = 0; J != I; ++J) {
12839 ConflictMask.setBitVal(J, EltI.
getInt() == EltJ.
getInt());
12841 ResultElements.push_back(
APValue(
APSInt(ConflictMask, DestUnsigned)));
12843 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12845 case X86::BI__builtin_ia32_blendpd:
12846 case X86::BI__builtin_ia32_blendpd256:
12847 case X86::BI__builtin_ia32_blendps:
12848 case X86::BI__builtin_ia32_blendps256:
12849 case X86::BI__builtin_ia32_pblendw128:
12850 case X86::BI__builtin_ia32_pblendw256:
12851 case X86::BI__builtin_ia32_pblendd128:
12852 case X86::BI__builtin_ia32_pblendd256: {
12853 APValue SourceF, SourceT, SourceC;
12862 ResultElements.reserve(SourceLen);
12863 for (
unsigned EltNum = 0; EltNum != SourceLen; ++EltNum) {
12866 ResultElements.push_back(
C[EltNum % 8] ?
T : F);
12869 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12872 case X86::BI__builtin_ia32_psignb128:
12873 case X86::BI__builtin_ia32_psignb256:
12874 case X86::BI__builtin_ia32_psignw128:
12875 case X86::BI__builtin_ia32_psignw256:
12876 case X86::BI__builtin_ia32_psignd128:
12877 case X86::BI__builtin_ia32_psignd256:
12878 return EvaluateBinOpExpr([](
const APInt &AElem,
const APInt &BElem) {
12879 if (BElem.isZero())
12880 return APInt::getZero(AElem.getBitWidth());
12881 if (BElem.isNegative())
12886 case X86::BI__builtin_ia32_blendvpd:
12887 case X86::BI__builtin_ia32_blendvpd256:
12888 case X86::BI__builtin_ia32_blendvps:
12889 case X86::BI__builtin_ia32_blendvps256:
12890 case X86::BI__builtin_ia32_pblendvb128:
12891 case X86::BI__builtin_ia32_pblendvb256: {
12893 APValue SourceF, SourceT, SourceC;
12901 ResultElements.reserve(SourceLen);
12903 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12907 APInt M =
C.isInt() ? (
APInt)
C.getInt() :
C.getFloat().bitcastToAPInt();
12908 ResultElements.push_back(M.isNegative() ?
T : F);
12911 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12913 case X86::BI__builtin_ia32_selectb_128:
12914 case X86::BI__builtin_ia32_selectb_256:
12915 case X86::BI__builtin_ia32_selectb_512:
12916 case X86::BI__builtin_ia32_selectw_128:
12917 case X86::BI__builtin_ia32_selectw_256:
12918 case X86::BI__builtin_ia32_selectw_512:
12919 case X86::BI__builtin_ia32_selectd_128:
12920 case X86::BI__builtin_ia32_selectd_256:
12921 case X86::BI__builtin_ia32_selectd_512:
12922 case X86::BI__builtin_ia32_selectq_128:
12923 case X86::BI__builtin_ia32_selectq_256:
12924 case X86::BI__builtin_ia32_selectq_512:
12925 case X86::BI__builtin_ia32_selectph_128:
12926 case X86::BI__builtin_ia32_selectph_256:
12927 case X86::BI__builtin_ia32_selectph_512:
12928 case X86::BI__builtin_ia32_selectpbf_128:
12929 case X86::BI__builtin_ia32_selectpbf_256:
12930 case X86::BI__builtin_ia32_selectpbf_512:
12931 case X86::BI__builtin_ia32_selectps_128:
12932 case X86::BI__builtin_ia32_selectps_256:
12933 case X86::BI__builtin_ia32_selectps_512:
12934 case X86::BI__builtin_ia32_selectpd_128:
12935 case X86::BI__builtin_ia32_selectpd_256:
12936 case X86::BI__builtin_ia32_selectpd_512: {
12938 APValue SourceMask, SourceLHS, SourceRHS;
12947 ResultElements.reserve(SourceLen);
12949 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12952 ResultElements.push_back(Mask[EltNum] ? LHS : RHS);
12955 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12958 case X86::BI__builtin_ia32_cvtsd2ss: {
12971 Elements.push_back(ResultVal);
12974 for (
unsigned I = 1; I < NumEltsA; ++I) {
12980 case X86::BI__builtin_ia32_cvtsd2ss_round_mask: {
12981 APValue VecA, VecB, VecSrc, MaskValue;
12989 unsigned Mask = MaskValue.
getInt().getZExtValue();
12997 Elements.push_back(ResultVal);
13003 for (
unsigned I = 1; I < NumEltsA; ++I) {
13009 case X86::BI__builtin_ia32_cvtpd2ps:
13010 case X86::BI__builtin_ia32_cvtpd2ps256:
13011 case X86::BI__builtin_ia32_cvtpd2ps_mask:
13012 case X86::BI__builtin_ia32_cvtpd2ps512_mask: {
13015 bool IsMasked = (BuiltinID == X86::BI__builtin_ia32_cvtpd2ps_mask ||
13016 BuiltinID == X86::BI__builtin_ia32_cvtpd2ps512_mask);
13023 unsigned Mask = 0xFFFFFFFF;
13024 bool NeedsMerge =
false;
13029 Mask = MaskValue.
getInt().getZExtValue();
13030 auto NumEltsResult = E->
getType()->
getAs<VectorType>()->getNumElements();
13031 for (
unsigned I = 0; I < NumEltsResult; ++I) {
13032 if (!((Mask >> I) & 1)) {
13043 unsigned NumEltsResult =
13047 for (
unsigned I = 0; I < NumEltsResult; ++I) {
13048 if (IsMasked && !((Mask >> I) & 1)) {
13056 if (I >= NumEltsInput) {
13057 Elements.push_back(
APValue(APFloat::getZero(APFloat::IEEEsingle())));
13066 Elements.push_back(ResultVal);
13071 case X86::BI__builtin_ia32_shufps:
13072 case X86::BI__builtin_ia32_shufps256:
13073 case X86::BI__builtin_ia32_shufps512: {
13077 [](
unsigned DstIdx,
13078 unsigned ShuffleMask) -> std::pair<unsigned, int> {
13079 constexpr unsigned LaneBits = 128u;
13080 unsigned NumElemPerLane = LaneBits / 32;
13081 unsigned NumSelectableElems = NumElemPerLane / 2;
13082 unsigned BitsPerElem = 2;
13083 unsigned IndexMask = (1u << BitsPerElem) - 1;
13084 unsigned MaskBits = 8;
13085 unsigned Lane = DstIdx / NumElemPerLane;
13086 unsigned ElemInLane = DstIdx % NumElemPerLane;
13087 unsigned LaneOffset = Lane * NumElemPerLane;
13088 unsigned BitIndex = (DstIdx * BitsPerElem) % MaskBits;
13089 unsigned SrcIdx = (ElemInLane < NumSelectableElems) ? 0 : 1;
13090 unsigned Index = (ShuffleMask >> BitIndex) & IndexMask;
13091 return {SrcIdx,
static_cast<int>(LaneOffset + Index)};
13096 case X86::BI__builtin_ia32_shufpd:
13097 case X86::BI__builtin_ia32_shufpd256:
13098 case X86::BI__builtin_ia32_shufpd512: {
13102 [](
unsigned DstIdx,
13103 unsigned ShuffleMask) -> std::pair<unsigned, int> {
13104 constexpr unsigned LaneBits = 128u;
13105 unsigned NumElemPerLane = LaneBits / 64;
13106 unsigned NumSelectableElems = NumElemPerLane / 2;
13107 unsigned BitsPerElem = 1;
13108 unsigned IndexMask = (1u << BitsPerElem) - 1;
13109 unsigned MaskBits = 8;
13110 unsigned Lane = DstIdx / NumElemPerLane;
13111 unsigned ElemInLane = DstIdx % NumElemPerLane;
13112 unsigned LaneOffset = Lane * NumElemPerLane;
13113 unsigned BitIndex = (DstIdx * BitsPerElem) % MaskBits;
13114 unsigned SrcIdx = (ElemInLane < NumSelectableElems) ? 0 : 1;
13115 unsigned Index = (ShuffleMask >> BitIndex) & IndexMask;
13116 return {SrcIdx,
static_cast<int>(LaneOffset + Index)};
13121 case X86::BI__builtin_ia32_insertps128: {
13125 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13127 if ((Mask & (1 << DstIdx)) != 0) {
13132 unsigned SrcElem = (Mask >> 6) & 0x3;
13133 unsigned DstElem = (Mask >> 4) & 0x3;
13134 if (DstIdx == DstElem) {
13136 return {1,
static_cast<int>(SrcElem)};
13139 return {0,
static_cast<int>(DstIdx)};
13145 case X86::BI__builtin_ia32_pshufb128:
13146 case X86::BI__builtin_ia32_pshufb256:
13147 case X86::BI__builtin_ia32_pshufb512: {
13151 [](
unsigned DstIdx,
13152 unsigned ShuffleMask) -> std::pair<unsigned, int> {
13153 uint8_t Ctlb =
static_cast<uint8_t
>(ShuffleMask);
13155 return std::make_pair(0, -1);
13157 unsigned LaneBase = (DstIdx / 16) * 16;
13158 unsigned SrcOffset = Ctlb & 0x0F;
13159 unsigned SrcIdx = LaneBase + SrcOffset;
13160 return std::make_pair(0,
static_cast<int>(SrcIdx));
13166 case X86::BI__builtin_ia32_pshuflw:
13167 case X86::BI__builtin_ia32_pshuflw256:
13168 case X86::BI__builtin_ia32_pshuflw512: {
13172 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13173 constexpr unsigned LaneBits = 128u;
13174 constexpr unsigned ElemBits = 16u;
13175 constexpr unsigned LaneElts = LaneBits / ElemBits;
13176 constexpr unsigned HalfSize = 4;
13177 unsigned LaneBase = (DstIdx / LaneElts) * LaneElts;
13178 unsigned LaneIdx = DstIdx % LaneElts;
13179 if (LaneIdx < HalfSize) {
13180 unsigned Sel = (Mask >> (2 * LaneIdx)) & 0x3;
13181 return std::make_pair(0,
static_cast<int>(LaneBase + Sel));
13183 return std::make_pair(0,
static_cast<int>(DstIdx));
13189 case X86::BI__builtin_ia32_pshufhw:
13190 case X86::BI__builtin_ia32_pshufhw256:
13191 case X86::BI__builtin_ia32_pshufhw512: {
13195 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13196 constexpr unsigned LaneBits = 128u;
13197 constexpr unsigned ElemBits = 16u;
13198 constexpr unsigned LaneElts = LaneBits / ElemBits;
13199 constexpr unsigned HalfSize = 4;
13200 unsigned LaneBase = (DstIdx / LaneElts) * LaneElts;
13201 unsigned LaneIdx = DstIdx % LaneElts;
13202 if (LaneIdx >= HalfSize) {
13203 unsigned Rel = LaneIdx - HalfSize;
13204 unsigned Sel = (Mask >> (2 * Rel)) & 0x3;
13205 return std::make_pair(
13206 0,
static_cast<int>(LaneBase + HalfSize + Sel));
13208 return std::make_pair(0,
static_cast<int>(DstIdx));
13214 case X86::BI__builtin_ia32_pshufd:
13215 case X86::BI__builtin_ia32_pshufd256:
13216 case X86::BI__builtin_ia32_pshufd512:
13217 case X86::BI__builtin_ia32_vpermilps:
13218 case X86::BI__builtin_ia32_vpermilps256:
13219 case X86::BI__builtin_ia32_vpermilps512: {
13223 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13224 constexpr unsigned LaneBits = 128u;
13225 constexpr unsigned ElemBits = 32u;
13226 constexpr unsigned LaneElts = LaneBits / ElemBits;
13227 unsigned LaneBase = (DstIdx / LaneElts) * LaneElts;
13228 unsigned LaneIdx = DstIdx % LaneElts;
13229 unsigned Sel = (Mask >> (2 * LaneIdx)) & 0x3;
13230 return std::make_pair(0,
static_cast<int>(LaneBase + Sel));
13236 case X86::BI__builtin_ia32_vpermilvarpd:
13237 case X86::BI__builtin_ia32_vpermilvarpd256:
13238 case X86::BI__builtin_ia32_vpermilvarpd512: {
13242 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13243 unsigned NumElemPerLane = 2;
13244 unsigned Lane = DstIdx / NumElemPerLane;
13245 unsigned Offset = Mask & 0b10 ? 1 : 0;
13246 return std::make_pair(
13247 0,
static_cast<int>(Lane * NumElemPerLane + Offset));
13253 case X86::BI__builtin_ia32_vpermilpd:
13254 case X86::BI__builtin_ia32_vpermilpd256:
13255 case X86::BI__builtin_ia32_vpermilpd512: {
13258 unsigned NumElemPerLane = 2;
13259 unsigned BitsPerElem = 1;
13260 unsigned MaskBits = 8;
13261 unsigned IndexMask = 0x1;
13262 unsigned Lane = DstIdx / NumElemPerLane;
13263 unsigned LaneOffset = Lane * NumElemPerLane;
13264 unsigned BitIndex = (DstIdx * BitsPerElem) % MaskBits;
13265 unsigned Index = (Control >> BitIndex) & IndexMask;
13266 return std::make_pair(0,
static_cast<int>(LaneOffset + Index));
13272 case X86::BI__builtin_ia32_permdf256:
13273 case X86::BI__builtin_ia32_permdi256: {
13278 unsigned Index = (Control >> (2 * DstIdx)) & 0x3;
13279 return std::make_pair(0,
static_cast<int>(Index));
13285 case X86::BI__builtin_ia32_vpermilvarps:
13286 case X86::BI__builtin_ia32_vpermilvarps256:
13287 case X86::BI__builtin_ia32_vpermilvarps512: {
13291 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13292 unsigned NumElemPerLane = 4;
13293 unsigned Lane = DstIdx / NumElemPerLane;
13294 unsigned Offset = Mask & 0b11;
13295 return std::make_pair(
13296 0,
static_cast<int>(Lane * NumElemPerLane + Offset));
13302 case X86::BI__builtin_ia32_vpmultishiftqb128:
13303 case X86::BI__builtin_ia32_vpmultishiftqb256:
13304 case X86::BI__builtin_ia32_vpmultishiftqb512: {
13312 unsigned NumBytesInQWord = 8;
13313 unsigned NumBitsInByte = 8;
13315 unsigned NumQWords = NumBytes / NumBytesInQWord;
13317 Result.reserve(NumBytes);
13319 for (
unsigned QWordId = 0; QWordId != NumQWords; ++QWordId) {
13320 APInt BQWord(64, 0);
13321 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
13322 unsigned Idx = QWordId * NumBytesInQWord + ByteIdx;
13324 BQWord.insertBits(
APInt(8, Byte & 0xFF), ByteIdx * NumBitsInByte);
13327 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
13328 unsigned Idx = QWordId * NumBytesInQWord + ByteIdx;
13332 for (
unsigned BitIdx = 0; BitIdx != NumBitsInByte; ++BitIdx) {
13333 Byte.setBitVal(BitIdx, BQWord[(Ctrl + BitIdx) & 0x3F]);
13341 case X86::BI__builtin_ia32_phminposuw128: {
13348 unsigned ElemBitWidth = Info.Ctx.
getTypeSize(ElemQT);
13350 APInt MinIndex(ElemBitWidth, 0);
13352 for (
unsigned I = 1; I != SourceLen; ++I) {
13354 if (MinVal.ugt(Val)) {
13363 ->isUnsignedIntegerOrEnumerationType();
13366 Result.reserve(SourceLen);
13368 Result.emplace_back(
APSInt(MinIndex, ResultUnsigned));
13369 for (
unsigned I = 0; I != SourceLen - 2; ++I) {
13375 case X86::BI__builtin_ia32_psraq128:
13376 case X86::BI__builtin_ia32_psraq256:
13377 case X86::BI__builtin_ia32_psraq512:
13378 case X86::BI__builtin_ia32_psrad128:
13379 case X86::BI__builtin_ia32_psrad256:
13380 case X86::BI__builtin_ia32_psrad512:
13381 case X86::BI__builtin_ia32_psraw128:
13382 case X86::BI__builtin_ia32_psraw256:
13383 case X86::BI__builtin_ia32_psraw512: {
13387 [](
const APInt &Elt, uint64_t Count) {
return Elt.ashr(Count); },
13388 [](
const APInt &Elt,
unsigned Width) {
13389 return Elt.ashr(Width - 1);
13395 case X86::BI__builtin_ia32_psllq128:
13396 case X86::BI__builtin_ia32_psllq256:
13397 case X86::BI__builtin_ia32_psllq512:
13398 case X86::BI__builtin_ia32_pslld128:
13399 case X86::BI__builtin_ia32_pslld256:
13400 case X86::BI__builtin_ia32_pslld512:
13401 case X86::BI__builtin_ia32_psllw128:
13402 case X86::BI__builtin_ia32_psllw256:
13403 case X86::BI__builtin_ia32_psllw512: {
13407 [](
const APInt &Elt, uint64_t Count) {
return Elt.shl(Count); },
13408 [](
const APInt &Elt,
unsigned Width) {
13409 return APInt::getZero(Width);
13415 case X86::BI__builtin_ia32_psrlq128:
13416 case X86::BI__builtin_ia32_psrlq256:
13417 case X86::BI__builtin_ia32_psrlq512:
13418 case X86::BI__builtin_ia32_psrld128:
13419 case X86::BI__builtin_ia32_psrld256:
13420 case X86::BI__builtin_ia32_psrld512:
13421 case X86::BI__builtin_ia32_psrlw128:
13422 case X86::BI__builtin_ia32_psrlw256:
13423 case X86::BI__builtin_ia32_psrlw512: {
13427 [](
const APInt &Elt, uint64_t Count) {
return Elt.lshr(Count); },
13428 [](
const APInt &Elt,
unsigned Width) {
13429 return APInt::getZero(Width);
13435 case X86::BI__builtin_ia32_pternlogd128_mask:
13436 case X86::BI__builtin_ia32_pternlogd256_mask:
13437 case X86::BI__builtin_ia32_pternlogd512_mask:
13438 case X86::BI__builtin_ia32_pternlogq128_mask:
13439 case X86::BI__builtin_ia32_pternlogq256_mask:
13440 case X86::BI__builtin_ia32_pternlogq512_mask: {
13441 APValue AValue, BValue, CValue, ImmValue, UValue;
13449 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13455 ResultElements.reserve(ResultLen);
13457 for (
unsigned EltNum = 0; EltNum < ResultLen; ++EltNum) {
13463 unsigned BitWidth = ALane.getBitWidth();
13464 APInt ResLane(BitWidth, 0);
13466 for (
unsigned Bit = 0; Bit < BitWidth; ++Bit) {
13467 unsigned ABit = ALane[Bit];
13468 unsigned BBit = BLane[Bit];
13469 unsigned CBit = CLane[Bit];
13471 unsigned Idx = (ABit << 2) | (BBit << 1) | CBit;
13472 ResLane.setBitVal(Bit, Imm[Idx]);
13474 ResultElements.push_back(
APValue(
APSInt(ResLane, DestUnsigned)));
13476 ResultElements.push_back(
APValue(
APSInt(ALane, DestUnsigned)));
13479 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13481 case X86::BI__builtin_ia32_pternlogd128_maskz:
13482 case X86::BI__builtin_ia32_pternlogd256_maskz:
13483 case X86::BI__builtin_ia32_pternlogd512_maskz:
13484 case X86::BI__builtin_ia32_pternlogq128_maskz:
13485 case X86::BI__builtin_ia32_pternlogq256_maskz:
13486 case X86::BI__builtin_ia32_pternlogq512_maskz: {
13487 APValue AValue, BValue, CValue, ImmValue, UValue;
13495 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13501 ResultElements.reserve(ResultLen);
13503 for (
unsigned EltNum = 0; EltNum < ResultLen; ++EltNum) {
13508 unsigned BitWidth = ALane.getBitWidth();
13509 APInt ResLane(BitWidth, 0);
13512 for (
unsigned Bit = 0; Bit < BitWidth; ++Bit) {
13513 unsigned ABit = ALane[Bit];
13514 unsigned BBit = BLane[Bit];
13515 unsigned CBit = CLane[Bit];
13517 unsigned Idx = (ABit << 2) | (BBit << 1) | CBit;
13518 ResLane.setBitVal(Bit, Imm[Idx]);
13521 ResultElements.push_back(
APValue(
APSInt(ResLane, DestUnsigned)));
13523 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13526 case Builtin::BI__builtin_elementwise_clzg:
13527 case Builtin::BI__builtin_elementwise_ctzg: {
13529 std::optional<APValue> Fallback;
13536 Fallback = FallbackTmp;
13539 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13542 ResultElements.reserve(SourceLen);
13544 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13549 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
13551 Builtin::BI__builtin_elementwise_ctzg);
13554 ResultElements.push_back(Fallback->getVectorElt(EltNum));
13558 case Builtin::BI__builtin_elementwise_clzg:
13559 ResultElements.push_back(
APValue(
13563 case Builtin::BI__builtin_elementwise_ctzg:
13564 ResultElements.push_back(
APValue(
13571 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13574 case Builtin::BI__builtin_elementwise_fma: {
13575 APValue SourceX, SourceY, SourceZ;
13583 ResultElements.reserve(SourceLen);
13585 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13590 (void)
Result.fusedMultiplyAdd(Y, Z, RM);
13593 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13596 case clang::X86::BI__builtin_ia32_phaddw128:
13597 case clang::X86::BI__builtin_ia32_phaddw256:
13598 case clang::X86::BI__builtin_ia32_phaddd128:
13599 case clang::X86::BI__builtin_ia32_phaddd256:
13600 case clang::X86::BI__builtin_ia32_phaddsw128:
13601 case clang::X86::BI__builtin_ia32_phaddsw256:
13603 case clang::X86::BI__builtin_ia32_phsubw128:
13604 case clang::X86::BI__builtin_ia32_phsubw256:
13605 case clang::X86::BI__builtin_ia32_phsubd128:
13606 case clang::X86::BI__builtin_ia32_phsubd256:
13607 case clang::X86::BI__builtin_ia32_phsubsw128:
13608 case clang::X86::BI__builtin_ia32_phsubsw256: {
13609 APValue SourceLHS, SourceRHS;
13613 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13617 unsigned EltBits = Info.Ctx.
getIntWidth(DestEltTy);
13618 unsigned EltsPerLane = 128 / EltBits;
13620 ResultElements.reserve(NumElts);
13622 for (
unsigned LaneStart = 0; LaneStart != NumElts;
13623 LaneStart += EltsPerLane) {
13624 for (
unsigned I = 0; I != EltsPerLane; I += 2) {
13628 case clang::X86::BI__builtin_ia32_phaddw128:
13629 case clang::X86::BI__builtin_ia32_phaddw256:
13630 case clang::X86::BI__builtin_ia32_phaddd128:
13631 case clang::X86::BI__builtin_ia32_phaddd256: {
13632 APSInt Res(LHSA + LHSB, DestUnsigned);
13633 ResultElements.push_back(
APValue(Res));
13636 case clang::X86::BI__builtin_ia32_phaddsw128:
13637 case clang::X86::BI__builtin_ia32_phaddsw256: {
13638 APSInt Res(LHSA.sadd_sat(LHSB));
13639 ResultElements.push_back(
APValue(Res));
13642 case clang::X86::BI__builtin_ia32_phsubw128:
13643 case clang::X86::BI__builtin_ia32_phsubw256:
13644 case clang::X86::BI__builtin_ia32_phsubd128:
13645 case clang::X86::BI__builtin_ia32_phsubd256: {
13646 APSInt Res(LHSA - LHSB, DestUnsigned);
13647 ResultElements.push_back(
APValue(Res));
13650 case clang::X86::BI__builtin_ia32_phsubsw128:
13651 case clang::X86::BI__builtin_ia32_phsubsw256: {
13652 APSInt Res(LHSA.ssub_sat(LHSB));
13653 ResultElements.push_back(
APValue(Res));
13658 for (
unsigned I = 0; I != EltsPerLane; I += 2) {
13662 case clang::X86::BI__builtin_ia32_phaddw128:
13663 case clang::X86::BI__builtin_ia32_phaddw256:
13664 case clang::X86::BI__builtin_ia32_phaddd128:
13665 case clang::X86::BI__builtin_ia32_phaddd256: {
13666 APSInt Res(RHSA + RHSB, DestUnsigned);
13667 ResultElements.push_back(
APValue(Res));
13670 case clang::X86::BI__builtin_ia32_phaddsw128:
13671 case clang::X86::BI__builtin_ia32_phaddsw256: {
13672 APSInt Res(RHSA.sadd_sat(RHSB));
13673 ResultElements.push_back(
APValue(Res));
13676 case clang::X86::BI__builtin_ia32_phsubw128:
13677 case clang::X86::BI__builtin_ia32_phsubw256:
13678 case clang::X86::BI__builtin_ia32_phsubd128:
13679 case clang::X86::BI__builtin_ia32_phsubd256: {
13680 APSInt Res(RHSA - RHSB, DestUnsigned);
13681 ResultElements.push_back(
APValue(Res));
13684 case clang::X86::BI__builtin_ia32_phsubsw128:
13685 case clang::X86::BI__builtin_ia32_phsubsw256: {
13686 APSInt Res(RHSA.ssub_sat(RHSB));
13687 ResultElements.push_back(
APValue(Res));
13693 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13695 case clang::X86::BI__builtin_ia32_haddpd:
13696 case clang::X86::BI__builtin_ia32_haddps:
13697 case clang::X86::BI__builtin_ia32_haddps256:
13698 case clang::X86::BI__builtin_ia32_haddpd256:
13699 case clang::X86::BI__builtin_ia32_hsubpd:
13700 case clang::X86::BI__builtin_ia32_hsubps:
13701 case clang::X86::BI__builtin_ia32_hsubps256:
13702 case clang::X86::BI__builtin_ia32_hsubpd256: {
13703 APValue SourceLHS, SourceRHS;
13709 ResultElements.reserve(NumElts);
13711 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13712 unsigned EltBits = Info.Ctx.
getTypeSize(DestEltTy);
13713 unsigned NumLanes = NumElts * EltBits / 128;
13714 unsigned NumElemsPerLane = NumElts / NumLanes;
13715 unsigned HalfElemsPerLane = NumElemsPerLane / 2;
13717 for (
unsigned L = 0; L != NumElts; L += NumElemsPerLane) {
13718 for (
unsigned I = 0; I != HalfElemsPerLane; ++I) {
13722 case clang::X86::BI__builtin_ia32_haddpd:
13723 case clang::X86::BI__builtin_ia32_haddps:
13724 case clang::X86::BI__builtin_ia32_haddps256:
13725 case clang::X86::BI__builtin_ia32_haddpd256:
13726 LHSA.add(LHSB, RM);
13728 case clang::X86::BI__builtin_ia32_hsubpd:
13729 case clang::X86::BI__builtin_ia32_hsubps:
13730 case clang::X86::BI__builtin_ia32_hsubps256:
13731 case clang::X86::BI__builtin_ia32_hsubpd256:
13732 LHSA.subtract(LHSB, RM);
13735 ResultElements.push_back(
APValue(LHSA));
13737 for (
unsigned I = 0; I != HalfElemsPerLane; ++I) {
13741 case clang::X86::BI__builtin_ia32_haddpd:
13742 case clang::X86::BI__builtin_ia32_haddps:
13743 case clang::X86::BI__builtin_ia32_haddps256:
13744 case clang::X86::BI__builtin_ia32_haddpd256:
13745 RHSA.add(RHSB, RM);
13747 case clang::X86::BI__builtin_ia32_hsubpd:
13748 case clang::X86::BI__builtin_ia32_hsubps:
13749 case clang::X86::BI__builtin_ia32_hsubps256:
13750 case clang::X86::BI__builtin_ia32_hsubpd256:
13751 RHSA.subtract(RHSB, RM);
13754 ResultElements.push_back(
APValue(RHSA));
13757 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13759 case clang::X86::BI__builtin_ia32_addsubpd:
13760 case clang::X86::BI__builtin_ia32_addsubps:
13761 case clang::X86::BI__builtin_ia32_addsubpd256:
13762 case clang::X86::BI__builtin_ia32_addsubps256: {
13765 APValue SourceLHS, SourceRHS;
13771 ResultElements.reserve(NumElems);
13774 for (
unsigned I = 0; I != NumElems; ++I) {
13779 LHS.subtract(RHS, RM);
13784 ResultElements.push_back(
APValue(LHS));
13786 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13788 case clang::X86::BI__builtin_ia32_pclmulqdq128:
13789 case clang::X86::BI__builtin_ia32_pclmulqdq256:
13790 case clang::X86::BI__builtin_ia32_pclmulqdq512: {
13794 APValue SourceLHS, SourceRHS;
13804 bool SelectUpperA = (Imm8 & 0x01) != 0;
13805 bool SelectUpperB = (Imm8 & 0x10) != 0;
13809 ResultElements.reserve(NumElems);
13810 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13814 for (
unsigned Lane = 0; Lane < NumElems; Lane += 2) {
13823 APInt A = SelectUpperA ? A1 : A0;
13824 APInt B = SelectUpperB ? B1 : B0;
13827 APInt A128 = A.zext(128);
13828 APInt B128 = B.zext(128);
13831 APInt Result = llvm::APIntOps::clmul(A128, B128);
13834 APSInt ResultLow(
Result.extractBits(64, 0), DestUnsigned);
13835 APSInt ResultHigh(
Result.extractBits(64, 64), DestUnsigned);
13837 ResultElements.push_back(
APValue(ResultLow));
13838 ResultElements.push_back(
APValue(ResultHigh));
13841 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13843 case Builtin::BI__builtin_elementwise_fshl:
13844 case Builtin::BI__builtin_elementwise_fshr: {
13845 APValue SourceHi, SourceLo, SourceShift;
13851 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13857 ResultElements.reserve(SourceLen);
13858 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13863 case Builtin::BI__builtin_elementwise_fshl:
13864 ResultElements.push_back(
APValue(
13865 APSInt(llvm::APIntOps::fshl(Hi, Lo, Shift), Hi.isUnsigned())));
13867 case Builtin::BI__builtin_elementwise_fshr:
13868 ResultElements.push_back(
APValue(
13869 APSInt(llvm::APIntOps::fshr(Hi, Lo, Shift), Hi.isUnsigned())));
13874 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13877 case X86::BI__builtin_ia32_shuf_f32x4_256:
13878 case X86::BI__builtin_ia32_shuf_i32x4_256:
13879 case X86::BI__builtin_ia32_shuf_f64x2_256:
13880 case X86::BI__builtin_ia32_shuf_i64x2_256:
13881 case X86::BI__builtin_ia32_shuf_f32x4:
13882 case X86::BI__builtin_ia32_shuf_i32x4:
13883 case X86::BI__builtin_ia32_shuf_f64x2:
13884 case X86::BI__builtin_ia32_shuf_i64x2: {
13898 unsigned ElemBits = Info.Ctx.
getTypeSize(ElemQT);
13899 unsigned LaneBits = 128u;
13900 unsigned NumLanes = (NumElems * ElemBits) / LaneBits;
13901 unsigned NumElemsPerLane = LaneBits / ElemBits;
13905 ResultElements.reserve(DstLen);
13910 [NumLanes, NumElemsPerLane](
unsigned DstIdx,
unsigned ShuffleMask)
13911 -> std::pair<unsigned, int> {
13913 unsigned BitsPerElem = NumLanes / 2;
13914 unsigned IndexMask = (1u << BitsPerElem) - 1;
13915 unsigned Lane = DstIdx / NumElemsPerLane;
13916 unsigned SrcIdx = (Lane < NumLanes / 2) ? 0 : 1;
13917 unsigned BitIdx = BitsPerElem * Lane;
13918 unsigned SrcLaneIdx = (ShuffleMask >> BitIdx) & IndexMask;
13919 unsigned ElemInLane = DstIdx % NumElemsPerLane;
13920 unsigned IdxToPick = SrcLaneIdx * NumElemsPerLane + ElemInLane;
13921 return {SrcIdx, IdxToPick};
13927 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v16qi:
13928 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v32qi:
13929 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v64qi:
13930 case X86::BI__builtin_ia32_vgf2p8affineqb_v16qi:
13931 case X86::BI__builtin_ia32_vgf2p8affineqb_v32qi:
13932 case X86::BI__builtin_ia32_vgf2p8affineqb_v64qi: {
13944 bool IsInverse =
false;
13946 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v16qi:
13947 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v32qi:
13948 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v64qi: {
13953 unsigned NumBitsInByte = 8;
13954 unsigned NumBytesInQWord = 8;
13955 unsigned NumBitsInQWord = 64;
13957 unsigned NumQWords = NumBytes / NumBytesInQWord;
13959 Result.reserve(NumBytes);
13962 for (
unsigned QWordIdx = 0; QWordIdx != NumQWords; ++QWordIdx) {
13964 APInt XQWord(NumBitsInQWord, 0);
13965 APInt AQWord(NumBitsInQWord, 0);
13966 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
13967 unsigned Idx = QWordIdx * NumBytesInQWord + ByteIdx;
13968 APInt XByte =
X.getVectorElt(Idx).getInt();
13970 XQWord.insertBits(XByte, ByteIdx * NumBitsInByte);
13971 AQWord.insertBits(AByte, ByteIdx * NumBitsInByte);
13974 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
13976 XQWord.lshr(ByteIdx * NumBitsInByte).getLoBits(8).getZExtValue();
13985 case X86::BI__builtin_ia32_vgf2p8mulb_v16qi:
13986 case X86::BI__builtin_ia32_vgf2p8mulb_v32qi:
13987 case X86::BI__builtin_ia32_vgf2p8mulb_v64qi: {
13998 Result.reserve(NumBytes);
14000 for (
unsigned ByteIdx = 0; ByteIdx != NumBytes; ++ByteIdx) {
14010 case X86::BI__builtin_ia32_insertf32x4_256:
14011 case X86::BI__builtin_ia32_inserti32x4_256:
14012 case X86::BI__builtin_ia32_insertf64x2_256:
14013 case X86::BI__builtin_ia32_inserti64x2_256:
14014 case X86::BI__builtin_ia32_insertf32x4:
14015 case X86::BI__builtin_ia32_inserti32x4:
14016 case X86::BI__builtin_ia32_insertf64x2_512:
14017 case X86::BI__builtin_ia32_inserti64x2_512:
14018 case X86::BI__builtin_ia32_insertf32x8:
14019 case X86::BI__builtin_ia32_inserti32x8:
14020 case X86::BI__builtin_ia32_insertf64x4:
14021 case X86::BI__builtin_ia32_inserti64x4:
14022 case X86::BI__builtin_ia32_vinsertf128_ps256:
14023 case X86::BI__builtin_ia32_vinsertf128_pd256:
14024 case X86::BI__builtin_ia32_vinsertf128_si256:
14025 case X86::BI__builtin_ia32_insert128i256: {
14026 APValue SourceDst, SourceSub;
14038 assert(SubLen != 0 && DstLen != 0 && (DstLen % SubLen) == 0);
14039 unsigned NumLanes = DstLen / SubLen;
14040 unsigned LaneIdx = (Imm.getZExtValue() % NumLanes) * SubLen;
14043 ResultElements.reserve(DstLen);
14045 for (
unsigned EltNum = 0; EltNum < DstLen; ++EltNum) {
14046 if (EltNum >= LaneIdx && EltNum < LaneIdx + SubLen)
14047 ResultElements.push_back(SourceSub.
getVectorElt(EltNum - LaneIdx));
14049 ResultElements.push_back(SourceDst.
getVectorElt(EltNum));
14052 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14055 case clang::X86::BI__builtin_ia32_vec_set_v4hi:
14056 case clang::X86::BI__builtin_ia32_vec_set_v16qi:
14057 case clang::X86::BI__builtin_ia32_vec_set_v8hi:
14058 case clang::X86::BI__builtin_ia32_vec_set_v4si:
14059 case clang::X86::BI__builtin_ia32_vec_set_v2di:
14060 case clang::X86::BI__builtin_ia32_vec_set_v32qi:
14061 case clang::X86::BI__builtin_ia32_vec_set_v16hi:
14062 case clang::X86::BI__builtin_ia32_vec_set_v8si:
14063 case clang::X86::BI__builtin_ia32_vec_set_v4di: {
14071 QualType ElemTy = E->
getType()->
castAs<VectorType>()->getElementType();
14072 unsigned ElemWidth = Info.Ctx.
getIntWidth(ElemTy);
14074 Scalar.setIsUnsigned(ElemUnsigned);
14080 static_cast<unsigned>(IndexAPS.getZExtValue() & (NumElems - 1));
14083 Elems.reserve(NumElems);
14084 for (
unsigned ElemNum = 0; ElemNum != NumElems; ++ElemNum)
14085 Elems.push_back(ElemNum == Index ? ElemAV : VecVal.
getVectorElt(ElemNum));
14090 case X86::BI__builtin_ia32_pslldqi128_byteshift:
14091 case X86::BI__builtin_ia32_pslldqi256_byteshift:
14092 case X86::BI__builtin_ia32_pslldqi512_byteshift: {
14096 [](
unsigned DstIdx,
unsigned Shift) -> std::pair<unsigned, int> {
14097 unsigned LaneBase = (DstIdx / 16) * 16;
14098 unsigned LaneIdx = DstIdx % 16;
14099 if (LaneIdx < Shift)
14100 return std::make_pair(0, -1);
14102 return std::make_pair(
14103 0,
static_cast<int>(LaneBase + LaneIdx - Shift));
14109 case X86::BI__builtin_ia32_psrldqi128_byteshift:
14110 case X86::BI__builtin_ia32_psrldqi256_byteshift:
14111 case X86::BI__builtin_ia32_psrldqi512_byteshift: {
14115 [](
unsigned DstIdx,
unsigned Shift) -> std::pair<unsigned, int> {
14116 unsigned LaneBase = (DstIdx / 16) * 16;
14117 unsigned LaneIdx = DstIdx % 16;
14118 if (LaneIdx + Shift < 16)
14119 return std::make_pair(
14120 0,
static_cast<int>(LaneBase + LaneIdx + Shift));
14122 return std::make_pair(0, -1);
14128 case X86::BI__builtin_ia32_palignr128:
14129 case X86::BI__builtin_ia32_palignr256:
14130 case X86::BI__builtin_ia32_palignr512: {
14134 unsigned VecIdx = 1;
14137 int Lane = DstIdx / 16;
14138 int Offset = DstIdx % 16;
14141 unsigned ShiftedIdx = Offset + (
Shift & 0xFF);
14142 if (ShiftedIdx < 16) {
14143 ElemIdx = ShiftedIdx + (Lane * 16);
14144 }
else if (ShiftedIdx < 32) {
14146 ElemIdx = (ShiftedIdx - 16) + (Lane * 16);
14149 return std::pair<unsigned, int>{VecIdx, ElemIdx};
14154 case X86::BI__builtin_ia32_alignd128:
14155 case X86::BI__builtin_ia32_alignd256:
14156 case X86::BI__builtin_ia32_alignd512:
14157 case X86::BI__builtin_ia32_alignq128:
14158 case X86::BI__builtin_ia32_alignq256:
14159 case X86::BI__builtin_ia32_alignq512: {
14161 unsigned NumElems = E->
getType()->
castAs<VectorType>()->getNumElements();
14163 [NumElems](
unsigned DstIdx,
unsigned Shift) {
14164 unsigned Imm =
Shift & 0xFF;
14165 unsigned EffectiveShift = Imm & (NumElems - 1);
14166 unsigned SourcePos = DstIdx + EffectiveShift;
14167 unsigned VecIdx = SourcePos < NumElems ? 1 : 0;
14168 unsigned ElemIdx = SourcePos & (NumElems - 1);
14170 return std::pair<unsigned, int>{
14171 VecIdx,
static_cast<int>(ElemIdx)};
14176 case X86::BI__builtin_ia32_permvarsi256:
14177 case X86::BI__builtin_ia32_permvarsf256:
14178 case X86::BI__builtin_ia32_permvardf512:
14179 case X86::BI__builtin_ia32_permvardi512:
14180 case X86::BI__builtin_ia32_permvarhi128: {
14183 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14184 int Offset = ShuffleMask & 0x7;
14185 return std::pair<unsigned, int>{0, Offset};
14190 case X86::BI__builtin_ia32_permvarqi128:
14191 case X86::BI__builtin_ia32_permvarhi256:
14192 case X86::BI__builtin_ia32_permvarsi512:
14193 case X86::BI__builtin_ia32_permvarsf512: {
14196 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14197 int Offset = ShuffleMask & 0xF;
14198 return std::pair<unsigned, int>{0, Offset};
14203 case X86::BI__builtin_ia32_permvardi256:
14204 case X86::BI__builtin_ia32_permvardf256: {
14207 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14208 int Offset = ShuffleMask & 0x3;
14209 return std::pair<unsigned, int>{0, Offset};
14214 case X86::BI__builtin_ia32_permvarqi256:
14215 case X86::BI__builtin_ia32_permvarhi512: {
14218 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14219 int Offset = ShuffleMask & 0x1F;
14220 return std::pair<unsigned, int>{0, Offset};
14225 case X86::BI__builtin_ia32_permvarqi512: {
14228 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14229 int Offset = ShuffleMask & 0x3F;
14230 return std::pair<unsigned, int>{0, Offset};
14235 case X86::BI__builtin_ia32_vpermi2varq128:
14236 case X86::BI__builtin_ia32_vpermi2varpd128: {
14239 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14240 int Offset = ShuffleMask & 0x1;
14241 unsigned SrcIdx = (ShuffleMask >> 1) & 0x1;
14242 return std::pair<unsigned, int>{SrcIdx, Offset};
14247 case X86::BI__builtin_ia32_vpermi2vard128:
14248 case X86::BI__builtin_ia32_vpermi2varps128:
14249 case X86::BI__builtin_ia32_vpermi2varq256:
14250 case X86::BI__builtin_ia32_vpermi2varpd256: {
14253 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14254 int Offset = ShuffleMask & 0x3;
14255 unsigned SrcIdx = (ShuffleMask >> 2) & 0x1;
14256 return std::pair<unsigned, int>{SrcIdx, Offset};
14261 case X86::BI__builtin_ia32_vpermi2varhi128:
14262 case X86::BI__builtin_ia32_vpermi2vard256:
14263 case X86::BI__builtin_ia32_vpermi2varps256:
14264 case X86::BI__builtin_ia32_vpermi2varq512:
14265 case X86::BI__builtin_ia32_vpermi2varpd512: {
14268 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14269 int Offset = ShuffleMask & 0x7;
14270 unsigned SrcIdx = (ShuffleMask >> 3) & 0x1;
14271 return std::pair<unsigned, int>{SrcIdx, Offset};
14276 case X86::BI__builtin_ia32_vpermi2varqi128:
14277 case X86::BI__builtin_ia32_vpermi2varhi256:
14278 case X86::BI__builtin_ia32_vpermi2vard512:
14279 case X86::BI__builtin_ia32_vpermi2varps512: {
14282 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14283 int Offset = ShuffleMask & 0xF;
14284 unsigned SrcIdx = (ShuffleMask >> 4) & 0x1;
14285 return std::pair<unsigned, int>{SrcIdx, Offset};
14290 case X86::BI__builtin_ia32_vpermi2varqi256:
14291 case X86::BI__builtin_ia32_vpermi2varhi512: {
14294 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14295 int Offset = ShuffleMask & 0x1F;
14296 unsigned SrcIdx = (ShuffleMask >> 5) & 0x1;
14297 return std::pair<unsigned, int>{SrcIdx, Offset};
14302 case X86::BI__builtin_ia32_vpermi2varqi512: {
14305 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14306 int Offset = ShuffleMask & 0x3F;
14307 unsigned SrcIdx = (ShuffleMask >> 6) & 0x1;
14308 return std::pair<unsigned, int>{SrcIdx, Offset};
14314 case clang::X86::BI__builtin_ia32_vcvtps2ph:
14315 case clang::X86::BI__builtin_ia32_vcvtps2ph256: {
14325 unsigned SrcNumElems = SrcVTy->getNumElements();
14327 unsigned DstNumElems = DstVTy->getNumElements();
14328 QualType DstElemTy = DstVTy->getElementType();
14330 const llvm::fltSemantics &HalfSem =
14333 int ImmVal = Imm.getZExtValue();
14334 bool UseMXCSR = (ImmVal & 4) != 0;
14335 bool IsFPConstrained =
14338 llvm::RoundingMode RM;
14340 switch (ImmVal & 3) {
14342 RM = llvm::RoundingMode::NearestTiesToEven;
14345 RM = llvm::RoundingMode::TowardNegative;
14348 RM = llvm::RoundingMode::TowardPositive;
14351 RM = llvm::RoundingMode::TowardZero;
14354 llvm_unreachable(
"Invalid immediate rounding mode");
14357 RM = llvm::RoundingMode::NearestTiesToEven;
14361 ResultElements.reserve(DstNumElems);
14363 for (
unsigned I = 0; I < SrcNumElems; ++I) {
14367 APFloat::opStatus St = SrcVal.convert(HalfSem, RM, &LostInfo);
14369 if (UseMXCSR && IsFPConstrained && St != APFloat::opOK) {
14370 Info.FFDiag(E, diag::note_constexpr_dynamic_rounding);
14374 APSInt DstInt(SrcVal.bitcastToAPInt(),
14376 ResultElements.push_back(
APValue(DstInt));
14379 if (DstNumElems > SrcNumElems) {
14381 for (
unsigned I = SrcNumElems; I < DstNumElems; ++I) {
14386 return Success(ResultElements, E);
14388 case X86::BI__builtin_ia32_vperm2f128_pd256:
14389 case X86::BI__builtin_ia32_vperm2f128_ps256:
14390 case X86::BI__builtin_ia32_vperm2f128_si256:
14391 case X86::BI__builtin_ia32_permti256: {
14392 unsigned NumElements =
14394 unsigned PreservedBitsCnt = NumElements >> 2;
14398 [PreservedBitsCnt](
unsigned DstIdx,
unsigned ShuffleMask) {
14399 unsigned ControlBitsCnt = DstIdx >> PreservedBitsCnt << 2;
14400 unsigned ControlBits = ShuffleMask >> ControlBitsCnt;
14402 if (ControlBits & 0b1000)
14403 return std::make_pair(0u, -1);
14405 unsigned SrcVecIdx = (ControlBits & 0b10) >> 1;
14406 unsigned PreservedBitsMask = (1 << PreservedBitsCnt) - 1;
14407 int SrcIdx = ((ControlBits & 0b1) << PreservedBitsCnt) |
14408 (DstIdx & PreservedBitsMask);
14409 return std::make_pair(SrcVecIdx, SrcIdx);
14417bool VectorExprEvaluator::VisitConvertVectorExpr(
const ConvertVectorExpr *E) {
14423 QualType DestTy = E->
getType()->
castAs<VectorType>()->getElementType();
14424 QualType SourceTy = SourceVecType->
castAs<VectorType>()->getElementType();
14430 ResultElements.reserve(SourceLen);
14431 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
14436 ResultElements.push_back(std::move(Elt));
14439 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14444 APValue const &VecVal2,
unsigned EltNum,
14446 unsigned const TotalElementsInInputVector1 = VecVal1.
getVectorLength();
14447 unsigned const TotalElementsInInputVector2 = VecVal2.
getVectorLength();
14450 int64_t
index = IndexVal.getExtValue();
14457 E, diag::err_shufflevector_minus_one_is_undefined_behavior_constexpr)
14463 index >= TotalElementsInInputVector1 + TotalElementsInInputVector2)
14464 llvm_unreachable(
"Out of bounds shuffle index");
14466 if (
index >= TotalElementsInInputVector1)
14473bool VectorExprEvaluator::VisitShuffleVectorExpr(
const ShuffleVectorExpr *E) {
14478 const Expr *Vec1 = E->
getExpr(0);
14482 const Expr *Vec2 = E->
getExpr(1);
14486 VectorType
const *DestVecTy = E->
getType()->
castAs<VectorType>();
14492 ResultElements.reserve(TotalElementsInOutputVector);
14493 for (
unsigned EltNum = 0; EltNum < TotalElementsInOutputVector; ++EltNum) {
14497 ResultElements.push_back(std::move(Elt));
14500 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14508 class ArrayExprEvaluator
14509 :
public ExprEvaluatorBase<ArrayExprEvaluator> {
14510 const LValue &
This;
14514 ArrayExprEvaluator(EvalInfo &Info,
const LValue &This,
APValue &
Result)
14518 assert(
V.isArray() &&
"expected array");
14523 bool ZeroInitialization(
const Expr *E) {
14524 const ConstantArrayType *CAT =
14539 if (!
Result.hasArrayFiller())
14543 LValue Subobject =
This;
14544 Subobject.addArray(Info, E, CAT);
14549 bool VisitCallExpr(
const CallExpr *E) {
14550 return handleCallExpr(E,
Result, &This);
14552 bool VisitCastExpr(
const CastExpr *E);
14553 bool VisitInitListExpr(
const InitListExpr *E,
14554 QualType AllocType = QualType());
14555 bool VisitArrayInitLoopExpr(
const ArrayInitLoopExpr *E);
14556 bool VisitCXXConstructExpr(
const CXXConstructExpr *E);
14557 bool VisitCXXConstructExpr(
const CXXConstructExpr *E,
14558 const LValue &Subobject,
14560 bool VisitStringLiteral(
const StringLiteral *E,
14561 QualType AllocType = QualType()) {
14565 bool VisitCXXParenListInitExpr(
const CXXParenListInitExpr *E);
14566 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
14567 ArrayRef<Expr *> Args,
14568 const Expr *ArrayFiller,
14569 QualType AllocType = QualType());
14574 APValue &Result, EvalInfo &Info) {
14577 "not an array prvalue");
14578 return ArrayExprEvaluator(Info,
This, Result).Visit(E);
14586 "not an array prvalue");
14587 return ArrayExprEvaluator(Info,
This, Result)
14588 .VisitInitListExpr(ILE, AllocType);
14597 "not an array prvalue");
14598 return ArrayExprEvaluator(Info,
This, Result)
14599 .VisitCXXConstructExpr(CCE,
This, &Result, AllocType);
14608 if (
const InitListExpr *ILE = dyn_cast<InitListExpr>(FillerExpr)) {
14609 for (
unsigned I = 0, E = ILE->
getNumInits(); I != E; ++I) {
14614 if (ILE->hasArrayFiller() &&
14623bool ArrayExprEvaluator::VisitCastExpr(
const CastExpr *E) {
14628 return ExprEvaluatorBaseTy::VisitCastExpr(E);
14629 case CK_HLSLAggregateSplatCast: {
14649 case CK_HLSLElementwiseCast: {
14666bool ArrayExprEvaluator::VisitInitListExpr(
const InitListExpr *E,
14667 QualType AllocType) {
14681 return VisitStringLiteral(SL, AllocType);
14686 "transparent array list initialization is not string literal init?");
14692bool ArrayExprEvaluator::VisitCXXParenListOrInitListExpr(
14694 QualType AllocType) {
14700 assert((!
Result.isArray() ||
Result.getArrayInitializedElts() == 0) &&
14701 "zero-initialized array shouldn't have any initialized elts");
14706 unsigned NumEltsToInit = Args.size();
14711 if (NumEltsToInit != NumElts &&
14713 NumEltsToInit = NumElts;
14715 for (
auto *
Init : Args) {
14716 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts()))
14717 NumEltsToInit += EmbedS->getDataElementCount() - 1;
14719 if (NumEltsToInit > NumElts)
14720 NumEltsToInit = NumElts;
14723 LLVM_DEBUG(llvm::dbgs() <<
"The number of elements to initialize: "
14724 << NumEltsToInit <<
".\n");
14726 Result =
APValue(APValue::UninitArray(), NumEltsToInit, NumElts);
14731 for (
unsigned I = 0, E =
Result.getArrayInitializedElts(); I != E; ++I)
14732 Result.getArrayInitializedElt(I) = Filler;
14733 if (
Result.hasArrayFiller())
14737 LValue Subobject =
This;
14738 Subobject.addArray(Info, ExprToVisit, CAT);
14739 auto Eval = [&](
const Expr *
Init,
unsigned ArrayIndex) {
14740 if (
Init->isValueDependent())
14744 Subobject,
Init) ||
14747 if (!Info.noteFailure())
14753 unsigned ArrayIndex = 0;
14756 for (
unsigned Index = 0; Index != NumEltsToInit; ++Index) {
14757 const Expr *
Init = Index < Args.size() ? Args[Index] : ArrayFiller;
14758 if (ArrayIndex >= NumEltsToInit)
14760 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
14761 StringLiteral *SL = EmbedS->getDataStringLiteral();
14762 for (
unsigned I = EmbedS->getStartingElementPos(),
14763 N = EmbedS->getDataElementCount();
14764 I != EmbedS->getStartingElementPos() + N; ++I) {
14770 const FPOptions FPO =
14776 Result.getArrayInitializedElt(ArrayIndex) =
APValue(FValue);
14781 if (!Eval(
Init, ArrayIndex))
14787 if (!
Result.hasArrayFiller())
14792 assert(ArrayFiller &&
"no array filler for incomplete init list");
14798bool ArrayExprEvaluator::VisitArrayInitLoopExpr(
const ArrayInitLoopExpr *E) {
14801 !
Evaluate(Info.CurrentCall->createTemporary(
14804 ScopeKind::FullExpression, CommonLV),
14811 Result =
APValue(APValue::UninitArray(), Elements, Elements);
14813 LValue Subobject =
This;
14814 Subobject.addArray(Info, E, CAT);
14817 for (EvalInfo::ArrayInitLoopIndex Index(Info); Index != Elements; ++Index) {
14826 FullExpressionRAII Scope(Info);
14832 if (!Info.noteFailure())
14844bool ArrayExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E) {
14845 return VisitCXXConstructExpr(E, This, &
Result, E->
getType());
14848bool ArrayExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E,
14849 const LValue &Subobject,
14852 bool HadZeroInit =
Value->hasValue();
14859 HadZeroInit &&
Value->hasArrayFiller() ?
Value->getArrayFiller()
14862 *
Value =
APValue(APValue::UninitArray(), 0, FinalSize);
14863 if (FinalSize == 0)
14869 LValue ArrayElt = Subobject;
14870 ArrayElt.addArray(Info, E, CAT);
14876 for (
const unsigned N : {1u, FinalSize}) {
14877 unsigned OldElts =
Value->getArrayInitializedElts();
14882 APValue NewValue(APValue::UninitArray(), N, FinalSize);
14883 for (
unsigned I = 0; I < OldElts; ++I)
14884 NewValue.getArrayInitializedElt(I).swap(
14885 Value->getArrayInitializedElt(I));
14886 Value->swap(NewValue);
14889 for (
unsigned I = OldElts; I < N; ++I)
14890 Value->getArrayInitializedElt(I) = Filler;
14892 if (HasTrivialConstructor && N == FinalSize && FinalSize != 1) {
14895 APValue &FirstResult =
Value->getArrayInitializedElt(0);
14896 for (
unsigned I = OldElts; I < FinalSize; ++I)
14897 Value->getArrayInitializedElt(I) = FirstResult;
14899 for (
unsigned I = OldElts; I < N; ++I) {
14900 if (!VisitCXXConstructExpr(E, ArrayElt,
14901 &
Value->getArrayInitializedElt(I),
14908 if (Info.EvalStatus.
Diag && !Info.EvalStatus.
Diag->empty() &&
14909 !Info.keepEvaluatingAfterFailure())
14918 if (!
Type->isRecordType())
14921 return RecordExprEvaluator(Info, Subobject, *
Value)
14922 .VisitCXXConstructExpr(E,
Type);
14925bool ArrayExprEvaluator::VisitCXXParenListInitExpr(
14926 const CXXParenListInitExpr *E) {
14928 "Expression result is not a constant array type");
14930 return VisitCXXParenListOrInitListExpr(E, E->
getInitExprs(),
14943class IntExprEvaluator
14944 :
public ExprEvaluatorBase<IntExprEvaluator> {
14947 IntExprEvaluator(EvalInfo &info,
APValue &result)
14948 : ExprEvaluatorBaseTy(info),
Result(result) {}
14952 "Invalid evaluation result.");
14954 "Invalid evaluation result.");
14956 "Invalid evaluation result.");
14960 bool Success(
const llvm::APSInt &SI,
const Expr *E) {
14966 "Invalid evaluation result.");
14968 "Invalid evaluation result.");
14970 Result.getInt().setIsUnsigned(
14974 bool Success(
const llvm::APInt &I,
const Expr *E) {
14980 "Invalid evaluation result.");
14988 bool Success(CharUnits Size,
const Expr *E) {
14995 if (
V.isLValue() ||
V.isAddrLabelDiff() ||
V.isIndeterminate() ||
14996 V.allowConstexprUnknown()) {
15003 bool ZeroInitialization(
const Expr *E) {
return Success(0, E); }
15005 friend std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &,
15012 bool VisitIntegerLiteral(
const IntegerLiteral *E) {
15015 bool VisitCharacterLiteral(
const CharacterLiteral *E) {
15019 bool CheckReferencedDecl(
const Expr *E,
const Decl *D);
15020 bool VisitDeclRefExpr(
const DeclRefExpr *E) {
15021 if (CheckReferencedDecl(E, E->
getDecl()))
15024 return ExprEvaluatorBaseTy::VisitDeclRefExpr(E);
15026 bool VisitMemberExpr(
const MemberExpr *E) {
15028 VisitIgnoredBaseExpression(E->
getBase());
15032 return ExprEvaluatorBaseTy::VisitMemberExpr(E);
15035 bool VisitCallExpr(
const CallExpr *E);
15036 bool VisitBuiltinCallExpr(
const CallExpr *E,
unsigned BuiltinOp);
15037 bool VisitBinaryOperator(
const BinaryOperator *E);
15038 bool VisitOffsetOfExpr(
const OffsetOfExpr *E);
15039 bool VisitUnaryOperator(
const UnaryOperator *E);
15041 bool VisitCastExpr(
const CastExpr* E);
15042 bool VisitUnaryExprOrTypeTraitExpr(
const UnaryExprOrTypeTraitExpr *E);
15044 bool VisitCXXBoolLiteralExpr(
const CXXBoolLiteralExpr *E) {
15048 bool VisitObjCBoolLiteralExpr(
const ObjCBoolLiteralExpr *E) {
15052 bool VisitArrayInitIndexExpr(
const ArrayInitIndexExpr *E) {
15053 if (Info.ArrayInitIndex ==
uint64_t(-1)) {
15059 return Success(Info.ArrayInitIndex, E);
15063 bool VisitGNUNullExpr(
const GNUNullExpr *E) {
15064 return ZeroInitialization(E);
15067 bool VisitTypeTraitExpr(
const TypeTraitExpr *E) {
15076 bool VisitArrayTypeTraitExpr(
const ArrayTypeTraitExpr *E) {
15080 bool VisitExpressionTraitExpr(
const ExpressionTraitExpr *E) {
15084 bool VisitOpenACCAsteriskSizeExpr(
const OpenACCAsteriskSizeExpr *E) {
15091 bool VisitUnaryReal(
const UnaryOperator *E);
15092 bool VisitUnaryImag(
const UnaryOperator *E);
15094 bool VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E);
15095 bool VisitSizeOfPackExpr(
const SizeOfPackExpr *E);
15096 bool VisitSourceLocExpr(
const SourceLocExpr *E);
15097 bool VisitConceptSpecializationExpr(
const ConceptSpecializationExpr *E);
15102class FixedPointExprEvaluator
15103 :
public ExprEvaluatorBase<FixedPointExprEvaluator> {
15107 FixedPointExprEvaluator(EvalInfo &info,
APValue &result)
15108 : ExprEvaluatorBaseTy(info),
Result(result) {}
15110 bool Success(
const llvm::APInt &I,
const Expr *E) {
15121 return Success(
V.getFixedPoint(), E);
15124 bool Success(
const APFixedPoint &
V,
const Expr *E) {
15127 "Invalid evaluation result.");
15132 bool ZeroInitialization(
const Expr *E) {
15140 bool VisitFixedPointLiteral(
const FixedPointLiteral *E) {
15144 bool VisitCastExpr(
const CastExpr *E);
15145 bool VisitUnaryOperator(
const UnaryOperator *E);
15146 bool VisitBinaryOperator(
const BinaryOperator *E);
15162 return IntExprEvaluator(Info, Result).Visit(E);
15170 if (!Val.
isInt()) {
15173 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
15180bool IntExprEvaluator::VisitSourceLocExpr(
const SourceLocExpr *E) {
15182 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.
getDefaultExpr());
15191 if (!FixedPointExprEvaluator(Info, Val).Visit(E))
15210 Result = APFixedPoint(Val, FXSema);
15221bool IntExprEvaluator::CheckReferencedDecl(
const Expr* E,
const Decl* D) {
15223 if (
const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(D)) {
15225 bool SameSign = (ECD->getInitVal().isSigned()
15227 bool SameWidth = (ECD->getInitVal().
getBitWidth()
15229 if (SameSign && SameWidth)
15230 return Success(ECD->getInitVal(), E);
15234 llvm::APSInt Val = ECD->getInitVal();
15236 Val.setIsSigned(!ECD->getInitVal().isSigned());
15249 assert(!
T->isDependentType() &&
"unexpected dependent type");
15254#define TYPE(ID, BASE)
15255#define DEPENDENT_TYPE(ID, BASE) case Type::ID:
15256#define NON_CANONICAL_TYPE(ID, BASE) case Type::ID:
15257#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(ID, BASE) case Type::ID:
15258#include "clang/AST/TypeNodes.inc"
15260 case Type::DeducedTemplateSpecialization:
15261 llvm_unreachable(
"unexpected non-canonical or dependent type");
15263 case Type::Builtin:
15265#define BUILTIN_TYPE(ID, SINGLETON_ID)
15266#define SIGNED_TYPE(ID, SINGLETON_ID) \
15267 case BuiltinType::ID: return GCCTypeClass::Integer;
15268#define FLOATING_TYPE(ID, SINGLETON_ID) \
15269 case BuiltinType::ID: return GCCTypeClass::RealFloat;
15270#define PLACEHOLDER_TYPE(ID, SINGLETON_ID) \
15271 case BuiltinType::ID: break;
15272#include "clang/AST/BuiltinTypes.def"
15273 case BuiltinType::Void:
15276 case BuiltinType::Bool:
15279 case BuiltinType::Char_U:
15280 case BuiltinType::UChar:
15281 case BuiltinType::WChar_U:
15282 case BuiltinType::Char8:
15283 case BuiltinType::Char16:
15284 case BuiltinType::Char32:
15285 case BuiltinType::UShort:
15286 case BuiltinType::UInt:
15287 case BuiltinType::ULong:
15288 case BuiltinType::ULongLong:
15289 case BuiltinType::UInt128:
15292 case BuiltinType::UShortAccum:
15293 case BuiltinType::UAccum:
15294 case BuiltinType::ULongAccum:
15295 case BuiltinType::UShortFract:
15296 case BuiltinType::UFract:
15297 case BuiltinType::ULongFract:
15298 case BuiltinType::SatUShortAccum:
15299 case BuiltinType::SatUAccum:
15300 case BuiltinType::SatULongAccum:
15301 case BuiltinType::SatUShortFract:
15302 case BuiltinType::SatUFract:
15303 case BuiltinType::SatULongFract:
15306 case BuiltinType::NullPtr:
15308 case BuiltinType::ObjCId:
15309 case BuiltinType::ObjCClass:
15310 case BuiltinType::ObjCSel:
15311#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
15312 case BuiltinType::Id:
15313#include "clang/Basic/OpenCLImageTypes.def"
15314#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
15315 case BuiltinType::Id:
15316#include "clang/Basic/OpenCLExtensionTypes.def"
15317 case BuiltinType::OCLSampler:
15318 case BuiltinType::OCLEvent:
15319 case BuiltinType::OCLClkEvent:
15320 case BuiltinType::OCLQueue:
15321 case BuiltinType::OCLReserveID:
15322#define SVE_TYPE(Name, Id, SingletonId) \
15323 case BuiltinType::Id:
15324#include "clang/Basic/AArch64ACLETypes.def"
15325#define PPC_VECTOR_TYPE(Name, Id, Size) \
15326 case BuiltinType::Id:
15327#include "clang/Basic/PPCTypes.def"
15328#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
15329#include "clang/Basic/RISCVVTypes.def"
15330#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
15331#include "clang/Basic/WebAssemblyReferenceTypes.def"
15332#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
15333#include "clang/Basic/AMDGPUTypes.def"
15334#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
15335#include "clang/Basic/HLSLIntangibleTypes.def"
15338 case BuiltinType::Dependent:
15339 llvm_unreachable(
"unexpected dependent type");
15341 llvm_unreachable(
"unexpected placeholder type");
15346 case Type::Pointer:
15347 case Type::ConstantArray:
15348 case Type::VariableArray:
15349 case Type::IncompleteArray:
15350 case Type::FunctionNoProto:
15351 case Type::FunctionProto:
15352 case Type::ArrayParameter:
15355 case Type::MemberPointer:
15360 case Type::Complex:
15373 case Type::ExtVector:
15376 case Type::BlockPointer:
15377 case Type::ConstantMatrix:
15378 case Type::ObjCObject:
15379 case Type::ObjCInterface:
15380 case Type::ObjCObjectPointer:
15382 case Type::HLSLAttributedResource:
15383 case Type::HLSLInlineSpirv:
15391 case Type::LValueReference:
15392 case Type::RValueReference:
15393 llvm_unreachable(
"invalid type for expression");
15396 llvm_unreachable(
"unexpected type class");
15421 if (
Base.isNull()) {
15424 }
else if (
const Expr *E =
Base.dyn_cast<
const Expr *>()) {
15443 SpeculativeEvaluationRAII SpeculativeEval(Info);
15448 FoldConstant Fold(Info,
true);
15466 if (ArgType->isIntegralOrEnumerationType() || ArgType->isFloatingType() ||
15467 ArgType->isAnyComplexType() || ArgType->isPointerType() ||
15468 ArgType->isNullPtrType()) {
15471 Fold.keepDiagnostics();
15480 return V.hasValue();
15491 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
15515 const auto *Cast = dyn_cast<CastExpr>(NoParens);
15516 if (Cast ==
nullptr)
15521 auto CastKind = Cast->getCastKind();
15523 CastKind != CK_AddressSpaceConversion)
15526 const auto *SubExpr = Cast->getSubExpr();
15548 assert(!LVal.Designator.Invalid);
15550 auto IsLastOrInvalidFieldDecl = [&Ctx](
const FieldDecl *FD) {
15558 auto &
Base = LVal.getLValueBase();
15559 if (
auto *ME = dyn_cast_or_null<MemberExpr>(
Base.dyn_cast<
const Expr *>())) {
15560 if (
auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
15561 if (!IsLastOrInvalidFieldDecl(FD))
15563 }
else if (
auto *IFD = dyn_cast<IndirectFieldDecl>(ME->getMemberDecl())) {
15564 for (
auto *FD : IFD->chain()) {
15573 if (LVal.Designator.FirstEntryIsAnUnsizedArray) {
15577 if (BaseType->isIncompleteArrayType())
15583 for (
unsigned E = LVal.Designator.Entries.size(); I != E; ++I) {
15584 const auto &Entry = LVal.Designator.Entries[I];
15585 if (BaseType->isArrayType()) {
15591 uint64_t Index = Entry.getAsArrayIndex();
15595 }
else if (BaseType->isAnyComplexType()) {
15596 const auto *CT = BaseType->castAs<
ComplexType>();
15597 uint64_t Index = Entry.getAsArrayIndex();
15600 BaseType = CT->getElementType();
15601 }
else if (
auto *FD = getAsField(Entry)) {
15602 if (!IsLastOrInvalidFieldDecl(FD))
15606 assert(getAsBaseClass(Entry) &&
"Expecting cast to a base class");
15618 if (LVal.Designator.Invalid)
15621 if (!LVal.Designator.Entries.empty())
15622 return LVal.Designator.isMostDerivedAnUnsizedArray();
15624 if (!LVal.InvalidBase)
15636 const SubobjectDesignator &
Designator = LVal.Designator;
15648 auto isFlexibleArrayMember = [&] {
15650 FAMKind StrictFlexArraysLevel =
15653 if (
Designator.isMostDerivedAnUnsizedArray())
15656 if (StrictFlexArraysLevel == FAMKind::Default)
15659 if (
Designator.getMostDerivedArraySize() == 0 &&
15660 StrictFlexArraysLevel != FAMKind::IncompleteOnly)
15663 if (
Designator.getMostDerivedArraySize() == 1 &&
15664 StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete)
15670 return LVal.InvalidBase &&
15672 Designator.MostDerivedIsArrayElement && isFlexibleArrayMember() &&
15680 auto CharUnitsMax = std::numeric_limits<CharUnits::QuantityType>::max();
15681 if (Int.ugt(CharUnitsMax))
15691 if (!
T.isNull() &&
T->isStructureType() &&
15692 T->castAsRecordDecl()->hasFlexibleArrayMember())
15693 if (
const auto *
V = LV.getLValueBase().dyn_cast<
const ValueDecl *>())
15694 if (
const auto *VD = dyn_cast<VarDecl>(
V))
15706 unsigned Type,
const LValue &LVal,
15725 if (!(
Type & 1) || LVal.Designator.Invalid || DetermineForCompleteObject) {
15727 if (
Type == 3 && !DetermineForCompleteObject)
15730 llvm::APInt APEndOffset;
15731 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
15735 if (LVal.InvalidBase)
15739 const bool Ret = CheckedHandleSizeof(BaseTy, EndOffset);
15745 const SubobjectDesignator &
Designator = LVal.Designator;
15757 llvm::APInt APEndOffset;
15758 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
15770 if (!CheckedHandleSizeof(
Designator.MostDerivedType, BytesPerElem))
15776 int64_t ElemsRemaining;
15779 uint64_t ArraySize =
Designator.getMostDerivedArraySize();
15780 uint64_t ArrayIndex =
Designator.Entries.back().getAsArrayIndex();
15781 ElemsRemaining = ArraySize <= ArrayIndex ? 0 : ArraySize - ArrayIndex;
15783 ElemsRemaining =
Designator.isOnePastTheEnd() ? 0 : 1;
15786 EndOffset = LVal.getLValueOffset() + BytesPerElem * ElemsRemaining;
15796 EvalInfo &Info, uint64_t &Size) {
15803 SpeculativeEvaluationRAII SpeculativeEval(Info);
15804 IgnoreSideEffectsRAII Fold(Info);
15812 LVal.setFrom(Info.Ctx, RVal);
15820 if (LVal.getLValueOffset().isNegative()) {
15831 if (EndOffset <= LVal.getLValueOffset())
15834 Size = (EndOffset - LVal.getLValueOffset()).getQuantity();
15838bool IntExprEvaluator::VisitCallExpr(
const CallExpr *E) {
15839 if (!IsConstantEvaluatedBuiltinCall(E))
15840 return ExprEvaluatorBaseTy::VisitCallExpr(E);
15857 Info.FFDiag(E->
getArg(0));
15863 assert(SrcInt.getBitWidth() >= Alignment.getBitWidth() &&
15864 "Bit widths must be the same");
15871bool IntExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *E,
15872 unsigned BuiltinOp) {
15873 auto EvalTestOp = [&](llvm::function_ref<
bool(
const APInt &,
const APInt &)>
15875 APValue SourceLHS, SourceRHS;
15883 unsigned LaneWidth = Info.Ctx.
getTypeSize(ElemQT);
15885 APInt AWide(LaneWidth * SourceLen, 0);
15886 APInt BWide(LaneWidth * SourceLen, 0);
15888 for (
unsigned I = 0; I != SourceLen; ++I) {
15891 if (ElemQT->isIntegerType()) {
15894 }
else if (ElemQT->isFloatingType()) {
15902 AWide.insertBits(ALane, I * LaneWidth);
15903 BWide.insertBits(BLane, I * LaneWidth);
15908 auto HandleMaskBinOp =
15921 switch (BuiltinOp) {
15925 case Builtin::BI__builtin_dynamic_object_size:
15926 case Builtin::BI__builtin_object_size: {
15930 assert(
Type <= 3 &&
"unexpected type");
15941 switch (Info.EvalMode) {
15942 case EvaluationMode::ConstantExpression:
15943 case EvaluationMode::ConstantFold:
15944 case EvaluationMode::IgnoreSideEffects:
15947 case EvaluationMode::ConstantExpressionUnevaluated:
15952 llvm_unreachable(
"unexpected EvalMode");
15955 case Builtin::BI__builtin_os_log_format_buffer_size: {
15956 analyze_os_log::OSLogBufferLayout Layout;
15961 case Builtin::BI__builtin_is_aligned: {
15969 Ptr.setFrom(Info.Ctx, Src);
15975 assert(Alignment.isPowerOf2());
15988 Info.FFDiag(E->
getArg(0), diag::note_constexpr_alignment_compute)
15992 assert(Src.
isInt());
15993 return Success((Src.
getInt() & (Alignment - 1)) == 0 ? 1 : 0, E);
15995 case Builtin::BI__builtin_align_up: {
16003 APSInt((Src.
getInt() + (Alignment - 1)) & ~(Alignment - 1),
16004 Src.
getInt().isUnsigned());
16005 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
16006 return Success(AlignedVal, E);
16008 case Builtin::BI__builtin_align_down: {
16017 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
16018 return Success(AlignedVal, E);
16021 case Builtin::BI__builtin_bitreverse8:
16022 case Builtin::BI__builtin_bitreverse16:
16023 case Builtin::BI__builtin_bitreverse32:
16024 case Builtin::BI__builtin_bitreverse64:
16025 case Builtin::BI__builtin_elementwise_bitreverse: {
16030 return Success(Val.reverseBits(), E);
16032 case Builtin::BI__builtin_bswapg:
16033 case Builtin::BI__builtin_bswap16:
16034 case Builtin::BI__builtin_bswap32:
16035 case Builtin::BI__builtin_bswap64: {
16039 if (Val.getBitWidth() == 8)
16042 return Success(Val.byteSwap(), E);
16045 case Builtin::BI__builtin_classify_type:
16048 case Builtin::BI__builtin_clrsb:
16049 case Builtin::BI__builtin_clrsbl:
16050 case Builtin::BI__builtin_clrsbll: {
16055 return Success(Val.getBitWidth() - Val.getSignificantBits(), E);
16058 case Builtin::BI__builtin_clz:
16059 case Builtin::BI__builtin_clzl:
16060 case Builtin::BI__builtin_clzll:
16061 case Builtin::BI__builtin_clzs:
16062 case Builtin::BI__builtin_clzg:
16063 case Builtin::BI__builtin_elementwise_clzg:
16064 case Builtin::BI__lzcnt16:
16065 case Builtin::BI__lzcnt:
16066 case Builtin::BI__lzcnt64: {
16077 std::optional<APSInt> Fallback;
16078 if ((BuiltinOp == Builtin::BI__builtin_clzg ||
16079 BuiltinOp == Builtin::BI__builtin_elementwise_clzg) &&
16084 Fallback = FallbackTemp;
16089 return Success(*Fallback, E);
16094 bool ZeroIsUndefined = BuiltinOp != Builtin::BI__lzcnt16 &&
16095 BuiltinOp != Builtin::BI__lzcnt &&
16096 BuiltinOp != Builtin::BI__lzcnt64;
16098 if (BuiltinOp == Builtin::BI__builtin_elementwise_clzg) {
16099 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
16103 if (ZeroIsUndefined)
16107 return Success(Val.countl_zero(), E);
16110 case Builtin::BI__builtin_constant_p: {
16111 const Expr *Arg = E->
getArg(0);
16120 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
16124 case Builtin::BI__noop:
16128 case Builtin::BI__builtin_is_constant_evaluated: {
16129 const auto *
Callee = Info.CurrentCall->getCallee();
16130 if (Info.InConstantContext && !Info.CheckingPotentialConstantExpression &&
16131 (Info.CallStackDepth == 1 ||
16132 (Info.CallStackDepth == 2 &&
Callee->isInStdNamespace() &&
16133 Callee->getIdentifier() &&
16134 Callee->getIdentifier()->isStr(
"is_constant_evaluated")))) {
16136 if (Info.EvalStatus.
Diag)
16137 Info.report((Info.CallStackDepth == 1)
16139 : Info.CurrentCall->getCallRange().getBegin(),
16140 diag::warn_is_constant_evaluated_always_true_constexpr)
16141 << (Info.CallStackDepth == 1 ?
"__builtin_is_constant_evaluated"
16142 :
"std::is_constant_evaluated");
16145 return Success(Info.InConstantContext, E);
16148 case Builtin::BI__builtin_is_within_lifetime:
16149 if (
auto result = EvaluateBuiltinIsWithinLifetime(*
this, E))
16153 case Builtin::BI__builtin_ctz:
16154 case Builtin::BI__builtin_ctzl:
16155 case Builtin::BI__builtin_ctzll:
16156 case Builtin::BI__builtin_ctzs:
16157 case Builtin::BI__builtin_ctzg:
16158 case Builtin::BI__builtin_elementwise_ctzg: {
16169 std::optional<APSInt> Fallback;
16170 if ((BuiltinOp == Builtin::BI__builtin_ctzg ||
16171 BuiltinOp == Builtin::BI__builtin_elementwise_ctzg) &&
16176 Fallback = FallbackTemp;
16181 return Success(*Fallback, E);
16183 if (BuiltinOp == Builtin::BI__builtin_elementwise_ctzg) {
16184 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
16190 return Success(Val.countr_zero(), E);
16193 case Builtin::BI__builtin_eh_return_data_regno: {
16199 case Builtin::BI__builtin_elementwise_abs: {
16204 return Success(Val.abs(), E);
16207 case Builtin::BI__builtin_expect:
16208 case Builtin::BI__builtin_expect_with_probability:
16209 return Visit(E->
getArg(0));
16211 case Builtin::BI__builtin_ptrauth_string_discriminator: {
16218 case Builtin::BI__builtin_infer_alloc_token: {
16224 E, diag::note_constexpr_infer_alloc_token_type_inference_failed);
16227 return Error(E, diag::note_constexpr_infer_alloc_token_no_metadata);
16229 Info.getLangOpts().AllocTokenMode.value_or(llvm::DefaultAllocTokenMode);
16231 auto MaxTokensOpt = Info.getLangOpts().AllocTokenMax;
16233 MaxTokensOpt.value_or(0) ? *MaxTokensOpt : (~0ULL >> (64 - BitWidth));
16234 auto MaybeToken = llvm::getAllocToken(Mode, *ATMD, MaxTokens);
16236 return Error(E, diag::note_constexpr_infer_alloc_token_stateful_mode);
16237 return Success(llvm::APInt(BitWidth, *MaybeToken), E);
16240 case Builtin::BI__builtin_ffs:
16241 case Builtin::BI__builtin_ffsl:
16242 case Builtin::BI__builtin_ffsll: {
16247 unsigned N = Val.countr_zero();
16248 return Success(N == Val.getBitWidth() ? 0 : N + 1, E);
16251 case Builtin::BI__builtin_fpclassify: {
16256 switch (Val.getCategory()) {
16257 case APFloat::fcNaN: Arg = 0;
break;
16258 case APFloat::fcInfinity: Arg = 1;
break;
16259 case APFloat::fcNormal: Arg = Val.isDenormal() ? 3 : 2;
break;
16260 case APFloat::fcZero: Arg = 4;
break;
16262 return Visit(E->
getArg(Arg));
16265 case Builtin::BI__builtin_isinf_sign: {
16268 Success(Val.isInfinity() ? (Val.isNegative() ? -1 : 1) : 0, E);
16271 case Builtin::BI__builtin_isinf: {
16274 Success(Val.isInfinity() ? 1 : 0, E);
16277 case Builtin::BI__builtin_isfinite: {
16280 Success(Val.isFinite() ? 1 : 0, E);
16283 case Builtin::BI__builtin_isnan: {
16286 Success(Val.isNaN() ? 1 : 0, E);
16289 case Builtin::BI__builtin_isnormal: {
16292 Success(Val.isNormal() ? 1 : 0, E);
16295 case Builtin::BI__builtin_issubnormal: {
16298 Success(Val.isDenormal() ? 1 : 0, E);
16301 case Builtin::BI__builtin_iszero: {
16304 Success(Val.isZero() ? 1 : 0, E);
16307 case Builtin::BI__builtin_signbit:
16308 case Builtin::BI__builtin_signbitf:
16309 case Builtin::BI__builtin_signbitl: {
16312 Success(Val.isNegative() ? 1 : 0, E);
16315 case Builtin::BI__builtin_isgreater:
16316 case Builtin::BI__builtin_isgreaterequal:
16317 case Builtin::BI__builtin_isless:
16318 case Builtin::BI__builtin_islessequal:
16319 case Builtin::BI__builtin_islessgreater:
16320 case Builtin::BI__builtin_isunordered: {
16329 switch (BuiltinOp) {
16330 case Builtin::BI__builtin_isgreater:
16332 case Builtin::BI__builtin_isgreaterequal:
16334 case Builtin::BI__builtin_isless:
16336 case Builtin::BI__builtin_islessequal:
16338 case Builtin::BI__builtin_islessgreater: {
16339 APFloat::cmpResult cmp = LHS.compare(RHS);
16340 return cmp == APFloat::cmpResult::cmpLessThan ||
16341 cmp == APFloat::cmpResult::cmpGreaterThan;
16343 case Builtin::BI__builtin_isunordered:
16344 return LHS.compare(RHS) == APFloat::cmpResult::cmpUnordered;
16346 llvm_unreachable(
"Unexpected builtin ID: Should be a floating "
16347 "point comparison function");
16355 case Builtin::BI__builtin_issignaling: {
16358 Success(Val.isSignaling() ? 1 : 0, E);
16361 case Builtin::BI__builtin_isfpclass: {
16365 unsigned Test =
static_cast<llvm::FPClassTest
>(MaskVal.getZExtValue());
16368 Success((Val.classify() & Test) ? 1 : 0, E);
16371 case Builtin::BI__builtin_parity:
16372 case Builtin::BI__builtin_parityl:
16373 case Builtin::BI__builtin_parityll: {
16378 return Success(Val.popcount() % 2, E);
16381 case Builtin::BI__builtin_abs:
16382 case Builtin::BI__builtin_labs:
16383 case Builtin::BI__builtin_llabs: {
16387 if (Val ==
APSInt(APInt::getSignedMinValue(Val.getBitWidth()),
16390 if (Val.isNegative())
16395 case Builtin::BI__builtin_popcount:
16396 case Builtin::BI__builtin_popcountl:
16397 case Builtin::BI__builtin_popcountll:
16398 case Builtin::BI__builtin_popcountg:
16399 case Builtin::BI__builtin_elementwise_popcount:
16400 case Builtin::BI__popcnt16:
16401 case Builtin::BI__popcnt:
16402 case Builtin::BI__popcnt64: {
16413 return Success(Val.popcount(), E);
16416 case Builtin::BI__builtin_rotateleft8:
16417 case Builtin::BI__builtin_rotateleft16:
16418 case Builtin::BI__builtin_rotateleft32:
16419 case Builtin::BI__builtin_rotateleft64:
16420 case Builtin::BI_rotl8:
16421 case Builtin::BI_rotl16:
16422 case Builtin::BI_rotl:
16423 case Builtin::BI_lrotl:
16424 case Builtin::BI_rotl64: {
16430 return Success(Val.rotl(Amt), E);
16433 case Builtin::BI__builtin_rotateright8:
16434 case Builtin::BI__builtin_rotateright16:
16435 case Builtin::BI__builtin_rotateright32:
16436 case Builtin::BI__builtin_rotateright64:
16437 case Builtin::BI_rotr8:
16438 case Builtin::BI_rotr16:
16439 case Builtin::BI_rotr:
16440 case Builtin::BI_lrotr:
16441 case Builtin::BI_rotr64: {
16447 return Success(Val.rotr(Amt), E);
16450 case Builtin::BI__builtin_elementwise_add_sat: {
16456 APInt Result = LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS);
16459 case Builtin::BI__builtin_elementwise_sub_sat: {
16465 APInt Result = LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
16468 case Builtin::BI__builtin_elementwise_max: {
16477 case Builtin::BI__builtin_elementwise_min: {
16486 case Builtin::BI__builtin_elementwise_fshl:
16487 case Builtin::BI__builtin_elementwise_fshr: {
16494 switch (BuiltinOp) {
16495 case Builtin::BI__builtin_elementwise_fshl: {
16496 APSInt Result(llvm::APIntOps::fshl(Hi, Lo, Shift), Hi.isUnsigned());
16499 case Builtin::BI__builtin_elementwise_fshr: {
16500 APSInt Result(llvm::APIntOps::fshr(Hi, Lo, Shift), Hi.isUnsigned());
16504 llvm_unreachable(
"Fully covered switch above");
16506 case Builtin::BIstrlen:
16507 case Builtin::BIwcslen:
16509 if (Info.getLangOpts().CPlusPlus11)
16510 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
16514 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
16516 case Builtin::BI__builtin_strlen:
16517 case Builtin::BI__builtin_wcslen: {
16526 case Builtin::BIstrcmp:
16527 case Builtin::BIwcscmp:
16528 case Builtin::BIstrncmp:
16529 case Builtin::BIwcsncmp:
16530 case Builtin::BImemcmp:
16531 case Builtin::BIbcmp:
16532 case Builtin::BIwmemcmp:
16534 if (Info.getLangOpts().CPlusPlus11)
16535 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
16539 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
16541 case Builtin::BI__builtin_strcmp:
16542 case Builtin::BI__builtin_wcscmp:
16543 case Builtin::BI__builtin_strncmp:
16544 case Builtin::BI__builtin_wcsncmp:
16545 case Builtin::BI__builtin_memcmp:
16546 case Builtin::BI__builtin_bcmp:
16547 case Builtin::BI__builtin_wmemcmp: {
16548 LValue String1, String2;
16554 if (BuiltinOp != Builtin::BIstrcmp &&
16555 BuiltinOp != Builtin::BIwcscmp &&
16556 BuiltinOp != Builtin::BI__builtin_strcmp &&
16557 BuiltinOp != Builtin::BI__builtin_wcscmp) {
16561 MaxLength = N.getZExtValue();
16565 if (MaxLength == 0u)
16568 if (!String1.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
16569 !String2.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
16570 String1.Designator.Invalid || String2.Designator.Invalid)
16573 QualType CharTy1 = String1.Designator.getType(Info.Ctx);
16574 QualType CharTy2 = String2.Designator.getType(Info.Ctx);
16576 bool IsRawByte = BuiltinOp == Builtin::BImemcmp ||
16577 BuiltinOp == Builtin::BIbcmp ||
16578 BuiltinOp == Builtin::BI__builtin_memcmp ||
16579 BuiltinOp == Builtin::BI__builtin_bcmp;
16581 assert(IsRawByte ||
16591 Info.FFDiag(E, diag::note_constexpr_memcmp_unsupported)
16597 const auto &ReadCurElems = [&](
APValue &Char1,
APValue &Char2) {
16600 Char1.
isInt() && Char2.isInt();
16602 const auto &AdvanceElems = [&] {
16608 (BuiltinOp != Builtin::BImemcmp && BuiltinOp != Builtin::BIbcmp &&
16609 BuiltinOp != Builtin::BIwmemcmp &&
16610 BuiltinOp != Builtin::BI__builtin_memcmp &&
16611 BuiltinOp != Builtin::BI__builtin_bcmp &&
16612 BuiltinOp != Builtin::BI__builtin_wmemcmp);
16613 bool IsWide = BuiltinOp == Builtin::BIwcscmp ||
16614 BuiltinOp == Builtin::BIwcsncmp ||
16615 BuiltinOp == Builtin::BIwmemcmp ||
16616 BuiltinOp == Builtin::BI__builtin_wcscmp ||
16617 BuiltinOp == Builtin::BI__builtin_wcsncmp ||
16618 BuiltinOp == Builtin::BI__builtin_wmemcmp;
16620 for (; MaxLength; --MaxLength) {
16622 if (!ReadCurElems(Char1, Char2))
16630 if (StopAtNull && !Char1.
getInt())
16632 assert(!(StopAtNull && !Char2.
getInt()));
16633 if (!AdvanceElems())
16640 case Builtin::BI__atomic_always_lock_free:
16641 case Builtin::BI__atomic_is_lock_free:
16642 case Builtin::BI__c11_atomic_is_lock_free: {
16658 if (
Size.isPowerOfTwo()) {
16660 unsigned InlineWidthBits =
16663 if (BuiltinOp == Builtin::BI__c11_atomic_is_lock_free ||
16669 const Expr *PtrArg = E->
getArg(1);
16675 IntResult.isAligned(
Size.getAsAlign()))
16679 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(PtrArg)) {
16682 if (ICE->getCastKind() == CK_BitCast)
16683 PtrArg = ICE->getSubExpr();
16686 if (
auto PtrTy = PtrArg->
getType()->
getAs<PointerType>()) {
16697 return BuiltinOp == Builtin::BI__atomic_always_lock_free ?
16700 case Builtin::BI__builtin_addcb:
16701 case Builtin::BI__builtin_addcs:
16702 case Builtin::BI__builtin_addc:
16703 case Builtin::BI__builtin_addcl:
16704 case Builtin::BI__builtin_addcll:
16705 case Builtin::BI__builtin_subcb:
16706 case Builtin::BI__builtin_subcs:
16707 case Builtin::BI__builtin_subc:
16708 case Builtin::BI__builtin_subcl:
16709 case Builtin::BI__builtin_subcll: {
16710 LValue CarryOutLValue;
16722 bool FirstOverflowed =
false;
16723 bool SecondOverflowed =
false;
16724 switch (BuiltinOp) {
16726 llvm_unreachable(
"Invalid value for BuiltinOp");
16727 case Builtin::BI__builtin_addcb:
16728 case Builtin::BI__builtin_addcs:
16729 case Builtin::BI__builtin_addc:
16730 case Builtin::BI__builtin_addcl:
16731 case Builtin::BI__builtin_addcll:
16733 LHS.uadd_ov(RHS, FirstOverflowed).uadd_ov(CarryIn, SecondOverflowed);
16735 case Builtin::BI__builtin_subcb:
16736 case Builtin::BI__builtin_subcs:
16737 case Builtin::BI__builtin_subc:
16738 case Builtin::BI__builtin_subcl:
16739 case Builtin::BI__builtin_subcll:
16741 LHS.usub_ov(RHS, FirstOverflowed).usub_ov(CarryIn, SecondOverflowed);
16747 CarryOut = (
uint64_t)(FirstOverflowed | SecondOverflowed);
16753 case Builtin::BI__builtin_add_overflow:
16754 case Builtin::BI__builtin_sub_overflow:
16755 case Builtin::BI__builtin_mul_overflow:
16756 case Builtin::BI__builtin_sadd_overflow:
16757 case Builtin::BI__builtin_uadd_overflow:
16758 case Builtin::BI__builtin_uaddl_overflow:
16759 case Builtin::BI__builtin_uaddll_overflow:
16760 case Builtin::BI__builtin_usub_overflow:
16761 case Builtin::BI__builtin_usubl_overflow:
16762 case Builtin::BI__builtin_usubll_overflow:
16763 case Builtin::BI__builtin_umul_overflow:
16764 case Builtin::BI__builtin_umull_overflow:
16765 case Builtin::BI__builtin_umulll_overflow:
16766 case Builtin::BI__builtin_saddl_overflow:
16767 case Builtin::BI__builtin_saddll_overflow:
16768 case Builtin::BI__builtin_ssub_overflow:
16769 case Builtin::BI__builtin_ssubl_overflow:
16770 case Builtin::BI__builtin_ssubll_overflow:
16771 case Builtin::BI__builtin_smul_overflow:
16772 case Builtin::BI__builtin_smull_overflow:
16773 case Builtin::BI__builtin_smulll_overflow: {
16774 LValue ResultLValue;
16784 bool DidOverflow =
false;
16787 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
16788 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
16789 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
16790 bool IsSigned = LHS.isSigned() || RHS.isSigned() ||
16792 bool AllSigned = LHS.isSigned() && RHS.isSigned() &&
16794 uint64_t LHSSize = LHS.getBitWidth();
16795 uint64_t RHSSize = RHS.getBitWidth();
16797 uint64_t MaxBits = std::max(std::max(LHSSize, RHSSize), ResultSize);
16803 if (IsSigned && !AllSigned)
16806 LHS =
APSInt(LHS.extOrTrunc(MaxBits), !IsSigned);
16807 RHS =
APSInt(RHS.extOrTrunc(MaxBits), !IsSigned);
16812 switch (BuiltinOp) {
16814 llvm_unreachable(
"Invalid value for BuiltinOp");
16815 case Builtin::BI__builtin_add_overflow:
16816 case Builtin::BI__builtin_sadd_overflow:
16817 case Builtin::BI__builtin_saddl_overflow:
16818 case Builtin::BI__builtin_saddll_overflow:
16819 case Builtin::BI__builtin_uadd_overflow:
16820 case Builtin::BI__builtin_uaddl_overflow:
16821 case Builtin::BI__builtin_uaddll_overflow:
16822 Result = LHS.isSigned() ? LHS.sadd_ov(RHS, DidOverflow)
16823 : LHS.uadd_ov(RHS, DidOverflow);
16825 case Builtin::BI__builtin_sub_overflow:
16826 case Builtin::BI__builtin_ssub_overflow:
16827 case Builtin::BI__builtin_ssubl_overflow:
16828 case Builtin::BI__builtin_ssubll_overflow:
16829 case Builtin::BI__builtin_usub_overflow:
16830 case Builtin::BI__builtin_usubl_overflow:
16831 case Builtin::BI__builtin_usubll_overflow:
16832 Result = LHS.isSigned() ? LHS.ssub_ov(RHS, DidOverflow)
16833 : LHS.usub_ov(RHS, DidOverflow);
16835 case Builtin::BI__builtin_mul_overflow:
16836 case Builtin::BI__builtin_smul_overflow:
16837 case Builtin::BI__builtin_smull_overflow:
16838 case Builtin::BI__builtin_smulll_overflow:
16839 case Builtin::BI__builtin_umul_overflow:
16840 case Builtin::BI__builtin_umull_overflow:
16841 case Builtin::BI__builtin_umulll_overflow:
16842 Result = LHS.isSigned() ? LHS.smul_ov(RHS, DidOverflow)
16843 : LHS.umul_ov(RHS, DidOverflow);
16849 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
16850 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
16851 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
16860 if (!APSInt::isSameValue(Temp,
Result))
16861 DidOverflow =
true;
16868 return Success(DidOverflow, E);
16871 case Builtin::BI__builtin_reduce_add:
16872 case Builtin::BI__builtin_reduce_mul:
16873 case Builtin::BI__builtin_reduce_and:
16874 case Builtin::BI__builtin_reduce_or:
16875 case Builtin::BI__builtin_reduce_xor:
16876 case Builtin::BI__builtin_reduce_min:
16877 case Builtin::BI__builtin_reduce_max: {
16884 for (
unsigned EltNum = 1; EltNum < SourceLen; ++EltNum) {
16885 switch (BuiltinOp) {
16888 case Builtin::BI__builtin_reduce_add: {
16891 Reduced.getBitWidth() + 1, std::plus<APSInt>(), Reduced))
16895 case Builtin::BI__builtin_reduce_mul: {
16898 Reduced.getBitWidth() * 2, std::multiplies<APSInt>(), Reduced))
16902 case Builtin::BI__builtin_reduce_and: {
16906 case Builtin::BI__builtin_reduce_or: {
16910 case Builtin::BI__builtin_reduce_xor: {
16914 case Builtin::BI__builtin_reduce_min: {
16918 case Builtin::BI__builtin_reduce_max: {
16928 case clang::X86::BI__builtin_ia32_addcarryx_u32:
16929 case clang::X86::BI__builtin_ia32_addcarryx_u64:
16930 case clang::X86::BI__builtin_ia32_subborrow_u32:
16931 case clang::X86::BI__builtin_ia32_subborrow_u64: {
16932 LValue ResultLValue;
16933 APSInt CarryIn, LHS, RHS;
16941 bool IsAdd = BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u32 ||
16942 BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u64;
16944 unsigned BitWidth = LHS.getBitWidth();
16945 unsigned CarryInBit = CarryIn.ugt(0) ? 1 : 0;
16948 ? (LHS.zext(BitWidth + 1) + (RHS.zext(BitWidth + 1) + CarryInBit))
16949 : (LHS.zext(BitWidth + 1) - (RHS.zext(BitWidth + 1) + CarryInBit));
16951 APInt Result = ExResult.extractBits(BitWidth, 0);
16952 uint64_t CarryOut = ExResult.extractBitsAsZExtValue(1, BitWidth);
16960 case clang::X86::BI__builtin_ia32_movmskps:
16961 case clang::X86::BI__builtin_ia32_movmskpd:
16962 case clang::X86::BI__builtin_ia32_pmovmskb128:
16963 case clang::X86::BI__builtin_ia32_pmovmskb256:
16964 case clang::X86::BI__builtin_ia32_movmskps256:
16965 case clang::X86::BI__builtin_ia32_movmskpd256: {
16976 for (
unsigned I = 0; I != SourceLen; ++I) {
16978 if (ElemQT->isIntegerType()) {
16980 }
else if (ElemQT->isRealFloatingType()) {
16985 Result.setBitVal(I, Elem.isNegative());
16990 case clang::X86::BI__builtin_ia32_bextr_u32:
16991 case clang::X86::BI__builtin_ia32_bextr_u64:
16992 case clang::X86::BI__builtin_ia32_bextri_u32:
16993 case clang::X86::BI__builtin_ia32_bextri_u64: {
16999 unsigned BitWidth = Val.getBitWidth();
17001 uint64_t Length = Idx.extractBitsAsZExtValue(8, 8);
17002 Length = Length > BitWidth ? BitWidth : Length;
17005 if (Length == 0 || Shift >= BitWidth)
17009 Result &= llvm::maskTrailingOnes<uint64_t>(Length);
17013 case clang::X86::BI__builtin_ia32_bzhi_si:
17014 case clang::X86::BI__builtin_ia32_bzhi_di: {
17020 unsigned BitWidth = Val.getBitWidth();
17021 unsigned Index = Idx.extractBitsAsZExtValue(8, 0);
17022 if (Index < BitWidth)
17023 Val.clearHighBits(BitWidth - Index);
17027 case clang::X86::BI__builtin_ia32_ktestcqi:
17028 case clang::X86::BI__builtin_ia32_ktestchi:
17029 case clang::X86::BI__builtin_ia32_ktestcsi:
17030 case clang::X86::BI__builtin_ia32_ktestcdi: {
17036 return Success((~A & B) == 0, E);
17039 case clang::X86::BI__builtin_ia32_ktestzqi:
17040 case clang::X86::BI__builtin_ia32_ktestzhi:
17041 case clang::X86::BI__builtin_ia32_ktestzsi:
17042 case clang::X86::BI__builtin_ia32_ktestzdi: {
17048 return Success((A & B) == 0, E);
17051 case clang::X86::BI__builtin_ia32_kortestcqi:
17052 case clang::X86::BI__builtin_ia32_kortestchi:
17053 case clang::X86::BI__builtin_ia32_kortestcsi:
17054 case clang::X86::BI__builtin_ia32_kortestcdi: {
17060 return Success(~(A | B) == 0, E);
17063 case clang::X86::BI__builtin_ia32_kortestzqi:
17064 case clang::X86::BI__builtin_ia32_kortestzhi:
17065 case clang::X86::BI__builtin_ia32_kortestzsi:
17066 case clang::X86::BI__builtin_ia32_kortestzdi: {
17072 return Success((A | B) == 0, E);
17075 case clang::X86::BI__builtin_ia32_kunpckhi:
17076 case clang::X86::BI__builtin_ia32_kunpckdi:
17077 case clang::X86::BI__builtin_ia32_kunpcksi: {
17085 unsigned BW = A.getBitWidth();
17086 APSInt Result(A.trunc(BW / 2).concat(B.trunc(BW / 2)), A.isUnsigned());
17090 case clang::X86::BI__builtin_ia32_lzcnt_u16:
17091 case clang::X86::BI__builtin_ia32_lzcnt_u32:
17092 case clang::X86::BI__builtin_ia32_lzcnt_u64: {
17096 return Success(Val.countLeadingZeros(), E);
17099 case clang::X86::BI__builtin_ia32_tzcnt_u16:
17100 case clang::X86::BI__builtin_ia32_tzcnt_u32:
17101 case clang::X86::BI__builtin_ia32_tzcnt_u64: {
17105 return Success(Val.countTrailingZeros(), E);
17108 case clang::X86::BI__builtin_ia32_pdep_si:
17109 case clang::X86::BI__builtin_ia32_pdep_di: {
17115 unsigned BitWidth = Val.getBitWidth();
17117 for (
unsigned I = 0, P = 0; I != BitWidth; ++I)
17119 Result.setBitVal(I, Val[P++]);
17123 case clang::X86::BI__builtin_ia32_pext_si:
17124 case clang::X86::BI__builtin_ia32_pext_di: {
17130 unsigned BitWidth = Val.getBitWidth();
17132 for (
unsigned I = 0, P = 0; I != BitWidth; ++I)
17134 Result.setBitVal(P++, Val[I]);
17137 case X86::BI__builtin_ia32_ptestz128:
17138 case X86::BI__builtin_ia32_ptestz256:
17139 case X86::BI__builtin_ia32_vtestzps:
17140 case X86::BI__builtin_ia32_vtestzps256:
17141 case X86::BI__builtin_ia32_vtestzpd:
17142 case X86::BI__builtin_ia32_vtestzpd256: {
17144 [](
const APInt &A,
const APInt &B) {
return (A & B) == 0; });
17146 case X86::BI__builtin_ia32_ptestc128:
17147 case X86::BI__builtin_ia32_ptestc256:
17148 case X86::BI__builtin_ia32_vtestcps:
17149 case X86::BI__builtin_ia32_vtestcps256:
17150 case X86::BI__builtin_ia32_vtestcpd:
17151 case X86::BI__builtin_ia32_vtestcpd256: {
17153 [](
const APInt &A,
const APInt &B) {
return (~A & B) == 0; });
17155 case X86::BI__builtin_ia32_ptestnzc128:
17156 case X86::BI__builtin_ia32_ptestnzc256:
17157 case X86::BI__builtin_ia32_vtestnzcps:
17158 case X86::BI__builtin_ia32_vtestnzcps256:
17159 case X86::BI__builtin_ia32_vtestnzcpd:
17160 case X86::BI__builtin_ia32_vtestnzcpd256: {
17161 return EvalTestOp([](
const APInt &A,
const APInt &B) {
17162 return ((A & B) != 0) && ((~A & B) != 0);
17165 case X86::BI__builtin_ia32_kandqi:
17166 case X86::BI__builtin_ia32_kandhi:
17167 case X86::BI__builtin_ia32_kandsi:
17168 case X86::BI__builtin_ia32_kanddi: {
17169 return HandleMaskBinOp(
17170 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS & RHS; });
17173 case X86::BI__builtin_ia32_kandnqi:
17174 case X86::BI__builtin_ia32_kandnhi:
17175 case X86::BI__builtin_ia32_kandnsi:
17176 case X86::BI__builtin_ia32_kandndi: {
17177 return HandleMaskBinOp(
17178 [](
const APSInt &LHS,
const APSInt &RHS) {
return ~LHS & RHS; });
17181 case X86::BI__builtin_ia32_korqi:
17182 case X86::BI__builtin_ia32_korhi:
17183 case X86::BI__builtin_ia32_korsi:
17184 case X86::BI__builtin_ia32_kordi: {
17185 return HandleMaskBinOp(
17186 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS | RHS; });
17189 case X86::BI__builtin_ia32_kxnorqi:
17190 case X86::BI__builtin_ia32_kxnorhi:
17191 case X86::BI__builtin_ia32_kxnorsi:
17192 case X86::BI__builtin_ia32_kxnordi: {
17193 return HandleMaskBinOp(
17194 [](
const APSInt &LHS,
const APSInt &RHS) {
return ~(LHS ^ RHS); });
17197 case X86::BI__builtin_ia32_kxorqi:
17198 case X86::BI__builtin_ia32_kxorhi:
17199 case X86::BI__builtin_ia32_kxorsi:
17200 case X86::BI__builtin_ia32_kxordi: {
17201 return HandleMaskBinOp(
17202 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS ^ RHS; });
17205 case X86::BI__builtin_ia32_knotqi:
17206 case X86::BI__builtin_ia32_knothi:
17207 case X86::BI__builtin_ia32_knotsi:
17208 case X86::BI__builtin_ia32_knotdi: {
17216 case X86::BI__builtin_ia32_kaddqi:
17217 case X86::BI__builtin_ia32_kaddhi:
17218 case X86::BI__builtin_ia32_kaddsi:
17219 case X86::BI__builtin_ia32_kadddi: {
17220 return HandleMaskBinOp(
17221 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS + RHS; });
17224 case X86::BI__builtin_ia32_kmovb:
17225 case X86::BI__builtin_ia32_kmovw:
17226 case X86::BI__builtin_ia32_kmovd:
17227 case X86::BI__builtin_ia32_kmovq: {
17234 case X86::BI__builtin_ia32_kshiftliqi:
17235 case X86::BI__builtin_ia32_kshiftlihi:
17236 case X86::BI__builtin_ia32_kshiftlisi:
17237 case X86::BI__builtin_ia32_kshiftlidi: {
17238 return HandleMaskBinOp([](
const APSInt &LHS,
const APSInt &RHS) {
17239 unsigned Amt = RHS.getZExtValue() & 0xFF;
17240 if (Amt >= LHS.getBitWidth())
17241 return APSInt(APInt::getZero(LHS.getBitWidth()), LHS.isUnsigned());
17242 return APSInt(LHS.shl(Amt), LHS.isUnsigned());
17246 case X86::BI__builtin_ia32_kshiftriqi:
17247 case X86::BI__builtin_ia32_kshiftrihi:
17248 case X86::BI__builtin_ia32_kshiftrisi:
17249 case X86::BI__builtin_ia32_kshiftridi: {
17250 return HandleMaskBinOp([](
const APSInt &LHS,
const APSInt &RHS) {
17251 unsigned Amt = RHS.getZExtValue() & 0xFF;
17252 if (Amt >= LHS.getBitWidth())
17253 return APSInt(APInt::getZero(LHS.getBitWidth()), LHS.isUnsigned());
17254 return APSInt(LHS.lshr(Amt), LHS.isUnsigned());
17258 case clang::X86::BI__builtin_ia32_vec_ext_v4hi:
17259 case clang::X86::BI__builtin_ia32_vec_ext_v16qi:
17260 case clang::X86::BI__builtin_ia32_vec_ext_v8hi:
17261 case clang::X86::BI__builtin_ia32_vec_ext_v4si:
17262 case clang::X86::BI__builtin_ia32_vec_ext_v2di:
17263 case clang::X86::BI__builtin_ia32_vec_ext_v32qi:
17264 case clang::X86::BI__builtin_ia32_vec_ext_v16hi:
17265 case clang::X86::BI__builtin_ia32_vec_ext_v8si:
17266 case clang::X86::BI__builtin_ia32_vec_ext_v4di: {
17273 unsigned Idx =
static_cast<unsigned>(IdxAPS.getZExtValue() & (N - 1));
17277 case clang::X86::BI__builtin_ia32_cvtb2mask128:
17278 case clang::X86::BI__builtin_ia32_cvtb2mask256:
17279 case clang::X86::BI__builtin_ia32_cvtb2mask512:
17280 case clang::X86::BI__builtin_ia32_cvtw2mask128:
17281 case clang::X86::BI__builtin_ia32_cvtw2mask256:
17282 case clang::X86::BI__builtin_ia32_cvtw2mask512:
17283 case clang::X86::BI__builtin_ia32_cvtd2mask128:
17284 case clang::X86::BI__builtin_ia32_cvtd2mask256:
17285 case clang::X86::BI__builtin_ia32_cvtd2mask512:
17286 case clang::X86::BI__builtin_ia32_cvtq2mask128:
17287 case clang::X86::BI__builtin_ia32_cvtq2mask256:
17288 case clang::X86::BI__builtin_ia32_cvtq2mask512: {
17296 llvm::APInt Bits(RetWidth, 0);
17298 for (
unsigned ElemNum = 0; ElemNum != VectorLen; ++ElemNum) {
17300 unsigned MSB = A[A.getBitWidth() - 1];
17301 Bits.setBitVal(ElemNum, MSB);
17304 APSInt RetMask(Bits,
true);
17308 case clang::X86::BI__builtin_ia32_cmpb128_mask:
17309 case clang::X86::BI__builtin_ia32_cmpw128_mask:
17310 case clang::X86::BI__builtin_ia32_cmpd128_mask:
17311 case clang::X86::BI__builtin_ia32_cmpq128_mask:
17312 case clang::X86::BI__builtin_ia32_cmpb256_mask:
17313 case clang::X86::BI__builtin_ia32_cmpw256_mask:
17314 case clang::X86::BI__builtin_ia32_cmpd256_mask:
17315 case clang::X86::BI__builtin_ia32_cmpq256_mask:
17316 case clang::X86::BI__builtin_ia32_cmpb512_mask:
17317 case clang::X86::BI__builtin_ia32_cmpw512_mask:
17318 case clang::X86::BI__builtin_ia32_cmpd512_mask:
17319 case clang::X86::BI__builtin_ia32_cmpq512_mask:
17320 case clang::X86::BI__builtin_ia32_ucmpb128_mask:
17321 case clang::X86::BI__builtin_ia32_ucmpw128_mask:
17322 case clang::X86::BI__builtin_ia32_ucmpd128_mask:
17323 case clang::X86::BI__builtin_ia32_ucmpq128_mask:
17324 case clang::X86::BI__builtin_ia32_ucmpb256_mask:
17325 case clang::X86::BI__builtin_ia32_ucmpw256_mask:
17326 case clang::X86::BI__builtin_ia32_ucmpd256_mask:
17327 case clang::X86::BI__builtin_ia32_ucmpq256_mask:
17328 case clang::X86::BI__builtin_ia32_ucmpb512_mask:
17329 case clang::X86::BI__builtin_ia32_ucmpw512_mask:
17330 case clang::X86::BI__builtin_ia32_ucmpd512_mask:
17331 case clang::X86::BI__builtin_ia32_ucmpq512_mask: {
17335 (BuiltinOp >= clang::X86::BI__builtin_ia32_ucmpb128_mask &&
17336 BuiltinOp <= clang::X86::BI__builtin_ia32_ucmpw512_mask);
17349 unsigned RetWidth = Mask.getBitWidth();
17351 APSInt RetMask(llvm::APInt(RetWidth, 0),
true);
17353 for (
unsigned ElemNum = 0; ElemNum < VectorLen; ++ElemNum) {
17358 switch (
Opcode.getExtValue() & 0x7) {
17363 Result = IsUnsigned ? A.ult(B) : A.slt(B);
17366 Result = IsUnsigned ? A.ule(B) : A.sle(B);
17375 Result = IsUnsigned ? A.uge(B) : A.sge(B);
17378 Result = IsUnsigned ? A.ugt(B) : A.sgt(B);
17385 RetMask.setBitVal(ElemNum, Mask[ElemNum] &&
Result);
17390 case X86::BI__builtin_ia32_vpshufbitqmb128_mask:
17391 case X86::BI__builtin_ia32_vpshufbitqmb256_mask:
17392 case X86::BI__builtin_ia32_vpshufbitqmb512_mask: {
17405 unsigned NumBytesInQWord = 8;
17406 unsigned NumBitsInByte = 8;
17408 unsigned NumQWords = NumBytes / NumBytesInQWord;
17409 unsigned RetWidth = ZeroMask.getBitWidth();
17410 APSInt RetMask(llvm::APInt(RetWidth, 0),
true);
17412 for (
unsigned QWordId = 0; QWordId != NumQWords; ++QWordId) {
17413 APInt SourceQWord(64, 0);
17414 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
17418 SourceQWord.insertBits(
APInt(8, Byte & 0xFF), ByteIdx * NumBitsInByte);
17421 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
17422 unsigned SelIdx = QWordId * NumBytesInQWord + ByteIdx;
17425 if (ZeroMask[SelIdx]) {
17426 RetMask.setBitVal(SelIdx, SourceQWord[M]);
17438 const LValue &LV) {
17441 if (!LV.getLValueBase())
17446 if (!LV.getLValueDesignator().Invalid &&
17447 !LV.getLValueDesignator().isOnePastTheEnd())
17457 if (LV.getLValueDesignator().Invalid)
17463 return LV.getLValueOffset() == Size;
17473class DataRecursiveIntBinOpEvaluator {
17474 struct EvalResult {
17476 bool Failed =
false;
17478 EvalResult() =
default;
17480 void swap(EvalResult &RHS) {
17482 Failed = RHS.Failed;
17483 RHS.Failed =
false;
17489 EvalResult LHSResult;
17490 enum { AnyExprKind, BinOpKind, BinOpVisitedLHSKind }
Kind;
17493 Job(Job &&) =
default;
17495 void startSpeculativeEval(EvalInfo &Info) {
17496 SpecEvalRAII = SpeculativeEvaluationRAII(Info);
17500 SpeculativeEvaluationRAII SpecEvalRAII;
17503 SmallVector<Job, 16> Queue;
17505 IntExprEvaluator &IntEval;
17510 DataRecursiveIntBinOpEvaluator(IntExprEvaluator &IntEval,
APValue &
Result)
17511 : IntEval(IntEval), Info(IntEval.getEvalInfo()), FinalResult(
Result) { }
17517 static bool shouldEnqueue(
const BinaryOperator *E) {
17524 bool Traverse(
const BinaryOperator *E) {
17526 EvalResult PrevResult;
17527 while (!Queue.empty())
17528 process(PrevResult);
17530 if (PrevResult.Failed)
return false;
17532 FinalResult.
swap(PrevResult.Val);
17543 bool Error(
const Expr *E) {
17544 return IntEval.Error(E);
17547 return IntEval.Error(E, D);
17550 OptionalDiagnostic CCEDiag(
const Expr *E,
diag::kind D) {
17551 return Info.CCEDiag(E, D);
17555 bool VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
17556 bool &SuppressRHSDiags);
17558 bool VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
17561 void EvaluateExpr(
const Expr *E, EvalResult &
Result) {
17567 void process(EvalResult &
Result);
17569 void enqueue(
const Expr *E) {
17571 Queue.resize(Queue.size()+1);
17572 Queue.back().E = E;
17573 Queue.back().Kind = Job::AnyExprKind;
17579bool DataRecursiveIntBinOpEvaluator::
17580 VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
17581 bool &SuppressRHSDiags) {
17584 if (LHSResult.Failed)
17585 return Info.noteSideEffect();
17594 if (LHSAsBool == (E->
getOpcode() == BO_LOr)) {
17595 Success(LHSAsBool, E, LHSResult.Val);
17599 LHSResult.Failed =
true;
17603 if (!Info.noteSideEffect())
17609 SuppressRHSDiags =
true;
17618 if (LHSResult.Failed && !Info.noteFailure())
17629 assert(!LVal.
hasLValuePath() &&
"have designator for integer lvalue");
17631 uint64_t Offset64 = Offset.getQuantity();
17632 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
17634 : Offset64 + Index64);
17637bool DataRecursiveIntBinOpEvaluator::
17638 VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
17641 if (RHSResult.Failed)
17648 bool lhsResult, rhsResult;
17663 if (rhsResult == (E->
getOpcode() == BO_LOr))
17674 if (LHSResult.Failed || RHSResult.Failed)
17677 const APValue &LHSVal = LHSResult.Val;
17678 const APValue &RHSVal = RHSResult.Val;
17702 if (!LHSExpr || !RHSExpr)
17704 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
17705 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
17706 if (!LHSAddrExpr || !RHSAddrExpr)
17731void DataRecursiveIntBinOpEvaluator::process(EvalResult &
Result) {
17732 Job &job = Queue.back();
17734 switch (job.Kind) {
17735 case Job::AnyExprKind: {
17736 if (
const BinaryOperator *Bop = dyn_cast<BinaryOperator>(job.E)) {
17737 if (shouldEnqueue(Bop)) {
17738 job.Kind = Job::BinOpKind;
17739 enqueue(Bop->getLHS());
17744 EvaluateExpr(job.E,
Result);
17749 case Job::BinOpKind: {
17751 bool SuppressRHSDiags =
false;
17752 if (!VisitBinOpLHSOnly(
Result, Bop, SuppressRHSDiags)) {
17756 if (SuppressRHSDiags)
17757 job.startSpeculativeEval(Info);
17758 job.LHSResult.swap(
Result);
17759 job.Kind = Job::BinOpVisitedLHSKind;
17764 case Job::BinOpVisitedLHSKind: {
17768 Result.Failed = !VisitBinOp(job.LHSResult, RHS, Bop,
Result.Val);
17774 llvm_unreachable(
"Invalid Job::Kind!");
17778enum class CmpResult {
17787template <
class SuccessCB,
class AfterCB>
17790 SuccessCB &&
Success, AfterCB &&DoAfter) {
17795 "unsupported binary expression evaluation");
17797 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
17811 if (!LHSOK && !Info.noteFailure())
17816 return Success(CmpResult::Less, E);
17818 return Success(CmpResult::Greater, E);
17819 return Success(CmpResult::Equal, E);
17827 if (!LHSOK && !Info.noteFailure())
17832 return Success(CmpResult::Less, E);
17834 return Success(CmpResult::Greater, E);
17835 return Success(CmpResult::Equal, E);
17839 ComplexValue LHS, RHS;
17848 LHS.makeComplexFloat();
17849 LHS.FloatImag = APFloat(LHS.FloatReal.getSemantics());
17854 if (!LHSOK && !Info.noteFailure())
17860 RHS.makeComplexFloat();
17861 RHS.FloatImag = APFloat(RHS.FloatReal.getSemantics());
17865 if (LHS.isComplexFloat()) {
17866 APFloat::cmpResult CR_r =
17867 LHS.getComplexFloatReal().compare(RHS.getComplexFloatReal());
17868 APFloat::cmpResult CR_i =
17869 LHS.getComplexFloatImag().compare(RHS.getComplexFloatImag());
17870 bool IsEqual = CR_r == APFloat::cmpEqual && CR_i == APFloat::cmpEqual;
17871 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal, E);
17873 assert(IsEquality &&
"invalid complex comparison");
17874 bool IsEqual = LHS.getComplexIntReal() == RHS.getComplexIntReal() &&
17875 LHS.getComplexIntImag() == RHS.getComplexIntImag();
17876 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal, E);
17882 APFloat RHS(0.0), LHS(0.0);
17885 if (!LHSOK && !Info.noteFailure())
17892 llvm::APFloatBase::cmpResult APFloatCmpResult = LHS.compare(RHS);
17893 if (!Info.InConstantContext &&
17894 APFloatCmpResult == APFloat::cmpUnordered &&
17897 Info.FFDiag(E, diag::note_constexpr_float_arithmetic_strict);
17900 auto GetCmpRes = [&]() {
17901 switch (APFloatCmpResult) {
17902 case APFloat::cmpEqual:
17903 return CmpResult::Equal;
17904 case APFloat::cmpLessThan:
17905 return CmpResult::Less;
17906 case APFloat::cmpGreaterThan:
17907 return CmpResult::Greater;
17908 case APFloat::cmpUnordered:
17909 return CmpResult::Unordered;
17911 llvm_unreachable(
"Unrecognised APFloat::cmpResult enum");
17913 return Success(GetCmpRes(), E);
17917 LValue LHSValue, RHSValue;
17920 if (!LHSOK && !Info.noteFailure())
17931 if (Info.checkingPotentialConstantExpression() &&
17932 (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown))
17934 auto DiagComparison = [&] (
unsigned DiagID,
bool Reversed =
false) {
17935 std::string LHS = LHSValue.toString(Info.Ctx, E->
getLHS()->
getType());
17936 std::string RHS = RHSValue.toString(Info.Ctx, E->
getRHS()->
getType());
17937 Info.FFDiag(E, DiagID)
17944 return DiagComparison(
17945 diag::note_constexpr_pointer_comparison_unspecified);
17951 if ((!LHSValue.Base && !LHSValue.Offset.
isZero()) ||
17952 (!RHSValue.Base && !RHSValue.Offset.
isZero()))
17953 return DiagComparison(diag::note_constexpr_pointer_constant_comparison,
17967 return DiagComparison(diag::note_constexpr_literal_comparison);
17969 return DiagComparison(diag::note_constexpr_opaque_call_comparison,
17974 return DiagComparison(diag::note_constexpr_pointer_weak_comparison,
17978 if (LHSValue.Base && LHSValue.Offset.
isZero() &&
17980 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
17982 if (RHSValue.Base && RHSValue.Offset.
isZero() &&
17984 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
17990 return DiagComparison(
17991 diag::note_constexpr_pointer_comparison_zero_sized);
17992 if (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown)
17993 return DiagComparison(
17994 diag::note_constexpr_pointer_comparison_unspecified);
17996 return Success(CmpResult::Unequal, E);
17999 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
18000 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
18002 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
18003 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
18013 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid && IsRelational) {
18014 bool WasArrayIndex;
18017 :
getType(LHSValue.Base).getNonReferenceType(),
18018 LHSDesignator, RHSDesignator, WasArrayIndex);
18025 if (!WasArrayIndex && Mismatch < LHSDesignator.Entries.size() &&
18026 Mismatch < RHSDesignator.Entries.size()) {
18027 const FieldDecl *LF = getAsField(LHSDesignator.Entries[Mismatch]);
18028 const FieldDecl *RF = getAsField(RHSDesignator.Entries[Mismatch]);
18030 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_classes);
18032 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
18033 << getAsBaseClass(LHSDesignator.Entries[Mismatch])
18036 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
18037 << getAsBaseClass(RHSDesignator.Entries[Mismatch])
18042 diag::note_constexpr_pointer_comparison_differing_access)
18053 assert(PtrSize <= 64 &&
"Unexpected pointer width");
18054 uint64_t Mask = ~0ULL >> (64 - PtrSize);
18055 CompareLHS &= Mask;
18056 CompareRHS &= Mask;
18061 if (!LHSValue.Base.
isNull() && IsRelational) {
18066 uint64_t OffsetLimit = Size.getQuantity();
18067 if (CompareLHS > OffsetLimit || CompareRHS > OffsetLimit)
18071 if (CompareLHS < CompareRHS)
18072 return Success(CmpResult::Less, E);
18073 if (CompareLHS > CompareRHS)
18074 return Success(CmpResult::Greater, E);
18075 return Success(CmpResult::Equal, E);
18079 assert(IsEquality &&
"unexpected member pointer operation");
18082 MemberPtr LHSValue, RHSValue;
18085 if (!LHSOK && !Info.noteFailure())
18093 if (LHSValue.getDecl() && LHSValue.getDecl()->isWeak()) {
18094 Info.FFDiag(E, diag::note_constexpr_mem_pointer_weak_comparison)
18095 << LHSValue.getDecl();
18098 if (RHSValue.getDecl() && RHSValue.getDecl()->isWeak()) {
18099 Info.FFDiag(E, diag::note_constexpr_mem_pointer_weak_comparison)
18100 << RHSValue.getDecl();
18107 if (!LHSValue.getDecl() || !RHSValue.getDecl()) {
18108 bool Equal = !LHSValue.getDecl() && !RHSValue.getDecl();
18109 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal, E);
18114 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(LHSValue.getDecl()))
18115 if (MD->isVirtual())
18116 Info.CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
18117 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(RHSValue.getDecl()))
18118 if (MD->isVirtual())
18119 Info.CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
18125 bool Equal = LHSValue == RHSValue;
18126 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal, E);
18131 assert(RHSTy->
isNullPtrType() &&
"missing pointer conversion");
18139 return Success(CmpResult::Equal, E);
18145bool RecordExprEvaluator::VisitBinCmp(
const BinaryOperator *E) {
18149 auto OnSuccess = [&](CmpResult CR,
const BinaryOperator *E) {
18152 case CmpResult::Unequal:
18153 llvm_unreachable(
"should never produce Unequal for three-way comparison");
18154 case CmpResult::Less:
18155 CCR = ComparisonCategoryResult::Less;
18157 case CmpResult::Equal:
18158 CCR = ComparisonCategoryResult::Equal;
18160 case CmpResult::Greater:
18161 CCR = ComparisonCategoryResult::Greater;
18163 case CmpResult::Unordered:
18164 CCR = ComparisonCategoryResult::Unordered;
18169 const ComparisonCategoryInfo &CmpInfo =
18178 ConstantExprKind::Normal);
18181 return ExprEvaluatorBaseTy::VisitBinCmp(E);
18185bool RecordExprEvaluator::VisitCXXParenListInitExpr(
18186 const CXXParenListInitExpr *E) {
18187 return VisitCXXParenListOrInitListExpr(E, E->
getInitExprs());
18190bool IntExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
18195 if (!Info.noteFailure())
18199 if (DataRecursiveIntBinOpEvaluator::shouldEnqueue(E))
18200 return DataRecursiveIntBinOpEvaluator(*
this,
Result).Traverse(E);
18204 "DataRecursiveIntBinOpEvaluator should have handled integral types");
18209 auto OnSuccess = [&](CmpResult CR,
const BinaryOperator *E) {
18210 assert((CR != CmpResult::Unequal || E->
isEqualityOp()) &&
18211 "should only produce Unequal for equality comparisons");
18212 bool IsEqual = CR == CmpResult::Equal,
18213 IsLess = CR == CmpResult::Less,
18214 IsGreater = CR == CmpResult::Greater;
18218 llvm_unreachable(
"unsupported binary operator");
18221 return Success(IsEqual == (Op == BO_EQ), E);
18225 return Success(IsGreater, E);
18227 return Success(IsEqual || IsLess, E);
18229 return Success(IsEqual || IsGreater, E);
18233 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
18242 LValue LHSValue, RHSValue;
18245 if (!LHSOK && !Info.noteFailure())
18254 if (Info.checkingPotentialConstantExpression() &&
18255 (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown))
18258 const Expr *LHSExpr = LHSValue.Base.
dyn_cast<
const Expr *>();
18259 const Expr *RHSExpr = RHSValue.Base.
dyn_cast<
const Expr *>();
18261 auto DiagArith = [&](
unsigned DiagID) {
18262 std::string LHS = LHSValue.toString(Info.Ctx, E->
getLHS()->
getType());
18263 std::string RHS = RHSValue.toString(Info.Ctx, E->
getRHS()->
getType());
18264 Info.FFDiag(E, DiagID) << LHS << RHS;
18265 if (LHSExpr && LHSExpr == RHSExpr)
18267 diag::note_constexpr_repeated_literal_eval)
18272 if (!LHSExpr || !RHSExpr)
18273 return DiagArith(diag::note_constexpr_pointer_arith_unspecified);
18276 return DiagArith(diag::note_constexpr_literal_arith);
18278 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
18279 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
18280 if (!LHSAddrExpr || !RHSAddrExpr)
18288 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
18289 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
18291 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
18292 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
18298 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid &&
18301 Info.CCEDiag(E, diag::note_constexpr_pointer_subtraction_not_same_array);
18306 CharUnits ElementSize;
18313 if (ElementSize.
isZero()) {
18314 Info.FFDiag(E, diag::note_constexpr_pointer_subtraction_zero_size)
18331 APSInt TrueResult = (LHS - RHS) / ElemSize;
18334 if (
Result.extend(65) != TrueResult &&
18340 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
18345bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr(
18346 const UnaryExprOrTypeTraitExpr *E) {
18348 case UETT_PreferredAlignOf:
18349 case UETT_AlignOf: {
18358 case UETT_PtrAuthTypeDiscriminator: {
18364 case UETT_VecStep: {
18368 unsigned n = Ty->
castAs<VectorType>()->getNumElements();
18380 case UETT_DataSizeOf:
18381 case UETT_SizeOf: {
18385 if (
const ReferenceType *Ref = SrcTy->
getAs<ReferenceType>())
18396 case UETT_OpenMPRequiredSimdAlign:
18403 case UETT_VectorElements: {
18407 if (
const auto *VT = Ty->
getAs<VectorType>())
18411 if (Info.InConstantContext)
18412 Info.CCEDiag(E, diag::note_constexpr_non_const_vectorelements)
18417 case UETT_CountOf: {
18423 if (
const auto *CAT =
18435 if (VAT->getElementType()->isArrayType()) {
18438 if (!VAT->getSizeExpr()) {
18443 std::optional<APSInt> Res =
18444 VAT->getSizeExpr()->getIntegerConstantExpr(Info.Ctx);
18450 Res->getZExtValue()};
18462 llvm_unreachable(
"unknown expr/type trait");
18465bool IntExprEvaluator::VisitOffsetOfExpr(
const OffsetOfExpr *OOE) {
18471 for (
unsigned i = 0; i != n; ++i) {
18484 Result += IdxResult.getSExtValue() * ElementSize;
18489 FieldDecl *MemberDecl = ON.
getField();
18496 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
18503 llvm_unreachable(
"dependent __builtin_offsetof");
18506 CXXBaseSpecifier *BaseSpec = ON.
getBase();
18518 CurrentType = BaseSpec->
getType();
18532bool IntExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
18551 if (Info.checkingForUndefinedBehavior())
18553 diag::warn_integer_constant_overflow)
18581bool IntExprEvaluator::VisitCastExpr(
const CastExpr *E) {
18583 QualType DestType = E->
getType();
18584 QualType SrcType = SubExpr->
getType();
18587 case CK_BaseToDerived:
18588 case CK_DerivedToBase:
18589 case CK_UncheckedDerivedToBase:
18592 case CK_ArrayToPointerDecay:
18593 case CK_FunctionToPointerDecay:
18594 case CK_NullToPointer:
18595 case CK_NullToMemberPointer:
18596 case CK_BaseToDerivedMemberPointer:
18597 case CK_DerivedToBaseMemberPointer:
18598 case CK_ReinterpretMemberPointer:
18599 case CK_ConstructorConversion:
18600 case CK_IntegralToPointer:
18602 case CK_VectorSplat:
18603 case CK_IntegralToFloating:
18604 case CK_FloatingCast:
18605 case CK_CPointerToObjCPointerCast:
18606 case CK_BlockPointerToObjCPointerCast:
18607 case CK_AnyPointerToBlockPointerCast:
18608 case CK_ObjCObjectLValueCast:
18609 case CK_FloatingRealToComplex:
18610 case CK_FloatingComplexToReal:
18611 case CK_FloatingComplexCast:
18612 case CK_FloatingComplexToIntegralComplex:
18613 case CK_IntegralRealToComplex:
18614 case CK_IntegralComplexCast:
18615 case CK_IntegralComplexToFloatingComplex:
18616 case CK_BuiltinFnToFnPtr:
18617 case CK_ZeroToOCLOpaqueType:
18618 case CK_NonAtomicToAtomic:
18619 case CK_AddressSpaceConversion:
18620 case CK_IntToOCLSampler:
18621 case CK_FloatingToFixedPoint:
18622 case CK_FixedPointToFloating:
18623 case CK_FixedPointCast:
18624 case CK_IntegralToFixedPoint:
18625 case CK_MatrixCast:
18626 case CK_HLSLAggregateSplatCast:
18627 llvm_unreachable(
"invalid cast kind for integral value");
18631 case CK_LValueBitCast:
18632 case CK_ARCProduceObject:
18633 case CK_ARCConsumeObject:
18634 case CK_ARCReclaimReturnedObject:
18635 case CK_ARCExtendBlockObject:
18636 case CK_CopyAndAutoreleaseBlockObject:
18639 case CK_UserDefinedConversion:
18640 case CK_LValueToRValue:
18641 case CK_AtomicToNonAtomic:
18643 case CK_LValueToRValueBitCast:
18644 case CK_HLSLArrayRValue:
18645 return ExprEvaluatorBaseTy::VisitCastExpr(E);
18647 case CK_MemberPointerToBoolean:
18648 case CK_PointerToBoolean:
18649 case CK_IntegralToBoolean:
18650 case CK_FloatingToBoolean:
18651 case CK_BooleanToSignedIntegral:
18652 case CK_FloatingComplexToBoolean:
18653 case CK_IntegralComplexToBoolean: {
18658 if (BoolResult && E->
getCastKind() == CK_BooleanToSignedIntegral)
18660 return Success(IntResult, E);
18663 case CK_FixedPointToIntegral: {
18668 llvm::APSInt
Result = Src.convertToInt(
18676 case CK_FixedPointToBoolean: {
18679 if (!
Evaluate(Val, Info, SubExpr))
18684 case CK_IntegralCast: {
18685 if (!Visit(SubExpr))
18694 if (
Result.isAddrLabelDiff())
18712 if (!ED->isFixed()) {
18716 ED->getValueRange(
Max,
Min);
18719 if (ED->getNumNegativeBits() &&
18720 (
Max.slt(
Result.getInt().getSExtValue()) ||
18721 Min.sgt(
Result.getInt().getSExtValue())))
18722 Info.CCEDiag(E, diag::note_constexpr_unscoped_enum_out_of_range)
18723 << llvm::toString(
Result.getInt(), 10) <<
Min.getSExtValue()
18724 <<
Max.getSExtValue() << ED;
18725 else if (!ED->getNumNegativeBits() &&
18726 Max.ult(
Result.getInt().getZExtValue()))
18727 Info.CCEDiag(E, diag::note_constexpr_unscoped_enum_out_of_range)
18728 << llvm::toString(
Result.getInt(), 10) <<
Min.getZExtValue()
18729 <<
Max.getZExtValue() << ED;
18737 case CK_PointerToIntegral: {
18738 CCEDiag(E, diag::note_constexpr_invalid_cast)
18739 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
18746 if (LV.getLValueBase()) {
18754 LV.Designator.setInvalid();
18762 if (!
V.toIntegralConstant(AsInt, SrcType, Info.Ctx))
18763 llvm_unreachable(
"Can't cast this!");
18768 case CK_IntegralComplexToReal: {
18772 return Success(
C.getComplexIntReal(), E);
18775 case CK_FloatingToIntegral: {
18785 case CK_HLSLVectorTruncation: {
18791 case CK_HLSLMatrixTruncation: {
18795 case CK_HLSLElementwiseCast: {
18808 return Success(ResultVal, E);
18812 llvm_unreachable(
"unknown cast resulting in integral value");
18815bool IntExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
18820 if (!LV.isComplexInt())
18822 return Success(LV.getComplexIntReal(), E);
18828bool IntExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
18833 if (!LV.isComplexInt())
18835 return Success(LV.getComplexIntImag(), E);
18842bool IntExprEvaluator::VisitSizeOfPackExpr(
const SizeOfPackExpr *E) {
18846bool IntExprEvaluator::VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E) {
18850bool IntExprEvaluator::VisitConceptSpecializationExpr(
18851 const ConceptSpecializationExpr *E) {
18855bool IntExprEvaluator::VisitRequiresExpr(
const RequiresExpr *E) {
18859bool FixedPointExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
18869 if (!
Result.isFixedPoint())
18872 APFixedPoint Negated =
Result.getFixedPoint().negate(&Overflowed);
18886bool FixedPointExprEvaluator::VisitCastExpr(
const CastExpr *E) {
18888 QualType DestType = E->
getType();
18890 "Expected destination type to be a fixed point type");
18894 case CK_FixedPointCast: {
18899 APFixedPoint
Result = Src.convert(DestFXSema, &Overflowed);
18901 if (Info.checkingForUndefinedBehavior())
18903 diag::warn_fixedpoint_constant_overflow)
18910 case CK_IntegralToFixedPoint: {
18916 APFixedPoint IntResult = APFixedPoint::getFromIntValue(
18920 if (Info.checkingForUndefinedBehavior())
18922 diag::warn_fixedpoint_constant_overflow)
18923 << IntResult.toString() << E->
getType();
18928 return Success(IntResult, E);
18930 case CK_FloatingToFixedPoint: {
18936 APFixedPoint
Result = APFixedPoint::getFromFloatValue(
18940 if (Info.checkingForUndefinedBehavior())
18942 diag::warn_fixedpoint_constant_overflow)
18951 case CK_LValueToRValue:
18952 return ExprEvaluatorBaseTy::VisitCastExpr(E);
18958bool FixedPointExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
18960 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
18962 const Expr *LHS = E->
getLHS();
18963 const Expr *RHS = E->
getRHS();
18974 bool OpOverflow =
false, ConversionOverflow =
false;
18975 APFixedPoint
Result(LHSFX.getSemantics());
18978 Result = LHSFX.add(RHSFX, &OpOverflow)
18979 .convert(ResultFXSema, &ConversionOverflow);
18983 Result = LHSFX.sub(RHSFX, &OpOverflow)
18984 .convert(ResultFXSema, &ConversionOverflow);
18988 Result = LHSFX.mul(RHSFX, &OpOverflow)
18989 .convert(ResultFXSema, &ConversionOverflow);
18993 if (RHSFX.getValue() == 0) {
18994 Info.FFDiag(E, diag::note_expr_divide_by_zero);
18997 Result = LHSFX.div(RHSFX, &OpOverflow)
18998 .convert(ResultFXSema, &ConversionOverflow);
19004 llvm::APSInt RHSVal = RHSFX.getValue();
19007 LHSSema.getWidth() - (unsigned)LHSSema.hasUnsignedPadding();
19008 unsigned Amt = RHSVal.getLimitedValue(ShiftBW - 1);
19012 if (RHSVal.isNegative())
19013 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHSVal;
19014 else if (Amt != RHSVal)
19015 Info.CCEDiag(E, diag::note_constexpr_large_shift)
19016 << RHSVal << E->
getType() << ShiftBW;
19019 Result = LHSFX.shl(Amt, &OpOverflow);
19021 Result = LHSFX.shr(Amt, &OpOverflow);
19027 if (OpOverflow || ConversionOverflow) {
19028 if (Info.checkingForUndefinedBehavior())
19030 diag::warn_fixedpoint_constant_overflow)
19043class FloatExprEvaluator
19044 :
public ExprEvaluatorBase<FloatExprEvaluator> {
19047 FloatExprEvaluator(EvalInfo &info, APFloat &result)
19048 : ExprEvaluatorBaseTy(info),
Result(result) {}
19055 bool ZeroInitialization(
const Expr *E) {
19060 bool VisitCallExpr(
const CallExpr *E);
19062 bool VisitUnaryOperator(
const UnaryOperator *E);
19063 bool VisitBinaryOperator(
const BinaryOperator *E);
19064 bool VisitFloatingLiteral(
const FloatingLiteral *E);
19065 bool VisitCastExpr(
const CastExpr *E);
19067 bool VisitUnaryReal(
const UnaryOperator *E);
19068 bool VisitUnaryImag(
const UnaryOperator *E);
19077 return FloatExprEvaluator(Info, Result).Visit(E);
19084 llvm::APFloat &Result) {
19086 if (!S)
return false;
19088 const llvm::fltSemantics &Sem = Context.getFloatTypeSemantics(ResultTy);
19094 fill = llvm::APInt(32, 0);
19095 else if (S->
getString().getAsInteger(0, fill))
19098 if (Context.getTargetInfo().isNan2008()) {
19100 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
19102 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
19110 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
19112 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
19118bool FloatExprEvaluator::VisitCallExpr(
const CallExpr *E) {
19119 if (!IsConstantEvaluatedBuiltinCall(E))
19120 return ExprEvaluatorBaseTy::VisitCallExpr(E);
19126 case Builtin::BI__builtin_huge_val:
19127 case Builtin::BI__builtin_huge_valf:
19128 case Builtin::BI__builtin_huge_vall:
19129 case Builtin::BI__builtin_huge_valf16:
19130 case Builtin::BI__builtin_huge_valf128:
19131 case Builtin::BI__builtin_inf:
19132 case Builtin::BI__builtin_inff:
19133 case Builtin::BI__builtin_infl:
19134 case Builtin::BI__builtin_inff16:
19135 case Builtin::BI__builtin_inff128: {
19136 const llvm::fltSemantics &Sem =
19138 Result = llvm::APFloat::getInf(Sem);
19142 case Builtin::BI__builtin_nans:
19143 case Builtin::BI__builtin_nansf:
19144 case Builtin::BI__builtin_nansl:
19145 case Builtin::BI__builtin_nansf16:
19146 case Builtin::BI__builtin_nansf128:
19152 case Builtin::BI__builtin_nan:
19153 case Builtin::BI__builtin_nanf:
19154 case Builtin::BI__builtin_nanl:
19155 case Builtin::BI__builtin_nanf16:
19156 case Builtin::BI__builtin_nanf128:
19164 case Builtin::BI__builtin_elementwise_abs:
19165 case Builtin::BI__builtin_fabs:
19166 case Builtin::BI__builtin_fabsf:
19167 case Builtin::BI__builtin_fabsl:
19168 case Builtin::BI__builtin_fabsf128:
19177 if (
Result.isNegative())
19181 case Builtin::BI__arithmetic_fence:
19188 case Builtin::BI__builtin_copysign:
19189 case Builtin::BI__builtin_copysignf:
19190 case Builtin::BI__builtin_copysignl:
19191 case Builtin::BI__builtin_copysignf128: {
19200 case Builtin::BI__builtin_fmax:
19201 case Builtin::BI__builtin_fmaxf:
19202 case Builtin::BI__builtin_fmaxl:
19203 case Builtin::BI__builtin_fmaxf16:
19204 case Builtin::BI__builtin_fmaxf128: {
19213 case Builtin::BI__builtin_fmin:
19214 case Builtin::BI__builtin_fminf:
19215 case Builtin::BI__builtin_fminl:
19216 case Builtin::BI__builtin_fminf16:
19217 case Builtin::BI__builtin_fminf128: {
19226 case Builtin::BI__builtin_fmaximum_num:
19227 case Builtin::BI__builtin_fmaximum_numf:
19228 case Builtin::BI__builtin_fmaximum_numl:
19229 case Builtin::BI__builtin_fmaximum_numf16:
19230 case Builtin::BI__builtin_fmaximum_numf128: {
19239 case Builtin::BI__builtin_fminimum_num:
19240 case Builtin::BI__builtin_fminimum_numf:
19241 case Builtin::BI__builtin_fminimum_numl:
19242 case Builtin::BI__builtin_fminimum_numf16:
19243 case Builtin::BI__builtin_fminimum_numf128: {
19252 case Builtin::BI__builtin_elementwise_fma: {
19257 APFloat SourceY(0.), SourceZ(0.);
19263 (void)
Result.fusedMultiplyAdd(SourceY, SourceZ, RM);
19267 case clang::X86::BI__builtin_ia32_vec_ext_v4sf: {
19274 unsigned Idx =
static_cast<unsigned>(IdxAPS.getZExtValue() & (N - 1));
19280bool FloatExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
19292bool FloatExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
19303 Result = llvm::APFloat::getZero(Sem);
19307bool FloatExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
19309 default:
return Error(E);
19323bool FloatExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
19325 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
19329 if (!LHSOK && !Info.noteFailure())
19335bool FloatExprEvaluator::VisitFloatingLiteral(
const FloatingLiteral *E) {
19340bool FloatExprEvaluator::VisitCastExpr(
const CastExpr *E) {
19345 return ExprEvaluatorBaseTy::VisitCastExpr(E);
19347 case CK_HLSLAggregateSplatCast:
19348 llvm_unreachable(
"invalid cast kind for floating value");
19350 case CK_IntegralToFloating: {
19359 case CK_FixedPointToFloating: {
19368 case CK_FloatingCast: {
19369 if (!Visit(SubExpr))
19375 case CK_FloatingComplexToReal: {
19379 Result =
V.getComplexFloatReal();
19382 case CK_HLSLVectorTruncation: {
19388 case CK_HLSLMatrixTruncation: {
19392 case CK_HLSLElementwiseCast: {
19407 return Success(ResultVal, E);
19417class ComplexExprEvaluator
19418 :
public ExprEvaluatorBase<ComplexExprEvaluator> {
19422 ComplexExprEvaluator(EvalInfo &info, ComplexValue &
Result)
19430 bool ZeroInitialization(
const Expr *E);
19436 bool VisitImaginaryLiteral(
const ImaginaryLiteral *E);
19437 bool VisitCastExpr(
const CastExpr *E);
19438 bool VisitBinaryOperator(
const BinaryOperator *E);
19439 bool VisitUnaryOperator(
const UnaryOperator *E);
19440 bool VisitInitListExpr(
const InitListExpr *E);
19441 bool VisitCallExpr(
const CallExpr *E);
19449 return ComplexExprEvaluator(Info, Result).Visit(E);
19452bool ComplexExprEvaluator::ZeroInitialization(
const Expr *E) {
19453 QualType ElemTy = E->
getType()->
castAs<ComplexType>()->getElementType();
19455 Result.makeComplexFloat();
19460 Result.makeComplexInt();
19468bool ComplexExprEvaluator::VisitImaginaryLiteral(
const ImaginaryLiteral *E) {
19472 Result.makeComplexFloat();
19481 "Unexpected imaginary literal.");
19483 Result.makeComplexInt();
19488 Result.IntReal =
APSInt(Imag.getBitWidth(), !Imag.isSigned());
19493bool ComplexExprEvaluator::VisitCastExpr(
const CastExpr *E) {
19497 case CK_BaseToDerived:
19498 case CK_DerivedToBase:
19499 case CK_UncheckedDerivedToBase:
19502 case CK_ArrayToPointerDecay:
19503 case CK_FunctionToPointerDecay:
19504 case CK_NullToPointer:
19505 case CK_NullToMemberPointer:
19506 case CK_BaseToDerivedMemberPointer:
19507 case CK_DerivedToBaseMemberPointer:
19508 case CK_MemberPointerToBoolean:
19509 case CK_ReinterpretMemberPointer:
19510 case CK_ConstructorConversion:
19511 case CK_IntegralToPointer:
19512 case CK_PointerToIntegral:
19513 case CK_PointerToBoolean:
19515 case CK_VectorSplat:
19516 case CK_IntegralCast:
19517 case CK_BooleanToSignedIntegral:
19518 case CK_IntegralToBoolean:
19519 case CK_IntegralToFloating:
19520 case CK_FloatingToIntegral:
19521 case CK_FloatingToBoolean:
19522 case CK_FloatingCast:
19523 case CK_CPointerToObjCPointerCast:
19524 case CK_BlockPointerToObjCPointerCast:
19525 case CK_AnyPointerToBlockPointerCast:
19526 case CK_ObjCObjectLValueCast:
19527 case CK_FloatingComplexToReal:
19528 case CK_FloatingComplexToBoolean:
19529 case CK_IntegralComplexToReal:
19530 case CK_IntegralComplexToBoolean:
19531 case CK_ARCProduceObject:
19532 case CK_ARCConsumeObject:
19533 case CK_ARCReclaimReturnedObject:
19534 case CK_ARCExtendBlockObject:
19535 case CK_CopyAndAutoreleaseBlockObject:
19536 case CK_BuiltinFnToFnPtr:
19537 case CK_ZeroToOCLOpaqueType:
19538 case CK_NonAtomicToAtomic:
19539 case CK_AddressSpaceConversion:
19540 case CK_IntToOCLSampler:
19541 case CK_FloatingToFixedPoint:
19542 case CK_FixedPointToFloating:
19543 case CK_FixedPointCast:
19544 case CK_FixedPointToBoolean:
19545 case CK_FixedPointToIntegral:
19546 case CK_IntegralToFixedPoint:
19547 case CK_MatrixCast:
19548 case CK_HLSLVectorTruncation:
19549 case CK_HLSLMatrixTruncation:
19550 case CK_HLSLElementwiseCast:
19551 case CK_HLSLAggregateSplatCast:
19552 llvm_unreachable(
"invalid cast kind for complex value");
19554 case CK_LValueToRValue:
19555 case CK_AtomicToNonAtomic:
19557 case CK_LValueToRValueBitCast:
19558 case CK_HLSLArrayRValue:
19559 return ExprEvaluatorBaseTy::VisitCastExpr(E);
19562 case CK_LValueBitCast:
19563 case CK_UserDefinedConversion:
19566 case CK_FloatingRealToComplex: {
19571 Result.makeComplexFloat();
19576 case CK_FloatingComplexCast: {
19580 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
19588 case CK_FloatingComplexToIntegralComplex: {
19592 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
19595 Result.makeComplexInt();
19602 case CK_IntegralRealToComplex: {
19607 Result.makeComplexInt();
19608 Result.IntImag =
APSInt(Real.getBitWidth(), !Real.isSigned());
19612 case CK_IntegralComplexCast: {
19616 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
19625 case CK_IntegralComplexToFloatingComplex: {
19631 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
19634 Result.makeComplexFloat();
19636 To,
Result.FloatReal) &&
19642 llvm_unreachable(
"unknown cast resulting in complex value");
19647 const uint8_t GFInv[256] = {
19648 0x00, 0x01, 0x8d, 0xf6, 0xcb, 0x52, 0x7b, 0xd1, 0xe8, 0x4f, 0x29, 0xc0,
19649 0xb0, 0xe1, 0xe5, 0xc7, 0x74, 0xb4, 0xaa, 0x4b, 0x99, 0x2b, 0x60, 0x5f,
19650 0x58, 0x3f, 0xfd, 0xcc, 0xff, 0x40, 0xee, 0xb2, 0x3a, 0x6e, 0x5a, 0xf1,
19651 0x55, 0x4d, 0xa8, 0xc9, 0xc1, 0x0a, 0x98, 0x15, 0x30, 0x44, 0xa2, 0xc2,
19652 0x2c, 0x45, 0x92, 0x6c, 0xf3, 0x39, 0x66, 0x42, 0xf2, 0x35, 0x20, 0x6f,
19653 0x77, 0xbb, 0x59, 0x19, 0x1d, 0xfe, 0x37, 0x67, 0x2d, 0x31, 0xf5, 0x69,
19654 0xa7, 0x64, 0xab, 0x13, 0x54, 0x25, 0xe9, 0x09, 0xed, 0x5c, 0x05, 0xca,
19655 0x4c, 0x24, 0x87, 0xbf, 0x18, 0x3e, 0x22, 0xf0, 0x51, 0xec, 0x61, 0x17,
19656 0x16, 0x5e, 0xaf, 0xd3, 0x49, 0xa6, 0x36, 0x43, 0xf4, 0x47, 0x91, 0xdf,
19657 0x33, 0x93, 0x21, 0x3b, 0x79, 0xb7, 0x97, 0x85, 0x10, 0xb5, 0xba, 0x3c,
19658 0xb6, 0x70, 0xd0, 0x06, 0xa1, 0xfa, 0x81, 0x82, 0x83, 0x7e, 0x7f, 0x80,
19659 0x96, 0x73, 0xbe, 0x56, 0x9b, 0x9e, 0x95, 0xd9, 0xf7, 0x02, 0xb9, 0xa4,
19660 0xde, 0x6a, 0x32, 0x6d, 0xd8, 0x8a, 0x84, 0x72, 0x2a, 0x14, 0x9f, 0x88,
19661 0xf9, 0xdc, 0x89, 0x9a, 0xfb, 0x7c, 0x2e, 0xc3, 0x8f, 0xb8, 0x65, 0x48,
19662 0x26, 0xc8, 0x12, 0x4a, 0xce, 0xe7, 0xd2, 0x62, 0x0c, 0xe0, 0x1f, 0xef,
19663 0x11, 0x75, 0x78, 0x71, 0xa5, 0x8e, 0x76, 0x3d, 0xbd, 0xbc, 0x86, 0x57,
19664 0x0b, 0x28, 0x2f, 0xa3, 0xda, 0xd4, 0xe4, 0x0f, 0xa9, 0x27, 0x53, 0x04,
19665 0x1b, 0xfc, 0xac, 0xe6, 0x7a, 0x07, 0xae, 0x63, 0xc5, 0xdb, 0xe2, 0xea,
19666 0x94, 0x8b, 0xc4, 0xd5, 0x9d, 0xf8, 0x90, 0x6b, 0xb1, 0x0d, 0xd6, 0xeb,
19667 0xc6, 0x0e, 0xcf, 0xad, 0x08, 0x4e, 0xd7, 0xe3, 0x5d, 0x50, 0x1e, 0xb3,
19668 0x5b, 0x23, 0x38, 0x34, 0x68, 0x46, 0x03, 0x8c, 0xdd, 0x9c, 0x7d, 0xa0,
19669 0xcd, 0x1a, 0x41, 0x1c};
19671 return GFInv[Byte];
19676 unsigned NumBitsInByte = 8;
19678 uint8_t RetByte = 0;
19679 for (uint32_t BitIdx = 0; BitIdx != NumBitsInByte; ++BitIdx) {
19681 AQword.lshr((7 -
static_cast<int32_t
>(BitIdx)) * NumBitsInByte)
19688 Product = AByte & XByte;
19690 uint8_t Parity = 0;
19693 for (
unsigned PBitIdx = 0; PBitIdx != NumBitsInByte; ++PBitIdx) {
19694 Parity = Parity ^ ((Product >> PBitIdx) & 0x1);
19697 uint8_t Temp = Imm[BitIdx] ? 1 : 0;
19698 RetByte |= (Temp ^ Parity) << BitIdx;
19707 uint16_t TWord = 0;
19708 unsigned NumBitsInByte = 8;
19709 for (
unsigned BitIdx = 0; BitIdx != NumBitsInByte; ++BitIdx) {
19710 if ((BByte >> BitIdx) & 0x1) {
19711 TWord = TWord ^ (AByte << BitIdx);
19719 for (int32_t BitIdx = 14; BitIdx > 7; --BitIdx) {
19720 if ((TWord >> BitIdx) & 0x1) {
19721 TWord = TWord ^ (0x11B << (BitIdx - 8));
19724 return (TWord & 0xFF);
19728 APFloat &ResR, APFloat &ResI) {
19734 APFloat AC = A *
C;
19735 APFloat BD = B * D;
19736 APFloat AD = A * D;
19737 APFloat BC = B *
C;
19740 if (ResR.isNaN() && ResI.isNaN()) {
19741 bool Recalc =
false;
19742 if (A.isInfinity() || B.isInfinity()) {
19743 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
19745 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
19748 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
19750 D = APFloat::copySign(APFloat(D.getSemantics()), D);
19753 if (
C.isInfinity() || D.isInfinity()) {
19754 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
19756 D = APFloat::copySign(APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0),
19759 A = APFloat::copySign(APFloat(A.getSemantics()), A);
19761 B = APFloat::copySign(APFloat(B.getSemantics()), B);
19764 if (!Recalc && (AC.isInfinity() || BD.isInfinity() || AD.isInfinity() ||
19765 BC.isInfinity())) {
19767 A = APFloat::copySign(APFloat(A.getSemantics()), A);
19769 B = APFloat::copySign(APFloat(B.getSemantics()), B);
19771 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
19773 D = APFloat::copySign(APFloat(D.getSemantics()), D);
19777 ResR = APFloat::getInf(A.getSemantics()) * (A *
C - B * D);
19778 ResI = APFloat::getInf(A.getSemantics()) * (A * D + B *
C);
19784 APFloat &ResR, APFloat &ResI) {
19791 APFloat MaxCD = maxnum(
abs(
C),
abs(D));
19792 if (MaxCD.isFinite()) {
19793 DenomLogB =
ilogb(MaxCD);
19794 C =
scalbn(
C, -DenomLogB, APFloat::rmNearestTiesToEven);
19795 D =
scalbn(D, -DenomLogB, APFloat::rmNearestTiesToEven);
19797 APFloat Denom =
C *
C + D * D;
19799 scalbn((A *
C + B * D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
19801 scalbn((B *
C - A * D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
19802 if (ResR.isNaN() && ResI.isNaN()) {
19803 if (Denom.isPosZero() && (!A.isNaN() || !B.isNaN())) {
19804 ResR = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * A;
19805 ResI = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * B;
19806 }
else if ((A.isInfinity() || B.isInfinity()) &&
C.isFinite() &&
19808 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
19810 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
19812 ResR = APFloat::getInf(ResR.getSemantics()) * (A *
C + B * D);
19813 ResI = APFloat::getInf(ResI.getSemantics()) * (B *
C - A * D);
19814 }
else if (MaxCD.isInfinity() && A.isFinite() && B.isFinite()) {
19815 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
19817 D = APFloat::copySign(APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0),
19819 ResR = APFloat::getZero(ResR.getSemantics()) * (A *
C + B * D);
19820 ResI = APFloat::getZero(ResI.getSemantics()) * (B *
C - A * D);
19825bool ComplexExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
19827 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
19831 bool LHSReal =
false, RHSReal =
false;
19839 Result.makeComplexFloat();
19843 LHSOK = Visit(E->
getLHS());
19845 if (!LHSOK && !Info.noteFailure())
19851 APFloat &Real = RHS.FloatReal;
19854 RHS.makeComplexFloat();
19855 RHS.FloatImag =
APFloat(Real.getSemantics());
19859 assert(!(LHSReal && RHSReal) &&
19860 "Cannot have both operands of a complex operation be real.");
19862 default:
return Error(E);
19864 if (
Result.isComplexFloat()) {
19865 Result.getComplexFloatReal().add(RHS.getComplexFloatReal(),
19866 APFloat::rmNearestTiesToEven);
19868 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
19870 Result.getComplexFloatImag().add(RHS.getComplexFloatImag(),
19871 APFloat::rmNearestTiesToEven);
19873 Result.getComplexIntReal() += RHS.getComplexIntReal();
19874 Result.getComplexIntImag() += RHS.getComplexIntImag();
19878 if (
Result.isComplexFloat()) {
19879 Result.getComplexFloatReal().subtract(RHS.getComplexFloatReal(),
19880 APFloat::rmNearestTiesToEven);
19882 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
19883 Result.getComplexFloatImag().changeSign();
19884 }
else if (!RHSReal) {
19885 Result.getComplexFloatImag().subtract(RHS.getComplexFloatImag(),
19886 APFloat::rmNearestTiesToEven);
19889 Result.getComplexIntReal() -= RHS.getComplexIntReal();
19890 Result.getComplexIntImag() -= RHS.getComplexIntImag();
19894 if (
Result.isComplexFloat()) {
19899 ComplexValue LHS =
Result;
19900 APFloat &A = LHS.getComplexFloatReal();
19901 APFloat &B = LHS.getComplexFloatImag();
19902 APFloat &
C = RHS.getComplexFloatReal();
19903 APFloat &D = RHS.getComplexFloatImag();
19907 assert(!RHSReal &&
"Cannot have two real operands for a complex op!");
19915 }
else if (RHSReal) {
19927 ComplexValue LHS =
Result;
19928 Result.getComplexIntReal() =
19929 (LHS.getComplexIntReal() * RHS.getComplexIntReal() -
19930 LHS.getComplexIntImag() * RHS.getComplexIntImag());
19931 Result.getComplexIntImag() =
19932 (LHS.getComplexIntReal() * RHS.getComplexIntImag() +
19933 LHS.getComplexIntImag() * RHS.getComplexIntReal());
19937 if (
Result.isComplexFloat()) {
19942 ComplexValue LHS =
Result;
19943 APFloat &A = LHS.getComplexFloatReal();
19944 APFloat &B = LHS.getComplexFloatImag();
19945 APFloat &
C = RHS.getComplexFloatReal();
19946 APFloat &D = RHS.getComplexFloatImag();
19960 B = APFloat::getZero(A.getSemantics());
19965 ComplexValue LHS =
Result;
19966 APSInt Den = RHS.getComplexIntReal() * RHS.getComplexIntReal() +
19967 RHS.getComplexIntImag() * RHS.getComplexIntImag();
19969 return Error(E, diag::note_expr_divide_by_zero);
19971 Result.getComplexIntReal() =
19972 (LHS.getComplexIntReal() * RHS.getComplexIntReal() +
19973 LHS.getComplexIntImag() * RHS.getComplexIntImag()) / Den;
19974 Result.getComplexIntImag() =
19975 (LHS.getComplexIntImag() * RHS.getComplexIntReal() -
19976 LHS.getComplexIntReal() * RHS.getComplexIntImag()) / Den;
19984bool ComplexExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
19998 if (
Result.isComplexFloat()) {
19999 Result.getComplexFloatReal().changeSign();
20000 Result.getComplexFloatImag().changeSign();
20003 Result.getComplexIntReal() = -
Result.getComplexIntReal();
20004 Result.getComplexIntImag() = -
Result.getComplexIntImag();
20008 if (
Result.isComplexFloat())
20009 Result.getComplexFloatImag().changeSign();
20011 Result.getComplexIntImag() = -
Result.getComplexIntImag();
20016bool ComplexExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
20019 Result.makeComplexFloat();
20025 Result.makeComplexInt();
20033 return ExprEvaluatorBaseTy::VisitInitListExpr(E);
20036bool ComplexExprEvaluator::VisitCallExpr(
const CallExpr *E) {
20037 if (!IsConstantEvaluatedBuiltinCall(E))
20038 return ExprEvaluatorBaseTy::VisitCallExpr(E);
20041 case Builtin::BI__builtin_complex:
20042 Result.makeComplexFloat();
20060class AtomicExprEvaluator :
20061 public ExprEvaluatorBase<AtomicExprEvaluator> {
20062 const LValue *
This;
20065 AtomicExprEvaluator(EvalInfo &Info,
const LValue *This,
APValue &
Result)
20073 bool ZeroInitialization(
const Expr *E) {
20074 ImplicitValueInitExpr VIE(
20082 bool VisitCastExpr(
const CastExpr *E) {
20085 return ExprEvaluatorBaseTy::VisitCastExpr(E);
20086 case CK_NullToPointer:
20088 return ZeroInitialization(E);
20089 case CK_NonAtomicToAtomic:
20101 return AtomicExprEvaluator(Info,
This, Result).Visit(E);
20110class VoidExprEvaluator
20111 :
public ExprEvaluatorBase<VoidExprEvaluator> {
20113 VoidExprEvaluator(EvalInfo &Info) : ExprEvaluatorBaseTy(Info) {}
20117 bool ZeroInitialization(
const Expr *E) {
return true; }
20119 bool VisitCastExpr(
const CastExpr *E) {
20122 return ExprEvaluatorBaseTy::VisitCastExpr(E);
20129 bool VisitCallExpr(
const CallExpr *E) {
20130 if (!IsConstantEvaluatedBuiltinCall(E))
20131 return ExprEvaluatorBaseTy::VisitCallExpr(E);
20134 case Builtin::BI__assume:
20135 case Builtin::BI__builtin_assume:
20139 case Builtin::BI__builtin_operator_delete:
20147 bool VisitCXXDeleteExpr(
const CXXDeleteExpr *E);
20151bool VoidExprEvaluator::VisitCXXDeleteExpr(
const CXXDeleteExpr *E) {
20153 if (Info.SpeculativeEvaluationDepth)
20157 if (!OperatorDelete
20158 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
20159 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
20169 if (
Pointer.Designator.Invalid)
20173 if (
Pointer.isNullPointer()) {
20177 if (!Info.getLangOpts().CPlusPlus20)
20178 Info.CCEDiag(E, diag::note_constexpr_new);
20186 QualType AllocType =
Pointer.Base.getDynamicAllocType();
20192 Info.FFDiag(E, diag::note_constexpr_delete_base_nonvirt_dtor)
20201 if (VirtualDelete &&
20203 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
20204 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
20211 (*Alloc)->Value, AllocType))
20214 if (!Info.HeapAllocs.erase(
Pointer.Base.dyn_cast<DynamicAllocLValue>())) {
20219 Info.FFDiag(E, diag::note_constexpr_double_delete);
20229 return VoidExprEvaluator(Info).Visit(E);
20241 if (E->
isGLValue() ||
T->isFunctionType()) {
20245 LV.moveInto(Result);
20246 }
else if (
T->isVectorType()) {
20249 }
else if (
T->isIntegralOrEnumerationType()) {
20250 if (!IntExprEvaluator(Info, Result).Visit(E))
20252 }
else if (
T->hasPointerRepresentation()) {
20256 LV.moveInto(Result);
20257 }
else if (
T->isRealFloatingType()) {
20258 llvm::APFloat F(0.0);
20262 }
else if (
T->isAnyComplexType()) {
20266 C.moveInto(Result);
20267 }
else if (
T->isFixedPointType()) {
20268 if (!FixedPointExprEvaluator(Info, Result).Visit(E))
return false;
20269 }
else if (
T->isMemberPointerType()) {
20273 P.moveInto(Result);
20275 }
else if (
T->isArrayType()) {
20278 Info.CurrentCall->createTemporary(E,
T, ScopeKind::FullExpression, LV);
20282 }
else if (
T->isRecordType()) {
20285 Info.CurrentCall->createTemporary(E,
T, ScopeKind::FullExpression, LV);
20289 }
else if (
T->isVoidType()) {
20290 if (!Info.getLangOpts().CPlusPlus11)
20291 Info.CCEDiag(E, diag::note_constexpr_nonliteral)
20295 }
else if (
T->isAtomicType()) {
20296 QualType Unqual =
T.getAtomicUnqualifiedType();
20300 E, Unqual, ScopeKind::FullExpression, LV);
20308 }
else if (Info.getLangOpts().CPlusPlus11) {
20309 Info.FFDiag(E, diag::note_constexpr_nonliteral) << E->
getType();
20312 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
20323 const Expr *E,
bool AllowNonLiteralTypes) {
20339 if (
T->isArrayType())
20341 else if (
T->isRecordType())
20343 else if (
T->isAtomicType()) {
20344 QualType Unqual =
T.getAtomicUnqualifiedType();
20365 if (Info.EnableNewConstInterp) {
20369 ConstantExprKind::Normal);
20378 LV.setFrom(Info.Ctx, Result);
20385 ConstantExprKind::Normal) &&
20393 if (
const auto *L = dyn_cast<IntegerLiteral>(Exp)) {
20395 APValue(
APSInt(L->getValue(), L->getType()->isUnsignedIntegerType()));
20400 if (
const auto *L = dyn_cast<CXXBoolLiteralExpr>(Exp)) {
20406 if (
const auto *FL = dyn_cast<FloatingLiteral>(Exp)) {
20407 Result =
APValue(FL->getValue());
20412 if (
const auto *L = dyn_cast<CharacterLiteral>(Exp)) {
20418 if (
const auto *CE = dyn_cast<ConstantExpr>(Exp)) {
20419 if (CE->hasAPValueResult()) {
20420 APValue APV = CE->getAPValueResult();
20422 Result = std::move(APV);
20498 bool InConstantContext)
const {
20500 "Expression evaluator can't be called on a dependent expression.");
20501 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsRValue");
20503 Info.InConstantContext = InConstantContext;
20504 return ::EvaluateAsRValue(
this,
Result, Ctx, Info);
20508 bool InConstantContext)
const {
20510 "Expression evaluator can't be called on a dependent expression.");
20511 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsBooleanCondition");
20519 bool InConstantContext)
const {
20521 "Expression evaluator can't be called on a dependent expression.");
20522 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsInt");
20524 Info.InConstantContext = InConstantContext;
20525 return ::EvaluateAsInt(
this,
Result, Ctx, AllowSideEffects, Info);
20530 bool InConstantContext)
const {
20532 "Expression evaluator can't be called on a dependent expression.");
20533 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFixedPoint");
20535 Info.InConstantContext = InConstantContext;
20536 return ::EvaluateAsFixedPoint(
this,
Result, Ctx, AllowSideEffects, Info);
20541 bool InConstantContext)
const {
20543 "Expression evaluator can't be called on a dependent expression.");
20545 if (!
getType()->isRealFloatingType())
20548 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFloat");
20560 bool InConstantContext)
const {
20562 "Expression evaluator can't be called on a dependent expression.");
20564 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsLValue");
20566 Info.InConstantContext = InConstantContext;
20570 if (Info.EnableNewConstInterp) {
20572 ConstantExprKind::Normal))
20575 LV.setFrom(Ctx,
Result.Val);
20578 ConstantExprKind::Normal, CheckedTemps);
20581 if (!
EvaluateLValue(
this, LV, Info) || !Info.discardCleanups() ||
20582 Result.HasSideEffects ||
20585 ConstantExprKind::Normal, CheckedTemps))
20588 LV.moveInto(
Result.Val);
20595 bool IsConstantDestruction) {
20596 EvalInfo Info(Ctx, EStatus,
20599 Info.setEvaluatingDecl(
Base, DestroyedValue,
20600 EvalInfo::EvaluatingDeclKind::Dtor);
20601 Info.InConstantContext = IsConstantDestruction;
20610 if (!Info.discardCleanups())
20611 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
20619 "Expression evaluator can't be called on a dependent expression.");
20625 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsConstantExpr");
20627 EvalInfo Info(Ctx,
Result, EM);
20628 Info.InConstantContext =
true;
20630 if (Info.EnableNewConstInterp) {
20634 getStorageType(Ctx,
this),
Result.Val, Kind);
20639 if (Kind == ConstantExprKind::ClassTemplateArgument)
20655 FullExpressionRAII
Scope(Info);
20660 if (!Info.discardCleanups())
20661 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
20671 if (Kind == ConstantExprKind::ClassTemplateArgument &&
20674 Result.HasSideEffects)) {
20686 bool IsConstantInitialization)
const {
20688 "Expression evaluator can't be called on a dependent expression.");
20689 assert(VD &&
"Need a valid VarDecl");
20691 llvm::TimeTraceScope TimeScope(
"EvaluateAsInitializer", [&] {
20693 llvm::raw_string_ostream OS(Name);
20699 EStatus.
Diag = &Notes;
20701 EvalInfo Info(Ctx, EStatus,
20702 (IsConstantInitialization &&
20706 Info.setEvaluatingDecl(VD,
Value);
20707 Info.InConstantContext = IsConstantInitialization;
20712 if (Info.EnableNewConstInterp) {
20713 auto &InterpCtx =
const_cast<ASTContext &
>(Ctx).getInterpContext();
20714 if (!InterpCtx.evaluateAsInitializer(Info, VD,
this,
Value))
20718 ConstantExprKind::Normal);
20733 FullExpressionRAII
Scope(Info);
20736 EStatus.HasSideEffects)
20742 Info.performLifetimeExtension();
20744 if (!Info.discardCleanups())
20745 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
20749 ConstantExprKind::Normal) &&
20756 EStatus.
Diag = &Notes;
20773 IsConstantDestruction) ||
20785 "Expression evaluator can't be called on a dependent expression.");
20794 "Expression evaluator can't be called on a dependent expression.");
20796 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstInt");
20799 Info.InConstantContext =
true;
20803 assert(
Result &&
"Could not evaluate expression");
20804 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
20806 return EVResult.Val.getInt();
20812 "Expression evaluator can't be called on a dependent expression.");
20814 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstIntCheckOverflow");
20816 EVResult.Diag =
Diag;
20818 Info.InConstantContext =
true;
20819 Info.CheckingForUndefinedBehavior =
true;
20823 assert(
Result &&
"Could not evaluate expression");
20824 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
20826 return EVResult.Val.getInt();
20831 "Expression evaluator can't be called on a dependent expression.");
20833 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateForOverflow");
20838 Info.CheckingForUndefinedBehavior =
true;
20844 assert(
Val.isLValue());
20870 IK_ICEIfUnevaluated,
20886static ICEDiag
Worst(ICEDiag A, ICEDiag B) {
return A.Kind >= B.Kind ? A : B; }
20893 Info.InConstantContext =
true;
20902 assert(!E->
isValueDependent() &&
"Should not see value dependent exprs!");
20907#define ABSTRACT_STMT(Node)
20908#define STMT(Node, Base) case Expr::Node##Class:
20909#define EXPR(Node, Base)
20910#include "clang/AST/StmtNodes.inc"
20911 case Expr::PredefinedExprClass:
20912 case Expr::FloatingLiteralClass:
20913 case Expr::ImaginaryLiteralClass:
20914 case Expr::StringLiteralClass:
20915 case Expr::ArraySubscriptExprClass:
20916 case Expr::MatrixSingleSubscriptExprClass:
20917 case Expr::MatrixSubscriptExprClass:
20918 case Expr::ArraySectionExprClass:
20919 case Expr::OMPArrayShapingExprClass:
20920 case Expr::OMPIteratorExprClass:
20921 case Expr::MemberExprClass:
20922 case Expr::CompoundAssignOperatorClass:
20923 case Expr::CompoundLiteralExprClass:
20924 case Expr::ExtVectorElementExprClass:
20925 case Expr::DesignatedInitExprClass:
20926 case Expr::ArrayInitLoopExprClass:
20927 case Expr::ArrayInitIndexExprClass:
20928 case Expr::NoInitExprClass:
20929 case Expr::DesignatedInitUpdateExprClass:
20930 case Expr::ImplicitValueInitExprClass:
20931 case Expr::ParenListExprClass:
20932 case Expr::VAArgExprClass:
20933 case Expr::AddrLabelExprClass:
20934 case Expr::StmtExprClass:
20935 case Expr::CXXMemberCallExprClass:
20936 case Expr::CUDAKernelCallExprClass:
20937 case Expr::CXXAddrspaceCastExprClass:
20938 case Expr::CXXDynamicCastExprClass:
20939 case Expr::CXXTypeidExprClass:
20940 case Expr::CXXUuidofExprClass:
20941 case Expr::MSPropertyRefExprClass:
20942 case Expr::MSPropertySubscriptExprClass:
20943 case Expr::CXXNullPtrLiteralExprClass:
20944 case Expr::UserDefinedLiteralClass:
20945 case Expr::CXXThisExprClass:
20946 case Expr::CXXThrowExprClass:
20947 case Expr::CXXNewExprClass:
20948 case Expr::CXXDeleteExprClass:
20949 case Expr::CXXPseudoDestructorExprClass:
20950 case Expr::UnresolvedLookupExprClass:
20951 case Expr::RecoveryExprClass:
20952 case Expr::DependentScopeDeclRefExprClass:
20953 case Expr::CXXConstructExprClass:
20954 case Expr::CXXInheritedCtorInitExprClass:
20955 case Expr::CXXStdInitializerListExprClass:
20956 case Expr::CXXBindTemporaryExprClass:
20957 case Expr::ExprWithCleanupsClass:
20958 case Expr::CXXTemporaryObjectExprClass:
20959 case Expr::CXXUnresolvedConstructExprClass:
20960 case Expr::CXXDependentScopeMemberExprClass:
20961 case Expr::UnresolvedMemberExprClass:
20962 case Expr::ObjCStringLiteralClass:
20963 case Expr::ObjCBoxedExprClass:
20964 case Expr::ObjCArrayLiteralClass:
20965 case Expr::ObjCDictionaryLiteralClass:
20966 case Expr::ObjCEncodeExprClass:
20967 case Expr::ObjCMessageExprClass:
20968 case Expr::ObjCSelectorExprClass:
20969 case Expr::ObjCProtocolExprClass:
20970 case Expr::ObjCIvarRefExprClass:
20971 case Expr::ObjCPropertyRefExprClass:
20972 case Expr::ObjCSubscriptRefExprClass:
20973 case Expr::ObjCIsaExprClass:
20974 case Expr::ObjCAvailabilityCheckExprClass:
20975 case Expr::ShuffleVectorExprClass:
20976 case Expr::ConvertVectorExprClass:
20977 case Expr::BlockExprClass:
20979 case Expr::OpaqueValueExprClass:
20980 case Expr::PackExpansionExprClass:
20981 case Expr::SubstNonTypeTemplateParmPackExprClass:
20982 case Expr::FunctionParmPackExprClass:
20983 case Expr::AsTypeExprClass:
20984 case Expr::ObjCIndirectCopyRestoreExprClass:
20985 case Expr::MaterializeTemporaryExprClass:
20986 case Expr::PseudoObjectExprClass:
20987 case Expr::AtomicExprClass:
20988 case Expr::LambdaExprClass:
20989 case Expr::CXXFoldExprClass:
20990 case Expr::CoawaitExprClass:
20991 case Expr::DependentCoawaitExprClass:
20992 case Expr::CoyieldExprClass:
20993 case Expr::SYCLUniqueStableNameExprClass:
20994 case Expr::CXXParenListInitExprClass:
20995 case Expr::HLSLOutArgExprClass:
20998 case Expr::InitListExprClass: {
21009 case Expr::SizeOfPackExprClass:
21010 case Expr::GNUNullExprClass:
21011 case Expr::SourceLocExprClass:
21012 case Expr::EmbedExprClass:
21013 case Expr::OpenACCAsteriskSizeExprClass:
21016 case Expr::PackIndexingExprClass:
21019 case Expr::SubstNonTypeTemplateParmExprClass:
21023 case Expr::ConstantExprClass:
21026 case Expr::ParenExprClass:
21028 case Expr::GenericSelectionExprClass:
21030 case Expr::IntegerLiteralClass:
21031 case Expr::FixedPointLiteralClass:
21032 case Expr::CharacterLiteralClass:
21033 case Expr::ObjCBoolLiteralExprClass:
21034 case Expr::CXXBoolLiteralExprClass:
21035 case Expr::CXXScalarValueInitExprClass:
21036 case Expr::TypeTraitExprClass:
21037 case Expr::ConceptSpecializationExprClass:
21038 case Expr::RequiresExprClass:
21039 case Expr::ArrayTypeTraitExprClass:
21040 case Expr::ExpressionTraitExprClass:
21041 case Expr::CXXNoexceptExprClass:
21043 case Expr::CallExprClass:
21044 case Expr::CXXOperatorCallExprClass: {
21053 case Expr::CXXRewrittenBinaryOperatorClass:
21056 case Expr::DeclRefExprClass: {
21070 const VarDecl *VD = dyn_cast<VarDecl>(D);
21077 case Expr::UnaryOperatorClass: {
21100 llvm_unreachable(
"invalid unary operator class");
21102 case Expr::OffsetOfExprClass: {
21111 case Expr::UnaryExprOrTypeTraitExprClass: {
21113 if ((Exp->
getKind() == UETT_SizeOf) &&
21116 if (Exp->
getKind() == UETT_CountOf) {
21123 if (VAT->getElementType()->isArrayType())
21135 case Expr::BinaryOperatorClass: {
21180 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE) {
21183 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
21184 if (REval.isSigned() && REval.isAllOnes()) {
21186 if (LEval.isMinSignedValue())
21187 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
21195 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE)
21196 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
21202 return Worst(LHSResult, RHSResult);
21208 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICEIfUnevaluated) {
21218 return Worst(LHSResult, RHSResult);
21221 llvm_unreachable(
"invalid binary operator kind");
21223 case Expr::ImplicitCastExprClass:
21224 case Expr::CStyleCastExprClass:
21225 case Expr::CXXFunctionalCastExprClass:
21226 case Expr::CXXStaticCastExprClass:
21227 case Expr::CXXReinterpretCastExprClass:
21228 case Expr::CXXConstCastExprClass:
21229 case Expr::ObjCBridgedCastExprClass: {
21236 APSInt IgnoredVal(DestWidth, !DestSigned);
21241 if (FL->getValue().convertToInteger(IgnoredVal,
21242 llvm::APFloat::rmTowardZero,
21243 &Ignored) & APFloat::opInvalidOp)
21249 case CK_LValueToRValue:
21250 case CK_AtomicToNonAtomic:
21251 case CK_NonAtomicToAtomic:
21253 case CK_IntegralToBoolean:
21254 case CK_IntegralCast:
21260 case Expr::BinaryConditionalOperatorClass: {
21263 if (CommonResult.Kind == IK_NotICE)
return CommonResult;
21265 if (FalseResult.Kind == IK_NotICE)
return FalseResult;
21266 if (CommonResult.Kind == IK_ICEIfUnevaluated)
return CommonResult;
21267 if (FalseResult.Kind == IK_ICEIfUnevaluated &&
21269 return FalseResult;
21271 case Expr::ConditionalOperatorClass: {
21279 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
21282 if (CondResult.Kind == IK_NotICE)
21288 if (TrueResult.Kind == IK_NotICE)
21290 if (FalseResult.Kind == IK_NotICE)
21291 return FalseResult;
21292 if (CondResult.Kind == IK_ICEIfUnevaluated)
21294 if (TrueResult.Kind == IK_ICE && FalseResult.Kind == IK_ICE)
21300 return FalseResult;
21303 case Expr::CXXDefaultArgExprClass:
21305 case Expr::CXXDefaultInitExprClass:
21307 case Expr::ChooseExprClass: {
21310 case Expr::BuiltinBitCastExprClass: {
21311 if (!checkBitCastConstexprEligibility(
nullptr, Ctx,
cast<CastExpr>(E)))
21317 llvm_unreachable(
"Invalid StmtClass!");
21323 llvm::APSInt *
Value) {
21331 if (!Result.isInt())
21340 "Expression evaluator can't be called on a dependent expression.");
21342 ExprTimeTraceScope TimeScope(
this, Ctx,
"isIntegerConstantExpr");
21348 if (D.Kind != IK_ICE)
21353std::optional<llvm::APSInt>
21357 return std::nullopt;
21364 return std::nullopt;
21368 return std::nullopt;
21377 Info.InConstantContext =
true;
21380 llvm_unreachable(
"ICE cannot be evaluated!");
21387 "Expression evaluator can't be called on a dependent expression.");
21389 return CheckICE(
this, Ctx).Kind == IK_ICE;
21394 "Expression evaluator can't be called on a dependent expression.");
21411 Status.Diag = &Diags;
21418 Info.discardCleanups() && !Status.HasSideEffects;
21420 return IsConstExpr && Diags.empty();
21428 "Expression evaluator can't be called on a dependent expression.");
21430 llvm::TimeTraceScope TimeScope(
"EvaluateWithSubstitution", [&] {
21432 llvm::raw_string_ostream OS(Name);
21440 Info.InConstantContext =
true;
21443 const LValue *ThisPtr =
nullptr;
21446 auto *MD = dyn_cast<CXXMethodDecl>(Callee);
21447 assert(MD &&
"Don't provide `this` for non-methods.");
21448 assert(MD->isImplicitObjectMemberFunction() &&
21449 "Don't provide `this` for methods without an implicit object.");
21451 if (!
This->isValueDependent() &&
21454 ThisPtr = &ThisVal;
21461 CallRef
Call = Info.CurrentCall->createCall(Callee);
21464 unsigned Idx = I - Args.begin();
21465 if (Idx >= Callee->getNumParams())
21467 const ParmVarDecl *PVD = Callee->getParamDecl(Idx);
21468 if ((*I)->isValueDependent() ||
21472 if (
APValue *Slot = Info.getParamSlot(
Call, PVD))
21483 Info.discardCleanups();
21487 CallStackFrame Frame(Info, Callee->getLocation(), Callee, ThisPtr,
This,
21490 FullExpressionRAII
Scope(Info);
21504 llvm::TimeTraceScope TimeScope(
"isPotentialConstantExpr", [&] {
21506 llvm::raw_string_ostream OS(Name);
21513 Status.
Diag = &Diags;
21517 Info.InConstantContext =
true;
21518 Info.CheckingPotentialConstantExpression =
true;
21521 if (Info.EnableNewConstInterp) {
21523 return Diags.empty();
21534 This.set({&VIE, Info.CurrentCall->Index});
21542 Info.setEvaluatingDecl(
This.getLValueBase(), Scratch);
21548 &VIE, Args, CallRef(), FD->
getBody(), Info, Scratch,
21552 return Diags.empty();
21560 "Expression evaluator can't be called on a dependent expression.");
21563 Status.
Diag = &Diags;
21567 Info.InConstantContext =
true;
21568 Info.CheckingPotentialConstantExpression =
true;
21570 if (Info.EnableNewConstInterp) {
21572 return Diags.empty();
21577 nullptr, CallRef());
21581 return Diags.empty();
21585 unsigned Type)
const {
21586 if (!
getType()->isPointerType())
21595 EvalInfo &Info, std::string *StringResult) {
21607 if (
const StringLiteral *S = dyn_cast_or_null<StringLiteral>(
21608 String.getLValueBase().dyn_cast<
const Expr *>())) {
21611 if (Off >= 0 && (uint64_t)Off <= (uint64_t)Str.size() &&
21615 Str = Str.substr(Off);
21617 StringRef::size_type Pos = Str.find(0);
21618 if (Pos != StringRef::npos)
21619 Str = Str.substr(0, Pos);
21621 Result = Str.size();
21623 *StringResult = Str;
21631 for (uint64_t Strlen = 0; ; ++Strlen) {
21639 }
else if (StringResult)
21640 StringResult->push_back(Char.
getInt().getExtValue());
21650 std::string StringResult;
21652 if (Info.EnableNewConstInterp) {
21654 return std::nullopt;
21655 return StringResult;
21659 return StringResult;
21660 return std::nullopt;
21663template <
typename T>
21665 const Expr *SizeExpression,
21666 const Expr *PtrExpression,
21670 Info.InConstantContext =
true;
21672 if (Info.EnableNewConstInterp)
21674 PtrExpression, Result);
21677 FullExpressionRAII
Scope(Info);
21682 uint64_t Size = SizeValue.getZExtValue();
21685 if constexpr (std::is_same_v<APValue, T>)
21688 if (Size < Result.max_size())
21689 Result.reserve(Size);
21695 for (uint64_t I = 0; I < Size; ++I) {
21701 if constexpr (std::is_same_v<APValue, T>) {
21702 Result.getArrayInitializedElt(I) = std::move(Char);
21706 assert(
C.getBitWidth() <= 8 &&
21707 "string element not representable in char");
21709 Result.push_back(
static_cast<char>(
C.getExtValue()));
21720 const Expr *SizeExpression,
21724 PtrExpression, Ctx, Status);
21728 const Expr *SizeExpression,
21732 PtrExpression, Ctx, Status);
21739 if (Info.EnableNewConstInterp)
21746struct IsWithinLifetimeHandler {
21749 using result_type = std::optional<bool>;
21750 std::optional<bool> failed() {
return std::nullopt; }
21751 template <
typename T>
21752 std::optional<bool> found(
T &Subobj,
QualType SubobjType) {
21757std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &IEE,
21758 const CallExpr *E) {
21759 EvalInfo &Info = IEE.Info;
21764 if (!Info.InConstantContext)
21765 return std::nullopt;
21767 const Expr *Arg = E->
getArg(0);
21769 return std::nullopt;
21772 return std::nullopt;
21774 if (Val.allowConstexprUnknown())
21778 bool CalledFromStd =
false;
21779 const auto *
Callee = Info.CurrentCall->getCallee();
21780 if (Callee &&
Callee->isInStdNamespace()) {
21781 const IdentifierInfo *Identifier =
Callee->getIdentifier();
21782 CalledFromStd = Identifier && Identifier->
isStr(
"is_within_lifetime");
21784 Info.CCEDiag(CalledFromStd ? Info.CurrentCall->getCallRange().getBegin()
21786 diag::err_invalid_is_within_lifetime)
21787 << (CalledFromStd ?
"std::is_within_lifetime"
21788 :
"__builtin_is_within_lifetime")
21790 return std::nullopt;
21800 if (Val.isNullPointer() || Val.getLValueBase().isNull())
21802 QualType
T = Val.getLValueBase().getType();
21804 "Pointers to functions should have been typed as function pointers "
21805 "which would have been rejected earlier");
21808 if (Val.getLValueDesignator().isOnePastTheEnd())
21810 assert(Val.getLValueDesignator().isValidSubobject() &&
21811 "Unchecked case for valid subobject");
21815 CompleteObject CO =
21819 if (Info.EvaluatingDeclValue && CO.Value == Info.EvaluatingDeclValue)
21824 IsWithinLifetimeHandler handler{Info};
21825 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)
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...
ArrayRef< ParmVarDecl * >::const_iterator param_const_iterator
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)