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) {}
284 explicit SubobjectDesignator(
QualType T)
285 :
Invalid(
false), IsOnePastTheEnd(
false),
286 FirstEntryIsAnUnsizedArray(
false), MostDerivedIsArrayElement(
false),
287 MostDerivedPathLength(0), MostDerivedArraySize(0),
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 {
800 CallStackFrame *CurrentCall;
803 unsigned CallStackDepth;
806 unsigned NextCallIndex;
815 bool EnableNewConstInterp;
819 CallStackFrame BottomFrame;
823 llvm::SmallVector<Cleanup, 16> CleanupStack;
827 APValue::LValueBase EvaluatingDecl;
829 enum class EvaluatingDeclKind {
836 EvaluatingDeclKind IsEvaluatingDecl = EvaluatingDeclKind::None;
845 SmallVector<const Stmt *> BreakContinueStack;
848 llvm::DenseMap<ObjectUnderConstruction, ConstructionPhase>
849 ObjectsUnderConstruction;
854 std::map<DynamicAllocLValue, DynAlloc, DynAllocOrder> HeapAllocs;
857 unsigned NumHeapAllocs = 0;
859 struct EvaluatingConstructorRAII {
861 ObjectUnderConstruction Object;
863 EvaluatingConstructorRAII(EvalInfo &EI, ObjectUnderConstruction Object,
865 : EI(EI), Object(Object) {
867 EI.ObjectsUnderConstruction
868 .insert({Object, HasBases ? ConstructionPhase::Bases
869 : ConstructionPhase::AfterBases})
872 void finishedConstructingBases() {
873 EI.ObjectsUnderConstruction[Object] = ConstructionPhase::AfterBases;
875 void finishedConstructingFields() {
876 EI.ObjectsUnderConstruction[Object] = ConstructionPhase::AfterFields;
878 ~EvaluatingConstructorRAII() {
879 if (DidInsert) EI.ObjectsUnderConstruction.erase(Object);
883 struct EvaluatingDestructorRAII {
885 ObjectUnderConstruction Object;
887 EvaluatingDestructorRAII(EvalInfo &EI, ObjectUnderConstruction Object)
888 : EI(EI), Object(Object) {
889 DidInsert = EI.ObjectsUnderConstruction
890 .insert({Object, ConstructionPhase::Destroying})
893 void startedDestroyingBases() {
894 EI.ObjectsUnderConstruction[Object] =
895 ConstructionPhase::DestroyingBases;
897 ~EvaluatingDestructorRAII() {
899 EI.ObjectsUnderConstruction.erase(Object);
904 isEvaluatingCtorDtor(APValue::LValueBase Base,
905 ArrayRef<APValue::LValuePathEntry> Path) {
906 return ObjectsUnderConstruction.lookup({
Base, Path});
911 unsigned SpeculativeEvaluationDepth = 0;
917 EvalInfo(
const ASTContext &
C, Expr::EvalStatus &S,
EvaluationMode Mode)
918 : State(const_cast<ASTContext &>(
C), S), CurrentCall(
nullptr),
919 CallStackDepth(0), NextCallIndex(1),
920 StepsLeft(
C.getLangOpts().ConstexprStepLimit),
921 EnableNewConstInterp(
C.getLangOpts().EnableNewConstInterp),
922 BottomFrame(*this, SourceLocation(),
nullptr,
925 EvaluatingDecl((const ValueDecl *)
nullptr),
934 void setEvaluatingDecl(APValue::LValueBase Base,
APValue &
Value,
935 EvaluatingDeclKind EDK = EvaluatingDeclKind::Ctor) {
936 EvaluatingDecl =
Base;
937 IsEvaluatingDecl = EDK;
938 EvaluatingDeclValue = &
Value;
941 bool CheckCallLimit(SourceLocation Loc) {
944 if (checkingPotentialConstantExpression() && CallStackDepth > 1)
946 if (NextCallIndex == 0) {
948 FFDiag(Loc, diag::note_constexpr_call_limit_exceeded);
951 if (CallStackDepth <= getLangOpts().ConstexprCallDepth)
953 FFDiag(Loc, diag::note_constexpr_depth_limit_exceeded)
954 << getLangOpts().ConstexprCallDepth;
959 uint64_t ElemCount,
bool Diag) {
965 ElemCount >
uint64_t(std::numeric_limits<unsigned>::max())) {
967 FFDiag(Loc, diag::note_constexpr_new_too_large) << ElemCount;
976 uint64_t Limit = getLangOpts().ConstexprStepLimit;
977 if (Limit != 0 && ElemCount > Limit) {
979 FFDiag(Loc, diag::note_constexpr_new_exceeds_limits)
980 << ElemCount << Limit;
986 std::pair<CallStackFrame *, unsigned>
987 getCallFrameAndDepth(
unsigned CallIndex) {
988 assert(CallIndex &&
"no call index in getCallFrameAndDepth");
991 unsigned Depth = CallStackDepth;
992 CallStackFrame *Frame = CurrentCall;
993 while (Frame->Index > CallIndex) {
994 Frame = Frame->Caller;
997 if (Frame->Index == CallIndex)
998 return {Frame, Depth};
1002 bool nextStep(
const Stmt *S) {
1003 if (getLangOpts().ConstexprStepLimit == 0)
1007 FFDiag(S->
getBeginLoc(), diag::note_constexpr_step_limit_exceeded);
1014 APValue *createHeapAlloc(
const Expr *E, QualType T, LValue &LV);
1016 std::optional<DynAlloc *> lookupDynamicAlloc(DynamicAllocLValue DA) {
1017 std::optional<DynAlloc *>
Result;
1018 auto It = HeapAllocs.find(DA);
1019 if (It != HeapAllocs.end())
1025 APValue *getParamSlot(CallRef
Call,
const ParmVarDecl *PVD) {
1026 CallStackFrame *Frame = getCallFrameAndDepth(
Call.CallIndex).first;
1027 return Frame ? Frame->getTemporary(
Call.getOrigParam(PVD),
Call.Version)
1032 struct StdAllocatorCaller {
1033 unsigned FrameIndex;
1036 explicit operator bool()
const {
return FrameIndex != 0; };
1039 StdAllocatorCaller getStdAllocatorCaller(StringRef FnName)
const {
1040 for (
const CallStackFrame *
Call = CurrentCall;
Call != &BottomFrame;
1042 const auto *MD = dyn_cast_or_null<CXXMethodDecl>(
Call->Callee);
1045 const IdentifierInfo *FnII = MD->getIdentifier();
1046 if (!FnII || !FnII->
isStr(FnName))
1050 dyn_cast<ClassTemplateSpecializationDecl>(MD->getParent());
1054 const IdentifierInfo *ClassII = CTSD->getIdentifier();
1055 const TemplateArgumentList &TAL = CTSD->getTemplateArgs();
1056 if (CTSD->isInStdNamespace() && ClassII &&
1057 ClassII->
isStr(
"allocator") && TAL.
size() >= 1 &&
1059 return {
Call->Index, TAL[0].getAsType(),
Call->CallExpr};
1065 void performLifetimeExtension() {
1067 llvm::erase_if(CleanupStack, [](Cleanup &
C) {
1068 return !
C.isDestroyedAtEndOf(ScopeKind::FullExpression);
1075 bool discardCleanups() {
1076 for (Cleanup &
C : CleanupStack) {
1077 if (
C.hasSideEffect() && !noteSideEffect()) {
1078 CleanupStack.clear();
1082 CleanupStack.clear();
1087 const interp::Frame *getCurrentFrame()
override {
return CurrentCall; }
1088 const interp::Frame *getBottomFrame()
const override {
return &BottomFrame; }
1090 unsigned getCallStackDepth()
override {
return CallStackDepth; }
1091 bool stepsLeft()
const override {
return StepsLeft > 0; }
1104 [[nodiscard]]
bool noteFailure() {
1112 bool KeepGoing = keepEvaluatingAfterFailure();
1113 EvalStatus.HasSideEffects |= KeepGoing;
1117 class ArrayInitLoopIndex {
1122 ArrayInitLoopIndex(EvalInfo &Info)
1123 : Info(Info), OuterIndex(Info.ArrayInitIndex) {
1124 Info.ArrayInitIndex = 0;
1126 ~ArrayInitLoopIndex() { Info.ArrayInitIndex = OuterIndex; }
1128 operator uint64_t&() {
return Info.ArrayInitIndex; }
1133 struct FoldConstant {
1136 bool HadNoPriorDiags;
1139 explicit FoldConstant(EvalInfo &Info,
bool Enabled)
1142 HadNoPriorDiags(Info.EvalStatus.
Diag &&
1143 Info.EvalStatus.
Diag->empty() &&
1144 !Info.EvalStatus.HasSideEffects),
1145 OldMode(Info.EvalMode) {
1147 Info.EvalMode = EvaluationMode::ConstantFold;
1149 void keepDiagnostics() { Enabled =
false; }
1151 if (Enabled && HadNoPriorDiags && !Info.EvalStatus.Diag->empty() &&
1152 !Info.EvalStatus.HasSideEffects)
1153 Info.EvalStatus.Diag->clear();
1154 Info.EvalMode = OldMode;
1160 struct IgnoreSideEffectsRAII {
1163 explicit IgnoreSideEffectsRAII(EvalInfo &Info)
1164 : Info(Info), OldMode(Info.EvalMode) {
1165 Info.EvalMode = EvaluationMode::IgnoreSideEffects;
1168 ~IgnoreSideEffectsRAII() { Info.EvalMode = OldMode; }
1173 class SpeculativeEvaluationRAII {
1174 EvalInfo *Info =
nullptr;
1175 Expr::EvalStatus OldStatus;
1176 unsigned OldSpeculativeEvaluationDepth = 0;
1178 void moveFromAndCancel(SpeculativeEvaluationRAII &&
Other) {
1180 OldStatus =
Other.OldStatus;
1181 OldSpeculativeEvaluationDepth =
Other.OldSpeculativeEvaluationDepth;
1182 Other.Info =
nullptr;
1185 void maybeRestoreState() {
1189 Info->EvalStatus = OldStatus;
1190 Info->SpeculativeEvaluationDepth = OldSpeculativeEvaluationDepth;
1194 SpeculativeEvaluationRAII() =
default;
1196 SpeculativeEvaluationRAII(
1197 EvalInfo &Info, SmallVectorImpl<PartialDiagnosticAt> *NewDiag =
nullptr)
1198 : Info(&Info), OldStatus(Info.EvalStatus),
1199 OldSpeculativeEvaluationDepth(Info.SpeculativeEvaluationDepth) {
1200 Info.EvalStatus.Diag = NewDiag;
1201 Info.SpeculativeEvaluationDepth = Info.CallStackDepth + 1;
1204 SpeculativeEvaluationRAII(
const SpeculativeEvaluationRAII &
Other) =
delete;
1205 SpeculativeEvaluationRAII(SpeculativeEvaluationRAII &&
Other) {
1206 moveFromAndCancel(std::move(
Other));
1209 SpeculativeEvaluationRAII &operator=(SpeculativeEvaluationRAII &&
Other) {
1210 maybeRestoreState();
1211 moveFromAndCancel(std::move(
Other));
1215 ~SpeculativeEvaluationRAII() { maybeRestoreState(); }
1220 template<ScopeKind Kind>
1223 unsigned OldStackSize;
1225 ScopeRAII(EvalInfo &Info)
1226 : Info(Info), OldStackSize(Info.CleanupStack.size()) {
1229 Info.CurrentCall->pushTempVersion();
1231 bool destroy(
bool RunDestructors =
true) {
1232 bool OK =
cleanup(Info, RunDestructors, OldStackSize);
1233 OldStackSize = std::numeric_limits<unsigned>::max();
1237 if (OldStackSize != std::numeric_limits<unsigned>::max())
1241 Info.CurrentCall->popTempVersion();
1244 static bool cleanup(EvalInfo &Info,
bool RunDestructors,
1245 unsigned OldStackSize) {
1246 assert(OldStackSize <= Info.CleanupStack.size() &&
1247 "running cleanups out of order?");
1252 for (
unsigned I = Info.CleanupStack.size(); I > OldStackSize; --I) {
1253 if (Info.CleanupStack[I - 1].isDestroyedAtEndOf(Kind)) {
1254 if (!Info.CleanupStack[I - 1].endLifetime(Info, RunDestructors)) {
1262 auto NewEnd = Info.CleanupStack.begin() + OldStackSize;
1263 if (Kind != ScopeKind::Block)
1265 std::remove_if(NewEnd, Info.CleanupStack.end(), [](Cleanup &
C) {
1266 return C.isDestroyedAtEndOf(Kind);
1268 Info.CleanupStack.erase(NewEnd, Info.CleanupStack.end());
1272 typedef ScopeRAII<ScopeKind::Block> BlockScopeRAII;
1273 typedef ScopeRAII<ScopeKind::FullExpression> FullExpressionRAII;
1274 typedef ScopeRAII<ScopeKind::Call> CallScopeRAII;
1277bool SubobjectDesignator::checkSubobject(EvalInfo &Info,
const Expr *E,
1281 if (isOnePastTheEnd()) {
1282 Info.CCEDiag(E, diag::note_constexpr_past_end_subobject)
1293void SubobjectDesignator::diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info,
1295 Info.CCEDiag(E, diag::note_constexpr_unsized_array_indexed);
1300void SubobjectDesignator::diagnosePointerArithmetic(EvalInfo &Info,
1305 if (MostDerivedPathLength == Entries.size() && MostDerivedIsArrayElement)
1306 Info.CCEDiag(E, diag::note_constexpr_array_index)
1308 <<
static_cast<unsigned>(getMostDerivedArraySize());
1310 Info.CCEDiag(E, diag::note_constexpr_array_index)
1315CallStackFrame::CallStackFrame(EvalInfo &Info, SourceRange CallRange,
1316 const FunctionDecl *Callee,
const LValue *This,
1317 const Expr *CallExpr, CallRef Call)
1319 CallExpr(CallExpr),
Arguments(Call), CallRange(CallRange),
1320 Index(Info.NextCallIndex++) {
1321 Info.CurrentCall =
this;
1322 ++Info.CallStackDepth;
1325CallStackFrame::~CallStackFrame() {
1326 assert(Info.CurrentCall ==
this &&
"calls retired out of order");
1327 --Info.CallStackDepth;
1328 Info.CurrentCall = Caller;
1353 llvm_unreachable(
"unknown access kind");
1390 llvm_unreachable(
"unknown access kind");
1394 struct ComplexValue {
1402 ComplexValue() : FloatReal(
APFloat::Bogus()), FloatImag(
APFloat::Bogus()) {}
1404 void makeComplexFloat() { IsInt =
false; }
1405 bool isComplexFloat()
const {
return !IsInt; }
1406 APFloat &getComplexFloatReal() {
return FloatReal; }
1407 APFloat &getComplexFloatImag() {
return FloatImag; }
1409 void makeComplexInt() { IsInt =
true; }
1410 bool isComplexInt()
const {
return IsInt; }
1411 APSInt &getComplexIntReal() {
return IntReal; }
1412 APSInt &getComplexIntImag() {
return IntImag; }
1414 void moveInto(
APValue &v)
const {
1415 if (isComplexFloat())
1416 v =
APValue(FloatReal, FloatImag);
1418 v =
APValue(IntReal, IntImag);
1420 void setFrom(
const APValue &v) {
1435 APValue::LValueBase
Base;
1437 SubobjectDesignator Designator;
1439 bool InvalidBase : 1;
1441 bool AllowConstexprUnknown =
false;
1443 const APValue::LValueBase getLValueBase()
const {
return Base; }
1444 bool allowConstexprUnknown()
const {
return AllowConstexprUnknown; }
1445 CharUnits &getLValueOffset() {
return Offset; }
1446 const CharUnits &getLValueOffset()
const {
return Offset; }
1447 SubobjectDesignator &getLValueDesignator() {
return Designator; }
1448 const SubobjectDesignator &getLValueDesignator()
const {
return Designator;}
1449 bool isNullPointer()
const {
return IsNullPtr;}
1451 unsigned getLValueCallIndex()
const {
return Base.getCallIndex(); }
1452 unsigned getLValueVersion()
const {
return Base.getVersion(); }
1455 if (Designator.Invalid)
1456 V =
APValue(Base, Offset, APValue::NoLValuePath(), IsNullPtr);
1458 assert(!InvalidBase &&
"APValues can't handle invalid LValue bases");
1459 V =
APValue(Base, Offset, Designator.Entries,
1460 Designator.IsOnePastTheEnd, IsNullPtr);
1462 if (AllowConstexprUnknown)
1463 V.setConstexprUnknown();
1465 void setFrom(
const ASTContext &Ctx,
const APValue &
V) {
1466 assert(
V.isLValue() &&
"Setting LValue from a non-LValue?");
1467 Base =
V.getLValueBase();
1468 Offset =
V.getLValueOffset();
1469 InvalidBase =
false;
1470 Designator = SubobjectDesignator(Ctx,
V);
1471 IsNullPtr =
V.isNullPointer();
1472 AllowConstexprUnknown =
V.allowConstexprUnknown();
1475 void set(APValue::LValueBase B,
bool BInvalid =
false) {
1479 const auto *E = B.
get<
const Expr *>();
1481 "Unexpected type of invalid base");
1487 InvalidBase = BInvalid;
1488 Designator = SubobjectDesignator(
getType(B));
1490 AllowConstexprUnknown =
false;
1493 void setNull(ASTContext &Ctx, QualType PointerTy) {
1494 Base = (
const ValueDecl *)
nullptr;
1497 InvalidBase =
false;
1500 AllowConstexprUnknown =
false;
1503 void setInvalid(APValue::LValueBase B,
unsigned I = 0) {
1507 std::string
toString(ASTContext &Ctx, QualType T)
const {
1509 moveInto(Printable);
1516 template <
typename GenDiagType>
1517 bool checkNullPointerDiagnosingWith(
const GenDiagType &GenDiag) {
1518 if (Designator.Invalid)
1522 Designator.setInvalid();
1529 bool checkNullPointer(EvalInfo &Info,
const Expr *E,
1531 return checkNullPointerDiagnosingWith([&Info, E, CSK] {
1532 Info.CCEDiag(E, diag::note_constexpr_null_subobject) << CSK;
1536 bool checkNullPointerForFoldAccess(EvalInfo &Info,
const Expr *E,
1538 return checkNullPointerDiagnosingWith([&Info, E, AK] {
1539 if (AK == AccessKinds::AK_Dereference)
1540 Info.FFDiag(E, diag::note_constexpr_dereferencing_null);
1542 Info.FFDiag(E, diag::note_constexpr_access_null) << AK;
1550 Designator.checkSubobject(Info, E, CSK);
1553 void addDecl(EvalInfo &Info,
const Expr *E,
1554 const Decl *D,
bool Virtual =
false) {
1556 Designator.addDeclUnchecked(D,
Virtual);
1558 void addUnsizedArray(EvalInfo &Info,
const Expr *E, QualType ElemTy) {
1559 if (!Designator.Entries.empty()) {
1560 Info.CCEDiag(E, diag::note_constexpr_unsupported_unsized_array);
1561 Designator.setInvalid();
1565 assert(
getType(Base).getNonReferenceType()->isPointerType() ||
1566 getType(Base).getNonReferenceType()->isArrayType());
1567 Designator.FirstEntryIsAnUnsizedArray =
true;
1568 Designator.addUnsizedArrayUnchecked(ElemTy);
1571 void addArray(EvalInfo &Info,
const Expr *E,
const ConstantArrayType *CAT) {
1573 Designator.addArrayUnchecked(CAT);
1575 void addComplex(EvalInfo &Info,
const Expr *E, QualType EltTy,
bool Imag) {
1577 Designator.addComplexUnchecked(EltTy, Imag);
1579 void addVectorElement(EvalInfo &Info,
const Expr *E, QualType EltTy,
1580 uint64_t Size, uint64_t Idx) {
1582 Designator.addVectorElementUnchecked(EltTy, Size, Idx);
1584 void clearIsNullPointer() {
1587 void adjustOffsetAndIndex(EvalInfo &Info,
const Expr *E,
1588 const APSInt &Index, CharUnits ElementSize) {
1599 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
1603 Designator.adjustIndex(Info, E, Index, *
this);
1604 clearIsNullPointer();
1606 void adjustOffset(CharUnits N) {
1609 clearIsNullPointer();
1615 explicit MemberPtr(
const ValueDecl *Decl)
1616 : DeclAndIsDerivedMember(
Decl,
false) {}
1620 const ValueDecl *getDecl()
const {
1621 return DeclAndIsDerivedMember.getPointer();
1624 bool isDerivedMember()
const {
1625 return DeclAndIsDerivedMember.getInt();
1628 const CXXRecordDecl *getContainingRecord()
const {
1630 DeclAndIsDerivedMember.getPointer()->getDeclContext());
1634 V =
APValue(getDecl(), isDerivedMember(), Path);
1637 assert(
V.isMemberPointer());
1638 DeclAndIsDerivedMember.setPointer(
V.getMemberPointerDecl());
1639 DeclAndIsDerivedMember.setInt(
V.isMemberPointerToDerivedMember());
1641 llvm::append_range(Path,
V.getMemberPointerPath());
1647 llvm::PointerIntPair<const ValueDecl*, 1, bool> DeclAndIsDerivedMember;
1650 SmallVector<const CXXRecordDecl*, 4> Path;
1654 bool castBack(
const CXXRecordDecl *
Class) {
1655 assert(!Path.empty());
1656 const CXXRecordDecl *Expected;
1657 if (Path.size() >= 2)
1658 Expected = Path[Path.size() - 2];
1660 Expected = getContainingRecord();
1674 bool castToDerived(
const CXXRecordDecl *Derived) {
1677 if (!isDerivedMember()) {
1678 Path.push_back(Derived);
1681 if (!castBack(Derived))
1684 DeclAndIsDerivedMember.setInt(
false);
1692 DeclAndIsDerivedMember.setInt(
true);
1693 if (isDerivedMember()) {
1694 Path.push_back(Base);
1697 return castBack(Base);
1702 static bool operator==(
const MemberPtr &LHS,
const MemberPtr &RHS) {
1703 if (!LHS.getDecl() || !RHS.getDecl())
1704 return !LHS.getDecl() && !RHS.getDecl();
1705 if (LHS.getDecl()->getCanonicalDecl() != RHS.getDecl()->getCanonicalDecl())
1707 return LHS.Path == RHS.Path;
1711void SubobjectDesignator::adjustIndex(EvalInfo &Info,
const Expr *E,
APSInt N,
1715 uint64_t TruncatedN = N.extOrTrunc(64).getZExtValue();
1716 if (isMostDerivedAnUnsizedArray()) {
1717 diagnoseUnsizedArrayPointerArithmetic(Info, E);
1722 PathEntry::ArrayIndex(Entries.back().getAsArrayIndex() + TruncatedN);
1730 MostDerivedPathLength == Entries.size() && MostDerivedIsArrayElement;
1732 IsArray ? Entries.back().getAsArrayIndex() : (
uint64_t)IsOnePastTheEnd;
1735 if (N < -(int64_t)ArrayIndex || N > ArraySize - ArrayIndex) {
1736 if (!Info.checkingPotentialConstantExpression() ||
1737 !LV.AllowConstexprUnknown) {
1740 N = N.extend(std::max<unsigned>(N.getBitWidth() + 1, 65));
1741 (llvm::APInt &)N += ArrayIndex;
1742 assert(N.ugt(ArraySize) &&
"bounds check failed for in-bounds index");
1743 diagnosePointerArithmetic(Info, E, N);
1749 ArrayIndex += TruncatedN;
1750 assert(ArrayIndex <= ArraySize &&
1751 "bounds check succeeded for out-of-bounds index");
1754 Entries.back() = PathEntry::ArrayIndex(ArrayIndex);
1756 IsOnePastTheEnd = (ArrayIndex != 0);
1761 const LValue &This,
const Expr *E,
1762 bool AllowNonLiteralTypes =
false);
1764 bool InvalidBaseOK =
false);
1766 bool InvalidBaseOK =
false);
1774static bool EvaluateComplex(
const Expr *E, ComplexValue &Res, EvalInfo &Info);
1779static std::optional<uint64_t>
1781 std::string *StringResult =
nullptr);
1798 if (Int.isUnsigned() || Int.isMinSignedValue()) {
1799 Int = Int.extend(Int.getBitWidth() + 1);
1800 Int.setIsSigned(
true);
1805template<
typename KeyT>
1806APValue &CallStackFrame::createTemporary(
const KeyT *Key, QualType T,
1807 ScopeKind Scope, LValue &LV) {
1808 unsigned Version = getTempVersion();
1809 APValue::LValueBase
Base(Key, Index, Version);
1811 return createLocal(Base, Key, T, Scope);
1815APValue &CallStackFrame::createParam(CallRef Args,
const ParmVarDecl *PVD,
1817 assert(Args.CallIndex == Index &&
"creating parameter in wrong frame");
1818 APValue::LValueBase
Base(PVD, Index, Args.Version);
1823 return createLocal(Base, PVD, PVD->
getType(), ScopeKind::Call);
1826APValue &CallStackFrame::createLocal(APValue::LValueBase Base,
const void *Key,
1827 QualType T, ScopeKind Scope) {
1828 assert(
Base.getCallIndex() == Index &&
"lvalue for wrong frame");
1829 unsigned Version =
Base.getVersion();
1831 assert(
Result.isAbsent() &&
"local created multiple times");
1837 if (Index <= Info.SpeculativeEvaluationDepth) {
1839 Info.noteSideEffect();
1841 Info.CleanupStack.push_back(Cleanup(&
Result, Base, T, Scope));
1846APValue *EvalInfo::createHeapAlloc(
const Expr *E, QualType T, LValue &LV) {
1848 FFDiag(E, diag::note_constexpr_heap_alloc_limit_exceeded);
1852 DynamicAllocLValue DA(NumHeapAllocs++);
1854 auto Result = HeapAllocs.emplace(std::piecewise_construct,
1855 std::forward_as_tuple(DA), std::tuple<>());
1856 assert(
Result.second &&
"reused a heap alloc index?");
1857 Result.first->second.AllocExpr = E;
1858 return &
Result.first->second.Value;
1862void CallStackFrame::describe(raw_ostream &Out)
const {
1863 bool IsMemberCall =
false;
1864 bool ExplicitInstanceParam =
false;
1865 clang::PrintingPolicy PrintingPolicy = Info.Ctx.getPrintingPolicy();
1868 if (
const auto *MD = dyn_cast<CXXMethodDecl>(Callee)) {
1870 ExplicitInstanceParam = MD->isExplicitObjectMemberFunction();
1874 Callee->getNameForDiagnostic(Out, PrintingPolicy,
1877 if (This && IsMemberCall) {
1878 if (
const auto *MCE = dyn_cast_if_present<CXXMemberCallExpr>(CallExpr)) {
1879 const Expr *
Object = MCE->getImplicitObjectArgument();
1880 Object->printPretty(Out,
nullptr, PrintingPolicy,
1882 if (
Object->getType()->isPointerType())
1886 }
else if (
const auto *OCE =
1887 dyn_cast_if_present<CXXOperatorCallExpr>(CallExpr)) {
1888 OCE->getArg(0)->printPretty(Out,
nullptr, PrintingPolicy,
1893 This->moveInto(Val);
1896 Info.Ctx.getLValueReferenceType(
This->Designator.MostDerivedType));
1899 Callee->getNameForDiagnostic(Out, PrintingPolicy,
1905 llvm::ListSeparator
Comma;
1906 for (
const ParmVarDecl *Param :
1907 Callee->parameters().slice(ExplicitInstanceParam)) {
1909 const APValue *
V = Info.getParamSlot(Arguments, Param);
1911 V->printPretty(Out, Info.Ctx, Param->getType());
1927 return Info.noteSideEffect();
1934 return (
Builtin == Builtin::BI__builtin___CFStringMakeConstantString ||
1935 Builtin == Builtin::BI__builtin___NSStringMakeConstantString ||
1936 Builtin == Builtin::BI__builtin_ptrauth_sign_constant ||
1937 Builtin == Builtin::BI__builtin_function_start);
1941 const auto *BaseExpr =
1942 llvm::dyn_cast_if_present<CallExpr>(LVal.Base.
dyn_cast<
const Expr *>());
1957 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
1958 return VD->hasGlobalStorage();
1974 case Expr::CompoundLiteralExprClass: {
1978 case Expr::MaterializeTemporaryExprClass:
1983 case Expr::StringLiteralClass:
1984 case Expr::PredefinedExprClass:
1985 case Expr::ObjCStringLiteralClass:
1986 case Expr::ObjCEncodeExprClass:
1988 case Expr::ObjCBoxedExprClass:
1989 case Expr::ObjCArrayLiteralClass:
1990 case Expr::ObjCDictionaryLiteralClass:
1992 case Expr::CallExprClass:
1995 case Expr::AddrLabelExprClass:
1999 case Expr::BlockExprClass:
2003 case Expr::SourceLocExprClass:
2005 case Expr::ImplicitValueInitExprClass:
2030 const auto *BaseExpr = LVal.Base.
dyn_cast<
const Expr *>();
2035 if (
const auto *EE = dyn_cast<ObjCEncodeExpr>(BaseExpr)) {
2036 Info.Ctx.getObjCEncodingForType(EE->getEncodedType(),
2044 const auto *Lit = dyn_cast<StringLiteral>(BaseExpr);
2045 if (
const auto *PE = dyn_cast<PredefinedExpr>(BaseExpr))
2046 Lit = PE->getFunctionName();
2051 AsString.
Bytes = Lit->getBytes();
2052 AsString.
CharWidth = Lit->getCharByteWidth();
2072 const LValue &RHS) {
2081 CharUnits Offset = RHS.Offset - LHS.Offset;
2082 if (Offset.isNegative()) {
2083 if (LHSString.
Bytes.size() < (
size_t)-Offset.getQuantity())
2085 LHSString.
Bytes = LHSString.
Bytes.drop_front(-Offset.getQuantity());
2087 if (RHSString.
Bytes.size() < (
size_t)Offset.getQuantity())
2089 RHSString.
Bytes = RHSString.
Bytes.drop_front(Offset.getQuantity());
2092 bool LHSIsLonger = LHSString.
Bytes.size() > RHSString.
Bytes.size();
2093 StringRef Longer = LHSIsLonger ? LHSString.
Bytes : RHSString.
Bytes;
2094 StringRef Shorter = LHSIsLonger ? RHSString.
Bytes : LHSString.
Bytes;
2095 int ShorterCharWidth = (LHSIsLonger ? RHSString : LHSString).CharWidth;
2100 for (
int NullByte : llvm::seq(ShorterCharWidth)) {
2101 if (Shorter.size() + NullByte >= Longer.size())
2103 if (Longer[Shorter.size() + NullByte])
2109 return Shorter == Longer.take_front(Shorter.size());
2119 if (isa_and_nonnull<VarDecl>(
Decl)) {
2129 if (!A.getLValueBase())
2130 return !B.getLValueBase();
2131 if (!B.getLValueBase())
2134 if (A.getLValueBase().getOpaqueValue() !=
2135 B.getLValueBase().getOpaqueValue())
2138 return A.getLValueCallIndex() == B.getLValueCallIndex() &&
2139 A.getLValueVersion() == B.getLValueVersion();
2143 assert(
Base &&
"no location for a null lvalue");
2149 if (
auto *PVD = dyn_cast_or_null<ParmVarDecl>(VD)) {
2151 for (CallStackFrame *F = Info.CurrentCall; F; F = F->Caller) {
2152 if (F->Arguments.CallIndex ==
Base.getCallIndex() &&
2153 F->Arguments.Version ==
Base.getVersion() && F->Callee &&
2154 Idx < F->Callee->getNumParams()) {
2155 VD = F->Callee->getParamDecl(Idx);
2162 Info.Note(VD->
getLocation(), diag::note_declared_at);
2164 Info.Note(E->
getExprLoc(), diag::note_constexpr_temporary_here);
2167 if (std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA))
2168 Info.Note((*Alloc)->AllocExpr->getExprLoc(),
2169 diag::note_constexpr_dynamic_alloc_here);
2202 const SubobjectDesignator &
Designator = LVal.getLValueDesignator();
2210 if (isTemplateArgument(Kind)) {
2211 int InvalidBaseKind = -1;
2214 InvalidBaseKind = 0;
2215 else if (isa_and_nonnull<StringLiteral>(BaseE))
2216 InvalidBaseKind = 1;
2217 else if (isa_and_nonnull<MaterializeTemporaryExpr>(BaseE) ||
2218 isa_and_nonnull<LifetimeExtendedTemporaryDecl>(BaseVD))
2219 InvalidBaseKind = 2;
2220 else if (
auto *PE = dyn_cast_or_null<PredefinedExpr>(BaseE)) {
2221 InvalidBaseKind = 3;
2222 Ident = PE->getIdentKindName();
2225 if (InvalidBaseKind != -1) {
2226 Info.FFDiag(Loc, diag::note_constexpr_invalid_template_arg)
2227 << IsReferenceType << !
Designator.Entries.empty() << InvalidBaseKind
2233 if (
auto *FD = dyn_cast_or_null<FunctionDecl>(BaseVD);
2234 FD && FD->isImmediateFunction()) {
2235 Info.FFDiag(Loc, diag::note_consteval_address_accessible)
2237 Info.Note(FD->getLocation(), diag::note_declared_at);
2245 if (Info.getLangOpts().CPlusPlus11) {
2246 Info.FFDiag(Loc, diag::note_constexpr_non_global, 1)
2247 << IsReferenceType << !
Designator.Entries.empty() << !!BaseVD
2249 auto *VarD = dyn_cast_or_null<VarDecl>(BaseVD);
2250 if (VarD && VarD->isConstexpr()) {
2256 Info.Note(VarD->getLocation(), diag::note_constexpr_not_static)
2268 assert((Info.checkingPotentialConstantExpression() ||
2269 LVal.getLValueCallIndex() == 0) &&
2270 "have call index for global lvalue");
2272 if (LVal.allowConstexprUnknown()) {
2274 Info.FFDiag(Loc, diag::note_constexpr_var_init_non_constant, 1) << BaseVD;
2283 Info.FFDiag(Loc, diag::note_constexpr_dynamic_alloc)
2284 << IsReferenceType << !
Designator.Entries.empty();
2290 if (
const VarDecl *Var = dyn_cast<const VarDecl>(BaseVD)) {
2292 if (Var->getTLSKind())
2300 if (!isForManglingOnly(Kind) && Var->hasAttr<DLLImportAttr>() &&
2301 !Var->isStaticLocal())
2306 if (Info.getLangOpts().CUDA && Info.getLangOpts().CUDAIsDevice &&
2307 Info.Ctx.CUDAConstantEvalCtx.NoWrongSidedVars) {
2308 if ((!Var->hasAttr<CUDADeviceAttr>() &&
2309 !Var->hasAttr<CUDAConstantAttr>() &&
2310 !Var->getType()->isCUDADeviceBuiltinSurfaceType() &&
2311 !Var->getType()->isCUDADeviceBuiltinTextureType()) ||
2312 Var->hasAttr<HIPManagedAttr>())
2316 if (
const auto *FD = dyn_cast<const FunctionDecl>(BaseVD)) {
2327 if (Info.getLangOpts().CPlusPlus && !isForManglingOnly(Kind) &&
2328 FD->hasAttr<DLLImportAttr>())
2332 }
else if (
const auto *MTE =
2333 dyn_cast_or_null<MaterializeTemporaryExpr>(BaseE)) {
2334 if (CheckedTemps.insert(MTE).second) {
2337 Info.FFDiag(MTE->getExprLoc(),
2338 diag::note_constexpr_unsupported_temporary_nontrivial_dtor)
2343 APValue *
V = MTE->getOrCreateValue(
false);
2344 assert(
V &&
"evasluation result refers to uninitialised temporary");
2346 Info, MTE->getExprLoc(), TempType, *
V, Kind,
2347 nullptr, CheckedTemps))
2354 if (!IsReferenceType)
2366 Info.FFDiag(Loc, diag::note_constexpr_past_end, 1)
2367 << !
Designator.Entries.empty() << !!BaseVD << BaseVD;
2382 const auto *FD = dyn_cast_or_null<CXXMethodDecl>(
Member);
2385 if (FD->isImmediateFunction()) {
2386 Info.FFDiag(Loc, diag::note_consteval_address_accessible) << 0;
2387 Info.Note(FD->getLocation(), diag::note_declared_at);
2390 return isForManglingOnly(Kind) || FD->isVirtual() ||
2391 !FD->hasAttr<DLLImportAttr>();
2397 const LValue *
This =
nullptr) {
2399 if (Info.getLangOpts().CPlusPlus23)
2418 if (
This && Info.EvaluatingDecl ==
This->getLValueBase())
2422 if (Info.getLangOpts().CPlusPlus11)
2423 Info.FFDiag(E, diag::note_constexpr_nonliteral)
2426 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
2437 if (SubobjectDecl) {
2438 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
2439 << 1 << SubobjectDecl;
2441 diag::note_constexpr_subobject_declared_here);
2443 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
2452 Type = AT->getValueType();
2457 if (
Value.isArray()) {
2459 for (
unsigned I = 0, N =
Value.getArrayInitializedElts(); I != N; ++I) {
2461 Value.getArrayInitializedElt(I), Kind,
2462 SubobjectDecl, CheckedTemps))
2465 if (!
Value.hasArrayFiller())
2468 Value.getArrayFiller(), Kind, SubobjectDecl,
2471 if (
Value.isUnion() &&
Value.getUnionField()) {
2474 Value.getUnionValue(), Kind,
Value.getUnionField(), CheckedTemps);
2476 if (
Value.isStruct()) {
2478 if (
const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {
2479 unsigned BaseIndex = 0;
2481 const APValue &BaseValue =
Value.getStructBase(BaseIndex);
2484 Info.FFDiag(TypeBeginLoc, diag::note_constexpr_uninitialized_base)
2485 << BS.getType() <<
SourceRange(TypeBeginLoc, BS.getEndLoc());
2495 for (
const auto *I : RD->fields()) {
2496 if (I->isUnnamedBitField())
2500 Value.getStructField(I->getFieldIndex()), Kind,
2506 if (
Value.isLValue() &&
2509 LVal.setFrom(Info.Ctx,
Value);
2514 if (
Value.isMemberPointer() &&
2535 nullptr, CheckedTemps);
2545 ConstantExprKind::Normal,
nullptr, CheckedTemps);
2551 if (!Info.HeapAllocs.empty()) {
2555 Info.CCEDiag(Info.HeapAllocs.begin()->second.AllocExpr,
2556 diag::note_constexpr_memory_leak)
2557 <<
unsigned(Info.HeapAllocs.size() - 1);
2565 if (!
Value.getLValueBase()) {
2618 llvm_unreachable(
"unknown APValue kind");
2624 assert(E->
isPRValue() &&
"missing lvalue-to-rvalue conv in bool condition");
2633 const T &SrcValue,
QualType DestType) {
2634 Info.CCEDiag(E, diag::note_constexpr_overflow) << SrcValue << DestType;
2635 if (
const auto *OBT = DestType->
getAs<OverflowBehaviorType>();
2636 OBT && OBT->isTrapKind()) {
2639 return Info.noteUndefinedBehavior();
2645 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
2651 if (
Value.convertToInteger(
Result, llvm::APFloat::rmTowardZero, &ignored)
2652 & APFloat::opInvalidOp)
2663 llvm::RoundingMode RM =
2665 if (RM == llvm::RoundingMode::Dynamic)
2666 RM = llvm::RoundingMode::NearestTiesToEven;
2672 APFloat::opStatus St) {
2675 if (Info.InConstantContext)
2679 if ((St & APFloat::opInexact) &&
2683 Info.FFDiag(E, diag::note_constexpr_dynamic_rounding);
2687 if ((St != APFloat::opOK) &&
2690 FPO.getAllowFEnvAccess())) {
2691 Info.FFDiag(E, diag::note_constexpr_float_arithmetic_strict);
2695 if ((St & APFloat::opStatus::opInvalidOp) &&
2716 "HandleFloatToFloatCast has been checked with only CastExpr, "
2717 "CompoundAssignOperator and ConvertVectorExpr. Please either validate "
2718 "the new expression or address the root cause of this usage.");
2720 APFloat::opStatus St;
2723 St =
Result.convert(Info.Ctx.getFloatTypeSemantics(DestType), RM, &ignored);
2730 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
2744 Result = APFloat(Info.Ctx.getFloatTypeSemantics(DestType), 1);
2746 APFloat::opStatus St =
Result.convertFromAPInt(
Value,
Value.isSigned(), RM);
2752 assert(FD->
isBitField() &&
"truncateBitfieldValue on non-bitfield");
2754 if (!
Value.isInt()) {
2758 assert(
Value.isLValue() &&
"integral value neither int nor lvalue?");
2764 unsigned OldBitWidth = Int.getBitWidth();
2766 if (NewBitWidth < OldBitWidth)
2767 Int = Int.trunc(NewBitWidth).extend(OldBitWidth);
2774template<
typename Operation>
2777 unsigned BitWidth, Operation Op,
2779 if (LHS.isUnsigned()) {
2784 APSInt Value(Op(LHS.extend(BitWidth), RHS.extend(BitWidth)),
false);
2787 if (Info.checkingForUndefinedBehavior())
2788 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
2789 diag::warn_integer_constant_overflow)
2802 bool HandleOverflowResult =
true;
2809 std::multiplies<APSInt>(),
Result);
2812 std::plus<APSInt>(),
Result);
2815 std::minus<APSInt>(),
Result);
2816 case BO_And:
Result = LHS & RHS;
return true;
2817 case BO_Xor:
Result = LHS ^ RHS;
return true;
2818 case BO_Or:
Result = LHS | RHS;
return true;
2822 Info.FFDiag(E, diag::note_expr_divide_by_zero)
2828 if (RHS.isNegative() && RHS.isAllOnes() && LHS.isSigned() &&
2829 LHS.isMinSignedValue())
2831 Info, E, -LHS.extend(LHS.getBitWidth() + 1), E->
getType());
2832 Result = (Opcode == BO_Rem ? LHS % RHS : LHS / RHS);
2833 return HandleOverflowResult;
2835 if (Info.getLangOpts().OpenCL)
2837 RHS &=
APSInt(llvm::APInt(RHS.getBitWidth(),
2838 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2840 else if (RHS.isSigned() && RHS.isNegative()) {
2843 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
2844 if (!Info.noteUndefinedBehavior())
2852 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
2854 Info.CCEDiag(E, diag::note_constexpr_large_shift)
2855 << RHS << E->
getType() << LHS.getBitWidth();
2856 if (!Info.noteUndefinedBehavior())
2858 }
else if (LHS.isSigned() && !Info.getLangOpts().CPlusPlus20) {
2863 if (LHS.isNegative()) {
2864 Info.CCEDiag(E, diag::note_constexpr_lshift_of_negative) << LHS;
2865 if (!Info.noteUndefinedBehavior())
2867 }
else if (LHS.countl_zero() < SA) {
2868 Info.CCEDiag(E, diag::note_constexpr_lshift_discards);
2869 if (!Info.noteUndefinedBehavior())
2877 if (Info.getLangOpts().OpenCL)
2879 RHS &=
APSInt(llvm::APInt(RHS.getBitWidth(),
2880 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2882 else if (RHS.isSigned() && RHS.isNegative()) {
2885 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
2886 if (!Info.noteUndefinedBehavior())
2894 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
2896 Info.CCEDiag(E, diag::note_constexpr_large_shift)
2897 << RHS << E->
getType() << LHS.getBitWidth();
2898 if (!Info.noteUndefinedBehavior())
2906 case BO_LT:
Result = LHS < RHS;
return true;
2907 case BO_GT:
Result = LHS > RHS;
return true;
2908 case BO_LE:
Result = LHS <= RHS;
return true;
2909 case BO_GE:
Result = LHS >= RHS;
return true;
2910 case BO_EQ:
Result = LHS == RHS;
return true;
2911 case BO_NE:
Result = LHS != RHS;
return true;
2913 llvm_unreachable(
"BO_Cmp should be handled elsewhere");
2920 const APFloat &RHS) {
2922 APFloat::opStatus St;
2928 St = LHS.multiply(RHS, RM);
2931 St = LHS.add(RHS, RM);
2934 St = LHS.subtract(RHS, RM);
2940 Info.CCEDiag(E, diag::note_expr_divide_by_zero);
2941 St = LHS.divide(RHS, RM);
2950 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << LHS.isNaN();
2951 return Info.noteUndefinedBehavior();
2959 const APInt &RHSValue, APInt &
Result) {
2960 bool LHS = (LHSValue != 0);
2961 bool RHS = (RHSValue != 0);
2963 if (Opcode == BO_LAnd)
2971 const APFloat &RHSValue, APInt &
Result) {
2972 bool LHS = !LHSValue.isZero();
2973 bool RHS = !RHSValue.isZero();
2975 if (Opcode == BO_LAnd)
2994template <
typename APTy>
2997 const APTy &RHSValue, APInt &
Result) {
3000 llvm_unreachable(
"unsupported binary operator");
3002 Result = (LHSValue == RHSValue);
3005 Result = (LHSValue != RHSValue);
3008 Result = (LHSValue < RHSValue);
3011 Result = (LHSValue > RHSValue);
3014 Result = (LHSValue <= RHSValue);
3017 Result = (LHSValue >= RHSValue);
3046 assert(Opcode != BO_PtrMemD && Opcode != BO_PtrMemI &&
3047 "Operation not supported on vector types");
3051 QualType EltTy = VT->getElementType();
3058 "A vector result that isn't a vector OR uncalculated LValue");
3064 RHSValue.
getVectorLength() == NumElements &&
"Different vector sizes");
3068 for (
unsigned EltNum = 0; EltNum < NumElements; ++EltNum) {
3073 APSInt EltResult{Info.Ctx.getIntWidth(EltTy),
3083 RHSElt.
getInt(), EltResult);
3089 ResultElements.emplace_back(EltResult);
3094 "Mismatched LHS/RHS/Result Type");
3095 APFloat LHSFloat = LHSElt.
getFloat();
3103 ResultElements.emplace_back(LHSFloat);
3107 LHSValue =
APValue(ResultElements.data(), ResultElements.size());
3115 unsigned TruncatedElements) {
3116 SubobjectDesignator &D =
Result.Designator;
3119 if (TruncatedElements == D.Entries.size())
3121 assert(TruncatedElements >= D.MostDerivedPathLength &&
3122 "not casting to a derived class");
3128 for (
unsigned I = TruncatedElements, N = D.Entries.size(); I != N; ++I) {
3132 if (isVirtualBaseClass(D.Entries[I]))
3138 D.Entries.resize(TruncatedElements);
3148 RL = &Info.Ctx.getASTRecordLayout(Derived);
3151 Obj.addDecl(Info, E,
Base,
false);
3152 Obj.getLValueOffset() += RL->getBaseClassOffset(
Base);
3161 if (!
Base->isVirtual())
3164 SubobjectDesignator &D = Obj.Designator;
3179 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(DerivedDecl);
3180 Obj.addDecl(Info, E, BaseDecl,
true);
3189 PathI != PathE; ++PathI) {
3193 Type = (*PathI)->getType();
3205 llvm_unreachable(
"Class must be derived from the passed in base class!");
3220 RL = &Info.Ctx.getASTRecordLayout(FD->
getParent());
3224 LVal.addDecl(Info, E, FD);
3225 LVal.adjustOffset(Info.Ctx.toCharUnitsFromBits(RL->getFieldOffset(I)));
3233 for (
const auto *
C : IFD->
chain())
3267 Size = Info.Ctx.getTypeSizeInChars(
Type);
3269 Size = Info.Ctx.getTypeInfoDataSizeInChars(
Type).Width;
3286 LVal.adjustOffsetAndIndex(Info, E, Adjustment, SizeOfPointee);
3292 int64_t Adjustment) {
3294 APSInt::get(Adjustment));
3309 LVal.Offset += SizeOfComponent;
3311 LVal.addComplex(Info, E, EltTy, Imag);
3317 uint64_t Size, uint64_t Idx) {
3322 LVal.Offset += SizeOfElement * Idx;
3324 LVal.addVectorElement(Info, E, EltTy, Size, Idx);
3338 const VarDecl *VD, CallStackFrame *Frame,
3342 bool AllowConstexprUnknown =
3347 auto CheckUninitReference = [&](
bool IsLocalVariable) {
3359 if (!AllowConstexprUnknown || IsLocalVariable) {
3360 if (!Info.checkingPotentialConstantExpression())
3361 Info.FFDiag(E, diag::note_constexpr_use_uninit_reference);
3371 Result = Frame->getTemporary(VD, Version);
3373 return CheckUninitReference(
true);
3382 "missing value for local variable");
3383 if (Info.checkingPotentialConstantExpression())
3387 "A variable in a frame should either be a local or a parameter");
3393 if (Info.EvaluatingDecl ==
Base) {
3394 Result = Info.EvaluatingDeclValue;
3395 return CheckUninitReference(
false);
3403 if (AllowConstexprUnknown) {
3410 if (!Info.checkingPotentialConstantExpression() ||
3411 !Info.CurrentCall->Callee ||
3413 if (Info.getLangOpts().CPlusPlus11) {
3414 Info.FFDiag(E, diag::note_constexpr_function_param_value_unknown)
3435 if (!
Init && !AllowConstexprUnknown) {
3438 if (!Info.checkingPotentialConstantExpression()) {
3439 Info.FFDiag(E, diag::note_constexpr_var_init_unknown, 1)
3450 if (
Init &&
Init->isValueDependent()) {
3457 if (!Info.checkingPotentialConstantExpression()) {
3458 Info.FFDiag(E, Info.getLangOpts().CPlusPlus11
3459 ? diag::note_constexpr_ltor_non_constexpr
3460 : diag::note_constexpr_ltor_non_integral, 1)
3474 Info.FFDiag(E, diag::note_constexpr_var_init_non_constant, 1) << VD;
3490 !AllowConstexprUnknown) ||
3491 ((Info.getLangOpts().CPlusPlus || Info.getLangOpts().OpenCL) &&
3494 Info.CCEDiag(E, diag::note_constexpr_var_init_non_constant, 1) << VD;
3504 Info.FFDiag(E, diag::note_constexpr_var_init_weak) << VD;
3511 if (!
Result && !AllowConstexprUnknown)
3514 return CheckUninitReference(
false);
3524 E = Derived->
bases_end(); I != E; ++I, ++Index) {
3525 if (I->getType()->getAsCXXRecordDecl()->getCanonicalDecl() ==
Base)
3529 llvm_unreachable(
"base class missing from derived class's bases list");
3536 "SourceLocExpr should have already been converted to a StringLiteral");
3539 if (
const auto *ObjCEnc = dyn_cast<ObjCEncodeExpr>(Lit)) {
3541 Info.Ctx.getObjCEncodingForType(ObjCEnc->getEncodedType(), Str);
3542 assert(Index <= Str.size() &&
"Index too large");
3543 return APSInt::getUnsigned(Str.c_str()[Index]);
3546 if (
auto PE = dyn_cast<PredefinedExpr>(Lit))
3547 Lit = PE->getFunctionName();
3550 Info.Ctx.getAsConstantArrayType(S->
getType());
3551 assert(CAT &&
"string literal isn't an array");
3553 assert(CharType->
isIntegerType() &&
"unexpected character type");
3556 if (Index < S->getLength())
3569 AllocType.isNull() ? S->
getType() : AllocType);
3570 assert(CAT &&
"string literal isn't an array");
3572 assert(CharType->
isIntegerType() &&
"unexpected character type");
3579 if (
Result.hasArrayFiller())
3581 for (
unsigned I = 0, N =
Result.getArrayInitializedElts(); I != N; ++I) {
3589 unsigned Size =
Array.getArraySize();
3590 assert(Index < Size);
3593 unsigned OldElts =
Array.getArrayInitializedElts();
3594 unsigned NewElts = std::max(Index+1, OldElts * 2);
3595 NewElts = std::min(Size, std::max(NewElts, 8u));
3599 for (
unsigned I = 0; I != OldElts; ++I)
3601 for (
unsigned I = OldElts; I != NewElts; ++I)
3605 Array.swap(NewValue);
3612 Vec =
APValue(Elts.data(), Elts.size());
3622 CXXRecordDecl *RD = T->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
3633 for (
auto *Field : RD->
fields())
3634 if (!Field->isUnnamedBitField() &&
3638 for (
auto &BaseSpec : RD->
bases())
3649 CXXRecordDecl *RD = T->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
3656 for (
auto *Field : RD->
fields()) {
3661 if (Field->isMutable() &&
3663 Info.FFDiag(E, diag::note_constexpr_access_mutable, 1) << AK << Field;
3664 Info.Note(Field->getLocation(), diag::note_declared_at);
3672 for (
auto &BaseSpec : RD->
bases())
3682 bool MutableSubobject =
false) {
3687 switch (Info.IsEvaluatingDecl) {
3688 case EvalInfo::EvaluatingDeclKind::None:
3691 case EvalInfo::EvaluatingDeclKind::Ctor:
3693 if (Info.EvaluatingDecl ==
Base)
3698 if (
auto *BaseE =
Base.dyn_cast<
const Expr *>())
3699 if (
auto *BaseMTE = dyn_cast<MaterializeTemporaryExpr>(BaseE))
3700 return Info.EvaluatingDecl == BaseMTE->getExtendingDecl();
3703 case EvalInfo::EvaluatingDeclKind::Dtor:
3708 if (MutableSubobject ||
Base != Info.EvaluatingDecl)
3714 return T.isConstQualified() || T->isReferenceType();
3717 llvm_unreachable(
"unknown evaluating decl kind");
3722 return Info.CheckArraySize(
3742 uint64_t IntResult = BoolResult;
3745 : Info.Ctx.getIntTypeForBitwidth(64,
false);
3746 Result =
APValue(Info.Ctx.MakeIntValue(IntResult, IntType));
3751 Info.Ctx.getIntTypeForBitwidth(64,
false),
3754 Result = std::move(Result2);
3762 DestTy,
Result.getFloat());
3768 uint64_t IntResult = BoolResult;
3787 uint64_t IntResult = BoolResult;
3794 DestTy,
Result.getInt());
3798 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
3811 {&
Result, ResultType, 0}};
3814 while (!WorkList.empty() && ElI < Elements.size()) {
3815 auto [Res,
Type, BitWidth] = WorkList.pop_back_val();
3831 APSInt &Int = Res->getInt();
3832 unsigned OldBitWidth = Int.getBitWidth();
3833 unsigned NewBitWidth = BitWidth;
3834 if (NewBitWidth < OldBitWidth)
3835 Int = Int.trunc(NewBitWidth).extend(OldBitWidth);
3844 for (
unsigned I = 0; I < NumEl; ++I) {
3850 *Res =
APValue(Vals.data(), NumEl);
3859 for (int64_t I = Size - 1; I > -1; --I)
3860 WorkList.emplace_back(&Res->getArrayInitializedElt(I), ElTy, 0u);
3866 unsigned NumBases = 0;
3867 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
3868 NumBases = CXXRD->getNumBases();
3875 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
3876 if (CXXRD->getNumBases() > 0) {
3877 assert(CXXRD->getNumBases() == 1);
3879 ReverseList.emplace_back(&Res->getStructBase(0), BS.
getType(), 0u);
3886 if (FD->isUnnamedBitField())
3888 if (FD->isBitField()) {
3889 FDBW = FD->getBitWidthValue();
3892 ReverseList.emplace_back(&Res->getStructField(FD->getFieldIndex()),
3893 FD->getType(), FDBW);
3896 std::reverse(ReverseList.begin(), ReverseList.end());
3897 llvm::append_range(WorkList, ReverseList);
3900 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
3913 assert((Elements.size() == SrcTypes.size()) &&
3914 (Elements.size() == DestTypes.size()));
3916 for (
unsigned I = 0, ESz = Elements.size(); I < ESz; ++I) {
3917 APValue Original = Elements[I];
3921 if (!
handleScalarCast(Info, FPO, E, SourceTy, DestTy, Original, Results[I]))
3932 while (!WorkList.empty()) {
3955 for (uint64_t I = 0; I < ArrSize; ++I) {
3956 WorkList.push_back(ElTy);
3964 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
3965 if (CXXRD->getNumBases() > 0) {
3966 assert(CXXRD->getNumBases() == 1);
3968 WorkList.push_back(BS.
getType());
3974 if (FD->isUnnamedBitField())
3976 WorkList.push_back(FD->getType());
3993 "Not a valid HLSLAggregateSplatCast.");
4013 unsigned Populated = 0;
4014 while (!WorkList.empty() && Populated < Size) {
4015 auto [Work,
Type] = WorkList.pop_back_val();
4017 if (Work.isFloat() || Work.isInt()) {
4018 Elements.push_back(Work);
4019 Types.push_back(
Type);
4023 if (Work.isVector()) {
4026 for (
unsigned I = 0; I < Work.getVectorLength() && Populated < Size;
4028 Elements.push_back(Work.getVectorElt(I));
4029 Types.push_back(ElTy);
4034 if (Work.isMatrix()) {
4037 QualType ElTy = MT->getElementType();
4039 for (
unsigned Row = 0; Row < Work.getMatrixNumRows() && Populated < Size;
4041 for (
unsigned Col = 0;
4042 Col < Work.getMatrixNumColumns() && Populated < Size; Col++) {
4043 Elements.push_back(Work.getMatrixElt(Row, Col));
4044 Types.push_back(ElTy);
4050 if (Work.isArray()) {
4054 for (int64_t I = Work.getArraySize() - 1; I > -1; --I) {
4055 WorkList.emplace_back(Work.getArrayInitializedElt(I), ElTy);
4060 if (Work.isStruct()) {
4068 if (FD->isUnnamedBitField())
4070 ReverseList.emplace_back(Work.getStructField(FD->getFieldIndex()),
4074 std::reverse(ReverseList.begin(), ReverseList.end());
4075 llvm::append_range(WorkList, ReverseList);
4078 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4079 if (CXXRD->getNumBases() > 0) {
4080 assert(CXXRD->getNumBases() == 1);
4085 if (!
Base.isStruct())
4093 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
4102struct CompleteObject {
4104 APValue::LValueBase
Base;
4114 bool mayAccessMutableMembers(EvalInfo &Info,
AccessKinds AK)
const {
4125 if (!Info.getLangOpts().CPlusPlus14 &&
4126 AK != AccessKinds::AK_IsWithinLifetime)
4131 explicit operator bool()
const {
return !
Type.isNull(); }
4136 bool IsMutable =
false) {
4150template <
typename Sub
objectHandler>
4151static typename SubobjectHandler::result_type
4153 const SubobjectDesignator &Sub, SubobjectHandler &handler) {
4156 return handler.failed();
4157 if (Sub.isOnePastTheEnd() || Sub.isMostDerivedAnUnsizedArray()) {
4158 if (Info.getLangOpts().CPlusPlus11)
4159 Info.FFDiag(E, Sub.isOnePastTheEnd()
4160 ? diag::note_constexpr_access_past_end
4161 : diag::note_constexpr_access_unsized_array)
4162 << handler.AccessKind;
4165 return handler.failed();
4171 const FieldDecl *VolatileField =
nullptr;
4174 for (
unsigned I = 0, N = Sub.Entries.size(); ; ++I) {
4185 if (!Info.checkingPotentialConstantExpression()) {
4186 Info.FFDiag(E, diag::note_constexpr_access_uninit)
4191 return handler.failed();
4199 Info.isEvaluatingCtorDtor(
4200 Obj.Base,
ArrayRef(Sub.Entries.begin(), Sub.Entries.begin() + I)) !=
4201 ConstructionPhase::None) {
4202 ObjType = Info.Ctx.getCanonicalType(ObjType);
4211 if (Info.getLangOpts().CPlusPlus) {
4215 if (VolatileField) {
4218 Decl = VolatileField;
4221 Loc = VD->getLocation();
4228 Info.FFDiag(E, diag::note_constexpr_access_volatile_obj, 1)
4229 << handler.AccessKind << DiagKind <<
Decl;
4230 Info.Note(Loc, diag::note_constexpr_volatile_here) << DiagKind;
4232 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
4234 return handler.failed();
4242 !Obj.mayAccessMutableMembers(Info, handler.AccessKind) &&
4244 return handler.failed();
4248 if (!handler.found(*O, ObjType, Obj.Base))
4260 LastField =
nullptr;
4263 const ArrayType *AT = Info.Ctx.getAsArrayType(ObjType);
4265 "vla in literal type?");
4266 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4267 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT);
4268 CAT && CAT->
getSize().ule(Index)) {
4271 if (Info.getLangOpts().CPlusPlus11)
4272 Info.FFDiag(E, diag::note_constexpr_access_past_end)
4273 << handler.AccessKind;
4276 return handler.failed();
4283 else if (!
isRead(handler.AccessKind)) {
4284 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT);
4286 return handler.failed();
4294 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4296 if (Info.getLangOpts().CPlusPlus11)
4297 Info.FFDiag(E, diag::note_constexpr_access_past_end)
4298 << handler.AccessKind;
4301 return handler.failed();
4307 assert(I == N - 1 &&
"extracting subobject of scalar?");
4317 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4318 unsigned NumElements = VT->getNumElements();
4319 if (Index == NumElements) {
4320 if (Info.getLangOpts().CPlusPlus11)
4321 Info.FFDiag(E, diag::note_constexpr_access_past_end)
4322 << handler.AccessKind;
4325 return handler.failed();
4328 if (Index > NumElements) {
4329 Info.CCEDiag(E, diag::note_constexpr_array_index)
4330 << Index << 0 << NumElements;
4331 return handler.failed();
4334 ObjType = VT->getElementType();
4335 assert(I == N - 1 &&
"extracting subobject of scalar?");
4338 if (
isRead(handler.AccessKind)) {
4340 return handler.failed();
4344 assert(O->
isVector() &&
"unexpected object during vector element access");
4345 return handler.found(O->
getVectorElt(Index), ObjType, Obj.Base);
4346 }
else if (
const FieldDecl *Field = getAsField(Sub.Entries[I])) {
4347 if (Field->isMutable() &&
4348 !Obj.mayAccessMutableMembers(Info, handler.AccessKind)) {
4349 Info.FFDiag(E, diag::note_constexpr_access_mutable, 1)
4350 << handler.AccessKind << Field;
4351 Info.Note(Field->getLocation(), diag::note_declared_at);
4352 return handler.failed();
4361 if (I == N - 1 && handler.AccessKind ==
AK_Construct) {
4372 Info.FFDiag(E, diag::note_constexpr_access_inactive_union_member)
4373 << handler.AccessKind << Field << !UnionField << UnionField;
4374 return handler.failed();
4383 if (Field->getType().isVolatileQualified())
4384 VolatileField = Field;
4397struct ExtractSubobjectHandler {
4403 typedef bool result_type;
4404 bool failed() {
return false; }
4405 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
4415 bool found(APFloat &
Value, QualType SubobjType) {
4424 const CompleteObject &Obj,
4428 ExtractSubobjectHandler Handler = {Info, E,
Result, AK};
4433struct ModifySubobjectHandler {
4438 typedef bool result_type;
4441 bool checkConst(QualType QT) {
4444 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
4450 bool failed() {
return false; }
4451 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
4452 if (!checkConst(SubobjType))
4455 Subobj.
swap(NewVal);
4459 if (!checkConst(SubobjType))
4461 if (!NewVal.
isInt()) {
4469 bool found(APFloat &
Value, QualType SubobjType) {
4470 if (!checkConst(SubobjType))
4478const AccessKinds ModifySubobjectHandler::AccessKind;
4482 const CompleteObject &Obj,
4483 const SubobjectDesignator &Sub,
4485 ModifySubobjectHandler Handler = { Info, NewVal, E };
4492 const SubobjectDesignator &A,
4493 const SubobjectDesignator &B,
4494 bool &WasArrayIndex) {
4495 unsigned I = 0, N = std::min(A.Entries.size(), B.Entries.size());
4496 for (; I != N; ++I) {
4500 if (A.Entries[I].getAsArrayIndex() != B.Entries[I].getAsArrayIndex()) {
4501 WasArrayIndex =
true;
4509 if (A.Entries[I].getAsBaseOrMember() !=
4510 B.Entries[I].getAsBaseOrMember()) {
4511 WasArrayIndex =
false;
4514 if (
const FieldDecl *FD = getAsField(A.Entries[I]))
4516 ObjType = FD->getType();
4522 WasArrayIndex =
false;
4529 const SubobjectDesignator &A,
4530 const SubobjectDesignator &B) {
4531 if (A.Entries.size() != B.Entries.size())
4534 bool IsArray = A.MostDerivedIsArrayElement;
4535 if (IsArray && A.MostDerivedPathLength != A.Entries.size())
4544 return CommonLength >= A.Entries.size() - IsArray;
4551 if (LVal.InvalidBase) {
4553 return CompleteObject();
4558 Info.FFDiag(E, diag::note_constexpr_dereferencing_null);
4560 Info.FFDiag(E, diag::note_constexpr_access_null) << AK;
4561 return CompleteObject();
4564 CallStackFrame *Frame =
nullptr;
4566 if (LVal.getLValueCallIndex()) {
4567 std::tie(Frame, Depth) =
4568 Info.getCallFrameAndDepth(LVal.getLValueCallIndex());
4570 Info.FFDiag(E, diag::note_constexpr_access_uninit, 1)
4573 return CompleteObject();
4584 if (Info.getLangOpts().CPlusPlus)
4585 Info.FFDiag(E, diag::note_constexpr_access_volatile_type)
4589 return CompleteObject();
4596 if (Info.getLangOpts().CPlusPlus14 && LVal.Base == Info.EvaluatingDecl &&
4600 BaseVal = Info.EvaluatingDeclValue;
4603 if (
auto *GD = dyn_cast<MSGuidDecl>(D)) {
4606 Info.FFDiag(E, diag::note_constexpr_modify_global);
4607 return CompleteObject();
4611 Info.FFDiag(E, diag::note_constexpr_unsupported_layout)
4613 return CompleteObject();
4615 return CompleteObject(LVal.Base, &
V, GD->getType());
4619 if (
auto *GCD = dyn_cast<UnnamedGlobalConstantDecl>(D)) {
4621 Info.FFDiag(E, diag::note_constexpr_modify_global);
4622 return CompleteObject();
4624 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&GCD->getValue()),
4629 if (
auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
4631 Info.FFDiag(E, diag::note_constexpr_modify_global);
4632 return CompleteObject();
4634 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&TPO->getValue()),
4645 const VarDecl *VD = dyn_cast<VarDecl>(D);
4652 return CompleteObject();
4655 bool IsConstant = BaseType.isConstant(Info.Ctx);
4656 bool ConstexprVar =
false;
4657 if (
const auto *VD = dyn_cast_if_present<VarDecl>(
4669 }
else if (Info.getLangOpts().CPlusPlus14 &&
4676 Info.FFDiag(E, diag::note_constexpr_modify_global);
4677 return CompleteObject();
4680 }
else if (Info.getLangOpts().C23 && ConstexprVar) {
4682 return CompleteObject();
4683 }
else if (BaseType->isIntegralOrEnumerationType()) {
4686 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4687 if (Info.getLangOpts().CPlusPlus) {
4688 Info.FFDiag(E, diag::note_constexpr_ltor_non_const_int, 1) << VD;
4689 Info.Note(VD->
getLocation(), diag::note_declared_at);
4693 return CompleteObject();
4695 }
else if (!IsAccess) {
4696 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4697 }
else if ((IsConstant || BaseType->isReferenceType()) &&
4698 Info.checkingPotentialConstantExpression() &&
4699 BaseType->isLiteralType(Info.Ctx) && !VD->
hasDefinition()) {
4701 }
else if (IsConstant) {
4705 if (Info.getLangOpts().CPlusPlus) {
4706 Info.CCEDiag(E, Info.getLangOpts().CPlusPlus11
4707 ? diag::note_constexpr_ltor_non_constexpr
4708 : diag::note_constexpr_ltor_non_integral, 1)
4710 Info.Note(VD->
getLocation(), diag::note_declared_at);
4716 if (Info.getLangOpts().CPlusPlus) {
4717 Info.FFDiag(E, Info.getLangOpts().CPlusPlus11
4718 ? diag::note_constexpr_ltor_non_constexpr
4719 : diag::note_constexpr_ltor_non_integral, 1)
4721 Info.Note(VD->
getLocation(), diag::note_declared_at);
4725 return CompleteObject();
4734 return CompleteObject();
4739 if (!Info.checkingPotentialConstantExpression()) {
4740 Info.FFDiag(E, diag::note_constexpr_access_unknown_variable, 1)
4742 Info.Note(VD->getLocation(), diag::note_declared_at);
4744 return CompleteObject();
4747 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
4749 Info.FFDiag(E, diag::note_constexpr_access_deleted_object) << AK;
4750 return CompleteObject();
4752 return CompleteObject(LVal.Base, &(*Alloc)->Value,
4762 dyn_cast_or_null<MaterializeTemporaryExpr>(
Base)) {
4763 assert(MTE->getStorageDuration() ==
SD_Static &&
4764 "should have a frame for a non-global materialized temporary");
4791 if (!MTE->isUsableInConstantExpressions(Info.Ctx) &&
4794 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4795 Info.FFDiag(E, diag::note_constexpr_access_static_temporary, 1) << AK;
4796 Info.Note(MTE->getExprLoc(), diag::note_constexpr_temporary_here);
4797 return CompleteObject();
4800 BaseVal = MTE->getOrCreateValue(
false);
4801 assert(BaseVal &&
"got reference to unevaluated temporary");
4803 dyn_cast_or_null<CompoundLiteralExpr>(
Base)) {
4819 !CLETy.isConstant(Info.Ctx)) {
4821 Info.Note(CLE->getExprLoc(), diag::note_declared_at);
4822 return CompleteObject();
4825 BaseVal = &CLE->getStaticValue();
4828 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4831 Info.FFDiag(E, diag::note_constexpr_access_unreadable_object)
4834 Info.Ctx.getLValueReferenceType(LValType));
4836 return CompleteObject();
4840 assert(BaseVal &&
"missing value for temporary");
4851 unsigned VisibleDepth = Depth;
4852 if (llvm::isa_and_nonnull<ParmVarDecl>(
4855 if ((Frame && Info.getLangOpts().CPlusPlus14 &&
4856 Info.EvalStatus.HasSideEffects) ||
4857 (
isModification(AK) && VisibleDepth < Info.SpeculativeEvaluationDepth))
4858 return CompleteObject();
4860 return CompleteObject(LVal.getLValueBase(), BaseVal, BaseType);
4879 const LValue &LVal,
APValue &RVal,
4880 bool WantObjectRepresentation =
false) {
4881 if (LVal.Designator.Invalid)
4890 if (
Base && !LVal.getLValueCallIndex() && !
Type.isVolatileQualified()) {
4894 assert(LVal.Designator.Entries.size() <= 1 &&
4895 "Can only read characters from string literals");
4896 if (LVal.Designator.Entries.empty()) {
4903 if (LVal.Designator.isOnePastTheEnd()) {
4904 if (Info.getLangOpts().CPlusPlus11)
4905 Info.FFDiag(Conv, diag::note_constexpr_access_past_end) << AK;
4910 uint64_t CharIndex = LVal.Designator.Entries[0].getAsArrayIndex();
4917 return Obj &&
extractSubobject(Info, Conv, Obj, LVal.Designator, RVal, AK);
4931 LVal.setFrom(Info.Ctx, Val);
4947 if (LVal.Designator.Invalid)
4950 if (!Info.getLangOpts().CPlusPlus14) {
4960struct CompoundAssignSubobjectHandler {
4962 const CompoundAssignOperator *E;
4963 QualType PromotedLHSType;
4969 typedef bool result_type;
4971 bool checkConst(QualType QT) {
4974 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
4980 bool failed() {
return false; }
4981 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
4984 return found(Subobj.
getInt(), SubobjType);
4986 return found(Subobj.
getFloat(), SubobjType);
4993 return foundPointer(Subobj, SubobjType);
4995 return foundVector(Subobj, SubobjType);
4997 Info.FFDiag(E, diag::note_constexpr_access_uninit)
5009 bool foundVector(
APValue &
Value, QualType SubobjType) {
5010 if (!checkConst(SubobjType))
5021 if (!checkConst(SubobjType))
5040 Info.Ctx.getLangOpts());
5043 PromotedLHSType, FValue) &&
5052 bool found(APFloat &
Value, QualType SubobjType) {
5053 return checkConst(SubobjType) &&
5059 bool foundPointer(
APValue &Subobj, QualType SubobjType) {
5060 if (!checkConst(SubobjType))
5063 QualType PointeeType;
5064 if (
const PointerType *PT = SubobjType->
getAs<PointerType>())
5068 (Opcode != BO_Add && Opcode != BO_Sub)) {
5074 if (Opcode == BO_Sub)
5078 LVal.setFrom(Info.Ctx, Subobj);
5081 LVal.moveInto(Subobj);
5087const AccessKinds CompoundAssignSubobjectHandler::AccessKind;
5092 const LValue &LVal,
QualType LValType,
5096 if (LVal.Designator.Invalid)
5099 if (!Info.getLangOpts().CPlusPlus14) {
5105 CompoundAssignSubobjectHandler Handler = { Info, E, PromotedLValType, Opcode,
5107 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
5111struct IncDecSubobjectHandler {
5113 const UnaryOperator *E;
5117 typedef bool result_type;
5119 bool checkConst(QualType QT) {
5122 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
5128 bool failed() {
return false; }
5129 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
5139 return found(Subobj.
getInt(), SubobjType);
5141 return found(Subobj.
getFloat(), SubobjType);
5144 SubobjType->
castAs<ComplexType>()->getElementType()
5148 SubobjType->
castAs<ComplexType>()->getElementType()
5151 return foundPointer(Subobj, SubobjType);
5159 if (!checkConst(SubobjType))
5181 bool WasNegative =
Value.isNegative();
5195 unsigned BitWidth =
Value.getBitWidth();
5196 APSInt ActualValue(
Value.sext(BitWidth + 1),
false);
5197 ActualValue.setBit(BitWidth);
5203 bool found(APFloat &
Value, QualType SubobjType) {
5204 if (!checkConst(SubobjType))
5211 APFloat::opStatus St;
5213 St =
Value.add(One, RM);
5215 St =
Value.subtract(One, RM);
5218 bool foundPointer(
APValue &Subobj, QualType SubobjType) {
5219 if (!checkConst(SubobjType))
5222 QualType PointeeType;
5223 if (
const PointerType *PT = SubobjType->
getAs<PointerType>())
5231 LVal.setFrom(Info.Ctx, Subobj);
5235 LVal.moveInto(Subobj);
5244 if (LVal.Designator.Invalid)
5247 if (!Info.getLangOpts().CPlusPlus14) {
5255 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
5261 if (
Object->getType()->isPointerType() &&
Object->isPRValue())
5267 if (
Object->getType()->isLiteralType(Info.Ctx))
5270 if (
Object->getType()->isRecordType() &&
Object->isPRValue())
5273 Info.FFDiag(
Object, diag::note_constexpr_nonliteral) <<
Object->getType();
5292 bool IncludeMember =
true) {
5299 if (!MemPtr.getDecl()) {
5305 if (MemPtr.isDerivedMember()) {
5312 if (LV.Designator.MostDerivedPathLength + MemPtr.Path.size() >
5313 LV.Designator.Entries.size()) {
5317 unsigned PathLengthToMember =
5318 LV.Designator.Entries.size() - MemPtr.Path.size();
5319 for (
unsigned I = 0, N = MemPtr.Path.size(); I != N; ++I) {
5321 LV.Designator.Entries[PathLengthToMember + I]);
5338 (PathLengthToMember > LV.Designator.MostDerivedPathLength)
5339 ? getAsBaseClass(LV.Designator.Entries[PathLengthToMember - 1])
5341 const CXXRecordDecl *LastMPDecl = MemPtr.getContainingRecord();
5349 PathLengthToMember))
5351 }
else if (!MemPtr.Path.empty()) {
5353 LV.Designator.Entries.reserve(LV.Designator.Entries.size() +
5354 MemPtr.Path.size() + IncludeMember);
5360 assert(RD &&
"member pointer access on non-class-type expression");
5362 for (
unsigned I = 1, N = MemPtr.Path.size(); I != N; ++I) {
5370 MemPtr.getContainingRecord()))
5375 if (IncludeMember) {
5376 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(MemPtr.getDecl())) {
5380 dyn_cast<IndirectFieldDecl>(MemPtr.getDecl())) {
5384 llvm_unreachable(
"can't construct reference to bound member function");
5388 return MemPtr.getDecl();
5394 bool IncludeMember =
true) {
5398 if (Info.noteFailure()) {
5406 BO->
getRHS(), IncludeMember);
5413 SubobjectDesignator &D =
Result.Designator;
5421 auto InvalidCast = [&]() {
5422 if (!Info.checkingPotentialConstantExpression() ||
5423 !
Result.AllowConstexprUnknown) {
5424 Info.CCEDiag(E, diag::note_constexpr_invalid_downcast)
5425 << D.MostDerivedType << TargetQT;
5431 if (D.MostDerivedPathLength + E->
path_size() > D.Entries.size())
5432 return InvalidCast();
5436 unsigned NewEntriesSize = D.Entries.size() - E->
path_size();
5439 if (NewEntriesSize == D.MostDerivedPathLength)
5442 FinalType = getAsBaseClass(D.Entries[NewEntriesSize - 1]);
5444 return InvalidCast();
5459 if (
auto *RD = T->getAsCXXRecordDecl()) {
5460 if (RD->isInvalidDecl()) {
5464 if (RD->isUnion()) {
5473 End = RD->bases_end();
5474 I != End; ++I, ++Index)
5478 for (
const auto *I : RD->fields()) {
5479 if (I->isUnnamedBitField())
5482 I->getType(),
Result.getStructField(I->getFieldIndex()));
5488 dyn_cast_or_null<ConstantArrayType>(T->getAsArrayTypeUnsafe())) {
5490 if (
Result.hasArrayFiller())
5502enum EvalStmtResult {
5531 if (!
Result.Designator.Invalid &&
Result.Designator.isOnePastTheEnd()) {
5549 APValue &Val = Info.CurrentCall->createTemporary(VD, VD->
getType(),
5550 ScopeKind::Block,
Result);
5555 return Info.noteSideEffect();
5576 const DecompositionDecl *DD);
5579 bool EvaluateConditionDecl =
false) {
5581 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
5585 EvaluateConditionDecl && DD)
5595 if (
auto *VD = BD->getHoldingVar())
5603 if (
auto *DD = dyn_cast_if_present<DecompositionDecl>(VD)) {
5612 if (Info.noteSideEffect())
5614 assert(E->
containsErrors() &&
"valid value-dependent expression should never "
5615 "reach invalid code path.");
5622 if (
Cond->isValueDependent())
5624 FullExpressionRAII
Scope(Info);
5631 return Scope.destroy();
5644struct TempVersionRAII {
5645 CallStackFrame &Frame;
5647 TempVersionRAII(CallStackFrame &Frame) : Frame(Frame) {
5648 Frame.pushTempVersion();
5651 ~TempVersionRAII() {
5652 Frame.popTempVersion();
5660 const SwitchCase *SC =
nullptr);
5666 const Stmt *LoopOrSwitch,
5668 EvalStmtResult &ESR) {
5672 if (!IsSwitch && ESR == ESR_Succeeded) {
5677 if (ESR != ESR_Break && ESR != ESR_Continue)
5681 bool CanBreakOrContinue = !IsSwitch || ESR == ESR_Break;
5682 const Stmt *StackTop = Info.BreakContinueStack.back();
5683 if (CanBreakOrContinue && (StackTop ==
nullptr || StackTop == LoopOrSwitch)) {
5684 Info.BreakContinueStack.pop_back();
5685 if (ESR == ESR_Break)
5686 ESR = ESR_Succeeded;
5691 for (BlockScopeRAII *S : Scopes) {
5692 if (!S->destroy()) {
5704 BlockScopeRAII
Scope(Info);
5707 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5716 BlockScopeRAII
Scope(Info);
5723 if (ESR != ESR_Succeeded) {
5724 if (ESR != ESR_Failed && !
Scope.destroy())
5730 FullExpressionRAII CondScope(Info);
5745 if (!CondScope.destroy())
5766 if (LHSValue <=
Value &&
Value <= RHSValue) {
5773 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5777 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5784 llvm_unreachable(
"Should have been converted to Succeeded");
5790 case ESR_CaseNotFound:
5793 Info.FFDiag(
Found->getBeginLoc(),
5794 diag::note_constexpr_stmt_expr_unsupported);
5797 llvm_unreachable(
"Invalid EvalStmtResult!");
5807 Info.CCEDiag(VD->
getLocation(), diag::note_constexpr_static_local)
5817 if (!Info.nextStep(S))
5824 case Stmt::CompoundStmtClass:
5828 case Stmt::LabelStmtClass:
5829 case Stmt::AttributedStmtClass:
5830 case Stmt::DoStmtClass:
5833 case Stmt::CaseStmtClass:
5834 case Stmt::DefaultStmtClass:
5839 case Stmt::IfStmtClass: {
5846 BlockScopeRAII
Scope(Info);
5852 if (ESR != ESR_CaseNotFound) {
5853 assert(ESR != ESR_Succeeded);
5864 if (ESR == ESR_Failed)
5866 if (ESR != ESR_CaseNotFound)
5867 return Scope.destroy() ? ESR : ESR_Failed;
5869 return ESR_CaseNotFound;
5872 if (ESR == ESR_Failed)
5874 if (ESR != ESR_CaseNotFound)
5875 return Scope.destroy() ? ESR : ESR_Failed;
5876 return ESR_CaseNotFound;
5879 case Stmt::WhileStmtClass: {
5880 EvalStmtResult ESR =
5884 if (ESR != ESR_Continue)
5889 case Stmt::ForStmtClass: {
5891 BlockScopeRAII
Scope(Info);
5897 if (ESR != ESR_CaseNotFound) {
5898 assert(ESR != ESR_Succeeded);
5903 EvalStmtResult ESR =
5907 if (ESR != ESR_Continue)
5909 if (
const auto *Inc = FS->
getInc()) {
5910 if (Inc->isValueDependent()) {
5914 FullExpressionRAII IncScope(Info);
5922 case Stmt::DeclStmtClass: {
5926 for (
const auto *D : DS->
decls()) {
5927 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
5930 if (VD->hasLocalStorage() && !VD->getInit())
5938 return ESR_CaseNotFound;
5942 return ESR_CaseNotFound;
5948 if (
const Expr *E = dyn_cast<Expr>(S)) {
5957 FullExpressionRAII
Scope(Info);
5961 return ESR_Succeeded;
5967 case Stmt::NullStmtClass:
5968 return ESR_Succeeded;
5970 case Stmt::DeclStmtClass: {
5972 for (
const auto *D : DS->
decls()) {
5973 const VarDecl *VD = dyn_cast_or_null<VarDecl>(D);
5977 FullExpressionRAII
Scope(Info);
5979 !Info.noteFailure())
5981 if (!
Scope.destroy())
5984 return ESR_Succeeded;
5987 case Stmt::ReturnStmtClass: {
5989 FullExpressionRAII
Scope(Info);
6000 return Scope.destroy() ? ESR_Returned : ESR_Failed;
6003 case Stmt::CompoundStmtClass: {
6004 BlockScopeRAII
Scope(Info);
6007 for (
const auto *BI : CS->
body()) {
6009 if (ESR == ESR_Succeeded)
6011 else if (ESR != ESR_CaseNotFound) {
6012 if (ESR != ESR_Failed && !
Scope.destroy())
6018 return ESR_CaseNotFound;
6019 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
6022 case Stmt::IfStmtClass: {
6026 BlockScopeRAII
Scope(Info);
6029 if (ESR != ESR_Succeeded) {
6030 if (ESR != ESR_Failed && !
Scope.destroy())
6040 if (!Info.InConstantContext)
6048 if (ESR != ESR_Succeeded) {
6049 if (ESR != ESR_Failed && !
Scope.destroy())
6054 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
6057 case Stmt::WhileStmtClass: {
6060 BlockScopeRAII
Scope(Info);
6072 if (ESR != ESR_Continue) {
6073 if (ESR != ESR_Failed && !
Scope.destroy())
6077 if (!
Scope.destroy())
6080 return ESR_Succeeded;
6083 case Stmt::DoStmtClass: {
6090 if (ESR != ESR_Continue)
6099 FullExpressionRAII CondScope(Info);
6101 !CondScope.destroy())
6104 return ESR_Succeeded;
6107 case Stmt::ForStmtClass: {
6109 BlockScopeRAII ForScope(Info);
6112 if (ESR != ESR_Succeeded) {
6113 if (ESR != ESR_Failed && !ForScope.destroy())
6119 BlockScopeRAII IterScope(Info);
6120 bool Continue =
true;
6126 if (!IterScope.destroy())
6134 if (ESR != ESR_Continue) {
6135 if (ESR != ESR_Failed && (!IterScope.destroy() || !ForScope.destroy()))
6140 if (
const auto *Inc = FS->
getInc()) {
6141 if (Inc->isValueDependent()) {
6145 FullExpressionRAII IncScope(Info);
6151 if (!IterScope.destroy())
6154 return ForScope.destroy() ? ESR_Succeeded : ESR_Failed;
6157 case Stmt::CXXForRangeStmtClass: {
6159 BlockScopeRAII
Scope(Info);
6164 if (ESR != ESR_Succeeded) {
6165 if (ESR != ESR_Failed && !
Scope.destroy())
6173 if (ESR != ESR_Succeeded) {
6174 if (ESR != ESR_Failed && !
Scope.destroy())
6186 if (ESR != ESR_Succeeded) {
6187 if (ESR != ESR_Failed && !
Scope.destroy())
6192 if (ESR != ESR_Succeeded) {
6193 if (ESR != ESR_Failed && !
Scope.destroy())
6206 bool Continue =
true;
6207 FullExpressionRAII CondExpr(Info);
6215 BlockScopeRAII InnerScope(Info);
6217 if (ESR != ESR_Succeeded) {
6218 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
6227 if (ESR != ESR_Continue) {
6228 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
6241 if (!InnerScope.destroy())
6245 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
6248 case Stmt::SwitchStmtClass:
6251 case Stmt::ContinueStmtClass:
6252 case Stmt::BreakStmtClass: {
6254 Info.BreakContinueStack.push_back(B->getNamedLoopOrSwitch());
6258 case Stmt::LabelStmtClass:
6261 case Stmt::AttributedStmtClass: {
6263 const auto *SS = AS->getSubStmt();
6264 MSConstexprContextRAII ConstexprContext(
6268 auto LO = Info.Ctx.getLangOpts();
6269 if (LO.CXXAssumptions && !LO.MSVCCompat) {
6270 for (
auto *
Attr : AS->getAttrs()) {
6271 auto *AA = dyn_cast<CXXAssumeAttr>(
Attr);
6275 auto *Assumption = AA->getAssumption();
6276 if (Assumption->isValueDependent())
6279 if (Assumption->HasSideEffects(Info.Ctx))
6286 Info.CCEDiag(Assumption->getExprLoc(),
6287 diag::note_constexpr_assumption_failed);
6296 case Stmt::CaseStmtClass:
6297 case Stmt::DefaultStmtClass:
6299 case Stmt::CXXTryStmtClass:
6311 bool IsValueInitialization) {
6318 if (!CD->
isConstexpr() && !IsValueInitialization) {
6319 if (Info.getLangOpts().CPlusPlus11) {
6322 Info.CCEDiag(Loc, diag::note_constexpr_invalid_function, 1)
6324 Info.Note(CD->
getLocation(), diag::note_declared_at);
6326 Info.CCEDiag(Loc, diag::note_invalid_subexpr_in_const_expr);
6340 if (Info.checkingPotentialConstantExpression() && !
Definition &&
6348 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6357 Info.CCEDiag(CallLoc, diag::note_constexpr_virtual_call);
6360 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6366 (
Definition->isConstexpr() || (Info.CurrentCall->CanEvalMSConstexpr &&
6376 StringRef Name = DiagDecl->
getName();
6378 Name ==
"__assert_rtn" || Name ==
"__assert_fail" || Name ==
"_wassert";
6380 Info.FFDiag(CallLoc, diag::note_constexpr_assert_failed);
6385 if (Info.getLangOpts().CPlusPlus11) {
6388 auto *CD = dyn_cast<CXXConstructorDecl>(DiagDecl);
6389 if (CD && CD->isInheritingConstructor()) {
6390 auto *Inherited = CD->getInheritedConstructor().getConstructor();
6391 if (!Inherited->isConstexpr())
6392 DiagDecl = CD = Inherited;
6398 if (CD && CD->isInheritingConstructor())
6399 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_inhctor, 1)
6400 << CD->getInheritedConstructor().getConstructor()->getParent();
6402 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_function, 1)
6404 Info.Note(DiagDecl->
getLocation(), diag::note_declared_at);
6406 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6412struct CheckDynamicTypeHandler {
6414 typedef bool result_type;
6415 bool failed() {
return false; }
6416 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
6419 bool found(
APSInt &
Value, QualType SubobjType) {
return true; }
6420 bool found(APFloat &
Value, QualType SubobjType) {
return true; }
6428 if (
This.Designator.Invalid)
6440 if (
This.Designator.isOnePastTheEnd() ||
6441 This.Designator.isMostDerivedAnUnsizedArray()) {
6442 Info.FFDiag(E,
This.Designator.isOnePastTheEnd()
6443 ? diag::note_constexpr_access_past_end
6444 : diag::note_constexpr_access_unsized_array)
6447 }
else if (Polymorphic) {
6450 if (!Info.checkingPotentialConstantExpression() ||
6451 !
This.AllowConstexprUnknown) {
6455 Info.Ctx.getLValueReferenceType(
This.Designator.getType(Info.Ctx));
6456 Info.FFDiag(E, diag::note_constexpr_polymorphic_unknown_dynamic_type)
6464 CheckDynamicTypeHandler Handler{AK};
6487 unsigned PathLength) {
6488 assert(PathLength >=
Designator.MostDerivedPathLength && PathLength <=
6489 Designator.Entries.size() &&
"invalid path length");
6490 return (PathLength ==
Designator.MostDerivedPathLength)
6491 ?
Designator.MostDerivedType->getAsCXXRecordDecl()
6492 : getAsBaseClass(
Designator.Entries[PathLength - 1]);
6505 return std::nullopt;
6507 if (
This.Designator.Invalid)
6508 return std::nullopt;
6517 This.Designator.MostDerivedType->getAsCXXRecordDecl();
6518 if (!Class || Class->getNumVBases()) {
6520 return std::nullopt;
6528 for (
unsigned PathLength =
This.Designator.MostDerivedPathLength;
6529 PathLength <= Path.size(); ++PathLength) {
6530 switch (Info.isEvaluatingCtorDtor(
This.getLValueBase(),
6531 Path.slice(0, PathLength))) {
6532 case ConstructionPhase::Bases:
6533 case ConstructionPhase::DestroyingBases:
6538 case ConstructionPhase::None:
6539 case ConstructionPhase::AfterBases:
6540 case ConstructionPhase::AfterFields:
6541 case ConstructionPhase::Destroying:
6553 return std::nullopt;
6571 unsigned PathLength = DynType->PathLength;
6572 for (; PathLength <=
This.Designator.Entries.size(); ++PathLength) {
6575 Found->getCorrespondingMethodDeclaredInClass(Class,
false);
6585 if (Callee->isPureVirtual()) {
6586 Info.FFDiag(E, diag::note_constexpr_pure_virtual_call, 1) << Callee;
6587 Info.Note(Callee->getLocation(), diag::note_declared_at);
6593 if (!Info.Ctx.hasSameUnqualifiedType(Callee->getReturnType(),
6594 Found->getReturnType())) {
6595 CovariantAdjustmentPath.push_back(Callee->getReturnType());
6596 for (
unsigned CovariantPathLength = PathLength + 1;
6597 CovariantPathLength !=
This.Designator.Entries.size();
6598 ++CovariantPathLength) {
6602 Found->getCorrespondingMethodDeclaredInClass(NextClass,
false);
6603 if (
Next && !Info.Ctx.hasSameUnqualifiedType(
6604 Next->getReturnType(), CovariantAdjustmentPath.back()))
6605 CovariantAdjustmentPath.push_back(
Next->getReturnType());
6607 if (!Info.Ctx.hasSameUnqualifiedType(
Found->getReturnType(),
6608 CovariantAdjustmentPath.back()))
6609 CovariantAdjustmentPath.push_back(
Found->getReturnType());
6625 assert(
Result.isLValue() &&
6626 "unexpected kind of APValue for covariant return");
6627 if (
Result.isNullPointer())
6631 LVal.setFrom(Info.Ctx,
Result);
6633 const CXXRecordDecl *OldClass = Path[0]->getPointeeCXXRecordDecl();
6634 for (
unsigned I = 1; I != Path.size(); ++I) {
6635 const CXXRecordDecl *NewClass = Path[I]->getPointeeCXXRecordDecl();
6636 assert(OldClass && NewClass &&
"unexpected kind of covariant return");
6637 if (OldClass != NewClass &&
6640 OldClass = NewClass;
6652 auto *BaseClass = BaseSpec.getType()->getAsCXXRecordDecl();
6654 return BaseSpec.getAccessSpecifier() ==
AS_public;
6656 llvm_unreachable(
"Base is not a direct base of Derived");
6666 SubobjectDesignator &D = Ptr.Designator;
6672 if (Ptr.isNullPointer() && !E->
isGLValue())
6678 std::optional<DynamicType> DynType =
6690 assert(
C &&
"dynamic_cast target is not void pointer nor class");
6698 Ptr.setNull(Info.Ctx, E->
getType());
6705 DynType->Type->isDerivedFrom(
C)))
6707 else if (!Paths || Paths->begin() == Paths->end())
6709 else if (Paths->isAmbiguous(CQT))
6712 assert(Paths->front().Access !=
AS_public &&
"why did the cast fail?");
6715 Info.FFDiag(E, diag::note_constexpr_dynamic_cast_to_reference_failed)
6716 << DiagKind << Ptr.Designator.getType(Info.Ctx)
6717 << Info.Ctx.getCanonicalTagType(DynType->Type)
6725 for (
int PathLength = Ptr.Designator.Entries.size();
6726 PathLength >= (
int)DynType->PathLength; --PathLength) {
6731 if (PathLength > (
int)DynType->PathLength &&
6734 return RuntimeCheckFailed(
nullptr);
6741 if (DynType->Type->isDerivedFrom(
C, Paths) && !Paths.
isAmbiguous(CQT) &&
6754 return RuntimeCheckFailed(&Paths);
6758struct StartLifetimeOfUnionMemberHandler {
6760 const Expr *LHSExpr;
6761 const FieldDecl *
Field;
6763 bool Failed =
false;
6766 typedef bool result_type;
6767 bool failed() {
return Failed; }
6768 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
6783 }
else if (DuringInit) {
6787 Info.FFDiag(LHSExpr,
6788 diag::note_constexpr_union_member_change_during_init);
6797 llvm_unreachable(
"wrong value kind for union object");
6799 bool found(APFloat &
Value, QualType SubobjType) {
6800 llvm_unreachable(
"wrong value kind for union object");
6805const AccessKinds StartLifetimeOfUnionMemberHandler::AccessKind;
6812 const Expr *LHSExpr,
6813 const LValue &LHS) {
6814 if (LHS.InvalidBase || LHS.Designator.Invalid)
6820 unsigned PathLength = LHS.Designator.Entries.size();
6821 for (
const Expr *E = LHSExpr; E !=
nullptr;) {
6823 if (
auto *ME = dyn_cast<MemberExpr>(E)) {
6824 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
6827 if (!FD || FD->getType()->isReferenceType())
6831 if (FD->getParent()->isUnion()) {
6836 FD->getType()->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
6837 if (!RD || RD->hasTrivialDefaultConstructor())
6838 UnionPathLengths.push_back({PathLength - 1, FD});
6844 LHS.Designator.Entries[PathLength]
6845 .getAsBaseOrMember().getPointer()));
6849 }
else if (
auto *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
6851 auto *
Base = ASE->getBase()->IgnoreImplicit();
6852 if (!
Base->getType()->isArrayType())
6858 }
else if (
auto *ICE = dyn_cast<ImplicitCastExpr>(E)) {
6861 if (ICE->getCastKind() == CK_NoOp)
6863 if (ICE->getCastKind() != CK_DerivedToBase &&
6864 ICE->getCastKind() != CK_UncheckedDerivedToBase)
6868 if (Elt->isVirtual()) {
6877 LHS.Designator.Entries[PathLength]
6878 .getAsBaseOrMember().getPointer()));
6888 if (UnionPathLengths.empty())
6893 CompleteObject Obj =
6897 for (std::pair<unsigned, const FieldDecl *> LengthAndField :
6898 llvm::reverse(UnionPathLengths)) {
6900 SubobjectDesignator D = LHS.Designator;
6901 D.truncate(Info.Ctx, LHS.Base, LengthAndField.first);
6903 bool DuringInit = Info.isEvaluatingCtorDtor(LHS.Base, D.Entries) ==
6904 ConstructionPhase::AfterBases;
6905 StartLifetimeOfUnionMemberHandler StartLifetime{
6906 Info, LHSExpr, LengthAndField.second, DuringInit};
6915 CallRef
Call, EvalInfo &Info,
bool NonNull =
false,
6916 APValue **EvaluatedArg =
nullptr) {
6923 APValue &
V = PVD ? Info.CurrentCall->createParam(
Call, PVD, LV)
6924 : Info.CurrentCall->createTemporary(Arg, Arg->
getType(),
6925 ScopeKind::Call, LV);
6931 if (
NonNull &&
V.isLValue() &&
V.isNullPointer()) {
6932 Info.CCEDiag(Arg, diag::note_non_null_attribute_failed);
6945 bool RightToLeft =
false,
6946 LValue *ObjectArg =
nullptr) {
6948 llvm::SmallBitVector ForbiddenNullArgs;
6949 if (Callee->hasAttr<NonNullAttr>()) {
6950 ForbiddenNullArgs.resize(Args.size());
6951 for (
const auto *
Attr : Callee->specific_attrs<NonNullAttr>()) {
6952 if (!
Attr->args_size()) {
6953 ForbiddenNullArgs.set();
6956 for (
auto Idx :
Attr->args()) {
6957 unsigned ASTIdx = Idx.getASTIndex();
6958 if (ASTIdx >= Args.size())
6960 ForbiddenNullArgs[ASTIdx] =
true;
6964 for (
unsigned I = 0; I < Args.size(); I++) {
6965 unsigned Idx = RightToLeft ? Args.size() - I - 1 : I;
6967 Idx < Callee->getNumParams() ? Callee->getParamDecl(Idx) :
nullptr;
6968 bool NonNull = !ForbiddenNullArgs.empty() && ForbiddenNullArgs[Idx];
6973 if (!Info.noteFailure())
6978 ObjectArg->setFrom(Info.Ctx, *That);
6987 bool CopyObjectRepresentation) {
6989 CallStackFrame *Frame = Info.CurrentCall;
6990 APValue *RefValue = Info.getParamSlot(Frame->Arguments, Param);
6998 RefLValue.setFrom(Info.Ctx, *RefValue);
7001 CopyObjectRepresentation);
7007 const LValue *ObjectArg,
const Expr *E,
7009 const Stmt *Body, EvalInfo &Info,
7011 if (!Info.CheckCallLimit(CallLoc))
7040 ObjectArg->moveInto(
Result);
7049 if (!Info.checkingPotentialConstantExpression())
7051 Frame.LambdaThisCaptureField);
7054 StmtResult Ret = {
Result, ResultSlot};
7056 if (ESR == ESR_Succeeded) {
7057 if (Callee->getReturnType()->isVoidType())
7059 Info.FFDiag(Callee->getEndLoc(), diag::note_constexpr_no_return);
7061 return ESR == ESR_Returned;
7070 if (!Info.CheckCallLimit(CallLoc))
7075 Info.FFDiag(CallLoc, diag::note_constexpr_virtual_base) << RD;
7079 EvalInfo::EvaluatingConstructorRAII EvalObj(
7081 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries},
7088 StmtResult Ret = {RetVal,
nullptr};
7093 if ((*I)->getInit()->isValueDependent()) {
7097 FullExpressionRAII InitScope(Info);
7099 !InitScope.destroy())
7122 if (!
Result.hasValue()) {
7135 BlockScopeRAII LifetimeExtendedScope(Info);
7138 unsigned BasesSeen = 0;
7143 auto SkipToField = [&](
FieldDecl *FD,
bool Indirect) {
7148 assert(Indirect &&
"fields out of order?");
7154 assert(FieldIt != RD->
field_end() &&
"missing field?");
7155 if (!FieldIt->isUnnamedBitField())
7158 Result.getStructField(FieldIt->getFieldIndex()));
7163 LValue Subobject =
This;
7164 LValue SubobjectParent =
This;
7169 if (I->isBaseInitializer()) {
7170 QualType BaseType(I->getBaseClass(), 0);
7174 assert(!BaseIt->
isVirtual() &&
"virtual base for literal type");
7175 assert(Info.Ctx.hasSameUnqualifiedType(BaseIt->
getType(), BaseType) &&
7176 "base class initializers not in expected order");
7180 BaseType->getAsCXXRecordDecl(), &Layout))
7183 }
else if ((FD = I->getMember())) {
7190 SkipToField(FD,
false);
7196 auto IndirectFieldChain = IFD->chain();
7197 for (
auto *
C : IndirectFieldChain) {
7206 (
Value->isUnion() &&
7219 if (
C == IndirectFieldChain.back())
7220 SubobjectParent = Subobject;
7226 if (
C == IndirectFieldChain.front() && !RD->
isUnion())
7227 SkipToField(FD,
true);
7232 llvm_unreachable(
"unknown base initializer kind");
7239 if (
Init->isValueDependent()) {
7243 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &SubobjectParent,
7245 FullExpressionRAII InitScope(Info);
7251 if (!Info.noteFailure())
7260 if (!Info.noteFailure())
7268 if (I->isBaseInitializer() && BasesSeen == RD->
getNumBases())
7269 EvalObj.finishedConstructingBases();
7274 for (; FieldIt != RD->
field_end(); ++FieldIt) {
7275 if (!FieldIt->isUnnamedBitField())
7278 Result.getStructField(FieldIt->getFieldIndex()));
7282 EvalObj.finishedConstructingFields();
7286 LifetimeExtendedScope.destroy();
7293 CallScopeRAII CallScope(Info);
7299 CallScope.destroy();
7309 if (
Value.isAbsent() && !T->isNullPtrType()) {
7311 This.moveInto(Printable);
7313 diag::note_constexpr_destroy_out_of_lifetime)
7314 << Printable.
getAsString(Info.Ctx, Info.Ctx.getLValueReferenceType(T));
7330 LValue ElemLV =
This;
7331 ElemLV.addArray(Info, &LocE, CAT);
7338 if (Size && Size >
Value.getArrayInitializedElts())
7343 for (Size =
Value.getArraySize(); Size != 0; --Size) {
7344 APValue &Elem =
Value.getArrayInitializedElt(Size - 1);
7357 if (T.isDestructedType()) {
7359 diag::note_constexpr_unsupported_destruction)
7369 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_virtual_base) << RD;
7394 if (!Info.CheckCallLimit(CallRange.
getBegin()))
7403 CallStackFrame Frame(Info, CallRange,
Definition, &
This,
nullptr,
7408 EvalInfo::EvaluatingDestructorRAII EvalObj(
7410 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries});
7411 if (!EvalObj.DidInsert) {
7418 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_double_destroy);
7425 StmtResult Ret = {RetVal,
nullptr};
7438 for (
const FieldDecl *FD : llvm::reverse(Fields)) {
7439 if (FD->isUnnamedBitField())
7442 LValue Subobject =
This;
7446 APValue *SubobjectValue = &
Value.getStructField(FD->getFieldIndex());
7453 EvalObj.startedDestroyingBases();
7460 LValue Subobject =
This;
7462 BaseType->getAsCXXRecordDecl(), &Layout))
7465 APValue *SubobjectValue = &
Value.getStructBase(BasesLeft);
7470 assert(BasesLeft == 0 &&
"NumBases was wrong?");
7478struct DestroyObjectHandler {
7484 typedef bool result_type;
7485 bool failed() {
return false; }
7486 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
7491 Info.FFDiag(E, diag::note_constexpr_destroy_complex_elem);
7494 bool found(APFloat &
Value, QualType SubobjType) {
7495 Info.FFDiag(E, diag::note_constexpr_destroy_complex_elem);
7516 if (Info.EvalStatus.HasSideEffects)
7527 if (Info.checkingPotentialConstantExpression() ||
7528 Info.SpeculativeEvaluationDepth)
7532 auto Caller = Info.getStdAllocatorCaller(
"allocate");
7534 Info.FFDiag(E->
getExprLoc(), Info.getLangOpts().CPlusPlus20
7535 ? diag::note_constexpr_new_untyped
7536 : diag::note_constexpr_new);
7540 QualType ElemType = Caller.ElemType;
7543 diag::note_constexpr_new_not_complete_object_type)
7551 bool IsNothrow =
false;
7552 for (
unsigned I = 1, N = E->
getNumArgs(); I != N; ++I) {
7560 APInt Size, Remainder;
7561 APInt ElemSizeAP(ByteSize.getBitWidth(), ElemSize.
getQuantity());
7562 APInt::udivrem(ByteSize, ElemSizeAP, Size, Remainder);
7563 if (Remainder != 0) {
7565 Info.FFDiag(E->
getExprLoc(), diag::note_constexpr_operator_new_bad_size)
7566 << ByteSize <<
APSInt(ElemSizeAP,
true) << ElemType;
7570 if (!Info.CheckArraySize(E->
getBeginLoc(), ByteSize.getActiveBits(),
7571 Size.getZExtValue(), !IsNothrow)) {
7579 QualType AllocType = Info.Ctx.getConstantArrayType(
7581 APValue *Val = Info.createHeapAlloc(Caller.Call, AllocType,
Result);
7590 return DD->isVirtual();
7597 return DD->isVirtual() ? DD->getOperatorDelete() :
nullptr;
7608 DynAlloc::Kind DeallocKind) {
7609 auto PointerAsString = [&] {
7610 return Pointer.toString(Info.Ctx, Info.Ctx.VoidPtrTy);
7615 Info.FFDiag(E, diag::note_constexpr_delete_not_heap_alloc)
7616 << PointerAsString();
7619 return std::nullopt;
7622 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
7624 Info.FFDiag(E, diag::note_constexpr_double_delete);
7625 return std::nullopt;
7628 if (DeallocKind != (*Alloc)->getKind()) {
7630 Info.FFDiag(E, diag::note_constexpr_new_delete_mismatch)
7631 << DeallocKind << (*Alloc)->getKind() << AllocType;
7633 return std::nullopt;
7636 bool Subobject =
false;
7637 if (DeallocKind == DynAlloc::New) {
7638 Subobject =
Pointer.Designator.MostDerivedPathLength != 0 ||
7639 Pointer.Designator.isOnePastTheEnd();
7641 Subobject =
Pointer.Designator.Entries.size() != 1 ||
7642 Pointer.Designator.Entries[0].getAsArrayIndex() != 0;
7645 Info.FFDiag(E, diag::note_constexpr_delete_subobject)
7646 << PointerAsString() <<
Pointer.Designator.isOnePastTheEnd();
7647 return std::nullopt;
7655 if (Info.checkingPotentialConstantExpression() ||
7656 Info.SpeculativeEvaluationDepth)
7660 if (!Info.getStdAllocatorCaller(
"deallocate")) {
7668 for (
unsigned I = 1, N = E->
getNumArgs(); I != N; ++I)
7671 if (
Pointer.Designator.Invalid)
7676 if (
Pointer.isNullPointer()) {
7677 Info.CCEDiag(E->
getExprLoc(), diag::note_constexpr_deallocate_null);
7693class BitCastBuffer {
7699 SmallVector<std::optional<unsigned char>, 32> Bytes;
7701 static_assert(std::numeric_limits<unsigned char>::digits >= 8,
7702 "Need at least 8 bit unsigned char");
7704 bool TargetIsLittleEndian;
7707 BitCastBuffer(CharUnits Width,
bool TargetIsLittleEndian)
7708 : Bytes(Width.getQuantity()),
7709 TargetIsLittleEndian(TargetIsLittleEndian) {}
7711 [[nodiscard]]
bool readObject(CharUnits Offset, CharUnits Width,
7712 SmallVectorImpl<unsigned char> &Output)
const {
7713 for (CharUnits I = Offset, E = Offset + Width; I != E; ++I) {
7716 if (!Bytes[I.getQuantity()])
7718 Output.push_back(*Bytes[I.getQuantity()]);
7720 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
7721 std::reverse(Output.begin(), Output.end());
7725 void writeObject(CharUnits Offset, SmallVectorImpl<unsigned char> &Input) {
7726 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
7727 std::reverse(Input.begin(), Input.end());
7730 for (
unsigned char Byte : Input) {
7731 assert(!Bytes[Offset.
getQuantity() + Index] &&
"overwriting a byte?");
7737 size_t size() {
return Bytes.size(); }
7742class APValueToBufferConverter {
7744 BitCastBuffer Buffer;
7747 APValueToBufferConverter(EvalInfo &Info, CharUnits ObjectWidth,
7750 Buffer(ObjectWidth, Info.Ctx.getTargetInfo().isLittleEndian()),
7753 bool visit(
const APValue &Val, QualType Ty) {
7758 bool visit(
const APValue &Val, QualType Ty, CharUnits Offset) {
7759 assert((
size_t)Offset.
getQuantity() <= Buffer.size());
7772 return visitInt(Val.
getInt(), Ty, Offset);
7774 return visitFloat(Val.
getFloat(), Ty, Offset);
7776 return visitArray(Val, Ty, Offset);
7778 return visitRecord(Val, Ty, Offset);
7780 return visitVector(Val, Ty, Offset);
7784 return visitComplex(Val, Ty, Offset);
7794 diag::note_constexpr_bit_cast_unsupported_type)
7799 llvm_unreachable(
"Unhandled APValue::ValueKind");
7802 bool visitRecord(
const APValue &Val, QualType Ty, CharUnits Offset) {
7804 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD);
7807 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
7808 for (
size_t I = 0, E = CXXRD->getNumBases(); I != E; ++I) {
7809 const CXXBaseSpecifier &BS = CXXRD->bases_begin()[I];
7814 if (!
Base.isStruct())
7817 if (!visitRecord(Base, BS.
getType(),
7824 unsigned FieldIdx = 0;
7825 for (FieldDecl *FD : RD->
fields()) {
7826 if (FD->isBitField()) {
7828 diag::note_constexpr_bit_cast_unsupported_bitfield);
7834 assert(FieldOffsetBits % Info.Ctx.getCharWidth() == 0 &&
7835 "only bit-fields can have sub-char alignment");
7836 CharUnits FieldOffset =
7837 Info.Ctx.toCharUnitsFromBits(FieldOffsetBits) + Offset;
7838 QualType FieldTy = FD->getType();
7847 bool visitArray(
const APValue &Val, QualType Ty, CharUnits Offset) {
7853 CharUnits ElemWidth = Info.Ctx.getTypeSizeInChars(CAT->
getElementType());
7857 for (
unsigned I = 0; I != NumInitializedElts; ++I) {
7859 if (!visit(SubObj, CAT->
getElementType(), Offset + I * ElemWidth))
7866 for (
unsigned I = NumInitializedElts; I != ArraySize; ++I) {
7867 if (!visit(Filler, CAT->
getElementType(), Offset + I * ElemWidth))
7875 bool visitComplex(
const APValue &Val, QualType Ty, CharUnits Offset) {
7876 const ComplexType *ComplexTy = Ty->
castAs<ComplexType>();
7878 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
7883 Offset + (0 * EltSizeChars)))
7886 Offset + (1 * EltSizeChars)))
7890 Offset + (0 * EltSizeChars)))
7893 Offset + (1 * EltSizeChars)))
7900 bool visitVector(
const APValue &Val, QualType Ty, CharUnits Offset) {
7901 const VectorType *VTy = Ty->
castAs<VectorType>();
7914 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
7916 llvm::APInt Res = llvm::APInt::getZero(NElts);
7917 for (
unsigned I = 0; I < NElts; ++I) {
7919 assert(EltAsInt.isUnsigned() && EltAsInt.getBitWidth() == 1 &&
7920 "bool vector element must be 1-bit unsigned integer!");
7922 Res.insertBits(EltAsInt, BigEndian ? (NElts - I - 1) : I);
7925 SmallVector<uint8_t, 8> Bytes(NElts / 8);
7926 llvm::StoreIntToMemory(Res, &*Bytes.begin(), NElts / 8);
7927 Buffer.writeObject(Offset, Bytes);
7931 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
7932 for (
unsigned I = 0; I < NElts; ++I) {
7933 if (!visit(Val.
getVectorElt(I), EltTy, Offset + I * EltSizeChars))
7941 bool visitInt(
const APSInt &Val, QualType Ty, CharUnits Offset) {
7942 APSInt AdjustedVal = Val;
7943 unsigned Width = AdjustedVal.getBitWidth();
7945 Width = Info.Ctx.getTypeSize(Ty);
7946 AdjustedVal = AdjustedVal.extend(Width);
7949 SmallVector<uint8_t, 8> Bytes(Width / 8);
7950 llvm::StoreIntToMemory(AdjustedVal, &*Bytes.begin(), Width / 8);
7951 Buffer.writeObject(Offset, Bytes);
7955 bool visitFloat(
const APFloat &Val, QualType Ty, CharUnits Offset) {
7956 APSInt AsInt(Val.bitcastToAPInt());
7957 return visitInt(AsInt, Ty, Offset);
7961 static std::optional<BitCastBuffer>
7963 CharUnits DstSize = Info.Ctx.getTypeSizeInChars(BCE->
getType());
7964 APValueToBufferConverter Converter(Info, DstSize, BCE);
7966 return std::nullopt;
7967 return Converter.Buffer;
7972class BufferToAPValueConverter {
7974 const BitCastBuffer &Buffer;
7977 BufferToAPValueConverter(EvalInfo &Info,
const BitCastBuffer &Buffer,
7979 : Info(Info), Buffer(Buffer), BCE(BCE) {}
7984 std::nullopt_t unsupportedType(QualType Ty) {
7986 diag::note_constexpr_bit_cast_unsupported_type)
7988 return std::nullopt;
7991 std::nullopt_t unrepresentableValue(QualType Ty,
const APSInt &Val) {
7993 diag::note_constexpr_bit_cast_unrepresentable_value)
7995 return std::nullopt;
7998 std::optional<APValue> visit(
const BuiltinType *T, CharUnits Offset,
7999 const EnumType *EnumSugar =
nullptr) {
8001 uint64_t NullValue = Info.Ctx.getTargetNullPointerValue(QualType(T, 0));
8002 return APValue((Expr *)
nullptr,
8004 APValue::NoLValuePath{},
true);
8007 CharUnits
SizeOf = Info.Ctx.getTypeSizeInChars(T);
8013 const llvm::fltSemantics &Semantics =
8014 Info.Ctx.getFloatTypeSemantics(QualType(T, 0));
8015 unsigned NumBits = llvm::APFloatBase::getSizeInBits(Semantics);
8016 assert(NumBits % 8 == 0);
8022 SmallVector<uint8_t, 8> Bytes;
8023 if (!Buffer.readObject(Offset,
SizeOf, Bytes)) {
8026 bool IsStdByte = EnumSugar && EnumSugar->isStdByteType();
8030 if (!IsStdByte && !IsUChar) {
8031 QualType DisplayType(EnumSugar ? (
const Type *)EnumSugar : T, 0);
8033 diag::note_constexpr_bit_cast_indet_dest)
8034 << DisplayType << Info.Ctx.getLangOpts().CharIsSigned;
8035 return std::nullopt;
8041 APSInt Val(
SizeOf.getQuantity() * Info.Ctx.getCharWidth(),
true);
8042 llvm::LoadIntFromMemory(Val, &*Bytes.begin(), Bytes.size());
8047 unsigned IntWidth = Info.Ctx.getIntWidth(QualType(T, 0));
8048 if (IntWidth != Val.getBitWidth()) {
8049 APSInt Truncated = Val.trunc(IntWidth);
8050 if (Truncated.extend(Val.getBitWidth()) != Val)
8051 return unrepresentableValue(QualType(T, 0), Val);
8059 const llvm::fltSemantics &Semantics =
8060 Info.Ctx.getFloatTypeSemantics(QualType(T, 0));
8064 return unsupportedType(QualType(T, 0));
8067 std::optional<APValue> visit(
const RecordType *RTy, CharUnits Offset) {
8068 const RecordDecl *RD = RTy->getAsRecordDecl();
8069 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD);
8071 unsigned NumBases = 0;
8072 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
8073 NumBases = CXXRD->getNumBases();
8078 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
8079 for (
size_t I = 0, E = CXXRD->getNumBases(); I != E; ++I) {
8080 const CXXBaseSpecifier &BS = CXXRD->bases_begin()[I];
8083 std::optional<APValue> SubObj = visitType(
8086 return std::nullopt;
8087 ResultVal.getStructBase(I) = *SubObj;
8092 unsigned FieldIdx = 0;
8093 for (FieldDecl *FD : RD->
fields()) {
8096 if (FD->isBitField()) {
8098 diag::note_constexpr_bit_cast_unsupported_bitfield);
8099 return std::nullopt;
8103 assert(FieldOffsetBits % Info.Ctx.getCharWidth() == 0);
8105 CharUnits FieldOffset =
8108 QualType FieldTy = FD->getType();
8109 std::optional<APValue> SubObj = visitType(FieldTy, FieldOffset);
8111 return std::nullopt;
8112 ResultVal.getStructField(FieldIdx) = *SubObj;
8119 std::optional<APValue> visit(
const EnumType *Ty, CharUnits Offset) {
8120 QualType RepresentationType =
8121 Ty->getDecl()->getDefinitionOrSelf()->getIntegerType();
8122 assert(!RepresentationType.
isNull() &&
8123 "enum forward decl should be caught by Sema");
8124 const auto *AsBuiltin =
8128 return visit(AsBuiltin, Offset, Ty);
8131 std::optional<APValue> visit(
const ConstantArrayType *Ty, CharUnits Offset) {
8133 CharUnits ElementWidth = Info.Ctx.getTypeSizeInChars(Ty->
getElementType());
8135 APValue ArrayValue(APValue::UninitArray(), Size, Size);
8136 for (
size_t I = 0; I !=
Size; ++I) {
8137 std::optional<APValue> ElementValue =
8140 return std::nullopt;
8141 ArrayValue.getArrayInitializedElt(I) = std::move(*ElementValue);
8147 std::optional<APValue> visit(
const ComplexType *Ty, CharUnits Offset) {
8149 CharUnits ElementWidth = Info.Ctx.getTypeSizeInChars(ElementType);
8152 std::optional<APValue> Values[2];
8153 for (
unsigned I = 0; I != 2; ++I) {
8154 Values[I] = visitType(Ty->
getElementType(), Offset + I * ElementWidth);
8156 return std::nullopt;
8160 return APValue(Values[0]->getInt(), Values[1]->getInt());
8161 return APValue(Values[0]->getFloat(), Values[1]->getFloat());
8164 std::optional<APValue> visit(
const VectorType *VTy, CharUnits Offset) {
8170 SmallVector<APValue, 4> Elts;
8171 Elts.reserve(NElts);
8181 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
8183 SmallVector<uint8_t, 8> Bytes;
8184 Bytes.reserve(NElts / 8);
8186 return std::nullopt;
8188 APSInt SValInt(NElts,
true);
8189 llvm::LoadIntFromMemory(SValInt, &*Bytes.begin(), Bytes.size());
8191 for (
unsigned I = 0; I < NElts; ++I) {
8193 SValInt.extractBits(1, (BigEndian ? NElts - I - 1 : I) * EltSize);
8200 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
8201 for (
unsigned I = 0; I < NElts; ++I) {
8202 std::optional<APValue> EltValue =
8203 visitType(EltTy, Offset + I * EltSizeChars);
8205 return std::nullopt;
8206 Elts.push_back(std::move(*EltValue));
8210 return APValue(Elts.data(), Elts.size());
8213 std::optional<APValue> visit(
const Type *Ty, CharUnits Offset) {
8214 return unsupportedType(QualType(Ty, 0));
8217 std::optional<APValue> visitType(QualType Ty, CharUnits Offset) {
8221#define TYPE(Class, Base) \
8223 return visit(cast<Class##Type>(Can.getTypePtr()), Offset);
8224#define ABSTRACT_TYPE(Class, Base)
8225#define NON_CANONICAL_TYPE(Class, Base) \
8227 llvm_unreachable("non-canonical type should be impossible!");
8228#define DEPENDENT_TYPE(Class, Base) \
8231 "dependent types aren't supported in the constant evaluator!");
8232#define NON_CANONICAL_UNLESS_DEPENDENT(Class, Base) \
8234 llvm_unreachable("either dependent or not canonical!");
8235#include "clang/AST/TypeNodes.inc"
8237 llvm_unreachable(
"Unhandled Type::TypeClass");
8242 static std::optional<APValue> convert(EvalInfo &Info, BitCastBuffer &Buffer,
8244 BufferToAPValueConverter Converter(Info, Buffer, BCE);
8249static bool checkBitCastConstexprEligibilityType(SourceLocation Loc,
8250 QualType Ty, EvalInfo *Info,
8251 const ASTContext &Ctx,
8252 bool CheckingDest) {
8255 auto diag = [&](
int Reason) {
8257 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_invalid_type)
8258 << CheckingDest << (Reason == 4) << Reason;
8261 auto note = [&](
int Construct, QualType NoteTy, SourceLocation NoteLoc) {
8263 Info->Note(NoteLoc, diag::note_constexpr_bit_cast_invalid_subtype)
8264 << NoteTy << Construct << Ty;
8278 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(
Record)) {
8279 for (CXXBaseSpecifier &BS : CXXRD->bases())
8280 if (!checkBitCastConstexprEligibilityType(Loc, BS.
getType(), Info, Ctx,
8284 for (FieldDecl *FD :
Record->fields()) {
8285 if (FD->getType()->isReferenceType())
8287 if (!checkBitCastConstexprEligibilityType(Loc, FD->getType(), Info, Ctx,
8289 return note(0, FD->getType(), FD->getBeginLoc());
8295 Info, Ctx, CheckingDest))
8298 if (
const auto *VTy = Ty->
getAs<VectorType>()) {
8310 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_invalid_vector)
8311 << QualType(VTy, 0) << EltSize << NElts << Ctx.
getCharWidth();
8321 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_unsupported_type)
8330static bool checkBitCastConstexprEligibility(EvalInfo *Info,
8331 const ASTContext &Ctx,
8333 bool DestOK = checkBitCastConstexprEligibilityType(
8335 bool SourceOK = DestOK && checkBitCastConstexprEligibilityType(
8341static bool handleRValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
8344 assert(
CHAR_BIT == 8 && Info.Ctx.getTargetInfo().getCharWidth() == 8 &&
8345 "no host or target supports non 8-bit chars");
8347 if (!checkBitCastConstexprEligibility(&Info, Info.Ctx, BCE))
8351 std::optional<BitCastBuffer> Buffer =
8352 APValueToBufferConverter::convert(Info, SourceRValue, BCE);
8357 std::optional<APValue> MaybeDestValue =
8358 BufferToAPValueConverter::convert(Info, *Buffer, BCE);
8359 if (!MaybeDestValue)
8362 DestValue = std::move(*MaybeDestValue);
8366static bool handleLValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
8369 assert(
CHAR_BIT == 8 && Info.Ctx.getTargetInfo().getCharWidth() == 8 &&
8370 "no host or target supports non 8-bit chars");
8372 "LValueToRValueBitcast requires an lvalue operand!");
8374 LValue SourceLValue;
8376 SourceLValue.setFrom(Info.Ctx, SourceValue);
8379 SourceRValue,
true))
8382 return handleRValueToRValueBitCast(Info, DestValue, SourceRValue, BCE);
8385template <
class Derived>
8386class ExprEvaluatorBase
8387 :
public ConstStmtVisitor<Derived, bool> {
8389 Derived &getDerived() {
return static_cast<Derived&
>(*this); }
8390 bool DerivedSuccess(
const APValue &
V,
const Expr *E) {
8391 return getDerived().Success(
V, E);
8393 bool DerivedZeroInitialization(
const Expr *E) {
8394 return getDerived().ZeroInitialization(E);
8400 template<
typename ConditionalOperator>
8401 void CheckPotentialConstantConditional(
const ConditionalOperator *E) {
8402 assert(Info.checkingPotentialConstantExpression());
8405 SmallVector<PartialDiagnosticAt, 8>
Diag;
8407 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
8414 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
8421 Error(E, diag::note_constexpr_conditional_never_const);
8425 template<
typename ConditionalOperator>
8426 bool HandleConditionalOperator(
const ConditionalOperator *E) {
8429 if (Info.checkingPotentialConstantExpression() && Info.noteFailure()) {
8430 CheckPotentialConstantConditional(E);
8433 if (Info.noteFailure()) {
8441 return StmtVisitorTy::Visit(EvalExpr);
8446 typedef ConstStmtVisitor<Derived, bool> StmtVisitorTy;
8447 typedef ExprEvaluatorBase ExprEvaluatorBaseTy;
8449 OptionalDiagnostic CCEDiag(
const Expr *E,
diag::kind D) {
8450 return Info.CCEDiag(E, D);
8453 bool ZeroInitialization(
const Expr *E) {
return Error(E); }
8455 bool IsConstantEvaluatedBuiltinCall(
const CallExpr *E) {
8457 return BuiltinOp != 0 &&
8458 Info.Ctx.BuiltinInfo.isConstantEvaluated(BuiltinOp);
8462 ExprEvaluatorBase(EvalInfo &Info) : Info(Info) {}
8464 EvalInfo &getEvalInfo() {
return Info; }
8472 bool Error(
const Expr *E) {
8473 return Error(E, diag::note_invalid_subexpr_in_const_expr);
8476 bool VisitStmt(
const Stmt *) {
8477 llvm_unreachable(
"Expression evaluator should not be called on stmts");
8479 bool VisitExpr(
const Expr *E) {
8483 bool VisitEmbedExpr(
const EmbedExpr *E) {
8484 const auto It = E->
begin();
8485 return StmtVisitorTy::Visit(*It);
8488 bool VisitPredefinedExpr(
const PredefinedExpr *E) {
8491 bool VisitConstantExpr(
const ConstantExpr *E) {
8495 return StmtVisitorTy::Visit(E->
getSubExpr());
8498 bool VisitParenExpr(
const ParenExpr *E)
8499 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8500 bool VisitUnaryExtension(
const UnaryOperator *E)
8501 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8502 bool VisitUnaryPlus(
const UnaryOperator *E)
8503 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8504 bool VisitChooseExpr(
const ChooseExpr *E)
8506 bool VisitGenericSelectionExpr(
const GenericSelectionExpr *E)
8508 bool VisitSubstNonTypeTemplateParmExpr(
const SubstNonTypeTemplateParmExpr *E)
8510 bool VisitCXXDefaultArgExpr(
const CXXDefaultArgExpr *E) {
8511 TempVersionRAII RAII(*Info.CurrentCall);
8512 SourceLocExprScopeGuard Guard(E, Info.CurrentCall->CurSourceLocExprScope);
8513 return StmtVisitorTy::Visit(E->
getExpr());
8515 bool VisitCXXDefaultInitExpr(
const CXXDefaultInitExpr *E) {
8516 TempVersionRAII RAII(*Info.CurrentCall);
8520 SourceLocExprScopeGuard Guard(E, Info.CurrentCall->CurSourceLocExprScope);
8521 return StmtVisitorTy::Visit(E->
getExpr());
8524 bool VisitExprWithCleanups(
const ExprWithCleanups *E) {
8525 FullExpressionRAII Scope(Info);
8526 return StmtVisitorTy::Visit(E->
getSubExpr()) && Scope.destroy();
8531 bool VisitCXXBindTemporaryExpr(
const CXXBindTemporaryExpr *E) {
8532 return StmtVisitorTy::Visit(E->
getSubExpr());
8535 bool VisitCXXReinterpretCastExpr(
const CXXReinterpretCastExpr *E) {
8536 CCEDiag(E, diag::note_constexpr_invalid_cast)
8537 << diag::ConstexprInvalidCastKind::Reinterpret;
8538 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8540 bool VisitCXXDynamicCastExpr(
const CXXDynamicCastExpr *E) {
8541 if (!Info.Ctx.getLangOpts().CPlusPlus20)
8542 CCEDiag(E, diag::note_constexpr_invalid_cast)
8543 << diag::ConstexprInvalidCastKind::Dynamic;
8544 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8546 bool VisitBuiltinBitCastExpr(
const BuiltinBitCastExpr *E) {
8547 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8550 bool VisitBinaryOperator(
const BinaryOperator *E) {
8556 VisitIgnoredValue(E->
getLHS());
8557 return StmtVisitorTy::Visit(E->
getRHS());
8567 return DerivedSuccess(
Result, E);
8572 bool VisitCXXRewrittenBinaryOperator(
const CXXRewrittenBinaryOperator *E) {
8576 bool VisitBinaryConditionalOperator(
const BinaryConditionalOperator *E) {
8580 if (!
Evaluate(Info.CurrentCall->createTemporary(
8583 ScopeKind::FullExpression, CommonLV),
8587 return HandleConditionalOperator(E);
8590 bool VisitConditionalOperator(
const ConditionalOperator *E) {
8591 bool IsBcpCall =
false;
8596 if (
const CallExpr *CallCE =
8598 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
8605 if (Info.checkingPotentialConstantExpression() && IsBcpCall)
8608 FoldConstant Fold(Info, IsBcpCall);
8609 if (!HandleConditionalOperator(E)) {
8610 Fold.keepDiagnostics();
8617 bool VisitOpaqueValueExpr(
const OpaqueValueExpr *E) {
8618 if (
APValue *
Value = Info.CurrentCall->getCurrentTemporary(E);
8620 return DerivedSuccess(*
Value, E);
8626 assert(0 &&
"OpaqueValueExpr recursively refers to itself");
8629 return StmtVisitorTy::Visit(Source);
8632 bool VisitPseudoObjectExpr(
const PseudoObjectExpr *E) {
8633 for (
const Expr *SemE : E->
semantics()) {
8634 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
8643 if (OVE->isUnique())
8647 if (!
Evaluate(Info.CurrentCall->createTemporary(
8648 OVE, getStorageType(Info.Ctx, OVE),
8649 ScopeKind::FullExpression, LV),
8650 Info, OVE->getSourceExpr()))
8653 if (!StmtVisitorTy::Visit(SemE))
8663 bool VisitCallExpr(
const CallExpr *E) {
8665 if (!handleCallExpr(E,
Result,
nullptr))
8667 return DerivedSuccess(
Result, E);
8671 const LValue *ResultSlot) {
8672 CallScopeRAII CallScope(Info);
8675 QualType CalleeType =
Callee->getType();
8677 const FunctionDecl *FD =
nullptr;
8678 LValue *
This =
nullptr, ObjectArg;
8680 bool HasQualifier =
false;
8686 const CXXMethodDecl *
Member =
nullptr;
8687 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(Callee)) {
8691 Member = dyn_cast<CXXMethodDecl>(ME->getMemberDecl());
8693 return Error(Callee);
8695 HasQualifier = ME->hasQualifier();
8696 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(Callee)) {
8698 const ValueDecl *D =
8702 Member = dyn_cast<CXXMethodDecl>(D);
8704 return Error(Callee);
8706 }
else if (
const auto *PDE = dyn_cast<CXXPseudoDestructorExpr>(Callee)) {
8707 if (!Info.getLangOpts().CPlusPlus20)
8708 Info.CCEDiag(PDE, diag::note_constexpr_pseudo_destructor);
8712 return Error(Callee);
8719 if (!CalleeLV.getLValueOffset().isZero())
8720 return Error(Callee);
8721 if (CalleeLV.isNullPointer()) {
8722 Info.FFDiag(Callee, diag::note_constexpr_null_callee)
8723 <<
const_cast<Expr *
>(
Callee);
8726 FD = dyn_cast_or_null<FunctionDecl>(
8727 CalleeLV.getLValueBase().dyn_cast<
const ValueDecl *>());
8729 return Error(Callee);
8732 if (!Info.Ctx.hasSameFunctionTypeIgnoringExceptionSpec(
8739 auto *OCE = dyn_cast<CXXOperatorCallExpr>(E);
8740 if (OCE && OCE->isAssignmentOp()) {
8741 assert(Args.size() == 2 &&
"wrong number of arguments in assignment");
8742 Call = Info.CurrentCall->createCall(FD);
8743 bool HasThis =
false;
8744 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FD))
8745 HasThis = MD->isImplicitObjectMemberFunction();
8753 const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD);
8773 if (Info.getLangOpts().CPlusPlus20 && OCE &&
8774 OCE->getOperator() == OO_Equal && MD->
isTrivial() &&
8778 Args = Args.slice(1);
8784 const CXXRecordDecl *ClosureClass = MD->
getParent();
8786 ClosureClass->
captures().empty() &&
8787 "Number of captures must be zero for conversion to function-ptr");
8789 const CXXMethodDecl *LambdaCallOp =
8798 "A generic lambda's static-invoker function must be a "
8799 "template specialization");
8801 FunctionTemplateDecl *CallOpTemplate =
8803 void *InsertPos =
nullptr;
8804 FunctionDecl *CorrespondingCallOpSpecialization =
8806 assert(CorrespondingCallOpSpecialization &&
8807 "We must always have a function call operator specialization "
8808 "that corresponds to our static invoker specialization");
8810 FD = CorrespondingCallOpSpecialization;
8819 return CallScope.destroy();
8829 Call = Info.CurrentCall->createCall(FD);
8835 SmallVector<QualType, 4> CovariantAdjustmentPath;
8837 auto *NamedMember = dyn_cast<CXXMethodDecl>(FD);
8838 if (NamedMember && NamedMember->isVirtual() && !HasQualifier) {
8841 CovariantAdjustmentPath);
8844 }
else if (NamedMember && NamedMember->isImplicitObjectMemberFunction()) {
8854 if (
auto *DD = dyn_cast<CXXDestructorDecl>(FD)) {
8855 assert(This &&
"no 'this' pointer for destructor call");
8857 Info.Ctx.getCanonicalTagType(DD->getParent())) &&
8858 CallScope.destroy();
8875 if (!CovariantAdjustmentPath.empty() &&
8877 CovariantAdjustmentPath))
8880 return CallScope.destroy();
8883 bool VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E) {
8886 bool VisitInitListExpr(
const InitListExpr *E) {
8888 return DerivedZeroInitialization(E);
8890 return StmtVisitorTy::Visit(E->
getInit(0));
8893 bool VisitImplicitValueInitExpr(
const ImplicitValueInitExpr *E) {
8894 return DerivedZeroInitialization(E);
8896 bool VisitCXXScalarValueInitExpr(
const CXXScalarValueInitExpr *E) {
8897 return DerivedZeroInitialization(E);
8899 bool VisitCXXNullPtrLiteralExpr(
const CXXNullPtrLiteralExpr *E) {
8900 return DerivedZeroInitialization(E);
8904 bool VisitMemberExpr(
const MemberExpr *E) {
8905 assert(!Info.Ctx.getLangOpts().CPlusPlus11 &&
8906 "missing temporary materialization conversion");
8907 assert(!E->
isArrow() &&
"missing call to bound member function?");
8915 const FieldDecl *FD = dyn_cast<FieldDecl>(E->
getMemberDecl());
8916 if (!FD)
return Error(E);
8920 "record / field mismatch");
8925 CompleteObject Obj(APValue::LValueBase(), &Val, BaseTy);
8926 SubobjectDesignator Designator(BaseTy);
8927 Designator.addDeclUnchecked(FD);
8931 DerivedSuccess(
Result, E);
8934 bool VisitExtVectorElementExpr(
const ExtVectorElementExpr *E) {
8940 SmallVector<uint32_t, 4> Indices;
8942 if (Indices.size() == 1) {
8944 return DerivedSuccess(Val.
getVectorElt(Indices[0]), E);
8947 SmallVector<APValue, 4> Elts;
8948 for (
unsigned I = 0; I < Indices.size(); ++I) {
8951 APValue VecResult(Elts.data(), Indices.size());
8952 return DerivedSuccess(VecResult, E);
8959 bool VisitCastExpr(
const CastExpr *E) {
8964 case CK_AtomicToNonAtomic: {
8971 return DerivedSuccess(AtomicVal, E);
8975 case CK_UserDefinedConversion:
8976 return StmtVisitorTy::Visit(E->
getSubExpr());
8978 case CK_HLSLArrayRValue: {
8984 return DerivedSuccess(Val, E);
8995 return DerivedSuccess(RVal, E);
8997 case CK_LValueToRValue: {
9006 return DerivedSuccess(RVal, E);
9008 case CK_LValueToRValueBitCast: {
9009 APValue DestValue, SourceValue;
9012 if (!handleLValueToRValueBitCast(Info, DestValue, SourceValue, E))
9014 return DerivedSuccess(DestValue, E);
9017 case CK_AddressSpaceConversion: {
9021 return DerivedSuccess(
Value, E);
9028 bool VisitUnaryPostInc(
const UnaryOperator *UO) {
9029 return VisitUnaryPostIncDec(UO);
9031 bool VisitUnaryPostDec(
const UnaryOperator *UO) {
9032 return VisitUnaryPostIncDec(UO);
9034 bool VisitUnaryPostIncDec(
const UnaryOperator *UO) {
9035 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9045 return DerivedSuccess(RVal, UO);
9048 bool VisitStmtExpr(
const StmtExpr *E) {
9051 llvm::SaveAndRestore NotCheckingForUB(Info.CheckingForUndefinedBehavior,
9058 BlockScopeRAII Scope(Info);
9063 const Expr *FinalExpr = dyn_cast<Expr>(*BI);
9065 Info.FFDiag((*BI)->getBeginLoc(),
9066 diag::note_constexpr_stmt_expr_unsupported);
9069 return this->Visit(FinalExpr) && Scope.destroy();
9075 if (ESR != ESR_Succeeded) {
9079 if (ESR != ESR_Failed)
9080 Info.FFDiag((*BI)->getBeginLoc(),
9081 diag::note_constexpr_stmt_expr_unsupported);
9086 llvm_unreachable(
"Return from function from the loop above.");
9089 bool VisitPackIndexingExpr(
const PackIndexingExpr *E) {
9094 void VisitIgnoredValue(
const Expr *E) {
9099 void VisitIgnoredBaseExpression(
const Expr *E) {
9102 if (Info.getLangOpts().MSVCCompat && !E->
HasSideEffects(Info.Ctx))
9104 VisitIgnoredValue(E);
9114template<
class Derived>
9115class LValueExprEvaluatorBase
9116 :
public ExprEvaluatorBase<Derived> {
9120 typedef LValueExprEvaluatorBase LValueExprEvaluatorBaseTy;
9121 typedef ExprEvaluatorBase<Derived> ExprEvaluatorBaseTy;
9123 bool Success(APValue::LValueBase B) {
9128 bool evaluatePointer(
const Expr *E, LValue &
Result) {
9133 LValueExprEvaluatorBase(EvalInfo &Info, LValue &
Result,
bool InvalidBaseOK)
9135 InvalidBaseOK(InvalidBaseOK) {}
9138 Result.setFrom(this->Info.Ctx,
V);
9142 bool VisitMemberExpr(
const MemberExpr *E) {
9154 EvalOK = this->Visit(E->
getBase());
9165 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(E->
getMemberDecl())) {
9168 "record / field mismatch");
9172 }
else if (
const IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(MD)) {
9176 return this->
Error(E);
9188 bool VisitBinaryOperator(
const BinaryOperator *E) {
9191 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
9199 bool VisitCastExpr(
const CastExpr *E) {
9202 return ExprEvaluatorBaseTy::VisitCastExpr(E);
9204 case CK_DerivedToBase:
9205 case CK_UncheckedDerivedToBase:
9252class LValueExprEvaluator
9253 :
public LValueExprEvaluatorBase<LValueExprEvaluator> {
9255 LValueExprEvaluator(EvalInfo &Info, LValue &
Result,
bool InvalidBaseOK) :
9256 LValueExprEvaluatorBaseTy(Info,
Result, InvalidBaseOK) {}
9258 bool VisitVarDecl(
const Expr *E,
const VarDecl *VD);
9259 bool VisitUnaryPreIncDec(
const UnaryOperator *UO);
9261 bool VisitCallExpr(
const CallExpr *E);
9262 bool VisitDeclRefExpr(
const DeclRefExpr *E);
9263 bool VisitPredefinedExpr(
const PredefinedExpr *E) {
return Success(E); }
9264 bool VisitMaterializeTemporaryExpr(
const MaterializeTemporaryExpr *E);
9265 bool VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E);
9266 bool VisitMemberExpr(
const MemberExpr *E);
9267 bool VisitStringLiteral(
const StringLiteral *E) {
9269 APValue::LValueBase(E, 0, Info.Ctx.getNextStringLiteralVersion()));
9271 bool VisitObjCEncodeExpr(
const ObjCEncodeExpr *E) {
return Success(E); }
9272 bool VisitCXXTypeidExpr(
const CXXTypeidExpr *E);
9273 bool VisitCXXUuidofExpr(
const CXXUuidofExpr *E);
9274 bool VisitArraySubscriptExpr(
const ArraySubscriptExpr *E);
9275 bool VisitExtVectorElementExpr(
const ExtVectorElementExpr *E);
9276 bool VisitUnaryDeref(
const UnaryOperator *E);
9277 bool VisitUnaryReal(
const UnaryOperator *E);
9278 bool VisitUnaryImag(
const UnaryOperator *E);
9279 bool VisitUnaryPreInc(
const UnaryOperator *UO) {
9280 return VisitUnaryPreIncDec(UO);
9282 bool VisitUnaryPreDec(
const UnaryOperator *UO) {
9283 return VisitUnaryPreIncDec(UO);
9285 bool VisitBinAssign(
const BinaryOperator *BO);
9286 bool VisitCompoundAssignOperator(
const CompoundAssignOperator *CAO);
9288 bool VisitCastExpr(
const CastExpr *E) {
9291 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
9293 case CK_LValueBitCast:
9294 this->CCEDiag(E, diag::note_constexpr_invalid_cast)
9295 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
9296 << Info.Ctx.getLangOpts().CPlusPlus;
9299 Result.Designator.setInvalid();
9302 case CK_BaseToDerived:
9319 bool LValueToRValueConversion) {
9323 assert(Info.CurrentCall->This ==
nullptr &&
9324 "This should not be set for a static call operator");
9332 if (
Self->getType()->isReferenceType()) {
9333 APValue *RefValue = Info.getParamSlot(Info.CurrentCall->Arguments,
Self);
9335 Result.setFrom(Info.Ctx, *RefValue);
9337 const ParmVarDecl *VD = Info.CurrentCall->Arguments.getOrigParam(
Self);
9338 CallStackFrame *Frame =
9339 Info.getCallFrameAndDepth(Info.CurrentCall->Arguments.CallIndex)
9341 unsigned Version = Info.CurrentCall->Arguments.Version;
9342 Result.set({VD, Frame->Index, Version});
9345 Result = *Info.CurrentCall->This;
9355 if (LValueToRValueConversion) {
9359 Result.setFrom(Info.Ctx, RVal);
9370 bool InvalidBaseOK) {
9374 return LValueExprEvaluator(Info,
Result, InvalidBaseOK).Visit(E);
9377bool LValueExprEvaluator::VisitDeclRefExpr(
const DeclRefExpr *E) {
9378 const ValueDecl *D = E->
getDecl();
9390 if (Info.checkingPotentialConstantExpression())
9393 if (
auto *FD = Info.CurrentCall->LambdaCaptureFields.lookup(D)) {
9400 if (
isa<FunctionDecl, MSGuidDecl, TemplateParamObjectDecl,
9401 UnnamedGlobalConstantDecl>(D))
9403 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
9404 return VisitVarDecl(E, VD);
9405 if (
const BindingDecl *BD = dyn_cast<BindingDecl>(D))
9406 return Visit(BD->getBinding());
9410bool LValueExprEvaluator::VisitVarDecl(
const Expr *E,
const VarDecl *VD) {
9411 CallStackFrame *Frame =
nullptr;
9412 unsigned Version = 0;
9420 CallStackFrame *CurrFrame = Info.CurrentCall;
9425 if (
auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
9426 if (CurrFrame->Arguments) {
9427 VD = CurrFrame->Arguments.getOrigParam(PVD);
9429 Info.getCallFrameAndDepth(CurrFrame->Arguments.CallIndex).first;
9430 Version = CurrFrame->Arguments.Version;
9434 Version = CurrFrame->getCurrentTemporaryVersion(VD);
9441 Result.set({VD, Frame->Index, Version});
9447 if (!Info.getLangOpts().CPlusPlus11) {
9448 Info.CCEDiag(E, diag::note_constexpr_ltor_non_integral, 1)
9450 Info.Note(VD->
getLocation(), diag::note_declared_at);
9459 Result.AllowConstexprUnknown =
true;
9466bool LValueExprEvaluator::VisitCallExpr(
const CallExpr *E) {
9467 if (!IsConstantEvaluatedBuiltinCall(E))
9468 return ExprEvaluatorBaseTy::VisitCallExpr(E);
9473 case Builtin::BIas_const:
9474 case Builtin::BIforward:
9475 case Builtin::BIforward_like:
9476 case Builtin::BImove:
9477 case Builtin::BImove_if_noexcept:
9479 return Visit(E->
getArg(0));
9483 return ExprEvaluatorBaseTy::VisitCallExpr(E);
9486bool LValueExprEvaluator::VisitMaterializeTemporaryExpr(
9487 const MaterializeTemporaryExpr *E) {
9495 for (
const Expr *E : CommaLHSs)
9504 if (Info.EvalMode == EvaluationMode::ConstantFold)
9511 Value = &Info.CurrentCall->createTemporary(
9527 for (
unsigned I = Adjustments.size(); I != 0; ) {
9529 switch (Adjustments[I].Kind) {
9534 Type = Adjustments[I].DerivedToBase.BasePath->getType();
9540 Type = Adjustments[I].Field->getType();
9545 Adjustments[I].Ptr.RHS))
9547 Type = Adjustments[I].Ptr.MPT->getPointeeType();
9556LValueExprEvaluator::VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E) {
9557 assert((!Info.getLangOpts().CPlusPlus || E->
isFileScope()) &&
9558 "lvalue compound literal in c++?");
9570 assert(!Info.getLangOpts().CPlusPlus);
9572 ScopeKind::Block,
Result);
9584bool LValueExprEvaluator::VisitCXXTypeidExpr(
const CXXTypeidExpr *E) {
9585 TypeInfoLValue TypeInfo;
9593 if (!Info.Ctx.getLangOpts().CPlusPlus20) {
9594 Info.CCEDiag(E, diag::note_constexpr_typeid_polymorphic)
9602 std::optional<DynamicType> DynType =
9607 TypeInfo = TypeInfoLValue(
9608 Info.Ctx.getCanonicalTagType(DynType->Type).getTypePtr());
9614bool LValueExprEvaluator::VisitCXXUuidofExpr(
const CXXUuidofExpr *E) {
9618bool LValueExprEvaluator::VisitMemberExpr(
const MemberExpr *E) {
9620 if (
const VarDecl *VD = dyn_cast<VarDecl>(E->
getMemberDecl())) {
9621 VisitIgnoredBaseExpression(E->
getBase());
9622 return VisitVarDecl(E, VD);
9626 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(E->
getMemberDecl())) {
9627 if (MD->isStatic()) {
9628 VisitIgnoredBaseExpression(E->
getBase());
9634 return LValueExprEvaluatorBaseTy::VisitMemberExpr(E);
9637bool LValueExprEvaluator::VisitExtVectorElementExpr(
9638 const ExtVectorElementExpr *E) {
9643 if (!Info.noteFailure())
9651 if (Indices.size() > 1)
9655 Result.setFrom(Info.Ctx, Val);
9659 const auto *VT = BaseType->
castAs<VectorType>();
9661 VT->getNumElements(), Indices[0]);
9667bool LValueExprEvaluator::VisitArraySubscriptExpr(
const ArraySubscriptExpr *E) {
9677 if (!Info.noteFailure())
9683 if (!Info.noteFailure())
9689 Result.setFrom(Info.Ctx, Val);
9691 VT->getNumElements(), Index.getZExtValue());
9699 for (
const Expr *SubExpr : {E->
getLHS(), E->
getRHS()}) {
9700 if (SubExpr == E->
getBase() ? !evaluatePointer(SubExpr,
Result)
9702 if (!Info.noteFailure())
9712bool LValueExprEvaluator::VisitUnaryDeref(
const UnaryOperator *E) {
9723 Info.noteUndefinedBehavior();
9726bool LValueExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
9735bool LValueExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
9737 "lvalue __imag__ on scalar?");
9744bool LValueExprEvaluator::VisitUnaryPreIncDec(
const UnaryOperator *UO) {
9745 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9756bool LValueExprEvaluator::VisitCompoundAssignOperator(
9757 const CompoundAssignOperator *CAO) {
9758 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9766 if (!Info.noteFailure())
9781bool LValueExprEvaluator::VisitBinAssign(
const BinaryOperator *E) {
9782 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9790 if (!Info.noteFailure())
9798 if (Info.getLangOpts().CPlusPlus20 &&
9815 assert(isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
9816 "Can't get the size of a non alloc_size function");
9817 const auto *
Base = LVal.getLValueBase().get<
const Expr *>();
9819 std::optional<llvm::APInt> Size =
9820 CE->evaluateBytesReturnedByAllocSizeCall(Ctx);
9824 Result = std::move(*Size);
9843 dyn_cast_or_null<VarDecl>(
Base.dyn_cast<
const ValueDecl *>());
9848 if (!
Init ||
Init->getType().isNull())
9851 const Expr *E =
Init->IgnoreParens();
9852 if (!tryUnwrapAllocSizeCall(E))
9860 Result.addUnsizedArray(Info, E, Pointee);
9865class PointerExprEvaluator
9866 :
public ExprEvaluatorBase<PointerExprEvaluator> {
9875 bool evaluateLValue(
const Expr *E, LValue &
Result) {
9879 bool evaluatePointer(
const Expr *E, LValue &
Result) {
9883 bool visitNonBuiltinCallExpr(
const CallExpr *E);
9886 PointerExprEvaluator(EvalInfo &info, LValue &
Result,
bool InvalidBaseOK)
9888 InvalidBaseOK(InvalidBaseOK) {}
9894 bool ZeroInitialization(
const Expr *E) {
9899 bool VisitBinaryOperator(
const BinaryOperator *E);
9900 bool VisitCastExpr(
const CastExpr* E);
9901 bool VisitUnaryAddrOf(
const UnaryOperator *E);
9902 bool VisitObjCStringLiteral(
const ObjCStringLiteral *E)
9904 bool VisitObjCBoxedExpr(
const ObjCBoxedExpr *E) {
9907 if (Info.noteFailure())
9911 bool VisitObjCArrayLiteral(
const ObjCArrayLiteral *E) {
9914 bool VisitObjCDictionaryLiteral(
const ObjCDictionaryLiteral *E) {
9917 bool VisitAddrLabelExpr(
const AddrLabelExpr *E)
9919 bool VisitCallExpr(
const CallExpr *E);
9920 bool VisitBuiltinCallExpr(
const CallExpr *E,
unsigned BuiltinOp);
9921 bool VisitBlockExpr(
const BlockExpr *E) {
9926 bool VisitCXXThisExpr(
const CXXThisExpr *E) {
9927 auto DiagnoseInvalidUseOfThis = [&] {
9928 if (Info.getLangOpts().CPlusPlus11)
9929 Info.FFDiag(E, diag::note_constexpr_this) << E->
isImplicit();
9935 if (Info.checkingPotentialConstantExpression())
9938 bool IsExplicitLambda =
9940 if (!IsExplicitLambda) {
9941 if (!Info.CurrentCall->This) {
9942 DiagnoseInvalidUseOfThis();
9946 Result = *Info.CurrentCall->This;
9954 if (!Info.CurrentCall->LambdaThisCaptureField) {
9955 if (IsExplicitLambda && !Info.CurrentCall->This) {
9956 DiagnoseInvalidUseOfThis();
9965 Info, E,
Result, MD, Info.CurrentCall->LambdaThisCaptureField,
9971 bool VisitCXXNewExpr(
const CXXNewExpr *E);
9973 bool VisitSourceLocExpr(
const SourceLocExpr *E) {
9974 assert(!E->
isIntType() &&
"SourceLocExpr isn't a pointer type?");
9976 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.
getDefaultExpr());
9977 Result.setFrom(Info.Ctx, LValResult);
9981 bool VisitEmbedExpr(
const EmbedExpr *E) {
9982 llvm::report_fatal_error(
"Not yet implemented for ExprConstant.cpp");
9986 bool VisitSYCLUniqueStableNameExpr(
const SYCLUniqueStableNameExpr *E) {
9989 QualType CharTy = Info.Ctx.CharTy.withConst();
9990 APInt Size(Info.Ctx.getTypeSize(Info.Ctx.getSizeType()),
9991 ResultStr.size() + 1);
9992 QualType ArrayTy = Info.Ctx.getConstantArrayType(
9993 CharTy, Size,
nullptr, ArraySizeModifier::Normal, 0);
9996 StringLiteral::Create(Info.Ctx, ResultStr, StringLiteralKind::Ordinary,
9999 evaluateLValue(SL,
Result);
10009 bool InvalidBaseOK) {
10012 return PointerExprEvaluator(Info,
Result, InvalidBaseOK).Visit(E);
10015bool PointerExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
10018 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
10020 const Expr *PExp = E->
getLHS();
10021 const Expr *IExp = E->
getRHS();
10023 std::swap(PExp, IExp);
10025 bool EvalPtrOK = evaluatePointer(PExp,
Result);
10026 if (!EvalPtrOK && !Info.noteFailure())
10029 llvm::APSInt Offset;
10040bool PointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
10049 if (!FnII || !FnII->
isStr(
"current"))
10052 const auto *RD = dyn_cast<RecordDecl>(FD->
getParent());
10060bool PointerExprEvaluator::VisitCastExpr(
const CastExpr *E) {
10067 case CK_CPointerToObjCPointerCast:
10068 case CK_BlockPointerToObjCPointerCast:
10069 case CK_AnyPointerToBlockPointerCast:
10070 case CK_AddressSpaceConversion:
10071 if (!Visit(SubExpr))
10077 CCEDiag(E, diag::note_constexpr_invalid_cast)
10078 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
10079 << Info.Ctx.getLangOpts().CPlusPlus;
10080 Result.Designator.setInvalid();
10088 bool HasValidResult = !
Result.InvalidBase && !
Result.Designator.Invalid &&
10090 bool VoidPtrCastMaybeOK =
10093 Info.Ctx.hasSimilarType(
Result.Designator.getType(Info.Ctx),
10102 if (VoidPtrCastMaybeOK &&
10103 (Info.getStdAllocatorCaller(
"allocate") ||
10105 Info.getLangOpts().CPlusPlus26)) {
10109 Info.getLangOpts().CPlusPlus) {
10110 if (HasValidResult)
10111 CCEDiag(E, diag::note_constexpr_invalid_void_star_cast)
10112 << SubExpr->
getType() << Info.getLangOpts().CPlusPlus26
10113 <<
Result.Designator.getType(Info.Ctx).getCanonicalType()
10116 CCEDiag(E, diag::note_constexpr_invalid_cast)
10117 << diag::ConstexprInvalidCastKind::CastFrom
10120 CCEDiag(E, diag::note_constexpr_invalid_cast)
10121 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
10122 << Info.Ctx.getLangOpts().CPlusPlus;
10123 Result.Designator.setInvalid();
10127 ZeroInitialization(E);
10130 case CK_DerivedToBase:
10131 case CK_UncheckedDerivedToBase:
10143 case CK_BaseToDerived:
10155 case CK_NullToPointer:
10157 return ZeroInitialization(E);
10159 case CK_IntegralToPointer: {
10160 CCEDiag(E, diag::note_constexpr_invalid_cast)
10161 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
10162 << Info.Ctx.getLangOpts().CPlusPlus;
10168 if (
Value.isInt()) {
10169 unsigned Size = Info.Ctx.getTypeSize(E->
getType());
10170 uint64_t N =
Value.getInt().extOrTrunc(Size).getZExtValue();
10171 if (N == Info.Ctx.getTargetNullPointerValue(E->
getType())) {
10174 Result.Base = (Expr *)
nullptr;
10175 Result.InvalidBase =
false;
10177 Result.Designator.setInvalid();
10178 Result.IsNullPtr =
false;
10186 if (!
Value.isLValue())
10195 case CK_ArrayToPointerDecay: {
10197 if (!evaluateLValue(SubExpr,
Result))
10201 SubExpr, SubExpr->
getType(), ScopeKind::FullExpression,
Result);
10206 auto *AT = Info.Ctx.getAsArrayType(SubExpr->
getType());
10207 if (
auto *CAT = dyn_cast<ConstantArrayType>(AT))
10208 Result.addArray(Info, E, CAT);
10210 Result.addUnsizedArray(Info, E, AT->getElementType());
10214 case CK_FunctionToPointerDecay:
10215 return evaluateLValue(SubExpr,
Result);
10217 case CK_LValueToRValue: {
10226 return InvalidBaseOK &&
10232 return ExprEvaluatorBaseTy::VisitCastExpr(E);
10240 T = T.getNonReferenceType();
10242 if (T.getQualifiers().hasUnaligned())
10245 const bool AlignOfReturnsPreferred =
10246 Ctx.
getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver7;
10251 if (ExprKind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
10254 else if (ExprKind == UETT_AlignOf)
10257 llvm_unreachable(
"GetAlignOfType on a non-alignment ExprKind");
10270 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
10274 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(E))
10283 return Info.Ctx.getDeclAlign(VD);
10284 if (
const auto *E =
Value.Base.dyn_cast<
const Expr *>())
10292 EvalInfo &Info,
APSInt &Alignment) {
10295 if (Alignment < 0 || !Alignment.isPowerOf2()) {
10296 Info.FFDiag(E, diag::note_constexpr_invalid_alignment) << Alignment;
10299 unsigned SrcWidth = Info.Ctx.getIntWidth(ForType);
10300 APSInt MaxValue(APInt::getOneBitSet(SrcWidth, SrcWidth - 1));
10301 if (APSInt::compareValues(Alignment, MaxValue) > 0) {
10302 Info.FFDiag(E, diag::note_constexpr_alignment_too_big)
10303 << MaxValue << ForType << Alignment;
10309 APSInt(Alignment.zextOrTrunc(SrcWidth),
true);
10310 assert(APSInt::compareValues(Alignment, ExtAlignment) == 0 &&
10311 "Alignment should not be changed by ext/trunc");
10312 Alignment = ExtAlignment;
10313 assert(Alignment.getBitWidth() == SrcWidth);
10318bool PointerExprEvaluator::visitNonBuiltinCallExpr(
const CallExpr *E) {
10319 if (ExprEvaluatorBaseTy::VisitCallExpr(E))
10327 Result.addUnsizedArray(Info, E, PointeeTy);
10331bool PointerExprEvaluator::VisitCallExpr(
const CallExpr *E) {
10332 if (!IsConstantEvaluatedBuiltinCall(E))
10333 return visitNonBuiltinCallExpr(E);
10340 return T->isCharType() || T->isChar8Type();
10343bool PointerExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *E,
10344 unsigned BuiltinOp) {
10348 switch (BuiltinOp) {
10349 case Builtin::BIaddressof:
10350 case Builtin::BI__addressof:
10351 case Builtin::BI__builtin_addressof:
10353 case Builtin::BI__builtin_assume_aligned: {
10360 LValue OffsetResult(
Result);
10372 int64_t AdditionalOffset = -Offset.getZExtValue();
10377 if (OffsetResult.Base) {
10380 if (BaseAlignment < Align) {
10381 Result.Designator.setInvalid();
10382 CCEDiag(E->
getArg(0), diag::note_constexpr_baa_insufficient_alignment)
10389 if (OffsetResult.Offset.alignTo(Align) != OffsetResult.Offset) {
10390 Result.Designator.setInvalid();
10394 diag::note_constexpr_baa_insufficient_alignment)
10397 diag::note_constexpr_baa_value_insufficient_alignment))
10398 << OffsetResult.Offset.getQuantity() << Align.
getQuantity();
10404 case Builtin::BI__builtin_align_up:
10405 case Builtin::BI__builtin_align_down: {
10425 assert(Alignment.getBitWidth() <= 64 &&
10426 "Cannot handle > 64-bit address-space");
10427 uint64_t Alignment64 = Alignment.getZExtValue();
10429 BuiltinOp == Builtin::BI__builtin_align_down
10430 ? llvm::alignDown(
Result.Offset.getQuantity(), Alignment64)
10431 : llvm::alignTo(
Result.Offset.getQuantity(), Alignment64));
10437 Info.FFDiag(E->
getArg(0), diag::note_constexpr_alignment_adjust)
10441 case Builtin::BI__builtin_operator_new:
10443 case Builtin::BI__builtin_launder:
10445 case Builtin::BIstrchr:
10446 case Builtin::BIwcschr:
10447 case Builtin::BImemchr:
10448 case Builtin::BIwmemchr:
10449 if (Info.getLangOpts().CPlusPlus11)
10450 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
10452 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
10454 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
10456 case Builtin::BI__builtin_strchr:
10457 case Builtin::BI__builtin_wcschr:
10458 case Builtin::BI__builtin_memchr:
10459 case Builtin::BI__builtin_char_memchr:
10460 case Builtin::BI__builtin_wmemchr: {
10461 if (!Visit(E->
getArg(0)))
10467 if (BuiltinOp != Builtin::BIstrchr &&
10468 BuiltinOp != Builtin::BIwcschr &&
10469 BuiltinOp != Builtin::BI__builtin_strchr &&
10470 BuiltinOp != Builtin::BI__builtin_wcschr) {
10474 MaxLength = N.getZExtValue();
10477 if (MaxLength == 0u)
10478 return ZeroInitialization(E);
10479 if (!
Result.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
10480 Result.Designator.Invalid)
10482 QualType CharTy =
Result.Designator.getType(Info.Ctx);
10483 bool IsRawByte = BuiltinOp == Builtin::BImemchr ||
10484 BuiltinOp == Builtin::BI__builtin_memchr;
10485 assert(IsRawByte ||
10486 Info.Ctx.hasSameUnqualifiedType(
10490 Info.FFDiag(E, diag::note_constexpr_ltor_incomplete_type) << CharTy;
10496 Info.FFDiag(E, diag::note_constexpr_memchr_unsupported)
10497 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp) << CharTy;
10503 bool StopAtNull =
false;
10504 switch (BuiltinOp) {
10505 case Builtin::BIstrchr:
10506 case Builtin::BI__builtin_strchr:
10513 return ZeroInitialization(E);
10516 case Builtin::BImemchr:
10517 case Builtin::BI__builtin_memchr:
10518 case Builtin::BI__builtin_char_memchr:
10522 DesiredVal = Desired.trunc(Info.Ctx.getCharWidth()).getZExtValue();
10525 case Builtin::BIwcschr:
10526 case Builtin::BI__builtin_wcschr:
10529 case Builtin::BIwmemchr:
10530 case Builtin::BI__builtin_wmemchr:
10532 DesiredVal = Desired.getZExtValue();
10536 for (; MaxLength; --MaxLength) {
10541 if (Char.
getInt().getZExtValue() == DesiredVal)
10543 if (StopAtNull && !Char.
getInt())
10549 return ZeroInitialization(E);
10552 case Builtin::BImemcpy:
10553 case Builtin::BImemmove:
10554 case Builtin::BIwmemcpy:
10555 case Builtin::BIwmemmove:
10556 if (Info.getLangOpts().CPlusPlus11)
10557 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
10559 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
10561 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
10563 case Builtin::BI__builtin_memcpy:
10564 case Builtin::BI__builtin_memmove:
10565 case Builtin::BI__builtin_wmemcpy:
10566 case Builtin::BI__builtin_wmemmove: {
10567 bool WChar = BuiltinOp == Builtin::BIwmemcpy ||
10568 BuiltinOp == Builtin::BIwmemmove ||
10569 BuiltinOp == Builtin::BI__builtin_wmemcpy ||
10570 BuiltinOp == Builtin::BI__builtin_wmemmove;
10571 bool Move = BuiltinOp == Builtin::BImemmove ||
10572 BuiltinOp == Builtin::BIwmemmove ||
10573 BuiltinOp == Builtin::BI__builtin_memmove ||
10574 BuiltinOp == Builtin::BI__builtin_wmemmove;
10577 if (!Visit(E->
getArg(0)))
10588 assert(!N.isSigned() &&
"memcpy and friends take an unsigned size");
10598 if (!Src.Base || !Dest.Base) {
10600 (!Src.Base ? Src : Dest).moveInto(Val);
10601 Info.FFDiag(E, diag::note_constexpr_memcpy_null)
10602 <<
Move << WChar << !!Src.Base
10606 if (Src.Designator.Invalid || Dest.Designator.Invalid)
10612 QualType T = Dest.Designator.getType(Info.Ctx);
10613 QualType SrcT = Src.Designator.getType(Info.Ctx);
10614 if (!Info.Ctx.hasSameUnqualifiedType(T, SrcT)) {
10616 Info.FFDiag(E, diag::note_constexpr_memcpy_type_pun) <<
Move << SrcT << T;
10620 Info.FFDiag(E, diag::note_constexpr_memcpy_incomplete_type) <<
Move << T;
10624 Info.FFDiag(E, diag::note_constexpr_memcpy_nontrivial) <<
Move << T;
10629 uint64_t TSize = Info.Ctx.getTypeSizeInChars(T).getQuantity();
10634 llvm::APInt OrigN = N;
10635 llvm::APInt::udivrem(OrigN, TSize, N, Remainder);
10637 Info.FFDiag(E, diag::note_constexpr_memcpy_unsupported)
10638 <<
Move << WChar << 0 << T <<
toString(OrigN, 10,
false)
10639 << (unsigned)TSize;
10647 uint64_t RemainingSrcSize = Src.Designator.validIndexAdjustments().second;
10648 uint64_t RemainingDestSize = Dest.Designator.validIndexAdjustments().second;
10649 if (N.ugt(RemainingSrcSize) || N.ugt(RemainingDestSize)) {
10650 Info.FFDiag(E, diag::note_constexpr_memcpy_unsupported)
10651 <<
Move << WChar << (N.ugt(RemainingSrcSize) ? 1 : 2) << T
10655 uint64_t NElems = N.getZExtValue();
10661 uint64_t SrcOffset = Src.getLValueOffset().getQuantity();
10662 uint64_t DestOffset = Dest.getLValueOffset().getQuantity();
10663 if (DestOffset >= SrcOffset && DestOffset - SrcOffset < NBytes) {
10666 Info.FFDiag(E, diag::note_constexpr_memcpy_overlap) << WChar;
10674 }
else if (!Move && SrcOffset >= DestOffset &&
10675 SrcOffset - DestOffset < NBytes) {
10677 Info.FFDiag(E, diag::note_constexpr_memcpy_overlap) << WChar;
10706 QualType AllocType);
10709 const CXXConstructExpr *CCE,
10710 QualType AllocType);
10712bool PointerExprEvaluator::VisitCXXNewExpr(
const CXXNewExpr *E) {
10713 if (!Info.getLangOpts().CPlusPlus20)
10714 Info.CCEDiag(E, diag::note_constexpr_new);
10717 if (Info.SpeculativeEvaluationDepth)
10722 QualType TargetType = AllocType;
10724 bool IsNothrow =
false;
10725 bool IsPlacement =
false;
10743 }
else if (OperatorNew->isReservedGlobalPlacementOperator()) {
10744 if (Info.CurrentCall->isStdFunction() || Info.getLangOpts().CPlusPlus26 ||
10745 (Info.CurrentCall->CanEvalMSConstexpr &&
10746 OperatorNew->hasAttr<MSConstexprAttr>())) {
10749 if (
Result.Designator.Invalid)
10752 IsPlacement =
true;
10754 Info.FFDiag(E, diag::note_constexpr_new_placement)
10759 Info.FFDiag(E, diag::note_constexpr_new_placement)
10762 }
else if (!OperatorNew
10763 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
10764 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
10770 const InitListExpr *ResizedArrayILE =
nullptr;
10771 const CXXConstructExpr *ResizedArrayCCE =
nullptr;
10772 bool ValueInit =
false;
10774 if (std::optional<const Expr *> ArraySize = E->
getArraySize()) {
10775 const Expr *Stripped = *ArraySize;
10776 for (;
auto *ICE = dyn_cast<ImplicitCastExpr>(Stripped);
10777 Stripped = ICE->getSubExpr())
10778 if (ICE->getCastKind() != CK_NoOp &&
10779 ICE->getCastKind() != CK_IntegralCast)
10792 return ZeroInitialization(E);
10794 Info.FFDiag(*ArraySize, diag::note_constexpr_new_negative)
10795 <<
ArrayBound << (*ArraySize)->getSourceRange();
10801 if (!Info.CheckArraySize(ArraySize.value()->getExprLoc(),
10806 return ZeroInitialization(E);
10818 }
else if (
auto *CCE = dyn_cast<CXXConstructExpr>(
Init)) {
10819 ResizedArrayCCE = CCE;
10821 auto *CAT = Info.Ctx.getAsConstantArrayType(
Init->getType());
10822 assert(CAT &&
"unexpected type for array initializer");
10826 llvm::APInt InitBound = CAT->
getSize().zext(Bits);
10827 llvm::APInt AllocBound =
ArrayBound.zext(Bits);
10828 if (InitBound.ugt(AllocBound)) {
10830 return ZeroInitialization(E);
10832 Info.FFDiag(*ArraySize, diag::note_constexpr_new_too_small)
10833 <<
toString(AllocBound, 10,
false)
10835 << (*ArraySize)->getSourceRange();
10841 if (InitBound != AllocBound)
10845 AllocType = Info.Ctx.getConstantArrayType(AllocType,
ArrayBound,
nullptr,
10846 ArraySizeModifier::Normal, 0);
10849 "array allocation with non-array new");
10855 struct FindObjectHandler {
10858 QualType AllocType;
10862 typedef bool result_type;
10863 bool failed() {
return false; }
10864 bool checkConst(QualType QT) {
10866 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
10871 bool found(
APValue &Subobj, QualType SubobjType,
10872 APValue::LValueBase Base) {
10873 if (!checkConst(SubobjType))
10877 unsigned SubobjectSize = 1;
10878 unsigned AllocSize = 1;
10879 if (
auto *CAT = dyn_cast<ConstantArrayType>(AllocType))
10881 if (
auto *CAT = dyn_cast<ConstantArrayType>(SubobjType))
10883 if (SubobjectSize < AllocSize ||
10884 !Info.Ctx.hasSimilarType(Info.Ctx.getBaseElementType(SubobjType),
10885 Info.Ctx.getBaseElementType(AllocType))) {
10886 Info.FFDiag(E, diag::note_constexpr_placement_new_wrong_type)
10887 << SubobjType << AllocType;
10894 Info.FFDiag(E, diag::note_constexpr_construct_complex_elem);
10897 bool found(APFloat &
Value, QualType SubobjType) {
10898 Info.FFDiag(E, diag::note_constexpr_construct_complex_elem);
10901 } Handler = {Info, E, AllocType, AK,
nullptr};
10907 Val = Handler.Value;
10916 Val = Info.createHeapAlloc(E, AllocType,
Result);
10922 ImplicitValueInitExpr VIE(AllocType);
10925 }
else if (ResizedArrayILE) {
10929 }
else if (ResizedArrayCCE) {
10952class MemberPointerExprEvaluator
10953 :
public ExprEvaluatorBase<MemberPointerExprEvaluator> {
10956 bool Success(
const ValueDecl *D) {
10962 MemberPointerExprEvaluator(EvalInfo &Info, MemberPtr &
Result)
10969 bool ZeroInitialization(
const Expr *E) {
10970 return Success((
const ValueDecl*)
nullptr);
10973 bool VisitCastExpr(
const CastExpr *E);
10974 bool VisitUnaryAddrOf(
const UnaryOperator *E);
10982 return MemberPointerExprEvaluator(Info,
Result).Visit(E);
10985bool MemberPointerExprEvaluator::VisitCastExpr(
const CastExpr *E) {
10988 return ExprEvaluatorBaseTy::VisitCastExpr(E);
10990 case CK_NullToMemberPointer:
10992 return ZeroInitialization(E);
10994 case CK_BaseToDerivedMemberPointer: {
11002 typedef std::reverse_iterator<CastExpr::path_const_iterator> ReverseIter;
11004 PathI != PathE; ++PathI) {
11005 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
11006 const CXXRecordDecl *Derived = (*PathI)->getType()->getAsCXXRecordDecl();
11007 if (!
Result.castToDerived(Derived))
11011 ->
castAs<MemberPointerType>()
11012 ->getMostRecentCXXRecordDecl()))
11017 case CK_DerivedToBaseMemberPointer:
11021 PathE = E->
path_end(); PathI != PathE; ++PathI) {
11022 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
11023 const CXXRecordDecl *
Base = (*PathI)->getType()->getAsCXXRecordDecl();
11024 if (!
Result.castToBase(Base))
11031bool MemberPointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
11042 class RecordExprEvaluator
11043 :
public ExprEvaluatorBase<RecordExprEvaluator> {
11044 const LValue &
This;
11048 RecordExprEvaluator(EvalInfo &info,
const LValue &This,
APValue &
Result)
11055 bool ZeroInitialization(
const Expr *E) {
11056 return ZeroInitialization(E, E->
getType());
11058 bool ZeroInitialization(
const Expr *E, QualType T);
11060 bool VisitCallExpr(
const CallExpr *E) {
11061 return handleCallExpr(E,
Result, &This);
11063 bool VisitCastExpr(
const CastExpr *E);
11064 bool VisitInitListExpr(
const InitListExpr *E);
11065 bool VisitCXXConstructExpr(
const CXXConstructExpr *E) {
11066 return VisitCXXConstructExpr(E, E->
getType());
11069 bool VisitCXXInheritedCtorInitExpr(
const CXXInheritedCtorInitExpr *E);
11070 bool VisitCXXConstructExpr(
const CXXConstructExpr *E, QualType T);
11071 bool VisitCXXStdInitializerListExpr(
const CXXStdInitializerListExpr *E);
11072 bool VisitBinCmp(
const BinaryOperator *E);
11073 bool VisitCXXParenListInitExpr(
const CXXParenListInitExpr *E);
11074 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
11075 ArrayRef<Expr *> Args);
11076 bool VisitDesignatedInitUpdateExpr(
const DesignatedInitUpdateExpr *E);
11090 assert(!RD->
isUnion() &&
"Expected non-union class type");
11099 unsigned Index = 0;
11101 End = CD->
bases_end(); I != End; ++I, ++Index) {
11103 LValue Subobject =
This;
11107 Result.getStructBase(Index)))
11112 for (
const auto *I : RD->
fields()) {
11114 if (I->isUnnamedBitField() || I->getType()->isReferenceType())
11117 LValue Subobject =
This;
11123 Result.getStructField(I->getFieldIndex()), Info, Subobject, &VIE))
11130bool RecordExprEvaluator::ZeroInitialization(
const Expr *E, QualType T) {
11137 while (I != RD->
field_end() && (*I)->isUnnamedBitField())
11144 LValue Subobject =
This;
11148 ImplicitValueInitExpr VIE(I->getType());
11153 Info.FFDiag(E, diag::note_constexpr_virtual_base) << RD;
11160bool RecordExprEvaluator::VisitCastExpr(
const CastExpr *E) {
11163 return ExprEvaluatorBaseTy::VisitCastExpr(E);
11165 case CK_ConstructorConversion:
11168 case CK_DerivedToBase:
11169 case CK_UncheckedDerivedToBase: {
11180 PathE = E->
path_end(); PathI != PathE; ++PathI) {
11181 assert(!(*PathI)->isVirtual() &&
"record rvalue with virtual base");
11182 const CXXRecordDecl *
Base = (*PathI)->getType()->getAsCXXRecordDecl();
11189 case CK_HLSLAggregateSplatCast: {
11209 case CK_HLSLElementwiseCast: {
11227 LValue Subobject =
This;
11234 if (
Field->isBitField()) {
11244bool RecordExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
11247 return VisitCXXParenListOrInitListExpr(E, E->
inits());
11250bool RecordExprEvaluator::VisitCXXParenListOrInitListExpr(
11254 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD);
11255 auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
11257 EvalInfo::EvaluatingConstructorRAII EvalObj(
11259 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries},
11260 CXXRD && CXXRD->getNumBases());
11263 const FieldDecl *
Field;
11264 if (
auto *ILE = dyn_cast<InitListExpr>(ExprToVisit)) {
11265 Field = ILE->getInitializedFieldInUnion();
11266 }
else if (
auto *PLIE = dyn_cast<CXXParenListInitExpr>(ExprToVisit)) {
11267 Field = PLIE->getInitializedFieldInUnion();
11270 "Expression is neither an init list nor a C++ paren list");
11282 ImplicitValueInitExpr VIE(
Field->getType());
11283 const Expr *InitExpr = Args.empty() ? &VIE : Args[0];
11285 LValue Subobject =
This;
11290 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
11294 if (
Field->isBitField())
11304 Result =
APValue(APValue::UninitStruct(), CXXRD ? CXXRD->getNumBases() : 0,
11306 unsigned ElementNo = 0;
11310 if (CXXRD && CXXRD->getNumBases()) {
11311 for (
const auto &Base : CXXRD->bases()) {
11312 assert(ElementNo < Args.size() &&
"missing init for base class");
11313 const Expr *
Init = Args[ElementNo];
11315 LValue Subobject =
This;
11321 if (!Info.noteFailure())
11328 EvalObj.finishedConstructingBases();
11332 for (
const auto *Field : RD->
fields()) {
11335 if (
Field->isUnnamedBitField())
11338 LValue Subobject =
This;
11340 bool HaveInit = ElementNo < Args.size();
11345 Subobject, Field, &Layout))
11350 ImplicitValueInitExpr VIE(HaveInit ? Info.Ctx.IntTy :
Field->getType());
11351 const Expr *
Init = HaveInit ? Args[ElementNo++] : &VIE;
11358 if (
Field->getType()->isIncompleteArrayType()) {
11359 if (
auto *CAT = Info.Ctx.getAsConstantArrayType(
Init->getType())) {
11363 Info.FFDiag(
Init, diag::note_constexpr_unsupported_flexible_array);
11370 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
11374 if (
Field->getType()->isReferenceType()) {
11378 if (!Info.noteFailure())
11383 (
Field->isBitField() &&
11385 if (!Info.noteFailure())
11391 EvalObj.finishedConstructingFields();
11396bool RecordExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E,
11406 return ZeroInitialization(E, T);
11424 const Expr *SrcObj = E->
getArg(0);
11426 assert(Info.Ctx.hasSameUnqualifiedType(E->
getType(), SrcObj->
getType()));
11427 if (
const MaterializeTemporaryExpr *ME =
11428 dyn_cast<MaterializeTemporaryExpr>(SrcObj))
11429 return Visit(ME->getSubExpr());
11432 if (ZeroInit && !ZeroInitialization(E, T))
11441bool RecordExprEvaluator::VisitCXXInheritedCtorInitExpr(
11442 const CXXInheritedCtorInitExpr *E) {
11443 if (!Info.CurrentCall) {
11444 assert(Info.checkingPotentialConstantExpression());
11463bool RecordExprEvaluator::VisitCXXStdInitializerListExpr(
11464 const CXXStdInitializerListExpr *E) {
11465 const ConstantArrayType *ArrayType =
11472 assert(ArrayType &&
"unexpected type for array initializer");
11475 Array.addArray(Info, E, ArrayType);
11483 assert(Field !=
Record->field_end() &&
11484 Info.Ctx.hasSameType(
Field->getType()->getPointeeType(),
11486 "Expected std::initializer_list first field to be const E *");
11488 assert(Field !=
Record->field_end() &&
11489 "Expected std::initializer_list to have two fields");
11491 if (Info.Ctx.hasSameType(
Field->getType(), Info.Ctx.getSizeType())) {
11496 assert(Info.Ctx.hasSameType(
Field->getType()->getPointeeType(),
11498 "Expected std::initializer_list second field to be const E *");
11506 assert(++Field ==
Record->field_end() &&
11507 "Expected std::initializer_list to only have two fields");
11512bool RecordExprEvaluator::VisitLambdaExpr(
const LambdaExpr *E) {
11517 const size_t NumFields = ClosureClass->
getNumFields();
11521 "The number of lambda capture initializers should equal the number of "
11522 "fields within the closure type");
11529 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(ClosureClass);
11530 for (
const auto *Field : ClosureClass->
fields()) {
11533 Expr *
const CurFieldInit = *CaptureInitIt++;
11540 LValue Subobject =
This;
11547 if (!Info.keepEvaluatingAfterFailure())
11555bool RecordExprEvaluator::VisitDesignatedInitUpdateExpr(
11556 const DesignatedInitUpdateExpr *E) {
11566 "can't evaluate expression as a record rvalue");
11567 return RecordExprEvaluator(Info,
This,
Result).Visit(E);
11578class TemporaryExprEvaluator
11579 :
public LValueExprEvaluatorBase<TemporaryExprEvaluator> {
11581 TemporaryExprEvaluator(EvalInfo &Info, LValue &
Result) :
11582 LValueExprEvaluatorBaseTy(Info,
Result,
false) {}
11585 bool VisitConstructExpr(
const Expr *E) {
11591 bool VisitCastExpr(
const CastExpr *E) {
11594 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
11596 case CK_ConstructorConversion:
11600 bool VisitInitListExpr(
const InitListExpr *E) {
11601 return VisitConstructExpr(E);
11603 bool VisitCXXConstructExpr(
const CXXConstructExpr *E) {
11604 return VisitConstructExpr(E);
11606 bool VisitCallExpr(
const CallExpr *E) {
11607 return VisitConstructExpr(E);
11609 bool VisitCXXStdInitializerListExpr(
const CXXStdInitializerListExpr *E) {
11610 return VisitConstructExpr(E);
11613 return VisitConstructExpr(E);
11622 return TemporaryExprEvaluator(Info,
Result).Visit(E);
11630 class VectorExprEvaluator
11631 :
public ExprEvaluatorBase<VectorExprEvaluator> {
11638 bool Success(ArrayRef<APValue>
V,
const Expr *E) {
11639 assert(
V.size() == E->
getType()->
castAs<VectorType>()->getNumElements());
11645 assert(
V.isVector());
11649 bool ZeroInitialization(
const Expr *E);
11651 bool VisitUnaryReal(
const UnaryOperator *E)
11653 bool VisitCastExpr(
const CastExpr* E);
11654 bool VisitInitListExpr(
const InitListExpr *E);
11655 bool VisitUnaryImag(
const UnaryOperator *E);
11656 bool VisitBinaryOperator(
const BinaryOperator *E);
11657 bool VisitUnaryOperator(
const UnaryOperator *E);
11658 bool VisitCallExpr(
const CallExpr *E);
11659 bool VisitConvertVectorExpr(
const ConvertVectorExpr *E);
11660 bool VisitShuffleVectorExpr(
const ShuffleVectorExpr *E);
11669 "not a vector prvalue");
11670 return VectorExprEvaluator(Info,
Result).Visit(E);
11674 assert(Val.
isVector() &&
"expected vector APValue");
11678 llvm::APInt
Result(NumElts, 0);
11680 for (
unsigned I = 0; I < NumElts; ++I) {
11682 assert(Elt.
isInt() &&
"expected integer element in bool vector");
11684 if (Elt.
getInt().getBoolValue())
11691bool VectorExprEvaluator::VisitCastExpr(
const CastExpr *E) {
11692 const VectorType *VTy = E->
getType()->
castAs<VectorType>();
11696 QualType SETy = SE->
getType();
11699 case CK_VectorSplat: {
11705 Val =
APValue(std::move(IntResult));
11710 Val =
APValue(std::move(FloatResult));
11727 Info.FFDiag(E, diag::note_constexpr_invalid_cast)
11728 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
11729 << Info.Ctx.getLangOpts().CPlusPlus;
11733 if (!handleRValueToRValueBitCast(Info,
Result, SVal, E))
11738 case CK_HLSLVectorTruncation: {
11743 for (
unsigned I = 0; I < NElts; I++)
11747 case CK_HLSLMatrixTruncation: {
11753 for (
unsigned Row = 0;
11755 for (
unsigned Col = 0;
11760 case CK_HLSLAggregateSplatCast: {
11777 case CK_HLSLElementwiseCast: {
11790 return Success(ResultEls, E);
11793 return ExprEvaluatorBaseTy::VisitCastExpr(E);
11798VectorExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
11815 unsigned CountInits = 0, CountElts = 0;
11816 while (CountElts < NumElements) {
11818 if (CountInits < NumInits
11824 for (
unsigned j = 0; j < vlen; j++)
11828 llvm::APSInt sInt(32);
11829 if (CountInits < NumInits) {
11833 sInt = Info.Ctx.MakeIntValue(0, EltTy);
11834 Elements.push_back(
APValue(sInt));
11837 llvm::APFloat f(0.0);
11838 if (CountInits < NumInits) {
11842 f = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy));
11843 Elements.push_back(
APValue(f));
11852VectorExprEvaluator::ZeroInitialization(
const Expr *E) {
11856 if (EltTy->isIntegerType())
11857 ZeroElement =
APValue(Info.Ctx.MakeIntValue(0, EltTy));
11860 APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy)));
11866bool VectorExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
11868 return ZeroInitialization(E);
11871bool VectorExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
11873 assert(Op != BO_PtrMemD && Op != BO_PtrMemI && Op != BO_Cmp &&
11874 "Operation not supported on vector types");
11876 if (Op == BO_Comma)
11877 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
11879 Expr *LHS = E->
getLHS();
11880 Expr *RHS = E->
getRHS();
11883 "Must both be vector types");
11886 assert(LHS->
getType()->
castAs<VectorType>()->getNumElements() ==
11890 "All operands must be the same size.");
11894 bool LHSOK =
Evaluate(LHSValue, Info, LHS);
11895 if (!LHSOK && !Info.noteFailure())
11897 if (!
Evaluate(RHSValue, Info, RHS) || !LHSOK)
11919 "Vector can only be int or float type");
11927 "Vector operator ~ can only be int");
11928 Elt.
getInt().flipAllBits();
11938 "Vector can only be int or float type");
11944 EltResult.setAllBits();
11946 EltResult.clearAllBits();
11952 return std::nullopt;
11956bool VectorExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
11962 const QualType ResultEltTy = VD->getElementType();
11966 if (!
Evaluate(SubExprValue, Info, SubExpr))
11979 "Vector length doesn't match type?");
11982 for (
unsigned EltNum = 0; EltNum < VD->getNumElements(); ++EltNum) {
11984 Info.Ctx, ResultEltTy, Op, SubExprValue.
getVectorElt(EltNum));
11987 ResultElements.push_back(*Elt);
11989 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12000 DestTy,
Result.getFloat());
12016 DestTy,
Result.getInt());
12020 Info.FFDiag(E, diag::err_convertvector_constexpr_unsupported_vector_cast)
12021 << SourceTy << DestTy;
12026 llvm::function_ref<APInt(
const APSInt &)> PackFn) {
12035 assert(LHSVecLen != 0 && LHSVecLen == RHSVecLen &&
12036 "pack builtin LHSVecLen must equal to RHSVecLen");
12039 const unsigned SrcBits = Info.Ctx.getIntWidth(VT0->
getElementType());
12045 const unsigned SrcPerLane = 128 / SrcBits;
12046 const unsigned Lanes = LHSVecLen * SrcBits / 128;
12049 Out.reserve(LHSVecLen + RHSVecLen);
12051 for (
unsigned Lane = 0; Lane != Lanes; ++Lane) {
12052 unsigned base = Lane * SrcPerLane;
12053 for (
unsigned I = 0; I != SrcPerLane; ++I)
12056 for (
unsigned I = 0; I != SrcPerLane; ++I)
12067 llvm::function_ref<std::pair<unsigned, int>(
unsigned,
unsigned)>
12074 unsigned ShuffleMask = 0;
12076 bool IsVectorMask =
false;
12077 bool IsSingleOperand = (
Call->getNumArgs() == 2);
12079 if (IsSingleOperand) {
12082 IsVectorMask =
true;
12091 ShuffleMask =
static_cast<unsigned>(MaskImm.getZExtValue());
12101 IsVectorMask =
true;
12110 ShuffleMask =
static_cast<unsigned>(MaskImm.getZExtValue());
12121 ResultElements.reserve(NumElts);
12123 for (
unsigned DstIdx = 0; DstIdx != NumElts; ++DstIdx) {
12124 if (IsVectorMask) {
12125 ShuffleMask =
static_cast<unsigned>(
12126 MaskVector.getVectorElt(DstIdx).getInt().getZExtValue());
12128 auto [SrcVecIdx, SrcIdx] = GetSourceIndex(DstIdx, ShuffleMask);
12134 ResultElements.push_back(
12135 APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(ElemTy))));
12141 ResultElements.push_back(
APValue());
12144 const APValue &Src = (SrcVecIdx == 0) ? A : B;
12149 Out =
APValue(ResultElements.data(), ResultElements.size());
12155 if (OrigVal.isInfinity()) {
12156 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << 0;
12159 if (OrigVal.isNaN()) {
12160 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << 1;
12164 APFloat Val = OrigVal;
12165 bool LosesInfo =
false;
12166 APFloat::opStatus Status = Val.convert(
12167 APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven, &LosesInfo);
12169 if (LosesInfo || Val.isDenormal()) {
12170 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic_strict);
12174 if (Status != APFloat::opOK) {
12175 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
12184 llvm::function_ref<APInt(
const APInt &, uint64_t)> ShiftOp,
12185 llvm::function_ref<APInt(
const APInt &,
unsigned)> OverflowOp) {
12192 assert(
Call->getNumArgs() == 2);
12196 Call->getArg(1)->getType()->isVectorType());
12199 unsigned DestEltWidth = Source.getVectorElt(0).getInt().getBitWidth();
12200 unsigned DestLen = Source.getVectorLength();
12203 unsigned NumBitsInQWord = 64;
12204 unsigned NumCountElts = NumBitsInQWord / CountEltWidth;
12206 Result.reserve(DestLen);
12208 uint64_t CountLQWord = 0;
12209 for (
unsigned EltIdx = 0; EltIdx != NumCountElts; ++EltIdx) {
12211 CountLQWord |= (Elt << (EltIdx * CountEltWidth));
12214 for (
unsigned EltIdx = 0; EltIdx != DestLen; ++EltIdx) {
12215 APInt Elt = Source.getVectorElt(EltIdx).getInt();
12216 if (CountLQWord < DestEltWidth) {
12218 APValue(
APSInt(ShiftOp(Elt, CountLQWord), IsDestUnsigned)));
12221 APValue(
APSInt(OverflowOp(Elt, DestEltWidth), IsDestUnsigned)));
12229 std::optional<APSInt> RoundingMode,
12231 APSInt DefaultMode(APInt(32, 4),
true);
12232 if (RoundingMode.value_or(DefaultMode) != 4)
12233 return std::nullopt;
12234 if (A.isNaN() || A.isInfinity() || A.isDenormal() || B.isNaN() ||
12235 B.isInfinity() || B.isDenormal())
12236 return std::nullopt;
12237 if (A.isZero() && B.isZero())
12239 return IsMin ? llvm::minimum(A, B) : llvm::maximum(A, B);
12242bool VectorExprEvaluator::VisitCallExpr(
const CallExpr *E) {
12243 if (!IsConstantEvaluatedBuiltinCall(E))
12244 return ExprEvaluatorBaseTy::VisitCallExpr(E);
12246 auto EvaluateBinOpExpr =
12248 APValue SourceLHS, SourceRHS;
12254 QualType DestEltTy = DestTy->getElementType();
12255 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
12258 ResultElements.reserve(SourceLen);
12260 if (SourceRHS.
isInt()) {
12262 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12264 ResultElements.push_back(
12268 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12271 ResultElements.push_back(
12278 auto EvaluateFpBinOpExpr =
12279 [&](llvm::function_ref<std::optional<APFloat>(
12280 const APFloat &,
const APFloat &, std::optional<APSInt>)>
12282 bool IsScalar =
false) {
12292 std::optional<APSInt> RoundingMode;
12297 RoundingMode = Imm;
12302 ResultElements.reserve(NumElems);
12304 for (
unsigned EltNum = 0; EltNum < NumElems; ++EltNum) {
12305 if (IsScalar && EltNum > 0) {
12311 std::optional<APFloat>
Result =
Fn(EltA, EltB, RoundingMode);
12319 auto EvaluateScalarFpRoundMaskBinOp =
12320 [&](llvm::function_ref<std::optional<APFloat>(
12321 const APFloat &,
const APFloat &, std::optional<APSInt>)>
12325 APSInt MaskVal, Rounding;
12336 ResultElements.reserve(NumElems);
12338 if (MaskVal.getZExtValue() & 1) {
12341 std::optional<APFloat>
Result =
Fn(EltA, EltB, Rounding);
12349 for (
unsigned I = 1; I < NumElems; ++I)
12355 auto EvalSelectScalar = [&](
unsigned Len) ->
bool {
12363 bool TakeA0 = (Mask.getZExtValue() & 1u) != 0;
12367 for (
unsigned I = 1; I < Len; ++I)
12369 APValue V(Res.data(), Res.size());
12376 case Builtin::BI__builtin_elementwise_popcount:
12377 case Builtin::BI__builtin_elementwise_bitreverse: {
12382 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12385 ResultElements.reserve(SourceLen);
12387 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12390 case Builtin::BI__builtin_elementwise_popcount:
12391 ResultElements.push_back(
APValue(
12392 APSInt(
APInt(Info.Ctx.getIntWidth(DestEltTy), Elt.popcount()),
12395 case Builtin::BI__builtin_elementwise_bitreverse:
12396 ResultElements.push_back(
12403 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12405 case Builtin::BI__builtin_elementwise_abs: {
12410 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12413 ResultElements.reserve(SourceLen);
12415 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12420 CurrentEle.getInt().
abs(),
12421 DestEltTy->isUnsignedIntegerOrEnumerationType()));
12422 ResultElements.push_back(Val);
12425 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12428 case Builtin::BI__builtin_elementwise_add_sat:
12429 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12430 return LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS);
12433 case Builtin::BI__builtin_elementwise_sub_sat:
12434 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12435 return LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
12438 case X86::BI__builtin_ia32_extract128i256:
12439 case X86::BI__builtin_ia32_vextractf128_pd256:
12440 case X86::BI__builtin_ia32_vextractf128_ps256:
12441 case X86::BI__builtin_ia32_vextractf128_si256: {
12442 APValue SourceVec, SourceImm;
12451 unsigned RetLen = RetVT->getNumElements();
12452 unsigned Idx = SourceImm.
getInt().getZExtValue() & 1;
12455 ResultElements.reserve(RetLen);
12457 for (
unsigned I = 0; I < RetLen; I++)
12458 ResultElements.push_back(SourceVec.
getVectorElt(Idx * RetLen + I));
12463 case clang::X86::BI__builtin_ia32_cvtmask2b128:
12464 case clang::X86::BI__builtin_ia32_cvtmask2b256:
12465 case clang::X86::BI__builtin_ia32_cvtmask2b512:
12466 case clang::X86::BI__builtin_ia32_cvtmask2w128:
12467 case clang::X86::BI__builtin_ia32_cvtmask2w256:
12468 case clang::X86::BI__builtin_ia32_cvtmask2w512:
12469 case clang::X86::BI__builtin_ia32_cvtmask2d128:
12470 case clang::X86::BI__builtin_ia32_cvtmask2d256:
12471 case clang::X86::BI__builtin_ia32_cvtmask2d512:
12472 case clang::X86::BI__builtin_ia32_cvtmask2q128:
12473 case clang::X86::BI__builtin_ia32_cvtmask2q256:
12474 case clang::X86::BI__builtin_ia32_cvtmask2q512: {
12480 QualType VecTy = E->
getType();
12481 const VectorType *VT = VecTy->
castAs<VectorType>();
12484 unsigned ElemWidth = Info.Ctx.getTypeSize(ElemTy);
12487 for (
unsigned I = 0; I != VectorLen; ++I) {
12488 bool BitSet = Mask[I];
12489 APSInt ElemVal(ElemWidth,
false);
12491 ElemVal.setAllBits();
12493 Elems.push_back(
APValue(ElemVal));
12498 case X86::BI__builtin_ia32_extracti32x4_256_mask:
12499 case X86::BI__builtin_ia32_extractf32x4_256_mask:
12500 case X86::BI__builtin_ia32_extracti32x4_mask:
12501 case X86::BI__builtin_ia32_extractf32x4_mask:
12502 case X86::BI__builtin_ia32_extracti32x8_mask:
12503 case X86::BI__builtin_ia32_extractf32x8_mask:
12504 case X86::BI__builtin_ia32_extracti64x2_256_mask:
12505 case X86::BI__builtin_ia32_extractf64x2_256_mask:
12506 case X86::BI__builtin_ia32_extracti64x2_512_mask:
12507 case X86::BI__builtin_ia32_extractf64x2_512_mask:
12508 case X86::BI__builtin_ia32_extracti64x4_mask:
12509 case X86::BI__builtin_ia32_extractf64x4_mask: {
12520 unsigned RetLen = RetVT->getNumElements();
12525 unsigned Lanes = SrcLen / RetLen;
12526 unsigned Lane =
static_cast<unsigned>(Imm.getZExtValue() % Lanes);
12527 unsigned Base = Lane * RetLen;
12530 ResultElements.reserve(RetLen);
12531 for (
unsigned I = 0; I < RetLen; ++I) {
12533 ResultElements.push_back(SourceVec.
getVectorElt(Base + I));
12537 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12540 case clang::X86::BI__builtin_ia32_pavgb128:
12541 case clang::X86::BI__builtin_ia32_pavgw128:
12542 case clang::X86::BI__builtin_ia32_pavgb256:
12543 case clang::X86::BI__builtin_ia32_pavgw256:
12544 case clang::X86::BI__builtin_ia32_pavgb512:
12545 case clang::X86::BI__builtin_ia32_pavgw512:
12546 return EvaluateBinOpExpr(llvm::APIntOps::avgCeilU);
12548 case clang::X86::BI__builtin_ia32_pmulhrsw128:
12549 case clang::X86::BI__builtin_ia32_pmulhrsw256:
12550 case clang::X86::BI__builtin_ia32_pmulhrsw512:
12551 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12552 return (llvm::APIntOps::mulsExtended(LHS, RHS).ashr(14) + 1)
12553 .extractBits(16, 1);
12556 case clang::X86::BI__builtin_ia32_pmaddubsw128:
12557 case clang::X86::BI__builtin_ia32_pmaddubsw256:
12558 case clang::X86::BI__builtin_ia32_pmaddubsw512:
12559 case clang::X86::BI__builtin_ia32_pmaddwd128:
12560 case clang::X86::BI__builtin_ia32_pmaddwd256:
12561 case clang::X86::BI__builtin_ia32_pmaddwd512: {
12562 APValue SourceLHS, SourceRHS;
12568 QualType DestEltTy = DestTy->getElementType();
12570 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
12572 ResultElements.reserve(SourceLen / 2);
12574 for (
unsigned EltNum = 0; EltNum < SourceLen; EltNum += 2) {
12579 unsigned BitWidth = 2 * LoLHS.getBitWidth();
12582 case clang::X86::BI__builtin_ia32_pmaddubsw128:
12583 case clang::X86::BI__builtin_ia32_pmaddubsw256:
12584 case clang::X86::BI__builtin_ia32_pmaddubsw512:
12585 ResultElements.push_back(
APValue(
12586 APSInt((LoLHS.zext(BitWidth) * LoRHS.sext(BitWidth))
12587 .sadd_sat((HiLHS.zext(BitWidth) * HiRHS.sext(BitWidth))),
12590 case clang::X86::BI__builtin_ia32_pmaddwd128:
12591 case clang::X86::BI__builtin_ia32_pmaddwd256:
12592 case clang::X86::BI__builtin_ia32_pmaddwd512:
12593 ResultElements.push_back(
12594 APValue(
APSInt((LoLHS.sext(BitWidth) * LoRHS.sext(BitWidth)) +
12595 (HiLHS.sext(BitWidth) * HiRHS.sext(BitWidth)),
12601 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12604 case clang::X86::BI__builtin_ia32_dbpsadbw128:
12605 case clang::X86::BI__builtin_ia32_dbpsadbw256:
12606 case clang::X86::BI__builtin_ia32_dbpsadbw512: {
12607 APValue SourceA, SourceB, SourceImm;
12614 constexpr unsigned LaneSize = 16;
12615 unsigned Imm = SourceImm.
getInt().getZExtValue();
12618 QualType DestEltTy = DestTy->getElementType();
12619 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
12621 ResultElements.reserve(SourceLen / 2);
12627 for (
unsigned I = 0; I < SourceLen; I += LaneSize) {
12628 for (
unsigned J = 0; J < 4; ++J) {
12629 unsigned Part = (Imm >> (2 * J)) & 3;
12630 for (
unsigned K = 0; K < 4; ++K) {
12631 Shuffled[I + 4 * J + K] =
static_cast<uint8_t
>(
12632 SourceB.
getVectorElt(I + 4 * Part + K).getInt().getZExtValue());
12640 unsigned Size = SourceLen / 2;
12641 for (
unsigned I = 0; I <
Size; I += 4) {
12642 unsigned Sad[4] = {0, 0, 0, 0};
12643 for (
unsigned J = 0; J < 4; ++J) {
12644 uint8_t A1 =
static_cast<uint8_t
>(
12645 SourceA.
getVectorElt(2 * I + J).getInt().getZExtValue());
12646 uint8_t A2 =
static_cast<uint8_t
>(
12647 SourceA.
getVectorElt(2 * I + J + 4).getInt().getZExtValue());
12648 uint8_t B0 = Shuffled[2 * I + J];
12649 uint8_t B1 = Shuffled[2 * I + J + 1];
12650 uint8_t B2 = Shuffled[2 * I + J + 2];
12651 uint8_t B3 = Shuffled[2 * I + J + 3];
12652 Sad[0] += (A1 > B0) ? (A1 - B0) : (B0 - A1);
12653 Sad[1] += (A1 > B1) ? (A1 - B1) : (B1 - A1);
12654 Sad[2] += (A2 > B2) ? (A2 - B2) : (B2 - A2);
12655 Sad[3] += (A2 > B3) ? (A2 - B3) : (B3 - A2);
12657 for (
unsigned R = 0;
R < 4; ++
R)
12658 ResultElements.push_back(
12662 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12665 case clang::X86::BI__builtin_ia32_pmulhuw128:
12666 case clang::X86::BI__builtin_ia32_pmulhuw256:
12667 case clang::X86::BI__builtin_ia32_pmulhuw512:
12668 return EvaluateBinOpExpr(llvm::APIntOps::mulhu);
12670 case clang::X86::BI__builtin_ia32_pmulhw128:
12671 case clang::X86::BI__builtin_ia32_pmulhw256:
12672 case clang::X86::BI__builtin_ia32_pmulhw512:
12673 return EvaluateBinOpExpr(llvm::APIntOps::mulhs);
12675 case clang::X86::BI__builtin_ia32_psllv2di:
12676 case clang::X86::BI__builtin_ia32_psllv4di:
12677 case clang::X86::BI__builtin_ia32_psllv4si:
12678 case clang::X86::BI__builtin_ia32_psllv8di:
12679 case clang::X86::BI__builtin_ia32_psllv8hi:
12680 case clang::X86::BI__builtin_ia32_psllv8si:
12681 case clang::X86::BI__builtin_ia32_psllv16hi:
12682 case clang::X86::BI__builtin_ia32_psllv16si:
12683 case clang::X86::BI__builtin_ia32_psllv32hi:
12684 case clang::X86::BI__builtin_ia32_psllwi128:
12685 case clang::X86::BI__builtin_ia32_pslldi128:
12686 case clang::X86::BI__builtin_ia32_psllqi128:
12687 case clang::X86::BI__builtin_ia32_psllwi256:
12688 case clang::X86::BI__builtin_ia32_pslldi256:
12689 case clang::X86::BI__builtin_ia32_psllqi256:
12690 case clang::X86::BI__builtin_ia32_psllwi512:
12691 case clang::X86::BI__builtin_ia32_pslldi512:
12692 case clang::X86::BI__builtin_ia32_psllqi512:
12693 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12694 if (RHS.uge(LHS.getBitWidth())) {
12695 return APInt::getZero(LHS.getBitWidth());
12697 return LHS.shl(RHS.getZExtValue());
12700 case clang::X86::BI__builtin_ia32_psrav4si:
12701 case clang::X86::BI__builtin_ia32_psrav8di:
12702 case clang::X86::BI__builtin_ia32_psrav8hi:
12703 case clang::X86::BI__builtin_ia32_psrav8si:
12704 case clang::X86::BI__builtin_ia32_psrav16hi:
12705 case clang::X86::BI__builtin_ia32_psrav16si:
12706 case clang::X86::BI__builtin_ia32_psrav32hi:
12707 case clang::X86::BI__builtin_ia32_psravq128:
12708 case clang::X86::BI__builtin_ia32_psravq256:
12709 case clang::X86::BI__builtin_ia32_psrawi128:
12710 case clang::X86::BI__builtin_ia32_psradi128:
12711 case clang::X86::BI__builtin_ia32_psraqi128:
12712 case clang::X86::BI__builtin_ia32_psrawi256:
12713 case clang::X86::BI__builtin_ia32_psradi256:
12714 case clang::X86::BI__builtin_ia32_psraqi256:
12715 case clang::X86::BI__builtin_ia32_psrawi512:
12716 case clang::X86::BI__builtin_ia32_psradi512:
12717 case clang::X86::BI__builtin_ia32_psraqi512:
12718 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12719 if (RHS.uge(LHS.getBitWidth())) {
12720 return LHS.ashr(LHS.getBitWidth() - 1);
12722 return LHS.ashr(RHS.getZExtValue());
12725 case clang::X86::BI__builtin_ia32_psrlv2di:
12726 case clang::X86::BI__builtin_ia32_psrlv4di:
12727 case clang::X86::BI__builtin_ia32_psrlv4si:
12728 case clang::X86::BI__builtin_ia32_psrlv8di:
12729 case clang::X86::BI__builtin_ia32_psrlv8hi:
12730 case clang::X86::BI__builtin_ia32_psrlv8si:
12731 case clang::X86::BI__builtin_ia32_psrlv16hi:
12732 case clang::X86::BI__builtin_ia32_psrlv16si:
12733 case clang::X86::BI__builtin_ia32_psrlv32hi:
12734 case clang::X86::BI__builtin_ia32_psrlwi128:
12735 case clang::X86::BI__builtin_ia32_psrldi128:
12736 case clang::X86::BI__builtin_ia32_psrlqi128:
12737 case clang::X86::BI__builtin_ia32_psrlwi256:
12738 case clang::X86::BI__builtin_ia32_psrldi256:
12739 case clang::X86::BI__builtin_ia32_psrlqi256:
12740 case clang::X86::BI__builtin_ia32_psrlwi512:
12741 case clang::X86::BI__builtin_ia32_psrldi512:
12742 case clang::X86::BI__builtin_ia32_psrlqi512:
12743 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12744 if (RHS.uge(LHS.getBitWidth())) {
12745 return APInt::getZero(LHS.getBitWidth());
12747 return LHS.lshr(RHS.getZExtValue());
12749 case X86::BI__builtin_ia32_packsswb128:
12750 case X86::BI__builtin_ia32_packsswb256:
12751 case X86::BI__builtin_ia32_packsswb512:
12752 case X86::BI__builtin_ia32_packssdw128:
12753 case X86::BI__builtin_ia32_packssdw256:
12754 case X86::BI__builtin_ia32_packssdw512:
12756 return APSInt(Src).truncSSat(Src.getBitWidth() / 2);
12758 case X86::BI__builtin_ia32_packusdw128:
12759 case X86::BI__builtin_ia32_packusdw256:
12760 case X86::BI__builtin_ia32_packusdw512:
12761 case X86::BI__builtin_ia32_packuswb128:
12762 case X86::BI__builtin_ia32_packuswb256:
12763 case X86::BI__builtin_ia32_packuswb512:
12765 return APSInt(Src).truncSSatU(Src.getBitWidth() / 2);
12767 case clang::X86::BI__builtin_ia32_selectss_128:
12768 return EvalSelectScalar(4);
12769 case clang::X86::BI__builtin_ia32_selectsd_128:
12770 return EvalSelectScalar(2);
12771 case clang::X86::BI__builtin_ia32_selectsh_128:
12772 case clang::X86::BI__builtin_ia32_selectsbf_128:
12773 return EvalSelectScalar(8);
12774 case clang::X86::BI__builtin_ia32_pmuldq128:
12775 case clang::X86::BI__builtin_ia32_pmuldq256:
12776 case clang::X86::BI__builtin_ia32_pmuldq512:
12777 case clang::X86::BI__builtin_ia32_pmuludq128:
12778 case clang::X86::BI__builtin_ia32_pmuludq256:
12779 case clang::X86::BI__builtin_ia32_pmuludq512: {
12780 APValue SourceLHS, SourceRHS;
12787 ResultElements.reserve(SourceLen / 2);
12789 for (
unsigned EltNum = 0; EltNum < SourceLen; EltNum += 2) {
12794 case clang::X86::BI__builtin_ia32_pmuludq128:
12795 case clang::X86::BI__builtin_ia32_pmuludq256:
12796 case clang::X86::BI__builtin_ia32_pmuludq512:
12797 ResultElements.push_back(
12798 APValue(
APSInt(llvm::APIntOps::muluExtended(LHS, RHS),
true)));
12800 case clang::X86::BI__builtin_ia32_pmuldq128:
12801 case clang::X86::BI__builtin_ia32_pmuldq256:
12802 case clang::X86::BI__builtin_ia32_pmuldq512:
12803 ResultElements.push_back(
12804 APValue(
APSInt(llvm::APIntOps::mulsExtended(LHS, RHS),
false)));
12809 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12812 case X86::BI__builtin_ia32_vpmadd52luq128:
12813 case X86::BI__builtin_ia32_vpmadd52luq256:
12814 case X86::BI__builtin_ia32_vpmadd52luq512: {
12823 ResultElements.reserve(ALen);
12825 for (
unsigned EltNum = 0; EltNum < ALen; EltNum += 1) {
12828 APInt CElt =
C.getVectorElt(EltNum).getInt().trunc(52);
12829 APSInt ResElt(AElt + (BElt * CElt).zext(64),
false);
12830 ResultElements.push_back(
APValue(ResElt));
12833 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12835 case X86::BI__builtin_ia32_vpmadd52huq128:
12836 case X86::BI__builtin_ia32_vpmadd52huq256:
12837 case X86::BI__builtin_ia32_vpmadd52huq512: {
12846 ResultElements.reserve(ALen);
12848 for (
unsigned EltNum = 0; EltNum < ALen; EltNum += 1) {
12851 APInt CElt =
C.getVectorElt(EltNum).getInt().trunc(52);
12852 APSInt ResElt(AElt + llvm::APIntOps::mulhu(BElt, CElt).zext(64),
false);
12853 ResultElements.push_back(
APValue(ResElt));
12856 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12859 case clang::X86::BI__builtin_ia32_vprotbi:
12860 case clang::X86::BI__builtin_ia32_vprotdi:
12861 case clang::X86::BI__builtin_ia32_vprotqi:
12862 case clang::X86::BI__builtin_ia32_vprotwi:
12863 case clang::X86::BI__builtin_ia32_prold128:
12864 case clang::X86::BI__builtin_ia32_prold256:
12865 case clang::X86::BI__builtin_ia32_prold512:
12866 case clang::X86::BI__builtin_ia32_prolq128:
12867 case clang::X86::BI__builtin_ia32_prolq256:
12868 case clang::X86::BI__builtin_ia32_prolq512:
12869 return EvaluateBinOpExpr(
12870 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS.rotl(RHS); });
12872 case clang::X86::BI__builtin_ia32_prord128:
12873 case clang::X86::BI__builtin_ia32_prord256:
12874 case clang::X86::BI__builtin_ia32_prord512:
12875 case clang::X86::BI__builtin_ia32_prorq128:
12876 case clang::X86::BI__builtin_ia32_prorq256:
12877 case clang::X86::BI__builtin_ia32_prorq512:
12878 return EvaluateBinOpExpr(
12879 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS.rotr(RHS); });
12881 case Builtin::BI__builtin_elementwise_max:
12882 case Builtin::BI__builtin_elementwise_min: {
12883 APValue SourceLHS, SourceRHS;
12888 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12895 ResultElements.reserve(SourceLen);
12897 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12901 case Builtin::BI__builtin_elementwise_max:
12902 ResultElements.push_back(
12906 case Builtin::BI__builtin_elementwise_min:
12907 ResultElements.push_back(
12914 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12916 case X86::BI__builtin_ia32_vpshldd128:
12917 case X86::BI__builtin_ia32_vpshldd256:
12918 case X86::BI__builtin_ia32_vpshldd512:
12919 case X86::BI__builtin_ia32_vpshldq128:
12920 case X86::BI__builtin_ia32_vpshldq256:
12921 case X86::BI__builtin_ia32_vpshldq512:
12922 case X86::BI__builtin_ia32_vpshldw128:
12923 case X86::BI__builtin_ia32_vpshldw256:
12924 case X86::BI__builtin_ia32_vpshldw512: {
12925 APValue SourceHi, SourceLo, SourceAmt;
12931 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12934 ResultElements.reserve(SourceLen);
12937 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12940 APInt R = llvm::APIntOps::fshl(Hi, Lo, Amt);
12941 ResultElements.push_back(
12945 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12947 case X86::BI__builtin_ia32_vpshrdd128:
12948 case X86::BI__builtin_ia32_vpshrdd256:
12949 case X86::BI__builtin_ia32_vpshrdd512:
12950 case X86::BI__builtin_ia32_vpshrdq128:
12951 case X86::BI__builtin_ia32_vpshrdq256:
12952 case X86::BI__builtin_ia32_vpshrdq512:
12953 case X86::BI__builtin_ia32_vpshrdw128:
12954 case X86::BI__builtin_ia32_vpshrdw256:
12955 case X86::BI__builtin_ia32_vpshrdw512: {
12957 APValue SourceHi, SourceLo, SourceAmt;
12963 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12966 ResultElements.reserve(SourceLen);
12969 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12972 APInt R = llvm::APIntOps::fshr(Hi, Lo, Amt);
12973 ResultElements.push_back(
12977 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12979 case X86::BI__builtin_ia32_compressdf128_mask:
12980 case X86::BI__builtin_ia32_compressdf256_mask:
12981 case X86::BI__builtin_ia32_compressdf512_mask:
12982 case X86::BI__builtin_ia32_compressdi128_mask:
12983 case X86::BI__builtin_ia32_compressdi256_mask:
12984 case X86::BI__builtin_ia32_compressdi512_mask:
12985 case X86::BI__builtin_ia32_compresshi128_mask:
12986 case X86::BI__builtin_ia32_compresshi256_mask:
12987 case X86::BI__builtin_ia32_compresshi512_mask:
12988 case X86::BI__builtin_ia32_compressqi128_mask:
12989 case X86::BI__builtin_ia32_compressqi256_mask:
12990 case X86::BI__builtin_ia32_compressqi512_mask:
12991 case X86::BI__builtin_ia32_compresssf128_mask:
12992 case X86::BI__builtin_ia32_compresssf256_mask:
12993 case X86::BI__builtin_ia32_compresssf512_mask:
12994 case X86::BI__builtin_ia32_compresssi128_mask:
12995 case X86::BI__builtin_ia32_compresssi256_mask:
12996 case X86::BI__builtin_ia32_compresssi512_mask: {
13007 ResultElements.reserve(NumElts);
13009 for (
unsigned I = 0; I != NumElts; ++I) {
13013 for (
unsigned I = ResultElements.size(); I != NumElts; ++I) {
13017 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13019 case X86::BI__builtin_ia32_expanddf128_mask:
13020 case X86::BI__builtin_ia32_expanddf256_mask:
13021 case X86::BI__builtin_ia32_expanddf512_mask:
13022 case X86::BI__builtin_ia32_expanddi128_mask:
13023 case X86::BI__builtin_ia32_expanddi256_mask:
13024 case X86::BI__builtin_ia32_expanddi512_mask:
13025 case X86::BI__builtin_ia32_expandhi128_mask:
13026 case X86::BI__builtin_ia32_expandhi256_mask:
13027 case X86::BI__builtin_ia32_expandhi512_mask:
13028 case X86::BI__builtin_ia32_expandqi128_mask:
13029 case X86::BI__builtin_ia32_expandqi256_mask:
13030 case X86::BI__builtin_ia32_expandqi512_mask:
13031 case X86::BI__builtin_ia32_expandsf128_mask:
13032 case X86::BI__builtin_ia32_expandsf256_mask:
13033 case X86::BI__builtin_ia32_expandsf512_mask:
13034 case X86::BI__builtin_ia32_expandsi128_mask:
13035 case X86::BI__builtin_ia32_expandsi256_mask:
13036 case X86::BI__builtin_ia32_expandsi512_mask: {
13047 ResultElements.reserve(NumElts);
13049 unsigned SourceIdx = 0;
13050 for (
unsigned I = 0; I != NumElts; ++I) {
13052 ResultElements.push_back(Source.
getVectorElt(SourceIdx++));
13056 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13058 case X86::BI__builtin_ia32_vpconflictsi_128:
13059 case X86::BI__builtin_ia32_vpconflictsi_256:
13060 case X86::BI__builtin_ia32_vpconflictsi_512:
13061 case X86::BI__builtin_ia32_vpconflictdi_128:
13062 case X86::BI__builtin_ia32_vpconflictdi_256:
13063 case X86::BI__builtin_ia32_vpconflictdi_512: {
13071 ResultElements.reserve(SourceLen);
13074 bool DestUnsigned =
13075 VecT->getElementType()->isUnsignedIntegerOrEnumerationType();
13077 for (
unsigned I = 0; I != SourceLen; ++I) {
13080 APInt ConflictMask(EltI.
getInt().getBitWidth(), 0);
13081 for (
unsigned J = 0; J != I; ++J) {
13083 ConflictMask.setBitVal(J, EltI.
getInt() == EltJ.
getInt());
13085 ResultElements.push_back(
APValue(
APSInt(ConflictMask, DestUnsigned)));
13087 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13089 case X86::BI__builtin_ia32_blendpd:
13090 case X86::BI__builtin_ia32_blendpd256:
13091 case X86::BI__builtin_ia32_blendps:
13092 case X86::BI__builtin_ia32_blendps256:
13093 case X86::BI__builtin_ia32_pblendw128:
13094 case X86::BI__builtin_ia32_pblendw256:
13095 case X86::BI__builtin_ia32_pblendd128:
13096 case X86::BI__builtin_ia32_pblendd256: {
13097 APValue SourceF, SourceT, SourceC;
13106 ResultElements.reserve(SourceLen);
13107 for (
unsigned EltNum = 0; EltNum != SourceLen; ++EltNum) {
13110 ResultElements.push_back(
C[EltNum % 8] ? T : F);
13113 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13116 case X86::BI__builtin_ia32_psignb128:
13117 case X86::BI__builtin_ia32_psignb256:
13118 case X86::BI__builtin_ia32_psignw128:
13119 case X86::BI__builtin_ia32_psignw256:
13120 case X86::BI__builtin_ia32_psignd128:
13121 case X86::BI__builtin_ia32_psignd256:
13122 return EvaluateBinOpExpr([](
const APInt &AElem,
const APInt &BElem) {
13123 if (BElem.isZero())
13124 return APInt::getZero(AElem.getBitWidth());
13125 if (BElem.isNegative())
13130 case X86::BI__builtin_ia32_blendvpd:
13131 case X86::BI__builtin_ia32_blendvpd256:
13132 case X86::BI__builtin_ia32_blendvps:
13133 case X86::BI__builtin_ia32_blendvps256:
13134 case X86::BI__builtin_ia32_pblendvb128:
13135 case X86::BI__builtin_ia32_pblendvb256: {
13137 APValue SourceF, SourceT, SourceC;
13145 ResultElements.reserve(SourceLen);
13147 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13151 APInt M =
C.isInt() ? (
APInt)
C.getInt() :
C.getFloat().bitcastToAPInt();
13152 ResultElements.push_back(M.isNegative() ? T : F);
13155 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13157 case X86::BI__builtin_ia32_selectb_128:
13158 case X86::BI__builtin_ia32_selectb_256:
13159 case X86::BI__builtin_ia32_selectb_512:
13160 case X86::BI__builtin_ia32_selectw_128:
13161 case X86::BI__builtin_ia32_selectw_256:
13162 case X86::BI__builtin_ia32_selectw_512:
13163 case X86::BI__builtin_ia32_selectd_128:
13164 case X86::BI__builtin_ia32_selectd_256:
13165 case X86::BI__builtin_ia32_selectd_512:
13166 case X86::BI__builtin_ia32_selectq_128:
13167 case X86::BI__builtin_ia32_selectq_256:
13168 case X86::BI__builtin_ia32_selectq_512:
13169 case X86::BI__builtin_ia32_selectph_128:
13170 case X86::BI__builtin_ia32_selectph_256:
13171 case X86::BI__builtin_ia32_selectph_512:
13172 case X86::BI__builtin_ia32_selectpbf_128:
13173 case X86::BI__builtin_ia32_selectpbf_256:
13174 case X86::BI__builtin_ia32_selectpbf_512:
13175 case X86::BI__builtin_ia32_selectps_128:
13176 case X86::BI__builtin_ia32_selectps_256:
13177 case X86::BI__builtin_ia32_selectps_512:
13178 case X86::BI__builtin_ia32_selectpd_128:
13179 case X86::BI__builtin_ia32_selectpd_256:
13180 case X86::BI__builtin_ia32_selectpd_512: {
13182 APValue SourceMask, SourceLHS, SourceRHS;
13191 ResultElements.reserve(SourceLen);
13193 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13196 ResultElements.push_back(Mask[EltNum] ? LHS : RHS);
13199 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13202 case X86::BI__builtin_ia32_cvtsd2ss: {
13215 Elements.push_back(ResultVal);
13218 for (
unsigned I = 1; I < NumEltsA; ++I) {
13224 case X86::BI__builtin_ia32_cvtsd2ss_round_mask: {
13225 APValue VecA, VecB, VecSrc, MaskValue;
13233 unsigned Mask = MaskValue.
getInt().getZExtValue();
13241 Elements.push_back(ResultVal);
13247 for (
unsigned I = 1; I < NumEltsA; ++I) {
13253 case X86::BI__builtin_ia32_cvtpd2ps:
13254 case X86::BI__builtin_ia32_cvtpd2ps256:
13255 case X86::BI__builtin_ia32_cvtpd2ps_mask:
13256 case X86::BI__builtin_ia32_cvtpd2ps512_mask: {
13259 bool IsMasked = (BuiltinID == X86::BI__builtin_ia32_cvtpd2ps_mask ||
13260 BuiltinID == X86::BI__builtin_ia32_cvtpd2ps512_mask);
13267 unsigned Mask = 0xFFFFFFFF;
13268 bool NeedsMerge =
false;
13273 Mask = MaskValue.
getInt().getZExtValue();
13274 auto NumEltsResult = E->
getType()->
getAs<VectorType>()->getNumElements();
13275 for (
unsigned I = 0; I < NumEltsResult; ++I) {
13276 if (!((Mask >> I) & 1)) {
13287 unsigned NumEltsResult =
13291 for (
unsigned I = 0; I < NumEltsResult; ++I) {
13292 if (IsMasked && !((Mask >> I) & 1)) {
13300 if (I >= NumEltsInput) {
13301 Elements.push_back(
APValue(APFloat::getZero(APFloat::IEEEsingle())));
13310 Elements.push_back(ResultVal);
13315 case X86::BI__builtin_ia32_shufps:
13316 case X86::BI__builtin_ia32_shufps256:
13317 case X86::BI__builtin_ia32_shufps512: {
13321 [](
unsigned DstIdx,
13322 unsigned ShuffleMask) -> std::pair<unsigned, int> {
13323 constexpr unsigned LaneBits = 128u;
13324 unsigned NumElemPerLane = LaneBits / 32;
13325 unsigned NumSelectableElems = NumElemPerLane / 2;
13326 unsigned BitsPerElem = 2;
13327 unsigned IndexMask = (1u << BitsPerElem) - 1;
13328 unsigned MaskBits = 8;
13329 unsigned Lane = DstIdx / NumElemPerLane;
13330 unsigned ElemInLane = DstIdx % NumElemPerLane;
13331 unsigned LaneOffset = Lane * NumElemPerLane;
13332 unsigned BitIndex = (DstIdx * BitsPerElem) % MaskBits;
13333 unsigned SrcIdx = (ElemInLane < NumSelectableElems) ? 0 : 1;
13334 unsigned Index = (ShuffleMask >> BitIndex) & IndexMask;
13335 return {SrcIdx,
static_cast<int>(LaneOffset + Index)};
13340 case X86::BI__builtin_ia32_shufpd:
13341 case X86::BI__builtin_ia32_shufpd256:
13342 case X86::BI__builtin_ia32_shufpd512: {
13346 [](
unsigned DstIdx,
13347 unsigned ShuffleMask) -> std::pair<unsigned, int> {
13348 constexpr unsigned LaneBits = 128u;
13349 unsigned NumElemPerLane = LaneBits / 64;
13350 unsigned NumSelectableElems = NumElemPerLane / 2;
13351 unsigned BitsPerElem = 1;
13352 unsigned IndexMask = (1u << BitsPerElem) - 1;
13353 unsigned MaskBits = 8;
13354 unsigned Lane = DstIdx / NumElemPerLane;
13355 unsigned ElemInLane = DstIdx % NumElemPerLane;
13356 unsigned LaneOffset = Lane * NumElemPerLane;
13357 unsigned BitIndex = (DstIdx * BitsPerElem) % MaskBits;
13358 unsigned SrcIdx = (ElemInLane < NumSelectableElems) ? 0 : 1;
13359 unsigned Index = (ShuffleMask >> BitIndex) & IndexMask;
13360 return {SrcIdx,
static_cast<int>(LaneOffset + Index)};
13365 case X86::BI__builtin_ia32_insertps128: {
13369 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13371 if ((Mask & (1 << DstIdx)) != 0) {
13376 unsigned SrcElem = (Mask >> 6) & 0x3;
13377 unsigned DstElem = (Mask >> 4) & 0x3;
13378 if (DstIdx == DstElem) {
13380 return {1,
static_cast<int>(SrcElem)};
13383 return {0,
static_cast<int>(DstIdx)};
13389 case X86::BI__builtin_ia32_pshufb128:
13390 case X86::BI__builtin_ia32_pshufb256:
13391 case X86::BI__builtin_ia32_pshufb512: {
13395 [](
unsigned DstIdx,
13396 unsigned ShuffleMask) -> std::pair<unsigned, int> {
13397 uint8_t Ctlb =
static_cast<uint8_t
>(ShuffleMask);
13399 return std::make_pair(0, -1);
13401 unsigned LaneBase = (DstIdx / 16) * 16;
13402 unsigned SrcOffset = Ctlb & 0x0F;
13403 unsigned SrcIdx = LaneBase + SrcOffset;
13404 return std::make_pair(0,
static_cast<int>(SrcIdx));
13410 case X86::BI__builtin_ia32_pshuflw:
13411 case X86::BI__builtin_ia32_pshuflw256:
13412 case X86::BI__builtin_ia32_pshuflw512: {
13416 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13417 constexpr unsigned LaneBits = 128u;
13418 constexpr unsigned ElemBits = 16u;
13419 constexpr unsigned LaneElts = LaneBits / ElemBits;
13420 constexpr unsigned HalfSize = 4;
13421 unsigned LaneBase = (DstIdx / LaneElts) * LaneElts;
13422 unsigned LaneIdx = DstIdx % LaneElts;
13423 if (LaneIdx < HalfSize) {
13424 unsigned Sel = (Mask >> (2 * LaneIdx)) & 0x3;
13425 return std::make_pair(0,
static_cast<int>(LaneBase + Sel));
13427 return std::make_pair(0,
static_cast<int>(DstIdx));
13433 case X86::BI__builtin_ia32_pshufhw:
13434 case X86::BI__builtin_ia32_pshufhw256:
13435 case X86::BI__builtin_ia32_pshufhw512: {
13439 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13440 constexpr unsigned LaneBits = 128u;
13441 constexpr unsigned ElemBits = 16u;
13442 constexpr unsigned LaneElts = LaneBits / ElemBits;
13443 constexpr unsigned HalfSize = 4;
13444 unsigned LaneBase = (DstIdx / LaneElts) * LaneElts;
13445 unsigned LaneIdx = DstIdx % LaneElts;
13446 if (LaneIdx >= HalfSize) {
13447 unsigned Rel = LaneIdx - HalfSize;
13448 unsigned Sel = (Mask >> (2 * Rel)) & 0x3;
13449 return std::make_pair(
13450 0,
static_cast<int>(LaneBase + HalfSize + Sel));
13452 return std::make_pair(0,
static_cast<int>(DstIdx));
13458 case X86::BI__builtin_ia32_pshufd:
13459 case X86::BI__builtin_ia32_pshufd256:
13460 case X86::BI__builtin_ia32_pshufd512:
13461 case X86::BI__builtin_ia32_vpermilps:
13462 case X86::BI__builtin_ia32_vpermilps256:
13463 case X86::BI__builtin_ia32_vpermilps512: {
13467 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13468 constexpr unsigned LaneBits = 128u;
13469 constexpr unsigned ElemBits = 32u;
13470 constexpr unsigned LaneElts = LaneBits / ElemBits;
13471 unsigned LaneBase = (DstIdx / LaneElts) * LaneElts;
13472 unsigned LaneIdx = DstIdx % LaneElts;
13473 unsigned Sel = (Mask >> (2 * LaneIdx)) & 0x3;
13474 return std::make_pair(0,
static_cast<int>(LaneBase + Sel));
13480 case X86::BI__builtin_ia32_vpermilvarpd:
13481 case X86::BI__builtin_ia32_vpermilvarpd256:
13482 case X86::BI__builtin_ia32_vpermilvarpd512: {
13486 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13487 unsigned NumElemPerLane = 2;
13488 unsigned Lane = DstIdx / NumElemPerLane;
13489 unsigned Offset = Mask & 0b10 ? 1 : 0;
13490 return std::make_pair(
13491 0,
static_cast<int>(Lane * NumElemPerLane + Offset));
13497 case X86::BI__builtin_ia32_vpermilpd:
13498 case X86::BI__builtin_ia32_vpermilpd256:
13499 case X86::BI__builtin_ia32_vpermilpd512: {
13502 unsigned NumElemPerLane = 2;
13503 unsigned BitsPerElem = 1;
13504 unsigned MaskBits = 8;
13505 unsigned IndexMask = 0x1;
13506 unsigned Lane = DstIdx / NumElemPerLane;
13507 unsigned LaneOffset = Lane * NumElemPerLane;
13508 unsigned BitIndex = (DstIdx * BitsPerElem) % MaskBits;
13509 unsigned Index = (Control >> BitIndex) & IndexMask;
13510 return std::make_pair(0,
static_cast<int>(LaneOffset + Index));
13516 case X86::BI__builtin_ia32_permdf256:
13517 case X86::BI__builtin_ia32_permdi256: {
13522 unsigned Index = (Control >> (2 * DstIdx)) & 0x3;
13523 return std::make_pair(0,
static_cast<int>(Index));
13529 case X86::BI__builtin_ia32_vpermilvarps:
13530 case X86::BI__builtin_ia32_vpermilvarps256:
13531 case X86::BI__builtin_ia32_vpermilvarps512: {
13535 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13536 unsigned NumElemPerLane = 4;
13537 unsigned Lane = DstIdx / NumElemPerLane;
13538 unsigned Offset = Mask & 0b11;
13539 return std::make_pair(
13540 0,
static_cast<int>(Lane * NumElemPerLane + Offset));
13546 case X86::BI__builtin_ia32_vpmultishiftqb128:
13547 case X86::BI__builtin_ia32_vpmultishiftqb256:
13548 case X86::BI__builtin_ia32_vpmultishiftqb512: {
13556 unsigned NumBytesInQWord = 8;
13557 unsigned NumBitsInByte = 8;
13559 unsigned NumQWords = NumBytes / NumBytesInQWord;
13561 Result.reserve(NumBytes);
13563 for (
unsigned QWordId = 0; QWordId != NumQWords; ++QWordId) {
13564 APInt BQWord(64, 0);
13565 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
13566 unsigned Idx = QWordId * NumBytesInQWord + ByteIdx;
13568 BQWord.insertBits(
APInt(8, Byte & 0xFF), ByteIdx * NumBitsInByte);
13571 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
13572 unsigned Idx = QWordId * NumBytesInQWord + ByteIdx;
13576 for (
unsigned BitIdx = 0; BitIdx != NumBitsInByte; ++BitIdx) {
13577 Byte.setBitVal(BitIdx, BQWord[(Ctrl + BitIdx) & 0x3F]);
13585 case X86::BI__builtin_ia32_phminposuw128: {
13592 unsigned ElemBitWidth = Info.Ctx.getTypeSize(ElemQT);
13594 APInt MinIndex(ElemBitWidth, 0);
13596 for (
unsigned I = 1; I != SourceLen; ++I) {
13598 if (MinVal.ugt(Val)) {
13607 ->isUnsignedIntegerOrEnumerationType();
13610 Result.reserve(SourceLen);
13612 Result.emplace_back(
APSInt(MinIndex, ResultUnsigned));
13613 for (
unsigned I = 0; I != SourceLen - 2; ++I) {
13619 case X86::BI__builtin_ia32_psraq128:
13620 case X86::BI__builtin_ia32_psraq256:
13621 case X86::BI__builtin_ia32_psraq512:
13622 case X86::BI__builtin_ia32_psrad128:
13623 case X86::BI__builtin_ia32_psrad256:
13624 case X86::BI__builtin_ia32_psrad512:
13625 case X86::BI__builtin_ia32_psraw128:
13626 case X86::BI__builtin_ia32_psraw256:
13627 case X86::BI__builtin_ia32_psraw512: {
13631 [](
const APInt &Elt, uint64_t Count) {
return Elt.ashr(Count); },
13632 [](
const APInt &Elt,
unsigned Width) {
13633 return Elt.ashr(Width - 1);
13639 case X86::BI__builtin_ia32_psllq128:
13640 case X86::BI__builtin_ia32_psllq256:
13641 case X86::BI__builtin_ia32_psllq512:
13642 case X86::BI__builtin_ia32_pslld128:
13643 case X86::BI__builtin_ia32_pslld256:
13644 case X86::BI__builtin_ia32_pslld512:
13645 case X86::BI__builtin_ia32_psllw128:
13646 case X86::BI__builtin_ia32_psllw256:
13647 case X86::BI__builtin_ia32_psllw512: {
13651 [](
const APInt &Elt, uint64_t Count) {
return Elt.shl(Count); },
13652 [](
const APInt &Elt,
unsigned Width) {
13653 return APInt::getZero(Width);
13659 case X86::BI__builtin_ia32_psrlq128:
13660 case X86::BI__builtin_ia32_psrlq256:
13661 case X86::BI__builtin_ia32_psrlq512:
13662 case X86::BI__builtin_ia32_psrld128:
13663 case X86::BI__builtin_ia32_psrld256:
13664 case X86::BI__builtin_ia32_psrld512:
13665 case X86::BI__builtin_ia32_psrlw128:
13666 case X86::BI__builtin_ia32_psrlw256:
13667 case X86::BI__builtin_ia32_psrlw512: {
13671 [](
const APInt &Elt, uint64_t Count) {
return Elt.lshr(Count); },
13672 [](
const APInt &Elt,
unsigned Width) {
13673 return APInt::getZero(Width);
13679 case X86::BI__builtin_ia32_pternlogd128_mask:
13680 case X86::BI__builtin_ia32_pternlogd256_mask:
13681 case X86::BI__builtin_ia32_pternlogd512_mask:
13682 case X86::BI__builtin_ia32_pternlogq128_mask:
13683 case X86::BI__builtin_ia32_pternlogq256_mask:
13684 case X86::BI__builtin_ia32_pternlogq512_mask: {
13685 APValue AValue, BValue, CValue, ImmValue, UValue;
13693 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13699 ResultElements.reserve(ResultLen);
13701 for (
unsigned EltNum = 0; EltNum < ResultLen; ++EltNum) {
13707 unsigned BitWidth = ALane.getBitWidth();
13708 APInt ResLane(BitWidth, 0);
13710 for (
unsigned Bit = 0; Bit < BitWidth; ++Bit) {
13711 unsigned ABit = ALane[Bit];
13712 unsigned BBit = BLane[Bit];
13713 unsigned CBit = CLane[Bit];
13715 unsigned Idx = (ABit << 2) | (BBit << 1) | CBit;
13716 ResLane.setBitVal(Bit, Imm[Idx]);
13718 ResultElements.push_back(
APValue(
APSInt(ResLane, DestUnsigned)));
13720 ResultElements.push_back(
APValue(
APSInt(ALane, DestUnsigned)));
13723 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13725 case X86::BI__builtin_ia32_pternlogd128_maskz:
13726 case X86::BI__builtin_ia32_pternlogd256_maskz:
13727 case X86::BI__builtin_ia32_pternlogd512_maskz:
13728 case X86::BI__builtin_ia32_pternlogq128_maskz:
13729 case X86::BI__builtin_ia32_pternlogq256_maskz:
13730 case X86::BI__builtin_ia32_pternlogq512_maskz: {
13731 APValue AValue, BValue, CValue, ImmValue, UValue;
13739 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13745 ResultElements.reserve(ResultLen);
13747 for (
unsigned EltNum = 0; EltNum < ResultLen; ++EltNum) {
13752 unsigned BitWidth = ALane.getBitWidth();
13753 APInt ResLane(BitWidth, 0);
13756 for (
unsigned Bit = 0; Bit < BitWidth; ++Bit) {
13757 unsigned ABit = ALane[Bit];
13758 unsigned BBit = BLane[Bit];
13759 unsigned CBit = CLane[Bit];
13761 unsigned Idx = (ABit << 2) | (BBit << 1) | CBit;
13762 ResLane.setBitVal(Bit, Imm[Idx]);
13765 ResultElements.push_back(
APValue(
APSInt(ResLane, DestUnsigned)));
13767 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13770 case Builtin::BI__builtin_elementwise_clzg:
13771 case Builtin::BI__builtin_elementwise_ctzg: {
13773 std::optional<APValue> Fallback;
13780 Fallback = FallbackTmp;
13783 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13786 ResultElements.reserve(SourceLen);
13788 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13793 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
13795 Builtin::BI__builtin_elementwise_ctzg);
13798 ResultElements.push_back(Fallback->getVectorElt(EltNum));
13802 case Builtin::BI__builtin_elementwise_clzg:
13803 ResultElements.push_back(
APValue(
13804 APSInt(
APInt(Info.Ctx.getIntWidth(DestEltTy), LHS.countl_zero()),
13807 case Builtin::BI__builtin_elementwise_ctzg:
13808 ResultElements.push_back(
APValue(
13809 APSInt(
APInt(Info.Ctx.getIntWidth(DestEltTy), LHS.countr_zero()),
13815 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13818 case Builtin::BI__builtin_elementwise_fma: {
13819 APValue SourceX, SourceY, SourceZ;
13827 ResultElements.reserve(SourceLen);
13829 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13834 (void)
Result.fusedMultiplyAdd(Y, Z, RM);
13837 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13840 case clang::X86::BI__builtin_ia32_phaddw128:
13841 case clang::X86::BI__builtin_ia32_phaddw256:
13842 case clang::X86::BI__builtin_ia32_phaddd128:
13843 case clang::X86::BI__builtin_ia32_phaddd256:
13844 case clang::X86::BI__builtin_ia32_phaddsw128:
13845 case clang::X86::BI__builtin_ia32_phaddsw256:
13847 case clang::X86::BI__builtin_ia32_phsubw128:
13848 case clang::X86::BI__builtin_ia32_phsubw256:
13849 case clang::X86::BI__builtin_ia32_phsubd128:
13850 case clang::X86::BI__builtin_ia32_phsubd256:
13851 case clang::X86::BI__builtin_ia32_phsubsw128:
13852 case clang::X86::BI__builtin_ia32_phsubsw256: {
13853 APValue SourceLHS, SourceRHS;
13857 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13861 unsigned EltBits = Info.Ctx.getIntWidth(DestEltTy);
13862 unsigned EltsPerLane = 128 / EltBits;
13864 ResultElements.reserve(NumElts);
13866 for (
unsigned LaneStart = 0; LaneStart != NumElts;
13867 LaneStart += EltsPerLane) {
13868 for (
unsigned I = 0; I != EltsPerLane; I += 2) {
13872 case clang::X86::BI__builtin_ia32_phaddw128:
13873 case clang::X86::BI__builtin_ia32_phaddw256:
13874 case clang::X86::BI__builtin_ia32_phaddd128:
13875 case clang::X86::BI__builtin_ia32_phaddd256: {
13876 APSInt Res(LHSA + LHSB, DestUnsigned);
13877 ResultElements.push_back(
APValue(Res));
13880 case clang::X86::BI__builtin_ia32_phaddsw128:
13881 case clang::X86::BI__builtin_ia32_phaddsw256: {
13882 APSInt Res(LHSA.sadd_sat(LHSB));
13883 ResultElements.push_back(
APValue(Res));
13886 case clang::X86::BI__builtin_ia32_phsubw128:
13887 case clang::X86::BI__builtin_ia32_phsubw256:
13888 case clang::X86::BI__builtin_ia32_phsubd128:
13889 case clang::X86::BI__builtin_ia32_phsubd256: {
13890 APSInt Res(LHSA - LHSB, DestUnsigned);
13891 ResultElements.push_back(
APValue(Res));
13894 case clang::X86::BI__builtin_ia32_phsubsw128:
13895 case clang::X86::BI__builtin_ia32_phsubsw256: {
13896 APSInt Res(LHSA.ssub_sat(LHSB));
13897 ResultElements.push_back(
APValue(Res));
13902 for (
unsigned I = 0; I != EltsPerLane; I += 2) {
13906 case clang::X86::BI__builtin_ia32_phaddw128:
13907 case clang::X86::BI__builtin_ia32_phaddw256:
13908 case clang::X86::BI__builtin_ia32_phaddd128:
13909 case clang::X86::BI__builtin_ia32_phaddd256: {
13910 APSInt Res(RHSA + RHSB, DestUnsigned);
13911 ResultElements.push_back(
APValue(Res));
13914 case clang::X86::BI__builtin_ia32_phaddsw128:
13915 case clang::X86::BI__builtin_ia32_phaddsw256: {
13916 APSInt Res(RHSA.sadd_sat(RHSB));
13917 ResultElements.push_back(
APValue(Res));
13920 case clang::X86::BI__builtin_ia32_phsubw128:
13921 case clang::X86::BI__builtin_ia32_phsubw256:
13922 case clang::X86::BI__builtin_ia32_phsubd128:
13923 case clang::X86::BI__builtin_ia32_phsubd256: {
13924 APSInt Res(RHSA - RHSB, DestUnsigned);
13925 ResultElements.push_back(
APValue(Res));
13928 case clang::X86::BI__builtin_ia32_phsubsw128:
13929 case clang::X86::BI__builtin_ia32_phsubsw256: {
13930 APSInt Res(RHSA.ssub_sat(RHSB));
13931 ResultElements.push_back(
APValue(Res));
13937 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13939 case clang::X86::BI__builtin_ia32_haddpd:
13940 case clang::X86::BI__builtin_ia32_haddps:
13941 case clang::X86::BI__builtin_ia32_haddps256:
13942 case clang::X86::BI__builtin_ia32_haddpd256:
13943 case clang::X86::BI__builtin_ia32_hsubpd:
13944 case clang::X86::BI__builtin_ia32_hsubps:
13945 case clang::X86::BI__builtin_ia32_hsubps256:
13946 case clang::X86::BI__builtin_ia32_hsubpd256: {
13947 APValue SourceLHS, SourceRHS;
13953 ResultElements.reserve(NumElts);
13955 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13956 unsigned EltBits = Info.Ctx.getTypeSize(DestEltTy);
13957 unsigned NumLanes = NumElts * EltBits / 128;
13958 unsigned NumElemsPerLane = NumElts / NumLanes;
13959 unsigned HalfElemsPerLane = NumElemsPerLane / 2;
13961 for (
unsigned L = 0; L != NumElts; L += NumElemsPerLane) {
13962 for (
unsigned I = 0; I != HalfElemsPerLane; ++I) {
13966 case clang::X86::BI__builtin_ia32_haddpd:
13967 case clang::X86::BI__builtin_ia32_haddps:
13968 case clang::X86::BI__builtin_ia32_haddps256:
13969 case clang::X86::BI__builtin_ia32_haddpd256:
13970 LHSA.add(LHSB, RM);
13972 case clang::X86::BI__builtin_ia32_hsubpd:
13973 case clang::X86::BI__builtin_ia32_hsubps:
13974 case clang::X86::BI__builtin_ia32_hsubps256:
13975 case clang::X86::BI__builtin_ia32_hsubpd256:
13976 LHSA.subtract(LHSB, RM);
13979 ResultElements.push_back(
APValue(LHSA));
13981 for (
unsigned I = 0; I != HalfElemsPerLane; ++I) {
13985 case clang::X86::BI__builtin_ia32_haddpd:
13986 case clang::X86::BI__builtin_ia32_haddps:
13987 case clang::X86::BI__builtin_ia32_haddps256:
13988 case clang::X86::BI__builtin_ia32_haddpd256:
13989 RHSA.add(RHSB, RM);
13991 case clang::X86::BI__builtin_ia32_hsubpd:
13992 case clang::X86::BI__builtin_ia32_hsubps:
13993 case clang::X86::BI__builtin_ia32_hsubps256:
13994 case clang::X86::BI__builtin_ia32_hsubpd256:
13995 RHSA.subtract(RHSB, RM);
13998 ResultElements.push_back(
APValue(RHSA));
14001 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14003 case clang::X86::BI__builtin_ia32_addsubpd:
14004 case clang::X86::BI__builtin_ia32_addsubps:
14005 case clang::X86::BI__builtin_ia32_addsubpd256:
14006 case clang::X86::BI__builtin_ia32_addsubps256: {
14009 APValue SourceLHS, SourceRHS;
14015 ResultElements.reserve(NumElems);
14018 for (
unsigned I = 0; I != NumElems; ++I) {
14023 LHS.subtract(RHS, RM);
14028 ResultElements.push_back(
APValue(LHS));
14030 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14032 case clang::X86::BI__builtin_ia32_pclmulqdq128:
14033 case clang::X86::BI__builtin_ia32_pclmulqdq256:
14034 case clang::X86::BI__builtin_ia32_pclmulqdq512: {
14038 APValue SourceLHS, SourceRHS;
14048 bool SelectUpperA = (Imm8 & 0x01) != 0;
14049 bool SelectUpperB = (Imm8 & 0x10) != 0;
14053 ResultElements.reserve(NumElems);
14054 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14058 for (
unsigned Lane = 0; Lane < NumElems; Lane += 2) {
14067 APInt A = SelectUpperA ? A1 : A0;
14068 APInt B = SelectUpperB ? B1 : B0;
14071 APInt A128 = A.zext(128);
14072 APInt B128 = B.zext(128);
14075 APInt Result = llvm::APIntOps::clmul(A128, B128);
14078 APSInt ResultLow(
Result.extractBits(64, 0), DestUnsigned);
14079 APSInt ResultHigh(
Result.extractBits(64, 64), DestUnsigned);
14081 ResultElements.push_back(
APValue(ResultLow));
14082 ResultElements.push_back(
APValue(ResultHigh));
14085 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14087 case Builtin::BI__builtin_elementwise_fshl:
14088 case Builtin::BI__builtin_elementwise_fshr: {
14089 APValue SourceHi, SourceLo, SourceShift;
14095 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14101 ResultElements.reserve(SourceLen);
14102 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
14107 case Builtin::BI__builtin_elementwise_fshl:
14108 ResultElements.push_back(
APValue(
14109 APSInt(llvm::APIntOps::fshl(Hi, Lo, Shift), Hi.isUnsigned())));
14111 case Builtin::BI__builtin_elementwise_fshr:
14112 ResultElements.push_back(
APValue(
14113 APSInt(llvm::APIntOps::fshr(Hi, Lo, Shift), Hi.isUnsigned())));
14118 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14121 case X86::BI__builtin_ia32_shuf_f32x4_256:
14122 case X86::BI__builtin_ia32_shuf_i32x4_256:
14123 case X86::BI__builtin_ia32_shuf_f64x2_256:
14124 case X86::BI__builtin_ia32_shuf_i64x2_256:
14125 case X86::BI__builtin_ia32_shuf_f32x4:
14126 case X86::BI__builtin_ia32_shuf_i32x4:
14127 case X86::BI__builtin_ia32_shuf_f64x2:
14128 case X86::BI__builtin_ia32_shuf_i64x2: {
14142 unsigned ElemBits = Info.Ctx.getTypeSize(ElemQT);
14143 unsigned LaneBits = 128u;
14144 unsigned NumLanes = (NumElems * ElemBits) / LaneBits;
14145 unsigned NumElemsPerLane = LaneBits / ElemBits;
14149 ResultElements.reserve(DstLen);
14154 [NumLanes, NumElemsPerLane](
unsigned DstIdx,
unsigned ShuffleMask)
14155 -> std::pair<unsigned, int> {
14157 unsigned BitsPerElem = NumLanes / 2;
14158 unsigned IndexMask = (1u << BitsPerElem) - 1;
14159 unsigned Lane = DstIdx / NumElemsPerLane;
14160 unsigned SrcIdx = (Lane < NumLanes / 2) ? 0 : 1;
14161 unsigned BitIdx = BitsPerElem * Lane;
14162 unsigned SrcLaneIdx = (ShuffleMask >> BitIdx) & IndexMask;
14163 unsigned ElemInLane = DstIdx % NumElemsPerLane;
14164 unsigned IdxToPick = SrcLaneIdx * NumElemsPerLane + ElemInLane;
14165 return {SrcIdx, IdxToPick};
14171 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v16qi:
14172 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v32qi:
14173 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v64qi:
14174 case X86::BI__builtin_ia32_vgf2p8affineqb_v16qi:
14175 case X86::BI__builtin_ia32_vgf2p8affineqb_v32qi:
14176 case X86::BI__builtin_ia32_vgf2p8affineqb_v64qi: {
14188 bool IsInverse =
false;
14190 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v16qi:
14191 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v32qi:
14192 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v64qi: {
14197 unsigned NumBitsInByte = 8;
14198 unsigned NumBytesInQWord = 8;
14199 unsigned NumBitsInQWord = 64;
14201 unsigned NumQWords = NumBytes / NumBytesInQWord;
14203 Result.reserve(NumBytes);
14206 for (
unsigned QWordIdx = 0; QWordIdx != NumQWords; ++QWordIdx) {
14208 APInt XQWord(NumBitsInQWord, 0);
14209 APInt AQWord(NumBitsInQWord, 0);
14210 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
14211 unsigned Idx = QWordIdx * NumBytesInQWord + ByteIdx;
14212 APInt XByte =
X.getVectorElt(Idx).getInt();
14214 XQWord.insertBits(XByte, ByteIdx * NumBitsInByte);
14215 AQWord.insertBits(AByte, ByteIdx * NumBitsInByte);
14218 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
14220 XQWord.lshr(ByteIdx * NumBitsInByte).getLoBits(8).getZExtValue();
14229 case X86::BI__builtin_ia32_vgf2p8mulb_v16qi:
14230 case X86::BI__builtin_ia32_vgf2p8mulb_v32qi:
14231 case X86::BI__builtin_ia32_vgf2p8mulb_v64qi: {
14242 Result.reserve(NumBytes);
14244 for (
unsigned ByteIdx = 0; ByteIdx != NumBytes; ++ByteIdx) {
14254 case X86::BI__builtin_ia32_insertf32x4_256:
14255 case X86::BI__builtin_ia32_inserti32x4_256:
14256 case X86::BI__builtin_ia32_insertf64x2_256:
14257 case X86::BI__builtin_ia32_inserti64x2_256:
14258 case X86::BI__builtin_ia32_insertf32x4:
14259 case X86::BI__builtin_ia32_inserti32x4:
14260 case X86::BI__builtin_ia32_insertf64x2_512:
14261 case X86::BI__builtin_ia32_inserti64x2_512:
14262 case X86::BI__builtin_ia32_insertf32x8:
14263 case X86::BI__builtin_ia32_inserti32x8:
14264 case X86::BI__builtin_ia32_insertf64x4:
14265 case X86::BI__builtin_ia32_inserti64x4:
14266 case X86::BI__builtin_ia32_vinsertf128_ps256:
14267 case X86::BI__builtin_ia32_vinsertf128_pd256:
14268 case X86::BI__builtin_ia32_vinsertf128_si256:
14269 case X86::BI__builtin_ia32_insert128i256: {
14270 APValue SourceDst, SourceSub;
14282 assert(SubLen != 0 && DstLen != 0 && (DstLen % SubLen) == 0);
14283 unsigned NumLanes = DstLen / SubLen;
14284 unsigned LaneIdx = (Imm.getZExtValue() % NumLanes) * SubLen;
14287 ResultElements.reserve(DstLen);
14289 for (
unsigned EltNum = 0; EltNum < DstLen; ++EltNum) {
14290 if (EltNum >= LaneIdx && EltNum < LaneIdx + SubLen)
14291 ResultElements.push_back(SourceSub.
getVectorElt(EltNum - LaneIdx));
14293 ResultElements.push_back(SourceDst.
getVectorElt(EltNum));
14296 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14299 case clang::X86::BI__builtin_ia32_vec_set_v4hi:
14300 case clang::X86::BI__builtin_ia32_vec_set_v16qi:
14301 case clang::X86::BI__builtin_ia32_vec_set_v8hi:
14302 case clang::X86::BI__builtin_ia32_vec_set_v4si:
14303 case clang::X86::BI__builtin_ia32_vec_set_v2di:
14304 case clang::X86::BI__builtin_ia32_vec_set_v32qi:
14305 case clang::X86::BI__builtin_ia32_vec_set_v16hi:
14306 case clang::X86::BI__builtin_ia32_vec_set_v8si:
14307 case clang::X86::BI__builtin_ia32_vec_set_v4di: {
14315 QualType ElemTy = E->
getType()->
castAs<VectorType>()->getElementType();
14316 unsigned ElemWidth = Info.Ctx.getIntWidth(ElemTy);
14318 Scalar.setIsUnsigned(ElemUnsigned);
14324 static_cast<unsigned>(IndexAPS.getZExtValue() & (NumElems - 1));
14327 Elems.reserve(NumElems);
14328 for (
unsigned ElemNum = 0; ElemNum != NumElems; ++ElemNum)
14329 Elems.push_back(ElemNum == Index ? ElemAV : VecVal.
getVectorElt(ElemNum));
14334 case X86::BI__builtin_ia32_pslldqi128_byteshift:
14335 case X86::BI__builtin_ia32_pslldqi256_byteshift:
14336 case X86::BI__builtin_ia32_pslldqi512_byteshift: {
14340 [](
unsigned DstIdx,
unsigned Shift) -> std::pair<unsigned, int> {
14341 unsigned LaneBase = (DstIdx / 16) * 16;
14342 unsigned LaneIdx = DstIdx % 16;
14343 if (LaneIdx < Shift)
14344 return std::make_pair(0, -1);
14346 return std::make_pair(
14347 0,
static_cast<int>(LaneBase + LaneIdx - Shift));
14353 case X86::BI__builtin_ia32_psrldqi128_byteshift:
14354 case X86::BI__builtin_ia32_psrldqi256_byteshift:
14355 case X86::BI__builtin_ia32_psrldqi512_byteshift: {
14359 [](
unsigned DstIdx,
unsigned Shift) -> std::pair<unsigned, int> {
14360 unsigned LaneBase = (DstIdx / 16) * 16;
14361 unsigned LaneIdx = DstIdx % 16;
14362 if (LaneIdx + Shift < 16)
14363 return std::make_pair(
14364 0,
static_cast<int>(LaneBase + LaneIdx + Shift));
14366 return std::make_pair(0, -1);
14372 case X86::BI__builtin_ia32_palignr128:
14373 case X86::BI__builtin_ia32_palignr256:
14374 case X86::BI__builtin_ia32_palignr512: {
14378 unsigned VecIdx = 1;
14381 int Lane = DstIdx / 16;
14382 int Offset = DstIdx % 16;
14385 unsigned ShiftedIdx = Offset + (
Shift & 0xFF);
14386 if (ShiftedIdx < 16) {
14387 ElemIdx = ShiftedIdx + (Lane * 16);
14388 }
else if (ShiftedIdx < 32) {
14390 ElemIdx = (ShiftedIdx - 16) + (Lane * 16);
14393 return std::pair<unsigned, int>{VecIdx, ElemIdx};
14398 case X86::BI__builtin_ia32_alignd128:
14399 case X86::BI__builtin_ia32_alignd256:
14400 case X86::BI__builtin_ia32_alignd512:
14401 case X86::BI__builtin_ia32_alignq128:
14402 case X86::BI__builtin_ia32_alignq256:
14403 case X86::BI__builtin_ia32_alignq512: {
14405 unsigned NumElems = E->
getType()->
castAs<VectorType>()->getNumElements();
14407 [NumElems](
unsigned DstIdx,
unsigned Shift) {
14408 unsigned Imm =
Shift & 0xFF;
14409 unsigned EffectiveShift = Imm & (NumElems - 1);
14410 unsigned SourcePos = DstIdx + EffectiveShift;
14411 unsigned VecIdx = SourcePos < NumElems ? 1 : 0;
14412 unsigned ElemIdx = SourcePos & (NumElems - 1);
14414 return std::pair<unsigned, int>{
14415 VecIdx,
static_cast<int>(ElemIdx)};
14420 case X86::BI__builtin_ia32_permvarsi256:
14421 case X86::BI__builtin_ia32_permvarsf256:
14422 case X86::BI__builtin_ia32_permvardf512:
14423 case X86::BI__builtin_ia32_permvardi512:
14424 case X86::BI__builtin_ia32_permvarhi128: {
14427 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14428 int Offset = ShuffleMask & 0x7;
14429 return std::pair<unsigned, int>{0, Offset};
14434 case X86::BI__builtin_ia32_permvarqi128:
14435 case X86::BI__builtin_ia32_permvarhi256:
14436 case X86::BI__builtin_ia32_permvarsi512:
14437 case X86::BI__builtin_ia32_permvarsf512: {
14440 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14441 int Offset = ShuffleMask & 0xF;
14442 return std::pair<unsigned, int>{0, Offset};
14447 case X86::BI__builtin_ia32_permvardi256:
14448 case X86::BI__builtin_ia32_permvardf256: {
14451 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14452 int Offset = ShuffleMask & 0x3;
14453 return std::pair<unsigned, int>{0, Offset};
14458 case X86::BI__builtin_ia32_permvarqi256:
14459 case X86::BI__builtin_ia32_permvarhi512: {
14462 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14463 int Offset = ShuffleMask & 0x1F;
14464 return std::pair<unsigned, int>{0, Offset};
14469 case X86::BI__builtin_ia32_permvarqi512: {
14472 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14473 int Offset = ShuffleMask & 0x3F;
14474 return std::pair<unsigned, int>{0, Offset};
14479 case X86::BI__builtin_ia32_vpermi2varq128:
14480 case X86::BI__builtin_ia32_vpermi2varpd128: {
14483 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14484 int Offset = ShuffleMask & 0x1;
14485 unsigned SrcIdx = (ShuffleMask >> 1) & 0x1;
14486 return std::pair<unsigned, int>{SrcIdx, Offset};
14491 case X86::BI__builtin_ia32_vpermi2vard128:
14492 case X86::BI__builtin_ia32_vpermi2varps128:
14493 case X86::BI__builtin_ia32_vpermi2varq256:
14494 case X86::BI__builtin_ia32_vpermi2varpd256: {
14497 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14498 int Offset = ShuffleMask & 0x3;
14499 unsigned SrcIdx = (ShuffleMask >> 2) & 0x1;
14500 return std::pair<unsigned, int>{SrcIdx, Offset};
14505 case X86::BI__builtin_ia32_vpermi2varhi128:
14506 case X86::BI__builtin_ia32_vpermi2vard256:
14507 case X86::BI__builtin_ia32_vpermi2varps256:
14508 case X86::BI__builtin_ia32_vpermi2varq512:
14509 case X86::BI__builtin_ia32_vpermi2varpd512: {
14512 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14513 int Offset = ShuffleMask & 0x7;
14514 unsigned SrcIdx = (ShuffleMask >> 3) & 0x1;
14515 return std::pair<unsigned, int>{SrcIdx, Offset};
14520 case X86::BI__builtin_ia32_vpermi2varqi128:
14521 case X86::BI__builtin_ia32_vpermi2varhi256:
14522 case X86::BI__builtin_ia32_vpermi2vard512:
14523 case X86::BI__builtin_ia32_vpermi2varps512: {
14526 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14527 int Offset = ShuffleMask & 0xF;
14528 unsigned SrcIdx = (ShuffleMask >> 4) & 0x1;
14529 return std::pair<unsigned, int>{SrcIdx, Offset};
14534 case X86::BI__builtin_ia32_vpermi2varqi256:
14535 case X86::BI__builtin_ia32_vpermi2varhi512: {
14538 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14539 int Offset = ShuffleMask & 0x1F;
14540 unsigned SrcIdx = (ShuffleMask >> 5) & 0x1;
14541 return std::pair<unsigned, int>{SrcIdx, Offset};
14546 case X86::BI__builtin_ia32_vpermi2varqi512: {
14549 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14550 int Offset = ShuffleMask & 0x3F;
14551 unsigned SrcIdx = (ShuffleMask >> 6) & 0x1;
14552 return std::pair<unsigned, int>{SrcIdx, Offset};
14558 case clang::X86::BI__builtin_ia32_minps:
14559 case clang::X86::BI__builtin_ia32_minpd:
14560 case clang::X86::BI__builtin_ia32_minps256:
14561 case clang::X86::BI__builtin_ia32_minpd256:
14562 case clang::X86::BI__builtin_ia32_minps512:
14563 case clang::X86::BI__builtin_ia32_minpd512:
14564 case clang::X86::BI__builtin_ia32_minph128:
14565 case clang::X86::BI__builtin_ia32_minph256:
14566 case clang::X86::BI__builtin_ia32_minph512:
14567 return EvaluateFpBinOpExpr(
14568 [](
const APFloat &A,
const APFloat &B,
14569 std::optional<APSInt>) -> std::optional<APFloat> {
14570 if (A.isNaN() || A.isInfinity() || A.isDenormal() || B.isNaN() ||
14571 B.isInfinity() || B.isDenormal())
14572 return std::nullopt;
14573 if (A.isZero() && B.isZero())
14575 return llvm::minimum(A, B);
14578 case clang::X86::BI__builtin_ia32_minss:
14579 case clang::X86::BI__builtin_ia32_minsd:
14580 return EvaluateFpBinOpExpr(
14581 [](
const APFloat &A,
const APFloat &B,
14582 std::optional<APSInt> RoundingMode) -> std::optional<APFloat> {
14587 case clang::X86::BI__builtin_ia32_minsd_round_mask:
14588 case clang::X86::BI__builtin_ia32_minss_round_mask:
14589 case clang::X86::BI__builtin_ia32_minsh_round_mask:
14590 case clang::X86::BI__builtin_ia32_maxsd_round_mask:
14591 case clang::X86::BI__builtin_ia32_maxss_round_mask:
14592 case clang::X86::BI__builtin_ia32_maxsh_round_mask: {
14595 clang::X86::BI__builtin_ia32_minsd_round_mask ||
14597 clang::X86::BI__builtin_ia32_minss_round_mask ||
14599 return EvaluateScalarFpRoundMaskBinOp(
14600 [IsMin](
const APFloat &A,
const APFloat &B,
14601 std::optional<APSInt> RoundingMode) -> std::optional<APFloat> {
14606 case clang::X86::BI__builtin_ia32_maxps:
14607 case clang::X86::BI__builtin_ia32_maxpd:
14608 case clang::X86::BI__builtin_ia32_maxps256:
14609 case clang::X86::BI__builtin_ia32_maxpd256:
14610 case clang::X86::BI__builtin_ia32_maxps512:
14611 case clang::X86::BI__builtin_ia32_maxpd512:
14612 case clang::X86::BI__builtin_ia32_maxph128:
14613 case clang::X86::BI__builtin_ia32_maxph256:
14614 case clang::X86::BI__builtin_ia32_maxph512:
14615 return EvaluateFpBinOpExpr(
14616 [](
const APFloat &A,
const APFloat &B,
14617 std::optional<APSInt>) -> std::optional<APFloat> {
14618 if (A.isNaN() || A.isInfinity() || A.isDenormal() || B.isNaN() ||
14619 B.isInfinity() || B.isDenormal())
14620 return std::nullopt;
14621 if (A.isZero() && B.isZero())
14623 return llvm::maximum(A, B);
14626 case clang::X86::BI__builtin_ia32_maxss:
14627 case clang::X86::BI__builtin_ia32_maxsd:
14628 return EvaluateFpBinOpExpr(
14629 [](
const APFloat &A,
const APFloat &B,
14630 std::optional<APSInt> RoundingMode) -> std::optional<APFloat> {
14635 case clang::X86::BI__builtin_ia32_vcvtps2ph:
14636 case clang::X86::BI__builtin_ia32_vcvtps2ph256: {
14646 unsigned SrcNumElems = SrcVTy->getNumElements();
14648 unsigned DstNumElems = DstVTy->getNumElements();
14649 QualType DstElemTy = DstVTy->getElementType();
14651 const llvm::fltSemantics &HalfSem =
14652 Info.Ctx.getFloatTypeSemantics(Info.Ctx.HalfTy);
14654 int ImmVal = Imm.getZExtValue();
14655 bool UseMXCSR = (ImmVal & 4) != 0;
14656 bool IsFPConstrained =
14659 llvm::RoundingMode RM;
14661 switch (ImmVal & 3) {
14663 RM = llvm::RoundingMode::NearestTiesToEven;
14666 RM = llvm::RoundingMode::TowardNegative;
14669 RM = llvm::RoundingMode::TowardPositive;
14672 RM = llvm::RoundingMode::TowardZero;
14675 llvm_unreachable(
"Invalid immediate rounding mode");
14678 RM = llvm::RoundingMode::NearestTiesToEven;
14682 ResultElements.reserve(DstNumElems);
14684 for (
unsigned I = 0; I < SrcNumElems; ++I) {
14688 APFloat::opStatus St = SrcVal.convert(HalfSem, RM, &LostInfo);
14690 if (UseMXCSR && IsFPConstrained && St != APFloat::opOK) {
14691 Info.FFDiag(E, diag::note_constexpr_dynamic_rounding);
14695 APSInt DstInt(SrcVal.bitcastToAPInt(),
14697 ResultElements.push_back(
APValue(DstInt));
14700 if (DstNumElems > SrcNumElems) {
14701 APSInt Zero = Info.Ctx.MakeIntValue(0, DstElemTy);
14702 for (
unsigned I = SrcNumElems; I < DstNumElems; ++I) {
14707 return Success(ResultElements, E);
14709 case X86::BI__builtin_ia32_vperm2f128_pd256:
14710 case X86::BI__builtin_ia32_vperm2f128_ps256:
14711 case X86::BI__builtin_ia32_vperm2f128_si256:
14712 case X86::BI__builtin_ia32_permti256: {
14713 unsigned NumElements =
14715 unsigned PreservedBitsCnt = NumElements >> 2;
14719 [PreservedBitsCnt](
unsigned DstIdx,
unsigned ShuffleMask) {
14720 unsigned ControlBitsCnt = DstIdx >> PreservedBitsCnt << 2;
14721 unsigned ControlBits = ShuffleMask >> ControlBitsCnt;
14723 if (ControlBits & 0b1000)
14724 return std::make_pair(0u, -1);
14726 unsigned SrcVecIdx = (ControlBits & 0b10) >> 1;
14727 unsigned PreservedBitsMask = (1 << PreservedBitsCnt) - 1;
14728 int SrcIdx = ((ControlBits & 0b1) << PreservedBitsCnt) |
14729 (DstIdx & PreservedBitsMask);
14730 return std::make_pair(SrcVecIdx, SrcIdx);
14738bool VectorExprEvaluator::VisitConvertVectorExpr(
const ConvertVectorExpr *E) {
14744 QualType DestTy = E->
getType()->
castAs<VectorType>()->getElementType();
14745 QualType SourceTy = SourceVecType->
castAs<VectorType>()->getElementType();
14751 ResultElements.reserve(SourceLen);
14752 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
14757 ResultElements.push_back(std::move(Elt));
14760 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14765 APValue const &VecVal2,
unsigned EltNum,
14767 unsigned const TotalElementsInInputVector1 = VecVal1.
getVectorLength();
14768 unsigned const TotalElementsInInputVector2 = VecVal2.
getVectorLength();
14771 int64_t
index = IndexVal.getExtValue();
14778 E, diag::err_shufflevector_minus_one_is_undefined_behavior_constexpr)
14784 index >= TotalElementsInInputVector1 + TotalElementsInInputVector2)
14785 llvm_unreachable(
"Out of bounds shuffle index");
14787 if (
index >= TotalElementsInInputVector1)
14794bool VectorExprEvaluator::VisitShuffleVectorExpr(
const ShuffleVectorExpr *E) {
14799 const Expr *Vec1 = E->
getExpr(0);
14803 const Expr *Vec2 = E->
getExpr(1);
14807 VectorType
const *DestVecTy = E->
getType()->
castAs<VectorType>();
14813 ResultElements.reserve(TotalElementsInOutputVector);
14814 for (
unsigned EltNum = 0; EltNum < TotalElementsInOutputVector; ++EltNum) {
14818 ResultElements.push_back(std::move(Elt));
14821 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14829class MatrixExprEvaluator :
public ExprEvaluatorBase<MatrixExprEvaluator> {
14836 bool Success(ArrayRef<APValue> M,
const Expr *E) {
14838 assert(M.size() == CMTy->getNumElementsFlattened());
14840 Result =
APValue(M.data(), CMTy->getNumRows(), CMTy->getNumColumns());
14844 assert(M.
isMatrix() &&
"expected matrix");
14849 bool VisitCastExpr(
const CastExpr *E);
14850 bool VisitInitListExpr(
const InitListExpr *E);
14856 "not a matrix prvalue");
14857 return MatrixExprEvaluator(Info,
Result).Visit(E);
14860bool MatrixExprEvaluator::VisitCastExpr(
const CastExpr *E) {
14861 const auto *MT = E->
getType()->
castAs<ConstantMatrixType>();
14862 unsigned NumRows = MT->getNumRows();
14863 unsigned NumCols = MT->getNumColumns();
14864 unsigned NElts = NumRows * NumCols;
14865 QualType EltTy = MT->getElementType();
14869 case CK_HLSLAggregateSplatCast: {
14884 case CK_HLSLElementwiseCast: {
14897 return Success(ResultEls, E);
14900 return ExprEvaluatorBaseTy::VisitCastExpr(E);
14904bool MatrixExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
14905 const auto *MT = E->
getType()->
castAs<ConstantMatrixType>();
14906 QualType EltTy = MT->getElementType();
14908 assert(E->
getNumInits() == MT->getNumElementsFlattened() &&
14909 "Expected number of elements in initializer list to match the number "
14910 "of matrix elements");
14913 Elements.reserve(MT->getNumElementsFlattened());
14918 for (
unsigned I = 0, N = MT->getNumElementsFlattened(); I < N; ++I) {
14919 if (EltTy->isIntegerType()) {
14920 llvm::APSInt IntVal;
14923 Elements.push_back(
APValue(IntVal));
14925 llvm::APFloat FloatVal(0.0);
14928 Elements.push_back(
APValue(FloatVal));
14940 class ArrayExprEvaluator
14941 :
public ExprEvaluatorBase<ArrayExprEvaluator> {
14942 const LValue &
This;
14946 ArrayExprEvaluator(EvalInfo &Info,
const LValue &This,
APValue &
Result)
14950 assert(
V.isArray() &&
"expected array");
14955 bool ZeroInitialization(
const Expr *E) {
14956 const ConstantArrayType *CAT =
14957 Info.Ctx.getAsConstantArrayType(E->
getType());
14971 if (!
Result.hasArrayFiller())
14975 LValue Subobject =
This;
14976 Subobject.addArray(Info, E, CAT);
14981 bool VisitCallExpr(
const CallExpr *E) {
14982 return handleCallExpr(E,
Result, &This);
14984 bool VisitCastExpr(
const CastExpr *E);
14985 bool VisitInitListExpr(
const InitListExpr *E,
14986 QualType AllocType = QualType());
14987 bool VisitArrayInitLoopExpr(
const ArrayInitLoopExpr *E);
14988 bool VisitCXXConstructExpr(
const CXXConstructExpr *E);
14989 bool VisitCXXConstructExpr(
const CXXConstructExpr *E,
14990 const LValue &Subobject,
14992 bool VisitStringLiteral(
const StringLiteral *E,
14993 QualType AllocType = QualType()) {
14997 bool VisitCXXParenListInitExpr(
const CXXParenListInitExpr *E);
14998 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
14999 ArrayRef<Expr *> Args,
15000 const Expr *ArrayFiller,
15001 QualType AllocType = QualType());
15009 "not an array prvalue");
15010 return ArrayExprEvaluator(Info,
This,
Result).Visit(E);
15018 "not an array prvalue");
15019 return ArrayExprEvaluator(Info,
This,
Result)
15020 .VisitInitListExpr(ILE, AllocType);
15029 "not an array prvalue");
15030 return ArrayExprEvaluator(Info,
This,
Result)
15031 .VisitCXXConstructExpr(CCE,
This, &
Result, AllocType);
15040 if (
const InitListExpr *ILE = dyn_cast<InitListExpr>(FillerExpr)) {
15041 for (
unsigned I = 0, E = ILE->
getNumInits(); I != E; ++I) {
15046 if (ILE->hasArrayFiller() &&
15055bool ArrayExprEvaluator::VisitCastExpr(
const CastExpr *E) {
15060 return ExprEvaluatorBaseTy::VisitCastExpr(E);
15061 case CK_HLSLAggregateSplatCast: {
15081 case CK_HLSLElementwiseCast: {
15098bool ArrayExprEvaluator::VisitInitListExpr(
const InitListExpr *E,
15099 QualType AllocType) {
15100 const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(
15113 return VisitStringLiteral(SL, AllocType);
15118 "transparent array list initialization is not string literal init?");
15124bool ArrayExprEvaluator::VisitCXXParenListOrInitListExpr(
15126 QualType AllocType) {
15127 const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(
15132 unsigned NumEltsToInit = Args.size();
15137 if (NumEltsToInit != NumElts &&
15139 NumEltsToInit = NumElts;
15142 for (
auto *
Init : Args) {
15143 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts()))
15144 NumEltsToInit += EmbedS->getDataElementCount() - 1;
15147 if (NumEltsToInit > NumElts)
15148 NumEltsToInit = NumElts;
15152 if (
Result.hasValue() && NumEltsToInit <
Result.getArrayInitializedElts())
15153 NumEltsToInit =
Result.getArrayInitializedElts();
15156 LLVM_DEBUG(llvm::dbgs() <<
"The number of elements to initialize: "
15157 << NumEltsToInit <<
".\n");
15159 if (!
Result.hasValue()) {
15160 Result =
APValue(APValue::UninitArray(), NumEltsToInit, NumElts);
15161 }
else if (
Result.getArrayInitializedElts() != NumEltsToInit) {
15172 APValue NewResult =
APValue(APValue::UninitArray(), NumEltsToInit, NumElts);
15174 unsigned NumOldElts =
Result.getArrayInitializedElts();
15175 for (
unsigned I = 0; I < NumOldElts; ++I) {
15177 std::move(
Result.getArrayInitializedElt(I));
15180 for (
unsigned I =
Result.getArrayInitializedElts(); I < NumEltsToInit; ++I)
15184 Result = std::move(NewResult);
15187 LValue Subobject =
This;
15188 Subobject.addArray(Info, ExprToVisit, CAT);
15189 auto Eval = [&](
const Expr *
Init,
unsigned ArrayIndex) {
15190 if (
Init->isValueDependent())
15199 Subobject,
Init) ||
15202 if (!Info.noteFailure())
15208 unsigned ArrayIndex = 0;
15211 for (
unsigned Index = 0; Index != NumEltsToInit; ++Index) {
15212 const Expr *
Init = Index < Args.size() ? Args[Index] : ArrayFiller;
15213 if (ArrayIndex >= NumEltsToInit)
15215 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
15216 StringLiteral *SL = EmbedS->getDataStringLiteral();
15217 for (
unsigned I = EmbedS->getStartingElementPos(),
15218 N = EmbedS->getDataElementCount();
15219 I != EmbedS->getStartingElementPos() + N; ++I) {
15225 const FPOptions FPO =
15226 Init->getFPFeaturesInEffect(Info.Ctx.getLangOpts());
15231 Result.getArrayInitializedElt(ArrayIndex) =
APValue(FValue);
15236 if (!Eval(
Init, ArrayIndex))
15242 if (!
Result.hasArrayFiller())
15247 assert(ArrayFiller &&
"no array filler for incomplete init list");
15253bool ArrayExprEvaluator::VisitArrayInitLoopExpr(
const ArrayInitLoopExpr *E) {
15256 !
Evaluate(Info.CurrentCall->createTemporary(
15259 ScopeKind::FullExpression, CommonLV),
15266 Result =
APValue(APValue::UninitArray(), Elements, Elements);
15268 LValue Subobject =
This;
15269 Subobject.addArray(Info, E, CAT);
15272 for (EvalInfo::ArrayInitLoopIndex Index(Info); Index != Elements; ++Index) {
15281 FullExpressionRAII Scope(Info);
15287 if (!Info.noteFailure())
15299bool ArrayExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E) {
15300 return VisitCXXConstructExpr(E, This, &
Result, E->
getType());
15303bool ArrayExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E,
15304 const LValue &Subobject,
15307 bool HadZeroInit =
Value->hasValue();
15309 if (
const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(
Type)) {
15314 HadZeroInit &&
Value->hasArrayFiller() ?
Value->getArrayFiller()
15317 *
Value =
APValue(APValue::UninitArray(), 0, FinalSize);
15318 if (FinalSize == 0)
15324 LValue ArrayElt = Subobject;
15325 ArrayElt.addArray(Info, E, CAT);
15331 for (
const unsigned N : {1u, FinalSize}) {
15332 unsigned OldElts =
Value->getArrayInitializedElts();
15337 APValue NewValue(APValue::UninitArray(), N, FinalSize);
15338 for (
unsigned I = 0; I < OldElts; ++I)
15339 NewValue.getArrayInitializedElt(I).swap(
15340 Value->getArrayInitializedElt(I));
15341 Value->swap(NewValue);
15344 for (
unsigned I = OldElts; I < N; ++I)
15345 Value->getArrayInitializedElt(I) = Filler;
15347 if (HasTrivialConstructor && N == FinalSize && FinalSize != 1) {
15350 APValue &FirstResult =
Value->getArrayInitializedElt(0);
15351 for (
unsigned I = OldElts; I < FinalSize; ++I)
15352 Value->getArrayInitializedElt(I) = FirstResult;
15354 for (
unsigned I = OldElts; I < N; ++I) {
15355 if (!VisitCXXConstructExpr(E, ArrayElt,
15356 &
Value->getArrayInitializedElt(I),
15363 if (Info.EvalStatus.Diag && !Info.EvalStatus.Diag->empty() &&
15364 !Info.keepEvaluatingAfterFailure())
15373 if (!
Type->isRecordType())
15376 return RecordExprEvaluator(Info, Subobject, *
Value)
15377 .VisitCXXConstructExpr(E,
Type);
15380bool ArrayExprEvaluator::VisitCXXParenListInitExpr(
15381 const CXXParenListInitExpr *E) {
15383 "Expression result is not a constant array type");
15385 return VisitCXXParenListOrInitListExpr(E, E->
getInitExprs(),
15398class IntExprEvaluator
15399 :
public ExprEvaluatorBase<IntExprEvaluator> {
15402 IntExprEvaluator(EvalInfo &info,
APValue &result)
15403 : ExprEvaluatorBaseTy(info),
Result(result) {}
15407 "Invalid evaluation result.");
15409 "Invalid evaluation result.");
15410 assert(SI.getBitWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
15411 "Invalid evaluation result.");
15415 bool Success(
const llvm::APSInt &SI,
const Expr *E) {
15421 "Invalid evaluation result.");
15422 assert(I.getBitWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
15423 "Invalid evaluation result.");
15425 Result.getInt().setIsUnsigned(
15429 bool Success(
const llvm::APInt &I,
const Expr *E) {
15435 "Invalid evaluation result.");
15443 bool Success(CharUnits Size,
const Expr *E) {
15450 if (
V.isLValue() ||
V.isAddrLabelDiff() ||
V.isIndeterminate() ||
15451 V.allowConstexprUnknown()) {
15458 bool ZeroInitialization(
const Expr *E) {
return Success(0, E); }
15460 friend std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &,
15467 bool VisitIntegerLiteral(
const IntegerLiteral *E) {
15470 bool VisitCharacterLiteral(
const CharacterLiteral *E) {
15474 bool CheckReferencedDecl(
const Expr *E,
const Decl *D);
15475 bool VisitDeclRefExpr(
const DeclRefExpr *E) {
15476 if (CheckReferencedDecl(E, E->
getDecl()))
15479 return ExprEvaluatorBaseTy::VisitDeclRefExpr(E);
15481 bool VisitMemberExpr(
const MemberExpr *E) {
15483 VisitIgnoredBaseExpression(E->
getBase());
15487 return ExprEvaluatorBaseTy::VisitMemberExpr(E);
15490 bool VisitCallExpr(
const CallExpr *E);
15491 bool VisitBuiltinCallExpr(
const CallExpr *E,
unsigned BuiltinOp);
15492 bool VisitBinaryOperator(
const BinaryOperator *E);
15493 bool VisitOffsetOfExpr(
const OffsetOfExpr *E);
15494 bool VisitUnaryOperator(
const UnaryOperator *E);
15496 bool VisitCastExpr(
const CastExpr* E);
15497 bool VisitUnaryExprOrTypeTraitExpr(
const UnaryExprOrTypeTraitExpr *E);
15499 bool VisitCXXBoolLiteralExpr(
const CXXBoolLiteralExpr *E) {
15503 bool VisitObjCBoolLiteralExpr(
const ObjCBoolLiteralExpr *E) {
15507 bool VisitArrayInitIndexExpr(
const ArrayInitIndexExpr *E) {
15508 if (Info.ArrayInitIndex ==
uint64_t(-1)) {
15514 return Success(Info.ArrayInitIndex, E);
15518 bool VisitGNUNullExpr(
const GNUNullExpr *E) {
15519 return ZeroInitialization(E);
15522 bool VisitTypeTraitExpr(
const TypeTraitExpr *E) {
15531 bool VisitArrayTypeTraitExpr(
const ArrayTypeTraitExpr *E) {
15535 bool VisitExpressionTraitExpr(
const ExpressionTraitExpr *E) {
15539 bool VisitOpenACCAsteriskSizeExpr(
const OpenACCAsteriskSizeExpr *E) {
15546 bool VisitUnaryReal(
const UnaryOperator *E);
15547 bool VisitUnaryImag(
const UnaryOperator *E);
15549 bool VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E);
15550 bool VisitSizeOfPackExpr(
const SizeOfPackExpr *E);
15551 bool VisitSourceLocExpr(
const SourceLocExpr *E);
15552 bool VisitConceptSpecializationExpr(
const ConceptSpecializationExpr *E);
15557class FixedPointExprEvaluator
15558 :
public ExprEvaluatorBase<FixedPointExprEvaluator> {
15562 FixedPointExprEvaluator(EvalInfo &info,
APValue &result)
15563 : ExprEvaluatorBaseTy(info),
Result(result) {}
15565 bool Success(
const llvm::APInt &I,
const Expr *E) {
15567 APFixedPoint(I, Info.Ctx.getFixedPointSemantics(E->
getType())), E);
15572 APFixedPoint(
Value, Info.Ctx.getFixedPointSemantics(E->
getType())), E);
15576 return Success(
V.getFixedPoint(), E);
15579 bool Success(
const APFixedPoint &
V,
const Expr *E) {
15581 assert(
V.getWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
15582 "Invalid evaluation result.");
15587 bool ZeroInitialization(
const Expr *E) {
15595 bool VisitFixedPointLiteral(
const FixedPointLiteral *E) {
15599 bool VisitCastExpr(
const CastExpr *E);
15600 bool VisitUnaryOperator(
const UnaryOperator *E);
15601 bool VisitBinaryOperator(
const BinaryOperator *E);
15617 return IntExprEvaluator(Info,
Result).Visit(E);
15625 if (!Val.
isInt()) {
15628 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
15635bool IntExprEvaluator::VisitSourceLocExpr(
const SourceLocExpr *E) {
15637 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.
getDefaultExpr());
15646 if (!FixedPointExprEvaluator(Info, Val).Visit(E))
15661 auto FXSema = Info.Ctx.getFixedPointSemantics(E->
getType());
15665 Result = APFixedPoint(Val, FXSema);
15676bool IntExprEvaluator::CheckReferencedDecl(
const Expr* E,
const Decl* D) {
15678 if (
const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(D)) {
15680 bool SameSign = (ECD->getInitVal().isSigned()
15682 bool SameWidth = (ECD->getInitVal().
getBitWidth()
15683 == Info.Ctx.getIntWidth(E->
getType()));
15684 if (SameSign && SameWidth)
15685 return Success(ECD->getInitVal(), E);
15689 llvm::APSInt Val = ECD->getInitVal();
15691 Val.setIsSigned(!ECD->getInitVal().isSigned());
15693 Val = Val.extOrTrunc(Info.Ctx.getIntWidth(E->
getType()));
15704 assert(!T->isDependentType() &&
"unexpected dependent type");
15709#define TYPE(ID, BASE)
15710#define DEPENDENT_TYPE(ID, BASE) case Type::ID:
15711#define NON_CANONICAL_TYPE(ID, BASE) case Type::ID:
15712#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(ID, BASE) case Type::ID:
15713#include "clang/AST/TypeNodes.inc"
15715 case Type::DeducedTemplateSpecialization:
15716 llvm_unreachable(
"unexpected non-canonical or dependent type");
15718 case Type::Builtin:
15720#define BUILTIN_TYPE(ID, SINGLETON_ID)
15721#define SIGNED_TYPE(ID, SINGLETON_ID) \
15722 case BuiltinType::ID: return GCCTypeClass::Integer;
15723#define FLOATING_TYPE(ID, SINGLETON_ID) \
15724 case BuiltinType::ID: return GCCTypeClass::RealFloat;
15725#define PLACEHOLDER_TYPE(ID, SINGLETON_ID) \
15726 case BuiltinType::ID: break;
15727#include "clang/AST/BuiltinTypes.def"
15728 case BuiltinType::Void:
15731 case BuiltinType::Bool:
15734 case BuiltinType::Char_U:
15735 case BuiltinType::UChar:
15736 case BuiltinType::WChar_U:
15737 case BuiltinType::Char8:
15738 case BuiltinType::Char16:
15739 case BuiltinType::Char32:
15740 case BuiltinType::UShort:
15741 case BuiltinType::UInt:
15742 case BuiltinType::ULong:
15743 case BuiltinType::ULongLong:
15744 case BuiltinType::UInt128:
15747 case BuiltinType::UShortAccum:
15748 case BuiltinType::UAccum:
15749 case BuiltinType::ULongAccum:
15750 case BuiltinType::UShortFract:
15751 case BuiltinType::UFract:
15752 case BuiltinType::ULongFract:
15753 case BuiltinType::SatUShortAccum:
15754 case BuiltinType::SatUAccum:
15755 case BuiltinType::SatULongAccum:
15756 case BuiltinType::SatUShortFract:
15757 case BuiltinType::SatUFract:
15758 case BuiltinType::SatULongFract:
15761 case BuiltinType::NullPtr:
15763 case BuiltinType::ObjCId:
15764 case BuiltinType::ObjCClass:
15765 case BuiltinType::ObjCSel:
15766#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
15767 case BuiltinType::Id:
15768#include "clang/Basic/OpenCLImageTypes.def"
15769#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
15770 case BuiltinType::Id:
15771#include "clang/Basic/OpenCLExtensionTypes.def"
15772 case BuiltinType::OCLSampler:
15773 case BuiltinType::OCLEvent:
15774 case BuiltinType::OCLClkEvent:
15775 case BuiltinType::OCLQueue:
15776 case BuiltinType::OCLReserveID:
15777#define SVE_TYPE(Name, Id, SingletonId) \
15778 case BuiltinType::Id:
15779#include "clang/Basic/AArch64ACLETypes.def"
15780#define PPC_VECTOR_TYPE(Name, Id, Size) \
15781 case BuiltinType::Id:
15782#include "clang/Basic/PPCTypes.def"
15783#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
15784#include "clang/Basic/RISCVVTypes.def"
15785#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
15786#include "clang/Basic/WebAssemblyReferenceTypes.def"
15787#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
15788#include "clang/Basic/AMDGPUTypes.def"
15789#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
15790#include "clang/Basic/HLSLIntangibleTypes.def"
15793 case BuiltinType::Dependent:
15794 llvm_unreachable(
"unexpected dependent type");
15796 llvm_unreachable(
"unexpected placeholder type");
15801 case Type::Pointer:
15802 case Type::ConstantArray:
15803 case Type::VariableArray:
15804 case Type::IncompleteArray:
15805 case Type::FunctionNoProto:
15806 case Type::FunctionProto:
15807 case Type::ArrayParameter:
15810 case Type::MemberPointer:
15815 case Type::Complex:
15828 case Type::ExtVector:
15831 case Type::BlockPointer:
15832 case Type::ConstantMatrix:
15833 case Type::ObjCObject:
15834 case Type::ObjCInterface:
15835 case Type::ObjCObjectPointer:
15837 case Type::HLSLAttributedResource:
15838 case Type::HLSLInlineSpirv:
15839 case Type::OverflowBehavior:
15847 case Type::LValueReference:
15848 case Type::RValueReference:
15849 llvm_unreachable(
"invalid type for expression");
15852 llvm_unreachable(
"unexpected type class");
15877 if (
Base.isNull()) {
15880 }
else if (
const Expr *E =
Base.dyn_cast<
const Expr *>()) {
15899 SpeculativeEvaluationRAII SpeculativeEval(Info);
15904 FoldConstant Fold(Info,
true);
15922 if (ArgType->isIntegralOrEnumerationType() || ArgType->isFloatingType() ||
15923 ArgType->isAnyComplexType() || ArgType->isPointerType() ||
15924 ArgType->isNullPtrType()) {
15927 Fold.keepDiagnostics();
15936 return V.hasValue();
15947 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
15971 const auto *Cast = dyn_cast<CastExpr>(NoParens);
15972 if (Cast ==
nullptr)
15977 auto CastKind = Cast->getCastKind();
15979 CastKind != CK_AddressSpaceConversion)
15982 const auto *SubExpr = Cast->getSubExpr();
16004 assert(!LVal.Designator.Invalid);
16006 auto IsLastOrInvalidFieldDecl = [&Ctx](
const FieldDecl *FD) {
16014 auto &
Base = LVal.getLValueBase();
16015 if (
auto *ME = dyn_cast_or_null<MemberExpr>(
Base.dyn_cast<
const Expr *>())) {
16016 if (
auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
16017 if (!IsLastOrInvalidFieldDecl(FD))
16019 }
else if (
auto *IFD = dyn_cast<IndirectFieldDecl>(ME->getMemberDecl())) {
16020 for (
auto *FD : IFD->chain()) {
16029 if (LVal.Designator.FirstEntryIsAnUnsizedArray) {
16033 if (BaseType->isIncompleteArrayType())
16039 for (
unsigned E = LVal.Designator.Entries.size(); I != E; ++I) {
16040 const auto &Entry = LVal.Designator.Entries[I];
16041 if (BaseType->isArrayType()) {
16047 uint64_t Index = Entry.getAsArrayIndex();
16051 }
else if (BaseType->isAnyComplexType()) {
16052 const auto *CT = BaseType->castAs<
ComplexType>();
16053 uint64_t Index = Entry.getAsArrayIndex();
16056 BaseType = CT->getElementType();
16057 }
else if (
auto *FD = getAsField(Entry)) {
16058 if (!IsLastOrInvalidFieldDecl(FD))
16062 assert(getAsBaseClass(Entry) &&
"Expecting cast to a base class");
16074 if (LVal.Designator.Invalid)
16077 if (!LVal.Designator.Entries.empty())
16078 return LVal.Designator.isMostDerivedAnUnsizedArray();
16080 if (!LVal.InvalidBase)
16092 const SubobjectDesignator &
Designator = LVal.Designator;
16104 auto isFlexibleArrayMember = [&] {
16106 FAMKind StrictFlexArraysLevel =
16109 if (
Designator.isMostDerivedAnUnsizedArray())
16112 if (StrictFlexArraysLevel == FAMKind::Default)
16115 if (
Designator.getMostDerivedArraySize() == 0 &&
16116 StrictFlexArraysLevel != FAMKind::IncompleteOnly)
16119 if (
Designator.getMostDerivedArraySize() == 1 &&
16120 StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete)
16126 return LVal.InvalidBase &&
16128 Designator.MostDerivedIsArrayElement && isFlexibleArrayMember() &&
16136 auto CharUnitsMax = std::numeric_limits<CharUnits::QuantityType>::max();
16137 if (Int.ugt(CharUnitsMax))
16147 if (!T.isNull() && T->isStructureType() &&
16148 T->castAsRecordDecl()->hasFlexibleArrayMember())
16149 if (
const auto *
V = LV.getLValueBase().dyn_cast<
const ValueDecl *>())
16150 if (
const auto *VD = dyn_cast<VarDecl>(
V))
16162 unsigned Type,
const LValue &LVal,
16181 if (!(
Type & 1) || LVal.Designator.Invalid || DetermineForCompleteObject) {
16183 if (
Type == 3 && !DetermineForCompleteObject)
16186 llvm::APInt APEndOffset;
16187 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
16191 if (LVal.InvalidBase)
16195 const bool Ret = CheckedHandleSizeof(BaseTy, EndOffset);
16201 const SubobjectDesignator &
Designator = LVal.Designator;
16213 llvm::APInt APEndOffset;
16214 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
16226 if (!CheckedHandleSizeof(
Designator.MostDerivedType, BytesPerElem))
16232 int64_t ElemsRemaining;
16235 uint64_t ArraySize =
Designator.getMostDerivedArraySize();
16236 uint64_t ArrayIndex =
Designator.Entries.back().getAsArrayIndex();
16237 ElemsRemaining = ArraySize <= ArrayIndex ? 0 : ArraySize - ArrayIndex;
16239 ElemsRemaining =
Designator.isOnePastTheEnd() ? 0 : 1;
16242 EndOffset = LVal.getLValueOffset() + BytesPerElem * ElemsRemaining;
16251static std::optional<uint64_t>
16259 SpeculativeEvaluationRAII SpeculativeEval(Info);
16260 IgnoreSideEffectsRAII Fold(Info);
16267 return std::nullopt;
16268 LVal.setFrom(Info.Ctx, RVal);
16271 return std::nullopt;
16276 if (LVal.getLValueOffset().isNegative())
16281 return std::nullopt;
16285 if (EndOffset <= LVal.getLValueOffset())
16287 return (EndOffset - LVal.getLValueOffset()).
getQuantity();
16290bool IntExprEvaluator::VisitCallExpr(
const CallExpr *E) {
16291 if (!IsConstantEvaluatedBuiltinCall(E))
16292 return ExprEvaluatorBaseTy::VisitCallExpr(E);
16309 Info.FFDiag(E->
getArg(0));
16315 assert(SrcInt.getBitWidth() >= Alignment.getBitWidth() &&
16316 "Bit widths must be the same");
16323bool IntExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *E,
16324 unsigned BuiltinOp) {
16325 auto EvalTestOp = [&](llvm::function_ref<
bool(
const APInt &,
const APInt &)>
16327 APValue SourceLHS, SourceRHS;
16335 unsigned LaneWidth = Info.Ctx.getTypeSize(ElemQT);
16337 APInt AWide(LaneWidth * SourceLen, 0);
16338 APInt BWide(LaneWidth * SourceLen, 0);
16340 for (
unsigned I = 0; I != SourceLen; ++I) {
16343 if (ElemQT->isIntegerType()) {
16346 }
else if (ElemQT->isFloatingType()) {
16354 AWide.insertBits(ALane, I * LaneWidth);
16355 BWide.insertBits(BLane, I * LaneWidth);
16360 auto HandleMaskBinOp =
16373 auto HandleCRC32 = [&](
unsigned DataBytes) ->
bool {
16379 uint64_t CRCVal = CRC.getZExtValue();
16383 static const uint32_t CRC32C_POLY = 0x82F63B78;
16387 for (
unsigned I = 0; I != DataBytes; ++I) {
16388 uint8_t Byte =
static_cast<uint8_t
>((DataVal >> (I * 8)) & 0xFF);
16390 for (
int J = 0; J != 8; ++J) {
16398 switch (BuiltinOp) {
16402 case X86::BI__builtin_ia32_crc32qi:
16403 return HandleCRC32(1);
16404 case X86::BI__builtin_ia32_crc32hi:
16405 return HandleCRC32(2);
16406 case X86::BI__builtin_ia32_crc32si:
16407 return HandleCRC32(4);
16408 case X86::BI__builtin_ia32_crc32di:
16409 return HandleCRC32(8);
16411 case Builtin::BI__builtin_dynamic_object_size:
16412 case Builtin::BI__builtin_object_size: {
16416 assert(
Type <= 3 &&
"unexpected type");
16418 if (std::optional<uint64_t> Size =
16427 switch (Info.EvalMode) {
16428 case EvaluationMode::ConstantExpression:
16429 case EvaluationMode::ConstantFold:
16430 case EvaluationMode::IgnoreSideEffects:
16433 case EvaluationMode::ConstantExpressionUnevaluated:
16438 llvm_unreachable(
"unexpected EvalMode");
16441 case Builtin::BI__builtin_os_log_format_buffer_size: {
16442 analyze_os_log::OSLogBufferLayout Layout;
16447 case Builtin::BI__builtin_is_aligned: {
16455 Ptr.setFrom(Info.Ctx, Src);
16461 assert(Alignment.isPowerOf2());
16474 Info.FFDiag(E->
getArg(0), diag::note_constexpr_alignment_compute)
16478 assert(Src.
isInt());
16479 return Success((Src.
getInt() & (Alignment - 1)) == 0 ? 1 : 0, E);
16481 case Builtin::BI__builtin_align_up: {
16489 APSInt((Src.
getInt() + (Alignment - 1)) & ~(Alignment - 1),
16490 Src.
getInt().isUnsigned());
16491 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
16492 return Success(AlignedVal, E);
16494 case Builtin::BI__builtin_align_down: {
16503 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
16504 return Success(AlignedVal, E);
16507 case Builtin::BI__builtin_bitreverseg:
16508 case Builtin::BI__builtin_bitreverse8:
16509 case Builtin::BI__builtin_bitreverse16:
16510 case Builtin::BI__builtin_bitreverse32:
16511 case Builtin::BI__builtin_bitreverse64:
16512 case Builtin::BI__builtin_elementwise_bitreverse: {
16517 return Success(Val.reverseBits(), E);
16519 case Builtin::BI__builtin_bswapg:
16520 case Builtin::BI__builtin_bswap16:
16521 case Builtin::BI__builtin_bswap32:
16522 case Builtin::BI__builtin_bswap64: {
16526 if (Val.getBitWidth() == 8 || Val.getBitWidth() == 1)
16529 return Success(Val.byteSwap(), E);
16532 case Builtin::BI__builtin_classify_type:
16535 case Builtin::BI__builtin_clrsb:
16536 case Builtin::BI__builtin_clrsbl:
16537 case Builtin::BI__builtin_clrsbll: {
16542 return Success(Val.getBitWidth() - Val.getSignificantBits(), E);
16545 case Builtin::BI__builtin_clz:
16546 case Builtin::BI__builtin_clzl:
16547 case Builtin::BI__builtin_clzll:
16548 case Builtin::BI__builtin_clzs:
16549 case Builtin::BI__builtin_clzg:
16550 case Builtin::BI__builtin_elementwise_clzg:
16551 case Builtin::BI__lzcnt16:
16552 case Builtin::BI__lzcnt:
16553 case Builtin::BI__lzcnt64: {
16564 std::optional<APSInt> Fallback;
16565 if ((BuiltinOp == Builtin::BI__builtin_clzg ||
16566 BuiltinOp == Builtin::BI__builtin_elementwise_clzg) &&
16571 Fallback = FallbackTemp;
16576 return Success(*Fallback, E);
16581 bool ZeroIsUndefined = BuiltinOp != Builtin::BI__lzcnt16 &&
16582 BuiltinOp != Builtin::BI__lzcnt &&
16583 BuiltinOp != Builtin::BI__lzcnt64;
16585 if (BuiltinOp == Builtin::BI__builtin_elementwise_clzg) {
16586 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
16590 if (ZeroIsUndefined)
16594 return Success(Val.countl_zero(), E);
16597 case Builtin::BI__builtin_constant_p: {
16598 const Expr *Arg = E->
getArg(0);
16607 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
16611 case Builtin::BI__noop:
16615 case Builtin::BI__builtin_is_constant_evaluated: {
16616 const auto *
Callee = Info.CurrentCall->getCallee();
16617 if (Info.InConstantContext && !Info.CheckingPotentialConstantExpression &&
16618 (Info.CallStackDepth == 1 ||
16619 (Info.CallStackDepth == 2 &&
Callee->isInStdNamespace() &&
16620 Callee->getIdentifier() &&
16621 Callee->getIdentifier()->isStr(
"is_constant_evaluated")))) {
16623 if (Info.EvalStatus.Diag)
16624 Info.report((Info.CallStackDepth == 1)
16626 : Info.CurrentCall->getCallRange().getBegin(),
16627 diag::warn_is_constant_evaluated_always_true_constexpr)
16628 << (Info.CallStackDepth == 1 ?
"__builtin_is_constant_evaluated"
16629 :
"std::is_constant_evaluated");
16632 return Success(Info.InConstantContext, E);
16635 case Builtin::BI__builtin_is_within_lifetime:
16636 if (
auto result = EvaluateBuiltinIsWithinLifetime(*
this, E))
16640 case Builtin::BI__builtin_ctz:
16641 case Builtin::BI__builtin_ctzl:
16642 case Builtin::BI__builtin_ctzll:
16643 case Builtin::BI__builtin_ctzs:
16644 case Builtin::BI__builtin_ctzg:
16645 case Builtin::BI__builtin_elementwise_ctzg: {
16656 std::optional<APSInt> Fallback;
16657 if ((BuiltinOp == Builtin::BI__builtin_ctzg ||
16658 BuiltinOp == Builtin::BI__builtin_elementwise_ctzg) &&
16663 Fallback = FallbackTemp;
16668 return Success(*Fallback, E);
16670 if (BuiltinOp == Builtin::BI__builtin_elementwise_ctzg) {
16671 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
16677 return Success(Val.countr_zero(), E);
16680 case Builtin::BI__builtin_eh_return_data_regno: {
16682 Operand = Info.Ctx.getTargetInfo().getEHDataRegisterNumber(Operand);
16686 case Builtin::BI__builtin_elementwise_abs: {
16691 return Success(Val.abs(), E);
16694 case Builtin::BI__builtin_expect:
16695 case Builtin::BI__builtin_expect_with_probability:
16696 return Visit(E->
getArg(0));
16698 case Builtin::BI__builtin_ptrauth_string_discriminator: {
16705 case Builtin::BI__builtin_infer_alloc_token: {
16711 E, diag::note_constexpr_infer_alloc_token_type_inference_failed);
16714 return Error(E, diag::note_constexpr_infer_alloc_token_no_metadata);
16716 Info.getLangOpts().AllocTokenMode.value_or(llvm::DefaultAllocTokenMode);
16717 uint64_t BitWidth = Info.Ctx.getTypeSize(Info.Ctx.getSizeType());
16718 auto MaxTokensOpt = Info.getLangOpts().AllocTokenMax;
16720 MaxTokensOpt.value_or(0) ? *MaxTokensOpt : (~0ULL >> (64 - BitWidth));
16721 auto MaybeToken = llvm::getAllocToken(Mode, *ATMD, MaxTokens);
16723 return Error(E, diag::note_constexpr_infer_alloc_token_stateful_mode);
16724 return Success(llvm::APInt(BitWidth, *MaybeToken), E);
16727 case Builtin::BI__builtin_ffs:
16728 case Builtin::BI__builtin_ffsl:
16729 case Builtin::BI__builtin_ffsll: {
16734 unsigned N = Val.countr_zero();
16735 return Success(N == Val.getBitWidth() ? 0 : N + 1, E);
16738 case Builtin::BI__builtin_fpclassify: {
16743 switch (Val.getCategory()) {
16744 case APFloat::fcNaN: Arg = 0;
break;
16745 case APFloat::fcInfinity: Arg = 1;
break;
16746 case APFloat::fcNormal: Arg = Val.isDenormal() ? 3 : 2;
break;
16747 case APFloat::fcZero: Arg = 4;
break;
16749 return Visit(E->
getArg(Arg));
16752 case Builtin::BI__builtin_isinf_sign: {
16755 Success(Val.isInfinity() ? (Val.isNegative() ? -1 : 1) : 0, E);
16758 case Builtin::BI__builtin_isinf: {
16761 Success(Val.isInfinity() ? 1 : 0, E);
16764 case Builtin::BI__builtin_isfinite: {
16767 Success(Val.isFinite() ? 1 : 0, E);
16770 case Builtin::BI__builtin_isnan: {
16773 Success(Val.isNaN() ? 1 : 0, E);
16776 case Builtin::BI__builtin_isnormal: {
16779 Success(Val.isNormal() ? 1 : 0, E);
16782 case Builtin::BI__builtin_issubnormal: {
16785 Success(Val.isDenormal() ? 1 : 0, E);
16788 case Builtin::BI__builtin_iszero: {
16791 Success(Val.isZero() ? 1 : 0, E);
16794 case Builtin::BI__builtin_signbit:
16795 case Builtin::BI__builtin_signbitf:
16796 case Builtin::BI__builtin_signbitl: {
16799 Success(Val.isNegative() ? 1 : 0, E);
16802 case Builtin::BI__builtin_isgreater:
16803 case Builtin::BI__builtin_isgreaterequal:
16804 case Builtin::BI__builtin_isless:
16805 case Builtin::BI__builtin_islessequal:
16806 case Builtin::BI__builtin_islessgreater:
16807 case Builtin::BI__builtin_isunordered: {
16816 switch (BuiltinOp) {
16817 case Builtin::BI__builtin_isgreater:
16819 case Builtin::BI__builtin_isgreaterequal:
16821 case Builtin::BI__builtin_isless:
16823 case Builtin::BI__builtin_islessequal:
16825 case Builtin::BI__builtin_islessgreater: {
16826 APFloat::cmpResult cmp = LHS.compare(RHS);
16827 return cmp == APFloat::cmpResult::cmpLessThan ||
16828 cmp == APFloat::cmpResult::cmpGreaterThan;
16830 case Builtin::BI__builtin_isunordered:
16831 return LHS.compare(RHS) == APFloat::cmpResult::cmpUnordered;
16833 llvm_unreachable(
"Unexpected builtin ID: Should be a floating "
16834 "point comparison function");
16842 case Builtin::BI__builtin_issignaling: {
16845 Success(Val.isSignaling() ? 1 : 0, E);
16848 case Builtin::BI__builtin_isfpclass: {
16852 unsigned Test =
static_cast<llvm::FPClassTest
>(MaskVal.getZExtValue());
16855 Success((Val.classify() & Test) ? 1 : 0, E);
16858 case Builtin::BI__builtin_parity:
16859 case Builtin::BI__builtin_parityl:
16860 case Builtin::BI__builtin_parityll: {
16865 return Success(Val.popcount() % 2, E);
16868 case Builtin::BI__builtin_abs:
16869 case Builtin::BI__builtin_labs:
16870 case Builtin::BI__builtin_llabs: {
16874 if (Val ==
APSInt(APInt::getSignedMinValue(Val.getBitWidth()),
16877 if (Val.isNegative())
16882 case Builtin::BI__builtin_popcount:
16883 case Builtin::BI__builtin_popcountl:
16884 case Builtin::BI__builtin_popcountll:
16885 case Builtin::BI__builtin_popcountg:
16886 case Builtin::BI__builtin_elementwise_popcount:
16887 case Builtin::BI__popcnt16:
16888 case Builtin::BI__popcnt:
16889 case Builtin::BI__popcnt64: {
16900 return Success(Val.popcount(), E);
16903 case Builtin::BI__builtin_rotateleft8:
16904 case Builtin::BI__builtin_rotateleft16:
16905 case Builtin::BI__builtin_rotateleft32:
16906 case Builtin::BI__builtin_rotateleft64:
16907 case Builtin::BI__builtin_rotateright8:
16908 case Builtin::BI__builtin_rotateright16:
16909 case Builtin::BI__builtin_rotateright32:
16910 case Builtin::BI__builtin_rotateright64:
16911 case Builtin::BI__builtin_stdc_rotate_left:
16912 case Builtin::BI__builtin_stdc_rotate_right:
16913 case Builtin::BIstdc_rotate_left_uc:
16914 case Builtin::BIstdc_rotate_left_us:
16915 case Builtin::BIstdc_rotate_left_ui:
16916 case Builtin::BIstdc_rotate_left_ul:
16917 case Builtin::BIstdc_rotate_left_ull:
16918 case Builtin::BIstdc_rotate_right_uc:
16919 case Builtin::BIstdc_rotate_right_us:
16920 case Builtin::BIstdc_rotate_right_ui:
16921 case Builtin::BIstdc_rotate_right_ul:
16922 case Builtin::BIstdc_rotate_right_ull:
16923 case Builtin::BI_rotl8:
16924 case Builtin::BI_rotl16:
16925 case Builtin::BI_rotl:
16926 case Builtin::BI_lrotl:
16927 case Builtin::BI_rotl64:
16928 case Builtin::BI_rotr8:
16929 case Builtin::BI_rotr16:
16930 case Builtin::BI_rotr:
16931 case Builtin::BI_lrotr:
16932 case Builtin::BI_rotr64: {
16940 switch (BuiltinOp) {
16941 case Builtin::BI__builtin_rotateright8:
16942 case Builtin::BI__builtin_rotateright16:
16943 case Builtin::BI__builtin_rotateright32:
16944 case Builtin::BI__builtin_rotateright64:
16945 case Builtin::BI__builtin_stdc_rotate_right:
16946 case Builtin::BIstdc_rotate_right_uc:
16947 case Builtin::BIstdc_rotate_right_us:
16948 case Builtin::BIstdc_rotate_right_ui:
16949 case Builtin::BIstdc_rotate_right_ul:
16950 case Builtin::BIstdc_rotate_right_ull:
16951 case Builtin::BI_rotr8:
16952 case Builtin::BI_rotr16:
16953 case Builtin::BI_rotr:
16954 case Builtin::BI_lrotr:
16955 case Builtin::BI_rotr64:
16964 case Builtin::BIstdc_leading_zeros_uc:
16965 case Builtin::BIstdc_leading_zeros_us:
16966 case Builtin::BIstdc_leading_zeros_ui:
16967 case Builtin::BIstdc_leading_zeros_ul:
16968 case Builtin::BIstdc_leading_zeros_ull:
16969 case Builtin::BIstdc_leading_ones_uc:
16970 case Builtin::BIstdc_leading_ones_us:
16971 case Builtin::BIstdc_leading_ones_ui:
16972 case Builtin::BIstdc_leading_ones_ul:
16973 case Builtin::BIstdc_leading_ones_ull:
16974 case Builtin::BIstdc_trailing_zeros_uc:
16975 case Builtin::BIstdc_trailing_zeros_us:
16976 case Builtin::BIstdc_trailing_zeros_ui:
16977 case Builtin::BIstdc_trailing_zeros_ul:
16978 case Builtin::BIstdc_trailing_zeros_ull:
16979 case Builtin::BIstdc_trailing_ones_uc:
16980 case Builtin::BIstdc_trailing_ones_us:
16981 case Builtin::BIstdc_trailing_ones_ui:
16982 case Builtin::BIstdc_trailing_ones_ul:
16983 case Builtin::BIstdc_trailing_ones_ull:
16984 case Builtin::BIstdc_first_leading_zero_uc:
16985 case Builtin::BIstdc_first_leading_zero_us:
16986 case Builtin::BIstdc_first_leading_zero_ui:
16987 case Builtin::BIstdc_first_leading_zero_ul:
16988 case Builtin::BIstdc_first_leading_zero_ull:
16989 case Builtin::BIstdc_first_leading_one_uc:
16990 case Builtin::BIstdc_first_leading_one_us:
16991 case Builtin::BIstdc_first_leading_one_ui:
16992 case Builtin::BIstdc_first_leading_one_ul:
16993 case Builtin::BIstdc_first_leading_one_ull:
16994 case Builtin::BIstdc_first_trailing_zero_uc:
16995 case Builtin::BIstdc_first_trailing_zero_us:
16996 case Builtin::BIstdc_first_trailing_zero_ui:
16997 case Builtin::BIstdc_first_trailing_zero_ul:
16998 case Builtin::BIstdc_first_trailing_zero_ull:
16999 case Builtin::BIstdc_first_trailing_one_uc:
17000 case Builtin::BIstdc_first_trailing_one_us:
17001 case Builtin::BIstdc_first_trailing_one_ui:
17002 case Builtin::BIstdc_first_trailing_one_ul:
17003 case Builtin::BIstdc_first_trailing_one_ull:
17004 case Builtin::BIstdc_count_zeros_uc:
17005 case Builtin::BIstdc_count_zeros_us:
17006 case Builtin::BIstdc_count_zeros_ui:
17007 case Builtin::BIstdc_count_zeros_ul:
17008 case Builtin::BIstdc_count_zeros_ull:
17009 case Builtin::BIstdc_count_ones_uc:
17010 case Builtin::BIstdc_count_ones_us:
17011 case Builtin::BIstdc_count_ones_ui:
17012 case Builtin::BIstdc_count_ones_ul:
17013 case Builtin::BIstdc_count_ones_ull:
17014 case Builtin::BIstdc_has_single_bit_uc:
17015 case Builtin::BIstdc_has_single_bit_us:
17016 case Builtin::BIstdc_has_single_bit_ui:
17017 case Builtin::BIstdc_has_single_bit_ul:
17018 case Builtin::BIstdc_has_single_bit_ull:
17019 case Builtin::BIstdc_bit_width_uc:
17020 case Builtin::BIstdc_bit_width_us:
17021 case Builtin::BIstdc_bit_width_ui:
17022 case Builtin::BIstdc_bit_width_ul:
17023 case Builtin::BIstdc_bit_width_ull:
17024 case Builtin::BIstdc_bit_floor_uc:
17025 case Builtin::BIstdc_bit_floor_us:
17026 case Builtin::BIstdc_bit_floor_ui:
17027 case Builtin::BIstdc_bit_floor_ul:
17028 case Builtin::BIstdc_bit_floor_ull:
17029 case Builtin::BIstdc_bit_ceil_uc:
17030 case Builtin::BIstdc_bit_ceil_us:
17031 case Builtin::BIstdc_bit_ceil_ui:
17032 case Builtin::BIstdc_bit_ceil_ul:
17033 case Builtin::BIstdc_bit_ceil_ull:
17034 case Builtin::BI__builtin_stdc_leading_zeros:
17035 case Builtin::BI__builtin_stdc_leading_ones:
17036 case Builtin::BI__builtin_stdc_trailing_zeros:
17037 case Builtin::BI__builtin_stdc_trailing_ones:
17038 case Builtin::BI__builtin_stdc_first_leading_zero:
17039 case Builtin::BI__builtin_stdc_first_leading_one:
17040 case Builtin::BI__builtin_stdc_first_trailing_zero:
17041 case Builtin::BI__builtin_stdc_first_trailing_one:
17042 case Builtin::BI__builtin_stdc_count_zeros:
17043 case Builtin::BI__builtin_stdc_count_ones:
17044 case Builtin::BI__builtin_stdc_has_single_bit:
17045 case Builtin::BI__builtin_stdc_bit_width:
17046 case Builtin::BI__builtin_stdc_bit_floor:
17047 case Builtin::BI__builtin_stdc_bit_ceil: {
17052 unsigned BitWidth = Val.getBitWidth();
17053 const unsigned ResBitWidth = Info.Ctx.getIntWidth(E->
getType());
17055 switch (BuiltinOp) {
17056 case Builtin::BIstdc_leading_zeros_uc:
17057 case Builtin::BIstdc_leading_zeros_us:
17058 case Builtin::BIstdc_leading_zeros_ui:
17059 case Builtin::BIstdc_leading_zeros_ul:
17060 case Builtin::BIstdc_leading_zeros_ull:
17061 case Builtin::BI__builtin_stdc_leading_zeros:
17062 return Success(
APInt(ResBitWidth, Val.countl_zero()), E);
17063 case Builtin::BIstdc_leading_ones_uc:
17064 case Builtin::BIstdc_leading_ones_us:
17065 case Builtin::BIstdc_leading_ones_ui:
17066 case Builtin::BIstdc_leading_ones_ul:
17067 case Builtin::BIstdc_leading_ones_ull:
17068 case Builtin::BI__builtin_stdc_leading_ones:
17069 return Success(
APInt(ResBitWidth, Val.countl_one()), E);
17070 case Builtin::BIstdc_trailing_zeros_uc:
17071 case Builtin::BIstdc_trailing_zeros_us:
17072 case Builtin::BIstdc_trailing_zeros_ui:
17073 case Builtin::BIstdc_trailing_zeros_ul:
17074 case Builtin::BIstdc_trailing_zeros_ull:
17075 case Builtin::BI__builtin_stdc_trailing_zeros:
17076 return Success(
APInt(ResBitWidth, Val.countr_zero()), E);
17077 case Builtin::BIstdc_trailing_ones_uc:
17078 case Builtin::BIstdc_trailing_ones_us:
17079 case Builtin::BIstdc_trailing_ones_ui:
17080 case Builtin::BIstdc_trailing_ones_ul:
17081 case Builtin::BIstdc_trailing_ones_ull:
17082 case Builtin::BI__builtin_stdc_trailing_ones:
17083 return Success(
APInt(ResBitWidth, Val.countr_one()), E);
17084 case Builtin::BIstdc_first_leading_zero_uc:
17085 case Builtin::BIstdc_first_leading_zero_us:
17086 case Builtin::BIstdc_first_leading_zero_ui:
17087 case Builtin::BIstdc_first_leading_zero_ul:
17088 case Builtin::BIstdc_first_leading_zero_ull:
17089 case Builtin::BI__builtin_stdc_first_leading_zero:
17091 APInt(ResBitWidth, Val.isAllOnes() ? 0 : Val.countl_one() + 1), E);
17092 case Builtin::BIstdc_first_leading_one_uc:
17093 case Builtin::BIstdc_first_leading_one_us:
17094 case Builtin::BIstdc_first_leading_one_ui:
17095 case Builtin::BIstdc_first_leading_one_ul:
17096 case Builtin::BIstdc_first_leading_one_ull:
17097 case Builtin::BI__builtin_stdc_first_leading_one:
17099 APInt(ResBitWidth, Val.isZero() ? 0 : Val.countl_zero() + 1), E);
17100 case Builtin::BIstdc_first_trailing_zero_uc:
17101 case Builtin::BIstdc_first_trailing_zero_us:
17102 case Builtin::BIstdc_first_trailing_zero_ui:
17103 case Builtin::BIstdc_first_trailing_zero_ul:
17104 case Builtin::BIstdc_first_trailing_zero_ull:
17105 case Builtin::BI__builtin_stdc_first_trailing_zero:
17107 APInt(ResBitWidth, Val.isAllOnes() ? 0 : Val.countr_one() + 1), E);
17108 case Builtin::BIstdc_first_trailing_one_uc:
17109 case Builtin::BIstdc_first_trailing_one_us:
17110 case Builtin::BIstdc_first_trailing_one_ui:
17111 case Builtin::BIstdc_first_trailing_one_ul:
17112 case Builtin::BIstdc_first_trailing_one_ull:
17113 case Builtin::BI__builtin_stdc_first_trailing_one:
17115 APInt(ResBitWidth, Val.isZero() ? 0 : Val.countr_zero() + 1), E);
17116 case Builtin::BIstdc_count_zeros_uc:
17117 case Builtin::BIstdc_count_zeros_us:
17118 case Builtin::BIstdc_count_zeros_ui:
17119 case Builtin::BIstdc_count_zeros_ul:
17120 case Builtin::BIstdc_count_zeros_ull:
17121 case Builtin::BI__builtin_stdc_count_zeros: {
17122 APInt Cnt(ResBitWidth, BitWidth - Val.popcount());
17125 case Builtin::BIstdc_count_ones_uc:
17126 case Builtin::BIstdc_count_ones_us:
17127 case Builtin::BIstdc_count_ones_ui:
17128 case Builtin::BIstdc_count_ones_ul:
17129 case Builtin::BIstdc_count_ones_ull:
17130 case Builtin::BI__builtin_stdc_count_ones: {
17131 APInt Cnt(ResBitWidth, Val.popcount());
17134 case Builtin::BIstdc_has_single_bit_uc:
17135 case Builtin::BIstdc_has_single_bit_us:
17136 case Builtin::BIstdc_has_single_bit_ui:
17137 case Builtin::BIstdc_has_single_bit_ul:
17138 case Builtin::BIstdc_has_single_bit_ull:
17139 case Builtin::BI__builtin_stdc_has_single_bit: {
17140 APInt Res(ResBitWidth, Val.popcount() == 1 ? 1 : 0);
17143 case Builtin::BIstdc_bit_width_uc:
17144 case Builtin::BIstdc_bit_width_us:
17145 case Builtin::BIstdc_bit_width_ui:
17146 case Builtin::BIstdc_bit_width_ul:
17147 case Builtin::BIstdc_bit_width_ull:
17148 case Builtin::BI__builtin_stdc_bit_width:
17149 return Success(
APInt(ResBitWidth, BitWidth - Val.countl_zero()), E);
17150 case Builtin::BIstdc_bit_floor_uc:
17151 case Builtin::BIstdc_bit_floor_us:
17152 case Builtin::BIstdc_bit_floor_ui:
17153 case Builtin::BIstdc_bit_floor_ul:
17154 case Builtin::BIstdc_bit_floor_ull:
17155 case Builtin::BI__builtin_stdc_bit_floor: {
17158 unsigned Exp = BitWidth - Val.countl_zero() - 1;
17160 APSInt(APInt::getOneBitSet(BitWidth, Exp),
true), E);
17162 case Builtin::BIstdc_bit_ceil_uc:
17163 case Builtin::BIstdc_bit_ceil_us:
17164 case Builtin::BIstdc_bit_ceil_ui:
17165 case Builtin::BIstdc_bit_ceil_ul:
17166 case Builtin::BIstdc_bit_ceil_ull:
17167 case Builtin::BI__builtin_stdc_bit_ceil: {
17170 APInt ValMinusOne = Val - 1;
17171 unsigned LZ = ValMinusOne.countl_zero();
17175 APInt Result = APInt::getOneBitSet(BitWidth, BitWidth - LZ);
17179 llvm_unreachable(
"Unknown stdc builtin");
17183 case Builtin::BI__builtin_elementwise_add_sat: {
17189 APInt Result = LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS);
17192 case Builtin::BI__builtin_elementwise_sub_sat: {
17198 APInt Result = LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
17201 case Builtin::BI__builtin_elementwise_max: {
17210 case Builtin::BI__builtin_elementwise_min: {
17219 case Builtin::BI__builtin_elementwise_fshl:
17220 case Builtin::BI__builtin_elementwise_fshr: {
17227 switch (BuiltinOp) {
17228 case Builtin::BI__builtin_elementwise_fshl: {
17229 APSInt Result(llvm::APIntOps::fshl(Hi, Lo, Shift), Hi.isUnsigned());
17232 case Builtin::BI__builtin_elementwise_fshr: {
17233 APSInt Result(llvm::APIntOps::fshr(Hi, Lo, Shift), Hi.isUnsigned());
17237 llvm_unreachable(
"Fully covered switch above");
17239 case Builtin::BIstrlen:
17240 case Builtin::BIwcslen:
17242 if (Info.getLangOpts().CPlusPlus11)
17243 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
17245 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
17247 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
17249 case Builtin::BI__builtin_strlen:
17250 case Builtin::BI__builtin_wcslen: {
17253 if (std::optional<uint64_t> StrLen =
17259 case Builtin::BIstrcmp:
17260 case Builtin::BIwcscmp:
17261 case Builtin::BIstrncmp:
17262 case Builtin::BIwcsncmp:
17263 case Builtin::BImemcmp:
17264 case Builtin::BIbcmp:
17265 case Builtin::BIwmemcmp:
17267 if (Info.getLangOpts().CPlusPlus11)
17268 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
17270 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
17272 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
17274 case Builtin::BI__builtin_strcmp:
17275 case Builtin::BI__builtin_wcscmp:
17276 case Builtin::BI__builtin_strncmp:
17277 case Builtin::BI__builtin_wcsncmp:
17278 case Builtin::BI__builtin_memcmp:
17279 case Builtin::BI__builtin_bcmp:
17280 case Builtin::BI__builtin_wmemcmp: {
17281 LValue String1, String2;
17287 if (BuiltinOp != Builtin::BIstrcmp &&
17288 BuiltinOp != Builtin::BIwcscmp &&
17289 BuiltinOp != Builtin::BI__builtin_strcmp &&
17290 BuiltinOp != Builtin::BI__builtin_wcscmp) {
17294 MaxLength = N.getZExtValue();
17298 if (MaxLength == 0u)
17301 if (!String1.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
17302 !String2.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
17303 String1.Designator.Invalid || String2.Designator.Invalid)
17306 QualType CharTy1 = String1.Designator.getType(Info.Ctx);
17307 QualType CharTy2 = String2.Designator.getType(Info.Ctx);
17309 bool IsRawByte = BuiltinOp == Builtin::BImemcmp ||
17310 BuiltinOp == Builtin::BIbcmp ||
17311 BuiltinOp == Builtin::BI__builtin_memcmp ||
17312 BuiltinOp == Builtin::BI__builtin_bcmp;
17314 assert(IsRawByte ||
17315 (Info.Ctx.hasSameUnqualifiedType(
17317 Info.Ctx.hasSameUnqualifiedType(CharTy1, CharTy2)));
17324 Info.FFDiag(E, diag::note_constexpr_memcmp_unsupported)
17325 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp) << CharTy1
17330 const auto &ReadCurElems = [&](
APValue &Char1,
APValue &Char2) {
17333 Char1.
isInt() && Char2.isInt();
17335 const auto &AdvanceElems = [&] {
17341 (BuiltinOp != Builtin::BImemcmp && BuiltinOp != Builtin::BIbcmp &&
17342 BuiltinOp != Builtin::BIwmemcmp &&
17343 BuiltinOp != Builtin::BI__builtin_memcmp &&
17344 BuiltinOp != Builtin::BI__builtin_bcmp &&
17345 BuiltinOp != Builtin::BI__builtin_wmemcmp);
17346 bool IsWide = BuiltinOp == Builtin::BIwcscmp ||
17347 BuiltinOp == Builtin::BIwcsncmp ||
17348 BuiltinOp == Builtin::BIwmemcmp ||
17349 BuiltinOp == Builtin::BI__builtin_wcscmp ||
17350 BuiltinOp == Builtin::BI__builtin_wcsncmp ||
17351 BuiltinOp == Builtin::BI__builtin_wmemcmp;
17353 for (; MaxLength; --MaxLength) {
17355 if (!ReadCurElems(Char1, Char2))
17363 if (StopAtNull && !Char1.
getInt())
17365 assert(!(StopAtNull && !Char2.
getInt()));
17366 if (!AdvanceElems())
17373 case Builtin::BI__atomic_always_lock_free:
17374 case Builtin::BI__atomic_is_lock_free:
17375 case Builtin::BI__c11_atomic_is_lock_free: {
17391 if (
Size.isPowerOfTwo()) {
17393 unsigned InlineWidthBits =
17394 Info.Ctx.getTargetInfo().getMaxAtomicInlineWidth();
17395 if (Size <= Info.Ctx.toCharUnitsFromBits(InlineWidthBits)) {
17396 if (BuiltinOp == Builtin::BI__c11_atomic_is_lock_free ||
17402 const Expr *PtrArg = E->
getArg(1);
17408 IntResult.isAligned(
Size.getAsAlign()))
17412 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(PtrArg)) {
17415 if (ICE->getCastKind() == CK_BitCast)
17416 PtrArg = ICE->getSubExpr();
17419 if (
auto PtrTy = PtrArg->
getType()->
getAs<PointerType>()) {
17422 Info.Ctx.getTypeAlignInChars(PointeeType) >= Size) {
17430 return BuiltinOp == Builtin::BI__atomic_always_lock_free ?
17433 case Builtin::BI__builtin_addcb:
17434 case Builtin::BI__builtin_addcs:
17435 case Builtin::BI__builtin_addc:
17436 case Builtin::BI__builtin_addcl:
17437 case Builtin::BI__builtin_addcll:
17438 case Builtin::BI__builtin_subcb:
17439 case Builtin::BI__builtin_subcs:
17440 case Builtin::BI__builtin_subc:
17441 case Builtin::BI__builtin_subcl:
17442 case Builtin::BI__builtin_subcll: {
17443 LValue CarryOutLValue;
17455 bool FirstOverflowed =
false;
17456 bool SecondOverflowed =
false;
17457 switch (BuiltinOp) {
17459 llvm_unreachable(
"Invalid value for BuiltinOp");
17460 case Builtin::BI__builtin_addcb:
17461 case Builtin::BI__builtin_addcs:
17462 case Builtin::BI__builtin_addc:
17463 case Builtin::BI__builtin_addcl:
17464 case Builtin::BI__builtin_addcll:
17466 LHS.uadd_ov(RHS, FirstOverflowed).uadd_ov(CarryIn, SecondOverflowed);
17468 case Builtin::BI__builtin_subcb:
17469 case Builtin::BI__builtin_subcs:
17470 case Builtin::BI__builtin_subc:
17471 case Builtin::BI__builtin_subcl:
17472 case Builtin::BI__builtin_subcll:
17474 LHS.usub_ov(RHS, FirstOverflowed).usub_ov(CarryIn, SecondOverflowed);
17480 CarryOut = (
uint64_t)(FirstOverflowed | SecondOverflowed);
17486 case Builtin::BI__builtin_add_overflow:
17487 case Builtin::BI__builtin_sub_overflow:
17488 case Builtin::BI__builtin_mul_overflow:
17489 case Builtin::BI__builtin_sadd_overflow:
17490 case Builtin::BI__builtin_uadd_overflow:
17491 case Builtin::BI__builtin_uaddl_overflow:
17492 case Builtin::BI__builtin_uaddll_overflow:
17493 case Builtin::BI__builtin_usub_overflow:
17494 case Builtin::BI__builtin_usubl_overflow:
17495 case Builtin::BI__builtin_usubll_overflow:
17496 case Builtin::BI__builtin_umul_overflow:
17497 case Builtin::BI__builtin_umull_overflow:
17498 case Builtin::BI__builtin_umulll_overflow:
17499 case Builtin::BI__builtin_saddl_overflow:
17500 case Builtin::BI__builtin_saddll_overflow:
17501 case Builtin::BI__builtin_ssub_overflow:
17502 case Builtin::BI__builtin_ssubl_overflow:
17503 case Builtin::BI__builtin_ssubll_overflow:
17504 case Builtin::BI__builtin_smul_overflow:
17505 case Builtin::BI__builtin_smull_overflow:
17506 case Builtin::BI__builtin_smulll_overflow: {
17507 LValue ResultLValue;
17517 bool DidOverflow =
false;
17520 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
17521 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
17522 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
17523 bool IsSigned = LHS.isSigned() || RHS.isSigned() ||
17525 bool AllSigned = LHS.isSigned() && RHS.isSigned() &&
17527 uint64_t LHSSize = LHS.getBitWidth();
17528 uint64_t RHSSize = RHS.getBitWidth();
17529 uint64_t ResultSize = Info.Ctx.getIntWidth(ResultType);
17530 uint64_t MaxBits = std::max(std::max(LHSSize, RHSSize), ResultSize);
17536 if (IsSigned && !AllSigned)
17539 LHS =
APSInt(LHS.extOrTrunc(MaxBits), !IsSigned);
17540 RHS =
APSInt(RHS.extOrTrunc(MaxBits), !IsSigned);
17545 switch (BuiltinOp) {
17547 llvm_unreachable(
"Invalid value for BuiltinOp");
17548 case Builtin::BI__builtin_add_overflow:
17549 case Builtin::BI__builtin_sadd_overflow:
17550 case Builtin::BI__builtin_saddl_overflow:
17551 case Builtin::BI__builtin_saddll_overflow:
17552 case Builtin::BI__builtin_uadd_overflow:
17553 case Builtin::BI__builtin_uaddl_overflow:
17554 case Builtin::BI__builtin_uaddll_overflow:
17555 Result = LHS.isSigned() ? LHS.sadd_ov(RHS, DidOverflow)
17556 : LHS.uadd_ov(RHS, DidOverflow);
17558 case Builtin::BI__builtin_sub_overflow:
17559 case Builtin::BI__builtin_ssub_overflow:
17560 case Builtin::BI__builtin_ssubl_overflow:
17561 case Builtin::BI__builtin_ssubll_overflow:
17562 case Builtin::BI__builtin_usub_overflow:
17563 case Builtin::BI__builtin_usubl_overflow:
17564 case Builtin::BI__builtin_usubll_overflow:
17565 Result = LHS.isSigned() ? LHS.ssub_ov(RHS, DidOverflow)
17566 : LHS.usub_ov(RHS, DidOverflow);
17568 case Builtin::BI__builtin_mul_overflow:
17569 case Builtin::BI__builtin_smul_overflow:
17570 case Builtin::BI__builtin_smull_overflow:
17571 case Builtin::BI__builtin_smulll_overflow:
17572 case Builtin::BI__builtin_umul_overflow:
17573 case Builtin::BI__builtin_umull_overflow:
17574 case Builtin::BI__builtin_umulll_overflow:
17575 Result = LHS.isSigned() ? LHS.smul_ov(RHS, DidOverflow)
17576 : LHS.umul_ov(RHS, DidOverflow);
17585 APSInt Temp =
Result.extOrTrunc(Info.Ctx.getIntWidth(ResultType));
17590 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
17591 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
17592 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
17593 if (!APSInt::isSameValue(Temp,
Result))
17594 DidOverflow =
true;
17601 return Success(DidOverflow, E);
17604 case Builtin::BI__builtin_reduce_add:
17605 case Builtin::BI__builtin_reduce_mul:
17606 case Builtin::BI__builtin_reduce_and:
17607 case Builtin::BI__builtin_reduce_or:
17608 case Builtin::BI__builtin_reduce_xor:
17609 case Builtin::BI__builtin_reduce_min:
17610 case Builtin::BI__builtin_reduce_max: {
17617 for (
unsigned EltNum = 1; EltNum < SourceLen; ++EltNum) {
17618 switch (BuiltinOp) {
17621 case Builtin::BI__builtin_reduce_add: {
17624 Reduced.getBitWidth() + 1, std::plus<APSInt>(), Reduced))
17628 case Builtin::BI__builtin_reduce_mul: {
17631 Reduced.getBitWidth() * 2, std::multiplies<APSInt>(), Reduced))
17635 case Builtin::BI__builtin_reduce_and: {
17639 case Builtin::BI__builtin_reduce_or: {
17643 case Builtin::BI__builtin_reduce_xor: {
17647 case Builtin::BI__builtin_reduce_min: {
17651 case Builtin::BI__builtin_reduce_max: {
17661 case clang::X86::BI__builtin_ia32_addcarryx_u32:
17662 case clang::X86::BI__builtin_ia32_addcarryx_u64:
17663 case clang::X86::BI__builtin_ia32_subborrow_u32:
17664 case clang::X86::BI__builtin_ia32_subborrow_u64: {
17665 LValue ResultLValue;
17666 APSInt CarryIn, LHS, RHS;
17674 bool IsAdd = BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u32 ||
17675 BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u64;
17677 unsigned BitWidth = LHS.getBitWidth();
17678 unsigned CarryInBit = CarryIn.ugt(0) ? 1 : 0;
17681 ? (LHS.zext(BitWidth + 1) + (RHS.zext(BitWidth + 1) + CarryInBit))
17682 : (LHS.zext(BitWidth + 1) - (RHS.zext(BitWidth + 1) + CarryInBit));
17684 APInt Result = ExResult.extractBits(BitWidth, 0);
17685 uint64_t CarryOut = ExResult.extractBitsAsZExtValue(1, BitWidth);
17693 case clang::X86::BI__builtin_ia32_movmskps:
17694 case clang::X86::BI__builtin_ia32_movmskpd:
17695 case clang::X86::BI__builtin_ia32_pmovmskb128:
17696 case clang::X86::BI__builtin_ia32_pmovmskb256:
17697 case clang::X86::BI__builtin_ia32_movmskps256:
17698 case clang::X86::BI__builtin_ia32_movmskpd256: {
17705 unsigned ResultLen = Info.Ctx.getTypeSize(
17709 for (
unsigned I = 0; I != SourceLen; ++I) {
17711 if (ElemQT->isIntegerType()) {
17713 }
else if (ElemQT->isRealFloatingType()) {
17718 Result.setBitVal(I, Elem.isNegative());
17723 case clang::X86::BI__builtin_ia32_bextr_u32:
17724 case clang::X86::BI__builtin_ia32_bextr_u64:
17725 case clang::X86::BI__builtin_ia32_bextri_u32:
17726 case clang::X86::BI__builtin_ia32_bextri_u64: {
17732 unsigned BitWidth = Val.getBitWidth();
17734 uint64_t Length = Idx.extractBitsAsZExtValue(8, 8);
17735 Length = Length > BitWidth ? BitWidth : Length;
17738 if (Length == 0 || Shift >= BitWidth)
17742 Result &= llvm::maskTrailingOnes<uint64_t>(Length);
17746 case clang::X86::BI__builtin_ia32_bzhi_si:
17747 case clang::X86::BI__builtin_ia32_bzhi_di: {
17753 unsigned BitWidth = Val.getBitWidth();
17754 unsigned Index = Idx.extractBitsAsZExtValue(8, 0);
17755 if (Index < BitWidth)
17756 Val.clearHighBits(BitWidth - Index);
17760 case clang::X86::BI__builtin_ia32_ktestcqi:
17761 case clang::X86::BI__builtin_ia32_ktestchi:
17762 case clang::X86::BI__builtin_ia32_ktestcsi:
17763 case clang::X86::BI__builtin_ia32_ktestcdi: {
17769 return Success((~A & B) == 0, E);
17772 case clang::X86::BI__builtin_ia32_ktestzqi:
17773 case clang::X86::BI__builtin_ia32_ktestzhi:
17774 case clang::X86::BI__builtin_ia32_ktestzsi:
17775 case clang::X86::BI__builtin_ia32_ktestzdi: {
17781 return Success((A & B) == 0, E);
17784 case clang::X86::BI__builtin_ia32_kortestcqi:
17785 case clang::X86::BI__builtin_ia32_kortestchi:
17786 case clang::X86::BI__builtin_ia32_kortestcsi:
17787 case clang::X86::BI__builtin_ia32_kortestcdi: {
17793 return Success(~(A | B) == 0, E);
17796 case clang::X86::BI__builtin_ia32_kortestzqi:
17797 case clang::X86::BI__builtin_ia32_kortestzhi:
17798 case clang::X86::BI__builtin_ia32_kortestzsi:
17799 case clang::X86::BI__builtin_ia32_kortestzdi: {
17805 return Success((A | B) == 0, E);
17808 case clang::X86::BI__builtin_ia32_kunpckhi:
17809 case clang::X86::BI__builtin_ia32_kunpckdi:
17810 case clang::X86::BI__builtin_ia32_kunpcksi: {
17818 unsigned BW = A.getBitWidth();
17819 APSInt Result(A.trunc(BW / 2).concat(B.trunc(BW / 2)), A.isUnsigned());
17823 case clang::X86::BI__builtin_ia32_lzcnt_u16:
17824 case clang::X86::BI__builtin_ia32_lzcnt_u32:
17825 case clang::X86::BI__builtin_ia32_lzcnt_u64: {
17829 return Success(Val.countLeadingZeros(), E);
17832 case clang::X86::BI__builtin_ia32_tzcnt_u16:
17833 case clang::X86::BI__builtin_ia32_tzcnt_u32:
17834 case clang::X86::BI__builtin_ia32_tzcnt_u64: {
17838 return Success(Val.countTrailingZeros(), E);
17841 case clang::X86::BI__builtin_ia32_pdep_si:
17842 case clang::X86::BI__builtin_ia32_pdep_di: {
17848 unsigned BitWidth = Val.getBitWidth();
17850 for (
unsigned I = 0, P = 0; I != BitWidth; ++I)
17852 Result.setBitVal(I, Val[P++]);
17856 case clang::X86::BI__builtin_ia32_pext_si:
17857 case clang::X86::BI__builtin_ia32_pext_di: {
17863 unsigned BitWidth = Val.getBitWidth();
17865 for (
unsigned I = 0, P = 0; I != BitWidth; ++I)
17867 Result.setBitVal(P++, Val[I]);
17870 case X86::BI__builtin_ia32_ptestz128:
17871 case X86::BI__builtin_ia32_ptestz256:
17872 case X86::BI__builtin_ia32_vtestzps:
17873 case X86::BI__builtin_ia32_vtestzps256:
17874 case X86::BI__builtin_ia32_vtestzpd:
17875 case X86::BI__builtin_ia32_vtestzpd256: {
17877 [](
const APInt &A,
const APInt &B) {
return (A & B) == 0; });
17879 case X86::BI__builtin_ia32_ptestc128:
17880 case X86::BI__builtin_ia32_ptestc256:
17881 case X86::BI__builtin_ia32_vtestcps:
17882 case X86::BI__builtin_ia32_vtestcps256:
17883 case X86::BI__builtin_ia32_vtestcpd:
17884 case X86::BI__builtin_ia32_vtestcpd256: {
17886 [](
const APInt &A,
const APInt &B) {
return (~A & B) == 0; });
17888 case X86::BI__builtin_ia32_ptestnzc128:
17889 case X86::BI__builtin_ia32_ptestnzc256:
17890 case X86::BI__builtin_ia32_vtestnzcps:
17891 case X86::BI__builtin_ia32_vtestnzcps256:
17892 case X86::BI__builtin_ia32_vtestnzcpd:
17893 case X86::BI__builtin_ia32_vtestnzcpd256: {
17894 return EvalTestOp([](
const APInt &A,
const APInt &B) {
17895 return ((A & B) != 0) && ((~A & B) != 0);
17898 case X86::BI__builtin_ia32_kandqi:
17899 case X86::BI__builtin_ia32_kandhi:
17900 case X86::BI__builtin_ia32_kandsi:
17901 case X86::BI__builtin_ia32_kanddi: {
17902 return HandleMaskBinOp(
17903 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS & RHS; });
17906 case X86::BI__builtin_ia32_kandnqi:
17907 case X86::BI__builtin_ia32_kandnhi:
17908 case X86::BI__builtin_ia32_kandnsi:
17909 case X86::BI__builtin_ia32_kandndi: {
17910 return HandleMaskBinOp(
17911 [](
const APSInt &LHS,
const APSInt &RHS) {
return ~LHS & RHS; });
17914 case X86::BI__builtin_ia32_korqi:
17915 case X86::BI__builtin_ia32_korhi:
17916 case X86::BI__builtin_ia32_korsi:
17917 case X86::BI__builtin_ia32_kordi: {
17918 return HandleMaskBinOp(
17919 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS | RHS; });
17922 case X86::BI__builtin_ia32_kxnorqi:
17923 case X86::BI__builtin_ia32_kxnorhi:
17924 case X86::BI__builtin_ia32_kxnorsi:
17925 case X86::BI__builtin_ia32_kxnordi: {
17926 return HandleMaskBinOp(
17927 [](
const APSInt &LHS,
const APSInt &RHS) {
return ~(LHS ^ RHS); });
17930 case X86::BI__builtin_ia32_kxorqi:
17931 case X86::BI__builtin_ia32_kxorhi:
17932 case X86::BI__builtin_ia32_kxorsi:
17933 case X86::BI__builtin_ia32_kxordi: {
17934 return HandleMaskBinOp(
17935 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS ^ RHS; });
17938 case X86::BI__builtin_ia32_knotqi:
17939 case X86::BI__builtin_ia32_knothi:
17940 case X86::BI__builtin_ia32_knotsi:
17941 case X86::BI__builtin_ia32_knotdi: {
17949 case X86::BI__builtin_ia32_kaddqi:
17950 case X86::BI__builtin_ia32_kaddhi:
17951 case X86::BI__builtin_ia32_kaddsi:
17952 case X86::BI__builtin_ia32_kadddi: {
17953 return HandleMaskBinOp(
17954 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS + RHS; });
17957 case X86::BI__builtin_ia32_kmovb:
17958 case X86::BI__builtin_ia32_kmovw:
17959 case X86::BI__builtin_ia32_kmovd:
17960 case X86::BI__builtin_ia32_kmovq: {
17967 case X86::BI__builtin_ia32_kshiftliqi:
17968 case X86::BI__builtin_ia32_kshiftlihi:
17969 case X86::BI__builtin_ia32_kshiftlisi:
17970 case X86::BI__builtin_ia32_kshiftlidi: {
17971 return HandleMaskBinOp([](
const APSInt &LHS,
const APSInt &RHS) {
17972 unsigned Amt = RHS.getZExtValue() & 0xFF;
17973 if (Amt >= LHS.getBitWidth())
17974 return APSInt(APInt::getZero(LHS.getBitWidth()), LHS.isUnsigned());
17975 return APSInt(LHS.shl(Amt), LHS.isUnsigned());
17979 case X86::BI__builtin_ia32_kshiftriqi:
17980 case X86::BI__builtin_ia32_kshiftrihi:
17981 case X86::BI__builtin_ia32_kshiftrisi:
17982 case X86::BI__builtin_ia32_kshiftridi: {
17983 return HandleMaskBinOp([](
const APSInt &LHS,
const APSInt &RHS) {
17984 unsigned Amt = RHS.getZExtValue() & 0xFF;
17985 if (Amt >= LHS.getBitWidth())
17986 return APSInt(APInt::getZero(LHS.getBitWidth()), LHS.isUnsigned());
17987 return APSInt(LHS.lshr(Amt), LHS.isUnsigned());
17991 case clang::X86::BI__builtin_ia32_vec_ext_v4hi:
17992 case clang::X86::BI__builtin_ia32_vec_ext_v16qi:
17993 case clang::X86::BI__builtin_ia32_vec_ext_v8hi:
17994 case clang::X86::BI__builtin_ia32_vec_ext_v4si:
17995 case clang::X86::BI__builtin_ia32_vec_ext_v2di:
17996 case clang::X86::BI__builtin_ia32_vec_ext_v32qi:
17997 case clang::X86::BI__builtin_ia32_vec_ext_v16hi:
17998 case clang::X86::BI__builtin_ia32_vec_ext_v8si:
17999 case clang::X86::BI__builtin_ia32_vec_ext_v4di: {
18006 unsigned Idx =
static_cast<unsigned>(IdxAPS.getZExtValue() & (N - 1));
18010 case clang::X86::BI__builtin_ia32_cvtb2mask128:
18011 case clang::X86::BI__builtin_ia32_cvtb2mask256:
18012 case clang::X86::BI__builtin_ia32_cvtb2mask512:
18013 case clang::X86::BI__builtin_ia32_cvtw2mask128:
18014 case clang::X86::BI__builtin_ia32_cvtw2mask256:
18015 case clang::X86::BI__builtin_ia32_cvtw2mask512:
18016 case clang::X86::BI__builtin_ia32_cvtd2mask128:
18017 case clang::X86::BI__builtin_ia32_cvtd2mask256:
18018 case clang::X86::BI__builtin_ia32_cvtd2mask512:
18019 case clang::X86::BI__builtin_ia32_cvtq2mask128:
18020 case clang::X86::BI__builtin_ia32_cvtq2mask256:
18021 case clang::X86::BI__builtin_ia32_cvtq2mask512: {
18028 unsigned RetWidth = Info.Ctx.getIntWidth(E->
getType());
18029 llvm::APInt Bits(RetWidth, 0);
18031 for (
unsigned ElemNum = 0; ElemNum != VectorLen; ++ElemNum) {
18033 unsigned MSB = A[A.getBitWidth() - 1];
18034 Bits.setBitVal(ElemNum, MSB);
18037 APSInt RetMask(Bits,
true);
18041 case clang::X86::BI__builtin_ia32_cmpb128_mask:
18042 case clang::X86::BI__builtin_ia32_cmpw128_mask:
18043 case clang::X86::BI__builtin_ia32_cmpd128_mask:
18044 case clang::X86::BI__builtin_ia32_cmpq128_mask:
18045 case clang::X86::BI__builtin_ia32_cmpb256_mask:
18046 case clang::X86::BI__builtin_ia32_cmpw256_mask:
18047 case clang::X86::BI__builtin_ia32_cmpd256_mask:
18048 case clang::X86::BI__builtin_ia32_cmpq256_mask:
18049 case clang::X86::BI__builtin_ia32_cmpb512_mask:
18050 case clang::X86::BI__builtin_ia32_cmpw512_mask:
18051 case clang::X86::BI__builtin_ia32_cmpd512_mask:
18052 case clang::X86::BI__builtin_ia32_cmpq512_mask:
18053 case clang::X86::BI__builtin_ia32_ucmpb128_mask:
18054 case clang::X86::BI__builtin_ia32_ucmpw128_mask:
18055 case clang::X86::BI__builtin_ia32_ucmpd128_mask:
18056 case clang::X86::BI__builtin_ia32_ucmpq128_mask:
18057 case clang::X86::BI__builtin_ia32_ucmpb256_mask:
18058 case clang::X86::BI__builtin_ia32_ucmpw256_mask:
18059 case clang::X86::BI__builtin_ia32_ucmpd256_mask:
18060 case clang::X86::BI__builtin_ia32_ucmpq256_mask:
18061 case clang::X86::BI__builtin_ia32_ucmpb512_mask:
18062 case clang::X86::BI__builtin_ia32_ucmpw512_mask:
18063 case clang::X86::BI__builtin_ia32_ucmpd512_mask:
18064 case clang::X86::BI__builtin_ia32_ucmpq512_mask: {
18068 (BuiltinOp >= clang::X86::BI__builtin_ia32_ucmpb128_mask &&
18069 BuiltinOp <= clang::X86::BI__builtin_ia32_ucmpw512_mask);
18082 unsigned RetWidth = Mask.getBitWidth();
18084 APSInt RetMask(llvm::APInt(RetWidth, 0),
true);
18086 for (
unsigned ElemNum = 0; ElemNum < VectorLen; ++ElemNum) {
18091 switch (
Opcode.getExtValue() & 0x7) {
18096 Result = IsUnsigned ? A.ult(B) : A.slt(B);
18099 Result = IsUnsigned ? A.ule(B) : A.sle(B);
18108 Result = IsUnsigned ? A.uge(B) : A.sge(B);
18111 Result = IsUnsigned ? A.ugt(B) : A.sgt(B);
18118 RetMask.setBitVal(ElemNum, Mask[ElemNum] &&
Result);
18123 case X86::BI__builtin_ia32_vpshufbitqmb128_mask:
18124 case X86::BI__builtin_ia32_vpshufbitqmb256_mask:
18125 case X86::BI__builtin_ia32_vpshufbitqmb512_mask: {
18138 unsigned NumBytesInQWord = 8;
18139 unsigned NumBitsInByte = 8;
18141 unsigned NumQWords = NumBytes / NumBytesInQWord;
18142 unsigned RetWidth = ZeroMask.getBitWidth();
18143 APSInt RetMask(llvm::APInt(RetWidth, 0),
true);
18145 for (
unsigned QWordId = 0; QWordId != NumQWords; ++QWordId) {
18146 APInt SourceQWord(64, 0);
18147 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
18151 SourceQWord.insertBits(
APInt(8, Byte & 0xFF), ByteIdx * NumBitsInByte);
18154 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
18155 unsigned SelIdx = QWordId * NumBytesInQWord + ByteIdx;
18158 if (ZeroMask[SelIdx]) {
18159 RetMask.setBitVal(SelIdx, SourceQWord[M]);
18171 const LValue &LV) {
18174 if (!LV.getLValueBase())
18179 if (!LV.getLValueDesignator().Invalid &&
18180 !LV.getLValueDesignator().isOnePastTheEnd())
18190 if (LV.getLValueDesignator().Invalid)
18196 return LV.getLValueOffset() == Size;
18206class DataRecursiveIntBinOpEvaluator {
18207 struct EvalResult {
18209 bool Failed =
false;
18211 EvalResult() =
default;
18213 void swap(EvalResult &RHS) {
18215 Failed = RHS.Failed;
18216 RHS.Failed =
false;
18222 EvalResult LHSResult;
18223 enum { AnyExprKind, BinOpKind, BinOpVisitedLHSKind }
Kind;
18226 Job(Job &&) =
default;
18228 void startSpeculativeEval(EvalInfo &Info) {
18229 SpecEvalRAII = SpeculativeEvaluationRAII(Info);
18233 SpeculativeEvaluationRAII SpecEvalRAII;
18236 SmallVector<Job, 16> Queue;
18238 IntExprEvaluator &IntEval;
18243 DataRecursiveIntBinOpEvaluator(IntExprEvaluator &IntEval,
APValue &
Result)
18244 : IntEval(IntEval), Info(IntEval.getEvalInfo()), FinalResult(
Result) { }
18250 static bool shouldEnqueue(
const BinaryOperator *E) {
18257 bool Traverse(
const BinaryOperator *E) {
18259 EvalResult PrevResult;
18260 while (!Queue.empty())
18261 process(PrevResult);
18263 if (PrevResult.Failed)
return false;
18265 FinalResult.
swap(PrevResult.Val);
18276 bool Error(
const Expr *E) {
18277 return IntEval.Error(E);
18280 return IntEval.Error(E, D);
18283 OptionalDiagnostic CCEDiag(
const Expr *E,
diag::kind D) {
18284 return Info.CCEDiag(E, D);
18288 bool VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
18289 bool &SuppressRHSDiags);
18291 bool VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
18294 void EvaluateExpr(
const Expr *E, EvalResult &
Result) {
18300 void process(EvalResult &
Result);
18302 void enqueue(
const Expr *E) {
18304 Queue.resize(Queue.size()+1);
18305 Queue.back().E = E;
18306 Queue.back().Kind = Job::AnyExprKind;
18312bool DataRecursiveIntBinOpEvaluator::
18313 VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
18314 bool &SuppressRHSDiags) {
18317 if (LHSResult.Failed)
18318 return Info.noteSideEffect();
18327 if (LHSAsBool == (E->
getOpcode() == BO_LOr)) {
18328 Success(LHSAsBool, E, LHSResult.Val);
18332 LHSResult.Failed =
true;
18336 if (!Info.noteSideEffect())
18342 SuppressRHSDiags =
true;
18351 if (LHSResult.Failed && !Info.noteFailure())
18362 assert(!LVal.
hasLValuePath() &&
"have designator for integer lvalue");
18364 uint64_t Offset64 = Offset.getQuantity();
18365 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
18367 : Offset64 + Index64);
18370bool DataRecursiveIntBinOpEvaluator::
18371 VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
18374 if (RHSResult.Failed)
18381 bool lhsResult, rhsResult;
18396 if (rhsResult == (E->
getOpcode() == BO_LOr))
18407 if (LHSResult.Failed || RHSResult.Failed)
18410 const APValue &LHSVal = LHSResult.Val;
18411 const APValue &RHSVal = RHSResult.Val;
18435 if (!LHSExpr || !RHSExpr)
18437 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
18438 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
18439 if (!LHSAddrExpr || !RHSAddrExpr)
18464void DataRecursiveIntBinOpEvaluator::process(EvalResult &
Result) {
18465 Job &job = Queue.back();
18467 switch (job.Kind) {
18468 case Job::AnyExprKind: {
18469 if (
const BinaryOperator *Bop = dyn_cast<BinaryOperator>(job.E)) {
18470 if (shouldEnqueue(Bop)) {
18471 job.Kind = Job::BinOpKind;
18472 enqueue(Bop->getLHS());
18477 EvaluateExpr(job.E,
Result);
18482 case Job::BinOpKind: {
18484 bool SuppressRHSDiags =
false;
18485 if (!VisitBinOpLHSOnly(
Result, Bop, SuppressRHSDiags)) {
18489 if (SuppressRHSDiags)
18490 job.startSpeculativeEval(Info);
18491 job.LHSResult.swap(
Result);
18492 job.Kind = Job::BinOpVisitedLHSKind;
18497 case Job::BinOpVisitedLHSKind: {
18501 Result.Failed = !VisitBinOp(job.LHSResult, RHS, Bop,
Result.Val);
18507 llvm_unreachable(
"Invalid Job::Kind!");
18511enum class CmpResult {
18520template <
class SuccessCB,
class AfterCB>
18523 SuccessCB &&
Success, AfterCB &&DoAfter) {
18528 "unsupported binary expression evaluation");
18530 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
18544 if (!LHSOK && !Info.noteFailure())
18549 return Success(CmpResult::Less, E);
18551 return Success(CmpResult::Greater, E);
18552 return Success(CmpResult::Equal, E);
18556 APFixedPoint LHSFX(Info.Ctx.getFixedPointSemantics(LHSTy));
18557 APFixedPoint RHSFX(Info.Ctx.getFixedPointSemantics(RHSTy));
18560 if (!LHSOK && !Info.noteFailure())
18565 return Success(CmpResult::Less, E);
18567 return Success(CmpResult::Greater, E);
18568 return Success(CmpResult::Equal, E);
18572 ComplexValue LHS, RHS;
18581 LHS.makeComplexFloat();
18582 LHS.FloatImag = APFloat(LHS.FloatReal.getSemantics());
18587 if (!LHSOK && !Info.noteFailure())
18593 RHS.makeComplexFloat();
18594 RHS.FloatImag = APFloat(RHS.FloatReal.getSemantics());
18598 if (LHS.isComplexFloat()) {
18599 APFloat::cmpResult CR_r =
18600 LHS.getComplexFloatReal().compare(RHS.getComplexFloatReal());
18601 APFloat::cmpResult CR_i =
18602 LHS.getComplexFloatImag().compare(RHS.getComplexFloatImag());
18603 bool IsEqual = CR_r == APFloat::cmpEqual && CR_i == APFloat::cmpEqual;
18604 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal, E);
18606 assert(IsEquality &&
"invalid complex comparison");
18607 bool IsEqual = LHS.getComplexIntReal() == RHS.getComplexIntReal() &&
18608 LHS.getComplexIntImag() == RHS.getComplexIntImag();
18609 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal, E);
18615 APFloat RHS(0.0), LHS(0.0);
18618 if (!LHSOK && !Info.noteFailure())
18625 llvm::APFloatBase::cmpResult APFloatCmpResult = LHS.compare(RHS);
18626 if (!Info.InConstantContext &&
18627 APFloatCmpResult == APFloat::cmpUnordered &&
18630 Info.FFDiag(E, diag::note_constexpr_float_arithmetic_strict);
18633 auto GetCmpRes = [&]() {
18634 switch (APFloatCmpResult) {
18635 case APFloat::cmpEqual:
18636 return CmpResult::Equal;
18637 case APFloat::cmpLessThan:
18638 return CmpResult::Less;
18639 case APFloat::cmpGreaterThan:
18640 return CmpResult::Greater;
18641 case APFloat::cmpUnordered:
18642 return CmpResult::Unordered;
18644 llvm_unreachable(
"Unrecognised APFloat::cmpResult enum");
18646 return Success(GetCmpRes(), E);
18650 LValue LHSValue, RHSValue;
18653 if (!LHSOK && !Info.noteFailure())
18664 if (Info.checkingPotentialConstantExpression() &&
18665 (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown))
18667 auto DiagComparison = [&] (
unsigned DiagID,
bool Reversed =
false) {
18668 std::string LHS = LHSValue.toString(Info.Ctx, E->
getLHS()->
getType());
18669 std::string RHS = RHSValue.toString(Info.Ctx, E->
getRHS()->
getType());
18670 Info.FFDiag(E, DiagID)
18677 return DiagComparison(
18678 diag::note_constexpr_pointer_comparison_unspecified);
18684 if ((!LHSValue.Base && !LHSValue.Offset.
isZero()) ||
18685 (!RHSValue.Base && !RHSValue.Offset.
isZero()))
18686 return DiagComparison(diag::note_constexpr_pointer_constant_comparison,
18700 return DiagComparison(diag::note_constexpr_literal_comparison);
18702 return DiagComparison(diag::note_constexpr_opaque_call_comparison,
18707 return DiagComparison(diag::note_constexpr_pointer_weak_comparison,
18711 if (LHSValue.Base && LHSValue.Offset.
isZero() &&
18713 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
18715 if (RHSValue.Base && RHSValue.Offset.
isZero() &&
18717 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
18723 return DiagComparison(
18724 diag::note_constexpr_pointer_comparison_zero_sized);
18725 if (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown)
18726 return DiagComparison(
18727 diag::note_constexpr_pointer_comparison_unspecified);
18729 return Success(CmpResult::Unequal, E);
18732 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
18733 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
18735 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
18736 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
18746 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid && IsRelational) {
18747 bool WasArrayIndex;
18750 :
getType(LHSValue.Base).getNonReferenceType(),
18751 LHSDesignator, RHSDesignator, WasArrayIndex);
18758 if (!WasArrayIndex && Mismatch < LHSDesignator.Entries.size() &&
18759 Mismatch < RHSDesignator.Entries.size()) {
18760 const FieldDecl *LF = getAsField(LHSDesignator.Entries[Mismatch]);
18761 const FieldDecl *RF = getAsField(RHSDesignator.Entries[Mismatch]);
18763 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_classes);
18765 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
18766 << getAsBaseClass(LHSDesignator.Entries[Mismatch])
18769 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
18770 << getAsBaseClass(RHSDesignator.Entries[Mismatch])
18775 diag::note_constexpr_pointer_comparison_differing_access)
18783 unsigned PtrSize = Info.Ctx.getTypeSize(LHSTy);
18786 assert(PtrSize <= 64 &&
"Unexpected pointer width");
18787 uint64_t Mask = ~0ULL >> (64 - PtrSize);
18788 CompareLHS &= Mask;
18789 CompareRHS &= Mask;
18794 if (!LHSValue.Base.
isNull() && IsRelational) {
18798 CharUnits Size = Info.Ctx.getTypeSizeInChars(BaseTy);
18799 uint64_t OffsetLimit = Size.getQuantity();
18800 if (CompareLHS > OffsetLimit || CompareRHS > OffsetLimit)
18804 if (CompareLHS < CompareRHS)
18805 return Success(CmpResult::Less, E);
18806 if (CompareLHS > CompareRHS)
18807 return Success(CmpResult::Greater, E);
18808 return Success(CmpResult::Equal, E);
18812 assert(IsEquality &&
"unexpected member pointer operation");
18815 MemberPtr LHSValue, RHSValue;
18818 if (!LHSOK && !Info.noteFailure())
18826 if (LHSValue.getDecl() && LHSValue.getDecl()->isWeak()) {
18827 Info.FFDiag(E, diag::note_constexpr_mem_pointer_weak_comparison)
18828 << LHSValue.getDecl();
18831 if (RHSValue.getDecl() && RHSValue.getDecl()->isWeak()) {
18832 Info.FFDiag(E, diag::note_constexpr_mem_pointer_weak_comparison)
18833 << RHSValue.getDecl();
18840 if (!LHSValue.getDecl() || !RHSValue.getDecl()) {
18841 bool Equal = !LHSValue.getDecl() && !RHSValue.getDecl();
18842 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal, E);
18847 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(LHSValue.getDecl()))
18848 if (MD->isVirtual())
18849 Info.CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
18850 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(RHSValue.getDecl()))
18851 if (MD->isVirtual())
18852 Info.CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
18858 bool Equal = LHSValue == RHSValue;
18859 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal, E);
18864 assert(RHSTy->
isNullPtrType() &&
"missing pointer conversion");
18872 return Success(CmpResult::Equal, E);
18878bool RecordExprEvaluator::VisitBinCmp(
const BinaryOperator *E) {
18882 auto OnSuccess = [&](CmpResult CR,
const BinaryOperator *E) {
18885 case CmpResult::Unequal:
18886 llvm_unreachable(
"should never produce Unequal for three-way comparison");
18887 case CmpResult::Less:
18888 CCR = ComparisonCategoryResult::Less;
18890 case CmpResult::Equal:
18891 CCR = ComparisonCategoryResult::Equal;
18893 case CmpResult::Greater:
18894 CCR = ComparisonCategoryResult::Greater;
18896 case CmpResult::Unordered:
18897 CCR = ComparisonCategoryResult::Unordered;
18902 const ComparisonCategoryInfo &CmpInfo =
18903 Info.Ctx.CompCategories.getInfoForType(E->
getType());
18911 ConstantExprKind::Normal);
18914 return ExprEvaluatorBaseTy::VisitBinCmp(E);
18918bool RecordExprEvaluator::VisitCXXParenListInitExpr(
18919 const CXXParenListInitExpr *E) {
18920 return VisitCXXParenListOrInitListExpr(E, E->
getInitExprs());
18923bool IntExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
18928 if (!Info.noteFailure())
18932 if (DataRecursiveIntBinOpEvaluator::shouldEnqueue(E))
18933 return DataRecursiveIntBinOpEvaluator(*
this,
Result).Traverse(E);
18937 "DataRecursiveIntBinOpEvaluator should have handled integral types");
18942 auto OnSuccess = [&](CmpResult CR,
const BinaryOperator *E) {
18943 assert((CR != CmpResult::Unequal || E->
isEqualityOp()) &&
18944 "should only produce Unequal for equality comparisons");
18945 bool IsEqual = CR == CmpResult::Equal,
18946 IsLess = CR == CmpResult::Less,
18947 IsGreater = CR == CmpResult::Greater;
18951 llvm_unreachable(
"unsupported binary operator");
18954 return Success(IsEqual == (Op == BO_EQ), E);
18958 return Success(IsGreater, E);
18960 return Success(IsEqual || IsLess, E);
18962 return Success(IsEqual || IsGreater, E);
18966 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
18975 LValue LHSValue, RHSValue;
18978 if (!LHSOK && !Info.noteFailure())
18987 if (Info.checkingPotentialConstantExpression() &&
18988 (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown))
18991 const Expr *LHSExpr = LHSValue.Base.
dyn_cast<
const Expr *>();
18992 const Expr *RHSExpr = RHSValue.Base.
dyn_cast<
const Expr *>();
18994 auto DiagArith = [&](
unsigned DiagID) {
18995 std::string LHS = LHSValue.toString(Info.Ctx, E->
getLHS()->
getType());
18996 std::string RHS = RHSValue.toString(Info.Ctx, E->
getRHS()->
getType());
18997 Info.FFDiag(E, DiagID) << LHS << RHS;
18998 if (LHSExpr && LHSExpr == RHSExpr)
19000 diag::note_constexpr_repeated_literal_eval)
19005 if (!LHSExpr || !RHSExpr)
19006 return DiagArith(diag::note_constexpr_pointer_arith_unspecified);
19009 return DiagArith(diag::note_constexpr_literal_arith);
19011 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
19012 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
19013 if (!LHSAddrExpr || !RHSAddrExpr)
19021 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
19022 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
19024 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
19025 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
19031 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid &&
19034 Info.CCEDiag(E, diag::note_constexpr_pointer_subtraction_not_same_array);
19039 CharUnits ElementSize;
19046 if (ElementSize.
isZero()) {
19047 Info.FFDiag(E, diag::note_constexpr_pointer_subtraction_zero_size)
19064 APSInt TrueResult = (LHS - RHS) / ElemSize;
19067 if (
Result.extend(65) != TrueResult &&
19073 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
19078bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr(
19079 const UnaryExprOrTypeTraitExpr *E) {
19081 case UETT_PreferredAlignOf:
19082 case UETT_AlignOf: {
19091 case UETT_PtrAuthTypeDiscriminator: {
19097 case UETT_VecStep: {
19101 unsigned n = Ty->
castAs<VectorType>()->getNumElements();
19113 case UETT_DataSizeOf:
19114 case UETT_SizeOf: {
19118 if (
const ReferenceType *Ref = SrcTy->
getAs<ReferenceType>())
19129 case UETT_OpenMPRequiredSimdAlign:
19132 Info.Ctx.toCharUnitsFromBits(
19136 case UETT_VectorElements: {
19140 if (
const auto *VT = Ty->
getAs<VectorType>())
19144 if (Info.InConstantContext)
19145 Info.CCEDiag(E, diag::note_constexpr_non_const_vectorelements)
19150 case UETT_CountOf: {
19156 if (
const auto *CAT =
19166 const auto *VAT = Info.Ctx.getAsVariableArrayType(Ty);
19168 if (VAT->getElementType()->isArrayType()) {
19171 if (!VAT->getSizeExpr()) {
19176 std::optional<APSInt> Res =
19177 VAT->getSizeExpr()->getIntegerConstantExpr(Info.Ctx);
19182 static_cast<unsigned>(Info.Ctx.getTypeSize(Info.Ctx.getSizeType())),
19183 Res->getZExtValue()};
19195 llvm_unreachable(
"unknown expr/type trait");
19198bool IntExprEvaluator::VisitOffsetOfExpr(
const OffsetOfExpr *OOE) {
19199 Info.Ctx.recordOffsetOfEvaluation(OOE);
19205 for (
unsigned i = 0; i != n; ++i) {
19213 const ArrayType *AT = Info.Ctx.getAsArrayType(CurrentType);
19217 CharUnits ElementSize = Info.Ctx.getTypeSizeInChars(CurrentType);
19218 Result += IdxResult.getSExtValue() * ElementSize;
19223 FieldDecl *MemberDecl = ON.
getField();
19228 const ASTRecordLayout &RL = Info.Ctx.getASTRecordLayout(RD);
19230 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
19237 llvm_unreachable(
"dependent __builtin_offsetof");
19240 CXXBaseSpecifier *BaseSpec = ON.
getBase();
19249 const ASTRecordLayout &RL = Info.Ctx.getASTRecordLayout(RD);
19252 CurrentType = BaseSpec->
getType();
19266bool IntExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
19286 if (Info.checkingForUndefinedBehavior())
19287 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
19288 diag::warn_integer_constant_overflow)
19316bool IntExprEvaluator::VisitCastExpr(
const CastExpr *E) {
19318 QualType DestType = E->
getType();
19319 QualType SrcType = SubExpr->
getType();
19322 case CK_BaseToDerived:
19323 case CK_DerivedToBase:
19324 case CK_UncheckedDerivedToBase:
19327 case CK_ArrayToPointerDecay:
19328 case CK_FunctionToPointerDecay:
19329 case CK_NullToPointer:
19330 case CK_NullToMemberPointer:
19331 case CK_BaseToDerivedMemberPointer:
19332 case CK_DerivedToBaseMemberPointer:
19333 case CK_ReinterpretMemberPointer:
19334 case CK_ConstructorConversion:
19335 case CK_IntegralToPointer:
19337 case CK_VectorSplat:
19338 case CK_IntegralToFloating:
19339 case CK_FloatingCast:
19340 case CK_CPointerToObjCPointerCast:
19341 case CK_BlockPointerToObjCPointerCast:
19342 case CK_AnyPointerToBlockPointerCast:
19343 case CK_ObjCObjectLValueCast:
19344 case CK_FloatingRealToComplex:
19345 case CK_FloatingComplexToReal:
19346 case CK_FloatingComplexCast:
19347 case CK_FloatingComplexToIntegralComplex:
19348 case CK_IntegralRealToComplex:
19349 case CK_IntegralComplexCast:
19350 case CK_IntegralComplexToFloatingComplex:
19351 case CK_BuiltinFnToFnPtr:
19352 case CK_ZeroToOCLOpaqueType:
19353 case CK_NonAtomicToAtomic:
19354 case CK_AddressSpaceConversion:
19355 case CK_IntToOCLSampler:
19356 case CK_FloatingToFixedPoint:
19357 case CK_FixedPointToFloating:
19358 case CK_FixedPointCast:
19359 case CK_IntegralToFixedPoint:
19360 case CK_MatrixCast:
19361 case CK_HLSLAggregateSplatCast:
19362 llvm_unreachable(
"invalid cast kind for integral value");
19366 case CK_LValueBitCast:
19367 case CK_ARCProduceObject:
19368 case CK_ARCConsumeObject:
19369 case CK_ARCReclaimReturnedObject:
19370 case CK_ARCExtendBlockObject:
19371 case CK_CopyAndAutoreleaseBlockObject:
19374 case CK_UserDefinedConversion:
19375 case CK_LValueToRValue:
19376 case CK_AtomicToNonAtomic:
19378 case CK_LValueToRValueBitCast:
19379 case CK_HLSLArrayRValue:
19380 return ExprEvaluatorBaseTy::VisitCastExpr(E);
19382 case CK_MemberPointerToBoolean:
19383 case CK_PointerToBoolean:
19384 case CK_IntegralToBoolean:
19385 case CK_FloatingToBoolean:
19386 case CK_BooleanToSignedIntegral:
19387 case CK_FloatingComplexToBoolean:
19388 case CK_IntegralComplexToBoolean: {
19393 if (BoolResult && E->
getCastKind() == CK_BooleanToSignedIntegral)
19395 return Success(IntResult, E);
19398 case CK_FixedPointToIntegral: {
19399 APFixedPoint Src(Info.Ctx.getFixedPointSemantics(SrcType));
19403 llvm::APSInt
Result = Src.convertToInt(
19404 Info.Ctx.getIntWidth(DestType),
19411 case CK_FixedPointToBoolean: {
19414 if (!
Evaluate(Val, Info, SubExpr))
19419 case CK_IntegralCast: {
19420 if (!Visit(SubExpr))
19430 if (
Result.isAddrLabelDiff()) {
19431 unsigned DestBits = Info.Ctx.getTypeSize(DestType);
19432 return DestBits >= 32 && DestBits <= Info.Ctx.getTypeSize(SrcType);
19435 return Info.Ctx.getTypeSize(DestType) == Info.Ctx.getTypeSize(SrcType);
19438 if (Info.Ctx.getLangOpts().CPlusPlus && DestType->
isEnumeralType()) {
19450 if (!ED->isFixed()) {
19454 ED->getValueRange(
Max,
Min);
19457 if (ED->getNumNegativeBits() &&
19458 (
Max.slt(
Result.getInt().getSExtValue()) ||
19459 Min.sgt(
Result.getInt().getSExtValue())))
19460 Info.CCEDiag(E, diag::note_constexpr_unscoped_enum_out_of_range)
19461 << llvm::toString(
Result.getInt(), 10) <<
Min.getSExtValue()
19462 <<
Max.getSExtValue() << ED;
19463 else if (!ED->getNumNegativeBits() &&
19464 Max.ult(
Result.getInt().getZExtValue()))
19465 Info.CCEDiag(E, diag::note_constexpr_unscoped_enum_out_of_range)
19466 << llvm::toString(
Result.getInt(), 10) <<
Min.getZExtValue()
19467 <<
Max.getZExtValue() << ED;
19475 case CK_PointerToIntegral: {
19476 CCEDiag(E, diag::note_constexpr_invalid_cast)
19477 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
19484 if (LV.getLValueBase()) {
19489 if (Info.Ctx.getTypeSize(DestType) != Info.Ctx.getTypeSize(SrcType))
19492 LV.Designator.setInvalid();
19500 if (!
V.toIntegralConstant(AsInt, SrcType, Info.Ctx))
19501 llvm_unreachable(
"Can't cast this!");
19506 case CK_IntegralComplexToReal: {
19510 return Success(
C.getComplexIntReal(), E);
19513 case CK_FloatingToIntegral: {
19523 case CK_HLSLVectorTruncation: {
19529 case CK_HLSLMatrixTruncation: {
19535 case CK_HLSLElementwiseCast: {
19548 return Success(ResultVal, E);
19552 llvm_unreachable(
"unknown cast resulting in integral value");
19555bool IntExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
19560 if (!LV.isComplexInt())
19562 return Success(LV.getComplexIntReal(), E);
19568bool IntExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
19573 if (!LV.isComplexInt())
19575 return Success(LV.getComplexIntImag(), E);
19582bool IntExprEvaluator::VisitSizeOfPackExpr(
const SizeOfPackExpr *E) {
19586bool IntExprEvaluator::VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E) {
19590bool IntExprEvaluator::VisitConceptSpecializationExpr(
19591 const ConceptSpecializationExpr *E) {
19595bool IntExprEvaluator::VisitRequiresExpr(
const RequiresExpr *E) {
19599bool FixedPointExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
19609 if (!
Result.isFixedPoint())
19612 APFixedPoint Negated =
Result.getFixedPoint().negate(&Overflowed);
19626bool FixedPointExprEvaluator::VisitCastExpr(
const CastExpr *E) {
19628 QualType DestType = E->
getType();
19630 "Expected destination type to be a fixed point type");
19631 auto DestFXSema = Info.Ctx.getFixedPointSemantics(DestType);
19634 case CK_FixedPointCast: {
19635 APFixedPoint Src(Info.Ctx.getFixedPointSemantics(SubExpr->
getType()));
19639 APFixedPoint
Result = Src.convert(DestFXSema, &Overflowed);
19641 if (Info.checkingForUndefinedBehavior())
19642 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
19643 diag::warn_fixedpoint_constant_overflow)
19650 case CK_IntegralToFixedPoint: {
19656 APFixedPoint IntResult = APFixedPoint::getFromIntValue(
19657 Src, Info.Ctx.getFixedPointSemantics(DestType), &Overflowed);
19660 if (Info.checkingForUndefinedBehavior())
19661 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
19662 diag::warn_fixedpoint_constant_overflow)
19663 << IntResult.toString() << E->
getType();
19668 return Success(IntResult, E);
19670 case CK_FloatingToFixedPoint: {
19676 APFixedPoint
Result = APFixedPoint::getFromFloatValue(
19677 Src, Info.Ctx.getFixedPointSemantics(DestType), &Overflowed);
19680 if (Info.checkingForUndefinedBehavior())
19681 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
19682 diag::warn_fixedpoint_constant_overflow)
19691 case CK_LValueToRValue:
19692 return ExprEvaluatorBaseTy::VisitCastExpr(E);
19698bool FixedPointExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
19700 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
19702 const Expr *LHS = E->
getLHS();
19703 const Expr *RHS = E->
getRHS();
19705 Info.Ctx.getFixedPointSemantics(E->
getType());
19707 APFixedPoint LHSFX(Info.Ctx.getFixedPointSemantics(LHS->
getType()));
19710 APFixedPoint RHSFX(Info.Ctx.getFixedPointSemantics(RHS->
getType()));
19714 bool OpOverflow =
false, ConversionOverflow =
false;
19715 APFixedPoint
Result(LHSFX.getSemantics());
19718 Result = LHSFX.add(RHSFX, &OpOverflow)
19719 .convert(ResultFXSema, &ConversionOverflow);
19723 Result = LHSFX.sub(RHSFX, &OpOverflow)
19724 .convert(ResultFXSema, &ConversionOverflow);
19728 Result = LHSFX.mul(RHSFX, &OpOverflow)
19729 .convert(ResultFXSema, &ConversionOverflow);
19733 if (RHSFX.getValue() == 0) {
19734 Info.FFDiag(E, diag::note_expr_divide_by_zero);
19737 Result = LHSFX.div(RHSFX, &OpOverflow)
19738 .convert(ResultFXSema, &ConversionOverflow);
19744 llvm::APSInt RHSVal = RHSFX.getValue();
19747 LHSSema.getWidth() - (unsigned)LHSSema.hasUnsignedPadding();
19748 unsigned Amt = RHSVal.getLimitedValue(ShiftBW - 1);
19752 if (RHSVal.isNegative())
19753 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHSVal;
19754 else if (Amt != RHSVal)
19755 Info.CCEDiag(E, diag::note_constexpr_large_shift)
19756 << RHSVal << E->
getType() << ShiftBW;
19759 Result = LHSFX.shl(Amt, &OpOverflow);
19761 Result = LHSFX.shr(Amt, &OpOverflow);
19767 if (OpOverflow || ConversionOverflow) {
19768 if (Info.checkingForUndefinedBehavior())
19769 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
19770 diag::warn_fixedpoint_constant_overflow)
19783class FloatExprEvaluator
19784 :
public ExprEvaluatorBase<FloatExprEvaluator> {
19787 FloatExprEvaluator(EvalInfo &info, APFloat &result)
19788 : ExprEvaluatorBaseTy(info),
Result(result) {}
19795 bool ZeroInitialization(
const Expr *E) {
19796 Result = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(E->
getType()));
19800 bool VisitCallExpr(
const CallExpr *E);
19802 bool VisitUnaryOperator(
const UnaryOperator *E);
19803 bool VisitBinaryOperator(
const BinaryOperator *E);
19804 bool VisitFloatingLiteral(
const FloatingLiteral *E);
19805 bool VisitCastExpr(
const CastExpr *E);
19807 bool VisitUnaryReal(
const UnaryOperator *E);
19808 bool VisitUnaryImag(
const UnaryOperator *E);
19817 return FloatExprEvaluator(Info,
Result).Visit(E);
19824 llvm::APFloat &
Result) {
19826 if (!S)
return false;
19828 const llvm::fltSemantics &Sem = Context.getFloatTypeSemantics(ResultTy);
19834 fill = llvm::APInt(32, 0);
19835 else if (S->
getString().getAsInteger(0, fill))
19838 if (Context.getTargetInfo().isNan2008()) {
19840 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
19842 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
19850 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
19852 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
19858bool FloatExprEvaluator::VisitCallExpr(
const CallExpr *E) {
19859 if (!IsConstantEvaluatedBuiltinCall(E))
19860 return ExprEvaluatorBaseTy::VisitCallExpr(E);
19866 case Builtin::BI__builtin_huge_val:
19867 case Builtin::BI__builtin_huge_valf:
19868 case Builtin::BI__builtin_huge_vall:
19869 case Builtin::BI__builtin_huge_valf16:
19870 case Builtin::BI__builtin_huge_valf128:
19871 case Builtin::BI__builtin_inf:
19872 case Builtin::BI__builtin_inff:
19873 case Builtin::BI__builtin_infl:
19874 case Builtin::BI__builtin_inff16:
19875 case Builtin::BI__builtin_inff128: {
19876 const llvm::fltSemantics &Sem =
19877 Info.Ctx.getFloatTypeSemantics(E->
getType());
19878 Result = llvm::APFloat::getInf(Sem);
19882 case Builtin::BI__builtin_nans:
19883 case Builtin::BI__builtin_nansf:
19884 case Builtin::BI__builtin_nansl:
19885 case Builtin::BI__builtin_nansf16:
19886 case Builtin::BI__builtin_nansf128:
19892 case Builtin::BI__builtin_nan:
19893 case Builtin::BI__builtin_nanf:
19894 case Builtin::BI__builtin_nanl:
19895 case Builtin::BI__builtin_nanf16:
19896 case Builtin::BI__builtin_nanf128:
19904 case Builtin::BI__builtin_elementwise_abs:
19905 case Builtin::BI__builtin_fabs:
19906 case Builtin::BI__builtin_fabsf:
19907 case Builtin::BI__builtin_fabsl:
19908 case Builtin::BI__builtin_fabsf128:
19917 if (
Result.isNegative())
19921 case Builtin::BI__arithmetic_fence:
19928 case Builtin::BI__builtin_copysign:
19929 case Builtin::BI__builtin_copysignf:
19930 case Builtin::BI__builtin_copysignl:
19931 case Builtin::BI__builtin_copysignf128: {
19940 case Builtin::BI__builtin_fmax:
19941 case Builtin::BI__builtin_fmaxf:
19942 case Builtin::BI__builtin_fmaxl:
19943 case Builtin::BI__builtin_fmaxf16:
19944 case Builtin::BI__builtin_fmaxf128: {
19953 case Builtin::BI__builtin_fmin:
19954 case Builtin::BI__builtin_fminf:
19955 case Builtin::BI__builtin_fminl:
19956 case Builtin::BI__builtin_fminf16:
19957 case Builtin::BI__builtin_fminf128: {
19966 case Builtin::BI__builtin_fmaximum_num:
19967 case Builtin::BI__builtin_fmaximum_numf:
19968 case Builtin::BI__builtin_fmaximum_numl:
19969 case Builtin::BI__builtin_fmaximum_numf16:
19970 case Builtin::BI__builtin_fmaximum_numf128: {
19979 case Builtin::BI__builtin_fminimum_num:
19980 case Builtin::BI__builtin_fminimum_numf:
19981 case Builtin::BI__builtin_fminimum_numl:
19982 case Builtin::BI__builtin_fminimum_numf16:
19983 case Builtin::BI__builtin_fminimum_numf128: {
19992 case Builtin::BI__builtin_elementwise_fma: {
19997 APFloat SourceY(0.), SourceZ(0.);
20003 (void)
Result.fusedMultiplyAdd(SourceY, SourceZ, RM);
20007 case clang::X86::BI__builtin_ia32_vec_ext_v4sf: {
20014 unsigned Idx =
static_cast<unsigned>(IdxAPS.getZExtValue() & (N - 1));
20020bool FloatExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
20032bool FloatExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
20042 const llvm::fltSemantics &Sem = Info.Ctx.getFloatTypeSemantics(E->
getType());
20043 Result = llvm::APFloat::getZero(Sem);
20047bool FloatExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
20049 default:
return Error(E);
20063bool FloatExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
20065 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
20069 if (!LHSOK && !Info.noteFailure())
20075bool FloatExprEvaluator::VisitFloatingLiteral(
const FloatingLiteral *E) {
20080bool FloatExprEvaluator::VisitCastExpr(
const CastExpr *E) {
20085 return ExprEvaluatorBaseTy::VisitCastExpr(E);
20087 case CK_HLSLAggregateSplatCast:
20088 llvm_unreachable(
"invalid cast kind for floating value");
20090 case CK_IntegralToFloating: {
20093 Info.Ctx.getLangOpts());
20099 case CK_FixedPointToFloating: {
20100 APFixedPoint FixResult(Info.Ctx.getFixedPointSemantics(SubExpr->
getType()));
20104 FixResult.convertToFloat(Info.Ctx.getFloatTypeSemantics(E->
getType()));
20108 case CK_FloatingCast: {
20109 if (!Visit(SubExpr))
20115 case CK_FloatingComplexToReal: {
20119 Result =
V.getComplexFloatReal();
20122 case CK_HLSLVectorTruncation: {
20128 case CK_HLSLMatrixTruncation: {
20134 case CK_HLSLElementwiseCast: {
20149 return Success(ResultVal, E);
20159class ComplexExprEvaluator
20160 :
public ExprEvaluatorBase<ComplexExprEvaluator> {
20164 ComplexExprEvaluator(EvalInfo &info, ComplexValue &
Result)
20172 bool ZeroInitialization(
const Expr *E);
20178 bool VisitImaginaryLiteral(
const ImaginaryLiteral *E);
20179 bool VisitCastExpr(
const CastExpr *E);
20180 bool VisitBinaryOperator(
const BinaryOperator *E);
20181 bool VisitUnaryOperator(
const UnaryOperator *E);
20182 bool VisitInitListExpr(
const InitListExpr *E);
20183 bool VisitCallExpr(
const CallExpr *E);
20191 return ComplexExprEvaluator(Info,
Result).Visit(E);
20194bool ComplexExprEvaluator::ZeroInitialization(
const Expr *E) {
20195 QualType ElemTy = E->
getType()->
castAs<ComplexType>()->getElementType();
20197 Result.makeComplexFloat();
20198 APFloat Zero = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(ElemTy));
20202 Result.makeComplexInt();
20203 APSInt Zero = Info.Ctx.MakeIntValue(0, ElemTy);
20210bool ComplexExprEvaluator::VisitImaginaryLiteral(
const ImaginaryLiteral *E) {
20214 Result.makeComplexFloat();
20223 "Unexpected imaginary literal.");
20225 Result.makeComplexInt();
20230 Result.IntReal =
APSInt(Imag.getBitWidth(), !Imag.isSigned());
20235bool ComplexExprEvaluator::VisitCastExpr(
const CastExpr *E) {
20239 case CK_BaseToDerived:
20240 case CK_DerivedToBase:
20241 case CK_UncheckedDerivedToBase:
20244 case CK_ArrayToPointerDecay:
20245 case CK_FunctionToPointerDecay:
20246 case CK_NullToPointer:
20247 case CK_NullToMemberPointer:
20248 case CK_BaseToDerivedMemberPointer:
20249 case CK_DerivedToBaseMemberPointer:
20250 case CK_MemberPointerToBoolean:
20251 case CK_ReinterpretMemberPointer:
20252 case CK_ConstructorConversion:
20253 case CK_IntegralToPointer:
20254 case CK_PointerToIntegral:
20255 case CK_PointerToBoolean:
20257 case CK_VectorSplat:
20258 case CK_IntegralCast:
20259 case CK_BooleanToSignedIntegral:
20260 case CK_IntegralToBoolean:
20261 case CK_IntegralToFloating:
20262 case CK_FloatingToIntegral:
20263 case CK_FloatingToBoolean:
20264 case CK_FloatingCast:
20265 case CK_CPointerToObjCPointerCast:
20266 case CK_BlockPointerToObjCPointerCast:
20267 case CK_AnyPointerToBlockPointerCast:
20268 case CK_ObjCObjectLValueCast:
20269 case CK_FloatingComplexToReal:
20270 case CK_FloatingComplexToBoolean:
20271 case CK_IntegralComplexToReal:
20272 case CK_IntegralComplexToBoolean:
20273 case CK_ARCProduceObject:
20274 case CK_ARCConsumeObject:
20275 case CK_ARCReclaimReturnedObject:
20276 case CK_ARCExtendBlockObject:
20277 case CK_CopyAndAutoreleaseBlockObject:
20278 case CK_BuiltinFnToFnPtr:
20279 case CK_ZeroToOCLOpaqueType:
20280 case CK_NonAtomicToAtomic:
20281 case CK_AddressSpaceConversion:
20282 case CK_IntToOCLSampler:
20283 case CK_FloatingToFixedPoint:
20284 case CK_FixedPointToFloating:
20285 case CK_FixedPointCast:
20286 case CK_FixedPointToBoolean:
20287 case CK_FixedPointToIntegral:
20288 case CK_IntegralToFixedPoint:
20289 case CK_MatrixCast:
20290 case CK_HLSLVectorTruncation:
20291 case CK_HLSLMatrixTruncation:
20292 case CK_HLSLElementwiseCast:
20293 case CK_HLSLAggregateSplatCast:
20294 llvm_unreachable(
"invalid cast kind for complex value");
20296 case CK_LValueToRValue:
20297 case CK_AtomicToNonAtomic:
20299 case CK_LValueToRValueBitCast:
20300 case CK_HLSLArrayRValue:
20301 return ExprEvaluatorBaseTy::VisitCastExpr(E);
20304 case CK_LValueBitCast:
20305 case CK_UserDefinedConversion:
20308 case CK_FloatingRealToComplex: {
20313 Result.makeComplexFloat();
20318 case CK_FloatingComplexCast: {
20322 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
20330 case CK_FloatingComplexToIntegralComplex: {
20334 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
20337 Result.makeComplexInt();
20344 case CK_IntegralRealToComplex: {
20349 Result.makeComplexInt();
20350 Result.IntImag =
APSInt(Real.getBitWidth(), !Real.isSigned());
20354 case CK_IntegralComplexCast: {
20358 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
20367 case CK_IntegralComplexToFloatingComplex: {
20372 Info.Ctx.getLangOpts());
20373 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
20376 Result.makeComplexFloat();
20378 To,
Result.FloatReal) &&
20384 llvm_unreachable(
"unknown cast resulting in complex value");
20389 const uint8_t GFInv[256] = {
20390 0x00, 0x01, 0x8d, 0xf6, 0xcb, 0x52, 0x7b, 0xd1, 0xe8, 0x4f, 0x29, 0xc0,
20391 0xb0, 0xe1, 0xe5, 0xc7, 0x74, 0xb4, 0xaa, 0x4b, 0x99, 0x2b, 0x60, 0x5f,
20392 0x58, 0x3f, 0xfd, 0xcc, 0xff, 0x40, 0xee, 0xb2, 0x3a, 0x6e, 0x5a, 0xf1,
20393 0x55, 0x4d, 0xa8, 0xc9, 0xc1, 0x0a, 0x98, 0x15, 0x30, 0x44, 0xa2, 0xc2,
20394 0x2c, 0x45, 0x92, 0x6c, 0xf3, 0x39, 0x66, 0x42, 0xf2, 0x35, 0x20, 0x6f,
20395 0x77, 0xbb, 0x59, 0x19, 0x1d, 0xfe, 0x37, 0x67, 0x2d, 0x31, 0xf5, 0x69,
20396 0xa7, 0x64, 0xab, 0x13, 0x54, 0x25, 0xe9, 0x09, 0xed, 0x5c, 0x05, 0xca,
20397 0x4c, 0x24, 0x87, 0xbf, 0x18, 0x3e, 0x22, 0xf0, 0x51, 0xec, 0x61, 0x17,
20398 0x16, 0x5e, 0xaf, 0xd3, 0x49, 0xa6, 0x36, 0x43, 0xf4, 0x47, 0x91, 0xdf,
20399 0x33, 0x93, 0x21, 0x3b, 0x79, 0xb7, 0x97, 0x85, 0x10, 0xb5, 0xba, 0x3c,
20400 0xb6, 0x70, 0xd0, 0x06, 0xa1, 0xfa, 0x81, 0x82, 0x83, 0x7e, 0x7f, 0x80,
20401 0x96, 0x73, 0xbe, 0x56, 0x9b, 0x9e, 0x95, 0xd9, 0xf7, 0x02, 0xb9, 0xa4,
20402 0xde, 0x6a, 0x32, 0x6d, 0xd8, 0x8a, 0x84, 0x72, 0x2a, 0x14, 0x9f, 0x88,
20403 0xf9, 0xdc, 0x89, 0x9a, 0xfb, 0x7c, 0x2e, 0xc3, 0x8f, 0xb8, 0x65, 0x48,
20404 0x26, 0xc8, 0x12, 0x4a, 0xce, 0xe7, 0xd2, 0x62, 0x0c, 0xe0, 0x1f, 0xef,
20405 0x11, 0x75, 0x78, 0x71, 0xa5, 0x8e, 0x76, 0x3d, 0xbd, 0xbc, 0x86, 0x57,
20406 0x0b, 0x28, 0x2f, 0xa3, 0xda, 0xd4, 0xe4, 0x0f, 0xa9, 0x27, 0x53, 0x04,
20407 0x1b, 0xfc, 0xac, 0xe6, 0x7a, 0x07, 0xae, 0x63, 0xc5, 0xdb, 0xe2, 0xea,
20408 0x94, 0x8b, 0xc4, 0xd5, 0x9d, 0xf8, 0x90, 0x6b, 0xb1, 0x0d, 0xd6, 0xeb,
20409 0xc6, 0x0e, 0xcf, 0xad, 0x08, 0x4e, 0xd7, 0xe3, 0x5d, 0x50, 0x1e, 0xb3,
20410 0x5b, 0x23, 0x38, 0x34, 0x68, 0x46, 0x03, 0x8c, 0xdd, 0x9c, 0x7d, 0xa0,
20411 0xcd, 0x1a, 0x41, 0x1c};
20413 return GFInv[Byte];
20418 unsigned NumBitsInByte = 8;
20420 uint8_t RetByte = 0;
20421 for (uint32_t BitIdx = 0; BitIdx != NumBitsInByte; ++BitIdx) {
20423 AQword.lshr((7 -
static_cast<int32_t
>(BitIdx)) * NumBitsInByte)
20430 Product = AByte & XByte;
20432 uint8_t Parity = 0;
20435 for (
unsigned PBitIdx = 0; PBitIdx != NumBitsInByte; ++PBitIdx) {
20436 Parity = Parity ^ ((Product >> PBitIdx) & 0x1);
20439 uint8_t Temp = Imm[BitIdx] ? 1 : 0;
20440 RetByte |= (Temp ^ Parity) << BitIdx;
20449 uint16_t TWord = 0;
20450 unsigned NumBitsInByte = 8;
20451 for (
unsigned BitIdx = 0; BitIdx != NumBitsInByte; ++BitIdx) {
20452 if ((BByte >> BitIdx) & 0x1) {
20453 TWord = TWord ^ (AByte << BitIdx);
20461 for (int32_t BitIdx = 14; BitIdx > 7; --BitIdx) {
20462 if ((TWord >> BitIdx) & 0x1) {
20463 TWord = TWord ^ (0x11B << (BitIdx - 8));
20466 return (TWord & 0xFF);
20470 APFloat &ResR, APFloat &ResI) {
20476 APFloat AC = A *
C;
20477 APFloat BD = B * D;
20478 APFloat AD = A * D;
20479 APFloat BC = B *
C;
20482 if (ResR.isNaN() && ResI.isNaN()) {
20483 bool Recalc =
false;
20484 if (A.isInfinity() || B.isInfinity()) {
20485 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
20487 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
20490 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
20492 D = APFloat::copySign(APFloat(D.getSemantics()), D);
20495 if (
C.isInfinity() || D.isInfinity()) {
20496 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
20498 D = APFloat::copySign(APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0),
20501 A = APFloat::copySign(APFloat(A.getSemantics()), A);
20503 B = APFloat::copySign(APFloat(B.getSemantics()), B);
20506 if (!Recalc && (AC.isInfinity() || BD.isInfinity() || AD.isInfinity() ||
20507 BC.isInfinity())) {
20509 A = APFloat::copySign(APFloat(A.getSemantics()), A);
20511 B = APFloat::copySign(APFloat(B.getSemantics()), B);
20513 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
20515 D = APFloat::copySign(APFloat(D.getSemantics()), D);
20519 ResR = APFloat::getInf(A.getSemantics()) * (A *
C - B * D);
20520 ResI = APFloat::getInf(A.getSemantics()) * (A * D + B *
C);
20526 APFloat &ResR, APFloat &ResI) {
20533 APFloat MaxCD = maxnum(
abs(
C),
abs(D));
20534 if (MaxCD.isFinite()) {
20535 DenomLogB =
ilogb(MaxCD);
20536 C =
scalbn(
C, -DenomLogB, APFloat::rmNearestTiesToEven);
20537 D =
scalbn(D, -DenomLogB, APFloat::rmNearestTiesToEven);
20539 APFloat Denom =
C *
C + D * D;
20541 scalbn((A *
C + B * D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
20543 scalbn((B *
C - A * D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
20544 if (ResR.isNaN() && ResI.isNaN()) {
20545 if (Denom.isPosZero() && (!A.isNaN() || !B.isNaN())) {
20546 ResR = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * A;
20547 ResI = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * B;
20548 }
else if ((A.isInfinity() || B.isInfinity()) &&
C.isFinite() &&
20550 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
20552 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
20554 ResR = APFloat::getInf(ResR.getSemantics()) * (A *
C + B * D);
20555 ResI = APFloat::getInf(ResI.getSemantics()) * (B *
C - A * D);
20556 }
else if (MaxCD.isInfinity() && A.isFinite() && B.isFinite()) {
20557 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
20559 D = APFloat::copySign(APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0),
20561 ResR = APFloat::getZero(ResR.getSemantics()) * (A *
C + B * D);
20562 ResI = APFloat::getZero(ResI.getSemantics()) * (B *
C - A * D);
20569 APSInt NormAmt = Amount;
20570 unsigned BitWidth =
Value.getBitWidth();
20571 unsigned AmtBitWidth = NormAmt.getBitWidth();
20572 if (BitWidth == 1) {
20574 NormAmt =
APSInt(APInt(AmtBitWidth, 0), NormAmt.isUnsigned());
20575 }
else if (BitWidth == 2) {
20580 APSInt(APInt(AmtBitWidth, NormAmt[0] ? 1 : 0), NormAmt.isUnsigned());
20583 if (AmtBitWidth > BitWidth) {
20584 Divisor = llvm::APInt(AmtBitWidth, BitWidth);
20586 Divisor = llvm::APInt(BitWidth, BitWidth);
20587 if (AmtBitWidth < BitWidth) {
20588 NormAmt = NormAmt.extend(BitWidth);
20593 if (NormAmt.isSigned()) {
20594 NormAmt =
APSInt(NormAmt.srem(Divisor),
false);
20595 if (NormAmt.isNegative()) {
20596 APSInt SignedDivisor(Divisor,
false);
20597 NormAmt += SignedDivisor;
20600 NormAmt =
APSInt(NormAmt.urem(Divisor),
true);
20607bool ComplexExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
20609 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
20613 bool LHSReal =
false, RHSReal =
false;
20621 Result.makeComplexFloat();
20625 LHSOK = Visit(E->
getLHS());
20627 if (!LHSOK && !Info.noteFailure())
20633 APFloat &Real = RHS.FloatReal;
20636 RHS.makeComplexFloat();
20637 RHS.FloatImag =
APFloat(Real.getSemantics());
20641 assert(!(LHSReal && RHSReal) &&
20642 "Cannot have both operands of a complex operation be real.");
20644 default:
return Error(E);
20646 if (
Result.isComplexFloat()) {
20647 Result.getComplexFloatReal().add(RHS.getComplexFloatReal(),
20648 APFloat::rmNearestTiesToEven);
20650 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
20652 Result.getComplexFloatImag().add(RHS.getComplexFloatImag(),
20653 APFloat::rmNearestTiesToEven);
20655 Result.getComplexIntReal() += RHS.getComplexIntReal();
20656 Result.getComplexIntImag() += RHS.getComplexIntImag();
20660 if (
Result.isComplexFloat()) {
20661 Result.getComplexFloatReal().subtract(RHS.getComplexFloatReal(),
20662 APFloat::rmNearestTiesToEven);
20664 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
20665 Result.getComplexFloatImag().changeSign();
20666 }
else if (!RHSReal) {
20667 Result.getComplexFloatImag().subtract(RHS.getComplexFloatImag(),
20668 APFloat::rmNearestTiesToEven);
20671 Result.getComplexIntReal() -= RHS.getComplexIntReal();
20672 Result.getComplexIntImag() -= RHS.getComplexIntImag();
20676 if (
Result.isComplexFloat()) {
20681 ComplexValue LHS =
Result;
20682 APFloat &A = LHS.getComplexFloatReal();
20683 APFloat &B = LHS.getComplexFloatImag();
20684 APFloat &
C = RHS.getComplexFloatReal();
20685 APFloat &D = RHS.getComplexFloatImag();
20689 assert(!RHSReal &&
"Cannot have two real operands for a complex op!");
20697 }
else if (RHSReal) {
20709 ComplexValue LHS =
Result;
20710 Result.getComplexIntReal() =
20711 (LHS.getComplexIntReal() * RHS.getComplexIntReal() -
20712 LHS.getComplexIntImag() * RHS.getComplexIntImag());
20713 Result.getComplexIntImag() =
20714 (LHS.getComplexIntReal() * RHS.getComplexIntImag() +
20715 LHS.getComplexIntImag() * RHS.getComplexIntReal());
20719 if (
Result.isComplexFloat()) {
20724 ComplexValue LHS =
Result;
20725 APFloat &A = LHS.getComplexFloatReal();
20726 APFloat &B = LHS.getComplexFloatImag();
20727 APFloat &
C = RHS.getComplexFloatReal();
20728 APFloat &D = RHS.getComplexFloatImag();
20742 B = APFloat::getZero(A.getSemantics());
20747 ComplexValue LHS =
Result;
20748 APSInt Den = RHS.getComplexIntReal() * RHS.getComplexIntReal() +
20749 RHS.getComplexIntImag() * RHS.getComplexIntImag();
20751 return Error(E, diag::note_expr_divide_by_zero);
20753 Result.getComplexIntReal() =
20754 (LHS.getComplexIntReal() * RHS.getComplexIntReal() +
20755 LHS.getComplexIntImag() * RHS.getComplexIntImag()) / Den;
20756 Result.getComplexIntImag() =
20757 (LHS.getComplexIntImag() * RHS.getComplexIntReal() -
20758 LHS.getComplexIntReal() * RHS.getComplexIntImag()) / Den;
20766bool ComplexExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
20780 if (
Result.isComplexFloat()) {
20781 Result.getComplexFloatReal().changeSign();
20782 Result.getComplexFloatImag().changeSign();
20785 Result.getComplexIntReal() = -
Result.getComplexIntReal();
20786 Result.getComplexIntImag() = -
Result.getComplexIntImag();
20790 if (
Result.isComplexFloat())
20791 Result.getComplexFloatImag().changeSign();
20793 Result.getComplexIntImag() = -
Result.getComplexIntImag();
20798bool ComplexExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
20801 Result.makeComplexFloat();
20807 Result.makeComplexInt();
20815 return ExprEvaluatorBaseTy::VisitInitListExpr(E);
20818bool ComplexExprEvaluator::VisitCallExpr(
const CallExpr *E) {
20819 if (!IsConstantEvaluatedBuiltinCall(E))
20820 return ExprEvaluatorBaseTy::VisitCallExpr(E);
20823 case Builtin::BI__builtin_complex:
20824 Result.makeComplexFloat();
20842class AtomicExprEvaluator :
20843 public ExprEvaluatorBase<AtomicExprEvaluator> {
20844 const LValue *
This;
20847 AtomicExprEvaluator(EvalInfo &Info,
const LValue *This,
APValue &
Result)
20855 bool ZeroInitialization(
const Expr *E) {
20856 ImplicitValueInitExpr VIE(
20864 bool VisitCastExpr(
const CastExpr *E) {
20867 return ExprEvaluatorBaseTy::VisitCastExpr(E);
20868 case CK_NullToPointer:
20870 return ZeroInitialization(E);
20871 case CK_NonAtomicToAtomic:
20883 return AtomicExprEvaluator(Info,
This,
Result).Visit(E);
20892class VoidExprEvaluator
20893 :
public ExprEvaluatorBase<VoidExprEvaluator> {
20895 VoidExprEvaluator(EvalInfo &Info) : ExprEvaluatorBaseTy(Info) {}
20899 bool ZeroInitialization(
const Expr *E) {
return true; }
20901 bool VisitCastExpr(
const CastExpr *E) {
20904 return ExprEvaluatorBaseTy::VisitCastExpr(E);
20911 bool VisitCallExpr(
const CallExpr *E) {
20912 if (!IsConstantEvaluatedBuiltinCall(E))
20913 return ExprEvaluatorBaseTy::VisitCallExpr(E);
20916 case Builtin::BI__assume:
20917 case Builtin::BI__builtin_assume:
20921 case Builtin::BI__builtin_operator_delete:
20929 bool VisitCXXDeleteExpr(
const CXXDeleteExpr *E);
20933bool VoidExprEvaluator::VisitCXXDeleteExpr(
const CXXDeleteExpr *E) {
20935 if (Info.SpeculativeEvaluationDepth)
20939 if (!OperatorDelete
20940 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
20941 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
20951 if (
Pointer.Designator.Invalid)
20955 if (
Pointer.isNullPointer()) {
20959 if (!Info.getLangOpts().CPlusPlus20)
20960 Info.CCEDiag(E, diag::note_constexpr_new);
20968 QualType AllocType =
Pointer.Base.getDynamicAllocType();
20974 Info.FFDiag(E, diag::note_constexpr_delete_base_nonvirt_dtor)
20983 if (VirtualDelete &&
20985 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
20986 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
20993 (*Alloc)->Value, AllocType))
20996 if (!Info.HeapAllocs.erase(
Pointer.Base.dyn_cast<DynamicAllocLValue>())) {
21001 Info.FFDiag(E, diag::note_constexpr_double_delete);
21011 return VoidExprEvaluator(Info).Visit(E);
21023 if (E->
isGLValue() || T->isFunctionType()) {
21028 }
else if (T->isVectorType()) {
21031 }
else if (T->isConstantMatrixType()) {
21034 }
else if (T->isIntegralOrEnumerationType()) {
21035 if (!IntExprEvaluator(Info,
Result).Visit(E))
21037 }
else if (T->hasPointerRepresentation()) {
21042 }
else if (T->isRealFloatingType()) {
21043 llvm::APFloat F(0.0);
21047 }
else if (T->isAnyComplexType()) {
21052 }
else if (T->isFixedPointType()) {
21053 if (!FixedPointExprEvaluator(Info,
Result).Visit(E))
return false;
21054 }
else if (T->isMemberPointerType()) {
21060 }
else if (T->isArrayType()) {
21063 Info.CurrentCall->createTemporary(E, T, ScopeKind::FullExpression, LV);
21067 }
else if (T->isRecordType()) {
21070 Info.CurrentCall->createTemporary(E, T, ScopeKind::FullExpression, LV);
21074 }
else if (T->isVoidType()) {
21075 if (!Info.getLangOpts().CPlusPlus11)
21076 Info.CCEDiag(E, diag::note_constexpr_nonliteral)
21080 }
else if (T->isAtomicType()) {
21085 E, Unqual, ScopeKind::FullExpression, LV);
21093 }
else if (Info.getLangOpts().CPlusPlus11) {
21094 Info.FFDiag(E, diag::note_constexpr_nonliteral) << E->
getType();
21097 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
21108 const Expr *E,
bool AllowNonLiteralTypes) {
21124 if (T->isArrayType())
21126 else if (T->isRecordType())
21128 else if (T->isAtomicType()) {
21150 if (Info.EnableNewConstInterp) {
21151 if (!Info.Ctx.getInterpContext().evaluateAsRValue(Info, E,
Result))
21154 ConstantExprKind::Normal);
21163 LV.setFrom(Info.Ctx,
Result);
21170 ConstantExprKind::Normal) &&
21178 if (
const auto *L = dyn_cast<IntegerLiteral>(Exp)) {
21180 APValue(
APSInt(L->getValue(), L->getType()->isUnsignedIntegerType()));
21185 if (
const auto *L = dyn_cast<CXXBoolLiteralExpr>(Exp)) {
21191 if (
const auto *FL = dyn_cast<FloatingLiteral>(Exp)) {
21197 if (
const auto *L = dyn_cast<CharacterLiteral>(Exp)) {
21203 if (
const auto *CE = dyn_cast<ConstantExpr>(Exp)) {
21204 if (CE->hasAPValueResult()) {
21205 APValue APV = CE->getAPValueResult();
21207 Result = std::move(APV);
21283 bool InConstantContext)
const {
21285 "Expression evaluator can't be called on a dependent expression.");
21286 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsRValue");
21288 Info.InConstantContext = InConstantContext;
21289 return ::EvaluateAsRValue(
this,
Result, Ctx, Info);
21293 bool InConstantContext)
const {
21295 "Expression evaluator can't be called on a dependent expression.");
21296 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsBooleanCondition");
21304 bool InConstantContext)
const {
21306 "Expression evaluator can't be called on a dependent expression.");
21307 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsInt");
21309 Info.InConstantContext = InConstantContext;
21310 return ::EvaluateAsInt(
this,
Result, Ctx, AllowSideEffects, Info);
21315 bool InConstantContext)
const {
21317 "Expression evaluator can't be called on a dependent expression.");
21318 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFixedPoint");
21320 Info.InConstantContext = InConstantContext;
21321 return ::EvaluateAsFixedPoint(
this,
Result, Ctx, AllowSideEffects, Info);
21326 bool InConstantContext)
const {
21328 "Expression evaluator can't be called on a dependent expression.");
21330 if (!
getType()->isRealFloatingType())
21333 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFloat");
21345 bool InConstantContext)
const {
21347 "Expression evaluator can't be called on a dependent expression.");
21349 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsLValue");
21351 Info.InConstantContext = InConstantContext;
21355 if (Info.EnableNewConstInterp) {
21356 if (!Info.Ctx.getInterpContext().evaluate(Info,
this,
Result.Val,
21357 ConstantExprKind::Normal))
21360 LV.setFrom(Ctx,
Result.Val);
21363 ConstantExprKind::Normal, CheckedTemps);
21366 if (!
EvaluateLValue(
this, LV, Info) || !Info.discardCleanups() ||
21367 Result.HasSideEffects ||
21370 ConstantExprKind::Normal, CheckedTemps))
21373 LV.moveInto(
Result.Val);
21380 bool IsConstantDestruction) {
21381 EvalInfo Info(Ctx, EStatus,
21384 Info.setEvaluatingDecl(
Base, DestroyedValue,
21385 EvalInfo::EvaluatingDeclKind::Dtor);
21386 Info.InConstantContext = IsConstantDestruction;
21395 if (!Info.discardCleanups())
21396 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
21404 "Expression evaluator can't be called on a dependent expression.");
21410 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsConstantExpr");
21412 EvalInfo Info(Ctx,
Result, EM);
21413 Info.InConstantContext =
true;
21415 if (Info.EnableNewConstInterp) {
21416 if (!Info.Ctx.getInterpContext().evaluate(Info,
this,
Result.Val, Kind))
21419 getStorageType(Ctx,
this),
Result.Val, Kind);
21424 if (Kind == ConstantExprKind::ClassTemplateArgument)
21440 FullExpressionRAII
Scope(Info);
21445 if (!Info.discardCleanups())
21446 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
21456 if (Kind == ConstantExprKind::ClassTemplateArgument &&
21459 Result.HasSideEffects)) {
21471 bool IsConstantInitialization)
const {
21473 "Expression evaluator can't be called on a dependent expression.");
21474 assert(VD &&
"Need a valid VarDecl");
21476 llvm::TimeTraceScope TimeScope(
"EvaluateAsInitializer", [&] {
21478 llvm::raw_string_ostream OS(Name);
21484 EStatus.
Diag = &Notes;
21486 EvalInfo Info(Ctx, EStatus,
21487 (IsConstantInitialization &&
21491 Info.setEvaluatingDecl(VD,
Value);
21492 Info.InConstantContext = IsConstantInitialization;
21497 if (Info.EnableNewConstInterp) {
21499 if (!InterpCtx.evaluateAsInitializer(Info, VD,
this,
Value))
21503 ConstantExprKind::Normal);
21518 FullExpressionRAII
Scope(Info);
21521 EStatus.HasSideEffects)
21527 Info.performLifetimeExtension();
21529 if (!Info.discardCleanups())
21530 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
21534 ConstantExprKind::Normal) &&
21541 EStatus.
Diag = &Notes;
21558 IsConstantDestruction) ||
21570 "Expression evaluator can't be called on a dependent expression.");
21579 "Expression evaluator can't be called on a dependent expression.");
21581 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstInt");
21584 Info.InConstantContext =
true;
21588 assert(
Result &&
"Could not evaluate expression");
21589 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
21591 return EVResult.Val.getInt();
21597 "Expression evaluator can't be called on a dependent expression.");
21599 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstIntCheckOverflow");
21601 EVResult.Diag =
Diag;
21603 Info.InConstantContext =
true;
21604 Info.CheckingForUndefinedBehavior =
true;
21608 assert(
Result &&
"Could not evaluate expression");
21609 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
21611 return EVResult.Val.getInt();
21616 "Expression evaluator can't be called on a dependent expression.");
21618 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateForOverflow");
21623 Info.CheckingForUndefinedBehavior =
true;
21629 assert(
Val.isLValue());
21655 IK_ICEIfUnevaluated,
21671static ICEDiag
Worst(ICEDiag A, ICEDiag B) {
return A.Kind >= B.Kind ? A : B; }
21678 Info.InConstantContext =
true;
21687 assert(!E->
isValueDependent() &&
"Should not see value dependent exprs!");
21692#define ABSTRACT_STMT(Node)
21693#define STMT(Node, Base) case Expr::Node##Class:
21694#define EXPR(Node, Base)
21695#include "clang/AST/StmtNodes.inc"
21696 case Expr::PredefinedExprClass:
21697 case Expr::FloatingLiteralClass:
21698 case Expr::ImaginaryLiteralClass:
21699 case Expr::StringLiteralClass:
21700 case Expr::ArraySubscriptExprClass:
21701 case Expr::MatrixSingleSubscriptExprClass:
21702 case Expr::MatrixSubscriptExprClass:
21703 case Expr::ArraySectionExprClass:
21704 case Expr::OMPArrayShapingExprClass:
21705 case Expr::OMPIteratorExprClass:
21706 case Expr::CompoundAssignOperatorClass:
21707 case Expr::CompoundLiteralExprClass:
21708 case Expr::ExtVectorElementExprClass:
21709 case Expr::MatrixElementExprClass:
21710 case Expr::DesignatedInitExprClass:
21711 case Expr::ArrayInitLoopExprClass:
21712 case Expr::ArrayInitIndexExprClass:
21713 case Expr::NoInitExprClass:
21714 case Expr::DesignatedInitUpdateExprClass:
21715 case Expr::ImplicitValueInitExprClass:
21716 case Expr::ParenListExprClass:
21717 case Expr::VAArgExprClass:
21718 case Expr::AddrLabelExprClass:
21719 case Expr::StmtExprClass:
21720 case Expr::CXXMemberCallExprClass:
21721 case Expr::CUDAKernelCallExprClass:
21722 case Expr::CXXAddrspaceCastExprClass:
21723 case Expr::CXXDynamicCastExprClass:
21724 case Expr::CXXTypeidExprClass:
21725 case Expr::CXXUuidofExprClass:
21726 case Expr::MSPropertyRefExprClass:
21727 case Expr::MSPropertySubscriptExprClass:
21728 case Expr::CXXNullPtrLiteralExprClass:
21729 case Expr::UserDefinedLiteralClass:
21730 case Expr::CXXThisExprClass:
21731 case Expr::CXXThrowExprClass:
21732 case Expr::CXXNewExprClass:
21733 case Expr::CXXDeleteExprClass:
21734 case Expr::CXXPseudoDestructorExprClass:
21735 case Expr::UnresolvedLookupExprClass:
21736 case Expr::RecoveryExprClass:
21737 case Expr::DependentScopeDeclRefExprClass:
21738 case Expr::CXXConstructExprClass:
21739 case Expr::CXXInheritedCtorInitExprClass:
21740 case Expr::CXXStdInitializerListExprClass:
21741 case Expr::CXXBindTemporaryExprClass:
21742 case Expr::ExprWithCleanupsClass:
21743 case Expr::CXXTemporaryObjectExprClass:
21744 case Expr::CXXUnresolvedConstructExprClass:
21745 case Expr::CXXDependentScopeMemberExprClass:
21746 case Expr::UnresolvedMemberExprClass:
21747 case Expr::ObjCStringLiteralClass:
21748 case Expr::ObjCBoxedExprClass:
21749 case Expr::ObjCArrayLiteralClass:
21750 case Expr::ObjCDictionaryLiteralClass:
21751 case Expr::ObjCEncodeExprClass:
21752 case Expr::ObjCMessageExprClass:
21753 case Expr::ObjCSelectorExprClass:
21754 case Expr::ObjCProtocolExprClass:
21755 case Expr::ObjCIvarRefExprClass:
21756 case Expr::ObjCPropertyRefExprClass:
21757 case Expr::ObjCSubscriptRefExprClass:
21758 case Expr::ObjCIsaExprClass:
21759 case Expr::ObjCAvailabilityCheckExprClass:
21760 case Expr::ShuffleVectorExprClass:
21761 case Expr::ConvertVectorExprClass:
21762 case Expr::BlockExprClass:
21764 case Expr::OpaqueValueExprClass:
21765 case Expr::PackExpansionExprClass:
21766 case Expr::SubstNonTypeTemplateParmPackExprClass:
21767 case Expr::FunctionParmPackExprClass:
21768 case Expr::AsTypeExprClass:
21769 case Expr::ObjCIndirectCopyRestoreExprClass:
21770 case Expr::MaterializeTemporaryExprClass:
21771 case Expr::PseudoObjectExprClass:
21772 case Expr::AtomicExprClass:
21773 case Expr::LambdaExprClass:
21774 case Expr::CXXFoldExprClass:
21775 case Expr::CoawaitExprClass:
21776 case Expr::DependentCoawaitExprClass:
21777 case Expr::CoyieldExprClass:
21778 case Expr::SYCLUniqueStableNameExprClass:
21779 case Expr::CXXParenListInitExprClass:
21780 case Expr::HLSLOutArgExprClass:
21783 case Expr::MemberExprClass: {
21786 while (
const auto *M = dyn_cast<MemberExpr>(ME)) {
21789 ME = M->getBase()->IgnoreParenImpCasts();
21791 const auto *DRE = dyn_cast<DeclRefExpr>(ME);
21793 if (
const auto *VD = dyn_cast<VarDecl>(DRE->getDecl());
21801 case Expr::InitListExprClass: {
21812 case Expr::SizeOfPackExprClass:
21813 case Expr::GNUNullExprClass:
21814 case Expr::SourceLocExprClass:
21815 case Expr::EmbedExprClass:
21816 case Expr::OpenACCAsteriskSizeExprClass:
21819 case Expr::PackIndexingExprClass:
21822 case Expr::SubstNonTypeTemplateParmExprClass:
21826 case Expr::ConstantExprClass:
21829 case Expr::ParenExprClass:
21831 case Expr::GenericSelectionExprClass:
21833 case Expr::IntegerLiteralClass:
21834 case Expr::FixedPointLiteralClass:
21835 case Expr::CharacterLiteralClass:
21836 case Expr::ObjCBoolLiteralExprClass:
21837 case Expr::CXXBoolLiteralExprClass:
21838 case Expr::CXXScalarValueInitExprClass:
21839 case Expr::TypeTraitExprClass:
21840 case Expr::ConceptSpecializationExprClass:
21841 case Expr::RequiresExprClass:
21842 case Expr::ArrayTypeTraitExprClass:
21843 case Expr::ExpressionTraitExprClass:
21844 case Expr::CXXNoexceptExprClass:
21845 case Expr::CXXReflectExprClass:
21847 case Expr::CallExprClass:
21848 case Expr::CXXOperatorCallExprClass: {
21857 case Expr::CXXRewrittenBinaryOperatorClass:
21860 case Expr::DeclRefExprClass: {
21874 const VarDecl *VD = dyn_cast<VarDecl>(D);
21881 case Expr::UnaryOperatorClass: {
21904 llvm_unreachable(
"invalid unary operator class");
21906 case Expr::OffsetOfExprClass: {
21915 case Expr::UnaryExprOrTypeTraitExprClass: {
21917 if ((Exp->
getKind() == UETT_SizeOf) &&
21920 if (Exp->
getKind() == UETT_CountOf) {
21927 if (VAT->getElementType()->isArrayType())
21939 case Expr::BinaryOperatorClass: {
21984 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE) {
21987 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
21988 if (REval.isSigned() && REval.isAllOnes()) {
21990 if (LEval.isMinSignedValue())
21991 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
21999 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE)
22000 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
22006 return Worst(LHSResult, RHSResult);
22012 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICEIfUnevaluated) {
22022 return Worst(LHSResult, RHSResult);
22025 llvm_unreachable(
"invalid binary operator kind");
22027 case Expr::ImplicitCastExprClass:
22028 case Expr::CStyleCastExprClass:
22029 case Expr::CXXFunctionalCastExprClass:
22030 case Expr::CXXStaticCastExprClass:
22031 case Expr::CXXReinterpretCastExprClass:
22032 case Expr::CXXConstCastExprClass:
22033 case Expr::ObjCBridgedCastExprClass: {
22040 APSInt IgnoredVal(DestWidth, !DestSigned);
22045 if (FL->getValue().convertToInteger(IgnoredVal,
22046 llvm::APFloat::rmTowardZero,
22047 &Ignored) & APFloat::opInvalidOp)
22053 case CK_LValueToRValue:
22054 case CK_AtomicToNonAtomic:
22055 case CK_NonAtomicToAtomic:
22057 case CK_IntegralToBoolean:
22058 case CK_IntegralCast:
22064 case Expr::BinaryConditionalOperatorClass: {
22067 if (CommonResult.Kind == IK_NotICE)
return CommonResult;
22069 if (FalseResult.Kind == IK_NotICE)
return FalseResult;
22070 if (CommonResult.Kind == IK_ICEIfUnevaluated)
return CommonResult;
22071 if (FalseResult.Kind == IK_ICEIfUnevaluated &&
22073 return FalseResult;
22075 case Expr::ConditionalOperatorClass: {
22083 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
22086 if (CondResult.Kind == IK_NotICE)
22092 if (TrueResult.Kind == IK_NotICE)
22094 if (FalseResult.Kind == IK_NotICE)
22095 return FalseResult;
22096 if (CondResult.Kind == IK_ICEIfUnevaluated)
22098 if (TrueResult.Kind == IK_ICE && FalseResult.Kind == IK_ICE)
22104 return FalseResult;
22107 case Expr::CXXDefaultArgExprClass:
22109 case Expr::CXXDefaultInitExprClass:
22111 case Expr::ChooseExprClass: {
22114 case Expr::BuiltinBitCastExprClass: {
22115 if (!checkBitCastConstexprEligibility(
nullptr, Ctx,
cast<CastExpr>(E)))
22121 llvm_unreachable(
"Invalid StmtClass!");
22127 llvm::APSInt *
Value) {
22144 "Expression evaluator can't be called on a dependent expression.");
22146 ExprTimeTraceScope TimeScope(
this, Ctx,
"isIntegerConstantExpr");
22152 if (D.Kind != IK_ICE)
22157std::optional<llvm::APSInt>
22161 return std::nullopt;
22168 return std::nullopt;
22172 return std::nullopt;
22181 Info.InConstantContext =
true;
22184 llvm_unreachable(
"ICE cannot be evaluated!");
22191 "Expression evaluator can't be called on a dependent expression.");
22193 return CheckICE(
this, Ctx).Kind == IK_ICE;
22198 "Expression evaluator can't be called on a dependent expression.");
22208 *
Result = std::move(Scratch);
22215 Status.Diag = &Diags;
22222 Info.discardCleanups() && !Status.HasSideEffects;
22224 return IsConstExpr && Diags.empty();
22232 "Expression evaluator can't be called on a dependent expression.");
22234 llvm::TimeTraceScope TimeScope(
"EvaluateWithSubstitution", [&] {
22236 llvm::raw_string_ostream OS(Name);
22244 Info.InConstantContext =
true;
22247 const LValue *ThisPtr =
nullptr;
22250 auto *MD = dyn_cast<CXXMethodDecl>(Callee);
22251 assert(MD &&
"Don't provide `this` for non-methods.");
22252 assert(MD->isImplicitObjectMemberFunction() &&
22253 "Don't provide `this` for methods without an implicit object.");
22255 if (!
This->isValueDependent() &&
22257 !Info.EvalStatus.HasSideEffects)
22258 ThisPtr = &ThisVal;
22262 Info.EvalStatus.HasSideEffects =
false;
22265 CallRef
Call = Info.CurrentCall->createCall(Callee);
22268 unsigned Idx = I - Args.begin();
22269 if (Idx >= Callee->getNumParams())
22271 const ParmVarDecl *PVD = Callee->getParamDecl(Idx);
22272 if ((*I)->isValueDependent() ||
22274 Info.EvalStatus.HasSideEffects) {
22276 if (
APValue *Slot = Info.getParamSlot(
Call, PVD))
22282 Info.EvalStatus.HasSideEffects =
false;
22287 Info.discardCleanups();
22288 Info.EvalStatus.HasSideEffects =
false;
22291 CallStackFrame Frame(Info, Callee->getLocation(), Callee, ThisPtr,
This,
22294 FullExpressionRAII
Scope(Info);
22296 !Info.EvalStatus.HasSideEffects;
22308 llvm::TimeTraceScope TimeScope(
"isPotentialConstantExpr", [&] {
22310 llvm::raw_string_ostream OS(Name);
22317 Status.
Diag = &Diags;
22321 Info.InConstantContext =
true;
22322 Info.CheckingPotentialConstantExpression =
true;
22325 if (Info.EnableNewConstInterp) {
22326 Info.Ctx.getInterpContext().isPotentialConstantExpr(Info, FD);
22327 return Diags.empty();
22338 This.set({&VIE, Info.CurrentCall->Index});
22346 Info.setEvaluatingDecl(
This.getLValueBase(), Scratch);
22352 &VIE, Args, CallRef(), FD->
getBody(), Info, Scratch,
22356 return Diags.empty();
22364 "Expression evaluator can't be called on a dependent expression.");
22367 Status.
Diag = &Diags;
22371 Info.InConstantContext =
true;
22372 Info.CheckingPotentialConstantExpression =
true;
22374 if (Info.EnableNewConstInterp) {
22375 Info.Ctx.getInterpContext().isPotentialConstantExprUnevaluated(Info, E, FD);
22376 return Diags.empty();
22381 nullptr, CallRef());
22385 return Diags.empty();
22389 unsigned Type)
const {
22390 if (!
getType()->isPointerType())
22391 return std::nullopt;
22395 if (Info.EnableNewConstInterp)
22396 return Info.Ctx.getInterpContext().tryEvaluateObjectSize(Info,
this,
Type);
22400static std::optional<uint64_t>
22402 std::string *StringResult) {
22404 return std::nullopt;
22409 return std::nullopt;
22414 if (
const StringLiteral *S = dyn_cast_or_null<StringLiteral>(
22415 String.getLValueBase().dyn_cast<
const Expr *>())) {
22418 if (Off >= 0 && (uint64_t)Off <= (uint64_t)Str.size() &&
22421 Info.Ctx.hasSameUnqualifiedType(CharTy, Info.Ctx.CharTy)) {
22422 Str = Str.substr(Off);
22424 StringRef::size_type Pos = Str.find(0);
22425 if (Pos != StringRef::npos)
22426 Str = Str.substr(0, Pos);
22429 *StringResult = Str;
22437 for (uint64_t Strlen = 0; ; ++Strlen) {
22441 return std::nullopt;
22444 else if (StringResult)
22445 StringResult->push_back(Char.
getInt().getExtValue());
22447 return std::nullopt;
22454 std::string StringResult;
22456 if (Info.EnableNewConstInterp) {
22457 if (!Info.Ctx.getInterpContext().evaluateString(Info,
this, StringResult))
22458 return std::nullopt;
22459 return StringResult;
22463 return StringResult;
22464 return std::nullopt;
22467template <
typename T>
22469 const Expr *SizeExpression,
22470 const Expr *PtrExpression,
22474 Info.InConstantContext =
true;
22476 if (Info.EnableNewConstInterp)
22477 return Info.Ctx.getInterpContext().evaluateCharRange(Info, SizeExpression,
22481 FullExpressionRAII
Scope(Info);
22486 uint64_t Size = SizeValue.getZExtValue();
22489 if constexpr (std::is_same_v<APValue, T>)
22492 if (Size <
Result.max_size())
22499 for (uint64_t I = 0; I < Size; ++I) {
22505 if constexpr (std::is_same_v<APValue, T>) {
22506 Result.getArrayInitializedElt(I) = std::move(Char);
22510 assert(
C.getBitWidth() <= 8 &&
22511 "string element not representable in char");
22513 Result.push_back(
static_cast<char>(
C.getExtValue()));
22524 const Expr *SizeExpression,
22528 PtrExpression, Ctx, Status);
22532 const Expr *SizeExpression,
22536 PtrExpression, Ctx, Status);
22543 if (Info.EnableNewConstInterp)
22544 return Info.Ctx.getInterpContext().evaluateStrlen(Info,
this);
22549struct IsWithinLifetimeHandler {
22552 using result_type = std::optional<bool>;
22553 std::optional<bool> failed() {
return std::nullopt; }
22554 template <
typename T>
22555 std::optional<bool> found(T &Subobj,
QualType SubobjType,
22559 template <
typename T>
22560 std::optional<bool> found(T &Subobj, QualType SubobjType) {
22565std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &IEE,
22566 const CallExpr *E) {
22567 EvalInfo &Info = IEE.Info;
22572 if (!Info.InConstantContext)
22573 return std::nullopt;
22575 const Expr *Arg = E->
getArg(0);
22577 return std::nullopt;
22580 return std::nullopt;
22582 if (Val.allowConstexprUnknown())
22586 bool CalledFromStd =
false;
22587 const auto *
Callee = Info.CurrentCall->getCallee();
22588 if (Callee &&
Callee->isInStdNamespace()) {
22589 const IdentifierInfo *Identifier =
Callee->getIdentifier();
22590 CalledFromStd = Identifier && Identifier->
isStr(
"is_within_lifetime");
22592 Info.CCEDiag(CalledFromStd ? Info.CurrentCall->getCallRange().getBegin()
22594 diag::err_invalid_is_within_lifetime)
22595 << (CalledFromStd ?
"std::is_within_lifetime"
22596 :
"__builtin_is_within_lifetime")
22598 return std::nullopt;
22608 if (Val.isNullPointer() || Val.getLValueBase().isNull())
22610 QualType T = Val.getLValueBase().getType();
22612 "Pointers to functions should have been typed as function pointers "
22613 "which would have been rejected earlier");
22616 if (Val.getLValueDesignator().isOnePastTheEnd())
22618 assert(Val.getLValueDesignator().isValidSubobject() &&
22619 "Unchecked case for valid subobject");
22623 CompleteObject CO =
22627 if (Info.EvaluatingDeclValue && CO.Value == Info.EvaluatingDeclValue)
22632 IsWithinLifetimeHandler handler{Info};
22633 return findSubobject(Info, E, CO, Val.getLValueDesignator(), handler);
Defines the clang::ASTContext interface.
This file provides some common utility functions for processing Lambda related AST Constructs.
Defines enum values for all the target-independent builtin functions.
static Address castToBase(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy, Address OriginalBaseAddress, llvm::Value *Addr)
static uint32_t getBitWidth(const Expr *E)
static Decl::Kind getKind(const Decl *D)
GCCTypeClass
Values returned by __builtin_classify_type, chosen to match the values produced by GCC's builtin.
@ PointerToMemberFunction
static bool isRead(AccessKinds AK)
static bool EvaluateCharRangeAsStringImpl(const Expr *, T &Result, const Expr *SizeExpression, const Expr *PtrExpression, ASTContext &Ctx, Expr::EvalResult &Status)
static bool isValidIndeterminateAccess(AccessKinds AK)
Is this kind of access valid on an indeterminate object value?
static unsigned elementwiseSize(EvalInfo &Info, QualType BaseTy)
static bool EvaluateMemberPointer(const Expr *E, MemberPtr &Result, EvalInfo &Info)
static bool hasUnacceptableSideEffect(Expr::EvalStatus &Result, Expr::SideEffectsKind SEK)
static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E, AccessKinds AK, const LValue &LVal, QualType LValType)
Find the complete object to which an LValue refers.
static bool evaluateLValueAsAllocSize(EvalInfo &Info, APValue::LValueBase Base, LValue &Result)
Attempts to evaluate the given LValueBase as the result of a call to a function with the alloc_size a...
static 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)
std::optional< APFloat > EvalScalarMinMaxFp(const APFloat &A, const APFloat &B, std::optional< APSInt > RoundingMode, bool IsMin)
static bool CheckMemoryLeaks(EvalInfo &Info)
Enforce C++2a [expr.const]/4.17, which disallows new-expressions unless "the allocated storage is dea...
static bool handleScalarCast(EvalInfo &Info, const FPOptions FPO, const Expr *E, QualType SourceTy, QualType DestTy, APValue const &Original, APValue &Result)
static ICEDiag CheckEvalInICE(const Expr *E, const ASTContext &Ctx)
static llvm::APInt ConvertBoolVectorToInt(const APValue &Val)
static bool flattenAPValue(EvalInfo &Info, const Expr *E, APValue Value, QualType BaseTy, SmallVectorImpl< APValue > &Elements, SmallVectorImpl< QualType > &Types, unsigned Size)
static bool hlslAggSplatHelper(EvalInfo &Info, const Expr *E, APValue &SrcVal, QualType &SrcTy)
static bool isBaseClassPublic(const CXXRecordDecl *Derived, const CXXRecordDecl *Base)
Determine whether Base, which is known to be a direct base class of Derived, is a public base class.
static bool hasVirtualDestructor(QualType T)
static bool HandleOverflow(EvalInfo &Info, const Expr *E, const T &SrcValue, QualType DestType)
static CharUnits getBaseAlignment(EvalInfo &Info, const LValue &Value)
static bool HandleLValueIndirectMember(EvalInfo &Info, const Expr *E, LValue &LVal, const IndirectFieldDecl *IFD)
Update LVal to refer to the given indirect field.
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 std::optional< uint64_t > tryEvaluateBuiltinObjectSize(const Expr *E, unsigned Type, EvalInfo &Info)
Tries to evaluate the __builtin_object_size for E. If successful, returns true and stores the result ...
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)
static void expandVector(APValue &Vec, unsigned NumElements)
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)
static std::optional< uint64_t > EvaluateBuiltinStrLen(const Expr *E, EvalInfo &Info, std::string *StringResult=nullptr)
void HandleComplexComplexDiv(APFloat A, APFloat B, APFloat C, APFloat D, APFloat &ResR, APFloat &ResI)
static bool handleTrivialCopy(EvalInfo &Info, const ParmVarDecl *Param, const Expr *E, APValue &Result, bool CopyObjectRepresentation)
Perform a trivial copy from Param, which is the parameter of a copy or move constructor or assignment...
static bool checkFloatingPointResult(EvalInfo &Info, const Expr *E, APFloat::opStatus St)
Check if the given evaluation result is allowed for constant evaluation.
static bool EvaluateBuiltinConstantPForLValue(const APValue &LV)
EvaluateBuiltinConstantPForLValue - Determine the result of __builtin_constant_p when applied to the ...
static bool EvaluateBuiltinConstantP(EvalInfo &Info, const Expr *Arg)
EvaluateBuiltinConstantP - Evaluate __builtin_constant_p as similarly to GCC as we can manage.
static bool checkNonVirtualMemberCallThisPointer(EvalInfo &Info, const Expr *E, const LValue &This, const CXXMethodDecl *NamedMember)
Check that the pointee of the 'this' pointer in a member function call is either within its lifetime ...
static bool CheckConstantExpression(EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value, ConstantExprKind Kind)
Check that this core constant expression value is a valid value for a constant expression.
static bool EvaluateAsBooleanCondition(const Expr *E, bool &Result, EvalInfo &Info)
static std::optional< DynamicType > ComputeDynamicType(EvalInfo &Info, const Expr *E, LValue &This, AccessKinds AK)
Determine the dynamic type of an object.
static bool EvaluateDecl(EvalInfo &Info, const Decl *D, bool EvaluateConditionDecl=false)
static void expandArray(APValue &Array, unsigned Index)
static bool handleLogicalOpForVector(const APInt &LHSValue, BinaryOperatorKind Opcode, const APInt &RHSValue, APInt &Result)
static unsigned FindDesignatorMismatch(QualType ObjType, const SubobjectDesignator &A, const SubobjectDesignator &B, bool &WasArrayIndex)
Find the position where two subobject designators diverge, or equivalently the length of the common i...
static bool isOnePastTheEndOfCompleteObject(const ASTContext &Ctx, const LValue &LV)
Determine whether this is a pointer past the end of the complete object referred to by the lvalue.
static unsigned getBaseIndex(const CXXRecordDecl *Derived, const CXXRecordDecl *Base)
Get the base index of the given base class within an APValue representing the given derived class.
static bool EvaluateFixedPoint(const Expr *E, APFixedPoint &Result, EvalInfo &Info)
Evaluate only a fixed point expression into an APResult.
void HandleComplexComplexMul(APFloat A, APFloat B, APFloat C, APFloat D, APFloat &ResR, APFloat &ResI)
static bool EvalPointerValueAsBool(const APValue &Value, bool &Result)
static bool handleVectorVectorBinOp(EvalInfo &Info, const BinaryOperator *E, BinaryOperatorKind Opcode, APValue &LHSValue, const APValue &RHSValue)
static bool EvaluateMatrix(const Expr *E, APValue &Result, EvalInfo &Info)
static const FunctionDecl * getVirtualOperatorDelete(QualType T)
static bool isDesignatorAtObjectEnd(const ASTContext &Ctx, const LValue &LVal)
Checks to see if the given LValue's Designator is at the end of the LValue's record layout....
static bool CheckArraySize(EvalInfo &Info, const ConstantArrayType *CAT, SourceLocation CallLoc={})
static bool EvaluateInPlace(APValue &Result, EvalInfo &Info, const LValue &This, const Expr *E, bool AllowNonLiteralTypes=false)
EvaluateInPlace - Evaluate an expression in-place in an APValue. In some cases, the in-place evaluati...
static bool handleFloatFloatBinOp(EvalInfo &Info, const BinaryOperator *E, APFloat &LHS, BinaryOperatorKind Opcode, const APFloat &RHS)
Perform the given binary floating-point operation, in-place, on LHS.
static std::optional< DynAlloc * > CheckDeleteKind(EvalInfo &Info, const Expr *E, const LValue &Pointer, DynAlloc::Kind DeallocKind)
Check that the given object is a suitable pointer to a heap allocation that still exists and is of th...
static bool EvaluateLValue(const Expr *E, LValue &Result, EvalInfo &Info, bool InvalidBaseOK=false)
Evaluate an expression as an lvalue. This can be legitimately called on expressions which are not glv...
static bool FastEvaluateAsRValue(const Expr *Exp, APValue &Result, const ASTContext &Ctx, bool &IsConst)
static bool HandleCovariantReturnAdjustment(EvalInfo &Info, const Expr *E, APValue &Result, ArrayRef< QualType > Path)
Perform the adjustment from a value returned by a virtual function to a value of the statically expec...
static bool evalShiftWithCount(EvalInfo &Info, const CallExpr *Call, APValue &Out, llvm::function_ref< APInt(const APInt &, uint64_t)> ShiftOp, llvm::function_ref< APInt(const APInt &, unsigned)> OverflowOp)
static EvalStmtResult EvaluateSwitch(StmtResult &Result, EvalInfo &Info, const SwitchStmt *SS)
Evaluate a switch statement.
static void expandStringLiteral(EvalInfo &Info, const StringLiteral *S, APValue &Result, QualType AllocType=QualType())
static bool EvaluateArgs(ArrayRef< const Expr * > Args, CallRef Call, EvalInfo &Info, const FunctionDecl *Callee, bool RightToLeft=false, LValue *ObjectArg=nullptr)
Evaluate the arguments to a function call.
static bool EvaluateAtomic(const Expr *E, const LValue *This, APValue &Result, EvalInfo &Info)
static bool getBytesReturnedByAllocSizeCall(const ASTContext &Ctx, const LValue &LVal, llvm::APInt &Result)
Convenience function. LVal's base must be a call to an alloc_size function.
static bool handleIntIntBinOp(EvalInfo &Info, const BinaryOperator *E, const APSInt &LHS, BinaryOperatorKind Opcode, APSInt RHS, APSInt &Result)
Perform the given binary integer operation.
static bool EvaluateInitForDeclOfReferenceType(EvalInfo &Info, const ValueDecl *D, const Expr *Init, LValue &Result, APValue &Val)
Evaluates the initializer of a reference.
static bool checkDynamicType(EvalInfo &Info, const Expr *E, const LValue &This, AccessKinds AK, bool Polymorphic)
Check that we can access the notional vptr of an object / determine its dynamic type.
static bool HandleFloatToIntCast(EvalInfo &Info, const Expr *E, QualType SrcType, const APFloat &Value, QualType DestType, APSInt &Result)
static bool getAlignmentArgument(const Expr *E, QualType ForType, EvalInfo &Info, APSInt &Alignment)
Evaluate the value of the alignment argument to __builtin_align_{up,down}, __builtin_is_aligned and _...
static bool CheckFullyInitialized(EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value)
Check that this evaluated value is fully-initialized and can be loaded by an lvalue-to-rvalue convers...
static SubobjectHandler::result_type findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, const SubobjectDesignator &Sub, SubobjectHandler &handler)
Find the designated sub-object of an rvalue.
static bool determineEndOffset(EvalInfo &Info, SourceLocation ExprLoc, unsigned Type, const LValue &LVal, CharUnits &EndOffset)
Helper for tryEvaluateBuiltinObjectSize – Given an LValue, this will determine how many bytes exist f...
static bool convertUnsignedAPIntToCharUnits(const llvm::APInt &Int, CharUnits &Result)
Converts the given APInt to CharUnits, assuming the APInt is unsigned. Fails if the conversion would ...
static bool EvaluateCallArg(const ParmVarDecl *PVD, const Expr *Arg, CallRef Call, EvalInfo &Info, bool NonNull=false, APValue **EvaluatedArg=nullptr)
llvm::SmallPtrSet< const MaterializeTemporaryExpr *, 8 > CheckedTemporaries
Materialized temporaries that we've already checked to determine if they're initializsed by a constan...
GCCTypeClass EvaluateBuiltinClassifyType(QualType T, const LangOptions &LangOpts)
EvaluateBuiltinClassifyType - Evaluate __builtin_classify_type the same way as GCC.
static bool EvaluateDependentExpr(const Expr *E, EvalInfo &Info)
static bool MaybeEvaluateDeferredVarDeclInit(EvalInfo &Info, const VarDecl *VD)
static APSInt HandleIntToIntCast(EvalInfo &Info, const Expr *E, QualType DestType, QualType SrcType, const APSInt &Value)
static std::optional< APValue > handleVectorUnaryOperator(ASTContext &Ctx, QualType ResultTy, UnaryOperatorKind Op, APValue Elt)
static bool lifetimeStartedInEvaluation(EvalInfo &Info, APValue::LValueBase Base, bool MutableSubobject=false)
static bool isOneByteCharacterType(QualType T)
static bool HandleLambdaCapture(EvalInfo &Info, const Expr *E, LValue &Result, const CXXMethodDecl *MD, const FieldDecl *FD, bool LValueToRValueConversion)
Get an lvalue to a field of a lambda's closure type.
static bool EvaluateCond(EvalInfo &Info, const VarDecl *CondDecl, const Expr *Cond, bool &Result)
Evaluate a condition (either a variable declaration or an expression).
static bool EvaluateAsFixedPoint(const Expr *E, Expr::EvalResult &ExprResult, const ASTContext &Ctx, Expr::SideEffectsKind AllowSideEffects, EvalInfo &Info)
static bool EvaluateAsRValue(EvalInfo &Info, const Expr *E, APValue &Result)
EvaluateAsRValue - Try to evaluate this expression, performing an implicit lvalue-to-rvalue cast if i...
static bool diagnoseMutableFields(EvalInfo &Info, const Expr *E, AccessKinds AK, QualType T)
Diagnose an attempt to read from any unreadable field within the specified type, which might be a cla...
static ICEDiag CheckICE(const Expr *E, const ASTContext &Ctx)
static bool CheckConstexprFunction(EvalInfo &Info, SourceLocation CallLoc, const FunctionDecl *Declaration, const FunctionDecl *Definition, const Stmt *Body)
CheckConstexprFunction - Check that a function can be called in a constant expression.
static bool EvaluateDestruction(const ASTContext &Ctx, APValue::LValueBase Base, APValue DestroyedValue, QualType Type, SourceLocation Loc, Expr::EvalStatus &EStatus, bool IsConstantDestruction)
static EvalStmtResult EvaluateStmt(StmtResult &Result, EvalInfo &Info, const Stmt *S, const SwitchCase *SC=nullptr)
static bool EvaluateArrayNewInitList(EvalInfo &Info, LValue &This, APValue &Result, const InitListExpr *ILE, QualType AllocType)
static bool HasSameBase(const LValue &A, const LValue &B)
static bool CheckLocalVariableDeclaration(EvalInfo &Info, const VarDecl *VD)
static bool HandleLValueDirectBase(EvalInfo &Info, const Expr *E, LValue &Obj, const CXXRecordDecl *Derived, const CXXRecordDecl *Base, const ASTRecordLayout *RL=nullptr)
static bool IsGlobalLValue(APValue::LValueBase B)
static llvm::RoundingMode getActiveRoundingMode(EvalInfo &Info, const Expr *E)
Get rounding mode to use in evaluation of the specified expression.
static QualType getObjectType(APValue::LValueBase B)
Retrieves the "underlying object type" of the given expression, as used by __builtin_object_size.
static bool handleCompareOpForVectorHelper(const APTy &LHSValue, BinaryOperatorKind Opcode, const APTy &RHSValue, APInt &Result)
static bool Evaluate(APValue &Result, EvalInfo &Info, const Expr *E)
static bool isReadByLvalueToRvalueConversion(const CXXRecordDecl *RD)
Determine whether a type would actually be read by an lvalue-to-rvalue conversion.
static void negateAsSigned(APSInt &Int)
Negate an APSInt in place, converting it to a signed form if necessary, and preserving its value (by ...
static bool HandleFunctionCall(SourceLocation CallLoc, const FunctionDecl *Callee, const LValue *ObjectArg, const Expr *E, ArrayRef< const Expr * > Args, CallRef Call, const Stmt *Body, EvalInfo &Info, APValue &Result, const LValue *ResultSlot)
Evaluate a function call.
static bool isUserWritingOffTheEnd(const ASTContext &Ctx, const LValue &LVal)
Attempts to detect a user writing into a piece of memory that's impossible to figure out the size of ...
static bool GetLValueBaseAsString(const EvalInfo &Info, const LValue &LVal, LValueBaseString &AsString)
static bool HandleOperatorDeleteCall(EvalInfo &Info, const CallExpr *E)
static bool EvaluateIntegerOrLValue(const Expr *E, APValue &Result, EvalInfo &Info)
EvaluateIntegerOrLValue - Evaluate an rvalue integral-typed expression, and produce either the intege...
static bool HandleDynamicCast(EvalInfo &Info, const ExplicitCastExpr *E, LValue &Ptr)
Apply the given dynamic cast operation on the provided lvalue.
static bool HandleOperatorNewCall(EvalInfo &Info, const CallExpr *E, LValue &Result)
Perform a call to 'operator new' or to ‘__builtin_operator_new’.
static bool HandleFloatToFloatCast(EvalInfo &Info, const Expr *E, QualType SrcType, QualType DestType, APFloat &Result)
static bool MaybeHandleUnionActiveMemberChange(EvalInfo &Info, const Expr *LHSExpr, const LValue &LHS)
Handle a builtin simple-assignment or a call to a trivial assignment operator whose left-hand side mi...
uint8_t GFNIMul(uint8_t AByte, uint8_t BByte)
static bool isFormalAccess(AccessKinds AK)
Is this an access per the C++ definition?
static bool handleCompoundAssignment(EvalInfo &Info, const CompoundAssignOperator *E, const LValue &LVal, QualType LValType, QualType PromotedLValType, BinaryOperatorKind Opcode, const APValue &RVal)
Perform a compound assignment of LVal <op>= RVal.
static bool handleIncDec(EvalInfo &Info, const Expr *E, const LValue &LVal, QualType LValType, bool IsIncrement, APValue *Old)
Perform an increment or decrement on LVal.
static bool EvaluateVoid(const Expr *E, EvalInfo &Info)
static bool HandleDestruction(EvalInfo &Info, const Expr *E, const LValue &This, QualType ThisType)
Perform a destructor or pseudo-destructor call on the given object, which might in general not be a c...
static bool HandleDestructionImpl(EvalInfo &Info, SourceRange CallRange, const LValue &This, APValue &Value, QualType T)
static bool ArePotentiallyOverlappingStringLiterals(const EvalInfo &Info, const LValue &LHS, const LValue &RHS)
uint8_t GFNIMultiplicativeInverse(uint8_t Byte)
uint8_t GFNIAffine(uint8_t XByte, const APInt &AQword, const APSInt &Imm, bool Inverse)
APSInt NormalizeRotateAmount(const APSInt &Value, const APSInt &Amount)
Result
Implement __builtin_bit_cast and related operations.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
llvm::MachO::Record Record
Implements a partial diagnostic which may not be emitted.
llvm::DenseMap< Stmt *, Stmt * > MapTy
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
Expr * getExpr()
Get 'expr' part of the associated expression/statement.
static QualType getPointeeType(const MemRegion *R)
Enumerates target-specific builtins in their own namespaces within namespace clang.
Defines the clang::TypeLoc interface and its subclasses.
C Language Family Type Representation.
__DEVICE__ long long abs(long long __n)
a trap message and trap category.
llvm::APInt getValue() const
unsigned getVersion() const
QualType getDynamicAllocType() const
QualType getTypeInfoType() const
static LValueBase getTypeInfo(TypeInfoLValue LV, QualType TypeInfo)
static LValueBase getDynamicAlloc(DynamicAllocLValue LV, QualType Type)
A non-discriminated union of a base, field, or array index.
BaseOrMemberType getAsBaseOrMember() const
static LValuePathEntry ArrayIndex(uint64_t Index)
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
bool hasArrayFiller() const
const LValueBase getLValueBase() const
APValue & getArrayInitializedElt(unsigned I)
void swap(APValue &RHS)
Swaps the contents of this and the given APValue.
APValue & getStructField(unsigned i)
unsigned getMatrixNumColumns() const
const FieldDecl * getUnionField() const
APSInt & getComplexIntImag()
bool isComplexInt() const
llvm::PointerIntPair< const Decl *, 1, bool > BaseOrMemberType
A FieldDecl or CXXRecordDecl, along with a flag indicating whether we mean a virtual or non-virtual b...
ValueKind getKind() const
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 getMatrixNumRows() const
unsigned getArraySize() const
bool allowConstexprUnknown() const
std::string getAsString(const ASTContext &Ctx, QualType Ty) const
bool isFixedPoint() const
APValue & getMatrixElt(unsigned Idx)
@ Indeterminate
This object has an indeterminate value (C++ [basic.indet]).
@ None
There is no such object (it's outside its lifetime).
APSInt & getComplexIntReal()
APFloat & getComplexFloatImag()
APFloat & getComplexFloatReal()
APValue & getStructBase(unsigned i)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
SourceManager & getSourceManager()
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
unsigned getIntWidth(QualType T) const
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
uint64_t getTargetNullPointerValue(QualType QT) const
Get target-dependent integer value for null pointer which is used for constant folding.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
unsigned getPreferredTypeAlign(QualType T) const
Return the "preferred" alignment of the specified type T for the current target, in bits.
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
const LangOptions & getLangOpts() const
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
interp::Context & getInterpContext() const
Returns the clang bytecode interpreter context.
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
const clang::PrintingPolicy & getPrintingPolicy() const
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
llvm::APSInt MakeIntValue(uint64_t Value, QualType Type) const
Make an APSInt of the appropriate width and signedness for the given Value and integer Type.
const VariableArrayType * getAsVariableArrayType(QualType T) const
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
CanQualType getCanonicalTagType(const TagDecl *TD) const
uint64_t getCharWidth() const
Return the size of the character type, in bits.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
unsigned getFieldCount() const
getFieldCount - Get the number of fields in the layout.
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - Get the offset, in chars, for the given base class.
LabelDecl * getLabel() const
OpaqueValueExpr * getCommonExpr() const
Get the common subexpression shared by all initializations (the source array).
Expr * getSubExpr() const
Get the initializer to use for each array element.
Expr * getLHS()
An array access can be written A[4] or 4[A] (both are equivalent).
uint64_t getValue() const
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
QualType getValueType() const
Gets the type contained by this atomic type, i.e.
Attr - This represents one attribute.
BinaryConditionalOperator - The GNU extension to the conditional operator which allows the middle ope...
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression which will be evaluated if the condition evaluates to false; ...
OpaqueValueExpr * getOpaqueValue() const
getOpaqueValue - Return the opaque value placeholder.
Expr * getCommon() const
getCommon - Return the common expression, written to the left of the condition.
A builtin binary operation expression such as "x + y" or "x <= y".
static bool isLogicalOp(Opcode Opc)
static bool isRelationalOp(Opcode Opc)
static bool isComparisonOp(Opcode Opc)
static Opcode getOpForCompoundAssignment(Opcode Opc)
SourceLocation getExprLoc() const
static bool isAdditiveOp(Opcode Opc)
static bool isPtrMemOp(Opcode Opc)
predicates to categorize the respective opcodes.
static bool isAssignmentOp(Opcode Opc)
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
static bool isEqualityOp(Opcode Opc)
bool hasCaptures() const
True if this block (or its nested blocks) captures anything of local storage from its enclosing scope...
const BlockDecl * getBlockDecl() const
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.
CaseStmt - Represent a case statement.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
path_iterator path_begin()
unsigned path_size() const
CastKind getCastKind() const
const FieldDecl * getTargetUnionField() const
const CXXBaseSpecifier *const * path_const_iterator
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operation.
CharUnits - This is an opaque type for sizes expressed in character units.
bool isPowerOfTwo() const
isPowerOfTwo - Test whether the quantity is a power of two.
CharUnits alignmentAtOffset(CharUnits offset) const
Given that this is a non-zero alignment value, what is the alignment at the given offset?
bool isZero() const
isZero - Test whether the quantity equals zero.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
unsigned getValue() const
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
const ValueInfo * getValueInfo(ComparisonCategoryResult ValueKind) const
ComparisonCategoryResult makeWeakResult(ComparisonCategoryResult Res) const
Converts the specified result kind into the correct result kind for this category.
Complex values, per C99 6.2.5p11.
QualType getElementType() const
CompoundAssignOperator - For compound assignments (e.g.
QualType getComputationLHSType() const
CompoundLiteralExpr - [C99 6.5.2.5].
bool hasStaticStorage() const
APValue & getOrCreateStaticValue(ASTContext &Ctx) const
const Expr * getInitializer() const
CompoundStmt - This represents a group of statements like { stmt stmt }.
Stmt *const * const_body_iterator
body_iterator body_begin()
bool isSatisfied() const
Whether or not the concept with the given arguments was satisfied when the expression was created.
ConditionalOperator - The ?
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
Expr * getCond() const
getCond - Return the expression representing the condition for the ?
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
Represents the canonical version of C arrays with a specified constant size.
unsigned getSizeBitWidth() const
Return the bit width of the size type.
static unsigned getNumAddressingBits(const ASTContext &Context, QualType ElementType, const llvm::APInt &NumElements)
Determine the number of bits required to address a member of.
static unsigned getMaxSizeBits(const ASTContext &Context)
Determine the maximum number of active bits that an array's size can require, which limits the maximu...
uint64_t getLimitedSize() const
Return the size zero-extended to uint64_t or UINT64_MAX if the value is larger than UINT64_MAX.
bool isZeroSize() const
Return true if the size is zero.
const Expr * getSizeExpr() const
Return a pointer to the size expression.
llvm::APInt getSize() const
Return the constant array size as an APInt.
uint64_t getZExtSize() const
Return the size zero-extended as a uint64_t.
APValue getAPValueResult() const
bool hasAPValueResult() const
Represents a concrete matrix type with constant number of rows and columns.
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
Represents the current source location and context used to determine the value of the source location...
const Expr * getDefaultExpr() const
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool Equals(const DeclContext *DC) const
Determine whether this declaration context is equivalent to the declaration context DC.
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
A reference to a declared variable, function, enum, etc.
bool refersToEnclosingVariableOrCapture() const
Does this DeclRefExpr refer to an enclosing local or a captured variable?
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Decl - This represents one declaration (or definition), e.g.
bool isInStdNamespace() const
ASTContext & getASTContext() const LLVM_READONLY
bool isInvalidDecl() const
SourceLocation getLocation() const
DeclContext * getDeclContext()
AccessSpecifier getAccess() const
bool isAnyOperatorNew() const
A decomposition declaration.
auto flat_bindings() const
InitListExpr * getUpdater() const
Designator - A designator in a C99 designated initializer.
DoStmt - This represents a 'do/while' stmt.
Symbolic representation of a dynamic allocation.
static unsigned getMaxIndex()
const Expr * getBase() const
ChildElementIter< false > begin()
ExplicitCastExpr - An explicit cast written in the source code.
QualType getTypeAsWritten() const
getTypeAsWritten - Returns the type that this expression is casting to, as written in the source code...
This represents one expression.
const Expr * skipRValueSubobjectAdjustments(SmallVectorImpl< const Expr * > &CommaLHS, SmallVectorImpl< SubobjectAdjustment > &Adjustments) const
Walk outwards from an expression we want to bind a reference to and find the expression whose lifetim...
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
static bool isPotentialConstantExpr(const FunctionDecl *FD, SmallVectorImpl< PartialDiagnosticAt > &Diags)
isPotentialConstantExpr - Return true if this function's definition might be usable in a constant exp...
bool isIntegerConstantExpr(const ASTContext &Ctx) const
static bool isPotentialConstantExprUnevaluated(Expr *E, const FunctionDecl *FD, SmallVectorImpl< PartialDiagnosticAt > &Diags)
isPotentialConstantExprUnevaluated - Return true if this expression might be usable in a constant exp...
@ SE_AllowSideEffects
Allow any unmodeled side effect.
@ SE_AllowUndefinedBehavior
Allow UB that we can give a value, but not arbitrary unmodeled side effects.
bool isCXX11ConstantExpr(const ASTContext &Ctx, APValue *Result=nullptr) const
isCXX11ConstantExpr - Return true if this expression is a constant expression in C++11.
bool EvaluateCharRangeAsString(std::string &Result, const Expr *SizeExpression, const Expr *PtrExpression, ASTContext &Ctx, EvalResult &Status) const
llvm::APSInt EvaluateKnownConstIntCheckOverflow(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
bool isValueDependent() const
Determines whether the value of this expression depends on.
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Returns the set of floating point options that apply to this expression.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
bool containsErrors() const
Whether this expression contains subexpressions which had errors.
bool EvaluateAsFloat(llvm::APFloat &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsFloat - Return true if this is a constant which we can fold and convert to a floating point...
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsLValue - Evaluate an expression to see if we can fold it to an lvalue with link time known ...
bool EvaluateAsFixedPoint(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsFixedPoint - Return true if this is a constant which we can fold and convert to a fixed poi...
bool isEvaluatable(const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
isEvaluatable - Call EvaluateAsRValue to see if this expression can be constant folded without side-e...
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language.
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...
std::optional< uint64_t > tryEvaluateStrLen(const ASTContext &Ctx) const
If the current Expr is a pointer, this will try to statically determine the strlen of the string poin...
bool HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects=true) const
HasSideEffects - This routine returns true for all those expressions which have any effect other than...
bool EvaluateAsConstantExpr(EvalResult &Result, const ASTContext &Ctx, ConstantExprKind Kind=ConstantExprKind::Normal) const
Evaluate an expression that is required to be a constant expression.
std::optional< std::string > tryEvaluateString(ASTContext &Ctx) const
If the current Expr can be evaluated to a pointer to a null-terminated constant string,...
bool EvaluateAsBooleanCondition(bool &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsBooleanCondition - Return true if this is a constant which we can fold and convert to a boo...
bool isTemporaryObject(ASTContext &Ctx, const CXXRecordDecl *TempTy) const
Determine whether the result of this expression is a temporary object of the given class type.
std::optional< uint64_t > tryEvaluateObjectSize(const ASTContext &Ctx, unsigned Type) const
If the current Expr is a pointer, this will try to statically determine the number of bytes available...
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
bool isCXX98IntegralConstantExpr(const ASTContext &Ctx) const
isCXX98IntegralConstantExpr - Return true if this expression is an integral constant expression in C+...
bool EvaluateWithSubstitution(APValue &Value, ASTContext &Ctx, const FunctionDecl *Callee, ArrayRef< const Expr * > Args, const Expr *This=nullptr) const
EvaluateWithSubstitution - Evaluate an expression as if from the context of a call to the given funct...
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...
bool isFPConstrained() const
LangOptions::FPExceptionModeKind getExceptionMode() const
RoundingMode getRoundingMode() const
Represents a member of a struct/union/class.
bool isBitField() const
Determines whether this field is a bitfield.
unsigned getBitWidthValue() const
Computes the bit width of this field, if this is a bit field.
unsigned getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
FieldDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this field.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
llvm::APInt getValue() const
Returns an internal integer representation of the literal.
llvm::APFloat getValue() const
ForStmt - This represents a 'for (init;cond;inc)' stmt.
VarDecl * getConditionVariable() const
Retrieve the variable declared in this "for" statement, if any.
const Expr * getSubExpr() const
Represents a function declaration or definition.
const ParmVarDecl * getParamDecl(unsigned i) const
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
bool isFunctionTemplateSpecialization() const
Determine whether this function is a function template specialization.
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
bool hasCXXExplicitFunctionObjectParameter() const
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
bool isConstexpr() const
Whether this is a (C++11) constexpr function or constexpr constructor.
bool isUsableAsGlobalAllocationFunctionInConstantEvaluation(UnsignedOrNone *AlignmentParam=nullptr, bool *IsNothrow=nullptr) const
Determines whether this function is one of the replaceable global allocation functions described in i...
bool isDefaulted() const
Whether this function is defaulted.
void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override
Appends a human-readable name for this declaration into the given stream.
FunctionDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
Expr * getResultExpr()
Return the result expression of this controlling expression.
One of these records is kept for each identifier that is lexed.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
IfStmt - This represents an if/then/else.
bool isNonNegatedConsteval() const
VarDecl * getConditionVariable()
Retrieve the variable declared in this "if" statement, if any.
const Expr * getSubExpr() const
Represents an implicitly-generated value initialization of an object of a given type.
Represents a field injected from an anonymous union/struct into the parent scope.
ArrayRef< NamedDecl * > chain() const
Describes an C or C++ initializer list.
bool isTransparent() const
Is this a transparent initializer list (that is, an InitListExpr that is purely syntactic,...
bool isStringLiteralInit() const
Is this an initializer for an array of characters, initialized by a string literal or an @encode?
unsigned getNumInits() const
Expr * getArrayFiller()
If this initializer list initializes an array with more elements than there are initializers in the l...
const Expr * getInit(unsigned Init) const
ArrayRef< Expr * > inits() const
capture_init_iterator capture_init_end()
Retrieve the iterator pointing one past the last initialization argument for this lambda expression.
capture_init_iterator capture_init_begin()
Retrieve the first initialization argument for this lambda expression (which initializes the first ca...
CXXRecordDecl * getLambdaClass() const
Retrieve the class that corresponds to the lambda.
StrictFlexArraysLevelKind
@ FPE_Ignore
Assume that floating-point exceptions are masked.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
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.
bool isTriviallyCopyableType(const ASTContext &Context) const
Return true if this is a trivially copyable type (C++0x [basic.types]p9)
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.
QualType getAtomicUnqualifiedType() const
Remove all qualifiers including _Atomic.
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after.
unsigned getCVRQualifiers() const
Retrieve the set of CVR (const-volatile-restrict) qualifiers applied to this type.
bool isWrapType() const
Returns true if it is a OverflowBehaviorType of Wrap kind.
Represents a struct/union/class.
unsigned getNumFields() const
Returns the number of fields (non-static data members) in this record.
field_iterator field_end() const
field_range fields() const
specific_decl_iterator< FieldDecl > field_iterator
bool isAnonymousStructOrUnion() const
Whether this is an anonymous struct or union.
field_iterator field_begin() const
bool isSatisfied() const
Whether or not the requires clause is satisfied.
SourceLocation getLocation() const
std::string ComputeName(ASTContext &Context) const
Scope - A scope is a transient data structure that is used while parsing the program.
ShuffleVectorExpr - clang-specific builtin-in function __builtin_shufflevector.
llvm::APSInt getShuffleMaskIdx(unsigned N) const
unsigned getNumSubExprs() const
getNumSubExprs - Return the size of the SubExprs array.
Expr * getExpr(unsigned Index)
getExpr - Return the Expr at the specified index.
unsigned getPackLength() const
Retrieve the length of the parameter pack.
APValue EvaluateInContext(const ASTContext &Ctx, const Expr *DefaultExpr) const
Return the result of evaluating this SourceLocExpr in the specified (and possibly null) default argum...
Encodes a location in the source.
A trivial tuple used to represent a source range.
SourceLocation getBegin() const
std::string printToString(const SourceManager &SM) const
CompoundStmt * getSubStmt()
Stmt - This represents one statement.
StmtClass getStmtClass() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
SourceLocation getBeginLoc() const LLVM_READONLY
StringLiteral - This represents a string literal expression, e.g.
unsigned getLength() const
StringRef getBytes() const
Allow access to clients that need the byte representation, such as ASTWriterStmt::VisitStringLiteral(...
uint32_t getCodeUnit(size_t i) const
StringRef getString() const
unsigned getCharByteWidth() const
Expr * getReplacement() const
const SwitchCase * getNextSwitchCase() const
SwitchStmt - This represents a 'switch' stmt.
VarDecl * getConditionVariable()
Retrieve the variable declared in this "switch" statement, if any.
SwitchCase * getSwitchCaseList()
TagDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
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 isConstantMatrixType() const
bool isPointerType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isEnumeralType() const
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
bool isVariableArrayType() const
bool isSveVLSBuiltinType() const
Determines if this is a sizeless type supported by the 'arm_sve_vector_bits' type attribute,...
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
bool isExtVectorBoolType() const
bool isMemberDataPointerType() const
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
RecordDecl * castAsRecordDecl() const
bool isAnyComplexType() const
bool isFixedPointType() const
Return true if this is a fixed point type according to ISO/IEC JTC1 SC22 WG14 N1169.
bool isMemberPointerType() const
bool isAtomicType() const
bool isComplexIntegerType() const
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isObjectType() const
Determine whether this type is an object type.
EnumDecl * getAsEnumDecl() const
Retrieves the EnumDecl this type refers to.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
bool isFunctionType() const
bool isVectorType() const
bool isRealFloatingType() const
Floating point categories.
bool isFloatingType() const
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
const T * castAsCanonical() const
Return this type's canonical type cast to the specified type.
bool isAnyPointerType() const
TypeClass getTypeClass() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isNullPtrType() const
bool isRecordType() const
bool isSizelessVectorType() const
Returns true for all scalable vector types.
bool hasPointerRepresentation() const
Whether this type is represented natively as a pointer.
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
QualType getArgumentType() const
SourceLocation getBeginLoc() const LLVM_READONLY
QualType getTypeOfArgument() const
Gets the argument type, or the type of the argument expression, whichever is appropriate.
bool isArgumentType() const
UnaryExprOrTypeTrait getKind() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
SourceLocation getExprLoc() const
Expr * getSubExpr() const
static bool isIncrementOp(Opcode Op)
bool canOverflow() const
Returns true if the unary operator can cause an overflow.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
bool isWeak() const
Determine whether this symbol is weakly-imported, or declared with the weak or weak-ref attr.
Represents a variable declaration or definition.
bool isConstexpr() const
Whether this variable is (C++11) constexpr.
bool hasICEInitializer(const ASTContext &Context) const
Determine whether the initializer of this variable is an integer constant expression.
bool isInitCapture() const
Whether this variable is the implicit variable for a lambda init-capture.
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.
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
@ 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.
unsigned SuppressLambdaBody
Whether to suppress printing the body of a lambda.
@ 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)