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 if (
const auto *MD = dyn_cast<CXXMethodDecl>(Callee)) {
1867 ExplicitInstanceParam = MD->isExplicitObjectMemberFunction();
1871 Callee->getNameForDiagnostic(Out, Info.Ctx.getPrintingPolicy(),
1874 if (This && IsMemberCall) {
1875 if (
const auto *MCE = dyn_cast_if_present<CXXMemberCallExpr>(CallExpr)) {
1876 const Expr *
Object = MCE->getImplicitObjectArgument();
1877 Object->printPretty(Out,
nullptr, Info.Ctx.getPrintingPolicy(),
1879 if (
Object->getType()->isPointerType())
1883 }
else if (
const auto *OCE =
1884 dyn_cast_if_present<CXXOperatorCallExpr>(CallExpr)) {
1885 OCE->getArg(0)->printPretty(Out,
nullptr,
1886 Info.Ctx.getPrintingPolicy(),
1891 This->moveInto(Val);
1894 Info.Ctx.getLValueReferenceType(
This->Designator.MostDerivedType));
1897 Callee->getNameForDiagnostic(Out, Info.Ctx.getPrintingPolicy(),
1903 llvm::ListSeparator
Comma;
1904 for (
const ParmVarDecl *Param :
1905 Callee->parameters().slice(ExplicitInstanceParam)) {
1907 const APValue *
V = Info.getParamSlot(Arguments, Param);
1909 V->printPretty(Out, Info.Ctx, Param->getType());
1925 return Info.noteSideEffect();
1932 return (
Builtin == Builtin::BI__builtin___CFStringMakeConstantString ||
1933 Builtin == Builtin::BI__builtin___NSStringMakeConstantString ||
1934 Builtin == Builtin::BI__builtin_ptrauth_sign_constant ||
1935 Builtin == Builtin::BI__builtin_function_start);
1939 const auto *BaseExpr =
1940 llvm::dyn_cast_if_present<CallExpr>(LVal.Base.
dyn_cast<
const Expr *>());
1955 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
1956 return VD->hasGlobalStorage();
1972 case Expr::CompoundLiteralExprClass: {
1976 case Expr::MaterializeTemporaryExprClass:
1981 case Expr::StringLiteralClass:
1982 case Expr::PredefinedExprClass:
1983 case Expr::ObjCStringLiteralClass:
1984 case Expr::ObjCEncodeExprClass:
1986 case Expr::ObjCBoxedExprClass:
1987 case Expr::ObjCArrayLiteralClass:
1988 case Expr::ObjCDictionaryLiteralClass:
1990 case Expr::CallExprClass:
1993 case Expr::AddrLabelExprClass:
1997 case Expr::BlockExprClass:
2001 case Expr::SourceLocExprClass:
2003 case Expr::ImplicitValueInitExprClass:
2028 const auto *BaseExpr = LVal.Base.
dyn_cast<
const Expr *>();
2033 if (
const auto *EE = dyn_cast<ObjCEncodeExpr>(BaseExpr)) {
2034 Info.Ctx.getObjCEncodingForType(EE->getEncodedType(),
2042 const auto *Lit = dyn_cast<StringLiteral>(BaseExpr);
2043 if (
const auto *PE = dyn_cast<PredefinedExpr>(BaseExpr))
2044 Lit = PE->getFunctionName();
2049 AsString.
Bytes = Lit->getBytes();
2050 AsString.
CharWidth = Lit->getCharByteWidth();
2070 const LValue &RHS) {
2079 CharUnits Offset = RHS.Offset - LHS.Offset;
2080 if (Offset.isNegative()) {
2081 if (LHSString.
Bytes.size() < (
size_t)-Offset.getQuantity())
2083 LHSString.
Bytes = LHSString.
Bytes.drop_front(-Offset.getQuantity());
2085 if (RHSString.
Bytes.size() < (
size_t)Offset.getQuantity())
2087 RHSString.
Bytes = RHSString.
Bytes.drop_front(Offset.getQuantity());
2090 bool LHSIsLonger = LHSString.
Bytes.size() > RHSString.
Bytes.size();
2091 StringRef Longer = LHSIsLonger ? LHSString.
Bytes : RHSString.
Bytes;
2092 StringRef Shorter = LHSIsLonger ? RHSString.
Bytes : LHSString.
Bytes;
2093 int ShorterCharWidth = (LHSIsLonger ? RHSString : LHSString).CharWidth;
2098 for (
int NullByte : llvm::seq(ShorterCharWidth)) {
2099 if (Shorter.size() + NullByte >= Longer.size())
2101 if (Longer[Shorter.size() + NullByte])
2107 return Shorter == Longer.take_front(Shorter.size());
2117 if (isa_and_nonnull<VarDecl>(
Decl)) {
2127 if (!A.getLValueBase())
2128 return !B.getLValueBase();
2129 if (!B.getLValueBase())
2132 if (A.getLValueBase().getOpaqueValue() !=
2133 B.getLValueBase().getOpaqueValue())
2136 return A.getLValueCallIndex() == B.getLValueCallIndex() &&
2137 A.getLValueVersion() == B.getLValueVersion();
2141 assert(
Base &&
"no location for a null lvalue");
2147 if (
auto *PVD = dyn_cast_or_null<ParmVarDecl>(VD)) {
2149 for (CallStackFrame *F = Info.CurrentCall; F; F = F->Caller) {
2150 if (F->Arguments.CallIndex ==
Base.getCallIndex() &&
2151 F->Arguments.Version ==
Base.getVersion() && F->Callee &&
2152 Idx < F->Callee->getNumParams()) {
2153 VD = F->Callee->getParamDecl(Idx);
2160 Info.Note(VD->
getLocation(), diag::note_declared_at);
2162 Info.Note(E->
getExprLoc(), diag::note_constexpr_temporary_here);
2165 if (std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA))
2166 Info.Note((*Alloc)->AllocExpr->getExprLoc(),
2167 diag::note_constexpr_dynamic_alloc_here);
2200 const SubobjectDesignator &
Designator = LVal.getLValueDesignator();
2208 if (isTemplateArgument(Kind)) {
2209 int InvalidBaseKind = -1;
2212 InvalidBaseKind = 0;
2213 else if (isa_and_nonnull<StringLiteral>(BaseE))
2214 InvalidBaseKind = 1;
2215 else if (isa_and_nonnull<MaterializeTemporaryExpr>(BaseE) ||
2216 isa_and_nonnull<LifetimeExtendedTemporaryDecl>(BaseVD))
2217 InvalidBaseKind = 2;
2218 else if (
auto *PE = dyn_cast_or_null<PredefinedExpr>(BaseE)) {
2219 InvalidBaseKind = 3;
2220 Ident = PE->getIdentKindName();
2223 if (InvalidBaseKind != -1) {
2224 Info.FFDiag(Loc, diag::note_constexpr_invalid_template_arg)
2225 << IsReferenceType << !
Designator.Entries.empty() << InvalidBaseKind
2231 if (
auto *FD = dyn_cast_or_null<FunctionDecl>(BaseVD);
2232 FD && FD->isImmediateFunction()) {
2233 Info.FFDiag(Loc, diag::note_consteval_address_accessible)
2235 Info.Note(FD->getLocation(), diag::note_declared_at);
2243 if (Info.getLangOpts().CPlusPlus11) {
2244 Info.FFDiag(Loc, diag::note_constexpr_non_global, 1)
2245 << IsReferenceType << !
Designator.Entries.empty() << !!BaseVD
2247 auto *VarD = dyn_cast_or_null<VarDecl>(BaseVD);
2248 if (VarD && VarD->isConstexpr()) {
2254 Info.Note(VarD->getLocation(), diag::note_constexpr_not_static)
2266 assert((Info.checkingPotentialConstantExpression() ||
2267 LVal.getLValueCallIndex() == 0) &&
2268 "have call index for global lvalue");
2270 if (LVal.allowConstexprUnknown()) {
2272 Info.FFDiag(Loc, diag::note_constexpr_var_init_non_constant, 1) << BaseVD;
2281 Info.FFDiag(Loc, diag::note_constexpr_dynamic_alloc)
2282 << IsReferenceType << !
Designator.Entries.empty();
2288 if (
const VarDecl *Var = dyn_cast<const VarDecl>(BaseVD)) {
2290 if (Var->getTLSKind())
2298 if (!isForManglingOnly(Kind) && Var->hasAttr<DLLImportAttr>() &&
2299 !Var->isStaticLocal())
2304 if (Info.getLangOpts().CUDA && Info.getLangOpts().CUDAIsDevice &&
2305 Info.Ctx.CUDAConstantEvalCtx.NoWrongSidedVars) {
2306 if ((!Var->hasAttr<CUDADeviceAttr>() &&
2307 !Var->hasAttr<CUDAConstantAttr>() &&
2308 !Var->getType()->isCUDADeviceBuiltinSurfaceType() &&
2309 !Var->getType()->isCUDADeviceBuiltinTextureType()) ||
2310 Var->hasAttr<HIPManagedAttr>())
2314 if (
const auto *FD = dyn_cast<const FunctionDecl>(BaseVD)) {
2325 if (Info.getLangOpts().CPlusPlus && !isForManglingOnly(Kind) &&
2326 FD->hasAttr<DLLImportAttr>())
2330 }
else if (
const auto *MTE =
2331 dyn_cast_or_null<MaterializeTemporaryExpr>(BaseE)) {
2332 if (CheckedTemps.insert(MTE).second) {
2335 Info.FFDiag(MTE->getExprLoc(),
2336 diag::note_constexpr_unsupported_temporary_nontrivial_dtor)
2341 APValue *
V = MTE->getOrCreateValue(
false);
2342 assert(
V &&
"evasluation result refers to uninitialised temporary");
2344 Info, MTE->getExprLoc(), TempType, *
V, Kind,
2345 nullptr, CheckedTemps))
2352 if (!IsReferenceType)
2364 Info.FFDiag(Loc, diag::note_constexpr_past_end, 1)
2365 << !
Designator.Entries.empty() << !!BaseVD << BaseVD;
2380 const auto *FD = dyn_cast_or_null<CXXMethodDecl>(
Member);
2383 if (FD->isImmediateFunction()) {
2384 Info.FFDiag(Loc, diag::note_consteval_address_accessible) << 0;
2385 Info.Note(FD->getLocation(), diag::note_declared_at);
2388 return isForManglingOnly(Kind) || FD->isVirtual() ||
2389 !FD->hasAttr<DLLImportAttr>();
2395 const LValue *
This =
nullptr) {
2397 if (Info.getLangOpts().CPlusPlus23)
2416 if (
This && Info.EvaluatingDecl ==
This->getLValueBase())
2420 if (Info.getLangOpts().CPlusPlus11)
2421 Info.FFDiag(E, diag::note_constexpr_nonliteral)
2424 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
2435 if (SubobjectDecl) {
2436 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
2437 << 1 << SubobjectDecl;
2439 diag::note_constexpr_subobject_declared_here);
2441 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
2450 Type = AT->getValueType();
2455 if (
Value.isArray()) {
2457 for (
unsigned I = 0, N =
Value.getArrayInitializedElts(); I != N; ++I) {
2459 Value.getArrayInitializedElt(I), Kind,
2460 SubobjectDecl, CheckedTemps))
2463 if (!
Value.hasArrayFiller())
2466 Value.getArrayFiller(), Kind, SubobjectDecl,
2469 if (
Value.isUnion() &&
Value.getUnionField()) {
2472 Value.getUnionValue(), Kind,
Value.getUnionField(), CheckedTemps);
2474 if (
Value.isStruct()) {
2476 if (
const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {
2477 unsigned BaseIndex = 0;
2479 const APValue &BaseValue =
Value.getStructBase(BaseIndex);
2482 Info.FFDiag(TypeBeginLoc, diag::note_constexpr_uninitialized_base)
2483 << BS.getType() <<
SourceRange(TypeBeginLoc, BS.getEndLoc());
2493 for (
const auto *I : RD->fields()) {
2494 if (I->isUnnamedBitField())
2498 Value.getStructField(I->getFieldIndex()), Kind,
2504 if (
Value.isLValue() &&
2507 LVal.setFrom(Info.Ctx,
Value);
2512 if (
Value.isMemberPointer() &&
2533 nullptr, CheckedTemps);
2543 ConstantExprKind::Normal,
nullptr, CheckedTemps);
2549 if (!Info.HeapAllocs.empty()) {
2553 Info.CCEDiag(Info.HeapAllocs.begin()->second.AllocExpr,
2554 diag::note_constexpr_memory_leak)
2555 <<
unsigned(Info.HeapAllocs.size() - 1);
2563 if (!
Value.getLValueBase()) {
2565 Result = !
Value.getLValueOffset().isZero();
2583 Result = Val.
getInt().getBoolValue();
2616 llvm_unreachable(
"unknown APValue kind");
2622 assert(E->
isPRValue() &&
"missing lvalue-to-rvalue conv in bool condition");
2631 const T &SrcValue,
QualType DestType) {
2632 Info.CCEDiag(E, diag::note_constexpr_overflow) << SrcValue << DestType;
2633 if (
const auto *OBT = DestType->
getAs<OverflowBehaviorType>();
2634 OBT && OBT->isTrapKind()) {
2637 return Info.noteUndefinedBehavior();
2643 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
2647 Result =
APSInt(DestWidth, !DestSigned);
2649 if (
Value.convertToInteger(Result, llvm::APFloat::rmTowardZero, &ignored)
2650 & APFloat::opInvalidOp)
2661 llvm::RoundingMode RM =
2663 if (RM == llvm::RoundingMode::Dynamic)
2664 RM = llvm::RoundingMode::NearestTiesToEven;
2670 APFloat::opStatus St) {
2673 if (Info.InConstantContext)
2677 if ((St & APFloat::opInexact) &&
2681 Info.FFDiag(E, diag::note_constexpr_dynamic_rounding);
2685 if ((St != APFloat::opOK) &&
2688 FPO.getAllowFEnvAccess())) {
2689 Info.FFDiag(E, diag::note_constexpr_float_arithmetic_strict);
2693 if ((St & APFloat::opStatus::opInvalidOp) &&
2714 "HandleFloatToFloatCast has been checked with only CastExpr, "
2715 "CompoundAssignOperator and ConvertVectorExpr. Please either validate "
2716 "the new expression or address the root cause of this usage.");
2718 APFloat::opStatus St;
2719 APFloat
Value = Result;
2721 St = Result.convert(Info.Ctx.getFloatTypeSemantics(DestType), RM, &ignored);
2728 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
2734 Result =
Value.getBoolValue();
2741 QualType DestType, APFloat &Result) {
2742 Result = APFloat(Info.Ctx.getFloatTypeSemantics(DestType), 1);
2744 APFloat::opStatus St = Result.convertFromAPInt(
Value,
Value.isSigned(), RM);
2750 assert(FD->
isBitField() &&
"truncateBitfieldValue on non-bitfield");
2752 if (!
Value.isInt()) {
2756 assert(
Value.isLValue() &&
"integral value neither int nor lvalue?");
2762 unsigned OldBitWidth = Int.getBitWidth();
2764 if (NewBitWidth < OldBitWidth)
2765 Int = Int.trunc(NewBitWidth).extend(OldBitWidth);
2772template<
typename Operation>
2775 unsigned BitWidth, Operation Op,
2777 if (LHS.isUnsigned()) {
2778 Result = Op(LHS, RHS);
2782 APSInt Value(Op(LHS.extend(BitWidth), RHS.extend(BitWidth)),
false);
2783 Result =
Value.trunc(LHS.getBitWidth());
2785 if (Info.checkingForUndefinedBehavior())
2786 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
2787 diag::warn_integer_constant_overflow)
2788 <<
toString(Result, 10, Result.isSigned(),
false,
2800 bool HandleOverflowResult =
true;
2807 std::multiplies<APSInt>(), Result);
2810 std::plus<APSInt>(), Result);
2813 std::minus<APSInt>(), Result);
2814 case BO_And: Result = LHS & RHS;
return true;
2815 case BO_Xor: Result = LHS ^ RHS;
return true;
2816 case BO_Or: Result = LHS | RHS;
return true;
2820 Info.FFDiag(E, diag::note_expr_divide_by_zero)
2826 if (RHS.isNegative() && RHS.isAllOnes() && LHS.isSigned() &&
2827 LHS.isMinSignedValue())
2829 Info, E, -LHS.extend(LHS.getBitWidth() + 1), E->
getType());
2830 Result = (Opcode == BO_Rem ? LHS % RHS : LHS / RHS);
2831 return HandleOverflowResult;
2833 if (Info.getLangOpts().OpenCL)
2835 RHS &=
APSInt(llvm::APInt(RHS.getBitWidth(),
2836 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2838 else if (RHS.isSigned() && RHS.isNegative()) {
2841 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
2842 if (!Info.noteUndefinedBehavior())
2850 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
2852 Info.CCEDiag(E, diag::note_constexpr_large_shift)
2853 << RHS << E->
getType() << LHS.getBitWidth();
2854 if (!Info.noteUndefinedBehavior())
2856 }
else if (LHS.isSigned() && !Info.getLangOpts().CPlusPlus20) {
2861 if (LHS.isNegative()) {
2862 Info.CCEDiag(E, diag::note_constexpr_lshift_of_negative) << LHS;
2863 if (!Info.noteUndefinedBehavior())
2865 }
else if (LHS.countl_zero() < SA) {
2866 Info.CCEDiag(E, diag::note_constexpr_lshift_discards);
2867 if (!Info.noteUndefinedBehavior())
2875 if (Info.getLangOpts().OpenCL)
2877 RHS &=
APSInt(llvm::APInt(RHS.getBitWidth(),
2878 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2880 else if (RHS.isSigned() && RHS.isNegative()) {
2883 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
2884 if (!Info.noteUndefinedBehavior())
2892 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
2894 Info.CCEDiag(E, diag::note_constexpr_large_shift)
2895 << RHS << E->
getType() << LHS.getBitWidth();
2896 if (!Info.noteUndefinedBehavior())
2904 case BO_LT: Result = LHS < RHS;
return true;
2905 case BO_GT: Result = LHS > RHS;
return true;
2906 case BO_LE: Result = LHS <= RHS;
return true;
2907 case BO_GE: Result = LHS >= RHS;
return true;
2908 case BO_EQ: Result = LHS == RHS;
return true;
2909 case BO_NE: Result = LHS != RHS;
return true;
2911 llvm_unreachable(
"BO_Cmp should be handled elsewhere");
2918 const APFloat &RHS) {
2920 APFloat::opStatus St;
2926 St = LHS.multiply(RHS, RM);
2929 St = LHS.add(RHS, RM);
2932 St = LHS.subtract(RHS, RM);
2938 Info.CCEDiag(E, diag::note_expr_divide_by_zero);
2939 St = LHS.divide(RHS, RM);
2948 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << LHS.isNaN();
2949 return Info.noteUndefinedBehavior();
2957 const APInt &RHSValue, APInt &Result) {
2958 bool LHS = (LHSValue != 0);
2959 bool RHS = (RHSValue != 0);
2961 if (Opcode == BO_LAnd)
2962 Result = LHS && RHS;
2964 Result = LHS || RHS;
2969 const APFloat &RHSValue, APInt &Result) {
2970 bool LHS = !LHSValue.isZero();
2971 bool RHS = !RHSValue.isZero();
2973 if (Opcode == BO_LAnd)
2974 Result = LHS && RHS;
2976 Result = LHS || RHS;
2982 const APValue &RHSValue, APInt &Result) {
2986 RHSValue.
getInt(), Result);
2992template <
typename APTy>
2995 const APTy &RHSValue, APInt &Result) {
2998 llvm_unreachable(
"unsupported binary operator");
3000 Result = (LHSValue == RHSValue);
3003 Result = (LHSValue != RHSValue);
3006 Result = (LHSValue < RHSValue);
3009 Result = (LHSValue > RHSValue);
3012 Result = (LHSValue <= RHSValue);
3015 Result = (LHSValue >= RHSValue);
3029 const APValue &RHSValue, APInt &Result) {
3033 RHSValue.
getInt(), Result);
3044 assert(Opcode != BO_PtrMemD && Opcode != BO_PtrMemI &&
3045 "Operation not supported on vector types");
3049 QualType EltTy = VT->getElementType();
3056 "A vector result that isn't a vector OR uncalculated LValue");
3062 RHSValue.
getVectorLength() == NumElements &&
"Different vector sizes");
3066 for (
unsigned EltNum = 0; EltNum < NumElements; ++EltNum) {
3071 APSInt EltResult{Info.Ctx.getIntWidth(EltTy),
3081 RHSElt.
getInt(), EltResult);
3087 ResultElements.emplace_back(EltResult);
3092 "Mismatched LHS/RHS/Result Type");
3093 APFloat LHSFloat = LHSElt.
getFloat();
3101 ResultElements.emplace_back(LHSFloat);
3105 LHSValue =
APValue(ResultElements.data(), ResultElements.size());
3113 unsigned TruncatedElements) {
3114 SubobjectDesignator &D = Result.Designator;
3117 if (TruncatedElements == D.Entries.size())
3119 assert(TruncatedElements >= D.MostDerivedPathLength &&
3120 "not casting to a derived class");
3126 for (
unsigned I = TruncatedElements, N = D.Entries.size(); I != N; ++I) {
3130 if (isVirtualBaseClass(D.Entries[I]))
3136 D.Entries.resize(TruncatedElements);
3146 RL = &Info.Ctx.getASTRecordLayout(Derived);
3149 Obj.addDecl(Info, E,
Base,
false);
3150 Obj.getLValueOffset() += RL->getBaseClassOffset(
Base);
3159 if (!
Base->isVirtual())
3162 SubobjectDesignator &D = Obj.Designator;
3177 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(DerivedDecl);
3178 Obj.addDecl(Info, E, BaseDecl,
true);
3187 PathI != PathE; ++PathI) {
3191 Type = (*PathI)->getType();
3203 llvm_unreachable(
"Class must be derived from the passed in base class!");
3218 RL = &Info.Ctx.getASTRecordLayout(FD->
getParent());
3222 LVal.addDecl(Info, E, FD);
3223 LVal.adjustOffset(Info.Ctx.toCharUnitsFromBits(RL->getFieldOffset(I)));
3231 for (
const auto *
C : IFD->
chain())
3265 Size = Info.Ctx.getTypeSizeInChars(
Type);
3267 Size = Info.Ctx.getTypeInfoDataSizeInChars(
Type).Width;
3284 LVal.adjustOffsetAndIndex(Info, E, Adjustment, SizeOfPointee);
3290 int64_t Adjustment) {
3292 APSInt::get(Adjustment));
3307 LVal.Offset += SizeOfComponent;
3309 LVal.addComplex(Info, E, EltTy, Imag);
3315 uint64_t Size, uint64_t Idx) {
3320 LVal.Offset += SizeOfElement * Idx;
3322 LVal.addVectorElement(Info, E, EltTy, Size, Idx);
3336 const VarDecl *VD, CallStackFrame *Frame,
3337 unsigned Version,
APValue *&Result) {
3340 bool AllowConstexprUnknown =
3345 auto CheckUninitReference = [&](
bool IsLocalVariable) {
3357 if (!AllowConstexprUnknown || IsLocalVariable) {
3358 if (!Info.checkingPotentialConstantExpression())
3359 Info.FFDiag(E, diag::note_constexpr_use_uninit_reference);
3369 Result = Frame->getTemporary(VD, Version);
3371 return CheckUninitReference(
true);
3380 "missing value for local variable");
3381 if (Info.checkingPotentialConstantExpression())
3385 "A variable in a frame should either be a local or a parameter");
3391 if (Info.EvaluatingDecl ==
Base) {
3392 Result = Info.EvaluatingDeclValue;
3393 return CheckUninitReference(
false);
3401 if (AllowConstexprUnknown) {
3408 if (!Info.checkingPotentialConstantExpression() ||
3409 !Info.CurrentCall->Callee ||
3411 if (Info.getLangOpts().CPlusPlus11) {
3412 Info.FFDiag(E, diag::note_constexpr_function_param_value_unknown)
3433 if (!
Init && !AllowConstexprUnknown) {
3436 if (!Info.checkingPotentialConstantExpression()) {
3437 Info.FFDiag(E, diag::note_constexpr_var_init_unknown, 1)
3448 if (
Init &&
Init->isValueDependent()) {
3455 if (!Info.checkingPotentialConstantExpression()) {
3456 Info.FFDiag(E, Info.getLangOpts().CPlusPlus11
3457 ? diag::note_constexpr_ltor_non_constexpr
3458 : diag::note_constexpr_ltor_non_integral, 1)
3472 Info.FFDiag(E, diag::note_constexpr_var_init_non_constant, 1) << VD;
3488 !AllowConstexprUnknown) ||
3489 ((Info.getLangOpts().CPlusPlus || Info.getLangOpts().OpenCL) &&
3492 Info.CCEDiag(E, diag::note_constexpr_var_init_non_constant, 1) << VD;
3502 Info.FFDiag(E, diag::note_constexpr_var_init_weak) << VD;
3509 if (!Result && !AllowConstexprUnknown)
3512 return CheckUninitReference(
false);
3522 E = Derived->
bases_end(); I != E; ++I, ++Index) {
3523 if (I->getType()->getAsCXXRecordDecl()->getCanonicalDecl() ==
Base)
3527 llvm_unreachable(
"base class missing from derived class's bases list");
3534 "SourceLocExpr should have already been converted to a StringLiteral");
3537 if (
const auto *ObjCEnc = dyn_cast<ObjCEncodeExpr>(Lit)) {
3539 Info.Ctx.getObjCEncodingForType(ObjCEnc->getEncodedType(), Str);
3540 assert(Index <= Str.size() &&
"Index too large");
3541 return APSInt::getUnsigned(Str.c_str()[Index]);
3544 if (
auto PE = dyn_cast<PredefinedExpr>(Lit))
3545 Lit = PE->getFunctionName();
3548 Info.Ctx.getAsConstantArrayType(S->
getType());
3549 assert(CAT &&
"string literal isn't an array");
3551 assert(CharType->
isIntegerType() &&
"unexpected character type");
3554 if (Index < S->getLength())
3567 AllocType.isNull() ? S->
getType() : AllocType);
3568 assert(CAT &&
"string literal isn't an array");
3570 assert(CharType->
isIntegerType() &&
"unexpected character type");
3577 if (Result.hasArrayFiller())
3579 for (
unsigned I = 0, N = Result.getArrayInitializedElts(); I != N; ++I) {
3587 unsigned Size = Array.getArraySize();
3588 assert(Index < Size);
3591 unsigned OldElts = Array.getArrayInitializedElts();
3592 unsigned NewElts = std::max(Index+1, OldElts * 2);
3593 NewElts = std::min(Size, std::max(NewElts, 8u));
3597 for (
unsigned I = 0; I != OldElts; ++I)
3599 for (
unsigned I = OldElts; I != NewElts; ++I)
3603 Array.
swap(NewValue);
3610 Vec =
APValue(Elts.data(), Elts.size());
3620 CXXRecordDecl *RD = T->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
3631 for (
auto *Field : RD->
fields())
3632 if (!Field->isUnnamedBitField() &&
3636 for (
auto &BaseSpec : RD->
bases())
3647 CXXRecordDecl *RD = T->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
3654 for (
auto *Field : RD->
fields()) {
3659 if (Field->isMutable() &&
3661 Info.FFDiag(E, diag::note_constexpr_access_mutable, 1) << AK << Field;
3662 Info.Note(Field->getLocation(), diag::note_declared_at);
3670 for (
auto &BaseSpec : RD->
bases())
3680 bool MutableSubobject =
false) {
3685 switch (Info.IsEvaluatingDecl) {
3686 case EvalInfo::EvaluatingDeclKind::None:
3689 case EvalInfo::EvaluatingDeclKind::Ctor:
3691 if (Info.EvaluatingDecl ==
Base)
3696 if (
auto *BaseE =
Base.dyn_cast<
const Expr *>())
3697 if (
auto *BaseMTE = dyn_cast<MaterializeTemporaryExpr>(BaseE))
3698 return Info.EvaluatingDecl == BaseMTE->getExtendingDecl();
3701 case EvalInfo::EvaluatingDeclKind::Dtor:
3706 if (MutableSubobject ||
Base != Info.EvaluatingDecl)
3712 return T.isConstQualified() || T->isReferenceType();
3715 llvm_unreachable(
"unknown evaluating decl kind");
3720 return Info.CheckArraySize(
3740 uint64_t IntResult = BoolResult;
3743 : Info.Ctx.getIntTypeForBitwidth(64,
false);
3744 Result =
APValue(Info.Ctx.MakeIntValue(IntResult, IntType));
3749 Info.Ctx.getIntTypeForBitwidth(64,
false),
3750 Result.getInt(), DestTy, Result2.
getFloat()))
3752 Result = std::move(Result2);
3758 Result =
APValue(APFloat(0.0));
3760 DestTy, Result.getFloat());
3766 uint64_t IntResult = BoolResult;
3767 Result =
APValue(Info.Ctx.MakeIntValue(IntResult, DestTy));
3785 uint64_t IntResult = BoolResult;
3786 Result =
APValue(Info.Ctx.MakeIntValue(IntResult, DestTy));
3792 DestTy, Result.getInt());
3796 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
3809 {&Result, ResultType, 0}};
3812 while (!WorkList.empty() && ElI < Elements.size()) {
3813 auto [Res,
Type, BitWidth] = WorkList.pop_back_val();
3829 APSInt &Int = Res->getInt();
3830 unsigned OldBitWidth = Int.getBitWidth();
3831 unsigned NewBitWidth = BitWidth;
3832 if (NewBitWidth < OldBitWidth)
3833 Int = Int.trunc(NewBitWidth).extend(OldBitWidth);
3842 for (
unsigned I = 0; I < NumEl; ++I) {
3848 *Res =
APValue(Vals.data(), NumEl);
3857 for (int64_t I = Size - 1; I > -1; --I)
3858 WorkList.emplace_back(&Res->getArrayInitializedElt(I), ElTy, 0u);
3864 unsigned NumBases = 0;
3865 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
3866 NumBases = CXXRD->getNumBases();
3873 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
3874 if (CXXRD->getNumBases() > 0) {
3875 assert(CXXRD->getNumBases() == 1);
3877 ReverseList.emplace_back(&Res->getStructBase(0), BS.
getType(), 0u);
3884 if (FD->isUnnamedBitField())
3886 if (FD->isBitField()) {
3887 FDBW = FD->getBitWidthValue();
3890 ReverseList.emplace_back(&Res->getStructField(FD->getFieldIndex()),
3891 FD->getType(), FDBW);
3894 std::reverse(ReverseList.begin(), ReverseList.end());
3895 llvm::append_range(WorkList, ReverseList);
3898 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
3911 assert((Elements.size() == SrcTypes.size()) &&
3912 (Elements.size() == DestTypes.size()));
3914 for (
unsigned I = 0, ESz = Elements.size(); I < ESz; ++I) {
3915 APValue Original = Elements[I];
3919 if (!
handleScalarCast(Info, FPO, E, SourceTy, DestTy, Original, Results[I]))
3930 while (!WorkList.empty()) {
3953 for (uint64_t I = 0; I < ArrSize; ++I) {
3954 WorkList.push_back(ElTy);
3962 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
3963 if (CXXRD->getNumBases() > 0) {
3964 assert(CXXRD->getNumBases() == 1);
3966 WorkList.push_back(BS.
getType());
3972 if (FD->isUnnamedBitField())
3974 WorkList.push_back(FD->getType());
3991 "Not a valid HLSLAggregateSplatCast.");
4011 unsigned Populated = 0;
4012 while (!WorkList.empty() && Populated < Size) {
4013 auto [Work,
Type] = WorkList.pop_back_val();
4015 if (Work.isFloat() || Work.isInt()) {
4016 Elements.push_back(Work);
4017 Types.push_back(
Type);
4021 if (Work.isVector()) {
4024 for (
unsigned I = 0; I < Work.getVectorLength() && Populated < Size;
4026 Elements.push_back(Work.getVectorElt(I));
4027 Types.push_back(ElTy);
4032 if (Work.isMatrix()) {
4035 QualType ElTy = MT->getElementType();
4037 for (
unsigned Row = 0; Row < Work.getMatrixNumRows() && Populated < Size;
4039 for (
unsigned Col = 0;
4040 Col < Work.getMatrixNumColumns() && Populated < Size; Col++) {
4041 Elements.push_back(Work.getMatrixElt(Row, Col));
4042 Types.push_back(ElTy);
4048 if (Work.isArray()) {
4052 for (int64_t I = Work.getArraySize() - 1; I > -1; --I) {
4053 WorkList.emplace_back(Work.getArrayInitializedElt(I), ElTy);
4058 if (Work.isStruct()) {
4066 if (FD->isUnnamedBitField())
4068 ReverseList.emplace_back(Work.getStructField(FD->getFieldIndex()),
4072 std::reverse(ReverseList.begin(), ReverseList.end());
4073 llvm::append_range(WorkList, ReverseList);
4076 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4077 if (CXXRD->getNumBases() > 0) {
4078 assert(CXXRD->getNumBases() == 1);
4083 if (!
Base.isStruct())
4091 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
4100struct CompleteObject {
4102 APValue::LValueBase
Base;
4112 bool mayAccessMutableMembers(EvalInfo &Info,
AccessKinds AK)
const {
4123 if (!Info.getLangOpts().CPlusPlus14 &&
4124 AK != AccessKinds::AK_IsWithinLifetime)
4129 explicit operator bool()
const {
return !
Type.isNull(); }
4134 bool IsMutable =
false) {
4148template <
typename Sub
objectHandler>
4149static typename SubobjectHandler::result_type
4151 const SubobjectDesignator &Sub, SubobjectHandler &handler) {
4154 return handler.failed();
4155 if (Sub.isOnePastTheEnd() || Sub.isMostDerivedAnUnsizedArray()) {
4156 if (Info.getLangOpts().CPlusPlus11)
4157 Info.FFDiag(E, Sub.isOnePastTheEnd()
4158 ? diag::note_constexpr_access_past_end
4159 : diag::note_constexpr_access_unsized_array)
4160 << handler.AccessKind;
4163 return handler.failed();
4169 const FieldDecl *VolatileField =
nullptr;
4172 for (
unsigned I = 0, N = Sub.Entries.size(); ; ++I) {
4183 if (!Info.checkingPotentialConstantExpression())
4184 Info.FFDiag(E, diag::note_constexpr_access_uninit)
4187 return handler.failed();
4195 Info.isEvaluatingCtorDtor(
4196 Obj.Base,
ArrayRef(Sub.Entries.begin(), Sub.Entries.begin() + I)) !=
4197 ConstructionPhase::None) {
4198 ObjType = Info.Ctx.getCanonicalType(ObjType);
4207 if (Info.getLangOpts().CPlusPlus) {
4211 if (VolatileField) {
4214 Decl = VolatileField;
4217 Loc = VD->getLocation();
4224 Info.FFDiag(E, diag::note_constexpr_access_volatile_obj, 1)
4225 << handler.AccessKind << DiagKind <<
Decl;
4226 Info.Note(Loc, diag::note_constexpr_volatile_here) << DiagKind;
4228 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
4230 return handler.failed();
4238 !Obj.mayAccessMutableMembers(Info, handler.AccessKind) &&
4240 return handler.failed();
4244 if (!handler.found(*O, ObjType))
4256 LastField =
nullptr;
4259 const ArrayType *AT = Info.Ctx.getAsArrayType(ObjType);
4261 "vla in literal type?");
4262 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4263 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT);
4264 CAT && CAT->
getSize().ule(Index)) {
4267 if (Info.getLangOpts().CPlusPlus11)
4268 Info.FFDiag(E, diag::note_constexpr_access_past_end)
4269 << handler.AccessKind;
4272 return handler.failed();
4279 else if (!
isRead(handler.AccessKind)) {
4280 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT);
4282 return handler.failed();
4290 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4292 if (Info.getLangOpts().CPlusPlus11)
4293 Info.FFDiag(E, diag::note_constexpr_access_past_end)
4294 << handler.AccessKind;
4297 return handler.failed();
4303 assert(I == N - 1 &&
"extracting subobject of scalar?");
4313 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4314 unsigned NumElements = VT->getNumElements();
4315 if (Index == NumElements) {
4316 if (Info.getLangOpts().CPlusPlus11)
4317 Info.FFDiag(E, diag::note_constexpr_access_past_end)
4318 << handler.AccessKind;
4321 return handler.failed();
4324 if (Index > NumElements) {
4325 Info.CCEDiag(E, diag::note_constexpr_array_index)
4326 << Index << 0 << NumElements;
4327 return handler.failed();
4330 ObjType = VT->getElementType();
4331 assert(I == N - 1 &&
"extracting subobject of scalar?");
4334 if (
isRead(handler.AccessKind)) {
4336 return handler.failed();
4340 assert(O->
isVector() &&
"unexpected object during vector element access");
4342 }
else if (
const FieldDecl *Field = getAsField(Sub.Entries[I])) {
4343 if (Field->isMutable() &&
4344 !Obj.mayAccessMutableMembers(Info, handler.AccessKind)) {
4345 Info.FFDiag(E, diag::note_constexpr_access_mutable, 1)
4346 << handler.AccessKind << Field;
4347 Info.Note(Field->getLocation(), diag::note_declared_at);
4348 return handler.failed();
4357 if (I == N - 1 && handler.AccessKind ==
AK_Construct) {
4368 Info.FFDiag(E, diag::note_constexpr_access_inactive_union_member)
4369 << handler.AccessKind << Field << !UnionField << UnionField;
4370 return handler.failed();
4379 if (Field->getType().isVolatileQualified())
4380 VolatileField = Field;
4393struct ExtractSubobjectHandler {
4399 typedef bool result_type;
4400 bool failed() {
return false; }
4401 bool found(
APValue &Subobj, QualType SubobjType) {
4411 bool found(APFloat &
Value, QualType SubobjType) {
4420 const CompleteObject &Obj,
4421 const SubobjectDesignator &Sub,
APValue &Result,
4424 ExtractSubobjectHandler Handler = {Info, E, Result, AK};
4429struct ModifySubobjectHandler {
4434 typedef bool result_type;
4437 bool checkConst(QualType QT) {
4440 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
4446 bool failed() {
return false; }
4447 bool found(
APValue &Subobj, QualType SubobjType) {
4448 if (!checkConst(SubobjType))
4451 Subobj.
swap(NewVal);
4455 if (!checkConst(SubobjType))
4457 if (!NewVal.
isInt()) {
4465 bool found(APFloat &
Value, QualType SubobjType) {
4466 if (!checkConst(SubobjType))
4474const AccessKinds ModifySubobjectHandler::AccessKind;
4478 const CompleteObject &Obj,
4479 const SubobjectDesignator &Sub,
4481 ModifySubobjectHandler Handler = { Info, NewVal, E };
4488 const SubobjectDesignator &A,
4489 const SubobjectDesignator &B,
4490 bool &WasArrayIndex) {
4491 unsigned I = 0, N = std::min(A.Entries.size(), B.Entries.size());
4492 for (; I != N; ++I) {
4496 if (A.Entries[I].getAsArrayIndex() != B.Entries[I].getAsArrayIndex()) {
4497 WasArrayIndex =
true;
4505 if (A.Entries[I].getAsBaseOrMember() !=
4506 B.Entries[I].getAsBaseOrMember()) {
4507 WasArrayIndex =
false;
4510 if (
const FieldDecl *FD = getAsField(A.Entries[I]))
4512 ObjType = FD->getType();
4518 WasArrayIndex =
false;
4525 const SubobjectDesignator &A,
4526 const SubobjectDesignator &B) {
4527 if (A.Entries.size() != B.Entries.size())
4530 bool IsArray = A.MostDerivedIsArrayElement;
4531 if (IsArray && A.MostDerivedPathLength != A.Entries.size())
4540 return CommonLength >= A.Entries.size() - IsArray;
4547 if (LVal.InvalidBase) {
4549 return CompleteObject();
4554 Info.FFDiag(E, diag::note_constexpr_dereferencing_null);
4556 Info.FFDiag(E, diag::note_constexpr_access_null) << AK;
4557 return CompleteObject();
4560 CallStackFrame *Frame =
nullptr;
4562 if (LVal.getLValueCallIndex()) {
4563 std::tie(Frame, Depth) =
4564 Info.getCallFrameAndDepth(LVal.getLValueCallIndex());
4566 Info.FFDiag(E, diag::note_constexpr_access_uninit, 1)
4569 return CompleteObject();
4580 if (Info.getLangOpts().CPlusPlus)
4581 Info.FFDiag(E, diag::note_constexpr_access_volatile_type)
4585 return CompleteObject();
4592 if (Info.getLangOpts().CPlusPlus14 && LVal.Base == Info.EvaluatingDecl &&
4596 BaseVal = Info.EvaluatingDeclValue;
4599 if (
auto *GD = dyn_cast<MSGuidDecl>(D)) {
4602 Info.FFDiag(E, diag::note_constexpr_modify_global);
4603 return CompleteObject();
4607 Info.FFDiag(E, diag::note_constexpr_unsupported_layout)
4609 return CompleteObject();
4611 return CompleteObject(LVal.Base, &
V, GD->getType());
4615 if (
auto *GCD = dyn_cast<UnnamedGlobalConstantDecl>(D)) {
4617 Info.FFDiag(E, diag::note_constexpr_modify_global);
4618 return CompleteObject();
4620 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&GCD->getValue()),
4625 if (
auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
4627 Info.FFDiag(E, diag::note_constexpr_modify_global);
4628 return CompleteObject();
4630 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&TPO->getValue()),
4641 const VarDecl *VD = dyn_cast<VarDecl>(D);
4648 return CompleteObject();
4651 bool IsConstant = BaseType.isConstant(Info.Ctx);
4652 bool ConstexprVar =
false;
4653 if (
const auto *VD = dyn_cast_if_present<VarDecl>(
4665 }
else if (Info.getLangOpts().CPlusPlus14 &&
4672 Info.FFDiag(E, diag::note_constexpr_modify_global);
4673 return CompleteObject();
4676 }
else if (Info.getLangOpts().C23 && ConstexprVar) {
4678 return CompleteObject();
4679 }
else if (BaseType->isIntegralOrEnumerationType()) {
4682 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4683 if (Info.getLangOpts().CPlusPlus) {
4684 Info.FFDiag(E, diag::note_constexpr_ltor_non_const_int, 1) << VD;
4685 Info.Note(VD->
getLocation(), diag::note_declared_at);
4689 return CompleteObject();
4691 }
else if (!IsAccess) {
4692 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4693 }
else if ((IsConstant || BaseType->isReferenceType()) &&
4694 Info.checkingPotentialConstantExpression() &&
4695 BaseType->isLiteralType(Info.Ctx) && !VD->
hasDefinition()) {
4697 }
else if (IsConstant) {
4701 if (Info.getLangOpts().CPlusPlus) {
4702 Info.CCEDiag(E, Info.getLangOpts().CPlusPlus11
4703 ? diag::note_constexpr_ltor_non_constexpr
4704 : diag::note_constexpr_ltor_non_integral, 1)
4706 Info.Note(VD->
getLocation(), diag::note_declared_at);
4712 if (Info.getLangOpts().CPlusPlus) {
4713 Info.FFDiag(E, Info.getLangOpts().CPlusPlus11
4714 ? diag::note_constexpr_ltor_non_constexpr
4715 : diag::note_constexpr_ltor_non_integral, 1)
4717 Info.Note(VD->
getLocation(), diag::note_declared_at);
4721 return CompleteObject();
4730 return CompleteObject();
4735 if (!Info.checkingPotentialConstantExpression()) {
4736 Info.FFDiag(E, diag::note_constexpr_access_unknown_variable, 1)
4738 Info.Note(VD->getLocation(), diag::note_declared_at);
4740 return CompleteObject();
4743 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
4745 Info.FFDiag(E, diag::note_constexpr_access_deleted_object) << AK;
4746 return CompleteObject();
4748 return CompleteObject(LVal.Base, &(*Alloc)->Value,
4758 dyn_cast_or_null<MaterializeTemporaryExpr>(
Base)) {
4759 assert(MTE->getStorageDuration() ==
SD_Static &&
4760 "should have a frame for a non-global materialized temporary");
4787 if (!MTE->isUsableInConstantExpressions(Info.Ctx) &&
4790 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4791 Info.FFDiag(E, diag::note_constexpr_access_static_temporary, 1) << AK;
4792 Info.Note(MTE->getExprLoc(), diag::note_constexpr_temporary_here);
4793 return CompleteObject();
4796 BaseVal = MTE->getOrCreateValue(
false);
4797 assert(BaseVal &&
"got reference to unevaluated temporary");
4799 dyn_cast_or_null<CompoundLiteralExpr>(
Base)) {
4815 !CLETy.isConstant(Info.Ctx)) {
4817 Info.Note(CLE->getExprLoc(), diag::note_declared_at);
4818 return CompleteObject();
4821 BaseVal = &CLE->getStaticValue();
4824 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4827 Info.FFDiag(E, diag::note_constexpr_access_unreadable_object)
4830 Info.Ctx.getLValueReferenceType(LValType));
4832 return CompleteObject();
4836 assert(BaseVal &&
"missing value for temporary");
4847 unsigned VisibleDepth = Depth;
4848 if (llvm::isa_and_nonnull<ParmVarDecl>(
4851 if ((Frame && Info.getLangOpts().CPlusPlus14 &&
4852 Info.EvalStatus.HasSideEffects) ||
4853 (
isModification(AK) && VisibleDepth < Info.SpeculativeEvaluationDepth))
4854 return CompleteObject();
4856 return CompleteObject(LVal.getLValueBase(), BaseVal, BaseType);
4875 const LValue &LVal,
APValue &RVal,
4876 bool WantObjectRepresentation =
false) {
4877 if (LVal.Designator.Invalid)
4886 if (
Base && !LVal.getLValueCallIndex() && !
Type.isVolatileQualified()) {
4890 assert(LVal.Designator.Entries.size() <= 1 &&
4891 "Can only read characters from string literals");
4892 if (LVal.Designator.Entries.empty()) {
4899 if (LVal.Designator.isOnePastTheEnd()) {
4900 if (Info.getLangOpts().CPlusPlus11)
4901 Info.FFDiag(Conv, diag::note_constexpr_access_past_end) << AK;
4906 uint64_t CharIndex = LVal.Designator.Entries[0].getAsArrayIndex();
4913 return Obj &&
extractSubobject(Info, Conv, Obj, LVal.Designator, RVal, AK);
4927 LVal.setFrom(Info.Ctx, Val);
4943 if (LVal.Designator.Invalid)
4946 if (!Info.getLangOpts().CPlusPlus14) {
4956struct CompoundAssignSubobjectHandler {
4958 const CompoundAssignOperator *E;
4959 QualType PromotedLHSType;
4965 typedef bool result_type;
4967 bool checkConst(QualType QT) {
4970 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
4976 bool failed() {
return false; }
4977 bool found(
APValue &Subobj, QualType SubobjType) {
4980 return found(Subobj.
getInt(), SubobjType);
4982 return found(Subobj.
getFloat(), SubobjType);
4989 return foundPointer(Subobj, SubobjType);
4991 return foundVector(Subobj, SubobjType);
4993 Info.FFDiag(E, diag::note_constexpr_access_uninit)
5004 bool foundVector(
APValue &
Value, QualType SubobjType) {
5005 if (!checkConst(SubobjType))
5016 if (!checkConst(SubobjType))
5035 Info.Ctx.getLangOpts());
5038 PromotedLHSType, FValue) &&
5047 bool found(APFloat &
Value, QualType SubobjType) {
5048 return checkConst(SubobjType) &&
5054 bool foundPointer(
APValue &Subobj, QualType SubobjType) {
5055 if (!checkConst(SubobjType))
5058 QualType PointeeType;
5059 if (
const PointerType *PT = SubobjType->
getAs<PointerType>())
5063 (Opcode != BO_Add && Opcode != BO_Sub)) {
5069 if (Opcode == BO_Sub)
5073 LVal.setFrom(Info.Ctx, Subobj);
5076 LVal.moveInto(Subobj);
5082const AccessKinds CompoundAssignSubobjectHandler::AccessKind;
5087 const LValue &LVal,
QualType LValType,
5091 if (LVal.Designator.Invalid)
5094 if (!Info.getLangOpts().CPlusPlus14) {
5100 CompoundAssignSubobjectHandler Handler = { Info, E, PromotedLValType, Opcode,
5102 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
5106struct IncDecSubobjectHandler {
5108 const UnaryOperator *E;
5112 typedef bool result_type;
5114 bool checkConst(QualType QT) {
5117 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
5123 bool failed() {
return false; }
5124 bool found(
APValue &Subobj, QualType SubobjType) {
5134 return found(Subobj.
getInt(), SubobjType);
5136 return found(Subobj.
getFloat(), SubobjType);
5139 SubobjType->
castAs<ComplexType>()->getElementType()
5143 SubobjType->
castAs<ComplexType>()->getElementType()
5146 return foundPointer(Subobj, SubobjType);
5154 if (!checkConst(SubobjType))
5176 bool WasNegative =
Value.isNegative();
5190 unsigned BitWidth =
Value.getBitWidth();
5191 APSInt ActualValue(
Value.sext(BitWidth + 1),
false);
5192 ActualValue.setBit(BitWidth);
5198 bool found(APFloat &
Value, QualType SubobjType) {
5199 if (!checkConst(SubobjType))
5206 APFloat::opStatus St;
5208 St =
Value.add(One, RM);
5210 St =
Value.subtract(One, RM);
5213 bool foundPointer(
APValue &Subobj, QualType SubobjType) {
5214 if (!checkConst(SubobjType))
5217 QualType PointeeType;
5218 if (
const PointerType *PT = SubobjType->
getAs<PointerType>())
5226 LVal.setFrom(Info.Ctx, Subobj);
5230 LVal.moveInto(Subobj);
5239 if (LVal.Designator.Invalid)
5242 if (!Info.getLangOpts().CPlusPlus14) {
5250 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
5256 if (Object->getType()->isPointerType() && Object->isPRValue())
5259 if (Object->isGLValue())
5262 if (Object->getType()->isLiteralType(Info.Ctx))
5265 if (Object->getType()->isRecordType() && Object->isPRValue())
5268 Info.FFDiag(Object, diag::note_constexpr_nonliteral) << Object->getType();
5287 bool IncludeMember =
true) {
5294 if (!MemPtr.getDecl()) {
5300 if (MemPtr.isDerivedMember()) {
5307 if (LV.Designator.MostDerivedPathLength + MemPtr.Path.size() >
5308 LV.Designator.Entries.size()) {
5312 unsigned PathLengthToMember =
5313 LV.Designator.Entries.size() - MemPtr.Path.size();
5314 for (
unsigned I = 0, N = MemPtr.Path.size(); I != N; ++I) {
5316 LV.Designator.Entries[PathLengthToMember + I]);
5333 (PathLengthToMember > LV.Designator.MostDerivedPathLength)
5334 ? getAsBaseClass(LV.Designator.Entries[PathLengthToMember - 1])
5336 const CXXRecordDecl *LastMPDecl = MemPtr.getContainingRecord();
5344 PathLengthToMember))
5346 }
else if (!MemPtr.Path.empty()) {
5348 LV.Designator.Entries.reserve(LV.Designator.Entries.size() +
5349 MemPtr.Path.size() + IncludeMember);
5355 assert(RD &&
"member pointer access on non-class-type expression");
5357 for (
unsigned I = 1, N = MemPtr.Path.size(); I != N; ++I) {
5365 MemPtr.getContainingRecord()))
5370 if (IncludeMember) {
5371 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(MemPtr.getDecl())) {
5375 dyn_cast<IndirectFieldDecl>(MemPtr.getDecl())) {
5379 llvm_unreachable(
"can't construct reference to bound member function");
5383 return MemPtr.getDecl();
5389 bool IncludeMember =
true) {
5393 if (Info.noteFailure()) {
5401 BO->
getRHS(), IncludeMember);
5408 SubobjectDesignator &D = Result.Designator;
5409 if (D.Invalid || !Result.checkNullPointer(Info, E,
CSK_Derived))
5416 auto InvalidCast = [&]() {
5417 if (!Info.checkingPotentialConstantExpression() ||
5418 !Result.AllowConstexprUnknown) {
5419 Info.CCEDiag(E, diag::note_constexpr_invalid_downcast)
5420 << D.MostDerivedType << TargetQT;
5426 if (D.MostDerivedPathLength + E->
path_size() > D.Entries.size())
5427 return InvalidCast();
5431 unsigned NewEntriesSize = D.Entries.size() - E->
path_size();
5434 if (NewEntriesSize == D.MostDerivedPathLength)
5437 FinalType = getAsBaseClass(D.Entries[NewEntriesSize - 1]);
5439 return InvalidCast();
5451 if (!Result.isAbsent())
5454 if (
auto *RD = T->getAsCXXRecordDecl()) {
5455 if (RD->isInvalidDecl()) {
5459 if (RD->isUnion()) {
5468 End = RD->bases_end();
5469 I != End; ++I, ++Index)
5473 for (
const auto *I : RD->fields()) {
5474 if (I->isUnnamedBitField())
5477 I->getType(), Result.getStructField(I->getFieldIndex()));
5483 dyn_cast_or_null<ConstantArrayType>(T->getAsArrayTypeUnsafe())) {
5485 if (Result.hasArrayFiller())
5497enum EvalStmtResult {
5526 if (!Result.Designator.Invalid && Result.Designator.isOnePastTheEnd()) {
5532 Result.moveInto(Val);
5544 APValue &Val = Info.CurrentCall->createTemporary(VD, VD->
getType(),
5545 ScopeKind::Block, Result);
5550 return Info.noteSideEffect();
5571 const DecompositionDecl *DD);
5574 bool EvaluateConditionDecl =
false) {
5576 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
5580 EvaluateConditionDecl && DD)
5590 if (
auto *VD = BD->getHoldingVar())
5598 if (
auto *DD = dyn_cast_if_present<DecompositionDecl>(VD)) {
5607 if (Info.noteSideEffect())
5609 assert(E->
containsErrors() &&
"valid value-dependent expression should never "
5610 "reach invalid code path.");
5617 if (
Cond->isValueDependent())
5619 FullExpressionRAII
Scope(Info);
5626 return Scope.destroy();
5639struct TempVersionRAII {
5640 CallStackFrame &Frame;
5642 TempVersionRAII(CallStackFrame &Frame) : Frame(Frame) {
5643 Frame.pushTempVersion();
5646 ~TempVersionRAII() {
5647 Frame.popTempVersion();
5655 const SwitchCase *SC =
nullptr);
5661 const Stmt *LoopOrSwitch,
5663 EvalStmtResult &ESR) {
5667 if (!IsSwitch && ESR == ESR_Succeeded) {
5672 if (ESR != ESR_Break && ESR != ESR_Continue)
5676 bool CanBreakOrContinue = !IsSwitch || ESR == ESR_Break;
5677 const Stmt *StackTop = Info.BreakContinueStack.back();
5678 if (CanBreakOrContinue && (StackTop ==
nullptr || StackTop == LoopOrSwitch)) {
5679 Info.BreakContinueStack.pop_back();
5680 if (ESR == ESR_Break)
5681 ESR = ESR_Succeeded;
5686 for (BlockScopeRAII *S : Scopes) {
5687 if (!S->destroy()) {
5699 BlockScopeRAII
Scope(Info);
5701 EvalStmtResult ESR =
EvaluateStmt(Result, Info, Body, Case);
5702 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5711 BlockScopeRAII
Scope(Info);
5718 if (ESR != ESR_Succeeded) {
5719 if (ESR != ESR_Failed && !
Scope.destroy())
5725 FullExpressionRAII CondScope(Info);
5740 if (!CondScope.destroy())
5761 if (LHSValue <=
Value &&
Value <= RHSValue) {
5768 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5772 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5779 llvm_unreachable(
"Should have been converted to Succeeded");
5785 case ESR_CaseNotFound:
5788 Info.FFDiag(
Found->getBeginLoc(),
5789 diag::note_constexpr_stmt_expr_unsupported);
5792 llvm_unreachable(
"Invalid EvalStmtResult!");
5802 Info.CCEDiag(VD->
getLocation(), diag::note_constexpr_static_local)
5812 if (!Info.nextStep(S))
5819 case Stmt::CompoundStmtClass:
5823 case Stmt::LabelStmtClass:
5824 case Stmt::AttributedStmtClass:
5825 case Stmt::DoStmtClass:
5828 case Stmt::CaseStmtClass:
5829 case Stmt::DefaultStmtClass:
5834 case Stmt::IfStmtClass: {
5841 BlockScopeRAII
Scope(Info);
5847 if (ESR != ESR_CaseNotFound) {
5848 assert(ESR != ESR_Succeeded);
5859 if (ESR == ESR_Failed)
5861 if (ESR != ESR_CaseNotFound)
5862 return Scope.destroy() ? ESR : ESR_Failed;
5864 return ESR_CaseNotFound;
5867 if (ESR == ESR_Failed)
5869 if (ESR != ESR_CaseNotFound)
5870 return Scope.destroy() ? ESR : ESR_Failed;
5871 return ESR_CaseNotFound;
5874 case Stmt::WhileStmtClass: {
5875 EvalStmtResult ESR =
5879 if (ESR != ESR_Continue)
5884 case Stmt::ForStmtClass: {
5886 BlockScopeRAII
Scope(Info);
5892 if (ESR != ESR_CaseNotFound) {
5893 assert(ESR != ESR_Succeeded);
5898 EvalStmtResult ESR =
5902 if (ESR != ESR_Continue)
5904 if (
const auto *Inc = FS->
getInc()) {
5905 if (Inc->isValueDependent()) {
5909 FullExpressionRAII IncScope(Info);
5917 case Stmt::DeclStmtClass: {
5921 for (
const auto *D : DS->
decls()) {
5922 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
5925 if (VD->hasLocalStorage() && !VD->getInit())
5933 return ESR_CaseNotFound;
5937 return ESR_CaseNotFound;
5943 if (
const Expr *E = dyn_cast<Expr>(S)) {
5952 FullExpressionRAII
Scope(Info);
5956 return ESR_Succeeded;
5962 case Stmt::NullStmtClass:
5963 return ESR_Succeeded;
5965 case Stmt::DeclStmtClass: {
5967 for (
const auto *D : DS->
decls()) {
5968 const VarDecl *VD = dyn_cast_or_null<VarDecl>(D);
5972 FullExpressionRAII
Scope(Info);
5974 !Info.noteFailure())
5976 if (!
Scope.destroy())
5979 return ESR_Succeeded;
5982 case Stmt::ReturnStmtClass: {
5984 FullExpressionRAII
Scope(Info);
5993 :
Evaluate(Result.Value, Info, RetExpr)))
5995 return Scope.destroy() ? ESR_Returned : ESR_Failed;
5998 case Stmt::CompoundStmtClass: {
5999 BlockScopeRAII
Scope(Info);
6002 for (
const auto *BI : CS->
body()) {
6003 EvalStmtResult ESR =
EvaluateStmt(Result, Info, BI, Case);
6004 if (ESR == ESR_Succeeded)
6006 else if (ESR != ESR_CaseNotFound) {
6007 if (ESR != ESR_Failed && !
Scope.destroy())
6013 return ESR_CaseNotFound;
6014 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
6017 case Stmt::IfStmtClass: {
6021 BlockScopeRAII
Scope(Info);
6024 if (ESR != ESR_Succeeded) {
6025 if (ESR != ESR_Failed && !
Scope.destroy())
6035 if (!Info.InConstantContext)
6042 EvalStmtResult ESR =
EvaluateStmt(Result, Info, SubStmt);
6043 if (ESR != ESR_Succeeded) {
6044 if (ESR != ESR_Failed && !
Scope.destroy())
6049 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
6052 case Stmt::WhileStmtClass: {
6055 BlockScopeRAII
Scope(Info);
6067 if (ESR != ESR_Continue) {
6068 if (ESR != ESR_Failed && !
Scope.destroy())
6072 if (!
Scope.destroy())
6075 return ESR_Succeeded;
6078 case Stmt::DoStmtClass: {
6085 if (ESR != ESR_Continue)
6094 FullExpressionRAII CondScope(Info);
6096 !CondScope.destroy())
6099 return ESR_Succeeded;
6102 case Stmt::ForStmtClass: {
6104 BlockScopeRAII ForScope(Info);
6107 if (ESR != ESR_Succeeded) {
6108 if (ESR != ESR_Failed && !ForScope.destroy())
6114 BlockScopeRAII IterScope(Info);
6115 bool Continue =
true;
6121 if (!IterScope.destroy())
6129 if (ESR != ESR_Continue) {
6130 if (ESR != ESR_Failed && (!IterScope.destroy() || !ForScope.destroy()))
6135 if (
const auto *Inc = FS->
getInc()) {
6136 if (Inc->isValueDependent()) {
6140 FullExpressionRAII IncScope(Info);
6146 if (!IterScope.destroy())
6149 return ForScope.destroy() ? ESR_Succeeded : ESR_Failed;
6152 case Stmt::CXXForRangeStmtClass: {
6154 BlockScopeRAII
Scope(Info);
6159 if (ESR != ESR_Succeeded) {
6160 if (ESR != ESR_Failed && !
Scope.destroy())
6168 if (ESR != ESR_Succeeded) {
6169 if (ESR != ESR_Failed && !
Scope.destroy())
6181 if (ESR != ESR_Succeeded) {
6182 if (ESR != ESR_Failed && !
Scope.destroy())
6187 if (ESR != ESR_Succeeded) {
6188 if (ESR != ESR_Failed && !
Scope.destroy())
6201 bool Continue =
true;
6202 FullExpressionRAII CondExpr(Info);
6210 BlockScopeRAII InnerScope(Info);
6212 if (ESR != ESR_Succeeded) {
6213 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
6222 if (ESR != ESR_Continue) {
6223 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
6236 if (!InnerScope.destroy())
6240 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
6243 case Stmt::SwitchStmtClass:
6246 case Stmt::ContinueStmtClass:
6247 case Stmt::BreakStmtClass: {
6249 Info.BreakContinueStack.push_back(B->getNamedLoopOrSwitch());
6253 case Stmt::LabelStmtClass:
6256 case Stmt::AttributedStmtClass: {
6258 const auto *SS = AS->getSubStmt();
6259 MSConstexprContextRAII ConstexprContext(
6263 auto LO = Info.Ctx.getLangOpts();
6264 if (LO.CXXAssumptions && !LO.MSVCCompat) {
6265 for (
auto *
Attr : AS->getAttrs()) {
6266 auto *AA = dyn_cast<CXXAssumeAttr>(
Attr);
6270 auto *Assumption = AA->getAssumption();
6271 if (Assumption->isValueDependent())
6274 if (Assumption->HasSideEffects(Info.Ctx))
6281 Info.CCEDiag(Assumption->getExprLoc(),
6282 diag::note_constexpr_assumption_failed);
6291 case Stmt::CaseStmtClass:
6292 case Stmt::DefaultStmtClass:
6294 case Stmt::CXXTryStmtClass:
6306 bool IsValueInitialization) {
6313 if (!CD->
isConstexpr() && !IsValueInitialization) {
6314 if (Info.getLangOpts().CPlusPlus11) {
6317 Info.CCEDiag(Loc, diag::note_constexpr_invalid_function, 1)
6319 Info.Note(CD->
getLocation(), diag::note_declared_at);
6321 Info.CCEDiag(Loc, diag::note_invalid_subexpr_in_const_expr);
6335 if (Info.checkingPotentialConstantExpression() && !
Definition &&
6343 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6352 Info.CCEDiag(CallLoc, diag::note_constexpr_virtual_call);
6355 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6361 (
Definition->isConstexpr() || (Info.CurrentCall->CanEvalMSConstexpr &&
6371 StringRef Name = DiagDecl->
getName();
6373 Name ==
"__assert_rtn" || Name ==
"__assert_fail" || Name ==
"_wassert";
6375 Info.FFDiag(CallLoc, diag::note_constexpr_assert_failed);
6380 if (Info.getLangOpts().CPlusPlus11) {
6383 auto *CD = dyn_cast<CXXConstructorDecl>(DiagDecl);
6384 if (CD && CD->isInheritingConstructor()) {
6385 auto *Inherited = CD->getInheritedConstructor().getConstructor();
6386 if (!Inherited->isConstexpr())
6387 DiagDecl = CD = Inherited;
6393 if (CD && CD->isInheritingConstructor())
6394 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_inhctor, 1)
6395 << CD->getInheritedConstructor().getConstructor()->getParent();
6397 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_function, 1)
6399 Info.Note(DiagDecl->
getLocation(), diag::note_declared_at);
6401 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6407struct CheckDynamicTypeHandler {
6409 typedef bool result_type;
6410 bool failed() {
return false; }
6411 bool found(
APValue &Subobj, QualType SubobjType) {
return true; }
6412 bool found(
APSInt &
Value, QualType SubobjType) {
return true; }
6413 bool found(APFloat &
Value, QualType SubobjType) {
return true; }
6421 if (
This.Designator.Invalid)
6433 if (
This.Designator.isOnePastTheEnd() ||
6434 This.Designator.isMostDerivedAnUnsizedArray()) {
6435 Info.FFDiag(E,
This.Designator.isOnePastTheEnd()
6436 ? diag::note_constexpr_access_past_end
6437 : diag::note_constexpr_access_unsized_array)
6440 }
else if (Polymorphic) {
6443 if (!Info.checkingPotentialConstantExpression() ||
6444 !
This.AllowConstexprUnknown) {
6448 Info.Ctx.getLValueReferenceType(
This.Designator.getType(Info.Ctx));
6449 Info.FFDiag(E, diag::note_constexpr_polymorphic_unknown_dynamic_type)
6457 CheckDynamicTypeHandler Handler{AK};
6480 unsigned PathLength) {
6481 assert(PathLength >=
Designator.MostDerivedPathLength && PathLength <=
6482 Designator.Entries.size() &&
"invalid path length");
6483 return (PathLength ==
Designator.MostDerivedPathLength)
6484 ?
Designator.MostDerivedType->getAsCXXRecordDecl()
6485 : getAsBaseClass(
Designator.Entries[PathLength - 1]);
6498 return std::nullopt;
6500 if (
This.Designator.Invalid)
6501 return std::nullopt;
6510 This.Designator.MostDerivedType->getAsCXXRecordDecl();
6511 if (!Class || Class->getNumVBases()) {
6513 return std::nullopt;
6521 for (
unsigned PathLength =
This.Designator.MostDerivedPathLength;
6522 PathLength <= Path.size(); ++PathLength) {
6523 switch (Info.isEvaluatingCtorDtor(
This.getLValueBase(),
6524 Path.slice(0, PathLength))) {
6525 case ConstructionPhase::Bases:
6526 case ConstructionPhase::DestroyingBases:
6531 case ConstructionPhase::None:
6532 case ConstructionPhase::AfterBases:
6533 case ConstructionPhase::AfterFields:
6534 case ConstructionPhase::Destroying:
6546 return std::nullopt;
6564 unsigned PathLength = DynType->PathLength;
6565 for (; PathLength <=
This.Designator.Entries.size(); ++PathLength) {
6568 Found->getCorrespondingMethodDeclaredInClass(Class,
false);
6578 if (Callee->isPureVirtual()) {
6579 Info.FFDiag(E, diag::note_constexpr_pure_virtual_call, 1) << Callee;
6580 Info.Note(Callee->getLocation(), diag::note_declared_at);
6586 if (!Info.Ctx.hasSameUnqualifiedType(Callee->getReturnType(),
6587 Found->getReturnType())) {
6588 CovariantAdjustmentPath.push_back(Callee->getReturnType());
6589 for (
unsigned CovariantPathLength = PathLength + 1;
6590 CovariantPathLength !=
This.Designator.Entries.size();
6591 ++CovariantPathLength) {
6595 Found->getCorrespondingMethodDeclaredInClass(NextClass,
false);
6596 if (
Next && !Info.Ctx.hasSameUnqualifiedType(
6597 Next->getReturnType(), CovariantAdjustmentPath.back()))
6598 CovariantAdjustmentPath.push_back(
Next->getReturnType());
6600 if (!Info.Ctx.hasSameUnqualifiedType(
Found->getReturnType(),
6601 CovariantAdjustmentPath.back()))
6602 CovariantAdjustmentPath.push_back(
Found->getReturnType());
6618 assert(Result.isLValue() &&
6619 "unexpected kind of APValue for covariant return");
6620 if (Result.isNullPointer())
6624 LVal.setFrom(Info.Ctx, Result);
6626 const CXXRecordDecl *OldClass = Path[0]->getPointeeCXXRecordDecl();
6627 for (
unsigned I = 1; I != Path.size(); ++I) {
6628 const CXXRecordDecl *NewClass = Path[I]->getPointeeCXXRecordDecl();
6629 assert(OldClass && NewClass &&
"unexpected kind of covariant return");
6630 if (OldClass != NewClass &&
6633 OldClass = NewClass;
6636 LVal.moveInto(Result);
6645 auto *BaseClass = BaseSpec.getType()->getAsCXXRecordDecl();
6647 return BaseSpec.getAccessSpecifier() ==
AS_public;
6649 llvm_unreachable(
"Base is not a direct base of Derived");
6659 SubobjectDesignator &D = Ptr.Designator;
6665 if (Ptr.isNullPointer() && !E->
isGLValue())
6671 std::optional<DynamicType> DynType =
6683 assert(
C &&
"dynamic_cast target is not void pointer nor class");
6691 Ptr.setNull(Info.Ctx, E->
getType());
6698 DynType->Type->isDerivedFrom(
C)))
6700 else if (!Paths || Paths->begin() == Paths->end())
6702 else if (Paths->isAmbiguous(CQT))
6705 assert(Paths->front().Access !=
AS_public &&
"why did the cast fail?");
6708 Info.FFDiag(E, diag::note_constexpr_dynamic_cast_to_reference_failed)
6709 << DiagKind << Ptr.Designator.getType(Info.Ctx)
6710 << Info.Ctx.getCanonicalTagType(DynType->Type)
6718 for (
int PathLength = Ptr.Designator.Entries.size();
6719 PathLength >= (
int)DynType->PathLength; --PathLength) {
6724 if (PathLength > (
int)DynType->PathLength &&
6727 return RuntimeCheckFailed(
nullptr);
6734 if (DynType->Type->isDerivedFrom(
C, Paths) && !Paths.
isAmbiguous(CQT) &&
6747 return RuntimeCheckFailed(&Paths);
6751struct StartLifetimeOfUnionMemberHandler {
6753 const Expr *LHSExpr;
6754 const FieldDecl *
Field;
6756 bool Failed =
false;
6759 typedef bool result_type;
6760 bool failed() {
return Failed; }
6761 bool found(
APValue &Subobj, QualType SubobjType) {
6776 }
else if (DuringInit) {
6780 Info.FFDiag(LHSExpr,
6781 diag::note_constexpr_union_member_change_during_init);
6790 llvm_unreachable(
"wrong value kind for union object");
6792 bool found(APFloat &
Value, QualType SubobjType) {
6793 llvm_unreachable(
"wrong value kind for union object");
6798const AccessKinds StartLifetimeOfUnionMemberHandler::AccessKind;
6805 const Expr *LHSExpr,
6806 const LValue &LHS) {
6807 if (LHS.InvalidBase || LHS.Designator.Invalid)
6813 unsigned PathLength = LHS.Designator.Entries.size();
6814 for (
const Expr *E = LHSExpr; E !=
nullptr;) {
6816 if (
auto *ME = dyn_cast<MemberExpr>(E)) {
6817 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
6820 if (!FD || FD->getType()->isReferenceType())
6824 if (FD->getParent()->isUnion()) {
6829 FD->getType()->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
6830 if (!RD || RD->hasTrivialDefaultConstructor())
6831 UnionPathLengths.push_back({PathLength - 1, FD});
6837 LHS.Designator.Entries[PathLength]
6838 .getAsBaseOrMember().getPointer()));
6842 }
else if (
auto *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
6844 auto *
Base = ASE->getBase()->IgnoreImplicit();
6845 if (!
Base->getType()->isArrayType())
6851 }
else if (
auto *ICE = dyn_cast<ImplicitCastExpr>(E)) {
6854 if (ICE->getCastKind() == CK_NoOp)
6856 if (ICE->getCastKind() != CK_DerivedToBase &&
6857 ICE->getCastKind() != CK_UncheckedDerivedToBase)
6861 if (Elt->isVirtual()) {
6870 LHS.Designator.Entries[PathLength]
6871 .getAsBaseOrMember().getPointer()));
6881 if (UnionPathLengths.empty())
6886 CompleteObject Obj =
6890 for (std::pair<unsigned, const FieldDecl *> LengthAndField :
6891 llvm::reverse(UnionPathLengths)) {
6893 SubobjectDesignator D = LHS.Designator;
6894 D.truncate(Info.Ctx, LHS.Base, LengthAndField.first);
6896 bool DuringInit = Info.isEvaluatingCtorDtor(LHS.Base, D.Entries) ==
6897 ConstructionPhase::AfterBases;
6898 StartLifetimeOfUnionMemberHandler StartLifetime{
6899 Info, LHSExpr, LengthAndField.second, DuringInit};
6908 CallRef
Call, EvalInfo &Info,
bool NonNull =
false,
6909 APValue **EvaluatedArg =
nullptr) {
6916 APValue &
V = PVD ? Info.CurrentCall->createParam(
Call, PVD, LV)
6917 : Info.CurrentCall->createTemporary(Arg, Arg->
getType(),
6918 ScopeKind::Call, LV);
6924 if (
NonNull &&
V.isLValue() &&
V.isNullPointer()) {
6925 Info.CCEDiag(Arg, diag::note_non_null_attribute_failed);
6938 bool RightToLeft =
false,
6939 LValue *ObjectArg =
nullptr) {
6941 llvm::SmallBitVector ForbiddenNullArgs;
6942 if (Callee->hasAttr<NonNullAttr>()) {
6943 ForbiddenNullArgs.resize(Args.size());
6944 for (
const auto *
Attr : Callee->specific_attrs<NonNullAttr>()) {
6945 if (!
Attr->args_size()) {
6946 ForbiddenNullArgs.set();
6949 for (
auto Idx :
Attr->args()) {
6950 unsigned ASTIdx = Idx.getASTIndex();
6951 if (ASTIdx >= Args.size())
6953 ForbiddenNullArgs[ASTIdx] =
true;
6957 for (
unsigned I = 0; I < Args.size(); I++) {
6958 unsigned Idx = RightToLeft ? Args.size() - I - 1 : I;
6960 Idx < Callee->getNumParams() ? Callee->getParamDecl(Idx) :
nullptr;
6961 bool NonNull = !ForbiddenNullArgs.empty() && ForbiddenNullArgs[Idx];
6966 if (!Info.noteFailure())
6971 ObjectArg->setFrom(Info.Ctx, *That);
6980 bool CopyObjectRepresentation) {
6982 CallStackFrame *Frame = Info.CurrentCall;
6983 APValue *RefValue = Info.getParamSlot(Frame->Arguments, Param);
6991 RefLValue.setFrom(Info.Ctx, *RefValue);
6994 CopyObjectRepresentation);
7000 const LValue *ObjectArg,
const Expr *E,
7002 const Stmt *Body, EvalInfo &Info,
7003 APValue &Result,
const LValue *ResultSlot) {
7004 if (!Info.CheckCallLimit(CallLoc))
7033 ObjectArg->moveInto(Result);
7042 if (!Info.checkingPotentialConstantExpression())
7044 Frame.LambdaThisCaptureField);
7047 StmtResult Ret = {Result, ResultSlot};
7049 if (ESR == ESR_Succeeded) {
7050 if (Callee->getReturnType()->isVoidType())
7052 Info.FFDiag(Callee->getEndLoc(), diag::note_constexpr_no_return);
7054 return ESR == ESR_Returned;
7061 EvalInfo &Info,
APValue &Result) {
7063 if (!Info.CheckCallLimit(CallLoc))
7068 Info.FFDiag(CallLoc, diag::note_constexpr_virtual_base) << RD;
7072 EvalInfo::EvaluatingConstructorRAII EvalObj(
7074 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries},
7081 StmtResult Ret = {RetVal,
nullptr};
7086 if ((*I)->getInit()->isValueDependent()) {
7090 FullExpressionRAII InitScope(Info);
7092 !InitScope.destroy())
7115 if (!Result.hasValue()) {
7128 BlockScopeRAII LifetimeExtendedScope(Info);
7131 unsigned BasesSeen = 0;
7136 auto SkipToField = [&](
FieldDecl *FD,
bool Indirect) {
7141 assert(Indirect &&
"fields out of order?");
7147 assert(FieldIt != RD->
field_end() &&
"missing field?");
7148 if (!FieldIt->isUnnamedBitField())
7151 Result.getStructField(FieldIt->getFieldIndex()));
7156 LValue Subobject =
This;
7157 LValue SubobjectParent =
This;
7162 if (I->isBaseInitializer()) {
7163 QualType BaseType(I->getBaseClass(), 0);
7167 assert(!BaseIt->
isVirtual() &&
"virtual base for literal type");
7168 assert(Info.Ctx.hasSameUnqualifiedType(BaseIt->
getType(), BaseType) &&
7169 "base class initializers not in expected order");
7173 BaseType->getAsCXXRecordDecl(), &Layout))
7175 Value = &Result.getStructBase(BasesSeen++);
7176 }
else if ((FD = I->getMember())) {
7181 Value = &Result.getUnionValue();
7183 SkipToField(FD,
false);
7189 auto IndirectFieldChain = IFD->chain();
7190 for (
auto *
C : IndirectFieldChain) {
7199 (
Value->isUnion() &&
7212 if (
C == IndirectFieldChain.back())
7213 SubobjectParent = Subobject;
7219 if (
C == IndirectFieldChain.front() && !RD->
isUnion())
7220 SkipToField(FD,
true);
7225 llvm_unreachable(
"unknown base initializer kind");
7232 if (
Init->isValueDependent()) {
7236 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &SubobjectParent,
7238 FullExpressionRAII InitScope(Info);
7244 if (!Info.noteFailure())
7253 if (!Info.noteFailure())
7261 if (I->isBaseInitializer() && BasesSeen == RD->
getNumBases())
7262 EvalObj.finishedConstructingBases();
7267 for (; FieldIt != RD->
field_end(); ++FieldIt) {
7268 if (!FieldIt->isUnnamedBitField())
7271 Result.getStructField(FieldIt->getFieldIndex()));
7275 EvalObj.finishedConstructingFields();
7279 LifetimeExtendedScope.destroy();
7285 EvalInfo &Info,
APValue &Result) {
7286 CallScopeRAII CallScope(Info);
7292 CallScope.destroy();
7302 if (
Value.isAbsent() && !T->isNullPtrType()) {
7304 This.moveInto(Printable);
7306 diag::note_constexpr_destroy_out_of_lifetime)
7307 << Printable.
getAsString(Info.Ctx, Info.Ctx.getLValueReferenceType(T));
7323 LValue ElemLV =
This;
7324 ElemLV.addArray(Info, &LocE, CAT);
7331 if (Size && Size >
Value.getArrayInitializedElts())
7336 for (Size =
Value.getArraySize(); Size != 0; --Size) {
7337 APValue &Elem =
Value.getArrayInitializedElt(Size - 1);
7350 if (T.isDestructedType()) {
7352 diag::note_constexpr_unsupported_destruction)
7362 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_virtual_base) << RD;
7387 if (!Info.CheckCallLimit(CallRange.
getBegin()))
7396 CallStackFrame Frame(Info, CallRange,
Definition, &
This,
nullptr,
7401 EvalInfo::EvaluatingDestructorRAII EvalObj(
7403 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries});
7404 if (!EvalObj.DidInsert) {
7411 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_double_destroy);
7418 StmtResult Ret = {RetVal,
nullptr};
7431 for (
const FieldDecl *FD : llvm::reverse(Fields)) {
7432 if (FD->isUnnamedBitField())
7435 LValue Subobject =
This;
7439 APValue *SubobjectValue = &
Value.getStructField(FD->getFieldIndex());
7446 EvalObj.startedDestroyingBases();
7453 LValue Subobject =
This;
7455 BaseType->getAsCXXRecordDecl(), &Layout))
7458 APValue *SubobjectValue = &
Value.getStructBase(BasesLeft);
7463 assert(BasesLeft == 0 &&
"NumBases was wrong?");
7471struct DestroyObjectHandler {
7477 typedef bool result_type;
7478 bool failed() {
return false; }
7479 bool found(
APValue &Subobj, QualType SubobjType) {
7484 Info.FFDiag(E, diag::note_constexpr_destroy_complex_elem);
7487 bool found(APFloat &
Value, QualType SubobjType) {
7488 Info.FFDiag(E, diag::note_constexpr_destroy_complex_elem);
7509 if (Info.EvalStatus.HasSideEffects)
7520 if (Info.checkingPotentialConstantExpression() ||
7521 Info.SpeculativeEvaluationDepth)
7525 auto Caller = Info.getStdAllocatorCaller(
"allocate");
7527 Info.FFDiag(E->
getExprLoc(), Info.getLangOpts().CPlusPlus20
7528 ? diag::note_constexpr_new_untyped
7529 : diag::note_constexpr_new);
7533 QualType ElemType = Caller.ElemType;
7536 diag::note_constexpr_new_not_complete_object_type)
7544 bool IsNothrow =
false;
7545 for (
unsigned I = 1, N = E->
getNumArgs(); I != N; ++I) {
7553 APInt Size, Remainder;
7554 APInt ElemSizeAP(ByteSize.getBitWidth(), ElemSize.
getQuantity());
7555 APInt::udivrem(ByteSize, ElemSizeAP, Size, Remainder);
7556 if (Remainder != 0) {
7558 Info.FFDiag(E->
getExprLoc(), diag::note_constexpr_operator_new_bad_size)
7559 << ByteSize <<
APSInt(ElemSizeAP,
true) << ElemType;
7563 if (!Info.CheckArraySize(E->
getBeginLoc(), ByteSize.getActiveBits(),
7564 Size.getZExtValue(), !IsNothrow)) {
7566 Result.setNull(Info.Ctx, E->
getType());
7572 QualType AllocType = Info.Ctx.getConstantArrayType(
7574 APValue *Val = Info.createHeapAlloc(Caller.Call, AllocType, Result);
7583 return DD->isVirtual();
7590 return DD->isVirtual() ? DD->getOperatorDelete() :
nullptr;
7601 DynAlloc::Kind DeallocKind) {
7602 auto PointerAsString = [&] {
7603 return Pointer.toString(Info.Ctx, Info.Ctx.VoidPtrTy);
7608 Info.FFDiag(E, diag::note_constexpr_delete_not_heap_alloc)
7609 << PointerAsString();
7612 return std::nullopt;
7615 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
7617 Info.FFDiag(E, diag::note_constexpr_double_delete);
7618 return std::nullopt;
7621 if (DeallocKind != (*Alloc)->getKind()) {
7623 Info.FFDiag(E, diag::note_constexpr_new_delete_mismatch)
7624 << DeallocKind << (*Alloc)->getKind() << AllocType;
7626 return std::nullopt;
7629 bool Subobject =
false;
7630 if (DeallocKind == DynAlloc::New) {
7631 Subobject =
Pointer.Designator.MostDerivedPathLength != 0 ||
7632 Pointer.Designator.isOnePastTheEnd();
7634 Subobject =
Pointer.Designator.Entries.size() != 1 ||
7635 Pointer.Designator.Entries[0].getAsArrayIndex() != 0;
7638 Info.FFDiag(E, diag::note_constexpr_delete_subobject)
7639 << PointerAsString() <<
Pointer.Designator.isOnePastTheEnd();
7640 return std::nullopt;
7648 if (Info.checkingPotentialConstantExpression() ||
7649 Info.SpeculativeEvaluationDepth)
7653 if (!Info.getStdAllocatorCaller(
"deallocate")) {
7661 for (
unsigned I = 1, N = E->
getNumArgs(); I != N; ++I)
7664 if (
Pointer.Designator.Invalid)
7669 if (
Pointer.isNullPointer()) {
7670 Info.CCEDiag(E->
getExprLoc(), diag::note_constexpr_deallocate_null);
7686class BitCastBuffer {
7692 SmallVector<std::optional<unsigned char>, 32> Bytes;
7694 static_assert(std::numeric_limits<unsigned char>::digits >= 8,
7695 "Need at least 8 bit unsigned char");
7697 bool TargetIsLittleEndian;
7700 BitCastBuffer(CharUnits Width,
bool TargetIsLittleEndian)
7701 : Bytes(Width.getQuantity()),
7702 TargetIsLittleEndian(TargetIsLittleEndian) {}
7704 [[nodiscard]]
bool readObject(CharUnits Offset, CharUnits Width,
7705 SmallVectorImpl<unsigned char> &Output)
const {
7706 for (CharUnits I = Offset, E = Offset + Width; I != E; ++I) {
7709 if (!Bytes[I.getQuantity()])
7711 Output.push_back(*Bytes[I.getQuantity()]);
7713 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
7714 std::reverse(Output.begin(), Output.end());
7718 void writeObject(CharUnits Offset, SmallVectorImpl<unsigned char> &Input) {
7719 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
7720 std::reverse(Input.begin(), Input.end());
7723 for (
unsigned char Byte : Input) {
7724 assert(!Bytes[Offset.
getQuantity() + Index] &&
"overwriting a byte?");
7730 size_t size() {
return Bytes.size(); }
7735class APValueToBufferConverter {
7737 BitCastBuffer Buffer;
7740 APValueToBufferConverter(EvalInfo &Info, CharUnits ObjectWidth,
7743 Buffer(ObjectWidth, Info.Ctx.getTargetInfo().isLittleEndian()),
7746 bool visit(
const APValue &Val, QualType Ty) {
7751 bool visit(
const APValue &Val, QualType Ty, CharUnits Offset) {
7752 assert((
size_t)Offset.
getQuantity() <= Buffer.size());
7765 return visitInt(Val.
getInt(), Ty, Offset);
7767 return visitFloat(Val.
getFloat(), Ty, Offset);
7769 return visitArray(Val, Ty, Offset);
7771 return visitRecord(Val, Ty, Offset);
7773 return visitVector(Val, Ty, Offset);
7777 return visitComplex(Val, Ty, Offset);
7787 diag::note_constexpr_bit_cast_unsupported_type)
7792 llvm_unreachable(
"Unhandled APValue::ValueKind");
7795 bool visitRecord(
const APValue &Val, QualType Ty, CharUnits Offset) {
7797 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD);
7800 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
7801 for (
size_t I = 0, E = CXXRD->getNumBases(); I != E; ++I) {
7802 const CXXBaseSpecifier &BS = CXXRD->bases_begin()[I];
7807 if (!
Base.isStruct())
7810 if (!visitRecord(Base, BS.
getType(),
7817 unsigned FieldIdx = 0;
7818 for (FieldDecl *FD : RD->
fields()) {
7819 if (FD->isBitField()) {
7821 diag::note_constexpr_bit_cast_unsupported_bitfield);
7827 assert(FieldOffsetBits % Info.Ctx.getCharWidth() == 0 &&
7828 "only bit-fields can have sub-char alignment");
7829 CharUnits FieldOffset =
7830 Info.Ctx.toCharUnitsFromBits(FieldOffsetBits) + Offset;
7831 QualType FieldTy = FD->getType();
7840 bool visitArray(
const APValue &Val, QualType Ty, CharUnits Offset) {
7846 CharUnits ElemWidth = Info.Ctx.getTypeSizeInChars(CAT->
getElementType());
7850 for (
unsigned I = 0; I != NumInitializedElts; ++I) {
7852 if (!visit(SubObj, CAT->
getElementType(), Offset + I * ElemWidth))
7859 for (
unsigned I = NumInitializedElts; I != ArraySize; ++I) {
7860 if (!visit(Filler, CAT->
getElementType(), Offset + I * ElemWidth))
7868 bool visitComplex(
const APValue &Val, QualType Ty, CharUnits Offset) {
7869 const ComplexType *ComplexTy = Ty->
castAs<ComplexType>();
7871 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
7876 Offset + (0 * EltSizeChars)))
7879 Offset + (1 * EltSizeChars)))
7883 Offset + (0 * EltSizeChars)))
7886 Offset + (1 * EltSizeChars)))
7893 bool visitVector(
const APValue &Val, QualType Ty, CharUnits Offset) {
7894 const VectorType *VTy = Ty->
castAs<VectorType>();
7907 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
7909 llvm::APInt Res = llvm::APInt::getZero(NElts);
7910 for (
unsigned I = 0; I < NElts; ++I) {
7912 assert(EltAsInt.isUnsigned() && EltAsInt.getBitWidth() == 1 &&
7913 "bool vector element must be 1-bit unsigned integer!");
7915 Res.insertBits(EltAsInt, BigEndian ? (NElts - I - 1) : I);
7918 SmallVector<uint8_t, 8> Bytes(NElts / 8);
7919 llvm::StoreIntToMemory(Res, &*Bytes.begin(), NElts / 8);
7920 Buffer.writeObject(Offset, Bytes);
7924 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
7925 for (
unsigned I = 0; I < NElts; ++I) {
7926 if (!visit(Val.
getVectorElt(I), EltTy, Offset + I * EltSizeChars))
7934 bool visitInt(
const APSInt &Val, QualType Ty, CharUnits Offset) {
7935 APSInt AdjustedVal = Val;
7936 unsigned Width = AdjustedVal.getBitWidth();
7938 Width = Info.Ctx.getTypeSize(Ty);
7939 AdjustedVal = AdjustedVal.extend(Width);
7942 SmallVector<uint8_t, 8> Bytes(Width / 8);
7943 llvm::StoreIntToMemory(AdjustedVal, &*Bytes.begin(), Width / 8);
7944 Buffer.writeObject(Offset, Bytes);
7948 bool visitFloat(
const APFloat &Val, QualType Ty, CharUnits Offset) {
7949 APSInt AsInt(Val.bitcastToAPInt());
7950 return visitInt(AsInt, Ty, Offset);
7954 static std::optional<BitCastBuffer>
7956 CharUnits DstSize = Info.Ctx.getTypeSizeInChars(BCE->
getType());
7957 APValueToBufferConverter Converter(Info, DstSize, BCE);
7959 return std::nullopt;
7960 return Converter.Buffer;
7965class BufferToAPValueConverter {
7967 const BitCastBuffer &Buffer;
7970 BufferToAPValueConverter(EvalInfo &Info,
const BitCastBuffer &Buffer,
7972 : Info(Info), Buffer(Buffer), BCE(BCE) {}
7977 std::nullopt_t unsupportedType(QualType Ty) {
7979 diag::note_constexpr_bit_cast_unsupported_type)
7981 return std::nullopt;
7984 std::nullopt_t unrepresentableValue(QualType Ty,
const APSInt &Val) {
7986 diag::note_constexpr_bit_cast_unrepresentable_value)
7988 return std::nullopt;
7991 std::optional<APValue> visit(
const BuiltinType *T, CharUnits Offset,
7992 const EnumType *EnumSugar =
nullptr) {
7994 uint64_t NullValue = Info.Ctx.getTargetNullPointerValue(QualType(T, 0));
7995 return APValue((Expr *)
nullptr,
7997 APValue::NoLValuePath{},
true);
8000 CharUnits
SizeOf = Info.Ctx.getTypeSizeInChars(T);
8006 const llvm::fltSemantics &Semantics =
8007 Info.Ctx.getFloatTypeSemantics(QualType(T, 0));
8008 unsigned NumBits = llvm::APFloatBase::getSizeInBits(Semantics);
8009 assert(NumBits % 8 == 0);
8015 SmallVector<uint8_t, 8> Bytes;
8016 if (!Buffer.readObject(Offset,
SizeOf, Bytes)) {
8019 bool IsStdByte = EnumSugar && EnumSugar->isStdByteType();
8023 if (!IsStdByte && !IsUChar) {
8024 QualType DisplayType(EnumSugar ? (
const Type *)EnumSugar : T, 0);
8026 diag::note_constexpr_bit_cast_indet_dest)
8027 << DisplayType << Info.Ctx.getLangOpts().CharIsSigned;
8028 return std::nullopt;
8034 APSInt Val(
SizeOf.getQuantity() * Info.Ctx.getCharWidth(),
true);
8035 llvm::LoadIntFromMemory(Val, &*Bytes.begin(), Bytes.size());
8040 unsigned IntWidth = Info.Ctx.getIntWidth(QualType(T, 0));
8041 if (IntWidth != Val.getBitWidth()) {
8042 APSInt Truncated = Val.trunc(IntWidth);
8043 if (Truncated.extend(Val.getBitWidth()) != Val)
8044 return unrepresentableValue(QualType(T, 0), Val);
8052 const llvm::fltSemantics &Semantics =
8053 Info.Ctx.getFloatTypeSemantics(QualType(T, 0));
8057 return unsupportedType(QualType(T, 0));
8060 std::optional<APValue> visit(
const RecordType *RTy, CharUnits Offset) {
8061 const RecordDecl *RD = RTy->getAsRecordDecl();
8062 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD);
8064 unsigned NumBases = 0;
8065 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
8066 NumBases = CXXRD->getNumBases();
8071 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
8072 for (
size_t I = 0, E = CXXRD->getNumBases(); I != E; ++I) {
8073 const CXXBaseSpecifier &BS = CXXRD->bases_begin()[I];
8076 std::optional<APValue> SubObj = visitType(
8079 return std::nullopt;
8080 ResultVal.getStructBase(I) = *SubObj;
8085 unsigned FieldIdx = 0;
8086 for (FieldDecl *FD : RD->
fields()) {
8089 if (FD->isBitField()) {
8091 diag::note_constexpr_bit_cast_unsupported_bitfield);
8092 return std::nullopt;
8096 assert(FieldOffsetBits % Info.Ctx.getCharWidth() == 0);
8098 CharUnits FieldOffset =
8101 QualType FieldTy = FD->getType();
8102 std::optional<APValue> SubObj = visitType(FieldTy, FieldOffset);
8104 return std::nullopt;
8105 ResultVal.getStructField(FieldIdx) = *SubObj;
8112 std::optional<APValue> visit(
const EnumType *Ty, CharUnits Offset) {
8113 QualType RepresentationType =
8114 Ty->getDecl()->getDefinitionOrSelf()->getIntegerType();
8115 assert(!RepresentationType.
isNull() &&
8116 "enum forward decl should be caught by Sema");
8117 const auto *AsBuiltin =
8121 return visit(AsBuiltin, Offset, Ty);
8124 std::optional<APValue> visit(
const ConstantArrayType *Ty, CharUnits Offset) {
8126 CharUnits ElementWidth = Info.Ctx.getTypeSizeInChars(Ty->
getElementType());
8128 APValue ArrayValue(APValue::UninitArray(), Size, Size);
8129 for (
size_t I = 0; I !=
Size; ++I) {
8130 std::optional<APValue> ElementValue =
8133 return std::nullopt;
8134 ArrayValue.getArrayInitializedElt(I) = std::move(*ElementValue);
8140 std::optional<APValue> visit(
const ComplexType *Ty, CharUnits Offset) {
8142 CharUnits ElementWidth = Info.Ctx.getTypeSizeInChars(ElementType);
8145 std::optional<APValue> Values[2];
8146 for (
unsigned I = 0; I != 2; ++I) {
8147 Values[I] = visitType(Ty->
getElementType(), Offset + I * ElementWidth);
8149 return std::nullopt;
8153 return APValue(Values[0]->getInt(), Values[1]->getInt());
8154 return APValue(Values[0]->getFloat(), Values[1]->getFloat());
8157 std::optional<APValue> visit(
const VectorType *VTy, CharUnits Offset) {
8163 SmallVector<APValue, 4> Elts;
8164 Elts.reserve(NElts);
8174 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
8176 SmallVector<uint8_t, 8> Bytes;
8177 Bytes.reserve(NElts / 8);
8179 return std::nullopt;
8181 APSInt SValInt(NElts,
true);
8182 llvm::LoadIntFromMemory(SValInt, &*Bytes.begin(), Bytes.size());
8184 for (
unsigned I = 0; I < NElts; ++I) {
8186 SValInt.extractBits(1, (BigEndian ? NElts - I - 1 : I) * EltSize);
8193 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
8194 for (
unsigned I = 0; I < NElts; ++I) {
8195 std::optional<APValue> EltValue =
8196 visitType(EltTy, Offset + I * EltSizeChars);
8198 return std::nullopt;
8199 Elts.push_back(std::move(*EltValue));
8203 return APValue(Elts.data(), Elts.size());
8206 std::optional<APValue> visit(
const Type *Ty, CharUnits Offset) {
8207 return unsupportedType(QualType(Ty, 0));
8210 std::optional<APValue> visitType(QualType Ty, CharUnits Offset) {
8214#define TYPE(Class, Base) \
8216 return visit(cast<Class##Type>(Can.getTypePtr()), Offset);
8217#define ABSTRACT_TYPE(Class, Base)
8218#define NON_CANONICAL_TYPE(Class, Base) \
8220 llvm_unreachable("non-canonical type should be impossible!");
8221#define DEPENDENT_TYPE(Class, Base) \
8224 "dependent types aren't supported in the constant evaluator!");
8225#define NON_CANONICAL_UNLESS_DEPENDENT(Class, Base) \
8227 llvm_unreachable("either dependent or not canonical!");
8228#include "clang/AST/TypeNodes.inc"
8230 llvm_unreachable(
"Unhandled Type::TypeClass");
8235 static std::optional<APValue> convert(EvalInfo &Info, BitCastBuffer &Buffer,
8237 BufferToAPValueConverter Converter(Info, Buffer, BCE);
8242static bool checkBitCastConstexprEligibilityType(SourceLocation Loc,
8243 QualType Ty, EvalInfo *Info,
8244 const ASTContext &Ctx,
8245 bool CheckingDest) {
8248 auto diag = [&](
int Reason) {
8250 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_invalid_type)
8251 << CheckingDest << (Reason == 4) << Reason;
8254 auto note = [&](
int Construct, QualType NoteTy, SourceLocation NoteLoc) {
8256 Info->Note(NoteLoc, diag::note_constexpr_bit_cast_invalid_subtype)
8257 << NoteTy << Construct << Ty;
8271 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(
Record)) {
8272 for (CXXBaseSpecifier &BS : CXXRD->bases())
8273 if (!checkBitCastConstexprEligibilityType(Loc, BS.
getType(), Info, Ctx,
8277 for (FieldDecl *FD :
Record->fields()) {
8278 if (FD->getType()->isReferenceType())
8280 if (!checkBitCastConstexprEligibilityType(Loc, FD->getType(), Info, Ctx,
8282 return note(0, FD->getType(), FD->getBeginLoc());
8288 Info, Ctx, CheckingDest))
8291 if (
const auto *VTy = Ty->
getAs<VectorType>()) {
8303 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_invalid_vector)
8304 << QualType(VTy, 0) << EltSize << NElts << Ctx.
getCharWidth();
8314 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_unsupported_type)
8323static bool checkBitCastConstexprEligibility(EvalInfo *Info,
8324 const ASTContext &Ctx,
8326 bool DestOK = checkBitCastConstexprEligibilityType(
8328 bool SourceOK = DestOK && checkBitCastConstexprEligibilityType(
8334static bool handleRValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
8337 assert(
CHAR_BIT == 8 && Info.Ctx.getTargetInfo().getCharWidth() == 8 &&
8338 "no host or target supports non 8-bit chars");
8340 if (!checkBitCastConstexprEligibility(&Info, Info.Ctx, BCE))
8344 std::optional<BitCastBuffer> Buffer =
8345 APValueToBufferConverter::convert(Info, SourceRValue, BCE);
8350 std::optional<APValue> MaybeDestValue =
8351 BufferToAPValueConverter::convert(Info, *Buffer, BCE);
8352 if (!MaybeDestValue)
8355 DestValue = std::move(*MaybeDestValue);
8359static bool handleLValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
8362 assert(
CHAR_BIT == 8 && Info.Ctx.getTargetInfo().getCharWidth() == 8 &&
8363 "no host or target supports non 8-bit chars");
8365 "LValueToRValueBitcast requires an lvalue operand!");
8367 LValue SourceLValue;
8369 SourceLValue.setFrom(Info.Ctx, SourceValue);
8372 SourceRValue,
true))
8375 return handleRValueToRValueBitCast(Info, DestValue, SourceRValue, BCE);
8378template <
class Derived>
8379class ExprEvaluatorBase
8380 :
public ConstStmtVisitor<Derived, bool> {
8382 Derived &getDerived() {
return static_cast<Derived&
>(*this); }
8383 bool DerivedSuccess(
const APValue &
V,
const Expr *E) {
8384 return getDerived().Success(
V, E);
8386 bool DerivedZeroInitialization(
const Expr *E) {
8387 return getDerived().ZeroInitialization(E);
8393 template<
typename ConditionalOperator>
8394 void CheckPotentialConstantConditional(
const ConditionalOperator *E) {
8395 assert(Info.checkingPotentialConstantExpression());
8398 SmallVector<PartialDiagnosticAt, 8>
Diag;
8400 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
8407 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
8414 Error(E, diag::note_constexpr_conditional_never_const);
8418 template<
typename ConditionalOperator>
8419 bool HandleConditionalOperator(
const ConditionalOperator *E) {
8422 if (Info.checkingPotentialConstantExpression() && Info.noteFailure()) {
8423 CheckPotentialConstantConditional(E);
8426 if (Info.noteFailure()) {
8434 return StmtVisitorTy::Visit(EvalExpr);
8439 typedef ConstStmtVisitor<Derived, bool> StmtVisitorTy;
8440 typedef ExprEvaluatorBase ExprEvaluatorBaseTy;
8442 OptionalDiagnostic CCEDiag(
const Expr *E,
diag::kind D) {
8443 return Info.CCEDiag(E, D);
8446 bool ZeroInitialization(
const Expr *E) {
return Error(E); }
8448 bool IsConstantEvaluatedBuiltinCall(
const CallExpr *E) {
8450 return BuiltinOp != 0 &&
8451 Info.Ctx.BuiltinInfo.isConstantEvaluated(BuiltinOp);
8455 ExprEvaluatorBase(EvalInfo &Info) : Info(Info) {}
8457 EvalInfo &getEvalInfo() {
return Info; }
8465 bool Error(
const Expr *E) {
8466 return Error(E, diag::note_invalid_subexpr_in_const_expr);
8469 bool VisitStmt(
const Stmt *) {
8470 llvm_unreachable(
"Expression evaluator should not be called on stmts");
8472 bool VisitExpr(
const Expr *E) {
8476 bool VisitEmbedExpr(
const EmbedExpr *E) {
8477 const auto It = E->
begin();
8478 return StmtVisitorTy::Visit(*It);
8481 bool VisitPredefinedExpr(
const PredefinedExpr *E) {
8484 bool VisitConstantExpr(
const ConstantExpr *E) {
8488 return StmtVisitorTy::Visit(E->
getSubExpr());
8491 bool VisitParenExpr(
const ParenExpr *E)
8492 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8493 bool VisitUnaryExtension(
const UnaryOperator *E)
8494 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8495 bool VisitUnaryPlus(
const UnaryOperator *E)
8496 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8497 bool VisitChooseExpr(
const ChooseExpr *E)
8499 bool VisitGenericSelectionExpr(
const GenericSelectionExpr *E)
8501 bool VisitSubstNonTypeTemplateParmExpr(
const SubstNonTypeTemplateParmExpr *E)
8503 bool VisitCXXDefaultArgExpr(
const CXXDefaultArgExpr *E) {
8504 TempVersionRAII RAII(*Info.CurrentCall);
8505 SourceLocExprScopeGuard Guard(E, Info.CurrentCall->CurSourceLocExprScope);
8506 return StmtVisitorTy::Visit(E->
getExpr());
8508 bool VisitCXXDefaultInitExpr(
const CXXDefaultInitExpr *E) {
8509 TempVersionRAII RAII(*Info.CurrentCall);
8513 SourceLocExprScopeGuard Guard(E, Info.CurrentCall->CurSourceLocExprScope);
8514 return StmtVisitorTy::Visit(E->
getExpr());
8517 bool VisitExprWithCleanups(
const ExprWithCleanups *E) {
8518 FullExpressionRAII Scope(Info);
8519 return StmtVisitorTy::Visit(E->
getSubExpr()) && Scope.destroy();
8524 bool VisitCXXBindTemporaryExpr(
const CXXBindTemporaryExpr *E) {
8525 return StmtVisitorTy::Visit(E->
getSubExpr());
8528 bool VisitCXXReinterpretCastExpr(
const CXXReinterpretCastExpr *E) {
8529 CCEDiag(E, diag::note_constexpr_invalid_cast)
8530 << diag::ConstexprInvalidCastKind::Reinterpret;
8531 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8533 bool VisitCXXDynamicCastExpr(
const CXXDynamicCastExpr *E) {
8534 if (!Info.Ctx.getLangOpts().CPlusPlus20)
8535 CCEDiag(E, diag::note_constexpr_invalid_cast)
8536 << diag::ConstexprInvalidCastKind::Dynamic;
8537 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8539 bool VisitBuiltinBitCastExpr(
const BuiltinBitCastExpr *E) {
8540 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8543 bool VisitBinaryOperator(
const BinaryOperator *E) {
8549 VisitIgnoredValue(E->
getLHS());
8550 return StmtVisitorTy::Visit(E->
getRHS());
8560 return DerivedSuccess(
Result, E);
8565 bool VisitCXXRewrittenBinaryOperator(
const CXXRewrittenBinaryOperator *E) {
8569 bool VisitBinaryConditionalOperator(
const BinaryConditionalOperator *E) {
8573 if (!
Evaluate(Info.CurrentCall->createTemporary(
8576 ScopeKind::FullExpression, CommonLV),
8580 return HandleConditionalOperator(E);
8583 bool VisitConditionalOperator(
const ConditionalOperator *E) {
8584 bool IsBcpCall =
false;
8589 if (
const CallExpr *CallCE =
8591 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
8598 if (Info.checkingPotentialConstantExpression() && IsBcpCall)
8601 FoldConstant Fold(Info, IsBcpCall);
8602 if (!HandleConditionalOperator(E)) {
8603 Fold.keepDiagnostics();
8610 bool VisitOpaqueValueExpr(
const OpaqueValueExpr *E) {
8611 if (
APValue *
Value = Info.CurrentCall->getCurrentTemporary(E);
8613 return DerivedSuccess(*
Value, E);
8619 assert(0 &&
"OpaqueValueExpr recursively refers to itself");
8622 return StmtVisitorTy::Visit(Source);
8625 bool VisitPseudoObjectExpr(
const PseudoObjectExpr *E) {
8626 for (
const Expr *SemE : E->
semantics()) {
8627 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
8636 if (OVE->isUnique())
8640 if (!
Evaluate(Info.CurrentCall->createTemporary(
8641 OVE, getStorageType(Info.Ctx, OVE),
8642 ScopeKind::FullExpression, LV),
8643 Info, OVE->getSourceExpr()))
8646 if (!StmtVisitorTy::Visit(SemE))
8656 bool VisitCallExpr(
const CallExpr *E) {
8658 if (!handleCallExpr(E,
Result,
nullptr))
8660 return DerivedSuccess(
Result, E);
8664 const LValue *ResultSlot) {
8665 CallScopeRAII CallScope(Info);
8668 QualType CalleeType =
Callee->getType();
8670 const FunctionDecl *FD =
nullptr;
8671 LValue *
This =
nullptr, ObjectArg;
8673 bool HasQualifier =
false;
8679 const CXXMethodDecl *
Member =
nullptr;
8680 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(Callee)) {
8684 Member = dyn_cast<CXXMethodDecl>(ME->getMemberDecl());
8686 return Error(Callee);
8688 HasQualifier = ME->hasQualifier();
8689 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(Callee)) {
8691 const ValueDecl *D =
8695 Member = dyn_cast<CXXMethodDecl>(D);
8697 return Error(Callee);
8699 }
else if (
const auto *PDE = dyn_cast<CXXPseudoDestructorExpr>(Callee)) {
8700 if (!Info.getLangOpts().CPlusPlus20)
8701 Info.CCEDiag(PDE, diag::note_constexpr_pseudo_destructor);
8705 return Error(Callee);
8712 if (!CalleeLV.getLValueOffset().isZero())
8713 return Error(Callee);
8714 if (CalleeLV.isNullPointer()) {
8715 Info.FFDiag(Callee, diag::note_constexpr_null_callee)
8716 <<
const_cast<Expr *
>(
Callee);
8719 FD = dyn_cast_or_null<FunctionDecl>(
8720 CalleeLV.getLValueBase().dyn_cast<
const ValueDecl *>());
8722 return Error(Callee);
8725 if (!Info.Ctx.hasSameFunctionTypeIgnoringExceptionSpec(
8732 auto *OCE = dyn_cast<CXXOperatorCallExpr>(E);
8733 if (OCE && OCE->isAssignmentOp()) {
8734 assert(Args.size() == 2 &&
"wrong number of arguments in assignment");
8735 Call = Info.CurrentCall->createCall(FD);
8736 bool HasThis =
false;
8737 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FD))
8738 HasThis = MD->isImplicitObjectMemberFunction();
8746 const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD);
8766 if (Info.getLangOpts().CPlusPlus20 && OCE &&
8767 OCE->getOperator() == OO_Equal && MD->
isTrivial() &&
8771 Args = Args.slice(1);
8777 const CXXRecordDecl *ClosureClass = MD->
getParent();
8779 ClosureClass->
captures().empty() &&
8780 "Number of captures must be zero for conversion to function-ptr");
8782 const CXXMethodDecl *LambdaCallOp =
8791 "A generic lambda's static-invoker function must be a "
8792 "template specialization");
8794 FunctionTemplateDecl *CallOpTemplate =
8796 void *InsertPos =
nullptr;
8797 FunctionDecl *CorrespondingCallOpSpecialization =
8799 assert(CorrespondingCallOpSpecialization &&
8800 "We must always have a function call operator specialization "
8801 "that corresponds to our static invoker specialization");
8803 FD = CorrespondingCallOpSpecialization;
8812 return CallScope.destroy();
8822 Call = Info.CurrentCall->createCall(FD);
8828 SmallVector<QualType, 4> CovariantAdjustmentPath;
8830 auto *NamedMember = dyn_cast<CXXMethodDecl>(FD);
8831 if (NamedMember && NamedMember->isVirtual() && !HasQualifier) {
8834 CovariantAdjustmentPath);
8837 }
else if (NamedMember && NamedMember->isImplicitObjectMemberFunction()) {
8847 if (
auto *DD = dyn_cast<CXXDestructorDecl>(FD)) {
8848 assert(This &&
"no 'this' pointer for destructor call");
8850 Info.Ctx.getCanonicalTagType(DD->getParent())) &&
8851 CallScope.destroy();
8868 if (!CovariantAdjustmentPath.empty() &&
8870 CovariantAdjustmentPath))
8873 return CallScope.destroy();
8876 bool VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E) {
8879 bool VisitInitListExpr(
const InitListExpr *E) {
8881 return DerivedZeroInitialization(E);
8883 return StmtVisitorTy::Visit(E->
getInit(0));
8886 bool VisitImplicitValueInitExpr(
const ImplicitValueInitExpr *E) {
8887 return DerivedZeroInitialization(E);
8889 bool VisitCXXScalarValueInitExpr(
const CXXScalarValueInitExpr *E) {
8890 return DerivedZeroInitialization(E);
8892 bool VisitCXXNullPtrLiteralExpr(
const CXXNullPtrLiteralExpr *E) {
8893 return DerivedZeroInitialization(E);
8897 bool VisitMemberExpr(
const MemberExpr *E) {
8898 assert(!Info.Ctx.getLangOpts().CPlusPlus11 &&
8899 "missing temporary materialization conversion");
8900 assert(!E->
isArrow() &&
"missing call to bound member function?");
8908 const FieldDecl *FD = dyn_cast<FieldDecl>(E->
getMemberDecl());
8909 if (!FD)
return Error(E);
8913 "record / field mismatch");
8918 CompleteObject Obj(APValue::LValueBase(), &Val, BaseTy);
8919 SubobjectDesignator Designator(BaseTy);
8920 Designator.addDeclUnchecked(FD);
8924 DerivedSuccess(
Result, E);
8927 bool VisitExtVectorElementExpr(
const ExtVectorElementExpr *E) {
8933 SmallVector<uint32_t, 4> Indices;
8935 if (Indices.size() == 1) {
8937 return DerivedSuccess(Val.
getVectorElt(Indices[0]), E);
8940 SmallVector<APValue, 4> Elts;
8941 for (
unsigned I = 0; I < Indices.size(); ++I) {
8944 APValue VecResult(Elts.data(), Indices.size());
8945 return DerivedSuccess(VecResult, E);
8952 bool VisitCastExpr(
const CastExpr *E) {
8957 case CK_AtomicToNonAtomic: {
8964 return DerivedSuccess(AtomicVal, E);
8968 case CK_UserDefinedConversion:
8969 return StmtVisitorTy::Visit(E->
getSubExpr());
8971 case CK_HLSLArrayRValue: {
8977 return DerivedSuccess(Val, E);
8988 return DerivedSuccess(RVal, E);
8990 case CK_LValueToRValue: {
8999 return DerivedSuccess(RVal, E);
9001 case CK_LValueToRValueBitCast: {
9002 APValue DestValue, SourceValue;
9005 if (!handleLValueToRValueBitCast(Info, DestValue, SourceValue, E))
9007 return DerivedSuccess(DestValue, E);
9010 case CK_AddressSpaceConversion: {
9014 return DerivedSuccess(
Value, E);
9021 bool VisitUnaryPostInc(
const UnaryOperator *UO) {
9022 return VisitUnaryPostIncDec(UO);
9024 bool VisitUnaryPostDec(
const UnaryOperator *UO) {
9025 return VisitUnaryPostIncDec(UO);
9027 bool VisitUnaryPostIncDec(
const UnaryOperator *UO) {
9028 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9038 return DerivedSuccess(RVal, UO);
9041 bool VisitStmtExpr(
const StmtExpr *E) {
9044 llvm::SaveAndRestore NotCheckingForUB(Info.CheckingForUndefinedBehavior,
9051 BlockScopeRAII Scope(Info);
9056 const Expr *FinalExpr = dyn_cast<Expr>(*BI);
9058 Info.FFDiag((*BI)->getBeginLoc(),
9059 diag::note_constexpr_stmt_expr_unsupported);
9062 return this->Visit(FinalExpr) && Scope.destroy();
9068 if (ESR != ESR_Succeeded) {
9072 if (ESR != ESR_Failed)
9073 Info.FFDiag((*BI)->getBeginLoc(),
9074 diag::note_constexpr_stmt_expr_unsupported);
9079 llvm_unreachable(
"Return from function from the loop above.");
9082 bool VisitPackIndexingExpr(
const PackIndexingExpr *E) {
9087 void VisitIgnoredValue(
const Expr *E) {
9092 void VisitIgnoredBaseExpression(
const Expr *E) {
9095 if (Info.getLangOpts().MSVCCompat && !E->
HasSideEffects(Info.Ctx))
9097 VisitIgnoredValue(E);
9107template<
class Derived>
9108class LValueExprEvaluatorBase
9109 :
public ExprEvaluatorBase<Derived> {
9113 typedef LValueExprEvaluatorBase LValueExprEvaluatorBaseTy;
9114 typedef ExprEvaluatorBase<Derived> ExprEvaluatorBaseTy;
9116 bool Success(APValue::LValueBase B) {
9121 bool evaluatePointer(
const Expr *E, LValue &
Result) {
9126 LValueExprEvaluatorBase(EvalInfo &Info, LValue &
Result,
bool InvalidBaseOK)
9128 InvalidBaseOK(InvalidBaseOK) {}
9131 Result.setFrom(this->Info.Ctx,
V);
9135 bool VisitMemberExpr(
const MemberExpr *E) {
9147 EvalOK = this->Visit(E->
getBase());
9158 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(E->
getMemberDecl())) {
9161 "record / field mismatch");
9165 }
else if (
const IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(MD)) {
9169 return this->
Error(E);
9181 bool VisitBinaryOperator(
const BinaryOperator *E) {
9184 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
9192 bool VisitCastExpr(
const CastExpr *E) {
9195 return ExprEvaluatorBaseTy::VisitCastExpr(E);
9197 case CK_DerivedToBase:
9198 case CK_UncheckedDerivedToBase:
9245class LValueExprEvaluator
9246 :
public LValueExprEvaluatorBase<LValueExprEvaluator> {
9248 LValueExprEvaluator(EvalInfo &Info, LValue &
Result,
bool InvalidBaseOK) :
9249 LValueExprEvaluatorBaseTy(Info,
Result, InvalidBaseOK) {}
9251 bool VisitVarDecl(
const Expr *E,
const VarDecl *VD);
9252 bool VisitUnaryPreIncDec(
const UnaryOperator *UO);
9254 bool VisitCallExpr(
const CallExpr *E);
9255 bool VisitDeclRefExpr(
const DeclRefExpr *E);
9256 bool VisitPredefinedExpr(
const PredefinedExpr *E) {
return Success(E); }
9257 bool VisitMaterializeTemporaryExpr(
const MaterializeTemporaryExpr *E);
9258 bool VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E);
9259 bool VisitMemberExpr(
const MemberExpr *E);
9260 bool VisitStringLiteral(
const StringLiteral *E) {
9262 APValue::LValueBase(E, 0, Info.Ctx.getNextStringLiteralVersion()));
9264 bool VisitObjCEncodeExpr(
const ObjCEncodeExpr *E) {
return Success(E); }
9265 bool VisitCXXTypeidExpr(
const CXXTypeidExpr *E);
9266 bool VisitCXXUuidofExpr(
const CXXUuidofExpr *E);
9267 bool VisitArraySubscriptExpr(
const ArraySubscriptExpr *E);
9268 bool VisitExtVectorElementExpr(
const ExtVectorElementExpr *E);
9269 bool VisitUnaryDeref(
const UnaryOperator *E);
9270 bool VisitUnaryReal(
const UnaryOperator *E);
9271 bool VisitUnaryImag(
const UnaryOperator *E);
9272 bool VisitUnaryPreInc(
const UnaryOperator *UO) {
9273 return VisitUnaryPreIncDec(UO);
9275 bool VisitUnaryPreDec(
const UnaryOperator *UO) {
9276 return VisitUnaryPreIncDec(UO);
9278 bool VisitBinAssign(
const BinaryOperator *BO);
9279 bool VisitCompoundAssignOperator(
const CompoundAssignOperator *CAO);
9281 bool VisitCastExpr(
const CastExpr *E) {
9284 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
9286 case CK_LValueBitCast:
9287 this->CCEDiag(E, diag::note_constexpr_invalid_cast)
9288 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
9289 << Info.Ctx.getLangOpts().CPlusPlus;
9292 Result.Designator.setInvalid();
9295 case CK_BaseToDerived:
9312 bool LValueToRValueConversion) {
9316 assert(Info.CurrentCall->This ==
nullptr &&
9317 "This should not be set for a static call operator");
9325 if (
Self->getType()->isReferenceType()) {
9326 APValue *RefValue = Info.getParamSlot(Info.CurrentCall->Arguments,
Self);
9328 Result.setFrom(Info.Ctx, *RefValue);
9330 const ParmVarDecl *VD = Info.CurrentCall->Arguments.getOrigParam(
Self);
9331 CallStackFrame *Frame =
9332 Info.getCallFrameAndDepth(Info.CurrentCall->Arguments.CallIndex)
9334 unsigned Version = Info.CurrentCall->Arguments.Version;
9335 Result.set({VD, Frame->Index, Version});
9338 Result = *Info.CurrentCall->This;
9348 if (LValueToRValueConversion) {
9352 Result.setFrom(Info.Ctx, RVal);
9363 bool InvalidBaseOK) {
9367 return LValueExprEvaluator(Info, Result, InvalidBaseOK).Visit(E);
9370bool LValueExprEvaluator::VisitDeclRefExpr(
const DeclRefExpr *E) {
9371 const ValueDecl *D = E->
getDecl();
9383 if (Info.checkingPotentialConstantExpression())
9386 if (
auto *FD = Info.CurrentCall->LambdaCaptureFields.lookup(D)) {
9393 if (
isa<FunctionDecl, MSGuidDecl, TemplateParamObjectDecl,
9394 UnnamedGlobalConstantDecl>(D))
9396 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
9397 return VisitVarDecl(E, VD);
9398 if (
const BindingDecl *BD = dyn_cast<BindingDecl>(D))
9399 return Visit(BD->getBinding());
9403bool LValueExprEvaluator::VisitVarDecl(
const Expr *E,
const VarDecl *VD) {
9404 CallStackFrame *Frame =
nullptr;
9405 unsigned Version = 0;
9413 CallStackFrame *CurrFrame = Info.CurrentCall;
9418 if (
auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
9419 if (CurrFrame->Arguments) {
9420 VD = CurrFrame->Arguments.getOrigParam(PVD);
9422 Info.getCallFrameAndDepth(CurrFrame->Arguments.CallIndex).first;
9423 Version = CurrFrame->Arguments.Version;
9427 Version = CurrFrame->getCurrentTemporaryVersion(VD);
9434 Result.set({VD, Frame->Index, Version});
9440 if (!Info.getLangOpts().CPlusPlus11) {
9441 Info.CCEDiag(E, diag::note_constexpr_ltor_non_integral, 1)
9443 Info.Note(VD->
getLocation(), diag::note_declared_at);
9452 Result.AllowConstexprUnknown =
true;
9459bool LValueExprEvaluator::VisitCallExpr(
const CallExpr *E) {
9460 if (!IsConstantEvaluatedBuiltinCall(E))
9461 return ExprEvaluatorBaseTy::VisitCallExpr(E);
9466 case Builtin::BIas_const:
9467 case Builtin::BIforward:
9468 case Builtin::BIforward_like:
9469 case Builtin::BImove:
9470 case Builtin::BImove_if_noexcept:
9472 return Visit(E->
getArg(0));
9476 return ExprEvaluatorBaseTy::VisitCallExpr(E);
9479bool LValueExprEvaluator::VisitMaterializeTemporaryExpr(
9480 const MaterializeTemporaryExpr *E) {
9488 for (
const Expr *E : CommaLHSs)
9497 if (Info.EvalMode == EvaluationMode::ConstantFold)
9504 Value = &Info.CurrentCall->createTemporary(
9520 for (
unsigned I = Adjustments.size(); I != 0; ) {
9522 switch (Adjustments[I].Kind) {
9527 Type = Adjustments[I].DerivedToBase.BasePath->getType();
9533 Type = Adjustments[I].Field->getType();
9538 Adjustments[I].Ptr.RHS))
9540 Type = Adjustments[I].Ptr.MPT->getPointeeType();
9549LValueExprEvaluator::VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E) {
9550 assert((!Info.getLangOpts().CPlusPlus || E->
isFileScope()) &&
9551 "lvalue compound literal in c++?");
9563 assert(!Info.getLangOpts().CPlusPlus);
9565 ScopeKind::Block,
Result);
9577bool LValueExprEvaluator::VisitCXXTypeidExpr(
const CXXTypeidExpr *E) {
9578 TypeInfoLValue TypeInfo;
9586 if (!Info.Ctx.getLangOpts().CPlusPlus20) {
9587 Info.CCEDiag(E, diag::note_constexpr_typeid_polymorphic)
9595 std::optional<DynamicType> DynType =
9600 TypeInfo = TypeInfoLValue(
9601 Info.Ctx.getCanonicalTagType(DynType->Type).getTypePtr());
9607bool LValueExprEvaluator::VisitCXXUuidofExpr(
const CXXUuidofExpr *E) {
9611bool LValueExprEvaluator::VisitMemberExpr(
const MemberExpr *E) {
9613 if (
const VarDecl *VD = dyn_cast<VarDecl>(E->
getMemberDecl())) {
9614 VisitIgnoredBaseExpression(E->
getBase());
9615 return VisitVarDecl(E, VD);
9619 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(E->
getMemberDecl())) {
9620 if (MD->isStatic()) {
9621 VisitIgnoredBaseExpression(E->
getBase());
9627 return LValueExprEvaluatorBaseTy::VisitMemberExpr(E);
9630bool LValueExprEvaluator::VisitExtVectorElementExpr(
9631 const ExtVectorElementExpr *E) {
9636 if (!Info.noteFailure())
9644 if (Indices.size() > 1)
9648 Result.setFrom(Info.Ctx, Val);
9652 const auto *VT = BaseType->
castAs<VectorType>();
9654 VT->getNumElements(), Indices[0]);
9660bool LValueExprEvaluator::VisitArraySubscriptExpr(
const ArraySubscriptExpr *E) {
9670 if (!Info.noteFailure())
9676 if (!Info.noteFailure())
9682 Result.setFrom(Info.Ctx, Val);
9684 VT->getNumElements(), Index.getZExtValue());
9692 for (
const Expr *SubExpr : {E->
getLHS(), E->
getRHS()}) {
9693 if (SubExpr == E->
getBase() ? !evaluatePointer(SubExpr,
Result)
9695 if (!Info.noteFailure())
9705bool LValueExprEvaluator::VisitUnaryDeref(
const UnaryOperator *E) {
9716 Info.noteUndefinedBehavior();
9719bool LValueExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
9728bool LValueExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
9730 "lvalue __imag__ on scalar?");
9737bool LValueExprEvaluator::VisitUnaryPreIncDec(
const UnaryOperator *UO) {
9738 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9749bool LValueExprEvaluator::VisitCompoundAssignOperator(
9750 const CompoundAssignOperator *CAO) {
9751 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9759 if (!Info.noteFailure())
9774bool LValueExprEvaluator::VisitBinAssign(
const BinaryOperator *E) {
9775 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9783 if (!Info.noteFailure())
9791 if (Info.getLangOpts().CPlusPlus20 &&
9807 llvm::APInt &Result) {
9808 assert(isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
9809 "Can't get the size of a non alloc_size function");
9810 const auto *
Base = LVal.getLValueBase().get<
const Expr *>();
9812 std::optional<llvm::APInt> Size =
9813 CE->evaluateBytesReturnedByAllocSizeCall(Ctx);
9817 Result = std::move(*Size);
9836 dyn_cast_or_null<VarDecl>(
Base.dyn_cast<
const ValueDecl *>());
9841 if (!
Init ||
Init->getType().isNull())
9844 const Expr *E =
Init->IgnoreParens();
9845 if (!tryUnwrapAllocSizeCall(E))
9850 Result.setInvalid(E);
9853 Result.addUnsizedArray(Info, E, Pointee);
9858class PointerExprEvaluator
9859 :
public ExprEvaluatorBase<PointerExprEvaluator> {
9868 bool evaluateLValue(
const Expr *E, LValue &
Result) {
9872 bool evaluatePointer(
const Expr *E, LValue &
Result) {
9876 bool visitNonBuiltinCallExpr(
const CallExpr *E);
9879 PointerExprEvaluator(EvalInfo &info, LValue &
Result,
bool InvalidBaseOK)
9881 InvalidBaseOK(InvalidBaseOK) {}
9887 bool ZeroInitialization(
const Expr *E) {
9892 bool VisitBinaryOperator(
const BinaryOperator *E);
9893 bool VisitCastExpr(
const CastExpr* E);
9894 bool VisitUnaryAddrOf(
const UnaryOperator *E);
9895 bool VisitObjCStringLiteral(
const ObjCStringLiteral *E)
9897 bool VisitObjCBoxedExpr(
const ObjCBoxedExpr *E) {
9900 if (Info.noteFailure())
9904 bool VisitObjCArrayLiteral(
const ObjCArrayLiteral *E) {
9907 bool VisitObjCDictionaryLiteral(
const ObjCDictionaryLiteral *E) {
9910 bool VisitAddrLabelExpr(
const AddrLabelExpr *E)
9912 bool VisitCallExpr(
const CallExpr *E);
9913 bool VisitBuiltinCallExpr(
const CallExpr *E,
unsigned BuiltinOp);
9914 bool VisitBlockExpr(
const BlockExpr *E) {
9919 bool VisitCXXThisExpr(
const CXXThisExpr *E) {
9920 auto DiagnoseInvalidUseOfThis = [&] {
9921 if (Info.getLangOpts().CPlusPlus11)
9922 Info.FFDiag(E, diag::note_constexpr_this) << E->
isImplicit();
9928 if (Info.checkingPotentialConstantExpression())
9931 bool IsExplicitLambda =
9933 if (!IsExplicitLambda) {
9934 if (!Info.CurrentCall->This) {
9935 DiagnoseInvalidUseOfThis();
9939 Result = *Info.CurrentCall->This;
9947 if (!Info.CurrentCall->LambdaThisCaptureField) {
9948 if (IsExplicitLambda && !Info.CurrentCall->This) {
9949 DiagnoseInvalidUseOfThis();
9958 Info, E,
Result, MD, Info.CurrentCall->LambdaThisCaptureField,
9964 bool VisitCXXNewExpr(
const CXXNewExpr *E);
9966 bool VisitSourceLocExpr(
const SourceLocExpr *E) {
9967 assert(!E->
isIntType() &&
"SourceLocExpr isn't a pointer type?");
9969 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.
getDefaultExpr());
9970 Result.setFrom(Info.Ctx, LValResult);
9974 bool VisitEmbedExpr(
const EmbedExpr *E) {
9975 llvm::report_fatal_error(
"Not yet implemented for ExprConstant.cpp");
9979 bool VisitSYCLUniqueStableNameExpr(
const SYCLUniqueStableNameExpr *E) {
9982 QualType CharTy = Info.Ctx.CharTy.withConst();
9983 APInt Size(Info.Ctx.getTypeSize(Info.Ctx.getSizeType()),
9984 ResultStr.size() + 1);
9985 QualType ArrayTy = Info.Ctx.getConstantArrayType(
9986 CharTy, Size,
nullptr, ArraySizeModifier::Normal, 0);
9989 StringLiteral::Create(Info.Ctx, ResultStr, StringLiteralKind::Ordinary,
9992 evaluateLValue(SL,
Result);
10002 bool InvalidBaseOK) {
10005 return PointerExprEvaluator(Info, Result, InvalidBaseOK).Visit(E);
10008bool PointerExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
10011 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
10013 const Expr *PExp = E->
getLHS();
10014 const Expr *IExp = E->
getRHS();
10016 std::swap(PExp, IExp);
10018 bool EvalPtrOK = evaluatePointer(PExp,
Result);
10019 if (!EvalPtrOK && !Info.noteFailure())
10022 llvm::APSInt Offset;
10033bool PointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
10042 if (!FnII || !FnII->
isStr(
"current"))
10045 const auto *RD = dyn_cast<RecordDecl>(FD->
getParent());
10053bool PointerExprEvaluator::VisitCastExpr(
const CastExpr *E) {
10060 case CK_CPointerToObjCPointerCast:
10061 case CK_BlockPointerToObjCPointerCast:
10062 case CK_AnyPointerToBlockPointerCast:
10063 case CK_AddressSpaceConversion:
10064 if (!Visit(SubExpr))
10070 CCEDiag(E, diag::note_constexpr_invalid_cast)
10071 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
10072 << Info.Ctx.getLangOpts().CPlusPlus;
10073 Result.Designator.setInvalid();
10081 bool HasValidResult = !
Result.InvalidBase && !
Result.Designator.Invalid &&
10083 bool VoidPtrCastMaybeOK =
10086 Info.Ctx.hasSimilarType(
Result.Designator.getType(Info.Ctx),
10095 if (VoidPtrCastMaybeOK &&
10096 (Info.getStdAllocatorCaller(
"allocate") ||
10098 Info.getLangOpts().CPlusPlus26)) {
10102 Info.getLangOpts().CPlusPlus) {
10103 if (HasValidResult)
10104 CCEDiag(E, diag::note_constexpr_invalid_void_star_cast)
10105 << SubExpr->
getType() << Info.getLangOpts().CPlusPlus26
10106 <<
Result.Designator.getType(Info.Ctx).getCanonicalType()
10109 CCEDiag(E, diag::note_constexpr_invalid_cast)
10110 << diag::ConstexprInvalidCastKind::CastFrom
10113 CCEDiag(E, diag::note_constexpr_invalid_cast)
10114 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
10115 << Info.Ctx.getLangOpts().CPlusPlus;
10116 Result.Designator.setInvalid();
10120 ZeroInitialization(E);
10123 case CK_DerivedToBase:
10124 case CK_UncheckedDerivedToBase:
10136 case CK_BaseToDerived:
10148 case CK_NullToPointer:
10150 return ZeroInitialization(E);
10152 case CK_IntegralToPointer: {
10153 CCEDiag(E, diag::note_constexpr_invalid_cast)
10154 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
10155 << Info.Ctx.getLangOpts().CPlusPlus;
10161 if (
Value.isInt()) {
10162 unsigned Size = Info.Ctx.getTypeSize(E->
getType());
10163 uint64_t N =
Value.getInt().extOrTrunc(Size).getZExtValue();
10164 if (N == Info.Ctx.getTargetNullPointerValue(E->
getType())) {
10167 Result.Base = (Expr *)
nullptr;
10168 Result.InvalidBase =
false;
10170 Result.Designator.setInvalid();
10171 Result.IsNullPtr =
false;
10179 if (!
Value.isLValue())
10188 case CK_ArrayToPointerDecay: {
10190 if (!evaluateLValue(SubExpr,
Result))
10194 SubExpr, SubExpr->
getType(), ScopeKind::FullExpression,
Result);
10199 auto *AT = Info.Ctx.getAsArrayType(SubExpr->
getType());
10200 if (
auto *CAT = dyn_cast<ConstantArrayType>(AT))
10201 Result.addArray(Info, E, CAT);
10203 Result.addUnsizedArray(Info, E, AT->getElementType());
10207 case CK_FunctionToPointerDecay:
10208 return evaluateLValue(SubExpr,
Result);
10210 case CK_LValueToRValue: {
10219 return InvalidBaseOK &&
10225 return ExprEvaluatorBaseTy::VisitCastExpr(E);
10233 T = T.getNonReferenceType();
10235 if (T.getQualifiers().hasUnaligned())
10238 const bool AlignOfReturnsPreferred =
10239 Ctx.
getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver7;
10244 if (ExprKind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
10247 else if (ExprKind == UETT_AlignOf)
10250 llvm_unreachable(
"GetAlignOfType on a non-alignment ExprKind");
10263 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
10267 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(E))
10276 return Info.Ctx.getDeclAlign(VD);
10277 if (
const auto *E =
Value.Base.dyn_cast<
const Expr *>())
10285 EvalInfo &Info,
APSInt &Alignment) {
10288 if (Alignment < 0 || !Alignment.isPowerOf2()) {
10289 Info.FFDiag(E, diag::note_constexpr_invalid_alignment) << Alignment;
10292 unsigned SrcWidth = Info.Ctx.getIntWidth(ForType);
10293 APSInt MaxValue(APInt::getOneBitSet(SrcWidth, SrcWidth - 1));
10294 if (APSInt::compareValues(Alignment, MaxValue) > 0) {
10295 Info.FFDiag(E, diag::note_constexpr_alignment_too_big)
10296 << MaxValue << ForType << Alignment;
10302 APSInt(Alignment.zextOrTrunc(SrcWidth),
true);
10303 assert(APSInt::compareValues(Alignment, ExtAlignment) == 0 &&
10304 "Alignment should not be changed by ext/trunc");
10305 Alignment = ExtAlignment;
10306 assert(Alignment.getBitWidth() == SrcWidth);
10311bool PointerExprEvaluator::visitNonBuiltinCallExpr(
const CallExpr *E) {
10312 if (ExprEvaluatorBaseTy::VisitCallExpr(E))
10320 Result.addUnsizedArray(Info, E, PointeeTy);
10324bool PointerExprEvaluator::VisitCallExpr(
const CallExpr *E) {
10325 if (!IsConstantEvaluatedBuiltinCall(E))
10326 return visitNonBuiltinCallExpr(E);
10333 return T->isCharType() || T->isChar8Type();
10336bool PointerExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *E,
10337 unsigned BuiltinOp) {
10341 switch (BuiltinOp) {
10342 case Builtin::BIaddressof:
10343 case Builtin::BI__addressof:
10344 case Builtin::BI__builtin_addressof:
10346 case Builtin::BI__builtin_assume_aligned: {
10353 LValue OffsetResult(
Result);
10365 int64_t AdditionalOffset = -Offset.getZExtValue();
10370 if (OffsetResult.Base) {
10373 if (BaseAlignment < Align) {
10374 Result.Designator.setInvalid();
10375 CCEDiag(E->
getArg(0), diag::note_constexpr_baa_insufficient_alignment)
10382 if (OffsetResult.Offset.alignTo(Align) != OffsetResult.Offset) {
10383 Result.Designator.setInvalid();
10387 diag::note_constexpr_baa_insufficient_alignment)
10390 diag::note_constexpr_baa_value_insufficient_alignment))
10391 << OffsetResult.Offset.getQuantity() << Align.
getQuantity();
10397 case Builtin::BI__builtin_align_up:
10398 case Builtin::BI__builtin_align_down: {
10418 assert(Alignment.getBitWidth() <= 64 &&
10419 "Cannot handle > 64-bit address-space");
10420 uint64_t Alignment64 = Alignment.getZExtValue();
10422 BuiltinOp == Builtin::BI__builtin_align_down
10423 ? llvm::alignDown(
Result.Offset.getQuantity(), Alignment64)
10424 : llvm::alignTo(
Result.Offset.getQuantity(), Alignment64));
10430 Info.FFDiag(E->
getArg(0), diag::note_constexpr_alignment_adjust)
10434 case Builtin::BI__builtin_operator_new:
10436 case Builtin::BI__builtin_launder:
10438 case Builtin::BIstrchr:
10439 case Builtin::BIwcschr:
10440 case Builtin::BImemchr:
10441 case Builtin::BIwmemchr:
10442 if (Info.getLangOpts().CPlusPlus11)
10443 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
10445 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
10447 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
10449 case Builtin::BI__builtin_strchr:
10450 case Builtin::BI__builtin_wcschr:
10451 case Builtin::BI__builtin_memchr:
10452 case Builtin::BI__builtin_char_memchr:
10453 case Builtin::BI__builtin_wmemchr: {
10454 if (!Visit(E->
getArg(0)))
10460 if (BuiltinOp != Builtin::BIstrchr &&
10461 BuiltinOp != Builtin::BIwcschr &&
10462 BuiltinOp != Builtin::BI__builtin_strchr &&
10463 BuiltinOp != Builtin::BI__builtin_wcschr) {
10467 MaxLength = N.getZExtValue();
10470 if (MaxLength == 0u)
10471 return ZeroInitialization(E);
10472 if (!
Result.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
10473 Result.Designator.Invalid)
10475 QualType CharTy =
Result.Designator.getType(Info.Ctx);
10476 bool IsRawByte = BuiltinOp == Builtin::BImemchr ||
10477 BuiltinOp == Builtin::BI__builtin_memchr;
10478 assert(IsRawByte ||
10479 Info.Ctx.hasSameUnqualifiedType(
10483 Info.FFDiag(E, diag::note_constexpr_ltor_incomplete_type) << CharTy;
10489 Info.FFDiag(E, diag::note_constexpr_memchr_unsupported)
10490 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp) << CharTy;
10496 bool StopAtNull =
false;
10497 switch (BuiltinOp) {
10498 case Builtin::BIstrchr:
10499 case Builtin::BI__builtin_strchr:
10506 return ZeroInitialization(E);
10509 case Builtin::BImemchr:
10510 case Builtin::BI__builtin_memchr:
10511 case Builtin::BI__builtin_char_memchr:
10515 DesiredVal = Desired.trunc(Info.Ctx.getCharWidth()).getZExtValue();
10518 case Builtin::BIwcschr:
10519 case Builtin::BI__builtin_wcschr:
10522 case Builtin::BIwmemchr:
10523 case Builtin::BI__builtin_wmemchr:
10525 DesiredVal = Desired.getZExtValue();
10529 for (; MaxLength; --MaxLength) {
10534 if (Char.
getInt().getZExtValue() == DesiredVal)
10536 if (StopAtNull && !Char.
getInt())
10542 return ZeroInitialization(E);
10545 case Builtin::BImemcpy:
10546 case Builtin::BImemmove:
10547 case Builtin::BIwmemcpy:
10548 case Builtin::BIwmemmove:
10549 if (Info.getLangOpts().CPlusPlus11)
10550 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
10552 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
10554 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
10556 case Builtin::BI__builtin_memcpy:
10557 case Builtin::BI__builtin_memmove:
10558 case Builtin::BI__builtin_wmemcpy:
10559 case Builtin::BI__builtin_wmemmove: {
10560 bool WChar = BuiltinOp == Builtin::BIwmemcpy ||
10561 BuiltinOp == Builtin::BIwmemmove ||
10562 BuiltinOp == Builtin::BI__builtin_wmemcpy ||
10563 BuiltinOp == Builtin::BI__builtin_wmemmove;
10564 bool Move = BuiltinOp == Builtin::BImemmove ||
10565 BuiltinOp == Builtin::BIwmemmove ||
10566 BuiltinOp == Builtin::BI__builtin_memmove ||
10567 BuiltinOp == Builtin::BI__builtin_wmemmove;
10570 if (!Visit(E->
getArg(0)))
10581 assert(!N.isSigned() &&
"memcpy and friends take an unsigned size");
10591 if (!Src.Base || !Dest.Base) {
10593 (!Src.Base ? Src : Dest).moveInto(Val);
10594 Info.FFDiag(E, diag::note_constexpr_memcpy_null)
10595 <<
Move << WChar << !!Src.Base
10599 if (Src.Designator.Invalid || Dest.Designator.Invalid)
10605 QualType T = Dest.Designator.getType(Info.Ctx);
10606 QualType SrcT = Src.Designator.getType(Info.Ctx);
10607 if (!Info.Ctx.hasSameUnqualifiedType(T, SrcT)) {
10609 Info.FFDiag(E, diag::note_constexpr_memcpy_type_pun) <<
Move << SrcT << T;
10613 Info.FFDiag(E, diag::note_constexpr_memcpy_incomplete_type) <<
Move << T;
10617 Info.FFDiag(E, diag::note_constexpr_memcpy_nontrivial) <<
Move << T;
10622 uint64_t TSize = Info.Ctx.getTypeSizeInChars(T).getQuantity();
10627 llvm::APInt OrigN = N;
10628 llvm::APInt::udivrem(OrigN, TSize, N, Remainder);
10630 Info.FFDiag(E, diag::note_constexpr_memcpy_unsupported)
10631 <<
Move << WChar << 0 << T <<
toString(OrigN, 10,
false)
10632 << (unsigned)TSize;
10640 uint64_t RemainingSrcSize = Src.Designator.validIndexAdjustments().second;
10641 uint64_t RemainingDestSize = Dest.Designator.validIndexAdjustments().second;
10642 if (N.ugt(RemainingSrcSize) || N.ugt(RemainingDestSize)) {
10643 Info.FFDiag(E, diag::note_constexpr_memcpy_unsupported)
10644 <<
Move << WChar << (N.ugt(RemainingSrcSize) ? 1 : 2) << T
10648 uint64_t NElems = N.getZExtValue();
10654 uint64_t SrcOffset = Src.getLValueOffset().getQuantity();
10655 uint64_t DestOffset = Dest.getLValueOffset().getQuantity();
10656 if (DestOffset >= SrcOffset && DestOffset - SrcOffset < NBytes) {
10659 Info.FFDiag(E, diag::note_constexpr_memcpy_overlap) << WChar;
10667 }
else if (!Move && SrcOffset >= DestOffset &&
10668 SrcOffset - DestOffset < NBytes) {
10670 Info.FFDiag(E, diag::note_constexpr_memcpy_overlap) << WChar;
10699 QualType AllocType);
10702 const CXXConstructExpr *CCE,
10703 QualType AllocType);
10705bool PointerExprEvaluator::VisitCXXNewExpr(
const CXXNewExpr *E) {
10706 if (!Info.getLangOpts().CPlusPlus20)
10707 Info.CCEDiag(E, diag::note_constexpr_new);
10710 if (Info.SpeculativeEvaluationDepth)
10715 QualType TargetType = AllocType;
10717 bool IsNothrow =
false;
10718 bool IsPlacement =
false;
10736 }
else if (OperatorNew->isReservedGlobalPlacementOperator()) {
10737 if (Info.CurrentCall->isStdFunction() || Info.getLangOpts().CPlusPlus26 ||
10738 (Info.CurrentCall->CanEvalMSConstexpr &&
10739 OperatorNew->hasAttr<MSConstexprAttr>())) {
10742 if (
Result.Designator.Invalid)
10745 IsPlacement =
true;
10747 Info.FFDiag(E, diag::note_constexpr_new_placement)
10752 Info.FFDiag(E, diag::note_constexpr_new_placement)
10755 }
else if (!OperatorNew
10756 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
10757 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
10763 const InitListExpr *ResizedArrayILE =
nullptr;
10764 const CXXConstructExpr *ResizedArrayCCE =
nullptr;
10765 bool ValueInit =
false;
10767 if (std::optional<const Expr *> ArraySize = E->
getArraySize()) {
10768 const Expr *Stripped = *ArraySize;
10769 for (;
auto *ICE = dyn_cast<ImplicitCastExpr>(Stripped);
10770 Stripped = ICE->getSubExpr())
10771 if (ICE->getCastKind() != CK_NoOp &&
10772 ICE->getCastKind() != CK_IntegralCast)
10785 return ZeroInitialization(E);
10787 Info.FFDiag(*ArraySize, diag::note_constexpr_new_negative)
10788 <<
ArrayBound << (*ArraySize)->getSourceRange();
10794 if (!Info.CheckArraySize(ArraySize.value()->getExprLoc(),
10799 return ZeroInitialization(E);
10811 }
else if (
auto *CCE = dyn_cast<CXXConstructExpr>(
Init)) {
10812 ResizedArrayCCE = CCE;
10814 auto *CAT = Info.Ctx.getAsConstantArrayType(
Init->getType());
10815 assert(CAT &&
"unexpected type for array initializer");
10819 llvm::APInt InitBound = CAT->
getSize().zext(Bits);
10820 llvm::APInt AllocBound =
ArrayBound.zext(Bits);
10821 if (InitBound.ugt(AllocBound)) {
10823 return ZeroInitialization(E);
10825 Info.FFDiag(*ArraySize, diag::note_constexpr_new_too_small)
10826 <<
toString(AllocBound, 10,
false)
10828 << (*ArraySize)->getSourceRange();
10834 if (InitBound != AllocBound)
10838 AllocType = Info.Ctx.getConstantArrayType(AllocType,
ArrayBound,
nullptr,
10839 ArraySizeModifier::Normal, 0);
10842 "array allocation with non-array new");
10848 struct FindObjectHandler {
10851 QualType AllocType;
10855 typedef bool result_type;
10856 bool failed() {
return false; }
10857 bool checkConst(QualType QT) {
10859 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
10864 bool found(
APValue &Subobj, QualType SubobjType) {
10865 if (!checkConst(SubobjType))
10869 unsigned SubobjectSize = 1;
10870 unsigned AllocSize = 1;
10871 if (
auto *CAT = dyn_cast<ConstantArrayType>(AllocType))
10873 if (
auto *CAT = dyn_cast<ConstantArrayType>(SubobjType))
10875 if (SubobjectSize < AllocSize ||
10876 !Info.Ctx.hasSimilarType(Info.Ctx.getBaseElementType(SubobjType),
10877 Info.Ctx.getBaseElementType(AllocType))) {
10878 Info.FFDiag(E, diag::note_constexpr_placement_new_wrong_type)
10879 << SubobjType << AllocType;
10886 Info.FFDiag(E, diag::note_constexpr_construct_complex_elem);
10889 bool found(APFloat &
Value, QualType SubobjType) {
10890 Info.FFDiag(E, diag::note_constexpr_construct_complex_elem);
10893 } Handler = {Info, E, AllocType, AK,
nullptr};
10899 Val = Handler.Value;
10908 Val = Info.createHeapAlloc(E, AllocType,
Result);
10914 ImplicitValueInitExpr VIE(AllocType);
10917 }
else if (ResizedArrayILE) {
10921 }
else if (ResizedArrayCCE) {
10944class MemberPointerExprEvaluator
10945 :
public ExprEvaluatorBase<MemberPointerExprEvaluator> {
10948 bool Success(
const ValueDecl *D) {
10954 MemberPointerExprEvaluator(EvalInfo &Info, MemberPtr &
Result)
10961 bool ZeroInitialization(
const Expr *E) {
10962 return Success((
const ValueDecl*)
nullptr);
10965 bool VisitCastExpr(
const CastExpr *E);
10966 bool VisitUnaryAddrOf(
const UnaryOperator *E);
10974 return MemberPointerExprEvaluator(Info, Result).Visit(E);
10977bool MemberPointerExprEvaluator::VisitCastExpr(
const CastExpr *E) {
10980 return ExprEvaluatorBaseTy::VisitCastExpr(E);
10982 case CK_NullToMemberPointer:
10984 return ZeroInitialization(E);
10986 case CK_BaseToDerivedMemberPointer: {
10994 typedef std::reverse_iterator<CastExpr::path_const_iterator> ReverseIter;
10996 PathI != PathE; ++PathI) {
10997 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
10998 const CXXRecordDecl *Derived = (*PathI)->getType()->getAsCXXRecordDecl();
10999 if (!
Result.castToDerived(Derived))
11003 ->
castAs<MemberPointerType>()
11004 ->getMostRecentCXXRecordDecl()))
11009 case CK_DerivedToBaseMemberPointer:
11013 PathE = E->
path_end(); PathI != PathE; ++PathI) {
11014 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
11015 const CXXRecordDecl *
Base = (*PathI)->getType()->getAsCXXRecordDecl();
11016 if (!
Result.castToBase(Base))
11023bool MemberPointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
11034 class RecordExprEvaluator
11035 :
public ExprEvaluatorBase<RecordExprEvaluator> {
11036 const LValue &
This;
11040 RecordExprEvaluator(EvalInfo &info,
const LValue &This,
APValue &
Result)
11047 bool ZeroInitialization(
const Expr *E) {
11048 return ZeroInitialization(E, E->
getType());
11050 bool ZeroInitialization(
const Expr *E, QualType T);
11052 bool VisitCallExpr(
const CallExpr *E) {
11053 return handleCallExpr(E,
Result, &This);
11055 bool VisitCastExpr(
const CastExpr *E);
11056 bool VisitInitListExpr(
const InitListExpr *E);
11057 bool VisitCXXConstructExpr(
const CXXConstructExpr *E) {
11058 return VisitCXXConstructExpr(E, E->
getType());
11061 bool VisitCXXInheritedCtorInitExpr(
const CXXInheritedCtorInitExpr *E);
11062 bool VisitCXXConstructExpr(
const CXXConstructExpr *E, QualType T);
11063 bool VisitCXXStdInitializerListExpr(
const CXXStdInitializerListExpr *E);
11064 bool VisitBinCmp(
const BinaryOperator *E);
11065 bool VisitCXXParenListInitExpr(
const CXXParenListInitExpr *E);
11066 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
11067 ArrayRef<Expr *> Args);
11081 assert(!RD->
isUnion() &&
"Expected non-union class type");
11090 unsigned Index = 0;
11092 End = CD->
bases_end(); I != End; ++I, ++Index) {
11094 LValue Subobject =
This;
11098 Result.getStructBase(Index)))
11103 for (
const auto *I : RD->
fields()) {
11105 if (I->isUnnamedBitField() || I->getType()->isReferenceType())
11108 LValue Subobject =
This;
11114 Result.getStructField(I->getFieldIndex()), Info, Subobject, &VIE))
11121bool RecordExprEvaluator::ZeroInitialization(
const Expr *E, QualType T) {
11128 while (I != RD->
field_end() && (*I)->isUnnamedBitField())
11135 LValue Subobject =
This;
11139 ImplicitValueInitExpr VIE(I->getType());
11144 Info.FFDiag(E, diag::note_constexpr_virtual_base) << RD;
11151bool RecordExprEvaluator::VisitCastExpr(
const CastExpr *E) {
11154 return ExprEvaluatorBaseTy::VisitCastExpr(E);
11156 case CK_ConstructorConversion:
11159 case CK_DerivedToBase:
11160 case CK_UncheckedDerivedToBase: {
11171 PathE = E->
path_end(); PathI != PathE; ++PathI) {
11172 assert(!(*PathI)->isVirtual() &&
"record rvalue with virtual base");
11173 const CXXRecordDecl *
Base = (*PathI)->getType()->getAsCXXRecordDecl();
11180 case CK_HLSLAggregateSplatCast: {
11200 case CK_HLSLElementwiseCast: {
11219bool RecordExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
11222 return VisitCXXParenListOrInitListExpr(E, E->
inits());
11225bool RecordExprEvaluator::VisitCXXParenListOrInitListExpr(
11229 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD);
11230 auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
11232 EvalInfo::EvaluatingConstructorRAII EvalObj(
11234 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries},
11235 CXXRD && CXXRD->getNumBases());
11238 const FieldDecl *
Field;
11239 if (
auto *ILE = dyn_cast<InitListExpr>(ExprToVisit)) {
11240 Field = ILE->getInitializedFieldInUnion();
11241 }
else if (
auto *PLIE = dyn_cast<CXXParenListInitExpr>(ExprToVisit)) {
11242 Field = PLIE->getInitializedFieldInUnion();
11245 "Expression is neither an init list nor a C++ paren list");
11257 ImplicitValueInitExpr VIE(
Field->getType());
11258 const Expr *InitExpr = Args.empty() ? &VIE : Args[0];
11260 LValue Subobject =
This;
11265 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
11269 if (
Field->isBitField())
11279 Result =
APValue(APValue::UninitStruct(), CXXRD ? CXXRD->getNumBases() : 0,
11281 unsigned ElementNo = 0;
11285 if (CXXRD && CXXRD->getNumBases()) {
11286 for (
const auto &Base : CXXRD->bases()) {
11287 assert(ElementNo < Args.size() &&
"missing init for base class");
11288 const Expr *
Init = Args[ElementNo];
11290 LValue Subobject =
This;
11296 if (!Info.noteFailure())
11303 EvalObj.finishedConstructingBases();
11307 for (
const auto *Field : RD->
fields()) {
11310 if (
Field->isUnnamedBitField())
11313 LValue Subobject =
This;
11315 bool HaveInit = ElementNo < Args.size();
11320 Subobject, Field, &Layout))
11325 ImplicitValueInitExpr VIE(HaveInit ? Info.Ctx.IntTy :
Field->getType());
11326 const Expr *
Init = HaveInit ? Args[ElementNo++] : &VIE;
11328 if (
Field->getType()->isIncompleteArrayType()) {
11329 if (
auto *CAT = Info.Ctx.getAsConstantArrayType(
Init->getType())) {
11333 Info.FFDiag(
Init, diag::note_constexpr_unsupported_flexible_array);
11340 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
11344 if (
Field->getType()->isReferenceType()) {
11348 if (!Info.noteFailure())
11353 (
Field->isBitField() &&
11355 if (!Info.noteFailure())
11361 EvalObj.finishedConstructingFields();
11366bool RecordExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E,
11376 return ZeroInitialization(E, T);
11394 const Expr *SrcObj = E->
getArg(0);
11396 assert(Info.Ctx.hasSameUnqualifiedType(E->
getType(), SrcObj->
getType()));
11397 if (
const MaterializeTemporaryExpr *ME =
11398 dyn_cast<MaterializeTemporaryExpr>(SrcObj))
11399 return Visit(ME->getSubExpr());
11402 if (ZeroInit && !ZeroInitialization(E, T))
11411bool RecordExprEvaluator::VisitCXXInheritedCtorInitExpr(
11412 const CXXInheritedCtorInitExpr *E) {
11413 if (!Info.CurrentCall) {
11414 assert(Info.checkingPotentialConstantExpression());
11433bool RecordExprEvaluator::VisitCXXStdInitializerListExpr(
11434 const CXXStdInitializerListExpr *E) {
11435 const ConstantArrayType *ArrayType =
11442 assert(ArrayType &&
"unexpected type for array initializer");
11445 Array.addArray(Info, E, ArrayType);
11453 assert(Field !=
Record->field_end() &&
11454 Info.Ctx.hasSameType(
Field->getType()->getPointeeType(),
11456 "Expected std::initializer_list first field to be const E *");
11458 assert(Field !=
Record->field_end() &&
11459 "Expected std::initializer_list to have two fields");
11461 if (Info.Ctx.hasSameType(
Field->getType(), Info.Ctx.getSizeType())) {
11466 assert(Info.Ctx.hasSameType(
Field->getType()->getPointeeType(),
11468 "Expected std::initializer_list second field to be const E *");
11476 assert(++Field ==
Record->field_end() &&
11477 "Expected std::initializer_list to only have two fields");
11482bool RecordExprEvaluator::VisitLambdaExpr(
const LambdaExpr *E) {
11487 const size_t NumFields = ClosureClass->
getNumFields();
11491 "The number of lambda capture initializers should equal the number of "
11492 "fields within the closure type");
11499 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(ClosureClass);
11500 for (
const auto *Field : ClosureClass->
fields()) {
11503 Expr *
const CurFieldInit = *CaptureInitIt++;
11510 LValue Subobject =
This;
11517 if (!Info.keepEvaluatingAfterFailure())
11526 APValue &Result, EvalInfo &Info) {
11529 "can't evaluate expression as a record rvalue");
11530 return RecordExprEvaluator(Info,
This, Result).Visit(E);
11541class TemporaryExprEvaluator
11542 :
public LValueExprEvaluatorBase<TemporaryExprEvaluator> {
11544 TemporaryExprEvaluator(EvalInfo &Info, LValue &
Result) :
11545 LValueExprEvaluatorBaseTy(Info,
Result,
false) {}
11548 bool VisitConstructExpr(
const Expr *E) {
11554 bool VisitCastExpr(
const CastExpr *E) {
11557 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
11559 case CK_ConstructorConversion:
11563 bool VisitInitListExpr(
const InitListExpr *E) {
11564 return VisitConstructExpr(E);
11566 bool VisitCXXConstructExpr(
const CXXConstructExpr *E) {
11567 return VisitConstructExpr(E);
11569 bool VisitCallExpr(
const CallExpr *E) {
11570 return VisitConstructExpr(E);
11572 bool VisitCXXStdInitializerListExpr(
const CXXStdInitializerListExpr *E) {
11573 return VisitConstructExpr(E);
11576 return VisitConstructExpr(E);
11585 return TemporaryExprEvaluator(Info, Result).Visit(E);
11593 class VectorExprEvaluator
11594 :
public ExprEvaluatorBase<VectorExprEvaluator> {
11601 bool Success(ArrayRef<APValue>
V,
const Expr *E) {
11602 assert(
V.size() == E->
getType()->
castAs<VectorType>()->getNumElements());
11608 assert(
V.isVector());
11612 bool ZeroInitialization(
const Expr *E);
11614 bool VisitUnaryReal(
const UnaryOperator *E)
11616 bool VisitCastExpr(
const CastExpr* E);
11617 bool VisitInitListExpr(
const InitListExpr *E);
11618 bool VisitUnaryImag(
const UnaryOperator *E);
11619 bool VisitBinaryOperator(
const BinaryOperator *E);
11620 bool VisitUnaryOperator(
const UnaryOperator *E);
11621 bool VisitCallExpr(
const CallExpr *E);
11622 bool VisitConvertVectorExpr(
const ConvertVectorExpr *E);
11623 bool VisitShuffleVectorExpr(
const ShuffleVectorExpr *E);
11632 "not a vector prvalue");
11633 return VectorExprEvaluator(Info, Result).Visit(E);
11637 assert(Val.
isVector() &&
"expected vector APValue");
11641 llvm::APInt
Result(NumElts, 0);
11643 for (
unsigned I = 0; I < NumElts; ++I) {
11645 assert(Elt.
isInt() &&
"expected integer element in bool vector");
11647 if (Elt.
getInt().getBoolValue())
11654bool VectorExprEvaluator::VisitCastExpr(
const CastExpr *E) {
11655 const VectorType *VTy = E->
getType()->
castAs<VectorType>();
11659 QualType SETy = SE->
getType();
11662 case CK_VectorSplat: {
11668 Val =
APValue(std::move(IntResult));
11673 Val =
APValue(std::move(FloatResult));
11690 Info.FFDiag(E, diag::note_constexpr_invalid_cast)
11691 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
11692 << Info.Ctx.getLangOpts().CPlusPlus;
11696 if (!handleRValueToRValueBitCast(Info,
Result, SVal, E))
11701 case CK_HLSLVectorTruncation: {
11706 for (
unsigned I = 0; I < NElts; I++)
11710 case CK_HLSLMatrixTruncation: {
11716 for (
unsigned Row = 0;
11718 for (
unsigned Col = 0;
11723 case CK_HLSLAggregateSplatCast: {
11740 case CK_HLSLElementwiseCast: {
11753 return Success(ResultEls, E);
11756 return ExprEvaluatorBaseTy::VisitCastExpr(E);
11761VectorExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
11778 unsigned CountInits = 0, CountElts = 0;
11779 while (CountElts < NumElements) {
11781 if (CountInits < NumInits
11787 for (
unsigned j = 0; j < vlen; j++)
11791 llvm::APSInt sInt(32);
11792 if (CountInits < NumInits) {
11796 sInt = Info.Ctx.MakeIntValue(0, EltTy);
11797 Elements.push_back(
APValue(sInt));
11800 llvm::APFloat f(0.0);
11801 if (CountInits < NumInits) {
11805 f = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy));
11806 Elements.push_back(
APValue(f));
11815VectorExprEvaluator::ZeroInitialization(
const Expr *E) {
11819 if (EltTy->isIntegerType())
11820 ZeroElement =
APValue(Info.Ctx.MakeIntValue(0, EltTy));
11823 APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy)));
11829bool VectorExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
11831 return ZeroInitialization(E);
11834bool VectorExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
11836 assert(Op != BO_PtrMemD && Op != BO_PtrMemI && Op != BO_Cmp &&
11837 "Operation not supported on vector types");
11839 if (Op == BO_Comma)
11840 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
11842 Expr *LHS = E->
getLHS();
11843 Expr *RHS = E->
getRHS();
11846 "Must both be vector types");
11849 assert(LHS->
getType()->
castAs<VectorType>()->getNumElements() ==
11853 "All operands must be the same size.");
11857 bool LHSOK =
Evaluate(LHSValue, Info, LHS);
11858 if (!LHSOK && !Info.noteFailure())
11860 if (!
Evaluate(RHSValue, Info, RHS) || !LHSOK)
11882 "Vector can only be int or float type");
11890 "Vector operator ~ can only be int");
11891 Elt.
getInt().flipAllBits();
11901 "Vector can only be int or float type");
11907 EltResult.setAllBits();
11909 EltResult.clearAllBits();
11915 return std::nullopt;
11919bool VectorExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
11925 const QualType ResultEltTy = VD->getElementType();
11929 if (!
Evaluate(SubExprValue, Info, SubExpr))
11942 "Vector length doesn't match type?");
11945 for (
unsigned EltNum = 0; EltNum < VD->getNumElements(); ++EltNum) {
11947 Info.Ctx, ResultEltTy, Op, SubExprValue.
getVectorElt(EltNum));
11950 ResultElements.push_back(*Elt);
11952 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
11961 Result =
APValue(APFloat(0.0));
11963 DestTy, Result.getFloat());
11974 Result.getFloat());
11979 DestTy, Result.getInt());
11983 Info.FFDiag(E, diag::err_convertvector_constexpr_unsupported_vector_cast)
11984 << SourceTy << DestTy;
11989 llvm::function_ref<APInt(
const APSInt &)> PackFn) {
11998 assert(LHSVecLen != 0 && LHSVecLen == RHSVecLen &&
11999 "pack builtin LHSVecLen must equal to RHSVecLen");
12002 const unsigned SrcBits = Info.Ctx.getIntWidth(VT0->
getElementType());
12008 const unsigned SrcPerLane = 128 / SrcBits;
12009 const unsigned Lanes = LHSVecLen * SrcBits / 128;
12012 Out.reserve(LHSVecLen + RHSVecLen);
12014 for (
unsigned Lane = 0; Lane != Lanes; ++Lane) {
12015 unsigned base = Lane * SrcPerLane;
12016 for (
unsigned I = 0; I != SrcPerLane; ++I)
12019 for (
unsigned I = 0; I != SrcPerLane; ++I)
12024 Result =
APValue(Out.data(), Out.size());
12030 llvm::function_ref<std::pair<unsigned, int>(
unsigned,
unsigned)>
12037 unsigned ShuffleMask = 0;
12039 bool IsVectorMask =
false;
12040 bool IsSingleOperand = (
Call->getNumArgs() == 2);
12042 if (IsSingleOperand) {
12045 IsVectorMask =
true;
12054 ShuffleMask =
static_cast<unsigned>(MaskImm.getZExtValue());
12064 IsVectorMask =
true;
12073 ShuffleMask =
static_cast<unsigned>(MaskImm.getZExtValue());
12084 ResultElements.reserve(NumElts);
12086 for (
unsigned DstIdx = 0; DstIdx != NumElts; ++DstIdx) {
12087 if (IsVectorMask) {
12088 ShuffleMask =
static_cast<unsigned>(
12089 MaskVector.getVectorElt(DstIdx).getInt().getZExtValue());
12091 auto [SrcVecIdx, SrcIdx] = GetSourceIndex(DstIdx, ShuffleMask);
12097 ResultElements.push_back(
12098 APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(ElemTy))));
12104 ResultElements.push_back(
APValue());
12107 const APValue &Src = (SrcVecIdx == 0) ? A : B;
12112 Out =
APValue(ResultElements.data(), ResultElements.size());
12116 APFloat OrigVal,
APValue &Result) {
12118 if (OrigVal.isInfinity()) {
12119 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << 0;
12122 if (OrigVal.isNaN()) {
12123 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << 1;
12127 APFloat Val = OrigVal;
12128 bool LosesInfo =
false;
12129 APFloat::opStatus Status = Val.convert(
12130 APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven, &LosesInfo);
12132 if (LosesInfo || Val.isDenormal()) {
12133 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic_strict);
12137 if (Status != APFloat::opOK) {
12138 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
12147 llvm::function_ref<APInt(
const APInt &, uint64_t)> ShiftOp,
12148 llvm::function_ref<APInt(
const APInt &,
unsigned)> OverflowOp) {
12155 assert(
Call->getNumArgs() == 2);
12159 Call->getArg(1)->getType()->isVectorType());
12162 unsigned DestEltWidth = Source.getVectorElt(0).getInt().getBitWidth();
12163 unsigned DestLen = Source.getVectorLength();
12166 unsigned NumBitsInQWord = 64;
12167 unsigned NumCountElts = NumBitsInQWord / CountEltWidth;
12169 Result.reserve(DestLen);
12171 uint64_t CountLQWord = 0;
12172 for (
unsigned EltIdx = 0; EltIdx != NumCountElts; ++EltIdx) {
12174 CountLQWord |= (Elt << (EltIdx * CountEltWidth));
12177 for (
unsigned EltIdx = 0; EltIdx != DestLen; ++EltIdx) {
12178 APInt Elt = Source.getVectorElt(EltIdx).getInt();
12179 if (CountLQWord < DestEltWidth) {
12181 APValue(
APSInt(ShiftOp(Elt, CountLQWord), IsDestUnsigned)));
12184 APValue(
APSInt(OverflowOp(Elt, DestEltWidth), IsDestUnsigned)));
12187 Out =
APValue(Result.data(), Result.size());
12192 std::optional<APSInt> RoundingMode,
12194 APSInt DefaultMode(APInt(32, 4),
true);
12195 if (RoundingMode.value_or(DefaultMode) != 4)
12196 return std::nullopt;
12197 if (A.isNaN() || A.isInfinity() || A.isDenormal() || B.isNaN() ||
12198 B.isInfinity() || B.isDenormal())
12199 return std::nullopt;
12200 if (A.isZero() && B.isZero())
12202 return IsMin ? llvm::minimum(A, B) : llvm::maximum(A, B);
12205bool VectorExprEvaluator::VisitCallExpr(
const CallExpr *E) {
12206 if (!IsConstantEvaluatedBuiltinCall(E))
12207 return ExprEvaluatorBaseTy::VisitCallExpr(E);
12209 auto EvaluateBinOpExpr =
12211 APValue SourceLHS, SourceRHS;
12217 QualType DestEltTy = DestTy->getElementType();
12218 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
12221 ResultElements.reserve(SourceLen);
12223 if (SourceRHS.
isInt()) {
12225 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12227 ResultElements.push_back(
12231 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12234 ResultElements.push_back(
12241 auto EvaluateFpBinOpExpr =
12242 [&](llvm::function_ref<std::optional<APFloat>(
12243 const APFloat &,
const APFloat &, std::optional<APSInt>)>
12245 bool IsScalar =
false) {
12255 std::optional<APSInt> RoundingMode;
12260 RoundingMode = Imm;
12265 ResultElements.reserve(NumElems);
12267 for (
unsigned EltNum = 0; EltNum < NumElems; ++EltNum) {
12268 if (IsScalar && EltNum > 0) {
12274 std::optional<APFloat>
Result =
Fn(EltA, EltB, RoundingMode);
12282 auto EvaluateScalarFpRoundMaskBinOp =
12283 [&](llvm::function_ref<std::optional<APFloat>(
12284 const APFloat &,
const APFloat &, std::optional<APSInt>)>
12288 APSInt MaskVal, Rounding;
12299 ResultElements.reserve(NumElems);
12301 if (MaskVal.getZExtValue() & 1) {
12304 std::optional<APFloat>
Result =
Fn(EltA, EltB, Rounding);
12312 for (
unsigned I = 1; I < NumElems; ++I)
12318 auto EvalSelectScalar = [&](
unsigned Len) ->
bool {
12326 bool TakeA0 = (Mask.getZExtValue() & 1u) != 0;
12330 for (
unsigned I = 1; I < Len; ++I)
12332 APValue V(Res.data(), Res.size());
12339 case Builtin::BI__builtin_elementwise_popcount:
12340 case Builtin::BI__builtin_elementwise_bitreverse: {
12345 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12348 ResultElements.reserve(SourceLen);
12350 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12353 case Builtin::BI__builtin_elementwise_popcount:
12354 ResultElements.push_back(
APValue(
12355 APSInt(
APInt(Info.Ctx.getIntWidth(DestEltTy), Elt.popcount()),
12358 case Builtin::BI__builtin_elementwise_bitreverse:
12359 ResultElements.push_back(
12366 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12368 case Builtin::BI__builtin_elementwise_abs: {
12373 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12376 ResultElements.reserve(SourceLen);
12378 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12383 CurrentEle.getInt().
abs(),
12384 DestEltTy->isUnsignedIntegerOrEnumerationType()));
12385 ResultElements.push_back(Val);
12388 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12391 case Builtin::BI__builtin_elementwise_add_sat:
12392 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12393 return LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS);
12396 case Builtin::BI__builtin_elementwise_sub_sat:
12397 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12398 return LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
12401 case X86::BI__builtin_ia32_extract128i256:
12402 case X86::BI__builtin_ia32_vextractf128_pd256:
12403 case X86::BI__builtin_ia32_vextractf128_ps256:
12404 case X86::BI__builtin_ia32_vextractf128_si256: {
12405 APValue SourceVec, SourceImm;
12414 unsigned RetLen = RetVT->getNumElements();
12415 unsigned Idx = SourceImm.
getInt().getZExtValue() & 1;
12418 ResultElements.reserve(RetLen);
12420 for (
unsigned I = 0; I < RetLen; I++)
12421 ResultElements.push_back(SourceVec.
getVectorElt(Idx * RetLen + I));
12426 case clang::X86::BI__builtin_ia32_cvtmask2b128:
12427 case clang::X86::BI__builtin_ia32_cvtmask2b256:
12428 case clang::X86::BI__builtin_ia32_cvtmask2b512:
12429 case clang::X86::BI__builtin_ia32_cvtmask2w128:
12430 case clang::X86::BI__builtin_ia32_cvtmask2w256:
12431 case clang::X86::BI__builtin_ia32_cvtmask2w512:
12432 case clang::X86::BI__builtin_ia32_cvtmask2d128:
12433 case clang::X86::BI__builtin_ia32_cvtmask2d256:
12434 case clang::X86::BI__builtin_ia32_cvtmask2d512:
12435 case clang::X86::BI__builtin_ia32_cvtmask2q128:
12436 case clang::X86::BI__builtin_ia32_cvtmask2q256:
12437 case clang::X86::BI__builtin_ia32_cvtmask2q512: {
12443 QualType VecTy = E->
getType();
12444 const VectorType *VT = VecTy->
castAs<VectorType>();
12447 unsigned ElemWidth = Info.Ctx.getTypeSize(ElemTy);
12450 for (
unsigned I = 0; I != VectorLen; ++I) {
12451 bool BitSet = Mask[I];
12452 APSInt ElemVal(ElemWidth,
false);
12454 ElemVal.setAllBits();
12456 Elems.push_back(
APValue(ElemVal));
12461 case X86::BI__builtin_ia32_extracti32x4_256_mask:
12462 case X86::BI__builtin_ia32_extractf32x4_256_mask:
12463 case X86::BI__builtin_ia32_extracti32x4_mask:
12464 case X86::BI__builtin_ia32_extractf32x4_mask:
12465 case X86::BI__builtin_ia32_extracti32x8_mask:
12466 case X86::BI__builtin_ia32_extractf32x8_mask:
12467 case X86::BI__builtin_ia32_extracti64x2_256_mask:
12468 case X86::BI__builtin_ia32_extractf64x2_256_mask:
12469 case X86::BI__builtin_ia32_extracti64x2_512_mask:
12470 case X86::BI__builtin_ia32_extractf64x2_512_mask:
12471 case X86::BI__builtin_ia32_extracti64x4_mask:
12472 case X86::BI__builtin_ia32_extractf64x4_mask: {
12483 unsigned RetLen = RetVT->getNumElements();
12488 unsigned Lanes = SrcLen / RetLen;
12489 unsigned Lane =
static_cast<unsigned>(Imm.getZExtValue() % Lanes);
12490 unsigned Base = Lane * RetLen;
12493 ResultElements.reserve(RetLen);
12494 for (
unsigned I = 0; I < RetLen; ++I) {
12496 ResultElements.push_back(SourceVec.
getVectorElt(Base + I));
12500 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12503 case clang::X86::BI__builtin_ia32_pavgb128:
12504 case clang::X86::BI__builtin_ia32_pavgw128:
12505 case clang::X86::BI__builtin_ia32_pavgb256:
12506 case clang::X86::BI__builtin_ia32_pavgw256:
12507 case clang::X86::BI__builtin_ia32_pavgb512:
12508 case clang::X86::BI__builtin_ia32_pavgw512:
12509 return EvaluateBinOpExpr(llvm::APIntOps::avgCeilU);
12511 case clang::X86::BI__builtin_ia32_pmulhrsw128:
12512 case clang::X86::BI__builtin_ia32_pmulhrsw256:
12513 case clang::X86::BI__builtin_ia32_pmulhrsw512:
12514 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12515 return (llvm::APIntOps::mulsExtended(LHS, RHS).ashr(14) + 1)
12516 .extractBits(16, 1);
12519 case clang::X86::BI__builtin_ia32_pmaddubsw128:
12520 case clang::X86::BI__builtin_ia32_pmaddubsw256:
12521 case clang::X86::BI__builtin_ia32_pmaddubsw512:
12522 case clang::X86::BI__builtin_ia32_pmaddwd128:
12523 case clang::X86::BI__builtin_ia32_pmaddwd256:
12524 case clang::X86::BI__builtin_ia32_pmaddwd512: {
12525 APValue SourceLHS, SourceRHS;
12531 QualType DestEltTy = DestTy->getElementType();
12533 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
12535 ResultElements.reserve(SourceLen / 2);
12537 for (
unsigned EltNum = 0; EltNum < SourceLen; EltNum += 2) {
12542 unsigned BitWidth = 2 * LoLHS.getBitWidth();
12545 case clang::X86::BI__builtin_ia32_pmaddubsw128:
12546 case clang::X86::BI__builtin_ia32_pmaddubsw256:
12547 case clang::X86::BI__builtin_ia32_pmaddubsw512:
12548 ResultElements.push_back(
APValue(
12549 APSInt((LoLHS.zext(BitWidth) * LoRHS.sext(BitWidth))
12550 .sadd_sat((HiLHS.zext(BitWidth) * HiRHS.sext(BitWidth))),
12553 case clang::X86::BI__builtin_ia32_pmaddwd128:
12554 case clang::X86::BI__builtin_ia32_pmaddwd256:
12555 case clang::X86::BI__builtin_ia32_pmaddwd512:
12556 ResultElements.push_back(
12557 APValue(
APSInt((LoLHS.sext(BitWidth) * LoRHS.sext(BitWidth)) +
12558 (HiLHS.sext(BitWidth) * HiRHS.sext(BitWidth)),
12564 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12567 case clang::X86::BI__builtin_ia32_pmulhuw128:
12568 case clang::X86::BI__builtin_ia32_pmulhuw256:
12569 case clang::X86::BI__builtin_ia32_pmulhuw512:
12570 return EvaluateBinOpExpr(llvm::APIntOps::mulhu);
12572 case clang::X86::BI__builtin_ia32_pmulhw128:
12573 case clang::X86::BI__builtin_ia32_pmulhw256:
12574 case clang::X86::BI__builtin_ia32_pmulhw512:
12575 return EvaluateBinOpExpr(llvm::APIntOps::mulhs);
12577 case clang::X86::BI__builtin_ia32_psllv2di:
12578 case clang::X86::BI__builtin_ia32_psllv4di:
12579 case clang::X86::BI__builtin_ia32_psllv4si:
12580 case clang::X86::BI__builtin_ia32_psllv8di:
12581 case clang::X86::BI__builtin_ia32_psllv8hi:
12582 case clang::X86::BI__builtin_ia32_psllv8si:
12583 case clang::X86::BI__builtin_ia32_psllv16hi:
12584 case clang::X86::BI__builtin_ia32_psllv16si:
12585 case clang::X86::BI__builtin_ia32_psllv32hi:
12586 case clang::X86::BI__builtin_ia32_psllwi128:
12587 case clang::X86::BI__builtin_ia32_pslldi128:
12588 case clang::X86::BI__builtin_ia32_psllqi128:
12589 case clang::X86::BI__builtin_ia32_psllwi256:
12590 case clang::X86::BI__builtin_ia32_pslldi256:
12591 case clang::X86::BI__builtin_ia32_psllqi256:
12592 case clang::X86::BI__builtin_ia32_psllwi512:
12593 case clang::X86::BI__builtin_ia32_pslldi512:
12594 case clang::X86::BI__builtin_ia32_psllqi512:
12595 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12596 if (RHS.uge(LHS.getBitWidth())) {
12597 return APInt::getZero(LHS.getBitWidth());
12599 return LHS.shl(RHS.getZExtValue());
12602 case clang::X86::BI__builtin_ia32_psrav4si:
12603 case clang::X86::BI__builtin_ia32_psrav8di:
12604 case clang::X86::BI__builtin_ia32_psrav8hi:
12605 case clang::X86::BI__builtin_ia32_psrav8si:
12606 case clang::X86::BI__builtin_ia32_psrav16hi:
12607 case clang::X86::BI__builtin_ia32_psrav16si:
12608 case clang::X86::BI__builtin_ia32_psrav32hi:
12609 case clang::X86::BI__builtin_ia32_psravq128:
12610 case clang::X86::BI__builtin_ia32_psravq256:
12611 case clang::X86::BI__builtin_ia32_psrawi128:
12612 case clang::X86::BI__builtin_ia32_psradi128:
12613 case clang::X86::BI__builtin_ia32_psraqi128:
12614 case clang::X86::BI__builtin_ia32_psrawi256:
12615 case clang::X86::BI__builtin_ia32_psradi256:
12616 case clang::X86::BI__builtin_ia32_psraqi256:
12617 case clang::X86::BI__builtin_ia32_psrawi512:
12618 case clang::X86::BI__builtin_ia32_psradi512:
12619 case clang::X86::BI__builtin_ia32_psraqi512:
12620 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12621 if (RHS.uge(LHS.getBitWidth())) {
12622 return LHS.ashr(LHS.getBitWidth() - 1);
12624 return LHS.ashr(RHS.getZExtValue());
12627 case clang::X86::BI__builtin_ia32_psrlv2di:
12628 case clang::X86::BI__builtin_ia32_psrlv4di:
12629 case clang::X86::BI__builtin_ia32_psrlv4si:
12630 case clang::X86::BI__builtin_ia32_psrlv8di:
12631 case clang::X86::BI__builtin_ia32_psrlv8hi:
12632 case clang::X86::BI__builtin_ia32_psrlv8si:
12633 case clang::X86::BI__builtin_ia32_psrlv16hi:
12634 case clang::X86::BI__builtin_ia32_psrlv16si:
12635 case clang::X86::BI__builtin_ia32_psrlv32hi:
12636 case clang::X86::BI__builtin_ia32_psrlwi128:
12637 case clang::X86::BI__builtin_ia32_psrldi128:
12638 case clang::X86::BI__builtin_ia32_psrlqi128:
12639 case clang::X86::BI__builtin_ia32_psrlwi256:
12640 case clang::X86::BI__builtin_ia32_psrldi256:
12641 case clang::X86::BI__builtin_ia32_psrlqi256:
12642 case clang::X86::BI__builtin_ia32_psrlwi512:
12643 case clang::X86::BI__builtin_ia32_psrldi512:
12644 case clang::X86::BI__builtin_ia32_psrlqi512:
12645 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12646 if (RHS.uge(LHS.getBitWidth())) {
12647 return APInt::getZero(LHS.getBitWidth());
12649 return LHS.lshr(RHS.getZExtValue());
12651 case X86::BI__builtin_ia32_packsswb128:
12652 case X86::BI__builtin_ia32_packsswb256:
12653 case X86::BI__builtin_ia32_packsswb512:
12654 case X86::BI__builtin_ia32_packssdw128:
12655 case X86::BI__builtin_ia32_packssdw256:
12656 case X86::BI__builtin_ia32_packssdw512:
12658 return APSInt(Src).truncSSat(Src.getBitWidth() / 2);
12660 case X86::BI__builtin_ia32_packusdw128:
12661 case X86::BI__builtin_ia32_packusdw256:
12662 case X86::BI__builtin_ia32_packusdw512:
12663 case X86::BI__builtin_ia32_packuswb128:
12664 case X86::BI__builtin_ia32_packuswb256:
12665 case X86::BI__builtin_ia32_packuswb512:
12667 return APSInt(Src).truncSSatU(Src.getBitWidth() / 2);
12669 case clang::X86::BI__builtin_ia32_selectss_128:
12670 return EvalSelectScalar(4);
12671 case clang::X86::BI__builtin_ia32_selectsd_128:
12672 return EvalSelectScalar(2);
12673 case clang::X86::BI__builtin_ia32_selectsh_128:
12674 case clang::X86::BI__builtin_ia32_selectsbf_128:
12675 return EvalSelectScalar(8);
12676 case clang::X86::BI__builtin_ia32_pmuldq128:
12677 case clang::X86::BI__builtin_ia32_pmuldq256:
12678 case clang::X86::BI__builtin_ia32_pmuldq512:
12679 case clang::X86::BI__builtin_ia32_pmuludq128:
12680 case clang::X86::BI__builtin_ia32_pmuludq256:
12681 case clang::X86::BI__builtin_ia32_pmuludq512: {
12682 APValue SourceLHS, SourceRHS;
12689 ResultElements.reserve(SourceLen / 2);
12691 for (
unsigned EltNum = 0; EltNum < SourceLen; EltNum += 2) {
12696 case clang::X86::BI__builtin_ia32_pmuludq128:
12697 case clang::X86::BI__builtin_ia32_pmuludq256:
12698 case clang::X86::BI__builtin_ia32_pmuludq512:
12699 ResultElements.push_back(
12700 APValue(
APSInt(llvm::APIntOps::muluExtended(LHS, RHS),
true)));
12702 case clang::X86::BI__builtin_ia32_pmuldq128:
12703 case clang::X86::BI__builtin_ia32_pmuldq256:
12704 case clang::X86::BI__builtin_ia32_pmuldq512:
12705 ResultElements.push_back(
12706 APValue(
APSInt(llvm::APIntOps::mulsExtended(LHS, RHS),
false)));
12711 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12714 case X86::BI__builtin_ia32_vpmadd52luq128:
12715 case X86::BI__builtin_ia32_vpmadd52luq256:
12716 case X86::BI__builtin_ia32_vpmadd52luq512: {
12725 ResultElements.reserve(ALen);
12727 for (
unsigned EltNum = 0; EltNum < ALen; EltNum += 1) {
12730 APInt CElt =
C.getVectorElt(EltNum).getInt().trunc(52);
12731 APSInt ResElt(AElt + (BElt * CElt).zext(64),
false);
12732 ResultElements.push_back(
APValue(ResElt));
12735 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12737 case X86::BI__builtin_ia32_vpmadd52huq128:
12738 case X86::BI__builtin_ia32_vpmadd52huq256:
12739 case X86::BI__builtin_ia32_vpmadd52huq512: {
12748 ResultElements.reserve(ALen);
12750 for (
unsigned EltNum = 0; EltNum < ALen; EltNum += 1) {
12753 APInt CElt =
C.getVectorElt(EltNum).getInt().trunc(52);
12754 APSInt ResElt(AElt + llvm::APIntOps::mulhu(BElt, CElt).zext(64),
false);
12755 ResultElements.push_back(
APValue(ResElt));
12758 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12761 case clang::X86::BI__builtin_ia32_vprotbi:
12762 case clang::X86::BI__builtin_ia32_vprotdi:
12763 case clang::X86::BI__builtin_ia32_vprotqi:
12764 case clang::X86::BI__builtin_ia32_vprotwi:
12765 case clang::X86::BI__builtin_ia32_prold128:
12766 case clang::X86::BI__builtin_ia32_prold256:
12767 case clang::X86::BI__builtin_ia32_prold512:
12768 case clang::X86::BI__builtin_ia32_prolq128:
12769 case clang::X86::BI__builtin_ia32_prolq256:
12770 case clang::X86::BI__builtin_ia32_prolq512:
12771 return EvaluateBinOpExpr(
12772 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS.rotl(RHS); });
12774 case clang::X86::BI__builtin_ia32_prord128:
12775 case clang::X86::BI__builtin_ia32_prord256:
12776 case clang::X86::BI__builtin_ia32_prord512:
12777 case clang::X86::BI__builtin_ia32_prorq128:
12778 case clang::X86::BI__builtin_ia32_prorq256:
12779 case clang::X86::BI__builtin_ia32_prorq512:
12780 return EvaluateBinOpExpr(
12781 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS.rotr(RHS); });
12783 case Builtin::BI__builtin_elementwise_max:
12784 case Builtin::BI__builtin_elementwise_min: {
12785 APValue SourceLHS, SourceRHS;
12790 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12797 ResultElements.reserve(SourceLen);
12799 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12803 case Builtin::BI__builtin_elementwise_max:
12804 ResultElements.push_back(
12808 case Builtin::BI__builtin_elementwise_min:
12809 ResultElements.push_back(
12816 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12818 case X86::BI__builtin_ia32_vpshldd128:
12819 case X86::BI__builtin_ia32_vpshldd256:
12820 case X86::BI__builtin_ia32_vpshldd512:
12821 case X86::BI__builtin_ia32_vpshldq128:
12822 case X86::BI__builtin_ia32_vpshldq256:
12823 case X86::BI__builtin_ia32_vpshldq512:
12824 case X86::BI__builtin_ia32_vpshldw128:
12825 case X86::BI__builtin_ia32_vpshldw256:
12826 case X86::BI__builtin_ia32_vpshldw512: {
12827 APValue SourceHi, SourceLo, SourceAmt;
12833 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12836 ResultElements.reserve(SourceLen);
12839 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12842 APInt R = llvm::APIntOps::fshl(Hi, Lo, Amt);
12843 ResultElements.push_back(
12847 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12849 case X86::BI__builtin_ia32_vpshrdd128:
12850 case X86::BI__builtin_ia32_vpshrdd256:
12851 case X86::BI__builtin_ia32_vpshrdd512:
12852 case X86::BI__builtin_ia32_vpshrdq128:
12853 case X86::BI__builtin_ia32_vpshrdq256:
12854 case X86::BI__builtin_ia32_vpshrdq512:
12855 case X86::BI__builtin_ia32_vpshrdw128:
12856 case X86::BI__builtin_ia32_vpshrdw256:
12857 case X86::BI__builtin_ia32_vpshrdw512: {
12859 APValue SourceHi, SourceLo, SourceAmt;
12865 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12868 ResultElements.reserve(SourceLen);
12871 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12874 APInt R = llvm::APIntOps::fshr(Hi, Lo, Amt);
12875 ResultElements.push_back(
12879 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12881 case X86::BI__builtin_ia32_compressdf128_mask:
12882 case X86::BI__builtin_ia32_compressdf256_mask:
12883 case X86::BI__builtin_ia32_compressdf512_mask:
12884 case X86::BI__builtin_ia32_compressdi128_mask:
12885 case X86::BI__builtin_ia32_compressdi256_mask:
12886 case X86::BI__builtin_ia32_compressdi512_mask:
12887 case X86::BI__builtin_ia32_compresshi128_mask:
12888 case X86::BI__builtin_ia32_compresshi256_mask:
12889 case X86::BI__builtin_ia32_compresshi512_mask:
12890 case X86::BI__builtin_ia32_compressqi128_mask:
12891 case X86::BI__builtin_ia32_compressqi256_mask:
12892 case X86::BI__builtin_ia32_compressqi512_mask:
12893 case X86::BI__builtin_ia32_compresssf128_mask:
12894 case X86::BI__builtin_ia32_compresssf256_mask:
12895 case X86::BI__builtin_ia32_compresssf512_mask:
12896 case X86::BI__builtin_ia32_compresssi128_mask:
12897 case X86::BI__builtin_ia32_compresssi256_mask:
12898 case X86::BI__builtin_ia32_compresssi512_mask: {
12909 ResultElements.reserve(NumElts);
12911 for (
unsigned I = 0; I != NumElts; ++I) {
12915 for (
unsigned I = ResultElements.size(); I != NumElts; ++I) {
12919 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12921 case X86::BI__builtin_ia32_expanddf128_mask:
12922 case X86::BI__builtin_ia32_expanddf256_mask:
12923 case X86::BI__builtin_ia32_expanddf512_mask:
12924 case X86::BI__builtin_ia32_expanddi128_mask:
12925 case X86::BI__builtin_ia32_expanddi256_mask:
12926 case X86::BI__builtin_ia32_expanddi512_mask:
12927 case X86::BI__builtin_ia32_expandhi128_mask:
12928 case X86::BI__builtin_ia32_expandhi256_mask:
12929 case X86::BI__builtin_ia32_expandhi512_mask:
12930 case X86::BI__builtin_ia32_expandqi128_mask:
12931 case X86::BI__builtin_ia32_expandqi256_mask:
12932 case X86::BI__builtin_ia32_expandqi512_mask:
12933 case X86::BI__builtin_ia32_expandsf128_mask:
12934 case X86::BI__builtin_ia32_expandsf256_mask:
12935 case X86::BI__builtin_ia32_expandsf512_mask:
12936 case X86::BI__builtin_ia32_expandsi128_mask:
12937 case X86::BI__builtin_ia32_expandsi256_mask:
12938 case X86::BI__builtin_ia32_expandsi512_mask: {
12949 ResultElements.reserve(NumElts);
12951 unsigned SourceIdx = 0;
12952 for (
unsigned I = 0; I != NumElts; ++I) {
12954 ResultElements.push_back(Source.
getVectorElt(SourceIdx++));
12958 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12960 case X86::BI__builtin_ia32_vpconflictsi_128:
12961 case X86::BI__builtin_ia32_vpconflictsi_256:
12962 case X86::BI__builtin_ia32_vpconflictsi_512:
12963 case X86::BI__builtin_ia32_vpconflictdi_128:
12964 case X86::BI__builtin_ia32_vpconflictdi_256:
12965 case X86::BI__builtin_ia32_vpconflictdi_512: {
12973 ResultElements.reserve(SourceLen);
12976 bool DestUnsigned =
12977 VecT->getElementType()->isUnsignedIntegerOrEnumerationType();
12979 for (
unsigned I = 0; I != SourceLen; ++I) {
12982 APInt ConflictMask(EltI.
getInt().getBitWidth(), 0);
12983 for (
unsigned J = 0; J != I; ++J) {
12985 ConflictMask.setBitVal(J, EltI.
getInt() == EltJ.
getInt());
12987 ResultElements.push_back(
APValue(
APSInt(ConflictMask, DestUnsigned)));
12989 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12991 case X86::BI__builtin_ia32_blendpd:
12992 case X86::BI__builtin_ia32_blendpd256:
12993 case X86::BI__builtin_ia32_blendps:
12994 case X86::BI__builtin_ia32_blendps256:
12995 case X86::BI__builtin_ia32_pblendw128:
12996 case X86::BI__builtin_ia32_pblendw256:
12997 case X86::BI__builtin_ia32_pblendd128:
12998 case X86::BI__builtin_ia32_pblendd256: {
12999 APValue SourceF, SourceT, SourceC;
13008 ResultElements.reserve(SourceLen);
13009 for (
unsigned EltNum = 0; EltNum != SourceLen; ++EltNum) {
13012 ResultElements.push_back(
C[EltNum % 8] ? T : F);
13015 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13018 case X86::BI__builtin_ia32_psignb128:
13019 case X86::BI__builtin_ia32_psignb256:
13020 case X86::BI__builtin_ia32_psignw128:
13021 case X86::BI__builtin_ia32_psignw256:
13022 case X86::BI__builtin_ia32_psignd128:
13023 case X86::BI__builtin_ia32_psignd256:
13024 return EvaluateBinOpExpr([](
const APInt &AElem,
const APInt &BElem) {
13025 if (BElem.isZero())
13026 return APInt::getZero(AElem.getBitWidth());
13027 if (BElem.isNegative())
13032 case X86::BI__builtin_ia32_blendvpd:
13033 case X86::BI__builtin_ia32_blendvpd256:
13034 case X86::BI__builtin_ia32_blendvps:
13035 case X86::BI__builtin_ia32_blendvps256:
13036 case X86::BI__builtin_ia32_pblendvb128:
13037 case X86::BI__builtin_ia32_pblendvb256: {
13039 APValue SourceF, SourceT, SourceC;
13047 ResultElements.reserve(SourceLen);
13049 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13053 APInt M =
C.isInt() ? (
APInt)
C.getInt() :
C.getFloat().bitcastToAPInt();
13054 ResultElements.push_back(M.isNegative() ? T : F);
13057 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13059 case X86::BI__builtin_ia32_selectb_128:
13060 case X86::BI__builtin_ia32_selectb_256:
13061 case X86::BI__builtin_ia32_selectb_512:
13062 case X86::BI__builtin_ia32_selectw_128:
13063 case X86::BI__builtin_ia32_selectw_256:
13064 case X86::BI__builtin_ia32_selectw_512:
13065 case X86::BI__builtin_ia32_selectd_128:
13066 case X86::BI__builtin_ia32_selectd_256:
13067 case X86::BI__builtin_ia32_selectd_512:
13068 case X86::BI__builtin_ia32_selectq_128:
13069 case X86::BI__builtin_ia32_selectq_256:
13070 case X86::BI__builtin_ia32_selectq_512:
13071 case X86::BI__builtin_ia32_selectph_128:
13072 case X86::BI__builtin_ia32_selectph_256:
13073 case X86::BI__builtin_ia32_selectph_512:
13074 case X86::BI__builtin_ia32_selectpbf_128:
13075 case X86::BI__builtin_ia32_selectpbf_256:
13076 case X86::BI__builtin_ia32_selectpbf_512:
13077 case X86::BI__builtin_ia32_selectps_128:
13078 case X86::BI__builtin_ia32_selectps_256:
13079 case X86::BI__builtin_ia32_selectps_512:
13080 case X86::BI__builtin_ia32_selectpd_128:
13081 case X86::BI__builtin_ia32_selectpd_256:
13082 case X86::BI__builtin_ia32_selectpd_512: {
13084 APValue SourceMask, SourceLHS, SourceRHS;
13093 ResultElements.reserve(SourceLen);
13095 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13098 ResultElements.push_back(Mask[EltNum] ? LHS : RHS);
13101 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13104 case X86::BI__builtin_ia32_cvtsd2ss: {
13117 Elements.push_back(ResultVal);
13120 for (
unsigned I = 1; I < NumEltsA; ++I) {
13126 case X86::BI__builtin_ia32_cvtsd2ss_round_mask: {
13127 APValue VecA, VecB, VecSrc, MaskValue;
13135 unsigned Mask = MaskValue.
getInt().getZExtValue();
13143 Elements.push_back(ResultVal);
13149 for (
unsigned I = 1; I < NumEltsA; ++I) {
13155 case X86::BI__builtin_ia32_cvtpd2ps:
13156 case X86::BI__builtin_ia32_cvtpd2ps256:
13157 case X86::BI__builtin_ia32_cvtpd2ps_mask:
13158 case X86::BI__builtin_ia32_cvtpd2ps512_mask: {
13161 bool IsMasked = (BuiltinID == X86::BI__builtin_ia32_cvtpd2ps_mask ||
13162 BuiltinID == X86::BI__builtin_ia32_cvtpd2ps512_mask);
13169 unsigned Mask = 0xFFFFFFFF;
13170 bool NeedsMerge =
false;
13175 Mask = MaskValue.
getInt().getZExtValue();
13176 auto NumEltsResult = E->
getType()->
getAs<VectorType>()->getNumElements();
13177 for (
unsigned I = 0; I < NumEltsResult; ++I) {
13178 if (!((Mask >> I) & 1)) {
13189 unsigned NumEltsResult =
13193 for (
unsigned I = 0; I < NumEltsResult; ++I) {
13194 if (IsMasked && !((Mask >> I) & 1)) {
13202 if (I >= NumEltsInput) {
13203 Elements.push_back(
APValue(APFloat::getZero(APFloat::IEEEsingle())));
13212 Elements.push_back(ResultVal);
13217 case X86::BI__builtin_ia32_shufps:
13218 case X86::BI__builtin_ia32_shufps256:
13219 case X86::BI__builtin_ia32_shufps512: {
13223 [](
unsigned DstIdx,
13224 unsigned ShuffleMask) -> std::pair<unsigned, int> {
13225 constexpr unsigned LaneBits = 128u;
13226 unsigned NumElemPerLane = LaneBits / 32;
13227 unsigned NumSelectableElems = NumElemPerLane / 2;
13228 unsigned BitsPerElem = 2;
13229 unsigned IndexMask = (1u << BitsPerElem) - 1;
13230 unsigned MaskBits = 8;
13231 unsigned Lane = DstIdx / NumElemPerLane;
13232 unsigned ElemInLane = DstIdx % NumElemPerLane;
13233 unsigned LaneOffset = Lane * NumElemPerLane;
13234 unsigned BitIndex = (DstIdx * BitsPerElem) % MaskBits;
13235 unsigned SrcIdx = (ElemInLane < NumSelectableElems) ? 0 : 1;
13236 unsigned Index = (ShuffleMask >> BitIndex) & IndexMask;
13237 return {SrcIdx,
static_cast<int>(LaneOffset + Index)};
13242 case X86::BI__builtin_ia32_shufpd:
13243 case X86::BI__builtin_ia32_shufpd256:
13244 case X86::BI__builtin_ia32_shufpd512: {
13248 [](
unsigned DstIdx,
13249 unsigned ShuffleMask) -> std::pair<unsigned, int> {
13250 constexpr unsigned LaneBits = 128u;
13251 unsigned NumElemPerLane = LaneBits / 64;
13252 unsigned NumSelectableElems = NumElemPerLane / 2;
13253 unsigned BitsPerElem = 1;
13254 unsigned IndexMask = (1u << BitsPerElem) - 1;
13255 unsigned MaskBits = 8;
13256 unsigned Lane = DstIdx / NumElemPerLane;
13257 unsigned ElemInLane = DstIdx % NumElemPerLane;
13258 unsigned LaneOffset = Lane * NumElemPerLane;
13259 unsigned BitIndex = (DstIdx * BitsPerElem) % MaskBits;
13260 unsigned SrcIdx = (ElemInLane < NumSelectableElems) ? 0 : 1;
13261 unsigned Index = (ShuffleMask >> BitIndex) & IndexMask;
13262 return {SrcIdx,
static_cast<int>(LaneOffset + Index)};
13267 case X86::BI__builtin_ia32_insertps128: {
13271 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13273 if ((Mask & (1 << DstIdx)) != 0) {
13278 unsigned SrcElem = (Mask >> 6) & 0x3;
13279 unsigned DstElem = (Mask >> 4) & 0x3;
13280 if (DstIdx == DstElem) {
13282 return {1,
static_cast<int>(SrcElem)};
13285 return {0,
static_cast<int>(DstIdx)};
13291 case X86::BI__builtin_ia32_pshufb128:
13292 case X86::BI__builtin_ia32_pshufb256:
13293 case X86::BI__builtin_ia32_pshufb512: {
13297 [](
unsigned DstIdx,
13298 unsigned ShuffleMask) -> std::pair<unsigned, int> {
13299 uint8_t Ctlb =
static_cast<uint8_t
>(ShuffleMask);
13301 return std::make_pair(0, -1);
13303 unsigned LaneBase = (DstIdx / 16) * 16;
13304 unsigned SrcOffset = Ctlb & 0x0F;
13305 unsigned SrcIdx = LaneBase + SrcOffset;
13306 return std::make_pair(0,
static_cast<int>(SrcIdx));
13312 case X86::BI__builtin_ia32_pshuflw:
13313 case X86::BI__builtin_ia32_pshuflw256:
13314 case X86::BI__builtin_ia32_pshuflw512: {
13318 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13319 constexpr unsigned LaneBits = 128u;
13320 constexpr unsigned ElemBits = 16u;
13321 constexpr unsigned LaneElts = LaneBits / ElemBits;
13322 constexpr unsigned HalfSize = 4;
13323 unsigned LaneBase = (DstIdx / LaneElts) * LaneElts;
13324 unsigned LaneIdx = DstIdx % LaneElts;
13325 if (LaneIdx < HalfSize) {
13326 unsigned Sel = (Mask >> (2 * LaneIdx)) & 0x3;
13327 return std::make_pair(0,
static_cast<int>(LaneBase + Sel));
13329 return std::make_pair(0,
static_cast<int>(DstIdx));
13335 case X86::BI__builtin_ia32_pshufhw:
13336 case X86::BI__builtin_ia32_pshufhw256:
13337 case X86::BI__builtin_ia32_pshufhw512: {
13341 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13342 constexpr unsigned LaneBits = 128u;
13343 constexpr unsigned ElemBits = 16u;
13344 constexpr unsigned LaneElts = LaneBits / ElemBits;
13345 constexpr unsigned HalfSize = 4;
13346 unsigned LaneBase = (DstIdx / LaneElts) * LaneElts;
13347 unsigned LaneIdx = DstIdx % LaneElts;
13348 if (LaneIdx >= HalfSize) {
13349 unsigned Rel = LaneIdx - HalfSize;
13350 unsigned Sel = (Mask >> (2 * Rel)) & 0x3;
13351 return std::make_pair(
13352 0,
static_cast<int>(LaneBase + HalfSize + Sel));
13354 return std::make_pair(0,
static_cast<int>(DstIdx));
13360 case X86::BI__builtin_ia32_pshufd:
13361 case X86::BI__builtin_ia32_pshufd256:
13362 case X86::BI__builtin_ia32_pshufd512:
13363 case X86::BI__builtin_ia32_vpermilps:
13364 case X86::BI__builtin_ia32_vpermilps256:
13365 case X86::BI__builtin_ia32_vpermilps512: {
13369 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13370 constexpr unsigned LaneBits = 128u;
13371 constexpr unsigned ElemBits = 32u;
13372 constexpr unsigned LaneElts = LaneBits / ElemBits;
13373 unsigned LaneBase = (DstIdx / LaneElts) * LaneElts;
13374 unsigned LaneIdx = DstIdx % LaneElts;
13375 unsigned Sel = (Mask >> (2 * LaneIdx)) & 0x3;
13376 return std::make_pair(0,
static_cast<int>(LaneBase + Sel));
13382 case X86::BI__builtin_ia32_vpermilvarpd:
13383 case X86::BI__builtin_ia32_vpermilvarpd256:
13384 case X86::BI__builtin_ia32_vpermilvarpd512: {
13388 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13389 unsigned NumElemPerLane = 2;
13390 unsigned Lane = DstIdx / NumElemPerLane;
13391 unsigned Offset = Mask & 0b10 ? 1 : 0;
13392 return std::make_pair(
13393 0,
static_cast<int>(Lane * NumElemPerLane + Offset));
13399 case X86::BI__builtin_ia32_vpermilpd:
13400 case X86::BI__builtin_ia32_vpermilpd256:
13401 case X86::BI__builtin_ia32_vpermilpd512: {
13404 unsigned NumElemPerLane = 2;
13405 unsigned BitsPerElem = 1;
13406 unsigned MaskBits = 8;
13407 unsigned IndexMask = 0x1;
13408 unsigned Lane = DstIdx / NumElemPerLane;
13409 unsigned LaneOffset = Lane * NumElemPerLane;
13410 unsigned BitIndex = (DstIdx * BitsPerElem) % MaskBits;
13411 unsigned Index = (Control >> BitIndex) & IndexMask;
13412 return std::make_pair(0,
static_cast<int>(LaneOffset + Index));
13418 case X86::BI__builtin_ia32_permdf256:
13419 case X86::BI__builtin_ia32_permdi256: {
13424 unsigned Index = (Control >> (2 * DstIdx)) & 0x3;
13425 return std::make_pair(0,
static_cast<int>(Index));
13431 case X86::BI__builtin_ia32_vpermilvarps:
13432 case X86::BI__builtin_ia32_vpermilvarps256:
13433 case X86::BI__builtin_ia32_vpermilvarps512: {
13437 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13438 unsigned NumElemPerLane = 4;
13439 unsigned Lane = DstIdx / NumElemPerLane;
13440 unsigned Offset = Mask & 0b11;
13441 return std::make_pair(
13442 0,
static_cast<int>(Lane * NumElemPerLane + Offset));
13448 case X86::BI__builtin_ia32_vpmultishiftqb128:
13449 case X86::BI__builtin_ia32_vpmultishiftqb256:
13450 case X86::BI__builtin_ia32_vpmultishiftqb512: {
13458 unsigned NumBytesInQWord = 8;
13459 unsigned NumBitsInByte = 8;
13461 unsigned NumQWords = NumBytes / NumBytesInQWord;
13463 Result.reserve(NumBytes);
13465 for (
unsigned QWordId = 0; QWordId != NumQWords; ++QWordId) {
13466 APInt BQWord(64, 0);
13467 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
13468 unsigned Idx = QWordId * NumBytesInQWord + ByteIdx;
13470 BQWord.insertBits(
APInt(8, Byte & 0xFF), ByteIdx * NumBitsInByte);
13473 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
13474 unsigned Idx = QWordId * NumBytesInQWord + ByteIdx;
13478 for (
unsigned BitIdx = 0; BitIdx != NumBitsInByte; ++BitIdx) {
13479 Byte.setBitVal(BitIdx, BQWord[(Ctrl + BitIdx) & 0x3F]);
13487 case X86::BI__builtin_ia32_phminposuw128: {
13494 unsigned ElemBitWidth = Info.Ctx.getTypeSize(ElemQT);
13496 APInt MinIndex(ElemBitWidth, 0);
13498 for (
unsigned I = 1; I != SourceLen; ++I) {
13500 if (MinVal.ugt(Val)) {
13509 ->isUnsignedIntegerOrEnumerationType();
13512 Result.reserve(SourceLen);
13514 Result.emplace_back(
APSInt(MinIndex, ResultUnsigned));
13515 for (
unsigned I = 0; I != SourceLen - 2; ++I) {
13521 case X86::BI__builtin_ia32_psraq128:
13522 case X86::BI__builtin_ia32_psraq256:
13523 case X86::BI__builtin_ia32_psraq512:
13524 case X86::BI__builtin_ia32_psrad128:
13525 case X86::BI__builtin_ia32_psrad256:
13526 case X86::BI__builtin_ia32_psrad512:
13527 case X86::BI__builtin_ia32_psraw128:
13528 case X86::BI__builtin_ia32_psraw256:
13529 case X86::BI__builtin_ia32_psraw512: {
13533 [](
const APInt &Elt, uint64_t Count) {
return Elt.ashr(Count); },
13534 [](
const APInt &Elt,
unsigned Width) {
13535 return Elt.ashr(Width - 1);
13541 case X86::BI__builtin_ia32_psllq128:
13542 case X86::BI__builtin_ia32_psllq256:
13543 case X86::BI__builtin_ia32_psllq512:
13544 case X86::BI__builtin_ia32_pslld128:
13545 case X86::BI__builtin_ia32_pslld256:
13546 case X86::BI__builtin_ia32_pslld512:
13547 case X86::BI__builtin_ia32_psllw128:
13548 case X86::BI__builtin_ia32_psllw256:
13549 case X86::BI__builtin_ia32_psllw512: {
13553 [](
const APInt &Elt, uint64_t Count) {
return Elt.shl(Count); },
13554 [](
const APInt &Elt,
unsigned Width) {
13555 return APInt::getZero(Width);
13561 case X86::BI__builtin_ia32_psrlq128:
13562 case X86::BI__builtin_ia32_psrlq256:
13563 case X86::BI__builtin_ia32_psrlq512:
13564 case X86::BI__builtin_ia32_psrld128:
13565 case X86::BI__builtin_ia32_psrld256:
13566 case X86::BI__builtin_ia32_psrld512:
13567 case X86::BI__builtin_ia32_psrlw128:
13568 case X86::BI__builtin_ia32_psrlw256:
13569 case X86::BI__builtin_ia32_psrlw512: {
13573 [](
const APInt &Elt, uint64_t Count) {
return Elt.lshr(Count); },
13574 [](
const APInt &Elt,
unsigned Width) {
13575 return APInt::getZero(Width);
13581 case X86::BI__builtin_ia32_pternlogd128_mask:
13582 case X86::BI__builtin_ia32_pternlogd256_mask:
13583 case X86::BI__builtin_ia32_pternlogd512_mask:
13584 case X86::BI__builtin_ia32_pternlogq128_mask:
13585 case X86::BI__builtin_ia32_pternlogq256_mask:
13586 case X86::BI__builtin_ia32_pternlogq512_mask: {
13587 APValue AValue, BValue, CValue, ImmValue, UValue;
13595 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13601 ResultElements.reserve(ResultLen);
13603 for (
unsigned EltNum = 0; EltNum < ResultLen; ++EltNum) {
13609 unsigned BitWidth = ALane.getBitWidth();
13610 APInt ResLane(BitWidth, 0);
13612 for (
unsigned Bit = 0; Bit < BitWidth; ++Bit) {
13613 unsigned ABit = ALane[Bit];
13614 unsigned BBit = BLane[Bit];
13615 unsigned CBit = CLane[Bit];
13617 unsigned Idx = (ABit << 2) | (BBit << 1) | CBit;
13618 ResLane.setBitVal(Bit, Imm[Idx]);
13620 ResultElements.push_back(
APValue(
APSInt(ResLane, DestUnsigned)));
13622 ResultElements.push_back(
APValue(
APSInt(ALane, DestUnsigned)));
13625 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13627 case X86::BI__builtin_ia32_pternlogd128_maskz:
13628 case X86::BI__builtin_ia32_pternlogd256_maskz:
13629 case X86::BI__builtin_ia32_pternlogd512_maskz:
13630 case X86::BI__builtin_ia32_pternlogq128_maskz:
13631 case X86::BI__builtin_ia32_pternlogq256_maskz:
13632 case X86::BI__builtin_ia32_pternlogq512_maskz: {
13633 APValue AValue, BValue, CValue, ImmValue, UValue;
13641 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13647 ResultElements.reserve(ResultLen);
13649 for (
unsigned EltNum = 0; EltNum < ResultLen; ++EltNum) {
13654 unsigned BitWidth = ALane.getBitWidth();
13655 APInt ResLane(BitWidth, 0);
13658 for (
unsigned Bit = 0; Bit < BitWidth; ++Bit) {
13659 unsigned ABit = ALane[Bit];
13660 unsigned BBit = BLane[Bit];
13661 unsigned CBit = CLane[Bit];
13663 unsigned Idx = (ABit << 2) | (BBit << 1) | CBit;
13664 ResLane.setBitVal(Bit, Imm[Idx]);
13667 ResultElements.push_back(
APValue(
APSInt(ResLane, DestUnsigned)));
13669 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13672 case Builtin::BI__builtin_elementwise_clzg:
13673 case Builtin::BI__builtin_elementwise_ctzg: {
13675 std::optional<APValue> Fallback;
13682 Fallback = FallbackTmp;
13685 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13688 ResultElements.reserve(SourceLen);
13690 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13695 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
13697 Builtin::BI__builtin_elementwise_ctzg);
13700 ResultElements.push_back(Fallback->getVectorElt(EltNum));
13704 case Builtin::BI__builtin_elementwise_clzg:
13705 ResultElements.push_back(
APValue(
13706 APSInt(
APInt(Info.Ctx.getIntWidth(DestEltTy), LHS.countl_zero()),
13709 case Builtin::BI__builtin_elementwise_ctzg:
13710 ResultElements.push_back(
APValue(
13711 APSInt(
APInt(Info.Ctx.getIntWidth(DestEltTy), LHS.countr_zero()),
13717 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13720 case Builtin::BI__builtin_elementwise_fma: {
13721 APValue SourceX, SourceY, SourceZ;
13729 ResultElements.reserve(SourceLen);
13731 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13736 (void)
Result.fusedMultiplyAdd(Y, Z, RM);
13739 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13742 case clang::X86::BI__builtin_ia32_phaddw128:
13743 case clang::X86::BI__builtin_ia32_phaddw256:
13744 case clang::X86::BI__builtin_ia32_phaddd128:
13745 case clang::X86::BI__builtin_ia32_phaddd256:
13746 case clang::X86::BI__builtin_ia32_phaddsw128:
13747 case clang::X86::BI__builtin_ia32_phaddsw256:
13749 case clang::X86::BI__builtin_ia32_phsubw128:
13750 case clang::X86::BI__builtin_ia32_phsubw256:
13751 case clang::X86::BI__builtin_ia32_phsubd128:
13752 case clang::X86::BI__builtin_ia32_phsubd256:
13753 case clang::X86::BI__builtin_ia32_phsubsw128:
13754 case clang::X86::BI__builtin_ia32_phsubsw256: {
13755 APValue SourceLHS, SourceRHS;
13759 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13763 unsigned EltBits = Info.Ctx.getIntWidth(DestEltTy);
13764 unsigned EltsPerLane = 128 / EltBits;
13766 ResultElements.reserve(NumElts);
13768 for (
unsigned LaneStart = 0; LaneStart != NumElts;
13769 LaneStart += EltsPerLane) {
13770 for (
unsigned I = 0; I != EltsPerLane; I += 2) {
13774 case clang::X86::BI__builtin_ia32_phaddw128:
13775 case clang::X86::BI__builtin_ia32_phaddw256:
13776 case clang::X86::BI__builtin_ia32_phaddd128:
13777 case clang::X86::BI__builtin_ia32_phaddd256: {
13778 APSInt Res(LHSA + LHSB, DestUnsigned);
13779 ResultElements.push_back(
APValue(Res));
13782 case clang::X86::BI__builtin_ia32_phaddsw128:
13783 case clang::X86::BI__builtin_ia32_phaddsw256: {
13784 APSInt Res(LHSA.sadd_sat(LHSB));
13785 ResultElements.push_back(
APValue(Res));
13788 case clang::X86::BI__builtin_ia32_phsubw128:
13789 case clang::X86::BI__builtin_ia32_phsubw256:
13790 case clang::X86::BI__builtin_ia32_phsubd128:
13791 case clang::X86::BI__builtin_ia32_phsubd256: {
13792 APSInt Res(LHSA - LHSB, DestUnsigned);
13793 ResultElements.push_back(
APValue(Res));
13796 case clang::X86::BI__builtin_ia32_phsubsw128:
13797 case clang::X86::BI__builtin_ia32_phsubsw256: {
13798 APSInt Res(LHSA.ssub_sat(LHSB));
13799 ResultElements.push_back(
APValue(Res));
13804 for (
unsigned I = 0; I != EltsPerLane; I += 2) {
13808 case clang::X86::BI__builtin_ia32_phaddw128:
13809 case clang::X86::BI__builtin_ia32_phaddw256:
13810 case clang::X86::BI__builtin_ia32_phaddd128:
13811 case clang::X86::BI__builtin_ia32_phaddd256: {
13812 APSInt Res(RHSA + RHSB, DestUnsigned);
13813 ResultElements.push_back(
APValue(Res));
13816 case clang::X86::BI__builtin_ia32_phaddsw128:
13817 case clang::X86::BI__builtin_ia32_phaddsw256: {
13818 APSInt Res(RHSA.sadd_sat(RHSB));
13819 ResultElements.push_back(
APValue(Res));
13822 case clang::X86::BI__builtin_ia32_phsubw128:
13823 case clang::X86::BI__builtin_ia32_phsubw256:
13824 case clang::X86::BI__builtin_ia32_phsubd128:
13825 case clang::X86::BI__builtin_ia32_phsubd256: {
13826 APSInt Res(RHSA - RHSB, DestUnsigned);
13827 ResultElements.push_back(
APValue(Res));
13830 case clang::X86::BI__builtin_ia32_phsubsw128:
13831 case clang::X86::BI__builtin_ia32_phsubsw256: {
13832 APSInt Res(RHSA.ssub_sat(RHSB));
13833 ResultElements.push_back(
APValue(Res));
13839 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13841 case clang::X86::BI__builtin_ia32_haddpd:
13842 case clang::X86::BI__builtin_ia32_haddps:
13843 case clang::X86::BI__builtin_ia32_haddps256:
13844 case clang::X86::BI__builtin_ia32_haddpd256:
13845 case clang::X86::BI__builtin_ia32_hsubpd:
13846 case clang::X86::BI__builtin_ia32_hsubps:
13847 case clang::X86::BI__builtin_ia32_hsubps256:
13848 case clang::X86::BI__builtin_ia32_hsubpd256: {
13849 APValue SourceLHS, SourceRHS;
13855 ResultElements.reserve(NumElts);
13857 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13858 unsigned EltBits = Info.Ctx.getTypeSize(DestEltTy);
13859 unsigned NumLanes = NumElts * EltBits / 128;
13860 unsigned NumElemsPerLane = NumElts / NumLanes;
13861 unsigned HalfElemsPerLane = NumElemsPerLane / 2;
13863 for (
unsigned L = 0; L != NumElts; L += NumElemsPerLane) {
13864 for (
unsigned I = 0; I != HalfElemsPerLane; ++I) {
13868 case clang::X86::BI__builtin_ia32_haddpd:
13869 case clang::X86::BI__builtin_ia32_haddps:
13870 case clang::X86::BI__builtin_ia32_haddps256:
13871 case clang::X86::BI__builtin_ia32_haddpd256:
13872 LHSA.add(LHSB, RM);
13874 case clang::X86::BI__builtin_ia32_hsubpd:
13875 case clang::X86::BI__builtin_ia32_hsubps:
13876 case clang::X86::BI__builtin_ia32_hsubps256:
13877 case clang::X86::BI__builtin_ia32_hsubpd256:
13878 LHSA.subtract(LHSB, RM);
13881 ResultElements.push_back(
APValue(LHSA));
13883 for (
unsigned I = 0; I != HalfElemsPerLane; ++I) {
13887 case clang::X86::BI__builtin_ia32_haddpd:
13888 case clang::X86::BI__builtin_ia32_haddps:
13889 case clang::X86::BI__builtin_ia32_haddps256:
13890 case clang::X86::BI__builtin_ia32_haddpd256:
13891 RHSA.add(RHSB, RM);
13893 case clang::X86::BI__builtin_ia32_hsubpd:
13894 case clang::X86::BI__builtin_ia32_hsubps:
13895 case clang::X86::BI__builtin_ia32_hsubps256:
13896 case clang::X86::BI__builtin_ia32_hsubpd256:
13897 RHSA.subtract(RHSB, RM);
13900 ResultElements.push_back(
APValue(RHSA));
13903 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13905 case clang::X86::BI__builtin_ia32_addsubpd:
13906 case clang::X86::BI__builtin_ia32_addsubps:
13907 case clang::X86::BI__builtin_ia32_addsubpd256:
13908 case clang::X86::BI__builtin_ia32_addsubps256: {
13911 APValue SourceLHS, SourceRHS;
13917 ResultElements.reserve(NumElems);
13920 for (
unsigned I = 0; I != NumElems; ++I) {
13925 LHS.subtract(RHS, RM);
13930 ResultElements.push_back(
APValue(LHS));
13932 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13934 case clang::X86::BI__builtin_ia32_pclmulqdq128:
13935 case clang::X86::BI__builtin_ia32_pclmulqdq256:
13936 case clang::X86::BI__builtin_ia32_pclmulqdq512: {
13940 APValue SourceLHS, SourceRHS;
13950 bool SelectUpperA = (Imm8 & 0x01) != 0;
13951 bool SelectUpperB = (Imm8 & 0x10) != 0;
13955 ResultElements.reserve(NumElems);
13956 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13960 for (
unsigned Lane = 0; Lane < NumElems; Lane += 2) {
13969 APInt A = SelectUpperA ? A1 : A0;
13970 APInt B = SelectUpperB ? B1 : B0;
13973 APInt A128 = A.zext(128);
13974 APInt B128 = B.zext(128);
13977 APInt Result = llvm::APIntOps::clmul(A128, B128);
13980 APSInt ResultLow(
Result.extractBits(64, 0), DestUnsigned);
13981 APSInt ResultHigh(
Result.extractBits(64, 64), DestUnsigned);
13983 ResultElements.push_back(
APValue(ResultLow));
13984 ResultElements.push_back(
APValue(ResultHigh));
13987 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13989 case Builtin::BI__builtin_elementwise_fshl:
13990 case Builtin::BI__builtin_elementwise_fshr: {
13991 APValue SourceHi, SourceLo, SourceShift;
13997 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14003 ResultElements.reserve(SourceLen);
14004 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
14009 case Builtin::BI__builtin_elementwise_fshl:
14010 ResultElements.push_back(
APValue(
14011 APSInt(llvm::APIntOps::fshl(Hi, Lo, Shift), Hi.isUnsigned())));
14013 case Builtin::BI__builtin_elementwise_fshr:
14014 ResultElements.push_back(
APValue(
14015 APSInt(llvm::APIntOps::fshr(Hi, Lo, Shift), Hi.isUnsigned())));
14020 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14023 case X86::BI__builtin_ia32_shuf_f32x4_256:
14024 case X86::BI__builtin_ia32_shuf_i32x4_256:
14025 case X86::BI__builtin_ia32_shuf_f64x2_256:
14026 case X86::BI__builtin_ia32_shuf_i64x2_256:
14027 case X86::BI__builtin_ia32_shuf_f32x4:
14028 case X86::BI__builtin_ia32_shuf_i32x4:
14029 case X86::BI__builtin_ia32_shuf_f64x2:
14030 case X86::BI__builtin_ia32_shuf_i64x2: {
14044 unsigned ElemBits = Info.Ctx.getTypeSize(ElemQT);
14045 unsigned LaneBits = 128u;
14046 unsigned NumLanes = (NumElems * ElemBits) / LaneBits;
14047 unsigned NumElemsPerLane = LaneBits / ElemBits;
14051 ResultElements.reserve(DstLen);
14056 [NumLanes, NumElemsPerLane](
unsigned DstIdx,
unsigned ShuffleMask)
14057 -> std::pair<unsigned, int> {
14059 unsigned BitsPerElem = NumLanes / 2;
14060 unsigned IndexMask = (1u << BitsPerElem) - 1;
14061 unsigned Lane = DstIdx / NumElemsPerLane;
14062 unsigned SrcIdx = (Lane < NumLanes / 2) ? 0 : 1;
14063 unsigned BitIdx = BitsPerElem * Lane;
14064 unsigned SrcLaneIdx = (ShuffleMask >> BitIdx) & IndexMask;
14065 unsigned ElemInLane = DstIdx % NumElemsPerLane;
14066 unsigned IdxToPick = SrcLaneIdx * NumElemsPerLane + ElemInLane;
14067 return {SrcIdx, IdxToPick};
14073 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v16qi:
14074 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v32qi:
14075 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v64qi:
14076 case X86::BI__builtin_ia32_vgf2p8affineqb_v16qi:
14077 case X86::BI__builtin_ia32_vgf2p8affineqb_v32qi:
14078 case X86::BI__builtin_ia32_vgf2p8affineqb_v64qi: {
14090 bool IsInverse =
false;
14092 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v16qi:
14093 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v32qi:
14094 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v64qi: {
14099 unsigned NumBitsInByte = 8;
14100 unsigned NumBytesInQWord = 8;
14101 unsigned NumBitsInQWord = 64;
14103 unsigned NumQWords = NumBytes / NumBytesInQWord;
14105 Result.reserve(NumBytes);
14108 for (
unsigned QWordIdx = 0; QWordIdx != NumQWords; ++QWordIdx) {
14110 APInt XQWord(NumBitsInQWord, 0);
14111 APInt AQWord(NumBitsInQWord, 0);
14112 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
14113 unsigned Idx = QWordIdx * NumBytesInQWord + ByteIdx;
14114 APInt XByte =
X.getVectorElt(Idx).getInt();
14116 XQWord.insertBits(XByte, ByteIdx * NumBitsInByte);
14117 AQWord.insertBits(AByte, ByteIdx * NumBitsInByte);
14120 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
14122 XQWord.lshr(ByteIdx * NumBitsInByte).getLoBits(8).getZExtValue();
14131 case X86::BI__builtin_ia32_vgf2p8mulb_v16qi:
14132 case X86::BI__builtin_ia32_vgf2p8mulb_v32qi:
14133 case X86::BI__builtin_ia32_vgf2p8mulb_v64qi: {
14144 Result.reserve(NumBytes);
14146 for (
unsigned ByteIdx = 0; ByteIdx != NumBytes; ++ByteIdx) {
14156 case X86::BI__builtin_ia32_insertf32x4_256:
14157 case X86::BI__builtin_ia32_inserti32x4_256:
14158 case X86::BI__builtin_ia32_insertf64x2_256:
14159 case X86::BI__builtin_ia32_inserti64x2_256:
14160 case X86::BI__builtin_ia32_insertf32x4:
14161 case X86::BI__builtin_ia32_inserti32x4:
14162 case X86::BI__builtin_ia32_insertf64x2_512:
14163 case X86::BI__builtin_ia32_inserti64x2_512:
14164 case X86::BI__builtin_ia32_insertf32x8:
14165 case X86::BI__builtin_ia32_inserti32x8:
14166 case X86::BI__builtin_ia32_insertf64x4:
14167 case X86::BI__builtin_ia32_inserti64x4:
14168 case X86::BI__builtin_ia32_vinsertf128_ps256:
14169 case X86::BI__builtin_ia32_vinsertf128_pd256:
14170 case X86::BI__builtin_ia32_vinsertf128_si256:
14171 case X86::BI__builtin_ia32_insert128i256: {
14172 APValue SourceDst, SourceSub;
14184 assert(SubLen != 0 && DstLen != 0 && (DstLen % SubLen) == 0);
14185 unsigned NumLanes = DstLen / SubLen;
14186 unsigned LaneIdx = (Imm.getZExtValue() % NumLanes) * SubLen;
14189 ResultElements.reserve(DstLen);
14191 for (
unsigned EltNum = 0; EltNum < DstLen; ++EltNum) {
14192 if (EltNum >= LaneIdx && EltNum < LaneIdx + SubLen)
14193 ResultElements.push_back(SourceSub.
getVectorElt(EltNum - LaneIdx));
14195 ResultElements.push_back(SourceDst.
getVectorElt(EltNum));
14198 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14201 case clang::X86::BI__builtin_ia32_vec_set_v4hi:
14202 case clang::X86::BI__builtin_ia32_vec_set_v16qi:
14203 case clang::X86::BI__builtin_ia32_vec_set_v8hi:
14204 case clang::X86::BI__builtin_ia32_vec_set_v4si:
14205 case clang::X86::BI__builtin_ia32_vec_set_v2di:
14206 case clang::X86::BI__builtin_ia32_vec_set_v32qi:
14207 case clang::X86::BI__builtin_ia32_vec_set_v16hi:
14208 case clang::X86::BI__builtin_ia32_vec_set_v8si:
14209 case clang::X86::BI__builtin_ia32_vec_set_v4di: {
14217 QualType ElemTy = E->
getType()->
castAs<VectorType>()->getElementType();
14218 unsigned ElemWidth = Info.Ctx.getIntWidth(ElemTy);
14220 Scalar.setIsUnsigned(ElemUnsigned);
14226 static_cast<unsigned>(IndexAPS.getZExtValue() & (NumElems - 1));
14229 Elems.reserve(NumElems);
14230 for (
unsigned ElemNum = 0; ElemNum != NumElems; ++ElemNum)
14231 Elems.push_back(ElemNum == Index ? ElemAV : VecVal.
getVectorElt(ElemNum));
14236 case X86::BI__builtin_ia32_pslldqi128_byteshift:
14237 case X86::BI__builtin_ia32_pslldqi256_byteshift:
14238 case X86::BI__builtin_ia32_pslldqi512_byteshift: {
14242 [](
unsigned DstIdx,
unsigned Shift) -> std::pair<unsigned, int> {
14243 unsigned LaneBase = (DstIdx / 16) * 16;
14244 unsigned LaneIdx = DstIdx % 16;
14245 if (LaneIdx < Shift)
14246 return std::make_pair(0, -1);
14248 return std::make_pair(
14249 0,
static_cast<int>(LaneBase + LaneIdx - Shift));
14255 case X86::BI__builtin_ia32_psrldqi128_byteshift:
14256 case X86::BI__builtin_ia32_psrldqi256_byteshift:
14257 case X86::BI__builtin_ia32_psrldqi512_byteshift: {
14261 [](
unsigned DstIdx,
unsigned Shift) -> std::pair<unsigned, int> {
14262 unsigned LaneBase = (DstIdx / 16) * 16;
14263 unsigned LaneIdx = DstIdx % 16;
14264 if (LaneIdx + Shift < 16)
14265 return std::make_pair(
14266 0,
static_cast<int>(LaneBase + LaneIdx + Shift));
14268 return std::make_pair(0, -1);
14274 case X86::BI__builtin_ia32_palignr128:
14275 case X86::BI__builtin_ia32_palignr256:
14276 case X86::BI__builtin_ia32_palignr512: {
14280 unsigned VecIdx = 1;
14283 int Lane = DstIdx / 16;
14284 int Offset = DstIdx % 16;
14287 unsigned ShiftedIdx = Offset + (
Shift & 0xFF);
14288 if (ShiftedIdx < 16) {
14289 ElemIdx = ShiftedIdx + (Lane * 16);
14290 }
else if (ShiftedIdx < 32) {
14292 ElemIdx = (ShiftedIdx - 16) + (Lane * 16);
14295 return std::pair<unsigned, int>{VecIdx, ElemIdx};
14300 case X86::BI__builtin_ia32_alignd128:
14301 case X86::BI__builtin_ia32_alignd256:
14302 case X86::BI__builtin_ia32_alignd512:
14303 case X86::BI__builtin_ia32_alignq128:
14304 case X86::BI__builtin_ia32_alignq256:
14305 case X86::BI__builtin_ia32_alignq512: {
14307 unsigned NumElems = E->
getType()->
castAs<VectorType>()->getNumElements();
14309 [NumElems](
unsigned DstIdx,
unsigned Shift) {
14310 unsigned Imm =
Shift & 0xFF;
14311 unsigned EffectiveShift = Imm & (NumElems - 1);
14312 unsigned SourcePos = DstIdx + EffectiveShift;
14313 unsigned VecIdx = SourcePos < NumElems ? 1 : 0;
14314 unsigned ElemIdx = SourcePos & (NumElems - 1);
14316 return std::pair<unsigned, int>{
14317 VecIdx,
static_cast<int>(ElemIdx)};
14322 case X86::BI__builtin_ia32_permvarsi256:
14323 case X86::BI__builtin_ia32_permvarsf256:
14324 case X86::BI__builtin_ia32_permvardf512:
14325 case X86::BI__builtin_ia32_permvardi512:
14326 case X86::BI__builtin_ia32_permvarhi128: {
14329 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14330 int Offset = ShuffleMask & 0x7;
14331 return std::pair<unsigned, int>{0, Offset};
14336 case X86::BI__builtin_ia32_permvarqi128:
14337 case X86::BI__builtin_ia32_permvarhi256:
14338 case X86::BI__builtin_ia32_permvarsi512:
14339 case X86::BI__builtin_ia32_permvarsf512: {
14342 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14343 int Offset = ShuffleMask & 0xF;
14344 return std::pair<unsigned, int>{0, Offset};
14349 case X86::BI__builtin_ia32_permvardi256:
14350 case X86::BI__builtin_ia32_permvardf256: {
14353 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14354 int Offset = ShuffleMask & 0x3;
14355 return std::pair<unsigned, int>{0, Offset};
14360 case X86::BI__builtin_ia32_permvarqi256:
14361 case X86::BI__builtin_ia32_permvarhi512: {
14364 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14365 int Offset = ShuffleMask & 0x1F;
14366 return std::pair<unsigned, int>{0, Offset};
14371 case X86::BI__builtin_ia32_permvarqi512: {
14374 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14375 int Offset = ShuffleMask & 0x3F;
14376 return std::pair<unsigned, int>{0, Offset};
14381 case X86::BI__builtin_ia32_vpermi2varq128:
14382 case X86::BI__builtin_ia32_vpermi2varpd128: {
14385 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14386 int Offset = ShuffleMask & 0x1;
14387 unsigned SrcIdx = (ShuffleMask >> 1) & 0x1;
14388 return std::pair<unsigned, int>{SrcIdx, Offset};
14393 case X86::BI__builtin_ia32_vpermi2vard128:
14394 case X86::BI__builtin_ia32_vpermi2varps128:
14395 case X86::BI__builtin_ia32_vpermi2varq256:
14396 case X86::BI__builtin_ia32_vpermi2varpd256: {
14399 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14400 int Offset = ShuffleMask & 0x3;
14401 unsigned SrcIdx = (ShuffleMask >> 2) & 0x1;
14402 return std::pair<unsigned, int>{SrcIdx, Offset};
14407 case X86::BI__builtin_ia32_vpermi2varhi128:
14408 case X86::BI__builtin_ia32_vpermi2vard256:
14409 case X86::BI__builtin_ia32_vpermi2varps256:
14410 case X86::BI__builtin_ia32_vpermi2varq512:
14411 case X86::BI__builtin_ia32_vpermi2varpd512: {
14414 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14415 int Offset = ShuffleMask & 0x7;
14416 unsigned SrcIdx = (ShuffleMask >> 3) & 0x1;
14417 return std::pair<unsigned, int>{SrcIdx, Offset};
14422 case X86::BI__builtin_ia32_vpermi2varqi128:
14423 case X86::BI__builtin_ia32_vpermi2varhi256:
14424 case X86::BI__builtin_ia32_vpermi2vard512:
14425 case X86::BI__builtin_ia32_vpermi2varps512: {
14428 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14429 int Offset = ShuffleMask & 0xF;
14430 unsigned SrcIdx = (ShuffleMask >> 4) & 0x1;
14431 return std::pair<unsigned, int>{SrcIdx, Offset};
14436 case X86::BI__builtin_ia32_vpermi2varqi256:
14437 case X86::BI__builtin_ia32_vpermi2varhi512: {
14440 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14441 int Offset = ShuffleMask & 0x1F;
14442 unsigned SrcIdx = (ShuffleMask >> 5) & 0x1;
14443 return std::pair<unsigned, int>{SrcIdx, Offset};
14448 case X86::BI__builtin_ia32_vpermi2varqi512: {
14451 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14452 int Offset = ShuffleMask & 0x3F;
14453 unsigned SrcIdx = (ShuffleMask >> 6) & 0x1;
14454 return std::pair<unsigned, int>{SrcIdx, Offset};
14460 case clang::X86::BI__builtin_ia32_minps:
14461 case clang::X86::BI__builtin_ia32_minpd:
14462 case clang::X86::BI__builtin_ia32_minps256:
14463 case clang::X86::BI__builtin_ia32_minpd256:
14464 case clang::X86::BI__builtin_ia32_minps512:
14465 case clang::X86::BI__builtin_ia32_minpd512:
14466 case clang::X86::BI__builtin_ia32_minph128:
14467 case clang::X86::BI__builtin_ia32_minph256:
14468 case clang::X86::BI__builtin_ia32_minph512:
14469 return EvaluateFpBinOpExpr(
14470 [](
const APFloat &A,
const APFloat &B,
14471 std::optional<APSInt>) -> std::optional<APFloat> {
14472 if (A.isNaN() || A.isInfinity() || A.isDenormal() || B.isNaN() ||
14473 B.isInfinity() || B.isDenormal())
14474 return std::nullopt;
14475 if (A.isZero() && B.isZero())
14477 return llvm::minimum(A, B);
14480 case clang::X86::BI__builtin_ia32_minss:
14481 case clang::X86::BI__builtin_ia32_minsd:
14482 return EvaluateFpBinOpExpr(
14483 [](
const APFloat &A,
const APFloat &B,
14484 std::optional<APSInt> RoundingMode) -> std::optional<APFloat> {
14489 case clang::X86::BI__builtin_ia32_minsd_round_mask:
14490 case clang::X86::BI__builtin_ia32_minss_round_mask:
14491 case clang::X86::BI__builtin_ia32_minsh_round_mask:
14492 case clang::X86::BI__builtin_ia32_maxsd_round_mask:
14493 case clang::X86::BI__builtin_ia32_maxss_round_mask:
14494 case clang::X86::BI__builtin_ia32_maxsh_round_mask: {
14497 clang::X86::BI__builtin_ia32_minsd_round_mask ||
14499 clang::X86::BI__builtin_ia32_minss_round_mask ||
14501 return EvaluateScalarFpRoundMaskBinOp(
14502 [IsMin](
const APFloat &A,
const APFloat &B,
14503 std::optional<APSInt> RoundingMode) -> std::optional<APFloat> {
14508 case clang::X86::BI__builtin_ia32_maxps:
14509 case clang::X86::BI__builtin_ia32_maxpd:
14510 case clang::X86::BI__builtin_ia32_maxps256:
14511 case clang::X86::BI__builtin_ia32_maxpd256:
14512 case clang::X86::BI__builtin_ia32_maxps512:
14513 case clang::X86::BI__builtin_ia32_maxpd512:
14514 case clang::X86::BI__builtin_ia32_maxph128:
14515 case clang::X86::BI__builtin_ia32_maxph256:
14516 case clang::X86::BI__builtin_ia32_maxph512:
14517 return EvaluateFpBinOpExpr(
14518 [](
const APFloat &A,
const APFloat &B,
14519 std::optional<APSInt>) -> std::optional<APFloat> {
14520 if (A.isNaN() || A.isInfinity() || A.isDenormal() || B.isNaN() ||
14521 B.isInfinity() || B.isDenormal())
14522 return std::nullopt;
14523 if (A.isZero() && B.isZero())
14525 return llvm::maximum(A, B);
14528 case clang::X86::BI__builtin_ia32_maxss:
14529 case clang::X86::BI__builtin_ia32_maxsd:
14530 return EvaluateFpBinOpExpr(
14531 [](
const APFloat &A,
const APFloat &B,
14532 std::optional<APSInt> RoundingMode) -> std::optional<APFloat> {
14537 case clang::X86::BI__builtin_ia32_vcvtps2ph:
14538 case clang::X86::BI__builtin_ia32_vcvtps2ph256: {
14548 unsigned SrcNumElems = SrcVTy->getNumElements();
14550 unsigned DstNumElems = DstVTy->getNumElements();
14551 QualType DstElemTy = DstVTy->getElementType();
14553 const llvm::fltSemantics &HalfSem =
14554 Info.Ctx.getFloatTypeSemantics(Info.Ctx.HalfTy);
14556 int ImmVal = Imm.getZExtValue();
14557 bool UseMXCSR = (ImmVal & 4) != 0;
14558 bool IsFPConstrained =
14561 llvm::RoundingMode RM;
14563 switch (ImmVal & 3) {
14565 RM = llvm::RoundingMode::NearestTiesToEven;
14568 RM = llvm::RoundingMode::TowardNegative;
14571 RM = llvm::RoundingMode::TowardPositive;
14574 RM = llvm::RoundingMode::TowardZero;
14577 llvm_unreachable(
"Invalid immediate rounding mode");
14580 RM = llvm::RoundingMode::NearestTiesToEven;
14584 ResultElements.reserve(DstNumElems);
14586 for (
unsigned I = 0; I < SrcNumElems; ++I) {
14590 APFloat::opStatus St = SrcVal.convert(HalfSem, RM, &LostInfo);
14592 if (UseMXCSR && IsFPConstrained && St != APFloat::opOK) {
14593 Info.FFDiag(E, diag::note_constexpr_dynamic_rounding);
14597 APSInt DstInt(SrcVal.bitcastToAPInt(),
14599 ResultElements.push_back(
APValue(DstInt));
14602 if (DstNumElems > SrcNumElems) {
14603 APSInt Zero = Info.Ctx.MakeIntValue(0, DstElemTy);
14604 for (
unsigned I = SrcNumElems; I < DstNumElems; ++I) {
14609 return Success(ResultElements, E);
14611 case X86::BI__builtin_ia32_vperm2f128_pd256:
14612 case X86::BI__builtin_ia32_vperm2f128_ps256:
14613 case X86::BI__builtin_ia32_vperm2f128_si256:
14614 case X86::BI__builtin_ia32_permti256: {
14615 unsigned NumElements =
14617 unsigned PreservedBitsCnt = NumElements >> 2;
14621 [PreservedBitsCnt](
unsigned DstIdx,
unsigned ShuffleMask) {
14622 unsigned ControlBitsCnt = DstIdx >> PreservedBitsCnt << 2;
14623 unsigned ControlBits = ShuffleMask >> ControlBitsCnt;
14625 if (ControlBits & 0b1000)
14626 return std::make_pair(0u, -1);
14628 unsigned SrcVecIdx = (ControlBits & 0b10) >> 1;
14629 unsigned PreservedBitsMask = (1 << PreservedBitsCnt) - 1;
14630 int SrcIdx = ((ControlBits & 0b1) << PreservedBitsCnt) |
14631 (DstIdx & PreservedBitsMask);
14632 return std::make_pair(SrcVecIdx, SrcIdx);
14640bool VectorExprEvaluator::VisitConvertVectorExpr(
const ConvertVectorExpr *E) {
14646 QualType DestTy = E->
getType()->
castAs<VectorType>()->getElementType();
14647 QualType SourceTy = SourceVecType->
castAs<VectorType>()->getElementType();
14653 ResultElements.reserve(SourceLen);
14654 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
14659 ResultElements.push_back(std::move(Elt));
14662 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14667 APValue const &VecVal2,
unsigned EltNum,
14669 unsigned const TotalElementsInInputVector1 = VecVal1.
getVectorLength();
14670 unsigned const TotalElementsInInputVector2 = VecVal2.
getVectorLength();
14673 int64_t
index = IndexVal.getExtValue();
14680 E, diag::err_shufflevector_minus_one_is_undefined_behavior_constexpr)
14686 index >= TotalElementsInInputVector1 + TotalElementsInInputVector2)
14687 llvm_unreachable(
"Out of bounds shuffle index");
14689 if (
index >= TotalElementsInInputVector1)
14696bool VectorExprEvaluator::VisitShuffleVectorExpr(
const ShuffleVectorExpr *E) {
14701 const Expr *Vec1 = E->
getExpr(0);
14705 const Expr *Vec2 = E->
getExpr(1);
14709 VectorType
const *DestVecTy = E->
getType()->
castAs<VectorType>();
14715 ResultElements.reserve(TotalElementsInOutputVector);
14716 for (
unsigned EltNum = 0; EltNum < TotalElementsInOutputVector; ++EltNum) {
14720 ResultElements.push_back(std::move(Elt));
14723 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14731class MatrixExprEvaluator :
public ExprEvaluatorBase<MatrixExprEvaluator> {
14738 bool Success(ArrayRef<APValue> M,
const Expr *E) {
14740 assert(M.size() == CMTy->getNumElementsFlattened());
14742 Result =
APValue(M.data(), CMTy->getNumRows(), CMTy->getNumColumns());
14746 assert(M.
isMatrix() &&
"expected matrix");
14751 bool VisitCastExpr(
const CastExpr *E);
14752 bool VisitInitListExpr(
const InitListExpr *E);
14758 "not a matrix prvalue");
14759 return MatrixExprEvaluator(Info, Result).Visit(E);
14762bool MatrixExprEvaluator::VisitCastExpr(
const CastExpr *E) {
14763 const auto *MT = E->
getType()->
castAs<ConstantMatrixType>();
14764 unsigned NumRows = MT->getNumRows();
14765 unsigned NumCols = MT->getNumColumns();
14766 unsigned NElts = NumRows * NumCols;
14767 QualType EltTy = MT->getElementType();
14771 case CK_HLSLAggregateSplatCast: {
14786 case CK_HLSLElementwiseCast: {
14799 return Success(ResultEls, E);
14802 return ExprEvaluatorBaseTy::VisitCastExpr(E);
14806bool MatrixExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
14807 const auto *MT = E->
getType()->
castAs<ConstantMatrixType>();
14808 QualType EltTy = MT->getElementType();
14810 assert(E->
getNumInits() == MT->getNumElementsFlattened() &&
14811 "Expected number of elements in initializer list to match the number "
14812 "of matrix elements");
14815 Elements.reserve(MT->getNumElementsFlattened());
14820 for (
unsigned I = 0, N = MT->getNumElementsFlattened(); I < N; ++I) {
14821 if (EltTy->isIntegerType()) {
14822 llvm::APSInt IntVal;
14825 Elements.push_back(
APValue(IntVal));
14827 llvm::APFloat FloatVal(0.0);
14830 Elements.push_back(
APValue(FloatVal));
14842 class ArrayExprEvaluator
14843 :
public ExprEvaluatorBase<ArrayExprEvaluator> {
14844 const LValue &
This;
14848 ArrayExprEvaluator(EvalInfo &Info,
const LValue &This,
APValue &
Result)
14852 assert(
V.isArray() &&
"expected array");
14857 bool ZeroInitialization(
const Expr *E) {
14858 const ConstantArrayType *CAT =
14859 Info.Ctx.getAsConstantArrayType(E->
getType());
14873 if (!
Result.hasArrayFiller())
14877 LValue Subobject =
This;
14878 Subobject.addArray(Info, E, CAT);
14883 bool VisitCallExpr(
const CallExpr *E) {
14884 return handleCallExpr(E,
Result, &This);
14886 bool VisitCastExpr(
const CastExpr *E);
14887 bool VisitInitListExpr(
const InitListExpr *E,
14888 QualType AllocType = QualType());
14889 bool VisitArrayInitLoopExpr(
const ArrayInitLoopExpr *E);
14890 bool VisitCXXConstructExpr(
const CXXConstructExpr *E);
14891 bool VisitCXXConstructExpr(
const CXXConstructExpr *E,
14892 const LValue &Subobject,
14894 bool VisitStringLiteral(
const StringLiteral *E,
14895 QualType AllocType = QualType()) {
14899 bool VisitCXXParenListInitExpr(
const CXXParenListInitExpr *E);
14900 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
14901 ArrayRef<Expr *> Args,
14902 const Expr *ArrayFiller,
14903 QualType AllocType = QualType());
14908 APValue &Result, EvalInfo &Info) {
14911 "not an array prvalue");
14912 return ArrayExprEvaluator(Info,
This, Result).Visit(E);
14920 "not an array prvalue");
14921 return ArrayExprEvaluator(Info,
This, Result)
14922 .VisitInitListExpr(ILE, AllocType);
14931 "not an array prvalue");
14932 return ArrayExprEvaluator(Info,
This, Result)
14933 .VisitCXXConstructExpr(CCE,
This, &Result, AllocType);
14942 if (
const InitListExpr *ILE = dyn_cast<InitListExpr>(FillerExpr)) {
14943 for (
unsigned I = 0, E = ILE->
getNumInits(); I != E; ++I) {
14948 if (ILE->hasArrayFiller() &&
14957bool ArrayExprEvaluator::VisitCastExpr(
const CastExpr *E) {
14962 return ExprEvaluatorBaseTy::VisitCastExpr(E);
14963 case CK_HLSLAggregateSplatCast: {
14983 case CK_HLSLElementwiseCast: {
15000bool ArrayExprEvaluator::VisitInitListExpr(
const InitListExpr *E,
15001 QualType AllocType) {
15002 const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(
15015 return VisitStringLiteral(SL, AllocType);
15020 "transparent array list initialization is not string literal init?");
15026bool ArrayExprEvaluator::VisitCXXParenListOrInitListExpr(
15028 QualType AllocType) {
15029 const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(
15034 assert((!
Result.isArray() ||
Result.getArrayInitializedElts() == 0) &&
15035 "zero-initialized array shouldn't have any initialized elts");
15040 unsigned NumEltsToInit = Args.size();
15045 if (NumEltsToInit != NumElts &&
15047 NumEltsToInit = NumElts;
15049 for (
auto *
Init : Args) {
15050 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts()))
15051 NumEltsToInit += EmbedS->getDataElementCount() - 1;
15053 if (NumEltsToInit > NumElts)
15054 NumEltsToInit = NumElts;
15057 LLVM_DEBUG(llvm::dbgs() <<
"The number of elements to initialize: "
15058 << NumEltsToInit <<
".\n");
15060 Result =
APValue(APValue::UninitArray(), NumEltsToInit, NumElts);
15065 for (
unsigned I = 0, E =
Result.getArrayInitializedElts(); I != E; ++I)
15066 Result.getArrayInitializedElt(I) = Filler;
15067 if (
Result.hasArrayFiller())
15071 LValue Subobject =
This;
15072 Subobject.addArray(Info, ExprToVisit, CAT);
15073 auto Eval = [&](
const Expr *
Init,
unsigned ArrayIndex) {
15074 if (
Init->isValueDependent())
15078 Subobject,
Init) ||
15081 if (!Info.noteFailure())
15087 unsigned ArrayIndex = 0;
15090 for (
unsigned Index = 0; Index != NumEltsToInit; ++Index) {
15091 const Expr *
Init = Index < Args.size() ? Args[Index] : ArrayFiller;
15092 if (ArrayIndex >= NumEltsToInit)
15094 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
15095 StringLiteral *SL = EmbedS->getDataStringLiteral();
15096 for (
unsigned I = EmbedS->getStartingElementPos(),
15097 N = EmbedS->getDataElementCount();
15098 I != EmbedS->getStartingElementPos() + N; ++I) {
15104 const FPOptions FPO =
15105 Init->getFPFeaturesInEffect(Info.Ctx.getLangOpts());
15110 Result.getArrayInitializedElt(ArrayIndex) =
APValue(FValue);
15115 if (!Eval(
Init, ArrayIndex))
15121 if (!
Result.hasArrayFiller())
15126 assert(ArrayFiller &&
"no array filler for incomplete init list");
15132bool ArrayExprEvaluator::VisitArrayInitLoopExpr(
const ArrayInitLoopExpr *E) {
15135 !
Evaluate(Info.CurrentCall->createTemporary(
15138 ScopeKind::FullExpression, CommonLV),
15145 Result =
APValue(APValue::UninitArray(), Elements, Elements);
15147 LValue Subobject =
This;
15148 Subobject.addArray(Info, E, CAT);
15151 for (EvalInfo::ArrayInitLoopIndex Index(Info); Index != Elements; ++Index) {
15160 FullExpressionRAII Scope(Info);
15166 if (!Info.noteFailure())
15178bool ArrayExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E) {
15179 return VisitCXXConstructExpr(E, This, &
Result, E->
getType());
15182bool ArrayExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E,
15183 const LValue &Subobject,
15186 bool HadZeroInit =
Value->hasValue();
15188 if (
const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(
Type)) {
15193 HadZeroInit &&
Value->hasArrayFiller() ?
Value->getArrayFiller()
15196 *
Value =
APValue(APValue::UninitArray(), 0, FinalSize);
15197 if (FinalSize == 0)
15203 LValue ArrayElt = Subobject;
15204 ArrayElt.addArray(Info, E, CAT);
15210 for (
const unsigned N : {1u, FinalSize}) {
15211 unsigned OldElts =
Value->getArrayInitializedElts();
15216 APValue NewValue(APValue::UninitArray(), N, FinalSize);
15217 for (
unsigned I = 0; I < OldElts; ++I)
15218 NewValue.getArrayInitializedElt(I).swap(
15219 Value->getArrayInitializedElt(I));
15220 Value->swap(NewValue);
15223 for (
unsigned I = OldElts; I < N; ++I)
15224 Value->getArrayInitializedElt(I) = Filler;
15226 if (HasTrivialConstructor && N == FinalSize && FinalSize != 1) {
15229 APValue &FirstResult =
Value->getArrayInitializedElt(0);
15230 for (
unsigned I = OldElts; I < FinalSize; ++I)
15231 Value->getArrayInitializedElt(I) = FirstResult;
15233 for (
unsigned I = OldElts; I < N; ++I) {
15234 if (!VisitCXXConstructExpr(E, ArrayElt,
15235 &
Value->getArrayInitializedElt(I),
15242 if (Info.EvalStatus.Diag && !Info.EvalStatus.Diag->empty() &&
15243 !Info.keepEvaluatingAfterFailure())
15252 if (!
Type->isRecordType())
15255 return RecordExprEvaluator(Info, Subobject, *
Value)
15256 .VisitCXXConstructExpr(E,
Type);
15259bool ArrayExprEvaluator::VisitCXXParenListInitExpr(
15260 const CXXParenListInitExpr *E) {
15262 "Expression result is not a constant array type");
15264 return VisitCXXParenListOrInitListExpr(E, E->
getInitExprs(),
15277class IntExprEvaluator
15278 :
public ExprEvaluatorBase<IntExprEvaluator> {
15281 IntExprEvaluator(EvalInfo &info,
APValue &result)
15282 : ExprEvaluatorBaseTy(info),
Result(result) {}
15286 "Invalid evaluation result.");
15288 "Invalid evaluation result.");
15289 assert(SI.getBitWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
15290 "Invalid evaluation result.");
15294 bool Success(
const llvm::APSInt &SI,
const Expr *E) {
15300 "Invalid evaluation result.");
15301 assert(I.getBitWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
15302 "Invalid evaluation result.");
15304 Result.getInt().setIsUnsigned(
15308 bool Success(
const llvm::APInt &I,
const Expr *E) {
15314 "Invalid evaluation result.");
15322 bool Success(CharUnits Size,
const Expr *E) {
15329 if (
V.isLValue() ||
V.isAddrLabelDiff() ||
V.isIndeterminate() ||
15330 V.allowConstexprUnknown()) {
15337 bool ZeroInitialization(
const Expr *E) {
return Success(0, E); }
15339 friend std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &,
15346 bool VisitIntegerLiteral(
const IntegerLiteral *E) {
15349 bool VisitCharacterLiteral(
const CharacterLiteral *E) {
15353 bool CheckReferencedDecl(
const Expr *E,
const Decl *D);
15354 bool VisitDeclRefExpr(
const DeclRefExpr *E) {
15355 if (CheckReferencedDecl(E, E->
getDecl()))
15358 return ExprEvaluatorBaseTy::VisitDeclRefExpr(E);
15360 bool VisitMemberExpr(
const MemberExpr *E) {
15362 VisitIgnoredBaseExpression(E->
getBase());
15366 return ExprEvaluatorBaseTy::VisitMemberExpr(E);
15369 bool VisitCallExpr(
const CallExpr *E);
15370 bool VisitBuiltinCallExpr(
const CallExpr *E,
unsigned BuiltinOp);
15371 bool VisitBinaryOperator(
const BinaryOperator *E);
15372 bool VisitOffsetOfExpr(
const OffsetOfExpr *E);
15373 bool VisitUnaryOperator(
const UnaryOperator *E);
15375 bool VisitCastExpr(
const CastExpr* E);
15376 bool VisitUnaryExprOrTypeTraitExpr(
const UnaryExprOrTypeTraitExpr *E);
15378 bool VisitCXXBoolLiteralExpr(
const CXXBoolLiteralExpr *E) {
15382 bool VisitObjCBoolLiteralExpr(
const ObjCBoolLiteralExpr *E) {
15386 bool VisitArrayInitIndexExpr(
const ArrayInitIndexExpr *E) {
15387 if (Info.ArrayInitIndex ==
uint64_t(-1)) {
15393 return Success(Info.ArrayInitIndex, E);
15397 bool VisitGNUNullExpr(
const GNUNullExpr *E) {
15398 return ZeroInitialization(E);
15401 bool VisitTypeTraitExpr(
const TypeTraitExpr *E) {
15410 bool VisitArrayTypeTraitExpr(
const ArrayTypeTraitExpr *E) {
15414 bool VisitExpressionTraitExpr(
const ExpressionTraitExpr *E) {
15418 bool VisitOpenACCAsteriskSizeExpr(
const OpenACCAsteriskSizeExpr *E) {
15425 bool VisitUnaryReal(
const UnaryOperator *E);
15426 bool VisitUnaryImag(
const UnaryOperator *E);
15428 bool VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E);
15429 bool VisitSizeOfPackExpr(
const SizeOfPackExpr *E);
15430 bool VisitSourceLocExpr(
const SourceLocExpr *E);
15431 bool VisitConceptSpecializationExpr(
const ConceptSpecializationExpr *E);
15436class FixedPointExprEvaluator
15437 :
public ExprEvaluatorBase<FixedPointExprEvaluator> {
15441 FixedPointExprEvaluator(EvalInfo &info,
APValue &result)
15442 : ExprEvaluatorBaseTy(info),
Result(result) {}
15444 bool Success(
const llvm::APInt &I,
const Expr *E) {
15446 APFixedPoint(I, Info.Ctx.getFixedPointSemantics(E->
getType())), E);
15451 APFixedPoint(
Value, Info.Ctx.getFixedPointSemantics(E->
getType())), E);
15455 return Success(
V.getFixedPoint(), E);
15458 bool Success(
const APFixedPoint &
V,
const Expr *E) {
15460 assert(
V.getWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
15461 "Invalid evaluation result.");
15466 bool ZeroInitialization(
const Expr *E) {
15474 bool VisitFixedPointLiteral(
const FixedPointLiteral *E) {
15478 bool VisitCastExpr(
const CastExpr *E);
15479 bool VisitUnaryOperator(
const UnaryOperator *E);
15480 bool VisitBinaryOperator(
const BinaryOperator *E);
15496 return IntExprEvaluator(Info, Result).Visit(E);
15504 if (!Val.
isInt()) {
15507 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
15514bool IntExprEvaluator::VisitSourceLocExpr(
const SourceLocExpr *E) {
15516 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.
getDefaultExpr());
15525 if (!FixedPointExprEvaluator(Info, Val).Visit(E))
15540 auto FXSema = Info.Ctx.getFixedPointSemantics(E->
getType());
15544 Result = APFixedPoint(Val, FXSema);
15555bool IntExprEvaluator::CheckReferencedDecl(
const Expr* E,
const Decl* D) {
15557 if (
const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(D)) {
15559 bool SameSign = (ECD->getInitVal().isSigned()
15561 bool SameWidth = (ECD->getInitVal().
getBitWidth()
15562 == Info.Ctx.getIntWidth(E->
getType()));
15563 if (SameSign && SameWidth)
15564 return Success(ECD->getInitVal(), E);
15568 llvm::APSInt Val = ECD->getInitVal();
15570 Val.setIsSigned(!ECD->getInitVal().isSigned());
15572 Val = Val.extOrTrunc(Info.Ctx.getIntWidth(E->
getType()));
15583 assert(!T->isDependentType() &&
"unexpected dependent type");
15588#define TYPE(ID, BASE)
15589#define DEPENDENT_TYPE(ID, BASE) case Type::ID:
15590#define NON_CANONICAL_TYPE(ID, BASE) case Type::ID:
15591#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(ID, BASE) case Type::ID:
15592#include "clang/AST/TypeNodes.inc"
15594 case Type::DeducedTemplateSpecialization:
15595 llvm_unreachable(
"unexpected non-canonical or dependent type");
15597 case Type::Builtin:
15599#define BUILTIN_TYPE(ID, SINGLETON_ID)
15600#define SIGNED_TYPE(ID, SINGLETON_ID) \
15601 case BuiltinType::ID: return GCCTypeClass::Integer;
15602#define FLOATING_TYPE(ID, SINGLETON_ID) \
15603 case BuiltinType::ID: return GCCTypeClass::RealFloat;
15604#define PLACEHOLDER_TYPE(ID, SINGLETON_ID) \
15605 case BuiltinType::ID: break;
15606#include "clang/AST/BuiltinTypes.def"
15607 case BuiltinType::Void:
15610 case BuiltinType::Bool:
15613 case BuiltinType::Char_U:
15614 case BuiltinType::UChar:
15615 case BuiltinType::WChar_U:
15616 case BuiltinType::Char8:
15617 case BuiltinType::Char16:
15618 case BuiltinType::Char32:
15619 case BuiltinType::UShort:
15620 case BuiltinType::UInt:
15621 case BuiltinType::ULong:
15622 case BuiltinType::ULongLong:
15623 case BuiltinType::UInt128:
15626 case BuiltinType::UShortAccum:
15627 case BuiltinType::UAccum:
15628 case BuiltinType::ULongAccum:
15629 case BuiltinType::UShortFract:
15630 case BuiltinType::UFract:
15631 case BuiltinType::ULongFract:
15632 case BuiltinType::SatUShortAccum:
15633 case BuiltinType::SatUAccum:
15634 case BuiltinType::SatULongAccum:
15635 case BuiltinType::SatUShortFract:
15636 case BuiltinType::SatUFract:
15637 case BuiltinType::SatULongFract:
15640 case BuiltinType::NullPtr:
15642 case BuiltinType::ObjCId:
15643 case BuiltinType::ObjCClass:
15644 case BuiltinType::ObjCSel:
15645#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
15646 case BuiltinType::Id:
15647#include "clang/Basic/OpenCLImageTypes.def"
15648#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
15649 case BuiltinType::Id:
15650#include "clang/Basic/OpenCLExtensionTypes.def"
15651 case BuiltinType::OCLSampler:
15652 case BuiltinType::OCLEvent:
15653 case BuiltinType::OCLClkEvent:
15654 case BuiltinType::OCLQueue:
15655 case BuiltinType::OCLReserveID:
15656#define SVE_TYPE(Name, Id, SingletonId) \
15657 case BuiltinType::Id:
15658#include "clang/Basic/AArch64ACLETypes.def"
15659#define PPC_VECTOR_TYPE(Name, Id, Size) \
15660 case BuiltinType::Id:
15661#include "clang/Basic/PPCTypes.def"
15662#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
15663#include "clang/Basic/RISCVVTypes.def"
15664#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
15665#include "clang/Basic/WebAssemblyReferenceTypes.def"
15666#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
15667#include "clang/Basic/AMDGPUTypes.def"
15668#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
15669#include "clang/Basic/HLSLIntangibleTypes.def"
15672 case BuiltinType::Dependent:
15673 llvm_unreachable(
"unexpected dependent type");
15675 llvm_unreachable(
"unexpected placeholder type");
15680 case Type::Pointer:
15681 case Type::ConstantArray:
15682 case Type::VariableArray:
15683 case Type::IncompleteArray:
15684 case Type::FunctionNoProto:
15685 case Type::FunctionProto:
15686 case Type::ArrayParameter:
15689 case Type::MemberPointer:
15694 case Type::Complex:
15707 case Type::ExtVector:
15710 case Type::BlockPointer:
15711 case Type::ConstantMatrix:
15712 case Type::ObjCObject:
15713 case Type::ObjCInterface:
15714 case Type::ObjCObjectPointer:
15716 case Type::HLSLAttributedResource:
15717 case Type::HLSLInlineSpirv:
15718 case Type::OverflowBehavior:
15726 case Type::LValueReference:
15727 case Type::RValueReference:
15728 llvm_unreachable(
"invalid type for expression");
15731 llvm_unreachable(
"unexpected type class");
15756 if (
Base.isNull()) {
15759 }
else if (
const Expr *E =
Base.dyn_cast<
const Expr *>()) {
15778 SpeculativeEvaluationRAII SpeculativeEval(Info);
15783 FoldConstant Fold(Info,
true);
15801 if (ArgType->isIntegralOrEnumerationType() || ArgType->isFloatingType() ||
15802 ArgType->isAnyComplexType() || ArgType->isPointerType() ||
15803 ArgType->isNullPtrType()) {
15806 Fold.keepDiagnostics();
15815 return V.hasValue();
15826 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
15850 const auto *Cast = dyn_cast<CastExpr>(NoParens);
15851 if (Cast ==
nullptr)
15856 auto CastKind = Cast->getCastKind();
15858 CastKind != CK_AddressSpaceConversion)
15861 const auto *SubExpr = Cast->getSubExpr();
15883 assert(!LVal.Designator.Invalid);
15885 auto IsLastOrInvalidFieldDecl = [&Ctx](
const FieldDecl *FD) {
15893 auto &
Base = LVal.getLValueBase();
15894 if (
auto *ME = dyn_cast_or_null<MemberExpr>(
Base.dyn_cast<
const Expr *>())) {
15895 if (
auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
15896 if (!IsLastOrInvalidFieldDecl(FD))
15898 }
else if (
auto *IFD = dyn_cast<IndirectFieldDecl>(ME->getMemberDecl())) {
15899 for (
auto *FD : IFD->chain()) {
15908 if (LVal.Designator.FirstEntryIsAnUnsizedArray) {
15912 if (BaseType->isIncompleteArrayType())
15918 for (
unsigned E = LVal.Designator.Entries.size(); I != E; ++I) {
15919 const auto &Entry = LVal.Designator.Entries[I];
15920 if (BaseType->isArrayType()) {
15926 uint64_t Index = Entry.getAsArrayIndex();
15930 }
else if (BaseType->isAnyComplexType()) {
15931 const auto *CT = BaseType->castAs<
ComplexType>();
15932 uint64_t Index = Entry.getAsArrayIndex();
15935 BaseType = CT->getElementType();
15936 }
else if (
auto *FD = getAsField(Entry)) {
15937 if (!IsLastOrInvalidFieldDecl(FD))
15941 assert(getAsBaseClass(Entry) &&
"Expecting cast to a base class");
15953 if (LVal.Designator.Invalid)
15956 if (!LVal.Designator.Entries.empty())
15957 return LVal.Designator.isMostDerivedAnUnsizedArray();
15959 if (!LVal.InvalidBase)
15971 const SubobjectDesignator &
Designator = LVal.Designator;
15983 auto isFlexibleArrayMember = [&] {
15985 FAMKind StrictFlexArraysLevel =
15988 if (
Designator.isMostDerivedAnUnsizedArray())
15991 if (StrictFlexArraysLevel == FAMKind::Default)
15994 if (
Designator.getMostDerivedArraySize() == 0 &&
15995 StrictFlexArraysLevel != FAMKind::IncompleteOnly)
15998 if (
Designator.getMostDerivedArraySize() == 1 &&
15999 StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete)
16005 return LVal.InvalidBase &&
16007 Designator.MostDerivedIsArrayElement && isFlexibleArrayMember() &&
16015 auto CharUnitsMax = std::numeric_limits<CharUnits::QuantityType>::max();
16016 if (Int.ugt(CharUnitsMax))
16026 if (!T.isNull() && T->isStructureType() &&
16027 T->castAsRecordDecl()->hasFlexibleArrayMember())
16028 if (
const auto *
V = LV.getLValueBase().dyn_cast<
const ValueDecl *>())
16029 if (
const auto *VD = dyn_cast<VarDecl>(
V))
16041 unsigned Type,
const LValue &LVal,
16060 if (!(
Type & 1) || LVal.Designator.Invalid || DetermineForCompleteObject) {
16062 if (
Type == 3 && !DetermineForCompleteObject)
16065 llvm::APInt APEndOffset;
16066 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
16070 if (LVal.InvalidBase)
16074 const bool Ret = CheckedHandleSizeof(BaseTy, EndOffset);
16080 const SubobjectDesignator &
Designator = LVal.Designator;
16092 llvm::APInt APEndOffset;
16093 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
16105 if (!CheckedHandleSizeof(
Designator.MostDerivedType, BytesPerElem))
16111 int64_t ElemsRemaining;
16114 uint64_t ArraySize =
Designator.getMostDerivedArraySize();
16115 uint64_t ArrayIndex =
Designator.Entries.back().getAsArrayIndex();
16116 ElemsRemaining = ArraySize <= ArrayIndex ? 0 : ArraySize - ArrayIndex;
16118 ElemsRemaining =
Designator.isOnePastTheEnd() ? 0 : 1;
16121 EndOffset = LVal.getLValueOffset() + BytesPerElem * ElemsRemaining;
16130static std::optional<uint64_t>
16138 SpeculativeEvaluationRAII SpeculativeEval(Info);
16139 IgnoreSideEffectsRAII Fold(Info);
16146 return std::nullopt;
16147 LVal.setFrom(Info.Ctx, RVal);
16150 return std::nullopt;
16155 if (LVal.getLValueOffset().isNegative())
16160 return std::nullopt;
16164 if (EndOffset <= LVal.getLValueOffset())
16166 return (EndOffset - LVal.getLValueOffset()).
getQuantity();
16169bool IntExprEvaluator::VisitCallExpr(
const CallExpr *E) {
16170 if (!IsConstantEvaluatedBuiltinCall(E))
16171 return ExprEvaluatorBaseTy::VisitCallExpr(E);
16188 Info.FFDiag(E->
getArg(0));
16194 assert(SrcInt.getBitWidth() >= Alignment.getBitWidth() &&
16195 "Bit widths must be the same");
16202bool IntExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *E,
16203 unsigned BuiltinOp) {
16204 auto EvalTestOp = [&](llvm::function_ref<
bool(
const APInt &,
const APInt &)>
16206 APValue SourceLHS, SourceRHS;
16214 unsigned LaneWidth = Info.Ctx.getTypeSize(ElemQT);
16216 APInt AWide(LaneWidth * SourceLen, 0);
16217 APInt BWide(LaneWidth * SourceLen, 0);
16219 for (
unsigned I = 0; I != SourceLen; ++I) {
16222 if (ElemQT->isIntegerType()) {
16225 }
else if (ElemQT->isFloatingType()) {
16233 AWide.insertBits(ALane, I * LaneWidth);
16234 BWide.insertBits(BLane, I * LaneWidth);
16239 auto HandleMaskBinOp =
16252 auto HandleCRC32 = [&](
unsigned DataBytes) ->
bool {
16258 uint64_t CRCVal = CRC.getZExtValue();
16262 static const uint32_t CRC32C_POLY = 0x82F63B78;
16266 for (
unsigned I = 0; I != DataBytes; ++I) {
16267 uint8_t Byte =
static_cast<uint8_t
>((DataVal >> (I * 8)) & 0xFF);
16269 for (
int J = 0; J != 8; ++J) {
16277 switch (BuiltinOp) {
16281 case X86::BI__builtin_ia32_crc32qi:
16282 return HandleCRC32(1);
16283 case X86::BI__builtin_ia32_crc32hi:
16284 return HandleCRC32(2);
16285 case X86::BI__builtin_ia32_crc32si:
16286 return HandleCRC32(4);
16287 case X86::BI__builtin_ia32_crc32di:
16288 return HandleCRC32(8);
16290 case Builtin::BI__builtin_dynamic_object_size:
16291 case Builtin::BI__builtin_object_size: {
16295 assert(
Type <= 3 &&
"unexpected type");
16297 if (std::optional<uint64_t> Size =
16306 switch (Info.EvalMode) {
16307 case EvaluationMode::ConstantExpression:
16308 case EvaluationMode::ConstantFold:
16309 case EvaluationMode::IgnoreSideEffects:
16312 case EvaluationMode::ConstantExpressionUnevaluated:
16317 llvm_unreachable(
"unexpected EvalMode");
16320 case Builtin::BI__builtin_os_log_format_buffer_size: {
16321 analyze_os_log::OSLogBufferLayout Layout;
16326 case Builtin::BI__builtin_is_aligned: {
16334 Ptr.setFrom(Info.Ctx, Src);
16340 assert(Alignment.isPowerOf2());
16353 Info.FFDiag(E->
getArg(0), diag::note_constexpr_alignment_compute)
16357 assert(Src.
isInt());
16358 return Success((Src.
getInt() & (Alignment - 1)) == 0 ? 1 : 0, E);
16360 case Builtin::BI__builtin_align_up: {
16368 APSInt((Src.
getInt() + (Alignment - 1)) & ~(Alignment - 1),
16369 Src.
getInt().isUnsigned());
16370 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
16371 return Success(AlignedVal, E);
16373 case Builtin::BI__builtin_align_down: {
16382 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
16383 return Success(AlignedVal, E);
16386 case Builtin::BI__builtin_bitreverseg:
16387 case Builtin::BI__builtin_bitreverse8:
16388 case Builtin::BI__builtin_bitreverse16:
16389 case Builtin::BI__builtin_bitreverse32:
16390 case Builtin::BI__builtin_bitreverse64:
16391 case Builtin::BI__builtin_elementwise_bitreverse: {
16396 return Success(Val.reverseBits(), E);
16398 case Builtin::BI__builtin_bswapg:
16399 case Builtin::BI__builtin_bswap16:
16400 case Builtin::BI__builtin_bswap32:
16401 case Builtin::BI__builtin_bswap64: {
16405 if (Val.getBitWidth() == 8 || Val.getBitWidth() == 1)
16408 return Success(Val.byteSwap(), E);
16411 case Builtin::BI__builtin_classify_type:
16414 case Builtin::BI__builtin_clrsb:
16415 case Builtin::BI__builtin_clrsbl:
16416 case Builtin::BI__builtin_clrsbll: {
16421 return Success(Val.getBitWidth() - Val.getSignificantBits(), E);
16424 case Builtin::BI__builtin_clz:
16425 case Builtin::BI__builtin_clzl:
16426 case Builtin::BI__builtin_clzll:
16427 case Builtin::BI__builtin_clzs:
16428 case Builtin::BI__builtin_clzg:
16429 case Builtin::BI__builtin_elementwise_clzg:
16430 case Builtin::BI__lzcnt16:
16431 case Builtin::BI__lzcnt:
16432 case Builtin::BI__lzcnt64: {
16443 std::optional<APSInt> Fallback;
16444 if ((BuiltinOp == Builtin::BI__builtin_clzg ||
16445 BuiltinOp == Builtin::BI__builtin_elementwise_clzg) &&
16450 Fallback = FallbackTemp;
16455 return Success(*Fallback, E);
16460 bool ZeroIsUndefined = BuiltinOp != Builtin::BI__lzcnt16 &&
16461 BuiltinOp != Builtin::BI__lzcnt &&
16462 BuiltinOp != Builtin::BI__lzcnt64;
16464 if (BuiltinOp == Builtin::BI__builtin_elementwise_clzg) {
16465 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
16469 if (ZeroIsUndefined)
16473 return Success(Val.countl_zero(), E);
16476 case Builtin::BI__builtin_constant_p: {
16477 const Expr *Arg = E->
getArg(0);
16486 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
16490 case Builtin::BI__noop:
16494 case Builtin::BI__builtin_is_constant_evaluated: {
16495 const auto *
Callee = Info.CurrentCall->getCallee();
16496 if (Info.InConstantContext && !Info.CheckingPotentialConstantExpression &&
16497 (Info.CallStackDepth == 1 ||
16498 (Info.CallStackDepth == 2 &&
Callee->isInStdNamespace() &&
16499 Callee->getIdentifier() &&
16500 Callee->getIdentifier()->isStr(
"is_constant_evaluated")))) {
16502 if (Info.EvalStatus.Diag)
16503 Info.report((Info.CallStackDepth == 1)
16505 : Info.CurrentCall->getCallRange().getBegin(),
16506 diag::warn_is_constant_evaluated_always_true_constexpr)
16507 << (Info.CallStackDepth == 1 ?
"__builtin_is_constant_evaluated"
16508 :
"std::is_constant_evaluated");
16511 return Success(Info.InConstantContext, E);
16514 case Builtin::BI__builtin_is_within_lifetime:
16515 if (
auto result = EvaluateBuiltinIsWithinLifetime(*
this, E))
16519 case Builtin::BI__builtin_ctz:
16520 case Builtin::BI__builtin_ctzl:
16521 case Builtin::BI__builtin_ctzll:
16522 case Builtin::BI__builtin_ctzs:
16523 case Builtin::BI__builtin_ctzg:
16524 case Builtin::BI__builtin_elementwise_ctzg: {
16535 std::optional<APSInt> Fallback;
16536 if ((BuiltinOp == Builtin::BI__builtin_ctzg ||
16537 BuiltinOp == Builtin::BI__builtin_elementwise_ctzg) &&
16542 Fallback = FallbackTemp;
16547 return Success(*Fallback, E);
16549 if (BuiltinOp == Builtin::BI__builtin_elementwise_ctzg) {
16550 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
16556 return Success(Val.countr_zero(), E);
16559 case Builtin::BI__builtin_eh_return_data_regno: {
16561 Operand = Info.Ctx.getTargetInfo().getEHDataRegisterNumber(Operand);
16565 case Builtin::BI__builtin_elementwise_abs: {
16570 return Success(Val.abs(), E);
16573 case Builtin::BI__builtin_expect:
16574 case Builtin::BI__builtin_expect_with_probability:
16575 return Visit(E->
getArg(0));
16577 case Builtin::BI__builtin_ptrauth_string_discriminator: {
16584 case Builtin::BI__builtin_infer_alloc_token: {
16590 E, diag::note_constexpr_infer_alloc_token_type_inference_failed);
16593 return Error(E, diag::note_constexpr_infer_alloc_token_no_metadata);
16595 Info.getLangOpts().AllocTokenMode.value_or(llvm::DefaultAllocTokenMode);
16596 uint64_t BitWidth = Info.Ctx.getTypeSize(Info.Ctx.getSizeType());
16597 auto MaxTokensOpt = Info.getLangOpts().AllocTokenMax;
16599 MaxTokensOpt.value_or(0) ? *MaxTokensOpt : (~0ULL >> (64 - BitWidth));
16600 auto MaybeToken = llvm::getAllocToken(Mode, *ATMD, MaxTokens);
16602 return Error(E, diag::note_constexpr_infer_alloc_token_stateful_mode);
16603 return Success(llvm::APInt(BitWidth, *MaybeToken), E);
16606 case Builtin::BI__builtin_ffs:
16607 case Builtin::BI__builtin_ffsl:
16608 case Builtin::BI__builtin_ffsll: {
16613 unsigned N = Val.countr_zero();
16614 return Success(N == Val.getBitWidth() ? 0 : N + 1, E);
16617 case Builtin::BI__builtin_fpclassify: {
16622 switch (Val.getCategory()) {
16623 case APFloat::fcNaN: Arg = 0;
break;
16624 case APFloat::fcInfinity: Arg = 1;
break;
16625 case APFloat::fcNormal: Arg = Val.isDenormal() ? 3 : 2;
break;
16626 case APFloat::fcZero: Arg = 4;
break;
16628 return Visit(E->
getArg(Arg));
16631 case Builtin::BI__builtin_isinf_sign: {
16634 Success(Val.isInfinity() ? (Val.isNegative() ? -1 : 1) : 0, E);
16637 case Builtin::BI__builtin_isinf: {
16640 Success(Val.isInfinity() ? 1 : 0, E);
16643 case Builtin::BI__builtin_isfinite: {
16646 Success(Val.isFinite() ? 1 : 0, E);
16649 case Builtin::BI__builtin_isnan: {
16652 Success(Val.isNaN() ? 1 : 0, E);
16655 case Builtin::BI__builtin_isnormal: {
16658 Success(Val.isNormal() ? 1 : 0, E);
16661 case Builtin::BI__builtin_issubnormal: {
16664 Success(Val.isDenormal() ? 1 : 0, E);
16667 case Builtin::BI__builtin_iszero: {
16670 Success(Val.isZero() ? 1 : 0, E);
16673 case Builtin::BI__builtin_signbit:
16674 case Builtin::BI__builtin_signbitf:
16675 case Builtin::BI__builtin_signbitl: {
16678 Success(Val.isNegative() ? 1 : 0, E);
16681 case Builtin::BI__builtin_isgreater:
16682 case Builtin::BI__builtin_isgreaterequal:
16683 case Builtin::BI__builtin_isless:
16684 case Builtin::BI__builtin_islessequal:
16685 case Builtin::BI__builtin_islessgreater:
16686 case Builtin::BI__builtin_isunordered: {
16695 switch (BuiltinOp) {
16696 case Builtin::BI__builtin_isgreater:
16698 case Builtin::BI__builtin_isgreaterequal:
16700 case Builtin::BI__builtin_isless:
16702 case Builtin::BI__builtin_islessequal:
16704 case Builtin::BI__builtin_islessgreater: {
16705 APFloat::cmpResult cmp = LHS.compare(RHS);
16706 return cmp == APFloat::cmpResult::cmpLessThan ||
16707 cmp == APFloat::cmpResult::cmpGreaterThan;
16709 case Builtin::BI__builtin_isunordered:
16710 return LHS.compare(RHS) == APFloat::cmpResult::cmpUnordered;
16712 llvm_unreachable(
"Unexpected builtin ID: Should be a floating "
16713 "point comparison function");
16721 case Builtin::BI__builtin_issignaling: {
16724 Success(Val.isSignaling() ? 1 : 0, E);
16727 case Builtin::BI__builtin_isfpclass: {
16731 unsigned Test =
static_cast<llvm::FPClassTest
>(MaskVal.getZExtValue());
16734 Success((Val.classify() & Test) ? 1 : 0, E);
16737 case Builtin::BI__builtin_parity:
16738 case Builtin::BI__builtin_parityl:
16739 case Builtin::BI__builtin_parityll: {
16744 return Success(Val.popcount() % 2, E);
16747 case Builtin::BI__builtin_abs:
16748 case Builtin::BI__builtin_labs:
16749 case Builtin::BI__builtin_llabs: {
16753 if (Val ==
APSInt(APInt::getSignedMinValue(Val.getBitWidth()),
16756 if (Val.isNegative())
16761 case Builtin::BI__builtin_popcount:
16762 case Builtin::BI__builtin_popcountl:
16763 case Builtin::BI__builtin_popcountll:
16764 case Builtin::BI__builtin_popcountg:
16765 case Builtin::BI__builtin_elementwise_popcount:
16766 case Builtin::BI__popcnt16:
16767 case Builtin::BI__popcnt:
16768 case Builtin::BI__popcnt64: {
16779 return Success(Val.popcount(), E);
16782 case Builtin::BI__builtin_rotateleft8:
16783 case Builtin::BI__builtin_rotateleft16:
16784 case Builtin::BI__builtin_rotateleft32:
16785 case Builtin::BI__builtin_rotateleft64:
16786 case Builtin::BI__builtin_rotateright8:
16787 case Builtin::BI__builtin_rotateright16:
16788 case Builtin::BI__builtin_rotateright32:
16789 case Builtin::BI__builtin_rotateright64:
16790 case Builtin::BI__builtin_stdc_rotate_left:
16791 case Builtin::BI__builtin_stdc_rotate_right:
16792 case Builtin::BI_rotl8:
16793 case Builtin::BI_rotl16:
16794 case Builtin::BI_rotl:
16795 case Builtin::BI_lrotl:
16796 case Builtin::BI_rotl64:
16797 case Builtin::BI_rotr8:
16798 case Builtin::BI_rotr16:
16799 case Builtin::BI_rotr:
16800 case Builtin::BI_lrotr:
16801 case Builtin::BI_rotr64: {
16809 switch (BuiltinOp) {
16810 case Builtin::BI__builtin_rotateright8:
16811 case Builtin::BI__builtin_rotateright16:
16812 case Builtin::BI__builtin_rotateright32:
16813 case Builtin::BI__builtin_rotateright64:
16814 case Builtin::BI__builtin_stdc_rotate_right:
16815 case Builtin::BI_rotr8:
16816 case Builtin::BI_rotr16:
16817 case Builtin::BI_rotr:
16818 case Builtin::BI_lrotr:
16819 case Builtin::BI_rotr64:
16828 case Builtin::BI__builtin_elementwise_add_sat: {
16834 APInt Result = LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS);
16837 case Builtin::BI__builtin_elementwise_sub_sat: {
16843 APInt Result = LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
16846 case Builtin::BI__builtin_elementwise_max: {
16855 case Builtin::BI__builtin_elementwise_min: {
16864 case Builtin::BI__builtin_elementwise_fshl:
16865 case Builtin::BI__builtin_elementwise_fshr: {
16872 switch (BuiltinOp) {
16873 case Builtin::BI__builtin_elementwise_fshl: {
16874 APSInt Result(llvm::APIntOps::fshl(Hi, Lo, Shift), Hi.isUnsigned());
16877 case Builtin::BI__builtin_elementwise_fshr: {
16878 APSInt Result(llvm::APIntOps::fshr(Hi, Lo, Shift), Hi.isUnsigned());
16882 llvm_unreachable(
"Fully covered switch above");
16884 case Builtin::BIstrlen:
16885 case Builtin::BIwcslen:
16887 if (Info.getLangOpts().CPlusPlus11)
16888 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
16890 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
16892 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
16894 case Builtin::BI__builtin_strlen:
16895 case Builtin::BI__builtin_wcslen: {
16898 if (std::optional<uint64_t> StrLen =
16904 case Builtin::BIstrcmp:
16905 case Builtin::BIwcscmp:
16906 case Builtin::BIstrncmp:
16907 case Builtin::BIwcsncmp:
16908 case Builtin::BImemcmp:
16909 case Builtin::BIbcmp:
16910 case Builtin::BIwmemcmp:
16912 if (Info.getLangOpts().CPlusPlus11)
16913 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
16915 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
16917 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
16919 case Builtin::BI__builtin_strcmp:
16920 case Builtin::BI__builtin_wcscmp:
16921 case Builtin::BI__builtin_strncmp:
16922 case Builtin::BI__builtin_wcsncmp:
16923 case Builtin::BI__builtin_memcmp:
16924 case Builtin::BI__builtin_bcmp:
16925 case Builtin::BI__builtin_wmemcmp: {
16926 LValue String1, String2;
16932 if (BuiltinOp != Builtin::BIstrcmp &&
16933 BuiltinOp != Builtin::BIwcscmp &&
16934 BuiltinOp != Builtin::BI__builtin_strcmp &&
16935 BuiltinOp != Builtin::BI__builtin_wcscmp) {
16939 MaxLength = N.getZExtValue();
16943 if (MaxLength == 0u)
16946 if (!String1.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
16947 !String2.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
16948 String1.Designator.Invalid || String2.Designator.Invalid)
16951 QualType CharTy1 = String1.Designator.getType(Info.Ctx);
16952 QualType CharTy2 = String2.Designator.getType(Info.Ctx);
16954 bool IsRawByte = BuiltinOp == Builtin::BImemcmp ||
16955 BuiltinOp == Builtin::BIbcmp ||
16956 BuiltinOp == Builtin::BI__builtin_memcmp ||
16957 BuiltinOp == Builtin::BI__builtin_bcmp;
16959 assert(IsRawByte ||
16960 (Info.Ctx.hasSameUnqualifiedType(
16962 Info.Ctx.hasSameUnqualifiedType(CharTy1, CharTy2)));
16969 Info.FFDiag(E, diag::note_constexpr_memcmp_unsupported)
16970 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp) << CharTy1
16975 const auto &ReadCurElems = [&](
APValue &Char1,
APValue &Char2) {
16978 Char1.
isInt() && Char2.isInt();
16980 const auto &AdvanceElems = [&] {
16986 (BuiltinOp != Builtin::BImemcmp && BuiltinOp != Builtin::BIbcmp &&
16987 BuiltinOp != Builtin::BIwmemcmp &&
16988 BuiltinOp != Builtin::BI__builtin_memcmp &&
16989 BuiltinOp != Builtin::BI__builtin_bcmp &&
16990 BuiltinOp != Builtin::BI__builtin_wmemcmp);
16991 bool IsWide = BuiltinOp == Builtin::BIwcscmp ||
16992 BuiltinOp == Builtin::BIwcsncmp ||
16993 BuiltinOp == Builtin::BIwmemcmp ||
16994 BuiltinOp == Builtin::BI__builtin_wcscmp ||
16995 BuiltinOp == Builtin::BI__builtin_wcsncmp ||
16996 BuiltinOp == Builtin::BI__builtin_wmemcmp;
16998 for (; MaxLength; --MaxLength) {
17000 if (!ReadCurElems(Char1, Char2))
17008 if (StopAtNull && !Char1.
getInt())
17010 assert(!(StopAtNull && !Char2.
getInt()));
17011 if (!AdvanceElems())
17018 case Builtin::BI__atomic_always_lock_free:
17019 case Builtin::BI__atomic_is_lock_free:
17020 case Builtin::BI__c11_atomic_is_lock_free: {
17036 if (
Size.isPowerOfTwo()) {
17038 unsigned InlineWidthBits =
17039 Info.Ctx.getTargetInfo().getMaxAtomicInlineWidth();
17040 if (Size <= Info.Ctx.toCharUnitsFromBits(InlineWidthBits)) {
17041 if (BuiltinOp == Builtin::BI__c11_atomic_is_lock_free ||
17047 const Expr *PtrArg = E->
getArg(1);
17053 IntResult.isAligned(
Size.getAsAlign()))
17057 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(PtrArg)) {
17060 if (ICE->getCastKind() == CK_BitCast)
17061 PtrArg = ICE->getSubExpr();
17064 if (
auto PtrTy = PtrArg->
getType()->
getAs<PointerType>()) {
17067 Info.Ctx.getTypeAlignInChars(PointeeType) >= Size) {
17075 return BuiltinOp == Builtin::BI__atomic_always_lock_free ?
17078 case Builtin::BI__builtin_addcb:
17079 case Builtin::BI__builtin_addcs:
17080 case Builtin::BI__builtin_addc:
17081 case Builtin::BI__builtin_addcl:
17082 case Builtin::BI__builtin_addcll:
17083 case Builtin::BI__builtin_subcb:
17084 case Builtin::BI__builtin_subcs:
17085 case Builtin::BI__builtin_subc:
17086 case Builtin::BI__builtin_subcl:
17087 case Builtin::BI__builtin_subcll: {
17088 LValue CarryOutLValue;
17100 bool FirstOverflowed =
false;
17101 bool SecondOverflowed =
false;
17102 switch (BuiltinOp) {
17104 llvm_unreachable(
"Invalid value for BuiltinOp");
17105 case Builtin::BI__builtin_addcb:
17106 case Builtin::BI__builtin_addcs:
17107 case Builtin::BI__builtin_addc:
17108 case Builtin::BI__builtin_addcl:
17109 case Builtin::BI__builtin_addcll:
17111 LHS.uadd_ov(RHS, FirstOverflowed).uadd_ov(CarryIn, SecondOverflowed);
17113 case Builtin::BI__builtin_subcb:
17114 case Builtin::BI__builtin_subcs:
17115 case Builtin::BI__builtin_subc:
17116 case Builtin::BI__builtin_subcl:
17117 case Builtin::BI__builtin_subcll:
17119 LHS.usub_ov(RHS, FirstOverflowed).usub_ov(CarryIn, SecondOverflowed);
17125 CarryOut = (
uint64_t)(FirstOverflowed | SecondOverflowed);
17131 case Builtin::BI__builtin_add_overflow:
17132 case Builtin::BI__builtin_sub_overflow:
17133 case Builtin::BI__builtin_mul_overflow:
17134 case Builtin::BI__builtin_sadd_overflow:
17135 case Builtin::BI__builtin_uadd_overflow:
17136 case Builtin::BI__builtin_uaddl_overflow:
17137 case Builtin::BI__builtin_uaddll_overflow:
17138 case Builtin::BI__builtin_usub_overflow:
17139 case Builtin::BI__builtin_usubl_overflow:
17140 case Builtin::BI__builtin_usubll_overflow:
17141 case Builtin::BI__builtin_umul_overflow:
17142 case Builtin::BI__builtin_umull_overflow:
17143 case Builtin::BI__builtin_umulll_overflow:
17144 case Builtin::BI__builtin_saddl_overflow:
17145 case Builtin::BI__builtin_saddll_overflow:
17146 case Builtin::BI__builtin_ssub_overflow:
17147 case Builtin::BI__builtin_ssubl_overflow:
17148 case Builtin::BI__builtin_ssubll_overflow:
17149 case Builtin::BI__builtin_smul_overflow:
17150 case Builtin::BI__builtin_smull_overflow:
17151 case Builtin::BI__builtin_smulll_overflow: {
17152 LValue ResultLValue;
17162 bool DidOverflow =
false;
17165 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
17166 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
17167 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
17168 bool IsSigned = LHS.isSigned() || RHS.isSigned() ||
17170 bool AllSigned = LHS.isSigned() && RHS.isSigned() &&
17172 uint64_t LHSSize = LHS.getBitWidth();
17173 uint64_t RHSSize = RHS.getBitWidth();
17174 uint64_t ResultSize = Info.Ctx.getTypeSize(ResultType);
17175 uint64_t MaxBits = std::max(std::max(LHSSize, RHSSize), ResultSize);
17181 if (IsSigned && !AllSigned)
17184 LHS =
APSInt(LHS.extOrTrunc(MaxBits), !IsSigned);
17185 RHS =
APSInt(RHS.extOrTrunc(MaxBits), !IsSigned);
17190 switch (BuiltinOp) {
17192 llvm_unreachable(
"Invalid value for BuiltinOp");
17193 case Builtin::BI__builtin_add_overflow:
17194 case Builtin::BI__builtin_sadd_overflow:
17195 case Builtin::BI__builtin_saddl_overflow:
17196 case Builtin::BI__builtin_saddll_overflow:
17197 case Builtin::BI__builtin_uadd_overflow:
17198 case Builtin::BI__builtin_uaddl_overflow:
17199 case Builtin::BI__builtin_uaddll_overflow:
17200 Result = LHS.isSigned() ? LHS.sadd_ov(RHS, DidOverflow)
17201 : LHS.uadd_ov(RHS, DidOverflow);
17203 case Builtin::BI__builtin_sub_overflow:
17204 case Builtin::BI__builtin_ssub_overflow:
17205 case Builtin::BI__builtin_ssubl_overflow:
17206 case Builtin::BI__builtin_ssubll_overflow:
17207 case Builtin::BI__builtin_usub_overflow:
17208 case Builtin::BI__builtin_usubl_overflow:
17209 case Builtin::BI__builtin_usubll_overflow:
17210 Result = LHS.isSigned() ? LHS.ssub_ov(RHS, DidOverflow)
17211 : LHS.usub_ov(RHS, DidOverflow);
17213 case Builtin::BI__builtin_mul_overflow:
17214 case Builtin::BI__builtin_smul_overflow:
17215 case Builtin::BI__builtin_smull_overflow:
17216 case Builtin::BI__builtin_smulll_overflow:
17217 case Builtin::BI__builtin_umul_overflow:
17218 case Builtin::BI__builtin_umull_overflow:
17219 case Builtin::BI__builtin_umulll_overflow:
17220 Result = LHS.isSigned() ? LHS.smul_ov(RHS, DidOverflow)
17221 : LHS.umul_ov(RHS, DidOverflow);
17227 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
17228 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
17229 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
17235 APSInt Temp =
Result.extOrTrunc(Info.Ctx.getTypeSize(ResultType));
17238 if (!APSInt::isSameValue(Temp,
Result))
17239 DidOverflow =
true;
17246 return Success(DidOverflow, E);
17249 case Builtin::BI__builtin_reduce_add:
17250 case Builtin::BI__builtin_reduce_mul:
17251 case Builtin::BI__builtin_reduce_and:
17252 case Builtin::BI__builtin_reduce_or:
17253 case Builtin::BI__builtin_reduce_xor:
17254 case Builtin::BI__builtin_reduce_min:
17255 case Builtin::BI__builtin_reduce_max: {
17262 for (
unsigned EltNum = 1; EltNum < SourceLen; ++EltNum) {
17263 switch (BuiltinOp) {
17266 case Builtin::BI__builtin_reduce_add: {
17269 Reduced.getBitWidth() + 1, std::plus<APSInt>(), Reduced))
17273 case Builtin::BI__builtin_reduce_mul: {
17276 Reduced.getBitWidth() * 2, std::multiplies<APSInt>(), Reduced))
17280 case Builtin::BI__builtin_reduce_and: {
17284 case Builtin::BI__builtin_reduce_or: {
17288 case Builtin::BI__builtin_reduce_xor: {
17292 case Builtin::BI__builtin_reduce_min: {
17296 case Builtin::BI__builtin_reduce_max: {
17306 case clang::X86::BI__builtin_ia32_addcarryx_u32:
17307 case clang::X86::BI__builtin_ia32_addcarryx_u64:
17308 case clang::X86::BI__builtin_ia32_subborrow_u32:
17309 case clang::X86::BI__builtin_ia32_subborrow_u64: {
17310 LValue ResultLValue;
17311 APSInt CarryIn, LHS, RHS;
17319 bool IsAdd = BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u32 ||
17320 BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u64;
17322 unsigned BitWidth = LHS.getBitWidth();
17323 unsigned CarryInBit = CarryIn.ugt(0) ? 1 : 0;
17326 ? (LHS.zext(BitWidth + 1) + (RHS.zext(BitWidth + 1) + CarryInBit))
17327 : (LHS.zext(BitWidth + 1) - (RHS.zext(BitWidth + 1) + CarryInBit));
17329 APInt Result = ExResult.extractBits(BitWidth, 0);
17330 uint64_t CarryOut = ExResult.extractBitsAsZExtValue(1, BitWidth);
17338 case clang::X86::BI__builtin_ia32_movmskps:
17339 case clang::X86::BI__builtin_ia32_movmskpd:
17340 case clang::X86::BI__builtin_ia32_pmovmskb128:
17341 case clang::X86::BI__builtin_ia32_pmovmskb256:
17342 case clang::X86::BI__builtin_ia32_movmskps256:
17343 case clang::X86::BI__builtin_ia32_movmskpd256: {
17350 unsigned ResultLen = Info.Ctx.getTypeSize(
17354 for (
unsigned I = 0; I != SourceLen; ++I) {
17356 if (ElemQT->isIntegerType()) {
17358 }
else if (ElemQT->isRealFloatingType()) {
17363 Result.setBitVal(I, Elem.isNegative());
17368 case clang::X86::BI__builtin_ia32_bextr_u32:
17369 case clang::X86::BI__builtin_ia32_bextr_u64:
17370 case clang::X86::BI__builtin_ia32_bextri_u32:
17371 case clang::X86::BI__builtin_ia32_bextri_u64: {
17377 unsigned BitWidth = Val.getBitWidth();
17379 uint64_t Length = Idx.extractBitsAsZExtValue(8, 8);
17380 Length = Length > BitWidth ? BitWidth : Length;
17383 if (Length == 0 || Shift >= BitWidth)
17387 Result &= llvm::maskTrailingOnes<uint64_t>(Length);
17391 case clang::X86::BI__builtin_ia32_bzhi_si:
17392 case clang::X86::BI__builtin_ia32_bzhi_di: {
17398 unsigned BitWidth = Val.getBitWidth();
17399 unsigned Index = Idx.extractBitsAsZExtValue(8, 0);
17400 if (Index < BitWidth)
17401 Val.clearHighBits(BitWidth - Index);
17405 case clang::X86::BI__builtin_ia32_ktestcqi:
17406 case clang::X86::BI__builtin_ia32_ktestchi:
17407 case clang::X86::BI__builtin_ia32_ktestcsi:
17408 case clang::X86::BI__builtin_ia32_ktestcdi: {
17414 return Success((~A & B) == 0, E);
17417 case clang::X86::BI__builtin_ia32_ktestzqi:
17418 case clang::X86::BI__builtin_ia32_ktestzhi:
17419 case clang::X86::BI__builtin_ia32_ktestzsi:
17420 case clang::X86::BI__builtin_ia32_ktestzdi: {
17426 return Success((A & B) == 0, E);
17429 case clang::X86::BI__builtin_ia32_kortestcqi:
17430 case clang::X86::BI__builtin_ia32_kortestchi:
17431 case clang::X86::BI__builtin_ia32_kortestcsi:
17432 case clang::X86::BI__builtin_ia32_kortestcdi: {
17438 return Success(~(A | B) == 0, E);
17441 case clang::X86::BI__builtin_ia32_kortestzqi:
17442 case clang::X86::BI__builtin_ia32_kortestzhi:
17443 case clang::X86::BI__builtin_ia32_kortestzsi:
17444 case clang::X86::BI__builtin_ia32_kortestzdi: {
17450 return Success((A | B) == 0, E);
17453 case clang::X86::BI__builtin_ia32_kunpckhi:
17454 case clang::X86::BI__builtin_ia32_kunpckdi:
17455 case clang::X86::BI__builtin_ia32_kunpcksi: {
17463 unsigned BW = A.getBitWidth();
17464 APSInt Result(A.trunc(BW / 2).concat(B.trunc(BW / 2)), A.isUnsigned());
17468 case clang::X86::BI__builtin_ia32_lzcnt_u16:
17469 case clang::X86::BI__builtin_ia32_lzcnt_u32:
17470 case clang::X86::BI__builtin_ia32_lzcnt_u64: {
17474 return Success(Val.countLeadingZeros(), E);
17477 case clang::X86::BI__builtin_ia32_tzcnt_u16:
17478 case clang::X86::BI__builtin_ia32_tzcnt_u32:
17479 case clang::X86::BI__builtin_ia32_tzcnt_u64: {
17483 return Success(Val.countTrailingZeros(), E);
17486 case clang::X86::BI__builtin_ia32_pdep_si:
17487 case clang::X86::BI__builtin_ia32_pdep_di: {
17493 unsigned BitWidth = Val.getBitWidth();
17495 for (
unsigned I = 0, P = 0; I != BitWidth; ++I)
17497 Result.setBitVal(I, Val[P++]);
17501 case clang::X86::BI__builtin_ia32_pext_si:
17502 case clang::X86::BI__builtin_ia32_pext_di: {
17508 unsigned BitWidth = Val.getBitWidth();
17510 for (
unsigned I = 0, P = 0; I != BitWidth; ++I)
17512 Result.setBitVal(P++, Val[I]);
17515 case X86::BI__builtin_ia32_ptestz128:
17516 case X86::BI__builtin_ia32_ptestz256:
17517 case X86::BI__builtin_ia32_vtestzps:
17518 case X86::BI__builtin_ia32_vtestzps256:
17519 case X86::BI__builtin_ia32_vtestzpd:
17520 case X86::BI__builtin_ia32_vtestzpd256: {
17522 [](
const APInt &A,
const APInt &B) {
return (A & B) == 0; });
17524 case X86::BI__builtin_ia32_ptestc128:
17525 case X86::BI__builtin_ia32_ptestc256:
17526 case X86::BI__builtin_ia32_vtestcps:
17527 case X86::BI__builtin_ia32_vtestcps256:
17528 case X86::BI__builtin_ia32_vtestcpd:
17529 case X86::BI__builtin_ia32_vtestcpd256: {
17531 [](
const APInt &A,
const APInt &B) {
return (~A & B) == 0; });
17533 case X86::BI__builtin_ia32_ptestnzc128:
17534 case X86::BI__builtin_ia32_ptestnzc256:
17535 case X86::BI__builtin_ia32_vtestnzcps:
17536 case X86::BI__builtin_ia32_vtestnzcps256:
17537 case X86::BI__builtin_ia32_vtestnzcpd:
17538 case X86::BI__builtin_ia32_vtestnzcpd256: {
17539 return EvalTestOp([](
const APInt &A,
const APInt &B) {
17540 return ((A & B) != 0) && ((~A & B) != 0);
17543 case X86::BI__builtin_ia32_kandqi:
17544 case X86::BI__builtin_ia32_kandhi:
17545 case X86::BI__builtin_ia32_kandsi:
17546 case X86::BI__builtin_ia32_kanddi: {
17547 return HandleMaskBinOp(
17548 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS & RHS; });
17551 case X86::BI__builtin_ia32_kandnqi:
17552 case X86::BI__builtin_ia32_kandnhi:
17553 case X86::BI__builtin_ia32_kandnsi:
17554 case X86::BI__builtin_ia32_kandndi: {
17555 return HandleMaskBinOp(
17556 [](
const APSInt &LHS,
const APSInt &RHS) {
return ~LHS & RHS; });
17559 case X86::BI__builtin_ia32_korqi:
17560 case X86::BI__builtin_ia32_korhi:
17561 case X86::BI__builtin_ia32_korsi:
17562 case X86::BI__builtin_ia32_kordi: {
17563 return HandleMaskBinOp(
17564 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS | RHS; });
17567 case X86::BI__builtin_ia32_kxnorqi:
17568 case X86::BI__builtin_ia32_kxnorhi:
17569 case X86::BI__builtin_ia32_kxnorsi:
17570 case X86::BI__builtin_ia32_kxnordi: {
17571 return HandleMaskBinOp(
17572 [](
const APSInt &LHS,
const APSInt &RHS) {
return ~(LHS ^ RHS); });
17575 case X86::BI__builtin_ia32_kxorqi:
17576 case X86::BI__builtin_ia32_kxorhi:
17577 case X86::BI__builtin_ia32_kxorsi:
17578 case X86::BI__builtin_ia32_kxordi: {
17579 return HandleMaskBinOp(
17580 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS ^ RHS; });
17583 case X86::BI__builtin_ia32_knotqi:
17584 case X86::BI__builtin_ia32_knothi:
17585 case X86::BI__builtin_ia32_knotsi:
17586 case X86::BI__builtin_ia32_knotdi: {
17594 case X86::BI__builtin_ia32_kaddqi:
17595 case X86::BI__builtin_ia32_kaddhi:
17596 case X86::BI__builtin_ia32_kaddsi:
17597 case X86::BI__builtin_ia32_kadddi: {
17598 return HandleMaskBinOp(
17599 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS + RHS; });
17602 case X86::BI__builtin_ia32_kmovb:
17603 case X86::BI__builtin_ia32_kmovw:
17604 case X86::BI__builtin_ia32_kmovd:
17605 case X86::BI__builtin_ia32_kmovq: {
17612 case X86::BI__builtin_ia32_kshiftliqi:
17613 case X86::BI__builtin_ia32_kshiftlihi:
17614 case X86::BI__builtin_ia32_kshiftlisi:
17615 case X86::BI__builtin_ia32_kshiftlidi: {
17616 return HandleMaskBinOp([](
const APSInt &LHS,
const APSInt &RHS) {
17617 unsigned Amt = RHS.getZExtValue() & 0xFF;
17618 if (Amt >= LHS.getBitWidth())
17619 return APSInt(APInt::getZero(LHS.getBitWidth()), LHS.isUnsigned());
17620 return APSInt(LHS.shl(Amt), LHS.isUnsigned());
17624 case X86::BI__builtin_ia32_kshiftriqi:
17625 case X86::BI__builtin_ia32_kshiftrihi:
17626 case X86::BI__builtin_ia32_kshiftrisi:
17627 case X86::BI__builtin_ia32_kshiftridi: {
17628 return HandleMaskBinOp([](
const APSInt &LHS,
const APSInt &RHS) {
17629 unsigned Amt = RHS.getZExtValue() & 0xFF;
17630 if (Amt >= LHS.getBitWidth())
17631 return APSInt(APInt::getZero(LHS.getBitWidth()), LHS.isUnsigned());
17632 return APSInt(LHS.lshr(Amt), LHS.isUnsigned());
17636 case clang::X86::BI__builtin_ia32_vec_ext_v4hi:
17637 case clang::X86::BI__builtin_ia32_vec_ext_v16qi:
17638 case clang::X86::BI__builtin_ia32_vec_ext_v8hi:
17639 case clang::X86::BI__builtin_ia32_vec_ext_v4si:
17640 case clang::X86::BI__builtin_ia32_vec_ext_v2di:
17641 case clang::X86::BI__builtin_ia32_vec_ext_v32qi:
17642 case clang::X86::BI__builtin_ia32_vec_ext_v16hi:
17643 case clang::X86::BI__builtin_ia32_vec_ext_v8si:
17644 case clang::X86::BI__builtin_ia32_vec_ext_v4di: {
17651 unsigned Idx =
static_cast<unsigned>(IdxAPS.getZExtValue() & (N - 1));
17655 case clang::X86::BI__builtin_ia32_cvtb2mask128:
17656 case clang::X86::BI__builtin_ia32_cvtb2mask256:
17657 case clang::X86::BI__builtin_ia32_cvtb2mask512:
17658 case clang::X86::BI__builtin_ia32_cvtw2mask128:
17659 case clang::X86::BI__builtin_ia32_cvtw2mask256:
17660 case clang::X86::BI__builtin_ia32_cvtw2mask512:
17661 case clang::X86::BI__builtin_ia32_cvtd2mask128:
17662 case clang::X86::BI__builtin_ia32_cvtd2mask256:
17663 case clang::X86::BI__builtin_ia32_cvtd2mask512:
17664 case clang::X86::BI__builtin_ia32_cvtq2mask128:
17665 case clang::X86::BI__builtin_ia32_cvtq2mask256:
17666 case clang::X86::BI__builtin_ia32_cvtq2mask512: {
17673 unsigned RetWidth = Info.Ctx.getIntWidth(E->
getType());
17674 llvm::APInt Bits(RetWidth, 0);
17676 for (
unsigned ElemNum = 0; ElemNum != VectorLen; ++ElemNum) {
17678 unsigned MSB = A[A.getBitWidth() - 1];
17679 Bits.setBitVal(ElemNum, MSB);
17682 APSInt RetMask(Bits,
true);
17686 case clang::X86::BI__builtin_ia32_cmpb128_mask:
17687 case clang::X86::BI__builtin_ia32_cmpw128_mask:
17688 case clang::X86::BI__builtin_ia32_cmpd128_mask:
17689 case clang::X86::BI__builtin_ia32_cmpq128_mask:
17690 case clang::X86::BI__builtin_ia32_cmpb256_mask:
17691 case clang::X86::BI__builtin_ia32_cmpw256_mask:
17692 case clang::X86::BI__builtin_ia32_cmpd256_mask:
17693 case clang::X86::BI__builtin_ia32_cmpq256_mask:
17694 case clang::X86::BI__builtin_ia32_cmpb512_mask:
17695 case clang::X86::BI__builtin_ia32_cmpw512_mask:
17696 case clang::X86::BI__builtin_ia32_cmpd512_mask:
17697 case clang::X86::BI__builtin_ia32_cmpq512_mask:
17698 case clang::X86::BI__builtin_ia32_ucmpb128_mask:
17699 case clang::X86::BI__builtin_ia32_ucmpw128_mask:
17700 case clang::X86::BI__builtin_ia32_ucmpd128_mask:
17701 case clang::X86::BI__builtin_ia32_ucmpq128_mask:
17702 case clang::X86::BI__builtin_ia32_ucmpb256_mask:
17703 case clang::X86::BI__builtin_ia32_ucmpw256_mask:
17704 case clang::X86::BI__builtin_ia32_ucmpd256_mask:
17705 case clang::X86::BI__builtin_ia32_ucmpq256_mask:
17706 case clang::X86::BI__builtin_ia32_ucmpb512_mask:
17707 case clang::X86::BI__builtin_ia32_ucmpw512_mask:
17708 case clang::X86::BI__builtin_ia32_ucmpd512_mask:
17709 case clang::X86::BI__builtin_ia32_ucmpq512_mask: {
17713 (BuiltinOp >= clang::X86::BI__builtin_ia32_ucmpb128_mask &&
17714 BuiltinOp <= clang::X86::BI__builtin_ia32_ucmpw512_mask);
17727 unsigned RetWidth = Mask.getBitWidth();
17729 APSInt RetMask(llvm::APInt(RetWidth, 0),
true);
17731 for (
unsigned ElemNum = 0; ElemNum < VectorLen; ++ElemNum) {
17736 switch (
Opcode.getExtValue() & 0x7) {
17741 Result = IsUnsigned ? A.ult(B) : A.slt(B);
17744 Result = IsUnsigned ? A.ule(B) : A.sle(B);
17753 Result = IsUnsigned ? A.uge(B) : A.sge(B);
17756 Result = IsUnsigned ? A.ugt(B) : A.sgt(B);
17763 RetMask.setBitVal(ElemNum, Mask[ElemNum] &&
Result);
17768 case X86::BI__builtin_ia32_vpshufbitqmb128_mask:
17769 case X86::BI__builtin_ia32_vpshufbitqmb256_mask:
17770 case X86::BI__builtin_ia32_vpshufbitqmb512_mask: {
17783 unsigned NumBytesInQWord = 8;
17784 unsigned NumBitsInByte = 8;
17786 unsigned NumQWords = NumBytes / NumBytesInQWord;
17787 unsigned RetWidth = ZeroMask.getBitWidth();
17788 APSInt RetMask(llvm::APInt(RetWidth, 0),
true);
17790 for (
unsigned QWordId = 0; QWordId != NumQWords; ++QWordId) {
17791 APInt SourceQWord(64, 0);
17792 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
17796 SourceQWord.insertBits(
APInt(8, Byte & 0xFF), ByteIdx * NumBitsInByte);
17799 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
17800 unsigned SelIdx = QWordId * NumBytesInQWord + ByteIdx;
17803 if (ZeroMask[SelIdx]) {
17804 RetMask.setBitVal(SelIdx, SourceQWord[M]);
17816 const LValue &LV) {
17819 if (!LV.getLValueBase())
17824 if (!LV.getLValueDesignator().Invalid &&
17825 !LV.getLValueDesignator().isOnePastTheEnd())
17835 if (LV.getLValueDesignator().Invalid)
17841 return LV.getLValueOffset() == Size;
17851class DataRecursiveIntBinOpEvaluator {
17852 struct EvalResult {
17854 bool Failed =
false;
17856 EvalResult() =
default;
17858 void swap(EvalResult &RHS) {
17860 Failed = RHS.Failed;
17861 RHS.Failed =
false;
17867 EvalResult LHSResult;
17868 enum { AnyExprKind, BinOpKind, BinOpVisitedLHSKind }
Kind;
17871 Job(Job &&) =
default;
17873 void startSpeculativeEval(EvalInfo &Info) {
17874 SpecEvalRAII = SpeculativeEvaluationRAII(Info);
17878 SpeculativeEvaluationRAII SpecEvalRAII;
17881 SmallVector<Job, 16> Queue;
17883 IntExprEvaluator &IntEval;
17888 DataRecursiveIntBinOpEvaluator(IntExprEvaluator &IntEval,
APValue &
Result)
17889 : IntEval(IntEval), Info(IntEval.getEvalInfo()), FinalResult(
Result) { }
17895 static bool shouldEnqueue(
const BinaryOperator *E) {
17902 bool Traverse(
const BinaryOperator *E) {
17904 EvalResult PrevResult;
17905 while (!Queue.empty())
17906 process(PrevResult);
17908 if (PrevResult.Failed)
return false;
17910 FinalResult.
swap(PrevResult.Val);
17921 bool Error(
const Expr *E) {
17922 return IntEval.Error(E);
17925 return IntEval.Error(E, D);
17928 OptionalDiagnostic CCEDiag(
const Expr *E,
diag::kind D) {
17929 return Info.CCEDiag(E, D);
17933 bool VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
17934 bool &SuppressRHSDiags);
17936 bool VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
17939 void EvaluateExpr(
const Expr *E, EvalResult &
Result) {
17945 void process(EvalResult &
Result);
17947 void enqueue(
const Expr *E) {
17949 Queue.resize(Queue.size()+1);
17950 Queue.back().E = E;
17951 Queue.back().Kind = Job::AnyExprKind;
17957bool DataRecursiveIntBinOpEvaluator::
17958 VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
17959 bool &SuppressRHSDiags) {
17962 if (LHSResult.Failed)
17963 return Info.noteSideEffect();
17972 if (LHSAsBool == (E->
getOpcode() == BO_LOr)) {
17973 Success(LHSAsBool, E, LHSResult.Val);
17977 LHSResult.Failed =
true;
17981 if (!Info.noteSideEffect())
17987 SuppressRHSDiags =
true;
17996 if (LHSResult.Failed && !Info.noteFailure())
18007 assert(!LVal.
hasLValuePath() &&
"have designator for integer lvalue");
18009 uint64_t Offset64 = Offset.getQuantity();
18010 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
18012 : Offset64 + Index64);
18015bool DataRecursiveIntBinOpEvaluator::
18016 VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
18019 if (RHSResult.Failed)
18026 bool lhsResult, rhsResult;
18041 if (rhsResult == (E->
getOpcode() == BO_LOr))
18052 if (LHSResult.Failed || RHSResult.Failed)
18055 const APValue &LHSVal = LHSResult.Val;
18056 const APValue &RHSVal = RHSResult.Val;
18080 if (!LHSExpr || !RHSExpr)
18082 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
18083 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
18084 if (!LHSAddrExpr || !RHSAddrExpr)
18109void DataRecursiveIntBinOpEvaluator::process(EvalResult &
Result) {
18110 Job &job = Queue.back();
18112 switch (job.Kind) {
18113 case Job::AnyExprKind: {
18114 if (
const BinaryOperator *Bop = dyn_cast<BinaryOperator>(job.E)) {
18115 if (shouldEnqueue(Bop)) {
18116 job.Kind = Job::BinOpKind;
18117 enqueue(Bop->getLHS());
18122 EvaluateExpr(job.E,
Result);
18127 case Job::BinOpKind: {
18129 bool SuppressRHSDiags =
false;
18130 if (!VisitBinOpLHSOnly(
Result, Bop, SuppressRHSDiags)) {
18134 if (SuppressRHSDiags)
18135 job.startSpeculativeEval(Info);
18136 job.LHSResult.swap(
Result);
18137 job.Kind = Job::BinOpVisitedLHSKind;
18142 case Job::BinOpVisitedLHSKind: {
18146 Result.Failed = !VisitBinOp(job.LHSResult, RHS, Bop,
Result.Val);
18152 llvm_unreachable(
"Invalid Job::Kind!");
18156enum class CmpResult {
18165template <
class SuccessCB,
class AfterCB>
18168 SuccessCB &&
Success, AfterCB &&DoAfter) {
18173 "unsupported binary expression evaluation");
18175 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
18189 if (!LHSOK && !Info.noteFailure())
18194 return Success(CmpResult::Less, E);
18196 return Success(CmpResult::Greater, E);
18197 return Success(CmpResult::Equal, E);
18201 APFixedPoint LHSFX(Info.Ctx.getFixedPointSemantics(LHSTy));
18202 APFixedPoint RHSFX(Info.Ctx.getFixedPointSemantics(RHSTy));
18205 if (!LHSOK && !Info.noteFailure())
18210 return Success(CmpResult::Less, E);
18212 return Success(CmpResult::Greater, E);
18213 return Success(CmpResult::Equal, E);
18217 ComplexValue LHS, RHS;
18226 LHS.makeComplexFloat();
18227 LHS.FloatImag = APFloat(LHS.FloatReal.getSemantics());
18232 if (!LHSOK && !Info.noteFailure())
18238 RHS.makeComplexFloat();
18239 RHS.FloatImag = APFloat(RHS.FloatReal.getSemantics());
18243 if (LHS.isComplexFloat()) {
18244 APFloat::cmpResult CR_r =
18245 LHS.getComplexFloatReal().compare(RHS.getComplexFloatReal());
18246 APFloat::cmpResult CR_i =
18247 LHS.getComplexFloatImag().compare(RHS.getComplexFloatImag());
18248 bool IsEqual = CR_r == APFloat::cmpEqual && CR_i == APFloat::cmpEqual;
18249 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal, E);
18251 assert(IsEquality &&
"invalid complex comparison");
18252 bool IsEqual = LHS.getComplexIntReal() == RHS.getComplexIntReal() &&
18253 LHS.getComplexIntImag() == RHS.getComplexIntImag();
18254 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal, E);
18260 APFloat RHS(0.0), LHS(0.0);
18263 if (!LHSOK && !Info.noteFailure())
18270 llvm::APFloatBase::cmpResult APFloatCmpResult = LHS.compare(RHS);
18271 if (!Info.InConstantContext &&
18272 APFloatCmpResult == APFloat::cmpUnordered &&
18275 Info.FFDiag(E, diag::note_constexpr_float_arithmetic_strict);
18278 auto GetCmpRes = [&]() {
18279 switch (APFloatCmpResult) {
18280 case APFloat::cmpEqual:
18281 return CmpResult::Equal;
18282 case APFloat::cmpLessThan:
18283 return CmpResult::Less;
18284 case APFloat::cmpGreaterThan:
18285 return CmpResult::Greater;
18286 case APFloat::cmpUnordered:
18287 return CmpResult::Unordered;
18289 llvm_unreachable(
"Unrecognised APFloat::cmpResult enum");
18291 return Success(GetCmpRes(), E);
18295 LValue LHSValue, RHSValue;
18298 if (!LHSOK && !Info.noteFailure())
18309 if (Info.checkingPotentialConstantExpression() &&
18310 (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown))
18312 auto DiagComparison = [&] (
unsigned DiagID,
bool Reversed =
false) {
18313 std::string LHS = LHSValue.toString(Info.Ctx, E->
getLHS()->
getType());
18314 std::string RHS = RHSValue.toString(Info.Ctx, E->
getRHS()->
getType());
18315 Info.FFDiag(E, DiagID)
18322 return DiagComparison(
18323 diag::note_constexpr_pointer_comparison_unspecified);
18329 if ((!LHSValue.Base && !LHSValue.Offset.
isZero()) ||
18330 (!RHSValue.Base && !RHSValue.Offset.
isZero()))
18331 return DiagComparison(diag::note_constexpr_pointer_constant_comparison,
18345 return DiagComparison(diag::note_constexpr_literal_comparison);
18347 return DiagComparison(diag::note_constexpr_opaque_call_comparison,
18352 return DiagComparison(diag::note_constexpr_pointer_weak_comparison,
18356 if (LHSValue.Base && LHSValue.Offset.
isZero() &&
18358 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
18360 if (RHSValue.Base && RHSValue.Offset.
isZero() &&
18362 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
18368 return DiagComparison(
18369 diag::note_constexpr_pointer_comparison_zero_sized);
18370 if (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown)
18371 return DiagComparison(
18372 diag::note_constexpr_pointer_comparison_unspecified);
18374 return Success(CmpResult::Unequal, E);
18377 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
18378 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
18380 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
18381 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
18391 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid && IsRelational) {
18392 bool WasArrayIndex;
18395 :
getType(LHSValue.Base).getNonReferenceType(),
18396 LHSDesignator, RHSDesignator, WasArrayIndex);
18403 if (!WasArrayIndex && Mismatch < LHSDesignator.Entries.size() &&
18404 Mismatch < RHSDesignator.Entries.size()) {
18405 const FieldDecl *LF = getAsField(LHSDesignator.Entries[Mismatch]);
18406 const FieldDecl *RF = getAsField(RHSDesignator.Entries[Mismatch]);
18408 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_classes);
18410 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
18411 << getAsBaseClass(LHSDesignator.Entries[Mismatch])
18414 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
18415 << getAsBaseClass(RHSDesignator.Entries[Mismatch])
18420 diag::note_constexpr_pointer_comparison_differing_access)
18428 unsigned PtrSize = Info.Ctx.getTypeSize(LHSTy);
18431 assert(PtrSize <= 64 &&
"Unexpected pointer width");
18432 uint64_t Mask = ~0ULL >> (64 - PtrSize);
18433 CompareLHS &= Mask;
18434 CompareRHS &= Mask;
18439 if (!LHSValue.Base.
isNull() && IsRelational) {
18443 CharUnits Size = Info.Ctx.getTypeSizeInChars(BaseTy);
18444 uint64_t OffsetLimit = Size.getQuantity();
18445 if (CompareLHS > OffsetLimit || CompareRHS > OffsetLimit)
18449 if (CompareLHS < CompareRHS)
18450 return Success(CmpResult::Less, E);
18451 if (CompareLHS > CompareRHS)
18452 return Success(CmpResult::Greater, E);
18453 return Success(CmpResult::Equal, E);
18457 assert(IsEquality &&
"unexpected member pointer operation");
18460 MemberPtr LHSValue, RHSValue;
18463 if (!LHSOK && !Info.noteFailure())
18471 if (LHSValue.getDecl() && LHSValue.getDecl()->isWeak()) {
18472 Info.FFDiag(E, diag::note_constexpr_mem_pointer_weak_comparison)
18473 << LHSValue.getDecl();
18476 if (RHSValue.getDecl() && RHSValue.getDecl()->isWeak()) {
18477 Info.FFDiag(E, diag::note_constexpr_mem_pointer_weak_comparison)
18478 << RHSValue.getDecl();
18485 if (!LHSValue.getDecl() || !RHSValue.getDecl()) {
18486 bool Equal = !LHSValue.getDecl() && !RHSValue.getDecl();
18487 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal, E);
18492 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(LHSValue.getDecl()))
18493 if (MD->isVirtual())
18494 Info.CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
18495 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(RHSValue.getDecl()))
18496 if (MD->isVirtual())
18497 Info.CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
18503 bool Equal = LHSValue == RHSValue;
18504 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal, E);
18509 assert(RHSTy->
isNullPtrType() &&
"missing pointer conversion");
18517 return Success(CmpResult::Equal, E);
18523bool RecordExprEvaluator::VisitBinCmp(
const BinaryOperator *E) {
18527 auto OnSuccess = [&](CmpResult CR,
const BinaryOperator *E) {
18530 case CmpResult::Unequal:
18531 llvm_unreachable(
"should never produce Unequal for three-way comparison");
18532 case CmpResult::Less:
18533 CCR = ComparisonCategoryResult::Less;
18535 case CmpResult::Equal:
18536 CCR = ComparisonCategoryResult::Equal;
18538 case CmpResult::Greater:
18539 CCR = ComparisonCategoryResult::Greater;
18541 case CmpResult::Unordered:
18542 CCR = ComparisonCategoryResult::Unordered;
18547 const ComparisonCategoryInfo &CmpInfo =
18548 Info.Ctx.CompCategories.getInfoForType(E->
getType());
18556 ConstantExprKind::Normal);
18559 return ExprEvaluatorBaseTy::VisitBinCmp(E);
18563bool RecordExprEvaluator::VisitCXXParenListInitExpr(
18564 const CXXParenListInitExpr *E) {
18565 return VisitCXXParenListOrInitListExpr(E, E->
getInitExprs());
18568bool IntExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
18573 if (!Info.noteFailure())
18577 if (DataRecursiveIntBinOpEvaluator::shouldEnqueue(E))
18578 return DataRecursiveIntBinOpEvaluator(*
this,
Result).Traverse(E);
18582 "DataRecursiveIntBinOpEvaluator should have handled integral types");
18587 auto OnSuccess = [&](CmpResult CR,
const BinaryOperator *E) {
18588 assert((CR != CmpResult::Unequal || E->
isEqualityOp()) &&
18589 "should only produce Unequal for equality comparisons");
18590 bool IsEqual = CR == CmpResult::Equal,
18591 IsLess = CR == CmpResult::Less,
18592 IsGreater = CR == CmpResult::Greater;
18596 llvm_unreachable(
"unsupported binary operator");
18599 return Success(IsEqual == (Op == BO_EQ), E);
18603 return Success(IsGreater, E);
18605 return Success(IsEqual || IsLess, E);
18607 return Success(IsEqual || IsGreater, E);
18611 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
18620 LValue LHSValue, RHSValue;
18623 if (!LHSOK && !Info.noteFailure())
18632 if (Info.checkingPotentialConstantExpression() &&
18633 (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown))
18636 const Expr *LHSExpr = LHSValue.Base.
dyn_cast<
const Expr *>();
18637 const Expr *RHSExpr = RHSValue.Base.
dyn_cast<
const Expr *>();
18639 auto DiagArith = [&](
unsigned DiagID) {
18640 std::string LHS = LHSValue.toString(Info.Ctx, E->
getLHS()->
getType());
18641 std::string RHS = RHSValue.toString(Info.Ctx, E->
getRHS()->
getType());
18642 Info.FFDiag(E, DiagID) << LHS << RHS;
18643 if (LHSExpr && LHSExpr == RHSExpr)
18645 diag::note_constexpr_repeated_literal_eval)
18650 if (!LHSExpr || !RHSExpr)
18651 return DiagArith(diag::note_constexpr_pointer_arith_unspecified);
18654 return DiagArith(diag::note_constexpr_literal_arith);
18656 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
18657 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
18658 if (!LHSAddrExpr || !RHSAddrExpr)
18666 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
18667 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
18669 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
18670 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
18676 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid &&
18679 Info.CCEDiag(E, diag::note_constexpr_pointer_subtraction_not_same_array);
18684 CharUnits ElementSize;
18691 if (ElementSize.
isZero()) {
18692 Info.FFDiag(E, diag::note_constexpr_pointer_subtraction_zero_size)
18709 APSInt TrueResult = (LHS - RHS) / ElemSize;
18712 if (
Result.extend(65) != TrueResult &&
18718 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
18723bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr(
18724 const UnaryExprOrTypeTraitExpr *E) {
18726 case UETT_PreferredAlignOf:
18727 case UETT_AlignOf: {
18736 case UETT_PtrAuthTypeDiscriminator: {
18742 case UETT_VecStep: {
18746 unsigned n = Ty->
castAs<VectorType>()->getNumElements();
18758 case UETT_DataSizeOf:
18759 case UETT_SizeOf: {
18763 if (
const ReferenceType *Ref = SrcTy->
getAs<ReferenceType>())
18774 case UETT_OpenMPRequiredSimdAlign:
18777 Info.Ctx.toCharUnitsFromBits(
18781 case UETT_VectorElements: {
18785 if (
const auto *VT = Ty->
getAs<VectorType>())
18789 if (Info.InConstantContext)
18790 Info.CCEDiag(E, diag::note_constexpr_non_const_vectorelements)
18795 case UETT_CountOf: {
18801 if (
const auto *CAT =
18811 const auto *VAT = Info.Ctx.getAsVariableArrayType(Ty);
18813 if (VAT->getElementType()->isArrayType()) {
18816 if (!VAT->getSizeExpr()) {
18821 std::optional<APSInt> Res =
18822 VAT->getSizeExpr()->getIntegerConstantExpr(Info.Ctx);
18827 static_cast<unsigned>(Info.Ctx.getTypeSize(Info.Ctx.getSizeType())),
18828 Res->getZExtValue()};
18840 llvm_unreachable(
"unknown expr/type trait");
18843bool IntExprEvaluator::VisitOffsetOfExpr(
const OffsetOfExpr *OOE) {
18844 Info.Ctx.recordOffsetOfEvaluation(OOE);
18850 for (
unsigned i = 0; i != n; ++i) {
18858 const ArrayType *AT = Info.Ctx.getAsArrayType(CurrentType);
18862 CharUnits ElementSize = Info.Ctx.getTypeSizeInChars(CurrentType);
18863 Result += IdxResult.getSExtValue() * ElementSize;
18868 FieldDecl *MemberDecl = ON.
getField();
18873 const ASTRecordLayout &RL = Info.Ctx.getASTRecordLayout(RD);
18875 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
18882 llvm_unreachable(
"dependent __builtin_offsetof");
18885 CXXBaseSpecifier *BaseSpec = ON.
getBase();
18894 const ASTRecordLayout &RL = Info.Ctx.getASTRecordLayout(RD);
18897 CurrentType = BaseSpec->
getType();
18911bool IntExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
18931 if (Info.checkingForUndefinedBehavior())
18932 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
18933 diag::warn_integer_constant_overflow)
18961bool IntExprEvaluator::VisitCastExpr(
const CastExpr *E) {
18963 QualType DestType = E->
getType();
18964 QualType SrcType = SubExpr->
getType();
18967 case CK_BaseToDerived:
18968 case CK_DerivedToBase:
18969 case CK_UncheckedDerivedToBase:
18972 case CK_ArrayToPointerDecay:
18973 case CK_FunctionToPointerDecay:
18974 case CK_NullToPointer:
18975 case CK_NullToMemberPointer:
18976 case CK_BaseToDerivedMemberPointer:
18977 case CK_DerivedToBaseMemberPointer:
18978 case CK_ReinterpretMemberPointer:
18979 case CK_ConstructorConversion:
18980 case CK_IntegralToPointer:
18982 case CK_VectorSplat:
18983 case CK_IntegralToFloating:
18984 case CK_FloatingCast:
18985 case CK_CPointerToObjCPointerCast:
18986 case CK_BlockPointerToObjCPointerCast:
18987 case CK_AnyPointerToBlockPointerCast:
18988 case CK_ObjCObjectLValueCast:
18989 case CK_FloatingRealToComplex:
18990 case CK_FloatingComplexToReal:
18991 case CK_FloatingComplexCast:
18992 case CK_FloatingComplexToIntegralComplex:
18993 case CK_IntegralRealToComplex:
18994 case CK_IntegralComplexCast:
18995 case CK_IntegralComplexToFloatingComplex:
18996 case CK_BuiltinFnToFnPtr:
18997 case CK_ZeroToOCLOpaqueType:
18998 case CK_NonAtomicToAtomic:
18999 case CK_AddressSpaceConversion:
19000 case CK_IntToOCLSampler:
19001 case CK_FloatingToFixedPoint:
19002 case CK_FixedPointToFloating:
19003 case CK_FixedPointCast:
19004 case CK_IntegralToFixedPoint:
19005 case CK_MatrixCast:
19006 case CK_HLSLAggregateSplatCast:
19007 llvm_unreachable(
"invalid cast kind for integral value");
19011 case CK_LValueBitCast:
19012 case CK_ARCProduceObject:
19013 case CK_ARCConsumeObject:
19014 case CK_ARCReclaimReturnedObject:
19015 case CK_ARCExtendBlockObject:
19016 case CK_CopyAndAutoreleaseBlockObject:
19019 case CK_UserDefinedConversion:
19020 case CK_LValueToRValue:
19021 case CK_AtomicToNonAtomic:
19023 case CK_LValueToRValueBitCast:
19024 case CK_HLSLArrayRValue:
19025 return ExprEvaluatorBaseTy::VisitCastExpr(E);
19027 case CK_MemberPointerToBoolean:
19028 case CK_PointerToBoolean:
19029 case CK_IntegralToBoolean:
19030 case CK_FloatingToBoolean:
19031 case CK_BooleanToSignedIntegral:
19032 case CK_FloatingComplexToBoolean:
19033 case CK_IntegralComplexToBoolean: {
19038 if (BoolResult && E->
getCastKind() == CK_BooleanToSignedIntegral)
19040 return Success(IntResult, E);
19043 case CK_FixedPointToIntegral: {
19044 APFixedPoint Src(Info.Ctx.getFixedPointSemantics(SrcType));
19048 llvm::APSInt
Result = Src.convertToInt(
19049 Info.Ctx.getIntWidth(DestType),
19056 case CK_FixedPointToBoolean: {
19059 if (!
Evaluate(Val, Info, SubExpr))
19064 case CK_IntegralCast: {
19065 if (!Visit(SubExpr))
19075 if (
Result.isAddrLabelDiff()) {
19076 unsigned DestBits = Info.Ctx.getTypeSize(DestType);
19077 return DestBits >= 32 && DestBits <= Info.Ctx.getTypeSize(SrcType);
19080 return Info.Ctx.getTypeSize(DestType) == Info.Ctx.getTypeSize(SrcType);
19083 if (Info.Ctx.getLangOpts().CPlusPlus && DestType->
isEnumeralType()) {
19095 if (!ED->isFixed()) {
19099 ED->getValueRange(
Max,
Min);
19102 if (ED->getNumNegativeBits() &&
19103 (
Max.slt(
Result.getInt().getSExtValue()) ||
19104 Min.sgt(
Result.getInt().getSExtValue())))
19105 Info.CCEDiag(E, diag::note_constexpr_unscoped_enum_out_of_range)
19106 << llvm::toString(
Result.getInt(), 10) <<
Min.getSExtValue()
19107 <<
Max.getSExtValue() << ED;
19108 else if (!ED->getNumNegativeBits() &&
19109 Max.ult(
Result.getInt().getZExtValue()))
19110 Info.CCEDiag(E, diag::note_constexpr_unscoped_enum_out_of_range)
19111 << llvm::toString(
Result.getInt(), 10) <<
Min.getZExtValue()
19112 <<
Max.getZExtValue() << ED;
19120 case CK_PointerToIntegral: {
19121 CCEDiag(E, diag::note_constexpr_invalid_cast)
19122 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
19129 if (LV.getLValueBase()) {
19134 if (Info.Ctx.getTypeSize(DestType) != Info.Ctx.getTypeSize(SrcType))
19137 LV.Designator.setInvalid();
19145 if (!
V.toIntegralConstant(AsInt, SrcType, Info.Ctx))
19146 llvm_unreachable(
"Can't cast this!");
19151 case CK_IntegralComplexToReal: {
19155 return Success(
C.getComplexIntReal(), E);
19158 case CK_FloatingToIntegral: {
19168 case CK_HLSLVectorTruncation: {
19174 case CK_HLSLMatrixTruncation: {
19180 case CK_HLSLElementwiseCast: {
19193 return Success(ResultVal, E);
19197 llvm_unreachable(
"unknown cast resulting in integral value");
19200bool IntExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
19205 if (!LV.isComplexInt())
19207 return Success(LV.getComplexIntReal(), E);
19213bool IntExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
19218 if (!LV.isComplexInt())
19220 return Success(LV.getComplexIntImag(), E);
19227bool IntExprEvaluator::VisitSizeOfPackExpr(
const SizeOfPackExpr *E) {
19231bool IntExprEvaluator::VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E) {
19235bool IntExprEvaluator::VisitConceptSpecializationExpr(
19236 const ConceptSpecializationExpr *E) {
19240bool IntExprEvaluator::VisitRequiresExpr(
const RequiresExpr *E) {
19244bool FixedPointExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
19254 if (!
Result.isFixedPoint())
19257 APFixedPoint Negated =
Result.getFixedPoint().negate(&Overflowed);
19271bool FixedPointExprEvaluator::VisitCastExpr(
const CastExpr *E) {
19273 QualType DestType = E->
getType();
19275 "Expected destination type to be a fixed point type");
19276 auto DestFXSema = Info.Ctx.getFixedPointSemantics(DestType);
19279 case CK_FixedPointCast: {
19280 APFixedPoint Src(Info.Ctx.getFixedPointSemantics(SubExpr->
getType()));
19284 APFixedPoint
Result = Src.convert(DestFXSema, &Overflowed);
19286 if (Info.checkingForUndefinedBehavior())
19287 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
19288 diag::warn_fixedpoint_constant_overflow)
19295 case CK_IntegralToFixedPoint: {
19301 APFixedPoint IntResult = APFixedPoint::getFromIntValue(
19302 Src, Info.Ctx.getFixedPointSemantics(DestType), &Overflowed);
19305 if (Info.checkingForUndefinedBehavior())
19306 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
19307 diag::warn_fixedpoint_constant_overflow)
19308 << IntResult.toString() << E->
getType();
19313 return Success(IntResult, E);
19315 case CK_FloatingToFixedPoint: {
19321 APFixedPoint
Result = APFixedPoint::getFromFloatValue(
19322 Src, Info.Ctx.getFixedPointSemantics(DestType), &Overflowed);
19325 if (Info.checkingForUndefinedBehavior())
19326 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
19327 diag::warn_fixedpoint_constant_overflow)
19336 case CK_LValueToRValue:
19337 return ExprEvaluatorBaseTy::VisitCastExpr(E);
19343bool FixedPointExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
19345 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
19347 const Expr *LHS = E->
getLHS();
19348 const Expr *RHS = E->
getRHS();
19350 Info.Ctx.getFixedPointSemantics(E->
getType());
19352 APFixedPoint LHSFX(Info.Ctx.getFixedPointSemantics(LHS->
getType()));
19355 APFixedPoint RHSFX(Info.Ctx.getFixedPointSemantics(RHS->
getType()));
19359 bool OpOverflow =
false, ConversionOverflow =
false;
19360 APFixedPoint
Result(LHSFX.getSemantics());
19363 Result = LHSFX.add(RHSFX, &OpOverflow)
19364 .convert(ResultFXSema, &ConversionOverflow);
19368 Result = LHSFX.sub(RHSFX, &OpOverflow)
19369 .convert(ResultFXSema, &ConversionOverflow);
19373 Result = LHSFX.mul(RHSFX, &OpOverflow)
19374 .convert(ResultFXSema, &ConversionOverflow);
19378 if (RHSFX.getValue() == 0) {
19379 Info.FFDiag(E, diag::note_expr_divide_by_zero);
19382 Result = LHSFX.div(RHSFX, &OpOverflow)
19383 .convert(ResultFXSema, &ConversionOverflow);
19389 llvm::APSInt RHSVal = RHSFX.getValue();
19392 LHSSema.getWidth() - (unsigned)LHSSema.hasUnsignedPadding();
19393 unsigned Amt = RHSVal.getLimitedValue(ShiftBW - 1);
19397 if (RHSVal.isNegative())
19398 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHSVal;
19399 else if (Amt != RHSVal)
19400 Info.CCEDiag(E, diag::note_constexpr_large_shift)
19401 << RHSVal << E->
getType() << ShiftBW;
19404 Result = LHSFX.shl(Amt, &OpOverflow);
19406 Result = LHSFX.shr(Amt, &OpOverflow);
19412 if (OpOverflow || ConversionOverflow) {
19413 if (Info.checkingForUndefinedBehavior())
19414 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
19415 diag::warn_fixedpoint_constant_overflow)
19428class FloatExprEvaluator
19429 :
public ExprEvaluatorBase<FloatExprEvaluator> {
19432 FloatExprEvaluator(EvalInfo &info, APFloat &result)
19433 : ExprEvaluatorBaseTy(info),
Result(result) {}
19440 bool ZeroInitialization(
const Expr *E) {
19441 Result = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(E->
getType()));
19445 bool VisitCallExpr(
const CallExpr *E);
19447 bool VisitUnaryOperator(
const UnaryOperator *E);
19448 bool VisitBinaryOperator(
const BinaryOperator *E);
19449 bool VisitFloatingLiteral(
const FloatingLiteral *E);
19450 bool VisitCastExpr(
const CastExpr *E);
19452 bool VisitUnaryReal(
const UnaryOperator *E);
19453 bool VisitUnaryImag(
const UnaryOperator *E);
19462 return FloatExprEvaluator(Info, Result).Visit(E);
19469 llvm::APFloat &Result) {
19471 if (!S)
return false;
19473 const llvm::fltSemantics &Sem = Context.getFloatTypeSemantics(ResultTy);
19479 fill = llvm::APInt(32, 0);
19480 else if (S->
getString().getAsInteger(0, fill))
19483 if (Context.getTargetInfo().isNan2008()) {
19485 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
19487 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
19495 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
19497 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
19503bool FloatExprEvaluator::VisitCallExpr(
const CallExpr *E) {
19504 if (!IsConstantEvaluatedBuiltinCall(E))
19505 return ExprEvaluatorBaseTy::VisitCallExpr(E);
19511 case Builtin::BI__builtin_huge_val:
19512 case Builtin::BI__builtin_huge_valf:
19513 case Builtin::BI__builtin_huge_vall:
19514 case Builtin::BI__builtin_huge_valf16:
19515 case Builtin::BI__builtin_huge_valf128:
19516 case Builtin::BI__builtin_inf:
19517 case Builtin::BI__builtin_inff:
19518 case Builtin::BI__builtin_infl:
19519 case Builtin::BI__builtin_inff16:
19520 case Builtin::BI__builtin_inff128: {
19521 const llvm::fltSemantics &Sem =
19522 Info.Ctx.getFloatTypeSemantics(E->
getType());
19523 Result = llvm::APFloat::getInf(Sem);
19527 case Builtin::BI__builtin_nans:
19528 case Builtin::BI__builtin_nansf:
19529 case Builtin::BI__builtin_nansl:
19530 case Builtin::BI__builtin_nansf16:
19531 case Builtin::BI__builtin_nansf128:
19537 case Builtin::BI__builtin_nan:
19538 case Builtin::BI__builtin_nanf:
19539 case Builtin::BI__builtin_nanl:
19540 case Builtin::BI__builtin_nanf16:
19541 case Builtin::BI__builtin_nanf128:
19549 case Builtin::BI__builtin_elementwise_abs:
19550 case Builtin::BI__builtin_fabs:
19551 case Builtin::BI__builtin_fabsf:
19552 case Builtin::BI__builtin_fabsl:
19553 case Builtin::BI__builtin_fabsf128:
19562 if (
Result.isNegative())
19566 case Builtin::BI__arithmetic_fence:
19573 case Builtin::BI__builtin_copysign:
19574 case Builtin::BI__builtin_copysignf:
19575 case Builtin::BI__builtin_copysignl:
19576 case Builtin::BI__builtin_copysignf128: {
19585 case Builtin::BI__builtin_fmax:
19586 case Builtin::BI__builtin_fmaxf:
19587 case Builtin::BI__builtin_fmaxl:
19588 case Builtin::BI__builtin_fmaxf16:
19589 case Builtin::BI__builtin_fmaxf128: {
19598 case Builtin::BI__builtin_fmin:
19599 case Builtin::BI__builtin_fminf:
19600 case Builtin::BI__builtin_fminl:
19601 case Builtin::BI__builtin_fminf16:
19602 case Builtin::BI__builtin_fminf128: {
19611 case Builtin::BI__builtin_fmaximum_num:
19612 case Builtin::BI__builtin_fmaximum_numf:
19613 case Builtin::BI__builtin_fmaximum_numl:
19614 case Builtin::BI__builtin_fmaximum_numf16:
19615 case Builtin::BI__builtin_fmaximum_numf128: {
19624 case Builtin::BI__builtin_fminimum_num:
19625 case Builtin::BI__builtin_fminimum_numf:
19626 case Builtin::BI__builtin_fminimum_numl:
19627 case Builtin::BI__builtin_fminimum_numf16:
19628 case Builtin::BI__builtin_fminimum_numf128: {
19637 case Builtin::BI__builtin_elementwise_fma: {
19642 APFloat SourceY(0.), SourceZ(0.);
19648 (void)
Result.fusedMultiplyAdd(SourceY, SourceZ, RM);
19652 case clang::X86::BI__builtin_ia32_vec_ext_v4sf: {
19659 unsigned Idx =
static_cast<unsigned>(IdxAPS.getZExtValue() & (N - 1));
19665bool FloatExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
19677bool FloatExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
19687 const llvm::fltSemantics &Sem = Info.Ctx.getFloatTypeSemantics(E->
getType());
19688 Result = llvm::APFloat::getZero(Sem);
19692bool FloatExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
19694 default:
return Error(E);
19708bool FloatExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
19710 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
19714 if (!LHSOK && !Info.noteFailure())
19720bool FloatExprEvaluator::VisitFloatingLiteral(
const FloatingLiteral *E) {
19725bool FloatExprEvaluator::VisitCastExpr(
const CastExpr *E) {
19730 return ExprEvaluatorBaseTy::VisitCastExpr(E);
19732 case CK_HLSLAggregateSplatCast:
19733 llvm_unreachable(
"invalid cast kind for floating value");
19735 case CK_IntegralToFloating: {
19738 Info.Ctx.getLangOpts());
19744 case CK_FixedPointToFloating: {
19745 APFixedPoint FixResult(Info.Ctx.getFixedPointSemantics(SubExpr->
getType()));
19749 FixResult.convertToFloat(Info.Ctx.getFloatTypeSemantics(E->
getType()));
19753 case CK_FloatingCast: {
19754 if (!Visit(SubExpr))
19760 case CK_FloatingComplexToReal: {
19764 Result =
V.getComplexFloatReal();
19767 case CK_HLSLVectorTruncation: {
19773 case CK_HLSLMatrixTruncation: {
19779 case CK_HLSLElementwiseCast: {
19794 return Success(ResultVal, E);
19804class ComplexExprEvaluator
19805 :
public ExprEvaluatorBase<ComplexExprEvaluator> {
19809 ComplexExprEvaluator(EvalInfo &info, ComplexValue &
Result)
19817 bool ZeroInitialization(
const Expr *E);
19823 bool VisitImaginaryLiteral(
const ImaginaryLiteral *E);
19824 bool VisitCastExpr(
const CastExpr *E);
19825 bool VisitBinaryOperator(
const BinaryOperator *E);
19826 bool VisitUnaryOperator(
const UnaryOperator *E);
19827 bool VisitInitListExpr(
const InitListExpr *E);
19828 bool VisitCallExpr(
const CallExpr *E);
19836 return ComplexExprEvaluator(Info, Result).Visit(E);
19839bool ComplexExprEvaluator::ZeroInitialization(
const Expr *E) {
19840 QualType ElemTy = E->
getType()->
castAs<ComplexType>()->getElementType();
19842 Result.makeComplexFloat();
19843 APFloat Zero = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(ElemTy));
19847 Result.makeComplexInt();
19848 APSInt Zero = Info.Ctx.MakeIntValue(0, ElemTy);
19855bool ComplexExprEvaluator::VisitImaginaryLiteral(
const ImaginaryLiteral *E) {
19859 Result.makeComplexFloat();
19868 "Unexpected imaginary literal.");
19870 Result.makeComplexInt();
19875 Result.IntReal =
APSInt(Imag.getBitWidth(), !Imag.isSigned());
19880bool ComplexExprEvaluator::VisitCastExpr(
const CastExpr *E) {
19884 case CK_BaseToDerived:
19885 case CK_DerivedToBase:
19886 case CK_UncheckedDerivedToBase:
19889 case CK_ArrayToPointerDecay:
19890 case CK_FunctionToPointerDecay:
19891 case CK_NullToPointer:
19892 case CK_NullToMemberPointer:
19893 case CK_BaseToDerivedMemberPointer:
19894 case CK_DerivedToBaseMemberPointer:
19895 case CK_MemberPointerToBoolean:
19896 case CK_ReinterpretMemberPointer:
19897 case CK_ConstructorConversion:
19898 case CK_IntegralToPointer:
19899 case CK_PointerToIntegral:
19900 case CK_PointerToBoolean:
19902 case CK_VectorSplat:
19903 case CK_IntegralCast:
19904 case CK_BooleanToSignedIntegral:
19905 case CK_IntegralToBoolean:
19906 case CK_IntegralToFloating:
19907 case CK_FloatingToIntegral:
19908 case CK_FloatingToBoolean:
19909 case CK_FloatingCast:
19910 case CK_CPointerToObjCPointerCast:
19911 case CK_BlockPointerToObjCPointerCast:
19912 case CK_AnyPointerToBlockPointerCast:
19913 case CK_ObjCObjectLValueCast:
19914 case CK_FloatingComplexToReal:
19915 case CK_FloatingComplexToBoolean:
19916 case CK_IntegralComplexToReal:
19917 case CK_IntegralComplexToBoolean:
19918 case CK_ARCProduceObject:
19919 case CK_ARCConsumeObject:
19920 case CK_ARCReclaimReturnedObject:
19921 case CK_ARCExtendBlockObject:
19922 case CK_CopyAndAutoreleaseBlockObject:
19923 case CK_BuiltinFnToFnPtr:
19924 case CK_ZeroToOCLOpaqueType:
19925 case CK_NonAtomicToAtomic:
19926 case CK_AddressSpaceConversion:
19927 case CK_IntToOCLSampler:
19928 case CK_FloatingToFixedPoint:
19929 case CK_FixedPointToFloating:
19930 case CK_FixedPointCast:
19931 case CK_FixedPointToBoolean:
19932 case CK_FixedPointToIntegral:
19933 case CK_IntegralToFixedPoint:
19934 case CK_MatrixCast:
19935 case CK_HLSLVectorTruncation:
19936 case CK_HLSLMatrixTruncation:
19937 case CK_HLSLElementwiseCast:
19938 case CK_HLSLAggregateSplatCast:
19939 llvm_unreachable(
"invalid cast kind for complex value");
19941 case CK_LValueToRValue:
19942 case CK_AtomicToNonAtomic:
19944 case CK_LValueToRValueBitCast:
19945 case CK_HLSLArrayRValue:
19946 return ExprEvaluatorBaseTy::VisitCastExpr(E);
19949 case CK_LValueBitCast:
19950 case CK_UserDefinedConversion:
19953 case CK_FloatingRealToComplex: {
19958 Result.makeComplexFloat();
19963 case CK_FloatingComplexCast: {
19967 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
19975 case CK_FloatingComplexToIntegralComplex: {
19979 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
19982 Result.makeComplexInt();
19989 case CK_IntegralRealToComplex: {
19994 Result.makeComplexInt();
19995 Result.IntImag =
APSInt(Real.getBitWidth(), !Real.isSigned());
19999 case CK_IntegralComplexCast: {
20003 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
20012 case CK_IntegralComplexToFloatingComplex: {
20017 Info.Ctx.getLangOpts());
20018 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
20021 Result.makeComplexFloat();
20023 To,
Result.FloatReal) &&
20029 llvm_unreachable(
"unknown cast resulting in complex value");
20034 const uint8_t GFInv[256] = {
20035 0x00, 0x01, 0x8d, 0xf6, 0xcb, 0x52, 0x7b, 0xd1, 0xe8, 0x4f, 0x29, 0xc0,
20036 0xb0, 0xe1, 0xe5, 0xc7, 0x74, 0xb4, 0xaa, 0x4b, 0x99, 0x2b, 0x60, 0x5f,
20037 0x58, 0x3f, 0xfd, 0xcc, 0xff, 0x40, 0xee, 0xb2, 0x3a, 0x6e, 0x5a, 0xf1,
20038 0x55, 0x4d, 0xa8, 0xc9, 0xc1, 0x0a, 0x98, 0x15, 0x30, 0x44, 0xa2, 0xc2,
20039 0x2c, 0x45, 0x92, 0x6c, 0xf3, 0x39, 0x66, 0x42, 0xf2, 0x35, 0x20, 0x6f,
20040 0x77, 0xbb, 0x59, 0x19, 0x1d, 0xfe, 0x37, 0x67, 0x2d, 0x31, 0xf5, 0x69,
20041 0xa7, 0x64, 0xab, 0x13, 0x54, 0x25, 0xe9, 0x09, 0xed, 0x5c, 0x05, 0xca,
20042 0x4c, 0x24, 0x87, 0xbf, 0x18, 0x3e, 0x22, 0xf0, 0x51, 0xec, 0x61, 0x17,
20043 0x16, 0x5e, 0xaf, 0xd3, 0x49, 0xa6, 0x36, 0x43, 0xf4, 0x47, 0x91, 0xdf,
20044 0x33, 0x93, 0x21, 0x3b, 0x79, 0xb7, 0x97, 0x85, 0x10, 0xb5, 0xba, 0x3c,
20045 0xb6, 0x70, 0xd0, 0x06, 0xa1, 0xfa, 0x81, 0x82, 0x83, 0x7e, 0x7f, 0x80,
20046 0x96, 0x73, 0xbe, 0x56, 0x9b, 0x9e, 0x95, 0xd9, 0xf7, 0x02, 0xb9, 0xa4,
20047 0xde, 0x6a, 0x32, 0x6d, 0xd8, 0x8a, 0x84, 0x72, 0x2a, 0x14, 0x9f, 0x88,
20048 0xf9, 0xdc, 0x89, 0x9a, 0xfb, 0x7c, 0x2e, 0xc3, 0x8f, 0xb8, 0x65, 0x48,
20049 0x26, 0xc8, 0x12, 0x4a, 0xce, 0xe7, 0xd2, 0x62, 0x0c, 0xe0, 0x1f, 0xef,
20050 0x11, 0x75, 0x78, 0x71, 0xa5, 0x8e, 0x76, 0x3d, 0xbd, 0xbc, 0x86, 0x57,
20051 0x0b, 0x28, 0x2f, 0xa3, 0xda, 0xd4, 0xe4, 0x0f, 0xa9, 0x27, 0x53, 0x04,
20052 0x1b, 0xfc, 0xac, 0xe6, 0x7a, 0x07, 0xae, 0x63, 0xc5, 0xdb, 0xe2, 0xea,
20053 0x94, 0x8b, 0xc4, 0xd5, 0x9d, 0xf8, 0x90, 0x6b, 0xb1, 0x0d, 0xd6, 0xeb,
20054 0xc6, 0x0e, 0xcf, 0xad, 0x08, 0x4e, 0xd7, 0xe3, 0x5d, 0x50, 0x1e, 0xb3,
20055 0x5b, 0x23, 0x38, 0x34, 0x68, 0x46, 0x03, 0x8c, 0xdd, 0x9c, 0x7d, 0xa0,
20056 0xcd, 0x1a, 0x41, 0x1c};
20058 return GFInv[Byte];
20063 unsigned NumBitsInByte = 8;
20065 uint8_t RetByte = 0;
20066 for (uint32_t BitIdx = 0; BitIdx != NumBitsInByte; ++BitIdx) {
20068 AQword.lshr((7 -
static_cast<int32_t
>(BitIdx)) * NumBitsInByte)
20075 Product = AByte & XByte;
20077 uint8_t Parity = 0;
20080 for (
unsigned PBitIdx = 0; PBitIdx != NumBitsInByte; ++PBitIdx) {
20081 Parity = Parity ^ ((Product >> PBitIdx) & 0x1);
20084 uint8_t Temp = Imm[BitIdx] ? 1 : 0;
20085 RetByte |= (Temp ^ Parity) << BitIdx;
20094 uint16_t TWord = 0;
20095 unsigned NumBitsInByte = 8;
20096 for (
unsigned BitIdx = 0; BitIdx != NumBitsInByte; ++BitIdx) {
20097 if ((BByte >> BitIdx) & 0x1) {
20098 TWord = TWord ^ (AByte << BitIdx);
20106 for (int32_t BitIdx = 14; BitIdx > 7; --BitIdx) {
20107 if ((TWord >> BitIdx) & 0x1) {
20108 TWord = TWord ^ (0x11B << (BitIdx - 8));
20111 return (TWord & 0xFF);
20115 APFloat &ResR, APFloat &ResI) {
20121 APFloat AC = A *
C;
20122 APFloat BD = B * D;
20123 APFloat AD = A * D;
20124 APFloat BC = B *
C;
20127 if (ResR.isNaN() && ResI.isNaN()) {
20128 bool Recalc =
false;
20129 if (A.isInfinity() || B.isInfinity()) {
20130 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
20132 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
20135 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
20137 D = APFloat::copySign(APFloat(D.getSemantics()), D);
20140 if (
C.isInfinity() || D.isInfinity()) {
20141 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
20143 D = APFloat::copySign(APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0),
20146 A = APFloat::copySign(APFloat(A.getSemantics()), A);
20148 B = APFloat::copySign(APFloat(B.getSemantics()), B);
20151 if (!Recalc && (AC.isInfinity() || BD.isInfinity() || AD.isInfinity() ||
20152 BC.isInfinity())) {
20154 A = APFloat::copySign(APFloat(A.getSemantics()), A);
20156 B = APFloat::copySign(APFloat(B.getSemantics()), B);
20158 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
20160 D = APFloat::copySign(APFloat(D.getSemantics()), D);
20164 ResR = APFloat::getInf(A.getSemantics()) * (A *
C - B * D);
20165 ResI = APFloat::getInf(A.getSemantics()) * (A * D + B *
C);
20171 APFloat &ResR, APFloat &ResI) {
20178 APFloat MaxCD = maxnum(
abs(
C),
abs(D));
20179 if (MaxCD.isFinite()) {
20180 DenomLogB =
ilogb(MaxCD);
20181 C =
scalbn(
C, -DenomLogB, APFloat::rmNearestTiesToEven);
20182 D =
scalbn(D, -DenomLogB, APFloat::rmNearestTiesToEven);
20184 APFloat Denom =
C *
C + D * D;
20186 scalbn((A *
C + B * D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
20188 scalbn((B *
C - A * D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
20189 if (ResR.isNaN() && ResI.isNaN()) {
20190 if (Denom.isPosZero() && (!A.isNaN() || !B.isNaN())) {
20191 ResR = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * A;
20192 ResI = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * B;
20193 }
else if ((A.isInfinity() || B.isInfinity()) &&
C.isFinite() &&
20195 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
20197 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
20199 ResR = APFloat::getInf(ResR.getSemantics()) * (A *
C + B * D);
20200 ResI = APFloat::getInf(ResI.getSemantics()) * (B *
C - A * D);
20201 }
else if (MaxCD.isInfinity() && A.isFinite() && B.isFinite()) {
20202 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
20204 D = APFloat::copySign(APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0),
20206 ResR = APFloat::getZero(ResR.getSemantics()) * (A *
C + B * D);
20207 ResI = APFloat::getZero(ResI.getSemantics()) * (B *
C - A * D);
20214 APSInt NormAmt = Amount;
20215 unsigned BitWidth =
Value.getBitWidth();
20216 unsigned AmtBitWidth = NormAmt.getBitWidth();
20217 if (BitWidth == 1) {
20219 NormAmt =
APSInt(APInt(AmtBitWidth, 0), NormAmt.isUnsigned());
20220 }
else if (BitWidth == 2) {
20225 APSInt(APInt(AmtBitWidth, NormAmt[0] ? 1 : 0), NormAmt.isUnsigned());
20228 if (AmtBitWidth > BitWidth) {
20229 Divisor = llvm::APInt(AmtBitWidth, BitWidth);
20231 Divisor = llvm::APInt(BitWidth, BitWidth);
20232 if (AmtBitWidth < BitWidth) {
20233 NormAmt = NormAmt.extend(BitWidth);
20238 if (NormAmt.isSigned()) {
20239 NormAmt =
APSInt(NormAmt.srem(Divisor),
false);
20240 if (NormAmt.isNegative()) {
20241 APSInt SignedDivisor(Divisor,
false);
20242 NormAmt += SignedDivisor;
20245 NormAmt =
APSInt(NormAmt.urem(Divisor),
true);
20252bool ComplexExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
20254 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
20258 bool LHSReal =
false, RHSReal =
false;
20266 Result.makeComplexFloat();
20270 LHSOK = Visit(E->
getLHS());
20272 if (!LHSOK && !Info.noteFailure())
20278 APFloat &Real = RHS.FloatReal;
20281 RHS.makeComplexFloat();
20282 RHS.FloatImag =
APFloat(Real.getSemantics());
20286 assert(!(LHSReal && RHSReal) &&
20287 "Cannot have both operands of a complex operation be real.");
20289 default:
return Error(E);
20291 if (
Result.isComplexFloat()) {
20292 Result.getComplexFloatReal().add(RHS.getComplexFloatReal(),
20293 APFloat::rmNearestTiesToEven);
20295 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
20297 Result.getComplexFloatImag().add(RHS.getComplexFloatImag(),
20298 APFloat::rmNearestTiesToEven);
20300 Result.getComplexIntReal() += RHS.getComplexIntReal();
20301 Result.getComplexIntImag() += RHS.getComplexIntImag();
20305 if (
Result.isComplexFloat()) {
20306 Result.getComplexFloatReal().subtract(RHS.getComplexFloatReal(),
20307 APFloat::rmNearestTiesToEven);
20309 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
20310 Result.getComplexFloatImag().changeSign();
20311 }
else if (!RHSReal) {
20312 Result.getComplexFloatImag().subtract(RHS.getComplexFloatImag(),
20313 APFloat::rmNearestTiesToEven);
20316 Result.getComplexIntReal() -= RHS.getComplexIntReal();
20317 Result.getComplexIntImag() -= RHS.getComplexIntImag();
20321 if (
Result.isComplexFloat()) {
20326 ComplexValue LHS =
Result;
20327 APFloat &A = LHS.getComplexFloatReal();
20328 APFloat &B = LHS.getComplexFloatImag();
20329 APFloat &
C = RHS.getComplexFloatReal();
20330 APFloat &D = RHS.getComplexFloatImag();
20334 assert(!RHSReal &&
"Cannot have two real operands for a complex op!");
20342 }
else if (RHSReal) {
20354 ComplexValue LHS =
Result;
20355 Result.getComplexIntReal() =
20356 (LHS.getComplexIntReal() * RHS.getComplexIntReal() -
20357 LHS.getComplexIntImag() * RHS.getComplexIntImag());
20358 Result.getComplexIntImag() =
20359 (LHS.getComplexIntReal() * RHS.getComplexIntImag() +
20360 LHS.getComplexIntImag() * RHS.getComplexIntReal());
20364 if (
Result.isComplexFloat()) {
20369 ComplexValue LHS =
Result;
20370 APFloat &A = LHS.getComplexFloatReal();
20371 APFloat &B = LHS.getComplexFloatImag();
20372 APFloat &
C = RHS.getComplexFloatReal();
20373 APFloat &D = RHS.getComplexFloatImag();
20387 B = APFloat::getZero(A.getSemantics());
20392 ComplexValue LHS =
Result;
20393 APSInt Den = RHS.getComplexIntReal() * RHS.getComplexIntReal() +
20394 RHS.getComplexIntImag() * RHS.getComplexIntImag();
20396 return Error(E, diag::note_expr_divide_by_zero);
20398 Result.getComplexIntReal() =
20399 (LHS.getComplexIntReal() * RHS.getComplexIntReal() +
20400 LHS.getComplexIntImag() * RHS.getComplexIntImag()) / Den;
20401 Result.getComplexIntImag() =
20402 (LHS.getComplexIntImag() * RHS.getComplexIntReal() -
20403 LHS.getComplexIntReal() * RHS.getComplexIntImag()) / Den;
20411bool ComplexExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
20425 if (
Result.isComplexFloat()) {
20426 Result.getComplexFloatReal().changeSign();
20427 Result.getComplexFloatImag().changeSign();
20430 Result.getComplexIntReal() = -
Result.getComplexIntReal();
20431 Result.getComplexIntImag() = -
Result.getComplexIntImag();
20435 if (
Result.isComplexFloat())
20436 Result.getComplexFloatImag().changeSign();
20438 Result.getComplexIntImag() = -
Result.getComplexIntImag();
20443bool ComplexExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
20446 Result.makeComplexFloat();
20452 Result.makeComplexInt();
20460 return ExprEvaluatorBaseTy::VisitInitListExpr(E);
20463bool ComplexExprEvaluator::VisitCallExpr(
const CallExpr *E) {
20464 if (!IsConstantEvaluatedBuiltinCall(E))
20465 return ExprEvaluatorBaseTy::VisitCallExpr(E);
20468 case Builtin::BI__builtin_complex:
20469 Result.makeComplexFloat();
20487class AtomicExprEvaluator :
20488 public ExprEvaluatorBase<AtomicExprEvaluator> {
20489 const LValue *
This;
20492 AtomicExprEvaluator(EvalInfo &Info,
const LValue *This,
APValue &
Result)
20500 bool ZeroInitialization(
const Expr *E) {
20501 ImplicitValueInitExpr VIE(
20509 bool VisitCastExpr(
const CastExpr *E) {
20512 return ExprEvaluatorBaseTy::VisitCastExpr(E);
20513 case CK_NullToPointer:
20515 return ZeroInitialization(E);
20516 case CK_NonAtomicToAtomic:
20528 return AtomicExprEvaluator(Info,
This, Result).Visit(E);
20537class VoidExprEvaluator
20538 :
public ExprEvaluatorBase<VoidExprEvaluator> {
20540 VoidExprEvaluator(EvalInfo &Info) : ExprEvaluatorBaseTy(Info) {}
20544 bool ZeroInitialization(
const Expr *E) {
return true; }
20546 bool VisitCastExpr(
const CastExpr *E) {
20549 return ExprEvaluatorBaseTy::VisitCastExpr(E);
20556 bool VisitCallExpr(
const CallExpr *E) {
20557 if (!IsConstantEvaluatedBuiltinCall(E))
20558 return ExprEvaluatorBaseTy::VisitCallExpr(E);
20561 case Builtin::BI__assume:
20562 case Builtin::BI__builtin_assume:
20566 case Builtin::BI__builtin_operator_delete:
20574 bool VisitCXXDeleteExpr(
const CXXDeleteExpr *E);
20578bool VoidExprEvaluator::VisitCXXDeleteExpr(
const CXXDeleteExpr *E) {
20580 if (Info.SpeculativeEvaluationDepth)
20584 if (!OperatorDelete
20585 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
20586 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
20596 if (
Pointer.Designator.Invalid)
20600 if (
Pointer.isNullPointer()) {
20604 if (!Info.getLangOpts().CPlusPlus20)
20605 Info.CCEDiag(E, diag::note_constexpr_new);
20613 QualType AllocType =
Pointer.Base.getDynamicAllocType();
20619 Info.FFDiag(E, diag::note_constexpr_delete_base_nonvirt_dtor)
20628 if (VirtualDelete &&
20630 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
20631 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
20638 (*Alloc)->Value, AllocType))
20641 if (!Info.HeapAllocs.erase(
Pointer.Base.dyn_cast<DynamicAllocLValue>())) {
20646 Info.FFDiag(E, diag::note_constexpr_double_delete);
20656 return VoidExprEvaluator(Info).Visit(E);
20668 if (E->
isGLValue() || T->isFunctionType()) {
20672 LV.moveInto(Result);
20673 }
else if (T->isVectorType()) {
20676 }
else if (T->isConstantMatrixType()) {
20679 }
else if (T->isIntegralOrEnumerationType()) {
20680 if (!IntExprEvaluator(Info, Result).Visit(E))
20682 }
else if (T->hasPointerRepresentation()) {
20686 LV.moveInto(Result);
20687 }
else if (T->isRealFloatingType()) {
20688 llvm::APFloat F(0.0);
20692 }
else if (T->isAnyComplexType()) {
20696 C.moveInto(Result);
20697 }
else if (T->isFixedPointType()) {
20698 if (!FixedPointExprEvaluator(Info, Result).Visit(E))
return false;
20699 }
else if (T->isMemberPointerType()) {
20703 P.moveInto(Result);
20705 }
else if (T->isArrayType()) {
20708 Info.CurrentCall->createTemporary(E, T, ScopeKind::FullExpression, LV);
20712 }
else if (T->isRecordType()) {
20715 Info.CurrentCall->createTemporary(E, T, ScopeKind::FullExpression, LV);
20719 }
else if (T->isVoidType()) {
20720 if (!Info.getLangOpts().CPlusPlus11)
20721 Info.CCEDiag(E, diag::note_constexpr_nonliteral)
20725 }
else if (T->isAtomicType()) {
20730 E, Unqual, ScopeKind::FullExpression, LV);
20738 }
else if (Info.getLangOpts().CPlusPlus11) {
20739 Info.FFDiag(E, diag::note_constexpr_nonliteral) << E->
getType();
20742 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
20753 const Expr *E,
bool AllowNonLiteralTypes) {
20769 if (T->isArrayType())
20771 else if (T->isRecordType())
20773 else if (T->isAtomicType()) {
20795 if (Info.EnableNewConstInterp) {
20796 if (!Info.Ctx.getInterpContext().evaluateAsRValue(Info, E, Result))
20799 ConstantExprKind::Normal);
20808 LV.setFrom(Info.Ctx, Result);
20815 ConstantExprKind::Normal) &&
20823 if (
const auto *L = dyn_cast<IntegerLiteral>(Exp)) {
20825 APValue(
APSInt(L->getValue(), L->getType()->isUnsignedIntegerType()));
20830 if (
const auto *L = dyn_cast<CXXBoolLiteralExpr>(Exp)) {
20836 if (
const auto *FL = dyn_cast<FloatingLiteral>(Exp)) {
20837 Result =
APValue(FL->getValue());
20842 if (
const auto *L = dyn_cast<CharacterLiteral>(Exp)) {
20848 if (
const auto *CE = dyn_cast<ConstantExpr>(Exp)) {
20849 if (CE->hasAPValueResult()) {
20850 APValue APV = CE->getAPValueResult();
20852 Result = std::move(APV);
20928 bool InConstantContext)
const {
20930 "Expression evaluator can't be called on a dependent expression.");
20931 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsRValue");
20933 Info.InConstantContext = InConstantContext;
20934 return ::EvaluateAsRValue(
this,
Result, Ctx, Info);
20938 bool InConstantContext)
const {
20940 "Expression evaluator can't be called on a dependent expression.");
20941 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsBooleanCondition");
20949 bool InConstantContext)
const {
20951 "Expression evaluator can't be called on a dependent expression.");
20952 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsInt");
20954 Info.InConstantContext = InConstantContext;
20955 return ::EvaluateAsInt(
this,
Result, Ctx, AllowSideEffects, Info);
20960 bool InConstantContext)
const {
20962 "Expression evaluator can't be called on a dependent expression.");
20963 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFixedPoint");
20965 Info.InConstantContext = InConstantContext;
20966 return ::EvaluateAsFixedPoint(
this,
Result, Ctx, AllowSideEffects, Info);
20971 bool InConstantContext)
const {
20973 "Expression evaluator can't be called on a dependent expression.");
20975 if (!
getType()->isRealFloatingType())
20978 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFloat");
20990 bool InConstantContext)
const {
20992 "Expression evaluator can't be called on a dependent expression.");
20994 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsLValue");
20996 Info.InConstantContext = InConstantContext;
21000 if (Info.EnableNewConstInterp) {
21001 if (!Info.Ctx.getInterpContext().evaluate(Info,
this,
Result.Val,
21002 ConstantExprKind::Normal))
21005 LV.setFrom(Ctx,
Result.Val);
21008 ConstantExprKind::Normal, CheckedTemps);
21011 if (!
EvaluateLValue(
this, LV, Info) || !Info.discardCleanups() ||
21012 Result.HasSideEffects ||
21015 ConstantExprKind::Normal, CheckedTemps))
21018 LV.moveInto(
Result.Val);
21025 bool IsConstantDestruction) {
21026 EvalInfo Info(Ctx, EStatus,
21029 Info.setEvaluatingDecl(
Base, DestroyedValue,
21030 EvalInfo::EvaluatingDeclKind::Dtor);
21031 Info.InConstantContext = IsConstantDestruction;
21040 if (!Info.discardCleanups())
21041 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
21049 "Expression evaluator can't be called on a dependent expression.");
21055 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsConstantExpr");
21057 EvalInfo Info(Ctx,
Result, EM);
21058 Info.InConstantContext =
true;
21060 if (Info.EnableNewConstInterp) {
21061 if (!Info.Ctx.getInterpContext().evaluate(Info,
this,
Result.Val, Kind))
21064 getStorageType(Ctx,
this),
Result.Val, Kind);
21069 if (Kind == ConstantExprKind::ClassTemplateArgument)
21085 FullExpressionRAII
Scope(Info);
21090 if (!Info.discardCleanups())
21091 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
21101 if (Kind == ConstantExprKind::ClassTemplateArgument &&
21104 Result.HasSideEffects)) {
21116 bool IsConstantInitialization)
const {
21118 "Expression evaluator can't be called on a dependent expression.");
21119 assert(VD &&
"Need a valid VarDecl");
21121 llvm::TimeTraceScope TimeScope(
"EvaluateAsInitializer", [&] {
21123 llvm::raw_string_ostream OS(Name);
21129 EStatus.
Diag = &Notes;
21131 EvalInfo Info(Ctx, EStatus,
21132 (IsConstantInitialization &&
21136 Info.setEvaluatingDecl(VD,
Value);
21137 Info.InConstantContext = IsConstantInitialization;
21142 if (Info.EnableNewConstInterp) {
21144 if (!InterpCtx.evaluateAsInitializer(Info, VD,
this,
Value))
21148 ConstantExprKind::Normal);
21163 FullExpressionRAII
Scope(Info);
21166 EStatus.HasSideEffects)
21172 Info.performLifetimeExtension();
21174 if (!Info.discardCleanups())
21175 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
21179 ConstantExprKind::Normal) &&
21186 EStatus.
Diag = &Notes;
21203 IsConstantDestruction) ||
21215 "Expression evaluator can't be called on a dependent expression.");
21224 "Expression evaluator can't be called on a dependent expression.");
21226 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstInt");
21229 Info.InConstantContext =
true;
21233 assert(
Result &&
"Could not evaluate expression");
21234 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
21236 return EVResult.Val.getInt();
21242 "Expression evaluator can't be called on a dependent expression.");
21244 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstIntCheckOverflow");
21246 EVResult.Diag =
Diag;
21248 Info.InConstantContext =
true;
21249 Info.CheckingForUndefinedBehavior =
true;
21253 assert(
Result &&
"Could not evaluate expression");
21254 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
21256 return EVResult.Val.getInt();
21261 "Expression evaluator can't be called on a dependent expression.");
21263 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateForOverflow");
21268 Info.CheckingForUndefinedBehavior =
true;
21274 assert(
Val.isLValue());
21300 IK_ICEIfUnevaluated,
21316static ICEDiag
Worst(ICEDiag A, ICEDiag B) {
return A.Kind >= B.Kind ? A : B; }
21323 Info.InConstantContext =
true;
21332 assert(!E->
isValueDependent() &&
"Should not see value dependent exprs!");
21337#define ABSTRACT_STMT(Node)
21338#define STMT(Node, Base) case Expr::Node##Class:
21339#define EXPR(Node, Base)
21340#include "clang/AST/StmtNodes.inc"
21341 case Expr::PredefinedExprClass:
21342 case Expr::FloatingLiteralClass:
21343 case Expr::ImaginaryLiteralClass:
21344 case Expr::StringLiteralClass:
21345 case Expr::ArraySubscriptExprClass:
21346 case Expr::MatrixSingleSubscriptExprClass:
21347 case Expr::MatrixSubscriptExprClass:
21348 case Expr::ArraySectionExprClass:
21349 case Expr::OMPArrayShapingExprClass:
21350 case Expr::OMPIteratorExprClass:
21351 case Expr::CompoundAssignOperatorClass:
21352 case Expr::CompoundLiteralExprClass:
21353 case Expr::ExtVectorElementExprClass:
21354 case Expr::MatrixElementExprClass:
21355 case Expr::DesignatedInitExprClass:
21356 case Expr::ArrayInitLoopExprClass:
21357 case Expr::ArrayInitIndexExprClass:
21358 case Expr::NoInitExprClass:
21359 case Expr::DesignatedInitUpdateExprClass:
21360 case Expr::ImplicitValueInitExprClass:
21361 case Expr::ParenListExprClass:
21362 case Expr::VAArgExprClass:
21363 case Expr::AddrLabelExprClass:
21364 case Expr::StmtExprClass:
21365 case Expr::CXXMemberCallExprClass:
21366 case Expr::CUDAKernelCallExprClass:
21367 case Expr::CXXAddrspaceCastExprClass:
21368 case Expr::CXXDynamicCastExprClass:
21369 case Expr::CXXTypeidExprClass:
21370 case Expr::CXXUuidofExprClass:
21371 case Expr::MSPropertyRefExprClass:
21372 case Expr::MSPropertySubscriptExprClass:
21373 case Expr::CXXNullPtrLiteralExprClass:
21374 case Expr::UserDefinedLiteralClass:
21375 case Expr::CXXThisExprClass:
21376 case Expr::CXXThrowExprClass:
21377 case Expr::CXXNewExprClass:
21378 case Expr::CXXDeleteExprClass:
21379 case Expr::CXXPseudoDestructorExprClass:
21380 case Expr::UnresolvedLookupExprClass:
21381 case Expr::RecoveryExprClass:
21382 case Expr::DependentScopeDeclRefExprClass:
21383 case Expr::CXXConstructExprClass:
21384 case Expr::CXXInheritedCtorInitExprClass:
21385 case Expr::CXXStdInitializerListExprClass:
21386 case Expr::CXXBindTemporaryExprClass:
21387 case Expr::ExprWithCleanupsClass:
21388 case Expr::CXXTemporaryObjectExprClass:
21389 case Expr::CXXUnresolvedConstructExprClass:
21390 case Expr::CXXDependentScopeMemberExprClass:
21391 case Expr::UnresolvedMemberExprClass:
21392 case Expr::ObjCStringLiteralClass:
21393 case Expr::ObjCBoxedExprClass:
21394 case Expr::ObjCArrayLiteralClass:
21395 case Expr::ObjCDictionaryLiteralClass:
21396 case Expr::ObjCEncodeExprClass:
21397 case Expr::ObjCMessageExprClass:
21398 case Expr::ObjCSelectorExprClass:
21399 case Expr::ObjCProtocolExprClass:
21400 case Expr::ObjCIvarRefExprClass:
21401 case Expr::ObjCPropertyRefExprClass:
21402 case Expr::ObjCSubscriptRefExprClass:
21403 case Expr::ObjCIsaExprClass:
21404 case Expr::ObjCAvailabilityCheckExprClass:
21405 case Expr::ShuffleVectorExprClass:
21406 case Expr::ConvertVectorExprClass:
21407 case Expr::BlockExprClass:
21409 case Expr::OpaqueValueExprClass:
21410 case Expr::PackExpansionExprClass:
21411 case Expr::SubstNonTypeTemplateParmPackExprClass:
21412 case Expr::FunctionParmPackExprClass:
21413 case Expr::AsTypeExprClass:
21414 case Expr::ObjCIndirectCopyRestoreExprClass:
21415 case Expr::MaterializeTemporaryExprClass:
21416 case Expr::PseudoObjectExprClass:
21417 case Expr::AtomicExprClass:
21418 case Expr::LambdaExprClass:
21419 case Expr::CXXFoldExprClass:
21420 case Expr::CoawaitExprClass:
21421 case Expr::DependentCoawaitExprClass:
21422 case Expr::CoyieldExprClass:
21423 case Expr::SYCLUniqueStableNameExprClass:
21424 case Expr::CXXParenListInitExprClass:
21425 case Expr::HLSLOutArgExprClass:
21428 case Expr::MemberExprClass: {
21431 while (
const auto *M = dyn_cast<MemberExpr>(ME)) {
21434 ME = M->getBase()->IgnoreParenImpCasts();
21436 const auto *DRE = dyn_cast<DeclRefExpr>(ME);
21438 if (
const auto *VD = dyn_cast<VarDecl>(DRE->getDecl());
21446 case Expr::InitListExprClass: {
21457 case Expr::SizeOfPackExprClass:
21458 case Expr::GNUNullExprClass:
21459 case Expr::SourceLocExprClass:
21460 case Expr::EmbedExprClass:
21461 case Expr::OpenACCAsteriskSizeExprClass:
21464 case Expr::PackIndexingExprClass:
21467 case Expr::SubstNonTypeTemplateParmExprClass:
21471 case Expr::ConstantExprClass:
21474 case Expr::ParenExprClass:
21476 case Expr::GenericSelectionExprClass:
21478 case Expr::IntegerLiteralClass:
21479 case Expr::FixedPointLiteralClass:
21480 case Expr::CharacterLiteralClass:
21481 case Expr::ObjCBoolLiteralExprClass:
21482 case Expr::CXXBoolLiteralExprClass:
21483 case Expr::CXXScalarValueInitExprClass:
21484 case Expr::TypeTraitExprClass:
21485 case Expr::ConceptSpecializationExprClass:
21486 case Expr::RequiresExprClass:
21487 case Expr::ArrayTypeTraitExprClass:
21488 case Expr::ExpressionTraitExprClass:
21489 case Expr::CXXNoexceptExprClass:
21490 case Expr::CXXReflectExprClass:
21492 case Expr::CallExprClass:
21493 case Expr::CXXOperatorCallExprClass: {
21502 case Expr::CXXRewrittenBinaryOperatorClass:
21505 case Expr::DeclRefExprClass: {
21519 const VarDecl *VD = dyn_cast<VarDecl>(D);
21526 case Expr::UnaryOperatorClass: {
21549 llvm_unreachable(
"invalid unary operator class");
21551 case Expr::OffsetOfExprClass: {
21560 case Expr::UnaryExprOrTypeTraitExprClass: {
21562 if ((Exp->
getKind() == UETT_SizeOf) &&
21565 if (Exp->
getKind() == UETT_CountOf) {
21572 if (VAT->getElementType()->isArrayType())
21584 case Expr::BinaryOperatorClass: {
21629 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE) {
21632 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
21633 if (REval.isSigned() && REval.isAllOnes()) {
21635 if (LEval.isMinSignedValue())
21636 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
21644 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE)
21645 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
21651 return Worst(LHSResult, RHSResult);
21657 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICEIfUnevaluated) {
21667 return Worst(LHSResult, RHSResult);
21670 llvm_unreachable(
"invalid binary operator kind");
21672 case Expr::ImplicitCastExprClass:
21673 case Expr::CStyleCastExprClass:
21674 case Expr::CXXFunctionalCastExprClass:
21675 case Expr::CXXStaticCastExprClass:
21676 case Expr::CXXReinterpretCastExprClass:
21677 case Expr::CXXConstCastExprClass:
21678 case Expr::ObjCBridgedCastExprClass: {
21685 APSInt IgnoredVal(DestWidth, !DestSigned);
21690 if (FL->getValue().convertToInteger(IgnoredVal,
21691 llvm::APFloat::rmTowardZero,
21692 &Ignored) & APFloat::opInvalidOp)
21698 case CK_LValueToRValue:
21699 case CK_AtomicToNonAtomic:
21700 case CK_NonAtomicToAtomic:
21702 case CK_IntegralToBoolean:
21703 case CK_IntegralCast:
21709 case Expr::BinaryConditionalOperatorClass: {
21712 if (CommonResult.Kind == IK_NotICE)
return CommonResult;
21714 if (FalseResult.Kind == IK_NotICE)
return FalseResult;
21715 if (CommonResult.Kind == IK_ICEIfUnevaluated)
return CommonResult;
21716 if (FalseResult.Kind == IK_ICEIfUnevaluated &&
21718 return FalseResult;
21720 case Expr::ConditionalOperatorClass: {
21728 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
21731 if (CondResult.Kind == IK_NotICE)
21737 if (TrueResult.Kind == IK_NotICE)
21739 if (FalseResult.Kind == IK_NotICE)
21740 return FalseResult;
21741 if (CondResult.Kind == IK_ICEIfUnevaluated)
21743 if (TrueResult.Kind == IK_ICE && FalseResult.Kind == IK_ICE)
21749 return FalseResult;
21752 case Expr::CXXDefaultArgExprClass:
21754 case Expr::CXXDefaultInitExprClass:
21756 case Expr::ChooseExprClass: {
21759 case Expr::BuiltinBitCastExprClass: {
21760 if (!checkBitCastConstexprEligibility(
nullptr, Ctx,
cast<CastExpr>(E)))
21766 llvm_unreachable(
"Invalid StmtClass!");
21772 llvm::APSInt *
Value) {
21780 if (!Result.isInt())
21789 "Expression evaluator can't be called on a dependent expression.");
21791 ExprTimeTraceScope TimeScope(
this, Ctx,
"isIntegerConstantExpr");
21797 if (D.Kind != IK_ICE)
21802std::optional<llvm::APSInt>
21806 return std::nullopt;
21813 return std::nullopt;
21817 return std::nullopt;
21826 Info.InConstantContext =
true;
21829 llvm_unreachable(
"ICE cannot be evaluated!");
21836 "Expression evaluator can't be called on a dependent expression.");
21838 return CheckICE(
this, Ctx).Kind == IK_ICE;
21843 "Expression evaluator can't be called on a dependent expression.");
21853 *
Result = std::move(Scratch);
21860 Status.Diag = &Diags;
21867 Info.discardCleanups() && !Status.HasSideEffects;
21869 return IsConstExpr && Diags.empty();
21877 "Expression evaluator can't be called on a dependent expression.");
21879 llvm::TimeTraceScope TimeScope(
"EvaluateWithSubstitution", [&] {
21881 llvm::raw_string_ostream OS(Name);
21889 Info.InConstantContext =
true;
21892 const LValue *ThisPtr =
nullptr;
21895 auto *MD = dyn_cast<CXXMethodDecl>(Callee);
21896 assert(MD &&
"Don't provide `this` for non-methods.");
21897 assert(MD->isImplicitObjectMemberFunction() &&
21898 "Don't provide `this` for methods without an implicit object.");
21900 if (!
This->isValueDependent() &&
21902 !Info.EvalStatus.HasSideEffects)
21903 ThisPtr = &ThisVal;
21907 Info.EvalStatus.HasSideEffects =
false;
21910 CallRef
Call = Info.CurrentCall->createCall(Callee);
21913 unsigned Idx = I - Args.begin();
21914 if (Idx >= Callee->getNumParams())
21916 const ParmVarDecl *PVD = Callee->getParamDecl(Idx);
21917 if ((*I)->isValueDependent() ||
21919 Info.EvalStatus.HasSideEffects) {
21921 if (
APValue *Slot = Info.getParamSlot(
Call, PVD))
21927 Info.EvalStatus.HasSideEffects =
false;
21932 Info.discardCleanups();
21933 Info.EvalStatus.HasSideEffects =
false;
21936 CallStackFrame Frame(Info, Callee->getLocation(), Callee, ThisPtr,
This,
21939 FullExpressionRAII
Scope(Info);
21941 !Info.EvalStatus.HasSideEffects;
21953 llvm::TimeTraceScope TimeScope(
"isPotentialConstantExpr", [&] {
21955 llvm::raw_string_ostream OS(Name);
21962 Status.
Diag = &Diags;
21966 Info.InConstantContext =
true;
21967 Info.CheckingPotentialConstantExpression =
true;
21970 if (Info.EnableNewConstInterp) {
21971 Info.Ctx.getInterpContext().isPotentialConstantExpr(Info, FD);
21972 return Diags.empty();
21983 This.set({&VIE, Info.CurrentCall->Index});
21991 Info.setEvaluatingDecl(
This.getLValueBase(), Scratch);
21997 &VIE, Args, CallRef(), FD->
getBody(), Info, Scratch,
22001 return Diags.empty();
22009 "Expression evaluator can't be called on a dependent expression.");
22012 Status.
Diag = &Diags;
22016 Info.InConstantContext =
true;
22017 Info.CheckingPotentialConstantExpression =
true;
22019 if (Info.EnableNewConstInterp) {
22020 Info.Ctx.getInterpContext().isPotentialConstantExprUnevaluated(Info, E, FD);
22021 return Diags.empty();
22026 nullptr, CallRef());
22030 return Diags.empty();
22034 unsigned Type)
const {
22035 if (!
getType()->isPointerType())
22036 return std::nullopt;
22040 if (Info.EnableNewConstInterp)
22041 return Info.Ctx.getInterpContext().tryEvaluateObjectSize(Info,
this,
Type);
22045static std::optional<uint64_t>
22047 std::string *StringResult) {
22049 return std::nullopt;
22054 return std::nullopt;
22059 if (
const StringLiteral *S = dyn_cast_or_null<StringLiteral>(
22060 String.getLValueBase().dyn_cast<
const Expr *>())) {
22063 if (Off >= 0 && (uint64_t)Off <= (uint64_t)Str.size() &&
22066 Info.Ctx.hasSameUnqualifiedType(CharTy, Info.Ctx.CharTy)) {
22067 Str = Str.substr(Off);
22069 StringRef::size_type Pos = Str.find(0);
22070 if (Pos != StringRef::npos)
22071 Str = Str.substr(0, Pos);
22074 *StringResult = Str;
22082 for (uint64_t Strlen = 0; ; ++Strlen) {
22086 return std::nullopt;
22089 else if (StringResult)
22090 StringResult->push_back(Char.
getInt().getExtValue());
22092 return std::nullopt;
22099 std::string StringResult;
22101 if (Info.EnableNewConstInterp) {
22102 if (!Info.Ctx.getInterpContext().evaluateString(Info,
this, StringResult))
22103 return std::nullopt;
22104 return StringResult;
22108 return StringResult;
22109 return std::nullopt;
22112template <
typename T>
22114 const Expr *SizeExpression,
22115 const Expr *PtrExpression,
22119 Info.InConstantContext =
true;
22121 if (Info.EnableNewConstInterp)
22122 return Info.Ctx.getInterpContext().evaluateCharRange(Info, SizeExpression,
22123 PtrExpression, Result);
22126 FullExpressionRAII
Scope(Info);
22131 uint64_t Size = SizeValue.getZExtValue();
22134 if constexpr (std::is_same_v<APValue, T>)
22137 if (Size < Result.max_size())
22138 Result.reserve(Size);
22144 for (uint64_t I = 0; I < Size; ++I) {
22150 if constexpr (std::is_same_v<APValue, T>) {
22151 Result.getArrayInitializedElt(I) = std::move(Char);
22155 assert(
C.getBitWidth() <= 8 &&
22156 "string element not representable in char");
22158 Result.push_back(
static_cast<char>(
C.getExtValue()));
22169 const Expr *SizeExpression,
22173 PtrExpression, Ctx, Status);
22177 const Expr *SizeExpression,
22181 PtrExpression, Ctx, Status);
22188 if (Info.EnableNewConstInterp)
22189 return Info.Ctx.getInterpContext().evaluateStrlen(Info,
this);
22194struct IsWithinLifetimeHandler {
22197 using result_type = std::optional<bool>;
22198 std::optional<bool> failed() {
return std::nullopt; }
22199 template <
typename T>
22200 std::optional<bool> found(T &Subobj,
QualType SubobjType) {
22205std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &IEE,
22206 const CallExpr *E) {
22207 EvalInfo &Info = IEE.Info;
22212 if (!Info.InConstantContext)
22213 return std::nullopt;
22215 const Expr *Arg = E->
getArg(0);
22217 return std::nullopt;
22220 return std::nullopt;
22222 if (Val.allowConstexprUnknown())
22226 bool CalledFromStd =
false;
22227 const auto *
Callee = Info.CurrentCall->getCallee();
22228 if (Callee &&
Callee->isInStdNamespace()) {
22229 const IdentifierInfo *Identifier =
Callee->getIdentifier();
22230 CalledFromStd = Identifier && Identifier->
isStr(
"is_within_lifetime");
22232 Info.CCEDiag(CalledFromStd ? Info.CurrentCall->getCallRange().getBegin()
22234 diag::err_invalid_is_within_lifetime)
22235 << (CalledFromStd ?
"std::is_within_lifetime"
22236 :
"__builtin_is_within_lifetime")
22238 return std::nullopt;
22248 if (Val.isNullPointer() || Val.getLValueBase().isNull())
22250 QualType T = Val.getLValueBase().getType();
22252 "Pointers to functions should have been typed as function pointers "
22253 "which would have been rejected earlier");
22256 if (Val.getLValueDesignator().isOnePastTheEnd())
22258 assert(Val.getLValueDesignator().isValidSubobject() &&
22259 "Unchecked case for valid subobject");
22263 CompleteObject CO =
22267 if (Info.EvaluatingDeclValue && CO.Value == Info.EvaluatingDeclValue)
22272 IsWithinLifetimeHandler handler{Info};
22273 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)
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 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
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()
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.
llvm::json::Object Object
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.
@ 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)