58#include "llvm/ADT/APFixedPoint.h"
59#include "llvm/ADT/Sequence.h"
60#include "llvm/ADT/SmallBitVector.h"
61#include "llvm/ADT/StringExtras.h"
62#include "llvm/Support/Casting.h"
63#include "llvm/Support/Debug.h"
64#include "llvm/Support/SaveAndRestore.h"
65#include "llvm/Support/SipHash.h"
66#include "llvm/Support/TimeProfiler.h"
67#include "llvm/Support/raw_ostream.h"
73#define DEBUG_TYPE "exprconstant"
76using llvm::APFixedPoint;
80using llvm::FixedPointSemantics;
87 using SourceLocExprScopeGuard =
122 static const CallExpr *tryUnwrapAllocSizeCall(
const Expr *E) {
130 if (
const auto *FE = dyn_cast<FullExpr>(E))
133 if (
const auto *Cast = dyn_cast<CastExpr>(E))
134 E = Cast->getSubExpr()->IgnoreParens();
136 if (
const auto *CE = dyn_cast<CallExpr>(E))
137 return CE->getCalleeAllocSizeAttr() ? CE :
nullptr;
144 const auto *E =
Base.dyn_cast<
const Expr *>();
145 return E && E->getType()->isPointerType() && tryUnwrapAllocSizeCall(E);
153 case ConstantExprKind::Normal:
154 case ConstantExprKind::ClassTemplateArgument:
155 case ConstantExprKind::ImmediateInvocation:
160 case ConstantExprKind::NonClassTemplateArgument:
163 llvm_unreachable(
"unknown ConstantExprKind");
168 case ConstantExprKind::Normal:
169 case ConstantExprKind::ImmediateInvocation:
172 case ConstantExprKind::ClassTemplateArgument:
173 case ConstantExprKind::NonClassTemplateArgument:
176 llvm_unreachable(
"unknown ConstantExprKind");
182 static const uint64_t AssumedSizeForUnsizedArray =
183 std::numeric_limits<uint64_t>::max() / 2;
193 bool &FirstEntryIsUnsizedArray) {
196 assert(!isBaseAnAllocSizeCall(
Base) &&
197 "Unsized arrays shouldn't appear here");
198 unsigned MostDerivedLength = 0;
203 for (
unsigned I = 0, N = Path.size(); I != N; ++I) {
207 MostDerivedLength = I + 1;
210 if (
auto *CAT = dyn_cast<ConstantArrayType>(AT)) {
211 ArraySize = CAT->getZExtSize();
213 assert(I == 0 &&
"unexpected unsized array designator");
214 FirstEntryIsUnsizedArray =
true;
215 ArraySize = AssumedSizeForUnsizedArray;
221 MostDerivedLength = I + 1;
224 Type = VT->getElementType();
225 ArraySize = VT->getNumElements();
226 MostDerivedLength = I + 1;
228 }
else if (
const FieldDecl *FD = getAsField(Path[I])) {
229 Type = FD->getType();
231 MostDerivedLength = I + 1;
239 return MostDerivedLength;
243 struct SubobjectDesignator {
247 LLVM_PREFERRED_TYPE(
bool)
251 LLVM_PREFERRED_TYPE(
bool)
252 unsigned IsOnePastTheEnd : 1;
255 LLVM_PREFERRED_TYPE(
bool)
256 unsigned FirstEntryIsAnUnsizedArray : 1;
259 LLVM_PREFERRED_TYPE(
bool)
260 unsigned MostDerivedIsArrayElement : 1;
264 unsigned MostDerivedPathLength : 28;
273 uint64_t MostDerivedArraySize;
282 SubobjectDesignator() :
Invalid(
true) {}
285 :
Invalid(
false), IsOnePastTheEnd(
false),
286 FirstEntryIsAnUnsizedArray(
false), MostDerivedIsArrayElement(
false),
287 MostDerivedPathLength(0), MostDerivedArraySize(0),
288 MostDerivedType(
T.isNull() ?
QualType() :
T.getNonReferenceType()) {}
291 :
Invalid(!
V.isLValue() || !
V.hasLValuePath()), IsOnePastTheEnd(
false),
292 FirstEntryIsAnUnsizedArray(
false), MostDerivedIsArrayElement(
false),
293 MostDerivedPathLength(0), MostDerivedArraySize(0) {
294 assert(
V.isLValue() &&
"Non-LValue used to make an LValue designator?");
296 IsOnePastTheEnd =
V.isLValueOnePastTheEnd();
297 llvm::append_range(Entries,
V.getLValuePath());
298 if (
V.getLValueBase()) {
299 bool IsArray =
false;
300 bool FirstIsUnsizedArray =
false;
301 MostDerivedPathLength = findMostDerivedSubobject(
302 Ctx,
V.getLValueBase(),
V.getLValuePath(), MostDerivedArraySize,
303 MostDerivedType, IsArray, FirstIsUnsizedArray);
304 MostDerivedIsArrayElement = IsArray;
305 FirstEntryIsAnUnsizedArray = FirstIsUnsizedArray;
311 unsigned NewLength) {
315 assert(
Base &&
"cannot truncate path for null pointer");
316 assert(NewLength <= Entries.size() &&
"not a truncation");
318 if (NewLength == Entries.size())
320 Entries.resize(NewLength);
322 bool IsArray =
false;
323 bool FirstIsUnsizedArray =
false;
324 MostDerivedPathLength = findMostDerivedSubobject(
325 Ctx,
Base, Entries, MostDerivedArraySize, MostDerivedType, IsArray,
326 FirstIsUnsizedArray);
327 MostDerivedIsArrayElement = IsArray;
328 FirstEntryIsAnUnsizedArray = FirstIsUnsizedArray;
338 bool isMostDerivedAnUnsizedArray()
const {
339 assert(!
Invalid &&
"Calling this makes no sense on invalid designators");
340 return Entries.size() == 1 && FirstEntryIsAnUnsizedArray;
345 uint64_t getMostDerivedArraySize()
const {
346 assert(!isMostDerivedAnUnsizedArray() &&
"Unsized array has no size");
347 return MostDerivedArraySize;
351 bool isOnePastTheEnd()
const {
355 if (!isMostDerivedAnUnsizedArray() && MostDerivedIsArrayElement &&
356 Entries[MostDerivedPathLength - 1].getAsArrayIndex() ==
357 MostDerivedArraySize)
365 std::pair<uint64_t, uint64_t> validIndexAdjustments() {
366 if (
Invalid || isMostDerivedAnUnsizedArray())
372 bool IsArray = MostDerivedPathLength == Entries.size() &&
373 MostDerivedIsArrayElement;
374 uint64_t ArrayIndex = IsArray ? Entries.back().getAsArrayIndex()
375 : (uint64_t)IsOnePastTheEnd;
377 IsArray ? getMostDerivedArraySize() : (uint64_t)1;
378 return {ArrayIndex, ArraySize - ArrayIndex};
382 bool isValidSubobject()
const {
385 return !isOnePastTheEnd();
393 assert(!
Invalid &&
"invalid designator has no subobject type");
394 return MostDerivedPathLength == Entries.size()
405 MostDerivedIsArrayElement =
true;
407 MostDerivedPathLength = Entries.size();
411 void addUnsizedArrayUnchecked(
QualType ElemTy) {
414 MostDerivedType = ElemTy;
415 MostDerivedIsArrayElement =
true;
419 MostDerivedArraySize = AssumedSizeForUnsizedArray;
420 MostDerivedPathLength = Entries.size();
424 void addDeclUnchecked(
const Decl *D,
bool Virtual =
false) {
428 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
429 MostDerivedType = FD->getType();
430 MostDerivedIsArrayElement =
false;
431 MostDerivedArraySize = 0;
432 MostDerivedPathLength = Entries.size();
436 void addComplexUnchecked(
QualType EltTy,
bool Imag) {
441 MostDerivedType = EltTy;
442 MostDerivedIsArrayElement =
true;
443 MostDerivedArraySize = 2;
444 MostDerivedPathLength = Entries.size();
447 void addVectorElementUnchecked(
QualType EltTy, uint64_t Size,
450 MostDerivedType = EltTy;
451 MostDerivedPathLength = Entries.size();
452 MostDerivedArraySize = 0;
453 MostDerivedIsArrayElement =
false;
456 void diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info,
const Expr *E);
457 void diagnosePointerArithmetic(EvalInfo &Info,
const Expr *E,
460 void adjustIndex(EvalInfo &Info,
const Expr *E,
APSInt N,
const LValue &LV);
464 enum class ScopeKind {
472 CallRef() : OrigCallee(), CallIndex(0), Version() {}
473 CallRef(
const FunctionDecl *Callee,
unsigned CallIndex,
unsigned Version)
474 : OrigCallee(Callee), CallIndex(CallIndex), Version(Version) {}
476 explicit operator bool()
const {
return OrigCallee; }
502 CallStackFrame *Caller;
524 typedef std::pair<const void *, unsigned> MapKeyTy;
525 typedef std::map<MapKeyTy, APValue>
MapTy;
537 unsigned CurTempVersion = TempVersionStack.back();
539 unsigned getTempVersion()
const {
return TempVersionStack.back(); }
541 void pushTempVersion() {
542 TempVersionStack.push_back(++CurTempVersion);
545 void popTempVersion() {
546 TempVersionStack.pop_back();
550 return {Callee, Index, ++CurTempVersion};
561 llvm::DenseMap<const ValueDecl *, FieldDecl *> LambdaCaptureFields;
562 FieldDecl *LambdaThisCaptureField =
nullptr;
564 CallStackFrame(EvalInfo &Info,
SourceRange CallRange,
570 APValue *getTemporary(
const void *Key,
unsigned Version) {
571 MapKeyTy KV(Key, Version);
572 auto LB = Temporaries.lower_bound(KV);
573 if (LB != Temporaries.end() && LB->first == KV)
579 APValue *getCurrentTemporary(
const void *Key) {
580 auto UB = Temporaries.upper_bound(MapKeyTy(Key,
UINT_MAX));
581 if (UB != Temporaries.begin() && std::prev(UB)->first.first == Key)
582 return &std::prev(UB)->second;
587 unsigned getCurrentTemporaryVersion(
const void *Key)
const {
588 auto UB = Temporaries.upper_bound(MapKeyTy(Key,
UINT_MAX));
589 if (UB != Temporaries.begin() && std::prev(UB)->first.first == Key)
590 return std::prev(UB)->first.second;
598 template<
typename KeyT>
600 ScopeKind
Scope, LValue &LV);
605 void describe(llvm::raw_ostream &OS)
const override;
607 Frame *getCaller()
const override {
return Caller; }
608 SourceRange getCallRange()
const override {
return CallRange; }
611 bool isStdFunction()
const {
612 for (
const DeclContext *DC = Callee; DC; DC = DC->getParent())
613 if (DC->isStdNamespace())
620 bool CanEvalMSConstexpr =
false;
628 class ThisOverrideRAII {
630 ThisOverrideRAII(CallStackFrame &Frame,
const LValue *NewThis,
bool Enable)
631 : Frame(Frame), OldThis(Frame.This) {
633 Frame.This = NewThis;
635 ~ThisOverrideRAII() {
636 Frame.This = OldThis;
639 CallStackFrame &Frame;
640 const LValue *OldThis;
645 class ExprTimeTraceScope {
647 ExprTimeTraceScope(
const Expr *E,
const ASTContext &Ctx, StringRef Name)
648 : TimeScope(Name, [E, &Ctx] {
653 llvm::TimeTraceScope TimeScope;
658 struct MSConstexprContextRAII {
659 CallStackFrame &Frame;
661 explicit MSConstexprContextRAII(CallStackFrame &Frame,
bool Value)
662 : Frame(Frame), OldValue(Frame.CanEvalMSConstexpr) {
663 Frame.CanEvalMSConstexpr =
Value;
666 ~MSConstexprContextRAII() { Frame.CanEvalMSConstexpr = OldValue; }
679 llvm::PointerIntPair<APValue*, 2, ScopeKind> Value;
680 APValue::LValueBase Base;
684 Cleanup(
APValue *Val, APValue::LValueBase Base, QualType T,
686 : Value(Val, Scope), Base(Base), T(T) {}
690 bool isDestroyedAtEndOf(ScopeKind K)
const {
691 return (
int)Value.getInt() >= (
int)K;
693 bool endLifetime(EvalInfo &Info,
bool RunDestructors) {
694 if (RunDestructors) {
696 if (
const ValueDecl *VD = Base.dyn_cast<
const ValueDecl*>())
697 Loc = VD->getLocation();
698 else if (
const Expr *E = Base.dyn_cast<
const Expr*>())
699 Loc = E->getExprLoc();
702 *Value.getPointer() =
APValue();
706 bool hasSideEffect() {
707 return T.isDestructedType();
712 struct ObjectUnderConstruction {
713 APValue::LValueBase Base;
714 ArrayRef<APValue::LValuePathEntry> Path;
715 friend bool operator==(
const ObjectUnderConstruction &LHS,
716 const ObjectUnderConstruction &RHS) {
717 return LHS.Base == RHS.Base && LHS.Path == RHS.Path;
719 friend llvm::hash_code
hash_value(
const ObjectUnderConstruction &Obj) {
720 return llvm::hash_combine(Obj.Base, Obj.Path);
723 enum class ConstructionPhase {
734template<>
struct DenseMapInfo<ObjectUnderConstruction> {
735 using Base = DenseMapInfo<APValue::LValueBase>;
737 return {Base::getEmptyKey(), {}}; }
739 return {Base::getTombstoneKey(), {}};
744 static bool isEqual(
const ObjectUnderConstruction &LHS,
745 const ObjectUnderConstruction &RHS) {
759 const Expr *AllocExpr =
nullptr;
770 if (
auto *NE = dyn_cast<CXXNewExpr>(AllocExpr))
771 return NE->isArray() ? ArrayNew : New;
777 struct DynAllocOrder {
778 bool operator()(DynamicAllocLValue L, DynamicAllocLValue R)
const {
802 Expr::EvalStatus &EvalStatus;
805 CallStackFrame *CurrentCall;
808 unsigned CallStackDepth;
811 unsigned NextCallIndex;
820 bool EnableNewConstInterp;
824 CallStackFrame BottomFrame;
828 llvm::SmallVector<Cleanup, 16> CleanupStack;
832 APValue::LValueBase EvaluatingDecl;
834 enum class EvaluatingDeclKind {
841 EvaluatingDeclKind IsEvaluatingDecl = EvaluatingDeclKind::None;
850 SmallVector<const Stmt *> BreakContinueStack;
853 llvm::DenseMap<ObjectUnderConstruction, ConstructionPhase>
854 ObjectsUnderConstruction;
859 std::map<DynamicAllocLValue, DynAlloc, DynAllocOrder> HeapAllocs;
862 unsigned NumHeapAllocs = 0;
864 struct EvaluatingConstructorRAII {
866 ObjectUnderConstruction Object;
868 EvaluatingConstructorRAII(EvalInfo &EI, ObjectUnderConstruction Object,
870 : EI(EI), Object(Object) {
872 EI.ObjectsUnderConstruction
873 .insert({Object, HasBases ? ConstructionPhase::Bases
874 : ConstructionPhase::AfterBases})
877 void finishedConstructingBases() {
878 EI.ObjectsUnderConstruction[Object] = ConstructionPhase::AfterBases;
880 void finishedConstructingFields() {
881 EI.ObjectsUnderConstruction[Object] = ConstructionPhase::AfterFields;
883 ~EvaluatingConstructorRAII() {
884 if (DidInsert) EI.ObjectsUnderConstruction.erase(Object);
888 struct EvaluatingDestructorRAII {
890 ObjectUnderConstruction Object;
892 EvaluatingDestructorRAII(EvalInfo &EI, ObjectUnderConstruction Object)
893 : EI(EI), Object(Object) {
894 DidInsert = EI.ObjectsUnderConstruction
895 .insert({Object, ConstructionPhase::Destroying})
898 void startedDestroyingBases() {
899 EI.ObjectsUnderConstruction[Object] =
900 ConstructionPhase::DestroyingBases;
902 ~EvaluatingDestructorRAII() {
904 EI.ObjectsUnderConstruction.erase(Object);
909 isEvaluatingCtorDtor(APValue::LValueBase Base,
910 ArrayRef<APValue::LValuePathEntry> Path) {
911 return ObjectsUnderConstruction.lookup({
Base, Path});
916 unsigned SpeculativeEvaluationDepth = 0;
924 bool HasActiveDiagnostic;
928 bool HasFoldFailureDiagnostic;
930 EvalInfo(
const ASTContext &
C, Expr::EvalStatus &S,
EvaluationMode Mode)
931 : Ctx(const_cast<ASTContext &>(
C)), EvalStatus(S), CurrentCall(
nullptr),
932 CallStackDepth(0), NextCallIndex(1),
933 StepsLeft(
C.getLangOpts().ConstexprStepLimit),
934 EnableNewConstInterp(
C.getLangOpts().EnableNewConstInterp),
935 BottomFrame(*this, SourceLocation(),
nullptr,
938 EvaluatingDecl((const ValueDecl *)
nullptr),
939 EvaluatingDeclValue(
nullptr), HasActiveDiagnostic(
false),
940 HasFoldFailureDiagnostic(
false) {
948 ASTContext &getASTContext()
const override {
return Ctx; }
949 const LangOptions &getLangOpts()
const {
return Ctx.getLangOpts(); }
951 void setEvaluatingDecl(APValue::LValueBase Base,
APValue &
Value,
952 EvaluatingDeclKind EDK = EvaluatingDeclKind::Ctor) {
953 EvaluatingDecl =
Base;
954 IsEvaluatingDecl = EDK;
955 EvaluatingDeclValue = &
Value;
958 bool CheckCallLimit(SourceLocation Loc) {
961 if (checkingPotentialConstantExpression() && CallStackDepth > 1)
963 if (NextCallIndex == 0) {
965 FFDiag(Loc, diag::note_constexpr_call_limit_exceeded);
968 if (CallStackDepth <= getLangOpts().ConstexprCallDepth)
970 FFDiag(Loc, diag::note_constexpr_depth_limit_exceeded)
971 << getLangOpts().ConstexprCallDepth;
976 uint64_t ElemCount,
bool Diag) {
982 ElemCount >
uint64_t(std::numeric_limits<unsigned>::max())) {
984 FFDiag(Loc, diag::note_constexpr_new_too_large) << ElemCount;
993 uint64_t Limit = Ctx.getLangOpts().ConstexprStepLimit;
994 if (Limit != 0 && ElemCount > Limit) {
996 FFDiag(Loc, diag::note_constexpr_new_exceeds_limits)
997 << ElemCount << Limit;
1003 std::pair<CallStackFrame *, unsigned>
1004 getCallFrameAndDepth(
unsigned CallIndex) {
1005 assert(CallIndex &&
"no call index in getCallFrameAndDepth");
1008 unsigned Depth = CallStackDepth;
1009 CallStackFrame *Frame = CurrentCall;
1010 while (Frame->Index > CallIndex) {
1011 Frame = Frame->Caller;
1014 if (Frame->Index == CallIndex)
1015 return {Frame, Depth};
1016 return {
nullptr, 0};
1019 bool nextStep(
const Stmt *S) {
1020 if (Ctx.getLangOpts().ConstexprStepLimit == 0)
1024 FFDiag(S->
getBeginLoc(), diag::note_constexpr_step_limit_exceeded);
1031 APValue *createHeapAlloc(
const Expr *E, QualType
T, LValue &LV);
1033 std::optional<DynAlloc *> lookupDynamicAlloc(DynamicAllocLValue DA) {
1034 std::optional<DynAlloc *>
Result;
1035 auto It = HeapAllocs.find(DA);
1036 if (It != HeapAllocs.end())
1042 APValue *getParamSlot(CallRef
Call,
const ParmVarDecl *PVD) {
1043 CallStackFrame *Frame = getCallFrameAndDepth(
Call.CallIndex).first;
1044 return Frame ? Frame->getTemporary(
Call.getOrigParam(PVD),
Call.Version)
1049 struct StdAllocatorCaller {
1050 unsigned FrameIndex;
1053 explicit operator bool()
const {
return FrameIndex != 0; };
1056 StdAllocatorCaller getStdAllocatorCaller(StringRef FnName)
const {
1057 for (
const CallStackFrame *
Call = CurrentCall;
Call != &BottomFrame;
1059 const auto *MD = dyn_cast_or_null<CXXMethodDecl>(
Call->Callee);
1062 const IdentifierInfo *FnII = MD->getIdentifier();
1063 if (!FnII || !FnII->
isStr(FnName))
1067 dyn_cast<ClassTemplateSpecializationDecl>(MD->getParent());
1071 const IdentifierInfo *ClassII = CTSD->getIdentifier();
1072 const TemplateArgumentList &TAL = CTSD->getTemplateArgs();
1073 if (CTSD->isInStdNamespace() && ClassII &&
1074 ClassII->
isStr(
"allocator") && TAL.
size() >= 1 &&
1076 return {
Call->Index, TAL[0].getAsType(),
Call->CallExpr};
1082 void performLifetimeExtension() {
1084 llvm::erase_if(CleanupStack, [](Cleanup &
C) {
1085 return !
C.isDestroyedAtEndOf(ScopeKind::FullExpression);
1092 bool discardCleanups() {
1093 for (Cleanup &
C : CleanupStack) {
1094 if (
C.hasSideEffect() && !noteSideEffect()) {
1095 CleanupStack.clear();
1099 CleanupStack.clear();
1104 interp::Frame *getCurrentFrame()
override {
return CurrentCall; }
1105 const interp::Frame *getBottomFrame()
const override {
return &BottomFrame; }
1107 bool hasActiveDiagnostic()
override {
return HasActiveDiagnostic; }
1108 void setActiveDiagnostic(
bool Flag)
override { HasActiveDiagnostic = Flag; }
1110 void setFoldFailureDiagnostic(
bool Flag)
override {
1111 HasFoldFailureDiagnostic = Flag;
1114 Expr::EvalStatus &getEvalStatus()
const override {
return EvalStatus; }
1122 bool hasPriorDiagnostic()
override {
1123 if (!EvalStatus.Diag->empty()) {
1125 case EvaluationMode::ConstantFold:
1126 case EvaluationMode::IgnoreSideEffects:
1127 if (!HasFoldFailureDiagnostic)
1131 case EvaluationMode::ConstantExpression:
1132 case EvaluationMode::ConstantExpressionUnevaluated:
1133 setActiveDiagnostic(
false);
1140 unsigned getCallStackDepth()
override {
return CallStackDepth; }
1145 bool keepEvaluatingAfterSideEffect()
const override {
1147 case EvaluationMode::IgnoreSideEffects:
1150 case EvaluationMode::ConstantExpression:
1151 case EvaluationMode::ConstantExpressionUnevaluated:
1152 case EvaluationMode::ConstantFold:
1155 return checkingPotentialConstantExpression() ||
1156 checkingForUndefinedBehavior();
1158 llvm_unreachable(
"Missed EvalMode case");
1163 bool noteSideEffect()
override {
1164 EvalStatus.HasSideEffects =
true;
1165 return keepEvaluatingAfterSideEffect();
1169 bool keepEvaluatingAfterUndefinedBehavior() {
1171 case EvaluationMode::IgnoreSideEffects:
1172 case EvaluationMode::ConstantFold:
1175 case EvaluationMode::ConstantExpression:
1176 case EvaluationMode::ConstantExpressionUnevaluated:
1177 return checkingForUndefinedBehavior();
1179 llvm_unreachable(
"Missed EvalMode case");
1185 bool noteUndefinedBehavior()
override {
1186 EvalStatus.HasUndefinedBehavior =
true;
1187 return keepEvaluatingAfterUndefinedBehavior();
1192 bool keepEvaluatingAfterFailure()
const override {
1193 uint64_t Limit = Ctx.getLangOpts().ConstexprStepLimit;
1194 if (Limit != 0 && !StepsLeft)
1198 case EvaluationMode::ConstantExpression:
1199 case EvaluationMode::ConstantExpressionUnevaluated:
1200 case EvaluationMode::ConstantFold:
1201 case EvaluationMode::IgnoreSideEffects:
1202 return checkingPotentialConstantExpression() ||
1203 checkingForUndefinedBehavior();
1205 llvm_unreachable(
"Missed EvalMode case");
1218 [[nodiscard]]
bool noteFailure() {
1226 bool KeepGoing = keepEvaluatingAfterFailure();
1227 EvalStatus.HasSideEffects |= KeepGoing;
1231 class ArrayInitLoopIndex {
1236 ArrayInitLoopIndex(EvalInfo &Info)
1237 : Info(Info), OuterIndex(Info.ArrayInitIndex) {
1238 Info.ArrayInitIndex = 0;
1240 ~ArrayInitLoopIndex() { Info.ArrayInitIndex = OuterIndex; }
1242 operator uint64_t&() {
return Info.ArrayInitIndex; }
1247 struct FoldConstant {
1250 bool HadNoPriorDiags;
1253 explicit FoldConstant(EvalInfo &Info,
bool Enabled)
1256 HadNoPriorDiags(Info.EvalStatus.
Diag &&
1257 Info.EvalStatus.
Diag->empty() &&
1258 !Info.EvalStatus.HasSideEffects),
1259 OldMode(Info.EvalMode) {
1261 Info.EvalMode = EvaluationMode::ConstantFold;
1263 void keepDiagnostics() { Enabled =
false; }
1265 if (Enabled && HadNoPriorDiags && !Info.EvalStatus.Diag->empty() &&
1266 !Info.EvalStatus.HasSideEffects)
1267 Info.EvalStatus.Diag->clear();
1268 Info.EvalMode = OldMode;
1274 struct IgnoreSideEffectsRAII {
1277 explicit IgnoreSideEffectsRAII(EvalInfo &Info)
1278 : Info(Info), OldMode(Info.EvalMode) {
1279 Info.EvalMode = EvaluationMode::IgnoreSideEffects;
1282 ~IgnoreSideEffectsRAII() { Info.EvalMode = OldMode; }
1287 class SpeculativeEvaluationRAII {
1288 EvalInfo *Info =
nullptr;
1289 Expr::EvalStatus OldStatus;
1290 unsigned OldSpeculativeEvaluationDepth = 0;
1292 void moveFromAndCancel(SpeculativeEvaluationRAII &&
Other) {
1294 OldStatus =
Other.OldStatus;
1295 OldSpeculativeEvaluationDepth =
Other.OldSpeculativeEvaluationDepth;
1296 Other.Info =
nullptr;
1299 void maybeRestoreState() {
1303 Info->EvalStatus = OldStatus;
1304 Info->SpeculativeEvaluationDepth = OldSpeculativeEvaluationDepth;
1308 SpeculativeEvaluationRAII() =
default;
1310 SpeculativeEvaluationRAII(
1311 EvalInfo &Info, SmallVectorImpl<PartialDiagnosticAt> *NewDiag =
nullptr)
1312 : Info(&Info), OldStatus(Info.EvalStatus),
1313 OldSpeculativeEvaluationDepth(Info.SpeculativeEvaluationDepth) {
1314 Info.EvalStatus.Diag = NewDiag;
1315 Info.SpeculativeEvaluationDepth = Info.CallStackDepth + 1;
1318 SpeculativeEvaluationRAII(
const SpeculativeEvaluationRAII &
Other) =
delete;
1319 SpeculativeEvaluationRAII(SpeculativeEvaluationRAII &&
Other) {
1320 moveFromAndCancel(std::move(
Other));
1323 SpeculativeEvaluationRAII &operator=(SpeculativeEvaluationRAII &&
Other) {
1324 maybeRestoreState();
1325 moveFromAndCancel(std::move(
Other));
1329 ~SpeculativeEvaluationRAII() { maybeRestoreState(); }
1334 template<ScopeKind Kind>
1337 unsigned OldStackSize;
1339 ScopeRAII(EvalInfo &Info)
1340 : Info(Info), OldStackSize(Info.CleanupStack.size()) {
1343 Info.CurrentCall->pushTempVersion();
1345 bool destroy(
bool RunDestructors =
true) {
1346 bool OK =
cleanup(Info, RunDestructors, OldStackSize);
1347 OldStackSize = std::numeric_limits<unsigned>::max();
1351 if (OldStackSize != std::numeric_limits<unsigned>::max())
1355 Info.CurrentCall->popTempVersion();
1358 static bool cleanup(EvalInfo &Info,
bool RunDestructors,
1359 unsigned OldStackSize) {
1360 assert(OldStackSize <= Info.CleanupStack.size() &&
1361 "running cleanups out of order?");
1366 for (
unsigned I = Info.CleanupStack.size(); I > OldStackSize; --I) {
1367 if (Info.CleanupStack[I - 1].isDestroyedAtEndOf(Kind)) {
1368 if (!Info.CleanupStack[I - 1].endLifetime(Info, RunDestructors)) {
1376 auto NewEnd = Info.CleanupStack.begin() + OldStackSize;
1377 if (Kind != ScopeKind::Block)
1379 std::remove_if(NewEnd, Info.CleanupStack.end(), [](Cleanup &
C) {
1380 return C.isDestroyedAtEndOf(Kind);
1382 Info.CleanupStack.erase(NewEnd, Info.CleanupStack.end());
1386 typedef ScopeRAII<ScopeKind::Block> BlockScopeRAII;
1387 typedef ScopeRAII<ScopeKind::FullExpression> FullExpressionRAII;
1388 typedef ScopeRAII<ScopeKind::Call> CallScopeRAII;
1391bool SubobjectDesignator::checkSubobject(EvalInfo &Info,
const Expr *E,
1395 if (isOnePastTheEnd()) {
1396 Info.CCEDiag(E, diag::note_constexpr_past_end_subobject)
1407void SubobjectDesignator::diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info,
1409 Info.CCEDiag(E, diag::note_constexpr_unsized_array_indexed);
1414void SubobjectDesignator::diagnosePointerArithmetic(EvalInfo &Info,
1419 if (MostDerivedPathLength == Entries.size() && MostDerivedIsArrayElement)
1420 Info.CCEDiag(E, diag::note_constexpr_array_index)
1422 <<
static_cast<unsigned>(getMostDerivedArraySize());
1424 Info.CCEDiag(E, diag::note_constexpr_array_index)
1429CallStackFrame::CallStackFrame(EvalInfo &Info, SourceRange CallRange,
1430 const FunctionDecl *Callee,
const LValue *This,
1431 const Expr *CallExpr, CallRef Call)
1433 CallExpr(CallExpr),
Arguments(Call), CallRange(CallRange),
1434 Index(Info.NextCallIndex++) {
1435 Info.CurrentCall =
this;
1436 ++Info.CallStackDepth;
1439CallStackFrame::~CallStackFrame() {
1440 assert(Info.CurrentCall ==
this &&
"calls retired out of order");
1441 --Info.CallStackDepth;
1442 Info.CurrentCall = Caller;
1467 llvm_unreachable(
"unknown access kind");
1504 llvm_unreachable(
"unknown access kind");
1508 struct ComplexValue {
1516 ComplexValue() : FloatReal(
APFloat::Bogus()), FloatImag(
APFloat::Bogus()) {}
1518 void makeComplexFloat() { IsInt =
false; }
1519 bool isComplexFloat()
const {
return !IsInt; }
1520 APFloat &getComplexFloatReal() {
return FloatReal; }
1521 APFloat &getComplexFloatImag() {
return FloatImag; }
1523 void makeComplexInt() { IsInt =
true; }
1524 bool isComplexInt()
const {
return IsInt; }
1525 APSInt &getComplexIntReal() {
return IntReal; }
1526 APSInt &getComplexIntImag() {
return IntImag; }
1528 void moveInto(
APValue &v)
const {
1529 if (isComplexFloat())
1530 v =
APValue(FloatReal, FloatImag);
1532 v =
APValue(IntReal, IntImag);
1534 void setFrom(
const APValue &v) {
1549 APValue::LValueBase
Base;
1551 SubobjectDesignator Designator;
1553 bool InvalidBase : 1;
1555 bool AllowConstexprUnknown =
false;
1557 const APValue::LValueBase getLValueBase()
const {
return Base; }
1558 bool allowConstexprUnknown()
const {
return AllowConstexprUnknown; }
1559 CharUnits &getLValueOffset() {
return Offset; }
1560 const CharUnits &getLValueOffset()
const {
return Offset; }
1561 SubobjectDesignator &getLValueDesignator() {
return Designator; }
1562 const SubobjectDesignator &getLValueDesignator()
const {
return Designator;}
1563 bool isNullPointer()
const {
return IsNullPtr;}
1565 unsigned getLValueCallIndex()
const {
return Base.getCallIndex(); }
1566 unsigned getLValueVersion()
const {
return Base.getVersion(); }
1569 if (Designator.Invalid)
1570 V =
APValue(Base, Offset, APValue::NoLValuePath(), IsNullPtr);
1572 assert(!InvalidBase &&
"APValues can't handle invalid LValue bases");
1573 V =
APValue(Base, Offset, Designator.Entries,
1574 Designator.IsOnePastTheEnd, IsNullPtr);
1576 if (AllowConstexprUnknown)
1577 V.setConstexprUnknown();
1579 void setFrom(
const ASTContext &Ctx,
const APValue &
V) {
1580 assert(
V.isLValue() &&
"Setting LValue from a non-LValue?");
1581 Base =
V.getLValueBase();
1582 Offset =
V.getLValueOffset();
1583 InvalidBase =
false;
1584 Designator = SubobjectDesignator(Ctx,
V);
1585 IsNullPtr =
V.isNullPointer();
1586 AllowConstexprUnknown =
V.allowConstexprUnknown();
1589 void set(APValue::LValueBase B,
bool BInvalid =
false) {
1593 const auto *E = B.
get<
const Expr *>();
1595 "Unexpected type of invalid base");
1601 InvalidBase = BInvalid;
1602 Designator = SubobjectDesignator(
getType(B));
1604 AllowConstexprUnknown =
false;
1607 void setNull(ASTContext &Ctx, QualType PointerTy) {
1608 Base = (
const ValueDecl *)
nullptr;
1611 InvalidBase =
false;
1614 AllowConstexprUnknown =
false;
1617 void setInvalid(APValue::LValueBase B,
unsigned I = 0) {
1621 std::string
toString(ASTContext &Ctx, QualType
T)
const {
1623 moveInto(Printable);
1630 template <
typename GenDiagType>
1631 bool checkNullPointerDiagnosingWith(
const GenDiagType &GenDiag) {
1632 if (Designator.Invalid)
1636 Designator.setInvalid();
1643 bool checkNullPointer(EvalInfo &Info,
const Expr *E,
1645 return checkNullPointerDiagnosingWith([&Info, E, CSK] {
1646 Info.CCEDiag(E, diag::note_constexpr_null_subobject) << CSK;
1650 bool checkNullPointerForFoldAccess(EvalInfo &Info,
const Expr *E,
1652 return checkNullPointerDiagnosingWith([&Info, E, AK] {
1653 if (AK == AccessKinds::AK_Dereference)
1654 Info.FFDiag(E, diag::note_constexpr_dereferencing_null);
1656 Info.FFDiag(E, diag::note_constexpr_access_null) << AK;
1664 Designator.checkSubobject(Info, E, CSK);
1667 void addDecl(EvalInfo &Info,
const Expr *E,
1668 const Decl *D,
bool Virtual =
false) {
1670 Designator.addDeclUnchecked(D,
Virtual);
1672 void addUnsizedArray(EvalInfo &Info,
const Expr *E, QualType ElemTy) {
1673 if (!Designator.Entries.empty()) {
1674 Info.CCEDiag(E, diag::note_constexpr_unsupported_unsized_array);
1675 Designator.setInvalid();
1679 assert(
getType(Base).getNonReferenceType()->isPointerType() ||
1680 getType(Base).getNonReferenceType()->isArrayType());
1681 Designator.FirstEntryIsAnUnsizedArray =
true;
1682 Designator.addUnsizedArrayUnchecked(ElemTy);
1685 void addArray(EvalInfo &Info,
const Expr *E,
const ConstantArrayType *CAT) {
1687 Designator.addArrayUnchecked(CAT);
1689 void addComplex(EvalInfo &Info,
const Expr *E, QualType EltTy,
bool Imag) {
1691 Designator.addComplexUnchecked(EltTy, Imag);
1693 void addVectorElement(EvalInfo &Info,
const Expr *E, QualType EltTy,
1694 uint64_t Size, uint64_t Idx) {
1696 Designator.addVectorElementUnchecked(EltTy, Size, Idx);
1698 void clearIsNullPointer() {
1701 void adjustOffsetAndIndex(EvalInfo &Info,
const Expr *E,
1702 const APSInt &Index, CharUnits ElementSize) {
1713 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
1717 Designator.adjustIndex(Info, E, Index, *
this);
1718 clearIsNullPointer();
1720 void adjustOffset(CharUnits N) {
1723 clearIsNullPointer();
1729 explicit MemberPtr(
const ValueDecl *Decl)
1730 : DeclAndIsDerivedMember(
Decl,
false) {}
1734 const ValueDecl *getDecl()
const {
1735 return DeclAndIsDerivedMember.getPointer();
1738 bool isDerivedMember()
const {
1739 return DeclAndIsDerivedMember.getInt();
1742 const CXXRecordDecl *getContainingRecord()
const {
1744 DeclAndIsDerivedMember.getPointer()->getDeclContext());
1748 V =
APValue(getDecl(), isDerivedMember(), Path);
1751 assert(
V.isMemberPointer());
1752 DeclAndIsDerivedMember.setPointer(
V.getMemberPointerDecl());
1753 DeclAndIsDerivedMember.setInt(
V.isMemberPointerToDerivedMember());
1755 llvm::append_range(Path,
V.getMemberPointerPath());
1761 llvm::PointerIntPair<const ValueDecl*, 1, bool> DeclAndIsDerivedMember;
1764 SmallVector<const CXXRecordDecl*, 4> Path;
1768 bool castBack(
const CXXRecordDecl *
Class) {
1769 assert(!Path.empty());
1770 const CXXRecordDecl *Expected;
1771 if (Path.size() >= 2)
1772 Expected = Path[Path.size() - 2];
1774 Expected = getContainingRecord();
1788 bool castToDerived(
const CXXRecordDecl *Derived) {
1791 if (!isDerivedMember()) {
1792 Path.push_back(Derived);
1795 if (!castBack(Derived))
1798 DeclAndIsDerivedMember.setInt(
false);
1806 DeclAndIsDerivedMember.setInt(
true);
1807 if (isDerivedMember()) {
1808 Path.push_back(Base);
1811 return castBack(Base);
1816 static bool operator==(
const MemberPtr &LHS,
const MemberPtr &RHS) {
1817 if (!LHS.getDecl() || !RHS.getDecl())
1818 return !LHS.getDecl() && !RHS.getDecl();
1819 if (LHS.getDecl()->getCanonicalDecl() != RHS.getDecl()->getCanonicalDecl())
1821 return LHS.Path == RHS.Path;
1825void SubobjectDesignator::adjustIndex(EvalInfo &Info,
const Expr *E,
APSInt N,
1829 uint64_t TruncatedN = N.extOrTrunc(64).getZExtValue();
1830 if (isMostDerivedAnUnsizedArray()) {
1831 diagnoseUnsizedArrayPointerArithmetic(Info, E);
1836 PathEntry::ArrayIndex(Entries.back().getAsArrayIndex() + TruncatedN);
1844 MostDerivedPathLength == Entries.size() && MostDerivedIsArrayElement;
1846 IsArray ? Entries.back().getAsArrayIndex() : (
uint64_t)IsOnePastTheEnd;
1849 if (N < -(int64_t)ArrayIndex || N > ArraySize - ArrayIndex) {
1850 if (!Info.checkingPotentialConstantExpression() ||
1851 !LV.AllowConstexprUnknown) {
1854 N = N.extend(std::max<unsigned>(N.getBitWidth() + 1, 65));
1855 (llvm::APInt &)N += ArrayIndex;
1856 assert(N.ugt(ArraySize) &&
"bounds check failed for in-bounds index");
1857 diagnosePointerArithmetic(Info, E, N);
1863 ArrayIndex += TruncatedN;
1864 assert(ArrayIndex <= ArraySize &&
1865 "bounds check succeeded for out-of-bounds index");
1868 Entries.back() = PathEntry::ArrayIndex(ArrayIndex);
1870 IsOnePastTheEnd = (ArrayIndex != 0);
1875 const LValue &This,
const Expr *E,
1876 bool AllowNonLiteralTypes =
false);
1878 bool InvalidBaseOK =
false);
1880 bool InvalidBaseOK =
false);
1888static bool EvaluateComplex(
const Expr *E, ComplexValue &Res, EvalInfo &Info);
1894 std::string *StringResult =
nullptr);
1911 if (Int.isUnsigned() || Int.isMinSignedValue()) {
1912 Int = Int.extend(Int.getBitWidth() + 1);
1913 Int.setIsSigned(
true);
1918template<
typename KeyT>
1919APValue &CallStackFrame::createTemporary(
const KeyT *Key, QualType
T,
1920 ScopeKind Scope, LValue &LV) {
1921 unsigned Version = getTempVersion();
1922 APValue::LValueBase
Base(Key, Index, Version);
1924 return createLocal(Base, Key,
T, Scope);
1928APValue &CallStackFrame::createParam(CallRef Args,
const ParmVarDecl *PVD,
1930 assert(Args.CallIndex == Index &&
"creating parameter in wrong frame");
1931 APValue::LValueBase
Base(PVD, Index, Args.Version);
1936 return createLocal(Base, PVD, PVD->
getType(), ScopeKind::Call);
1939APValue &CallStackFrame::createLocal(APValue::LValueBase Base,
const void *Key,
1940 QualType
T, ScopeKind Scope) {
1941 assert(
Base.getCallIndex() == Index &&
"lvalue for wrong frame");
1942 unsigned Version =
Base.getVersion();
1944 assert(
Result.isAbsent() &&
"local created multiple times");
1950 if (Index <= Info.SpeculativeEvaluationDepth) {
1951 if (
T.isDestructedType())
1952 Info.noteSideEffect();
1954 Info.CleanupStack.push_back(Cleanup(&
Result, Base,
T, Scope));
1959APValue *EvalInfo::createHeapAlloc(
const Expr *E, QualType
T, LValue &LV) {
1961 FFDiag(E, diag::note_constexpr_heap_alloc_limit_exceeded);
1965 DynamicAllocLValue DA(NumHeapAllocs++);
1967 auto Result = HeapAllocs.emplace(std::piecewise_construct,
1968 std::forward_as_tuple(DA), std::tuple<>());
1969 assert(
Result.second &&
"reused a heap alloc index?");
1970 Result.first->second.AllocExpr = E;
1971 return &
Result.first->second.Value;
1975void CallStackFrame::describe(raw_ostream &Out)
const {
1976 unsigned ArgIndex = 0;
1985 if (This && IsMemberCall) {
1986 if (
const auto *MCE = dyn_cast_if_present<CXXMemberCallExpr>(CallExpr)) {
1987 const Expr *
Object = MCE->getImplicitObjectArgument();
1990 if (
Object->getType()->isPointerType())
1994 }
else if (
const auto *OCE =
1995 dyn_cast_if_present<CXXOperatorCallExpr>(CallExpr)) {
1996 OCE->getArg(0)->printPretty(Out,
nullptr,
2002 This->moveInto(Val);
2010 IsMemberCall =
false;
2016 E =
Callee->param_end(); I != E; ++I, ++ArgIndex) {
2017 if (ArgIndex > (
unsigned)IsMemberCall)
2020 const ParmVarDecl *Param = *I;
2021 APValue *
V = Info.getParamSlot(Arguments, Param);
2023 V->printPretty(Out, Info.Ctx, Param->
getType());
2027 if (ArgIndex == 0 && IsMemberCall)
2042 return Info.noteSideEffect();
2049 return (
Builtin == Builtin::BI__builtin___CFStringMakeConstantString ||
2050 Builtin == Builtin::BI__builtin___NSStringMakeConstantString ||
2051 Builtin == Builtin::BI__builtin_ptrauth_sign_constant ||
2052 Builtin == Builtin::BI__builtin_function_start);
2056 const auto *BaseExpr =
2057 llvm::dyn_cast_if_present<CallExpr>(LVal.Base.
dyn_cast<
const Expr *>());
2072 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
2073 return VD->hasGlobalStorage();
2089 case Expr::CompoundLiteralExprClass: {
2093 case Expr::MaterializeTemporaryExprClass:
2098 case Expr::StringLiteralClass:
2099 case Expr::PredefinedExprClass:
2100 case Expr::ObjCStringLiteralClass:
2101 case Expr::ObjCEncodeExprClass:
2103 case Expr::ObjCBoxedExprClass:
2105 case Expr::CallExprClass:
2108 case Expr::AddrLabelExprClass:
2112 case Expr::BlockExprClass:
2116 case Expr::SourceLocExprClass:
2118 case Expr::ImplicitValueInitExprClass:
2143 const auto *BaseExpr = LVal.Base.
dyn_cast<
const Expr *>();
2148 if (
const auto *EE = dyn_cast<ObjCEncodeExpr>(BaseExpr)) {
2157 const auto *Lit = dyn_cast<StringLiteral>(BaseExpr);
2158 if (
const auto *PE = dyn_cast<PredefinedExpr>(BaseExpr))
2159 Lit = PE->getFunctionName();
2164 AsString.
Bytes = Lit->getBytes();
2165 AsString.
CharWidth = Lit->getCharByteWidth();
2185 const LValue &RHS) {
2194 CharUnits Offset = RHS.Offset - LHS.Offset;
2195 if (Offset.isNegative()) {
2196 if (LHSString.
Bytes.size() < (
size_t)-Offset.getQuantity())
2198 LHSString.
Bytes = LHSString.
Bytes.drop_front(-Offset.getQuantity());
2200 if (RHSString.
Bytes.size() < (
size_t)Offset.getQuantity())
2202 RHSString.
Bytes = RHSString.
Bytes.drop_front(Offset.getQuantity());
2205 bool LHSIsLonger = LHSString.
Bytes.size() > RHSString.
Bytes.size();
2206 StringRef Longer = LHSIsLonger ? LHSString.
Bytes : RHSString.
Bytes;
2207 StringRef Shorter = LHSIsLonger ? RHSString.
Bytes : LHSString.
Bytes;
2208 int ShorterCharWidth = (LHSIsLonger ? RHSString : LHSString).CharWidth;
2213 for (
int NullByte : llvm::seq(ShorterCharWidth)) {
2214 if (Shorter.size() + NullByte >= Longer.size())
2216 if (Longer[Shorter.size() + NullByte])
2222 return Shorter == Longer.take_front(Shorter.size());
2232 if (isa_and_nonnull<VarDecl>(
Decl)) {
2242 if (!A.getLValueBase())
2243 return !B.getLValueBase();
2244 if (!B.getLValueBase())
2247 if (A.getLValueBase().getOpaqueValue() !=
2248 B.getLValueBase().getOpaqueValue())
2251 return A.getLValueCallIndex() == B.getLValueCallIndex() &&
2252 A.getLValueVersion() == B.getLValueVersion();
2256 assert(
Base &&
"no location for a null lvalue");
2262 if (
auto *PVD = dyn_cast_or_null<ParmVarDecl>(VD)) {
2264 for (CallStackFrame *F = Info.CurrentCall; F; F = F->Caller) {
2265 if (F->Arguments.CallIndex ==
Base.getCallIndex() &&
2266 F->Arguments.Version ==
Base.getVersion() && F->Callee &&
2267 Idx < F->Callee->getNumParams()) {
2268 VD = F->Callee->getParamDecl(Idx);
2275 Info.Note(VD->
getLocation(), diag::note_declared_at);
2277 Info.Note(E->
getExprLoc(), diag::note_constexpr_temporary_here);
2280 if (std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA))
2281 Info.Note((*Alloc)->AllocExpr->getExprLoc(),
2282 diag::note_constexpr_dynamic_alloc_here);
2315 const SubobjectDesignator &
Designator = LVal.getLValueDesignator();
2323 if (isTemplateArgument(Kind)) {
2324 int InvalidBaseKind = -1;
2327 InvalidBaseKind = 0;
2328 else if (isa_and_nonnull<StringLiteral>(BaseE))
2329 InvalidBaseKind = 1;
2330 else if (isa_and_nonnull<MaterializeTemporaryExpr>(BaseE) ||
2331 isa_and_nonnull<LifetimeExtendedTemporaryDecl>(BaseVD))
2332 InvalidBaseKind = 2;
2333 else if (
auto *PE = dyn_cast_or_null<PredefinedExpr>(BaseE)) {
2334 InvalidBaseKind = 3;
2335 Ident = PE->getIdentKindName();
2338 if (InvalidBaseKind != -1) {
2339 Info.FFDiag(Loc, diag::note_constexpr_invalid_template_arg)
2340 << IsReferenceType << !
Designator.Entries.empty() << InvalidBaseKind
2346 if (
auto *FD = dyn_cast_or_null<FunctionDecl>(BaseVD);
2347 FD && FD->isImmediateFunction()) {
2348 Info.FFDiag(Loc, diag::note_consteval_address_accessible)
2350 Info.Note(FD->getLocation(), diag::note_declared_at);
2358 if (Info.getLangOpts().CPlusPlus11) {
2359 Info.FFDiag(Loc, diag::note_constexpr_non_global, 1)
2360 << IsReferenceType << !
Designator.Entries.empty() << !!BaseVD
2362 auto *VarD = dyn_cast_or_null<VarDecl>(BaseVD);
2363 if (VarD && VarD->isConstexpr()) {
2369 Info.Note(VarD->getLocation(), diag::note_constexpr_not_static)
2381 assert((Info.checkingPotentialConstantExpression() ||
2382 LVal.getLValueCallIndex() == 0) &&
2383 "have call index for global lvalue");
2385 if (LVal.allowConstexprUnknown()) {
2387 Info.FFDiag(Loc, diag::note_constexpr_var_init_non_constant, 1) << BaseVD;
2396 Info.FFDiag(Loc, diag::note_constexpr_dynamic_alloc)
2397 << IsReferenceType << !
Designator.Entries.empty();
2403 if (
const VarDecl *Var = dyn_cast<const VarDecl>(BaseVD)) {
2405 if (Var->getTLSKind())
2411 if (!isForManglingOnly(Kind) && Var->hasAttr<DLLImportAttr>())
2417 if (Info.getASTContext().getLangOpts().CUDA &&
2418 Info.getASTContext().getLangOpts().CUDAIsDevice &&
2419 Info.getASTContext().CUDAConstantEvalCtx.NoWrongSidedVars) {
2420 if ((!Var->hasAttr<CUDADeviceAttr>() &&
2421 !Var->hasAttr<CUDAConstantAttr>() &&
2422 !Var->getType()->isCUDADeviceBuiltinSurfaceType() &&
2423 !Var->getType()->isCUDADeviceBuiltinTextureType()) ||
2424 Var->hasAttr<HIPManagedAttr>())
2428 if (
const auto *FD = dyn_cast<const FunctionDecl>(BaseVD)) {
2439 if (Info.getLangOpts().CPlusPlus && !isForManglingOnly(Kind) &&
2440 FD->hasAttr<DLLImportAttr>())
2444 }
else if (
const auto *MTE =
2445 dyn_cast_or_null<MaterializeTemporaryExpr>(BaseE)) {
2446 if (CheckedTemps.insert(MTE).second) {
2449 Info.FFDiag(MTE->getExprLoc(),
2450 diag::note_constexpr_unsupported_temporary_nontrivial_dtor)
2455 APValue *
V = MTE->getOrCreateValue(
false);
2456 assert(
V &&
"evasluation result refers to uninitialised temporary");
2458 Info, MTE->getExprLoc(), TempType, *
V, Kind,
2459 nullptr, CheckedTemps))
2466 if (!IsReferenceType)
2478 Info.FFDiag(Loc, diag::note_constexpr_past_end, 1)
2479 << !
Designator.Entries.empty() << !!BaseVD << BaseVD;
2494 const auto *FD = dyn_cast_or_null<CXXMethodDecl>(
Member);
2497 if (FD->isImmediateFunction()) {
2498 Info.FFDiag(Loc, diag::note_consteval_address_accessible) << 0;
2499 Info.Note(FD->getLocation(), diag::note_declared_at);
2502 return isForManglingOnly(Kind) || FD->isVirtual() ||
2503 !FD->hasAttr<DLLImportAttr>();
2509 const LValue *
This =
nullptr) {
2511 if (Info.getLangOpts().CPlusPlus23)
2530 if (
This && Info.EvaluatingDecl ==
This->getLValueBase())
2534 if (Info.getLangOpts().CPlusPlus11)
2535 Info.FFDiag(E, diag::note_constexpr_nonliteral)
2538 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
2549 if (SubobjectDecl) {
2550 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
2551 << 1 << SubobjectDecl;
2553 diag::note_constexpr_subobject_declared_here);
2555 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
2564 Type = AT->getValueType();
2569 if (
Value.isArray()) {
2571 for (
unsigned I = 0, N =
Value.getArrayInitializedElts(); I != N; ++I) {
2573 Value.getArrayInitializedElt(I), Kind,
2574 SubobjectDecl, CheckedTemps))
2577 if (!
Value.hasArrayFiller())
2580 Value.getArrayFiller(), Kind, SubobjectDecl,
2583 if (
Value.isUnion() &&
Value.getUnionField()) {
2586 Value.getUnionValue(), Kind,
Value.getUnionField(), CheckedTemps);
2588 if (
Value.isStruct()) {
2590 if (
const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {
2591 unsigned BaseIndex = 0;
2593 const APValue &BaseValue =
Value.getStructBase(BaseIndex);
2596 Info.FFDiag(TypeBeginLoc, diag::note_constexpr_uninitialized_base)
2597 << BS.getType() <<
SourceRange(TypeBeginLoc, BS.getEndLoc());
2607 for (
const auto *I : RD->fields()) {
2608 if (I->isUnnamedBitField())
2612 Value.getStructField(I->getFieldIndex()), Kind,
2618 if (
Value.isLValue() &&
2621 LVal.setFrom(Info.Ctx,
Value);
2626 if (
Value.isMemberPointer() &&
2647 nullptr, CheckedTemps);
2657 ConstantExprKind::Normal,
nullptr, CheckedTemps);
2663 if (!Info.HeapAllocs.empty()) {
2667 Info.CCEDiag(Info.HeapAllocs.begin()->second.AllocExpr,
2668 diag::note_constexpr_memory_leak)
2669 <<
unsigned(Info.HeapAllocs.size() - 1);
2677 if (!
Value.getLValueBase()) {
2679 Result = !
Value.getLValueOffset().isZero();
2697 Result = Val.
getInt().getBoolValue();
2729 llvm_unreachable(
"unknown APValue kind");
2735 assert(E->
isPRValue() &&
"missing lvalue-to-rvalue conv in bool condition");
2745 Info.CCEDiag(E, diag::note_constexpr_overflow)
2746 << SrcValue << DestType;
2747 return Info.noteUndefinedBehavior();
2753 unsigned DestWidth = Info.Ctx.
getIntWidth(DestType);
2757 Result =
APSInt(DestWidth, !DestSigned);
2759 if (
Value.convertToInteger(Result, llvm::APFloat::rmTowardZero, &ignored)
2760 & APFloat::opInvalidOp)
2771 llvm::RoundingMode RM =
2773 if (RM == llvm::RoundingMode::Dynamic)
2774 RM = llvm::RoundingMode::NearestTiesToEven;
2780 APFloat::opStatus St) {
2783 if (Info.InConstantContext)
2787 if ((St & APFloat::opInexact) &&
2791 Info.FFDiag(E, diag::note_constexpr_dynamic_rounding);
2795 if ((St != APFloat::opOK) &&
2798 FPO.getAllowFEnvAccess())) {
2799 Info.FFDiag(E, diag::note_constexpr_float_arithmetic_strict);
2803 if ((St & APFloat::opStatus::opInvalidOp) &&
2824 "HandleFloatToFloatCast has been checked with only CastExpr, "
2825 "CompoundAssignOperator and ConvertVectorExpr. Please either validate "
2826 "the new expression or address the root cause of this usage.");
2828 APFloat::opStatus St;
2829 APFloat
Value = Result;
2838 unsigned DestWidth = Info.Ctx.
getIntWidth(DestType);
2844 Result =
Value.getBoolValue();
2851 QualType DestType, APFloat &Result) {
2854 APFloat::opStatus St = Result.convertFromAPInt(
Value,
Value.isSigned(), RM);
2860 assert(FD->
isBitField() &&
"truncateBitfieldValue on non-bitfield");
2862 if (!
Value.isInt()) {
2866 assert(
Value.isLValue() &&
"integral value neither int nor lvalue?");
2872 unsigned OldBitWidth = Int.getBitWidth();
2874 if (NewBitWidth < OldBitWidth)
2875 Int = Int.trunc(NewBitWidth).extend(OldBitWidth);
2882template<
typename Operation>
2885 unsigned BitWidth, Operation Op,
2887 if (LHS.isUnsigned()) {
2888 Result = Op(LHS, RHS);
2892 APSInt Value(Op(LHS.extend(BitWidth), RHS.extend(BitWidth)),
false);
2893 Result =
Value.trunc(LHS.getBitWidth());
2894 if (Result.extend(BitWidth) !=
Value) {
2895 if (Info.checkingForUndefinedBehavior())
2897 diag::warn_integer_constant_overflow)
2898 <<
toString(Result, 10, Result.isSigned(),
false,
2910 bool HandleOverflowResult =
true;
2917 std::multiplies<APSInt>(), Result);
2920 std::plus<APSInt>(), Result);
2923 std::minus<APSInt>(), Result);
2924 case BO_And: Result = LHS & RHS;
return true;
2925 case BO_Xor: Result = LHS ^ RHS;
return true;
2926 case BO_Or: Result = LHS | RHS;
return true;
2930 Info.FFDiag(E, diag::note_expr_divide_by_zero)
2936 if (RHS.isNegative() && RHS.isAllOnes() && LHS.isSigned() &&
2937 LHS.isMinSignedValue())
2939 Info, E, -LHS.extend(LHS.getBitWidth() + 1), E->
getType());
2940 Result = (Opcode == BO_Rem ? LHS % RHS : LHS / RHS);
2941 return HandleOverflowResult;
2943 if (Info.getLangOpts().OpenCL)
2945 RHS &=
APSInt(llvm::APInt(RHS.getBitWidth(),
2946 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2948 else if (RHS.isSigned() && RHS.isNegative()) {
2951 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
2952 if (!Info.noteUndefinedBehavior())
2960 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
2962 Info.CCEDiag(E, diag::note_constexpr_large_shift)
2963 << RHS << E->
getType() << LHS.getBitWidth();
2964 if (!Info.noteUndefinedBehavior())
2966 }
else if (LHS.isSigned() && !Info.getLangOpts().CPlusPlus20) {
2971 if (LHS.isNegative()) {
2972 Info.CCEDiag(E, diag::note_constexpr_lshift_of_negative) << LHS;
2973 if (!Info.noteUndefinedBehavior())
2975 }
else if (LHS.countl_zero() < SA) {
2976 Info.CCEDiag(E, diag::note_constexpr_lshift_discards);
2977 if (!Info.noteUndefinedBehavior())
2985 if (Info.getLangOpts().OpenCL)
2987 RHS &=
APSInt(llvm::APInt(RHS.getBitWidth(),
2988 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2990 else if (RHS.isSigned() && RHS.isNegative()) {
2993 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
2994 if (!Info.noteUndefinedBehavior())
3002 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
3004 Info.CCEDiag(E, diag::note_constexpr_large_shift)
3005 << RHS << E->
getType() << LHS.getBitWidth();
3006 if (!Info.noteUndefinedBehavior())
3014 case BO_LT: Result = LHS < RHS;
return true;
3015 case BO_GT: Result = LHS > RHS;
return true;
3016 case BO_LE: Result = LHS <= RHS;
return true;
3017 case BO_GE: Result = LHS >= RHS;
return true;
3018 case BO_EQ: Result = LHS == RHS;
return true;
3019 case BO_NE: Result = LHS != RHS;
return true;
3021 llvm_unreachable(
"BO_Cmp should be handled elsewhere");
3028 const APFloat &RHS) {
3030 APFloat::opStatus St;
3036 St = LHS.multiply(RHS, RM);
3039 St = LHS.add(RHS, RM);
3042 St = LHS.subtract(RHS, RM);
3048 Info.CCEDiag(E, diag::note_expr_divide_by_zero);
3049 St = LHS.divide(RHS, RM);
3058 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << LHS.isNaN();
3059 return Info.noteUndefinedBehavior();
3067 const APInt &RHSValue, APInt &Result) {
3068 bool LHS = (LHSValue != 0);
3069 bool RHS = (RHSValue != 0);
3071 if (Opcode == BO_LAnd)
3072 Result = LHS && RHS;
3074 Result = LHS || RHS;
3079 const APFloat &RHSValue, APInt &Result) {
3080 bool LHS = !LHSValue.isZero();
3081 bool RHS = !RHSValue.isZero();
3083 if (Opcode == BO_LAnd)
3084 Result = LHS && RHS;
3086 Result = LHS || RHS;
3092 const APValue &RHSValue, APInt &Result) {
3096 RHSValue.
getInt(), Result);
3102template <
typename APTy>
3105 const APTy &RHSValue, APInt &Result) {
3108 llvm_unreachable(
"unsupported binary operator");
3110 Result = (LHSValue == RHSValue);
3113 Result = (LHSValue != RHSValue);
3116 Result = (LHSValue < RHSValue);
3119 Result = (LHSValue > RHSValue);
3122 Result = (LHSValue <= RHSValue);
3125 Result = (LHSValue >= RHSValue);
3139 const APValue &RHSValue, APInt &Result) {
3143 RHSValue.
getInt(), Result);
3154 assert(Opcode != BO_PtrMemD && Opcode != BO_PtrMemI &&
3155 "Operation not supported on vector types");
3159 QualType EltTy = VT->getElementType();
3166 "A vector result that isn't a vector OR uncalculated LValue");
3172 RHSValue.
getVectorLength() == NumElements &&
"Different vector sizes");
3176 for (
unsigned EltNum = 0; EltNum < NumElements; ++EltNum) {
3191 RHSElt.
getInt(), EltResult);
3197 ResultElements.emplace_back(EltResult);
3202 "Mismatched LHS/RHS/Result Type");
3203 APFloat LHSFloat = LHSElt.
getFloat();
3211 ResultElements.emplace_back(LHSFloat);
3215 LHSValue =
APValue(ResultElements.data(), ResultElements.size());
3223 unsigned TruncatedElements) {
3224 SubobjectDesignator &D = Result.Designator;
3227 if (TruncatedElements == D.Entries.size())
3229 assert(TruncatedElements >= D.MostDerivedPathLength &&
3230 "not casting to a derived class");
3236 for (
unsigned I = TruncatedElements, N = D.Entries.size(); I != N; ++I) {
3240 if (isVirtualBaseClass(D.Entries[I]))
3246 D.Entries.resize(TruncatedElements);
3259 Obj.addDecl(Info, E,
Base,
false);
3260 Obj.getLValueOffset() += RL->getBaseClassOffset(
Base);
3269 if (!
Base->isVirtual())
3272 SubobjectDesignator &D = Obj.Designator;
3288 Obj.addDecl(Info, E, BaseDecl,
true);
3297 PathI != PathE; ++PathI) {
3301 Type = (*PathI)->getType();
3313 llvm_unreachable(
"Class must be derived from the passed in base class!");
3332 LVal.addDecl(Info, E, FD);
3341 for (
const auto *
C : IFD->
chain())
3394 LVal.adjustOffsetAndIndex(Info, E, Adjustment, SizeOfPointee);
3400 int64_t Adjustment) {
3402 APSInt::get(Adjustment));
3417 LVal.Offset += SizeOfComponent;
3419 LVal.addComplex(Info, E, EltTy, Imag);
3425 uint64_t Size, uint64_t Idx) {
3430 LVal.Offset += SizeOfElement * Idx;
3432 LVal.addVectorElement(Info, E, EltTy, Size, Idx);
3446 const VarDecl *VD, CallStackFrame *Frame,
3447 unsigned Version,
APValue *&Result) {
3450 bool AllowConstexprUnknown =
3455 auto CheckUninitReference = [&](
bool IsLocalVariable) {
3467 if (!AllowConstexprUnknown || IsLocalVariable) {
3468 if (!Info.checkingPotentialConstantExpression())
3469 Info.FFDiag(E, diag::note_constexpr_use_uninit_reference);
3479 Result = Frame->getTemporary(VD, Version);
3481 return CheckUninitReference(
true);
3490 "missing value for local variable");
3491 if (Info.checkingPotentialConstantExpression())
3496 diag::note_unimplemented_constexpr_lambda_feature_ast)
3497 <<
"captures not currently allowed";
3504 if (Info.EvaluatingDecl ==
Base) {
3505 Result = Info.EvaluatingDeclValue;
3506 return CheckUninitReference(
false);
3514 if (AllowConstexprUnknown) {
3521 if (!Info.checkingPotentialConstantExpression() ||
3522 !Info.CurrentCall->Callee ||
3524 if (Info.getLangOpts().CPlusPlus11) {
3525 Info.FFDiag(E, diag::note_constexpr_function_param_value_unknown)
3546 if (!
Init && !AllowConstexprUnknown) {
3549 if (!Info.checkingPotentialConstantExpression()) {
3550 Info.FFDiag(E, diag::note_constexpr_var_init_unknown, 1)
3561 if (
Init &&
Init->isValueDependent()) {
3568 if (!Info.checkingPotentialConstantExpression()) {
3569 Info.FFDiag(E, Info.getLangOpts().CPlusPlus11
3570 ? diag::note_constexpr_ltor_non_constexpr
3571 : diag::note_constexpr_ltor_non_integral, 1)
3585 Info.FFDiag(E, diag::note_constexpr_var_init_non_constant, 1) << VD;
3601 !AllowConstexprUnknown) ||
3602 ((Info.getLangOpts().CPlusPlus || Info.getLangOpts().OpenCL) &&
3605 Info.CCEDiag(E, diag::note_constexpr_var_init_non_constant, 1) << VD;
3615 Info.FFDiag(E, diag::note_constexpr_var_init_weak) << VD;
3622 if (!Result && !AllowConstexprUnknown)
3625 return CheckUninitReference(
false);
3635 E = Derived->
bases_end(); I != E; ++I, ++Index) {
3636 if (I->getType()->getAsCXXRecordDecl()->getCanonicalDecl() ==
Base)
3640 llvm_unreachable(
"base class missing from derived class's bases list");
3647 "SourceLocExpr should have already been converted to a StringLiteral");
3650 if (
const auto *ObjCEnc = dyn_cast<ObjCEncodeExpr>(Lit)) {
3653 assert(Index <= Str.size() &&
"Index too large");
3654 return APSInt::getUnsigned(Str.c_str()[Index]);
3657 if (
auto PE = dyn_cast<PredefinedExpr>(Lit))
3658 Lit = PE->getFunctionName();
3662 assert(CAT &&
"string literal isn't an array");
3664 assert(CharType->
isIntegerType() &&
"unexpected character type");
3667 if (Index < S->getLength())
3680 AllocType.isNull() ? S->
getType() : AllocType);
3681 assert(CAT &&
"string literal isn't an array");
3683 assert(CharType->
isIntegerType() &&
"unexpected character type");
3690 if (Result.hasArrayFiller())
3692 for (
unsigned I = 0, N = Result.getArrayInitializedElts(); I != N; ++I) {
3700 unsigned Size = Array.getArraySize();
3701 assert(Index < Size);
3704 unsigned OldElts = Array.getArrayInitializedElts();
3705 unsigned NewElts = std::max(Index+1, OldElts * 2);
3706 NewElts = std::min(Size, std::max(NewElts, 8u));
3710 for (
unsigned I = 0; I != OldElts; ++I)
3712 for (
unsigned I = OldElts; I != NewElts; ++I)
3716 Array.
swap(NewValue);
3726 CXXRecordDecl *RD =
T->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
3737 for (
auto *Field : RD->
fields())
3738 if (!Field->isUnnamedBitField() &&
3742 for (
auto &BaseSpec : RD->
bases())
3753 CXXRecordDecl *RD =
T->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
3760 for (
auto *Field : RD->
fields()) {
3765 if (Field->isMutable() &&
3767 Info.FFDiag(E, diag::note_constexpr_access_mutable, 1) << AK << Field;
3768 Info.Note(Field->getLocation(), diag::note_declared_at);
3776 for (
auto &BaseSpec : RD->
bases())
3786 bool MutableSubobject =
false) {
3791 switch (Info.IsEvaluatingDecl) {
3792 case EvalInfo::EvaluatingDeclKind::None:
3795 case EvalInfo::EvaluatingDeclKind::Ctor:
3797 if (Info.EvaluatingDecl ==
Base)
3802 if (
auto *BaseE =
Base.dyn_cast<
const Expr *>())
3803 if (
auto *BaseMTE = dyn_cast<MaterializeTemporaryExpr>(BaseE))
3804 return Info.EvaluatingDecl == BaseMTE->getExtendingDecl();
3807 case EvalInfo::EvaluatingDeclKind::Dtor:
3812 if (MutableSubobject ||
Base != Info.EvaluatingDecl)
3818 return T.isConstQualified() ||
T->isReferenceType();
3821 llvm_unreachable(
"unknown evaluating decl kind");
3826 return Info.CheckArraySize(
3846 uint64_t IntResult = BoolResult;
3856 Result.getInt(), DestTy, Result2.
getFloat()))
3864 Result =
APValue(APFloat(0.0));
3866 DestTy, Result.getFloat());
3872 uint64_t IntResult = BoolResult;
3891 uint64_t IntResult = BoolResult;
3898 DestTy, Result.getInt());
3902 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
3915 {&Result, ResultType, 0}};
3918 while (!WorkList.empty() && ElI < Elements.size()) {
3919 auto [Res,
Type, BitWidth] = WorkList.pop_back_val();
3935 APSInt &Int = Res->getInt();
3936 unsigned OldBitWidth = Int.getBitWidth();
3937 unsigned NewBitWidth = BitWidth;
3938 if (NewBitWidth < OldBitWidth)
3939 Int = Int.trunc(NewBitWidth).extend(OldBitWidth);
3948 for (
unsigned I = 0; I < NumEl; ++I) {
3954 *Res =
APValue(Vals.data(), NumEl);
3963 for (int64_t I = Size - 1; I > -1; --I)
3964 WorkList.emplace_back(&Res->getArrayInitializedElt(I), ElTy, 0u);
3970 unsigned NumBases = 0;
3971 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
3972 NumBases = CXXRD->getNumBases();
3980 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
3981 if (CXXRD->getNumBases() > 0) {
3982 assert(CXXRD->getNumBases() == 1);
3984 ReverseList.emplace_back(&Res->getStructBase(0), BS.
getType(), 0u);
3991 if (FD->isUnnamedBitField())
3993 if (FD->isBitField()) {
3994 FDBW = FD->getBitWidthValue();
3997 ReverseList.emplace_back(&Res->getStructField(FD->getFieldIndex()),
3998 FD->getType(), FDBW);
4001 std::reverse(ReverseList.begin(), ReverseList.end());
4002 llvm::append_range(WorkList, ReverseList);
4005 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
4018 assert((Elements.size() == SrcTypes.size()) &&
4019 (Elements.size() == DestTypes.size()));
4021 for (
unsigned I = 0, ESz = Elements.size(); I < ESz; ++I) {
4022 APValue Original = Elements[I];
4026 if (!
handleScalarCast(Info, FPO, E, SourceTy, DestTy, Original, Results[I]))
4037 while (!WorkList.empty()) {
4054 for (uint64_t I = 0; I < ArrSize; ++I) {
4055 WorkList.push_back(ElTy);
4063 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4064 if (CXXRD->getNumBases() > 0) {
4065 assert(CXXRD->getNumBases() == 1);
4067 WorkList.push_back(BS.
getType());
4073 if (FD->isUnnamedBitField())
4075 WorkList.push_back(FD->getType());
4092 "Not a valid HLSLAggregateSplatCast.");
4107 unsigned Populated = 0;
4108 while (!WorkList.empty() && Populated < Size) {
4109 auto [Work,
Type] = WorkList.pop_back_val();
4111 if (Work.isFloat() || Work.isInt()) {
4112 Elements.push_back(Work);
4113 Types.push_back(
Type);
4117 if (Work.isVector()) {
4120 for (
unsigned I = 0; I < Work.getVectorLength() && Populated < Size;
4122 Elements.push_back(Work.getVectorElt(I));
4123 Types.push_back(ElTy);
4128 if (Work.isArray()) {
4132 for (int64_t I = Work.getArraySize() - 1; I > -1; --I) {
4133 WorkList.emplace_back(Work.getArrayInitializedElt(I), ElTy);
4138 if (Work.isStruct()) {
4146 if (FD->isUnnamedBitField())
4148 ReverseList.emplace_back(Work.getStructField(FD->getFieldIndex()),
4152 std::reverse(ReverseList.begin(), ReverseList.end());
4153 llvm::append_range(WorkList, ReverseList);
4156 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4157 if (CXXRD->getNumBases() > 0) {
4158 assert(CXXRD->getNumBases() == 1);
4163 if (!
Base.isStruct())
4171 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
4180struct CompleteObject {
4182 APValue::LValueBase
Base;
4192 bool mayAccessMutableMembers(EvalInfo &Info,
AccessKinds AK)
const {
4203 if (!Info.getLangOpts().CPlusPlus14 &&
4204 AK != AccessKinds::AK_IsWithinLifetime)
4209 explicit operator bool()
const {
return !
Type.isNull(); }
4214 bool IsMutable =
false) {
4228template <
typename Sub
objectHandler>
4229static typename SubobjectHandler::result_type
4231 const SubobjectDesignator &Sub, SubobjectHandler &handler) {
4234 return handler.failed();
4235 if (Sub.isOnePastTheEnd() || Sub.isMostDerivedAnUnsizedArray()) {
4236 if (Info.getLangOpts().CPlusPlus11)
4237 Info.FFDiag(E, Sub.isOnePastTheEnd()
4238 ? diag::note_constexpr_access_past_end
4239 : diag::note_constexpr_access_unsized_array)
4240 << handler.AccessKind;
4243 return handler.failed();
4249 const FieldDecl *VolatileField =
nullptr;
4252 for (
unsigned I = 0, N = Sub.Entries.size(); ; ++I) {
4263 if (!Info.checkingPotentialConstantExpression())
4264 Info.FFDiag(E, diag::note_constexpr_access_uninit)
4267 return handler.failed();
4275 Info.isEvaluatingCtorDtor(
4276 Obj.Base,
ArrayRef(Sub.Entries.begin(), Sub.Entries.begin() + I)) !=
4277 ConstructionPhase::None) {
4287 if (Info.getLangOpts().CPlusPlus) {
4291 if (VolatileField) {
4294 Decl = VolatileField;
4297 Loc = VD->getLocation();
4304 Info.FFDiag(E, diag::note_constexpr_access_volatile_obj, 1)
4305 << handler.AccessKind << DiagKind <<
Decl;
4306 Info.Note(Loc, diag::note_constexpr_volatile_here) << DiagKind;
4308 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
4310 return handler.failed();
4318 !Obj.mayAccessMutableMembers(Info, handler.AccessKind) &&
4320 return handler.failed();
4324 if (!handler.found(*O, ObjType))
4336 LastField =
nullptr;
4341 "vla in literal type?");
4342 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4343 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT);
4344 CAT && CAT->
getSize().ule(Index)) {
4347 if (Info.getLangOpts().CPlusPlus11)
4348 Info.FFDiag(E, diag::note_constexpr_access_past_end)
4349 << handler.AccessKind;
4352 return handler.failed();
4359 else if (!
isRead(handler.AccessKind)) {
4360 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT);
4362 return handler.failed();
4370 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4372 if (Info.getLangOpts().CPlusPlus11)
4373 Info.FFDiag(E, diag::note_constexpr_access_past_end)
4374 << handler.AccessKind;
4377 return handler.failed();
4383 assert(I == N - 1 &&
"extracting subobject of scalar?");
4393 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4394 unsigned NumElements = VT->getNumElements();
4395 if (Index == NumElements) {
4396 if (Info.getLangOpts().CPlusPlus11)
4397 Info.FFDiag(E, diag::note_constexpr_access_past_end)
4398 << handler.AccessKind;
4401 return handler.failed();
4404 if (Index > NumElements) {
4405 Info.CCEDiag(E, diag::note_constexpr_array_index)
4406 << Index << 0 << NumElements;
4407 return handler.failed();
4410 ObjType = VT->getElementType();
4411 assert(I == N - 1 &&
"extracting subobject of scalar?");
4413 }
else if (
const FieldDecl *Field = getAsField(Sub.Entries[I])) {
4414 if (Field->isMutable() &&
4415 !Obj.mayAccessMutableMembers(Info, handler.AccessKind)) {
4416 Info.FFDiag(E, diag::note_constexpr_access_mutable, 1)
4417 << handler.AccessKind << Field;
4418 Info.Note(Field->getLocation(), diag::note_declared_at);
4419 return handler.failed();
4428 if (I == N - 1 && handler.AccessKind ==
AK_Construct) {
4439 Info.FFDiag(E, diag::note_constexpr_access_inactive_union_member)
4440 << handler.AccessKind << Field << !UnionField << UnionField;
4441 return handler.failed();
4450 if (Field->getType().isVolatileQualified())
4451 VolatileField = Field;
4464struct ExtractSubobjectHandler {
4470 typedef bool result_type;
4471 bool failed() {
return false; }
4472 bool found(
APValue &Subobj, QualType SubobjType) {
4482 bool found(APFloat &
Value, QualType SubobjType) {
4491 const CompleteObject &Obj,
4492 const SubobjectDesignator &Sub,
APValue &Result,
4495 ExtractSubobjectHandler Handler = {Info, E, Result, AK};
4500struct ModifySubobjectHandler {
4505 typedef bool result_type;
4508 bool checkConst(QualType QT) {
4511 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
4517 bool failed() {
return false; }
4518 bool found(
APValue &Subobj, QualType SubobjType) {
4519 if (!checkConst(SubobjType))
4522 Subobj.
swap(NewVal);
4526 if (!checkConst(SubobjType))
4528 if (!NewVal.
isInt()) {
4536 bool found(APFloat &
Value, QualType SubobjType) {
4537 if (!checkConst(SubobjType))
4545const AccessKinds ModifySubobjectHandler::AccessKind;
4549 const CompleteObject &Obj,
4550 const SubobjectDesignator &Sub,
4552 ModifySubobjectHandler Handler = { Info, NewVal, E };
4559 const SubobjectDesignator &A,
4560 const SubobjectDesignator &B,
4561 bool &WasArrayIndex) {
4562 unsigned I = 0, N = std::min(A.Entries.size(), B.Entries.size());
4563 for (; I != N; ++I) {
4567 if (A.Entries[I].getAsArrayIndex() != B.Entries[I].getAsArrayIndex()) {
4568 WasArrayIndex =
true;
4576 if (A.Entries[I].getAsBaseOrMember() !=
4577 B.Entries[I].getAsBaseOrMember()) {
4578 WasArrayIndex =
false;
4581 if (
const FieldDecl *FD = getAsField(A.Entries[I]))
4583 ObjType = FD->getType();
4589 WasArrayIndex =
false;
4596 const SubobjectDesignator &A,
4597 const SubobjectDesignator &B) {
4598 if (A.Entries.size() != B.Entries.size())
4601 bool IsArray = A.MostDerivedIsArrayElement;
4602 if (IsArray && A.MostDerivedPathLength != A.Entries.size())
4611 return CommonLength >= A.Entries.size() - IsArray;
4618 if (LVal.InvalidBase) {
4620 return CompleteObject();
4625 Info.FFDiag(E, diag::note_constexpr_dereferencing_null);
4627 Info.FFDiag(E, diag::note_constexpr_access_null) << AK;
4628 return CompleteObject();
4631 CallStackFrame *Frame =
nullptr;
4633 if (LVal.getLValueCallIndex()) {
4634 std::tie(Frame, Depth) =
4635 Info.getCallFrameAndDepth(LVal.getLValueCallIndex());
4637 Info.FFDiag(E, diag::note_constexpr_lifetime_ended, 1)
4640 return CompleteObject();
4651 if (Info.getLangOpts().CPlusPlus)
4652 Info.FFDiag(E, diag::note_constexpr_access_volatile_type)
4656 return CompleteObject();
4663 if (Info.getLangOpts().CPlusPlus14 && LVal.Base == Info.EvaluatingDecl &&
4667 BaseVal = Info.EvaluatingDeclValue;
4670 if (
auto *GD = dyn_cast<MSGuidDecl>(D)) {
4673 Info.FFDiag(E, diag::note_constexpr_modify_global);
4674 return CompleteObject();
4678 Info.FFDiag(E, diag::note_constexpr_unsupported_layout)
4680 return CompleteObject();
4682 return CompleteObject(LVal.Base, &
V, GD->getType());
4686 if (
auto *GCD = dyn_cast<UnnamedGlobalConstantDecl>(D)) {
4688 Info.FFDiag(E, diag::note_constexpr_modify_global);
4689 return CompleteObject();
4691 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&GCD->getValue()),
4696 if (
auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
4698 Info.FFDiag(E, diag::note_constexpr_modify_global);
4699 return CompleteObject();
4701 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&TPO->getValue()),
4712 const VarDecl *VD = dyn_cast<VarDecl>(D);
4719 return CompleteObject();
4722 bool IsConstant = BaseType.isConstant(Info.Ctx);
4723 bool ConstexprVar =
false;
4724 if (
const auto *VD = dyn_cast_if_present<VarDecl>(
4736 }
else if (Info.getLangOpts().CPlusPlus14 &&
4743 Info.FFDiag(E, diag::note_constexpr_modify_global);
4744 return CompleteObject();
4747 }
else if (Info.getLangOpts().C23 && ConstexprVar) {
4749 return CompleteObject();
4750 }
else if (BaseType->isIntegralOrEnumerationType()) {
4753 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4754 if (Info.getLangOpts().CPlusPlus) {
4755 Info.FFDiag(E, diag::note_constexpr_ltor_non_const_int, 1) << VD;
4756 Info.Note(VD->
getLocation(), diag::note_declared_at);
4760 return CompleteObject();
4762 }
else if (!IsAccess) {
4763 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4764 }
else if ((IsConstant || BaseType->isReferenceType()) &&
4765 Info.checkingPotentialConstantExpression() &&
4766 BaseType->isLiteralType(Info.Ctx) && !VD->
hasDefinition()) {
4768 }
else if (IsConstant) {
4772 if (Info.getLangOpts().CPlusPlus) {
4773 Info.CCEDiag(E, Info.getLangOpts().CPlusPlus11
4774 ? diag::note_constexpr_ltor_non_constexpr
4775 : diag::note_constexpr_ltor_non_integral, 1)
4777 Info.Note(VD->
getLocation(), diag::note_declared_at);
4783 if (Info.getLangOpts().CPlusPlus) {
4784 Info.FFDiag(E, Info.getLangOpts().CPlusPlus11
4785 ? diag::note_constexpr_ltor_non_constexpr
4786 : diag::note_constexpr_ltor_non_integral, 1)
4788 Info.Note(VD->
getLocation(), diag::note_declared_at);
4792 return CompleteObject();
4801 return CompleteObject();
4806 if (!Info.checkingPotentialConstantExpression()) {
4807 Info.FFDiag(E, diag::note_constexpr_access_unknown_variable, 1)
4809 Info.Note(VD->getLocation(), diag::note_declared_at);
4811 return CompleteObject();
4814 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
4816 Info.FFDiag(E, diag::note_constexpr_access_deleted_object) << AK;
4817 return CompleteObject();
4819 return CompleteObject(LVal.Base, &(*Alloc)->Value,
4829 dyn_cast_or_null<MaterializeTemporaryExpr>(
Base)) {
4830 assert(MTE->getStorageDuration() ==
SD_Static &&
4831 "should have a frame for a non-global materialized temporary");
4858 if (!MTE->isUsableInConstantExpressions(Info.Ctx) &&
4861 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4862 Info.FFDiag(E, diag::note_constexpr_access_static_temporary, 1) << AK;
4863 Info.Note(MTE->getExprLoc(), diag::note_constexpr_temporary_here);
4864 return CompleteObject();
4867 BaseVal = MTE->getOrCreateValue(
false);
4868 assert(BaseVal &&
"got reference to unevaluated temporary");
4870 dyn_cast_or_null<CompoundLiteralExpr>(
Base)) {
4886 !CLETy.isConstant(Info.Ctx)) {
4888 Info.Note(CLE->getExprLoc(), diag::note_declared_at);
4889 return CompleteObject();
4892 BaseVal = &CLE->getStaticValue();
4895 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4898 Info.FFDiag(E, diag::note_constexpr_access_unreadable_object)
4903 return CompleteObject();
4907 assert(BaseVal &&
"missing value for temporary");
4918 unsigned VisibleDepth = Depth;
4919 if (llvm::isa_and_nonnull<ParmVarDecl>(
4922 if ((Frame && Info.getLangOpts().CPlusPlus14 &&
4924 (
isModification(AK) && VisibleDepth < Info.SpeculativeEvaluationDepth))
4925 return CompleteObject();
4927 return CompleteObject(LVal.getLValueBase(), BaseVal, BaseType);
4946 const LValue &LVal,
APValue &RVal,
4947 bool WantObjectRepresentation =
false) {
4948 if (LVal.Designator.Invalid)
4957 if (
Base && !LVal.getLValueCallIndex() && !
Type.isVolatileQualified()) {
4961 assert(LVal.Designator.Entries.size() <= 1 &&
4962 "Can only read characters from string literals");
4963 if (LVal.Designator.Entries.empty()) {
4970 if (LVal.Designator.isOnePastTheEnd()) {
4971 if (Info.getLangOpts().CPlusPlus11)
4972 Info.FFDiag(Conv, diag::note_constexpr_access_past_end) << AK;
4977 uint64_t CharIndex = LVal.Designator.Entries[0].getAsArrayIndex();
4984 return Obj &&
extractSubobject(Info, Conv, Obj, LVal.Designator, RVal, AK);
4998 LVal.setFrom(Info.Ctx, Val);
5014 if (LVal.Designator.Invalid)
5017 if (!Info.getLangOpts().CPlusPlus14) {
5027struct CompoundAssignSubobjectHandler {
5029 const CompoundAssignOperator *E;
5030 QualType PromotedLHSType;
5036 typedef bool result_type;
5038 bool checkConst(QualType QT) {
5041 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
5047 bool failed() {
return false; }
5048 bool found(
APValue &Subobj, QualType SubobjType) {
5051 return found(Subobj.
getInt(), SubobjType);
5053 return found(Subobj.
getFloat(), SubobjType);
5060 return foundPointer(Subobj, SubobjType);
5062 return foundVector(Subobj, SubobjType);
5064 Info.FFDiag(E, diag::note_constexpr_access_uninit)
5075 bool foundVector(
APValue &
Value, QualType SubobjType) {
5076 if (!checkConst(SubobjType))
5087 if (!checkConst(SubobjType))
5109 PromotedLHSType, FValue) &&
5118 bool found(APFloat &
Value, QualType SubobjType) {
5119 return checkConst(SubobjType) &&
5125 bool foundPointer(
APValue &Subobj, QualType SubobjType) {
5126 if (!checkConst(SubobjType))
5129 QualType PointeeType;
5130 if (
const PointerType *PT = SubobjType->
getAs<PointerType>())
5134 (Opcode != BO_Add && Opcode != BO_Sub)) {
5140 if (Opcode == BO_Sub)
5144 LVal.setFrom(Info.Ctx, Subobj);
5147 LVal.moveInto(Subobj);
5153const AccessKinds CompoundAssignSubobjectHandler::AccessKind;
5158 const LValue &LVal,
QualType LValType,
5162 if (LVal.Designator.Invalid)
5165 if (!Info.getLangOpts().CPlusPlus14) {
5171 CompoundAssignSubobjectHandler Handler = { Info, E, PromotedLValType, Opcode,
5173 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
5177struct IncDecSubobjectHandler {
5179 const UnaryOperator *E;
5183 typedef bool result_type;
5185 bool checkConst(QualType QT) {
5188 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
5194 bool failed() {
return false; }
5195 bool found(
APValue &Subobj, QualType SubobjType) {
5205 return found(Subobj.
getInt(), SubobjType);
5207 return found(Subobj.
getFloat(), SubobjType);
5210 SubobjType->
castAs<ComplexType>()->getElementType()
5214 SubobjType->
castAs<ComplexType>()->getElementType()
5217 return foundPointer(Subobj, SubobjType);
5225 if (!checkConst(SubobjType))
5247 bool WasNegative =
Value.isNegative();
5259 unsigned BitWidth =
Value.getBitWidth();
5260 APSInt ActualValue(
Value.sext(BitWidth + 1),
false);
5261 ActualValue.setBit(BitWidth);
5267 bool found(APFloat &
Value, QualType SubobjType) {
5268 if (!checkConst(SubobjType))
5275 APFloat::opStatus St;
5277 St =
Value.add(One, RM);
5279 St =
Value.subtract(One, RM);
5282 bool foundPointer(
APValue &Subobj, QualType SubobjType) {
5283 if (!checkConst(SubobjType))
5286 QualType PointeeType;
5287 if (
const PointerType *PT = SubobjType->
getAs<PointerType>())
5295 LVal.setFrom(Info.Ctx, Subobj);
5299 LVal.moveInto(Subobj);
5308 if (LVal.Designator.Invalid)
5311 if (!Info.getLangOpts().CPlusPlus14) {
5319 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
5325 if (Object->getType()->isPointerType() && Object->isPRValue())
5328 if (Object->isGLValue())
5331 if (Object->getType()->isLiteralType(Info.Ctx))
5334 if (Object->getType()->isRecordType() && Object->isPRValue())
5337 Info.FFDiag(Object, diag::note_constexpr_nonliteral) << Object->getType();
5356 bool IncludeMember =
true) {
5363 if (!MemPtr.getDecl()) {
5369 if (MemPtr.isDerivedMember()) {
5376 if (LV.Designator.MostDerivedPathLength + MemPtr.Path.size() >
5377 LV.Designator.Entries.size()) {
5381 unsigned PathLengthToMember =
5382 LV.Designator.Entries.size() - MemPtr.Path.size();
5383 for (
unsigned I = 0, N = MemPtr.Path.size(); I != N; ++I) {
5385 LV.Designator.Entries[PathLengthToMember + I]);
5402 (PathLengthToMember > LV.Designator.MostDerivedPathLength)
5403 ? getAsBaseClass(LV.Designator.Entries[PathLengthToMember - 1])
5405 const CXXRecordDecl *LastMPDecl = MemPtr.getContainingRecord();
5413 PathLengthToMember))
5415 }
else if (!MemPtr.Path.empty()) {
5417 LV.Designator.Entries.reserve(LV.Designator.Entries.size() +
5418 MemPtr.Path.size() + IncludeMember);
5424 assert(RD &&
"member pointer access on non-class-type expression");
5426 for (
unsigned I = 1, N = MemPtr.Path.size(); I != N; ++I) {
5434 MemPtr.getContainingRecord()))
5439 if (IncludeMember) {
5440 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(MemPtr.getDecl())) {
5444 dyn_cast<IndirectFieldDecl>(MemPtr.getDecl())) {
5448 llvm_unreachable(
"can't construct reference to bound member function");
5452 return MemPtr.getDecl();
5458 bool IncludeMember =
true) {
5462 if (Info.noteFailure()) {
5470 BO->
getRHS(), IncludeMember);
5477 SubobjectDesignator &D = Result.Designator;
5478 if (D.Invalid || !Result.checkNullPointer(Info, E,
CSK_Derived))
5485 auto InvalidCast = [&]() {
5486 if (!Info.checkingPotentialConstantExpression() ||
5487 !Result.AllowConstexprUnknown) {
5488 Info.CCEDiag(E, diag::note_constexpr_invalid_downcast)
5489 << D.MostDerivedType << TargetQT;
5495 if (D.MostDerivedPathLength + E->
path_size() > D.Entries.size())
5496 return InvalidCast();
5500 unsigned NewEntriesSize = D.Entries.size() - E->
path_size();
5503 if (NewEntriesSize == D.MostDerivedPathLength)
5506 FinalType = getAsBaseClass(D.Entries[NewEntriesSize - 1]);
5508 return InvalidCast();
5520 if (!Result.isAbsent())
5523 if (
auto *RD =
T->getAsCXXRecordDecl()) {
5524 if (RD->isInvalidDecl()) {
5528 if (RD->isUnion()) {
5533 std::distance(RD->field_begin(), RD->field_end()));
5537 End = RD->bases_end();
5538 I != End; ++I, ++Index)
5542 for (
const auto *I : RD->fields()) {
5543 if (I->isUnnamedBitField())
5546 I->getType(), Result.getStructField(I->getFieldIndex()));
5552 dyn_cast_or_null<ConstantArrayType>(
T->getAsArrayTypeUnsafe())) {
5554 if (Result.hasArrayFiller())
5566enum EvalStmtResult {
5595 if (!Result.Designator.Invalid && Result.Designator.isOnePastTheEnd()) {
5601 Result.moveInto(Val);
5613 APValue &Val = Info.CurrentCall->createTemporary(VD, VD->
getType(),
5614 ScopeKind::Block, Result);
5619 return Info.noteSideEffect();
5640 const DecompositionDecl *DD);
5643 bool EvaluateConditionDecl =
false) {
5645 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
5649 EvaluateConditionDecl && DD)
5659 if (
auto *VD = BD->getHoldingVar())
5667 if (
auto *DD = dyn_cast_if_present<DecompositionDecl>(VD)) {
5676 if (Info.noteSideEffect())
5678 assert(E->
containsErrors() &&
"valid value-dependent expression should never "
5679 "reach invalid code path.");
5686 if (
Cond->isValueDependent())
5688 FullExpressionRAII
Scope(Info);
5695 return Scope.destroy();
5708struct TempVersionRAII {
5709 CallStackFrame &Frame;
5711 TempVersionRAII(CallStackFrame &Frame) : Frame(Frame) {
5712 Frame.pushTempVersion();
5715 ~TempVersionRAII() {
5716 Frame.popTempVersion();
5724 const SwitchCase *SC =
nullptr);
5730 const Stmt *LoopOrSwitch,
5732 EvalStmtResult &ESR) {
5736 if (!IsSwitch && ESR == ESR_Succeeded) {
5741 if (ESR != ESR_Break && ESR != ESR_Continue)
5745 bool CanBreakOrContinue = !IsSwitch || ESR == ESR_Break;
5746 const Stmt *StackTop = Info.BreakContinueStack.back();
5747 if (CanBreakOrContinue && (StackTop ==
nullptr || StackTop == LoopOrSwitch)) {
5748 Info.BreakContinueStack.pop_back();
5749 if (ESR == ESR_Break)
5750 ESR = ESR_Succeeded;
5755 for (BlockScopeRAII *S : Scopes) {
5756 if (!S->destroy()) {
5768 BlockScopeRAII
Scope(Info);
5770 EvalStmtResult ESR =
EvaluateStmt(Result, Info, Body, Case);
5771 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5780 BlockScopeRAII
Scope(Info);
5787 if (ESR != ESR_Succeeded) {
5788 if (ESR != ESR_Failed && !
Scope.destroy())
5794 FullExpressionRAII CondScope(Info);
5809 if (!CondScope.destroy())
5830 if (LHSValue <=
Value &&
Value <= RHSValue) {
5837 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5841 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5848 llvm_unreachable(
"Should have been converted to Succeeded");
5854 case ESR_CaseNotFound:
5857 Info.FFDiag(
Found->getBeginLoc(),
5858 diag::note_constexpr_stmt_expr_unsupported);
5861 llvm_unreachable(
"Invalid EvalStmtResult!");
5871 Info.CCEDiag(VD->
getLocation(), diag::note_constexpr_static_local)
5881 if (!Info.nextStep(S))
5888 case Stmt::CompoundStmtClass:
5892 case Stmt::LabelStmtClass:
5893 case Stmt::AttributedStmtClass:
5894 case Stmt::DoStmtClass:
5897 case Stmt::CaseStmtClass:
5898 case Stmt::DefaultStmtClass:
5903 case Stmt::IfStmtClass: {
5910 BlockScopeRAII
Scope(Info);
5916 if (ESR != ESR_CaseNotFound) {
5917 assert(ESR != ESR_Succeeded);
5928 if (ESR == ESR_Failed)
5930 if (ESR != ESR_CaseNotFound)
5931 return Scope.destroy() ? ESR : ESR_Failed;
5933 return ESR_CaseNotFound;
5936 if (ESR == ESR_Failed)
5938 if (ESR != ESR_CaseNotFound)
5939 return Scope.destroy() ? ESR : ESR_Failed;
5940 return ESR_CaseNotFound;
5943 case Stmt::WhileStmtClass: {
5944 EvalStmtResult ESR =
5948 if (ESR != ESR_Continue)
5953 case Stmt::ForStmtClass: {
5955 BlockScopeRAII
Scope(Info);
5961 if (ESR != ESR_CaseNotFound) {
5962 assert(ESR != ESR_Succeeded);
5967 EvalStmtResult ESR =
5971 if (ESR != ESR_Continue)
5973 if (
const auto *Inc = FS->
getInc()) {
5974 if (Inc->isValueDependent()) {
5978 FullExpressionRAII IncScope(Info);
5986 case Stmt::DeclStmtClass: {
5990 for (
const auto *D : DS->
decls()) {
5991 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
5994 if (VD->hasLocalStorage() && !VD->getInit())
6002 return ESR_CaseNotFound;
6006 return ESR_CaseNotFound;
6012 if (
const Expr *E = dyn_cast<Expr>(S)) {
6021 FullExpressionRAII
Scope(Info);
6025 return ESR_Succeeded;
6031 case Stmt::NullStmtClass:
6032 return ESR_Succeeded;
6034 case Stmt::DeclStmtClass: {
6036 for (
const auto *D : DS->
decls()) {
6037 const VarDecl *VD = dyn_cast_or_null<VarDecl>(D);
6041 FullExpressionRAII
Scope(Info);
6043 !Info.noteFailure())
6045 if (!
Scope.destroy())
6048 return ESR_Succeeded;
6051 case Stmt::ReturnStmtClass: {
6053 FullExpressionRAII
Scope(Info);
6062 :
Evaluate(Result.Value, Info, RetExpr)))
6064 return Scope.destroy() ? ESR_Returned : ESR_Failed;
6067 case Stmt::CompoundStmtClass: {
6068 BlockScopeRAII
Scope(Info);
6071 for (
const auto *BI : CS->
body()) {
6072 EvalStmtResult ESR =
EvaluateStmt(Result, Info, BI, Case);
6073 if (ESR == ESR_Succeeded)
6075 else if (ESR != ESR_CaseNotFound) {
6076 if (ESR != ESR_Failed && !
Scope.destroy())
6082 return ESR_CaseNotFound;
6083 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
6086 case Stmt::IfStmtClass: {
6090 BlockScopeRAII
Scope(Info);
6093 if (ESR != ESR_Succeeded) {
6094 if (ESR != ESR_Failed && !
Scope.destroy())
6104 if (!Info.InConstantContext)
6111 EvalStmtResult ESR =
EvaluateStmt(Result, Info, SubStmt);
6112 if (ESR != ESR_Succeeded) {
6113 if (ESR != ESR_Failed && !
Scope.destroy())
6118 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
6121 case Stmt::WhileStmtClass: {
6124 BlockScopeRAII
Scope(Info);
6136 if (ESR != ESR_Continue) {
6137 if (ESR != ESR_Failed && !
Scope.destroy())
6141 if (!
Scope.destroy())
6144 return ESR_Succeeded;
6147 case Stmt::DoStmtClass: {
6154 if (ESR != ESR_Continue)
6163 FullExpressionRAII CondScope(Info);
6165 !CondScope.destroy())
6168 return ESR_Succeeded;
6171 case Stmt::ForStmtClass: {
6173 BlockScopeRAII ForScope(Info);
6176 if (ESR != ESR_Succeeded) {
6177 if (ESR != ESR_Failed && !ForScope.destroy())
6183 BlockScopeRAII IterScope(Info);
6184 bool Continue =
true;
6190 if (!IterScope.destroy())
6198 if (ESR != ESR_Continue) {
6199 if (ESR != ESR_Failed && (!IterScope.destroy() || !ForScope.destroy()))
6204 if (
const auto *Inc = FS->
getInc()) {
6205 if (Inc->isValueDependent()) {
6209 FullExpressionRAII IncScope(Info);
6215 if (!IterScope.destroy())
6218 return ForScope.destroy() ? ESR_Succeeded : ESR_Failed;
6221 case Stmt::CXXForRangeStmtClass: {
6223 BlockScopeRAII
Scope(Info);
6228 if (ESR != ESR_Succeeded) {
6229 if (ESR != ESR_Failed && !
Scope.destroy())
6237 if (ESR != ESR_Succeeded) {
6238 if (ESR != ESR_Failed && !
Scope.destroy())
6250 if (ESR != ESR_Succeeded) {
6251 if (ESR != ESR_Failed && !
Scope.destroy())
6256 if (ESR != ESR_Succeeded) {
6257 if (ESR != ESR_Failed && !
Scope.destroy())
6270 bool Continue =
true;
6271 FullExpressionRAII CondExpr(Info);
6279 BlockScopeRAII InnerScope(Info);
6281 if (ESR != ESR_Succeeded) {
6282 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
6291 if (ESR != ESR_Continue) {
6292 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
6305 if (!InnerScope.destroy())
6309 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
6312 case Stmt::SwitchStmtClass:
6315 case Stmt::ContinueStmtClass:
6316 case Stmt::BreakStmtClass: {
6318 Info.BreakContinueStack.push_back(B->getNamedLoopOrSwitch());
6322 case Stmt::LabelStmtClass:
6325 case Stmt::AttributedStmtClass: {
6327 const auto *SS = AS->getSubStmt();
6328 MSConstexprContextRAII ConstexprContext(
6332 auto LO = Info.getASTContext().getLangOpts();
6333 if (LO.CXXAssumptions && !LO.MSVCCompat) {
6334 for (
auto *
Attr : AS->getAttrs()) {
6335 auto *AA = dyn_cast<CXXAssumeAttr>(
Attr);
6339 auto *Assumption = AA->getAssumption();
6340 if (Assumption->isValueDependent())
6343 if (Assumption->HasSideEffects(Info.getASTContext()))
6350 Info.CCEDiag(Assumption->getExprLoc(),
6351 diag::note_constexpr_assumption_failed);
6360 case Stmt::CaseStmtClass:
6361 case Stmt::DefaultStmtClass:
6363 case Stmt::CXXTryStmtClass:
6375 bool IsValueInitialization) {
6382 if (!CD->
isConstexpr() && !IsValueInitialization) {
6383 if (Info.getLangOpts().CPlusPlus11) {
6386 Info.CCEDiag(Loc, diag::note_constexpr_invalid_function, 1)
6388 Info.Note(CD->
getLocation(), diag::note_declared_at);
6390 Info.CCEDiag(Loc, diag::note_invalid_subexpr_in_const_expr);
6404 if (Info.checkingPotentialConstantExpression() && !
Definition &&
6412 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6421 Info.CCEDiag(CallLoc, diag::note_constexpr_virtual_call);
6424 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6430 (
Definition->isConstexpr() || (Info.CurrentCall->CanEvalMSConstexpr &&
6440 StringRef Name = DiagDecl->
getName();
6442 Name ==
"__assert_rtn" || Name ==
"__assert_fail" || Name ==
"_wassert";
6444 Info.FFDiag(CallLoc, diag::note_constexpr_assert_failed);
6449 if (Info.getLangOpts().CPlusPlus11) {
6452 auto *CD = dyn_cast<CXXConstructorDecl>(DiagDecl);
6453 if (CD && CD->isInheritingConstructor()) {
6454 auto *Inherited = CD->getInheritedConstructor().getConstructor();
6455 if (!Inherited->isConstexpr())
6456 DiagDecl = CD = Inherited;
6462 if (CD && CD->isInheritingConstructor())
6463 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_inhctor, 1)
6464 << CD->getInheritedConstructor().getConstructor()->getParent();
6466 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_function, 1)
6468 Info.Note(DiagDecl->
getLocation(), diag::note_declared_at);
6470 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6476struct CheckDynamicTypeHandler {
6478 typedef bool result_type;
6479 bool failed() {
return false; }
6480 bool found(
APValue &Subobj, QualType SubobjType) {
return true; }
6481 bool found(
APSInt &
Value, QualType SubobjType) {
return true; }
6482 bool found(APFloat &
Value, QualType SubobjType) {
return true; }
6490 if (
This.Designator.Invalid)
6502 if (
This.Designator.isOnePastTheEnd() ||
6503 This.Designator.isMostDerivedAnUnsizedArray()) {
6504 Info.FFDiag(E,
This.Designator.isOnePastTheEnd()
6505 ? diag::note_constexpr_access_past_end
6506 : diag::note_constexpr_access_unsized_array)
6509 }
else if (Polymorphic) {
6512 if (!Info.checkingPotentialConstantExpression() ||
6513 !
This.AllowConstexprUnknown) {
6518 Info.FFDiag(E, diag::note_constexpr_polymorphic_unknown_dynamic_type)
6526 CheckDynamicTypeHandler Handler{AK};
6549 unsigned PathLength) {
6550 assert(PathLength >=
Designator.MostDerivedPathLength && PathLength <=
6551 Designator.Entries.size() &&
"invalid path length");
6552 return (PathLength ==
Designator.MostDerivedPathLength)
6553 ?
Designator.MostDerivedType->getAsCXXRecordDecl()
6554 : getAsBaseClass(
Designator.Entries[PathLength - 1]);
6567 return std::nullopt;
6569 if (
This.Designator.Invalid)
6570 return std::nullopt;
6579 This.Designator.MostDerivedType->getAsCXXRecordDecl();
6580 if (!Class || Class->getNumVBases()) {
6582 return std::nullopt;
6590 for (
unsigned PathLength =
This.Designator.MostDerivedPathLength;
6591 PathLength <= Path.size(); ++PathLength) {
6592 switch (Info.isEvaluatingCtorDtor(
This.getLValueBase(),
6593 Path.slice(0, PathLength))) {
6594 case ConstructionPhase::Bases:
6595 case ConstructionPhase::DestroyingBases:
6600 case ConstructionPhase::None:
6601 case ConstructionPhase::AfterBases:
6602 case ConstructionPhase::AfterFields:
6603 case ConstructionPhase::Destroying:
6615 return std::nullopt;
6633 unsigned PathLength = DynType->PathLength;
6634 for (; PathLength <=
This.Designator.Entries.size(); ++PathLength) {
6637 Found->getCorrespondingMethodDeclaredInClass(Class,
false);
6647 if (Callee->isPureVirtual()) {
6648 Info.FFDiag(E, diag::note_constexpr_pure_virtual_call, 1) << Callee;
6649 Info.Note(Callee->getLocation(), diag::note_declared_at);
6656 Found->getReturnType())) {
6657 CovariantAdjustmentPath.push_back(Callee->getReturnType());
6658 for (
unsigned CovariantPathLength = PathLength + 1;
6659 CovariantPathLength !=
This.Designator.Entries.size();
6660 ++CovariantPathLength) {
6664 Found->getCorrespondingMethodDeclaredInClass(NextClass,
false);
6666 Next->getReturnType(), CovariantAdjustmentPath.back()))
6667 CovariantAdjustmentPath.push_back(
Next->getReturnType());
6670 CovariantAdjustmentPath.back()))
6671 CovariantAdjustmentPath.push_back(
Found->getReturnType());
6687 assert(Result.isLValue() &&
6688 "unexpected kind of APValue for covariant return");
6689 if (Result.isNullPointer())
6693 LVal.setFrom(Info.Ctx, Result);
6695 const CXXRecordDecl *OldClass = Path[0]->getPointeeCXXRecordDecl();
6696 for (
unsigned I = 1; I != Path.size(); ++I) {
6697 const CXXRecordDecl *NewClass = Path[I]->getPointeeCXXRecordDecl();
6698 assert(OldClass && NewClass &&
"unexpected kind of covariant return");
6699 if (OldClass != NewClass &&
6702 OldClass = NewClass;
6705 LVal.moveInto(Result);
6714 auto *BaseClass = BaseSpec.getType()->getAsCXXRecordDecl();
6716 return BaseSpec.getAccessSpecifier() ==
AS_public;
6718 llvm_unreachable(
"Base is not a direct base of Derived");
6728 SubobjectDesignator &D = Ptr.Designator;
6734 if (Ptr.isNullPointer() && !E->
isGLValue())
6740 std::optional<DynamicType> DynType =
6752 assert(
C &&
"dynamic_cast target is not void pointer nor class");
6760 Ptr.setNull(Info.Ctx, E->
getType());
6767 DynType->Type->isDerivedFrom(
C)))
6769 else if (!Paths || Paths->begin() == Paths->end())
6771 else if (Paths->isAmbiguous(CQT))
6774 assert(Paths->front().Access !=
AS_public &&
"why did the cast fail?");
6777 Info.FFDiag(E, diag::note_constexpr_dynamic_cast_to_reference_failed)
6778 << DiagKind << Ptr.Designator.getType(Info.Ctx)
6787 for (
int PathLength = Ptr.Designator.Entries.size();
6788 PathLength >= (
int)DynType->PathLength; --PathLength) {
6793 if (PathLength > (
int)DynType->PathLength &&
6796 return RuntimeCheckFailed(
nullptr);
6803 if (DynType->Type->isDerivedFrom(
C, Paths) && !Paths.
isAmbiguous(CQT) &&
6816 return RuntimeCheckFailed(&Paths);
6820struct StartLifetimeOfUnionMemberHandler {
6822 const Expr *LHSExpr;
6823 const FieldDecl *
Field;
6825 bool Failed =
false;
6828 typedef bool result_type;
6829 bool failed() {
return Failed; }
6830 bool found(
APValue &Subobj, QualType SubobjType) {
6845 }
else if (DuringInit) {
6849 Info.FFDiag(LHSExpr,
6850 diag::note_constexpr_union_member_change_during_init);
6859 llvm_unreachable(
"wrong value kind for union object");
6861 bool found(APFloat &
Value, QualType SubobjType) {
6862 llvm_unreachable(
"wrong value kind for union object");
6867const AccessKinds StartLifetimeOfUnionMemberHandler::AccessKind;
6874 const Expr *LHSExpr,
6875 const LValue &LHS) {
6876 if (LHS.InvalidBase || LHS.Designator.Invalid)
6882 unsigned PathLength = LHS.Designator.Entries.size();
6883 for (
const Expr *E = LHSExpr; E !=
nullptr;) {
6885 if (
auto *ME = dyn_cast<MemberExpr>(E)) {
6886 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
6889 if (!FD || FD->getType()->isReferenceType())
6893 if (FD->getParent()->isUnion()) {
6898 FD->getType()->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
6899 if (!RD || RD->hasTrivialDefaultConstructor())
6900 UnionPathLengths.push_back({PathLength - 1, FD});
6906 LHS.Designator.Entries[PathLength]
6907 .getAsBaseOrMember().getPointer()));
6911 }
else if (
auto *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
6913 auto *
Base = ASE->getBase()->IgnoreImplicit();
6914 if (!
Base->getType()->isArrayType())
6920 }
else if (
auto *ICE = dyn_cast<ImplicitCastExpr>(E)) {
6923 if (ICE->getCastKind() == CK_NoOp)
6925 if (ICE->getCastKind() != CK_DerivedToBase &&
6926 ICE->getCastKind() != CK_UncheckedDerivedToBase)
6930 if (Elt->isVirtual()) {
6939 LHS.Designator.Entries[PathLength]
6940 .getAsBaseOrMember().getPointer()));
6950 if (UnionPathLengths.empty())
6955 CompleteObject Obj =
6959 for (std::pair<unsigned, const FieldDecl *> LengthAndField :
6960 llvm::reverse(UnionPathLengths)) {
6962 SubobjectDesignator D = LHS.Designator;
6963 D.truncate(Info.Ctx, LHS.Base, LengthAndField.first);
6965 bool DuringInit = Info.isEvaluatingCtorDtor(LHS.Base, D.Entries) ==
6966 ConstructionPhase::AfterBases;
6967 StartLifetimeOfUnionMemberHandler StartLifetime{
6968 Info, LHSExpr, LengthAndField.second, DuringInit};
6977 CallRef
Call, EvalInfo &Info,
bool NonNull =
false,
6978 APValue **EvaluatedArg =
nullptr) {
6985 APValue &
V = PVD ? Info.CurrentCall->createParam(
Call, PVD, LV)
6986 : Info.CurrentCall->createTemporary(Arg, Arg->
getType(),
6987 ScopeKind::Call, LV);
6993 if (
NonNull &&
V.isLValue() &&
V.isNullPointer()) {
6994 Info.CCEDiag(Arg, diag::note_non_null_attribute_failed);
7007 bool RightToLeft =
false,
7008 LValue *ObjectArg =
nullptr) {
7010 llvm::SmallBitVector ForbiddenNullArgs;
7011 if (Callee->hasAttr<NonNullAttr>()) {
7012 ForbiddenNullArgs.resize(Args.size());
7013 for (
const auto *
Attr : Callee->specific_attrs<NonNullAttr>()) {
7014 if (!
Attr->args_size()) {
7015 ForbiddenNullArgs.set();
7018 for (
auto Idx :
Attr->args()) {
7019 unsigned ASTIdx = Idx.getASTIndex();
7020 if (ASTIdx >= Args.size())
7022 ForbiddenNullArgs[ASTIdx] =
true;
7026 for (
unsigned I = 0; I < Args.size(); I++) {
7027 unsigned Idx = RightToLeft ? Args.size() - I - 1 : I;
7029 Idx < Callee->getNumParams() ? Callee->getParamDecl(Idx) :
nullptr;
7030 bool NonNull = !ForbiddenNullArgs.empty() && ForbiddenNullArgs[Idx];
7035 if (!Info.noteFailure())
7040 ObjectArg->setFrom(Info.Ctx, *That);
7049 bool CopyObjectRepresentation) {
7051 CallStackFrame *Frame = Info.CurrentCall;
7052 APValue *RefValue = Info.getParamSlot(Frame->Arguments, Param);
7060 RefLValue.setFrom(Info.Ctx, *RefValue);
7063 CopyObjectRepresentation);
7069 const LValue *ObjectArg,
const Expr *E,
7071 const Stmt *Body, EvalInfo &Info,
7072 APValue &Result,
const LValue *ResultSlot) {
7073 if (!Info.CheckCallLimit(CallLoc))
7102 ObjectArg->moveInto(Result);
7111 if (!Info.checkingPotentialConstantExpression())
7113 Frame.LambdaThisCaptureField);
7116 StmtResult Ret = {Result, ResultSlot};
7118 if (ESR == ESR_Succeeded) {
7119 if (Callee->getReturnType()->isVoidType())
7121 Info.FFDiag(Callee->getEndLoc(), diag::note_constexpr_no_return);
7123 return ESR == ESR_Returned;
7130 EvalInfo &Info,
APValue &Result) {
7132 if (!Info.CheckCallLimit(CallLoc))
7137 Info.FFDiag(CallLoc, diag::note_constexpr_virtual_base) << RD;
7141 EvalInfo::EvaluatingConstructorRAII EvalObj(
7143 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries},
7150 StmtResult Ret = {RetVal,
nullptr};
7155 if ((*I)->getInit()->isValueDependent()) {
7159 FullExpressionRAII InitScope(Info);
7161 !InitScope.destroy())
7184 if (!Result.hasValue()) {
7197 BlockScopeRAII LifetimeExtendedScope(Info);
7200 unsigned BasesSeen = 0;
7205 auto SkipToField = [&](
FieldDecl *FD,
bool Indirect) {
7210 assert(Indirect &&
"fields out of order?");
7216 assert(FieldIt != RD->
field_end() &&
"missing field?");
7217 if (!FieldIt->isUnnamedBitField())
7220 Result.getStructField(FieldIt->getFieldIndex()));
7225 LValue Subobject =
This;
7226 LValue SubobjectParent =
This;
7231 if (I->isBaseInitializer()) {
7232 QualType BaseType(I->getBaseClass(), 0);
7236 assert(!BaseIt->
isVirtual() &&
"virtual base for literal type");
7238 "base class initializers not in expected order");
7242 BaseType->getAsCXXRecordDecl(), &Layout))
7244 Value = &Result.getStructBase(BasesSeen++);
7245 }
else if ((FD = I->getMember())) {
7250 Value = &Result.getUnionValue();
7252 SkipToField(FD,
false);
7258 auto IndirectFieldChain = IFD->chain();
7259 for (
auto *
C : IndirectFieldChain) {
7268 (
Value->isUnion() &&
7281 if (
C == IndirectFieldChain.back())
7282 SubobjectParent = Subobject;
7288 if (
C == IndirectFieldChain.front() && !RD->
isUnion())
7289 SkipToField(FD,
true);
7294 llvm_unreachable(
"unknown base initializer kind");
7301 if (
Init->isValueDependent()) {
7305 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &SubobjectParent,
7307 FullExpressionRAII InitScope(Info);
7313 if (!Info.noteFailure())
7322 if (!Info.noteFailure())
7330 if (I->isBaseInitializer() && BasesSeen == RD->
getNumBases())
7331 EvalObj.finishedConstructingBases();
7336 for (; FieldIt != RD->
field_end(); ++FieldIt) {
7337 if (!FieldIt->isUnnamedBitField())
7340 Result.getStructField(FieldIt->getFieldIndex()));
7344 EvalObj.finishedConstructingFields();
7348 LifetimeExtendedScope.destroy();
7354 EvalInfo &Info,
APValue &Result) {
7355 CallScopeRAII CallScope(Info);
7361 CallScope.destroy();
7371 if (
Value.isAbsent() && !
T->isNullPtrType()) {
7373 This.moveInto(Printable);
7375 diag::note_constexpr_destroy_out_of_lifetime)
7392 LValue ElemLV =
This;
7393 ElemLV.addArray(Info, &LocE, CAT);
7400 if (Size && Size >
Value.getArrayInitializedElts())
7405 for (Size =
Value.getArraySize(); Size != 0; --Size) {
7406 APValue &Elem =
Value.getArrayInitializedElt(Size - 1);
7419 if (
T.isDestructedType()) {
7421 diag::note_constexpr_unsupported_destruction)
7431 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_virtual_base) << RD;
7456 if (!Info.CheckCallLimit(CallRange.
getBegin()))
7465 CallStackFrame Frame(Info, CallRange,
Definition, &
This,
nullptr,
7470 EvalInfo::EvaluatingDestructorRAII EvalObj(
7472 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries});
7473 if (!EvalObj.DidInsert) {
7480 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_double_destroy);
7487 StmtResult Ret = {RetVal,
nullptr};
7500 for (
const FieldDecl *FD : llvm::reverse(Fields)) {
7501 if (FD->isUnnamedBitField())
7504 LValue Subobject =
This;
7508 APValue *SubobjectValue = &
Value.getStructField(FD->getFieldIndex());
7515 EvalObj.startedDestroyingBases();
7522 LValue Subobject =
This;
7524 BaseType->getAsCXXRecordDecl(), &Layout))
7527 APValue *SubobjectValue = &
Value.getStructBase(BasesLeft);
7532 assert(BasesLeft == 0 &&
"NumBases was wrong?");
7540struct DestroyObjectHandler {
7546 typedef bool result_type;
7547 bool failed() {
return false; }
7548 bool found(
APValue &Subobj, QualType SubobjType) {
7553 Info.FFDiag(E, diag::note_constexpr_destroy_complex_elem);
7556 bool found(APFloat &
Value, QualType SubobjType) {
7557 Info.FFDiag(E, diag::note_constexpr_destroy_complex_elem);
7589 if (Info.checkingPotentialConstantExpression() ||
7590 Info.SpeculativeEvaluationDepth)
7594 auto Caller = Info.getStdAllocatorCaller(
"allocate");
7596 Info.FFDiag(E->
getExprLoc(), Info.getLangOpts().CPlusPlus20
7597 ? diag::note_constexpr_new_untyped
7598 : diag::note_constexpr_new);
7602 QualType ElemType = Caller.ElemType;
7605 diag::note_constexpr_new_not_complete_object_type)
7613 bool IsNothrow =
false;
7614 for (
unsigned I = 1, N = E->
getNumArgs(); I != N; ++I) {
7622 APInt Size, Remainder;
7623 APInt ElemSizeAP(ByteSize.getBitWidth(), ElemSize.
getQuantity());
7624 APInt::udivrem(ByteSize, ElemSizeAP, Size, Remainder);
7625 if (Remainder != 0) {
7627 Info.FFDiag(E->
getExprLoc(), diag::note_constexpr_operator_new_bad_size)
7628 << ByteSize <<
APSInt(ElemSizeAP,
true) << ElemType;
7632 if (!Info.CheckArraySize(E->
getBeginLoc(), ByteSize.getActiveBits(),
7633 Size.getZExtValue(), !IsNothrow)) {
7635 Result.setNull(Info.Ctx, E->
getType());
7643 APValue *Val = Info.createHeapAlloc(Caller.Call, AllocType, Result);
7652 return DD->isVirtual();
7659 return DD->isVirtual() ? DD->getOperatorDelete() :
nullptr;
7670 DynAlloc::Kind DeallocKind) {
7671 auto PointerAsString = [&] {
7677 Info.FFDiag(E, diag::note_constexpr_delete_not_heap_alloc)
7678 << PointerAsString();
7681 return std::nullopt;
7684 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
7686 Info.FFDiag(E, diag::note_constexpr_double_delete);
7687 return std::nullopt;
7690 if (DeallocKind != (*Alloc)->getKind()) {
7692 Info.FFDiag(E, diag::note_constexpr_new_delete_mismatch)
7693 << DeallocKind << (*Alloc)->getKind() << AllocType;
7695 return std::nullopt;
7698 bool Subobject =
false;
7699 if (DeallocKind == DynAlloc::New) {
7700 Subobject =
Pointer.Designator.MostDerivedPathLength != 0 ||
7701 Pointer.Designator.isOnePastTheEnd();
7703 Subobject =
Pointer.Designator.Entries.size() != 1 ||
7704 Pointer.Designator.Entries[0].getAsArrayIndex() != 0;
7707 Info.FFDiag(E, diag::note_constexpr_delete_subobject)
7708 << PointerAsString() <<
Pointer.Designator.isOnePastTheEnd();
7709 return std::nullopt;
7717 if (Info.checkingPotentialConstantExpression() ||
7718 Info.SpeculativeEvaluationDepth)
7722 if (!Info.getStdAllocatorCaller(
"deallocate")) {
7730 for (
unsigned I = 1, N = E->
getNumArgs(); I != N; ++I)
7733 if (
Pointer.Designator.Invalid)
7738 if (
Pointer.isNullPointer()) {
7739 Info.CCEDiag(E->
getExprLoc(), diag::note_constexpr_deallocate_null);
7755class BitCastBuffer {
7761 SmallVector<std::optional<unsigned char>, 32> Bytes;
7763 static_assert(std::numeric_limits<unsigned char>::digits >= 8,
7764 "Need at least 8 bit unsigned char");
7766 bool TargetIsLittleEndian;
7769 BitCastBuffer(CharUnits Width,
bool TargetIsLittleEndian)
7770 : Bytes(Width.getQuantity()),
7771 TargetIsLittleEndian(TargetIsLittleEndian) {}
7773 [[nodiscard]]
bool readObject(CharUnits Offset, CharUnits Width,
7774 SmallVectorImpl<unsigned char> &Output)
const {
7775 for (CharUnits I = Offset, E = Offset + Width; I != E; ++I) {
7778 if (!Bytes[I.getQuantity()])
7780 Output.push_back(*Bytes[I.getQuantity()]);
7782 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
7783 std::reverse(Output.begin(), Output.end());
7787 void writeObject(CharUnits Offset, SmallVectorImpl<unsigned char> &Input) {
7788 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
7789 std::reverse(Input.begin(), Input.end());
7792 for (
unsigned char Byte : Input) {
7793 assert(!Bytes[Offset.
getQuantity() + Index] &&
"overwriting a byte?");
7799 size_t size() {
return Bytes.size(); }
7804class APValueToBufferConverter {
7806 BitCastBuffer Buffer;
7809 APValueToBufferConverter(EvalInfo &Info, CharUnits ObjectWidth,
7812 Buffer(ObjectWidth, Info.Ctx.getTargetInfo().isLittleEndian()),
7815 bool visit(
const APValue &Val, QualType Ty) {
7820 bool visit(
const APValue &Val, QualType Ty, CharUnits Offset) {
7821 assert((
size_t)Offset.
getQuantity() <= Buffer.size());
7834 return visitInt(Val.
getInt(), Ty, Offset);
7836 return visitFloat(Val.
getFloat(), Ty, Offset);
7838 return visitArray(Val, Ty, Offset);
7840 return visitRecord(Val, Ty, Offset);
7842 return visitVector(Val, Ty, Offset);
7846 return visitComplex(Val, Ty, Offset);
7854 diag::note_constexpr_bit_cast_unsupported_type)
7860 llvm_unreachable(
"LValue subobject in bit_cast?");
7862 llvm_unreachable(
"Unhandled APValue::ValueKind");
7865 bool visitRecord(
const APValue &Val, QualType Ty, CharUnits Offset) {
7870 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
7871 for (
size_t I = 0, E = CXXRD->getNumBases(); I != E; ++I) {
7872 const CXXBaseSpecifier &BS = CXXRD->bases_begin()[I];
7877 if (!
Base.isStruct())
7880 if (!visitRecord(Base, BS.
getType(),
7887 unsigned FieldIdx = 0;
7888 for (FieldDecl *FD : RD->
fields()) {
7889 if (FD->isBitField()) {
7891 diag::note_constexpr_bit_cast_unsupported_bitfield);
7897 assert(FieldOffsetBits % Info.Ctx.
getCharWidth() == 0 &&
7898 "only bit-fields can have sub-char alignment");
7899 CharUnits FieldOffset =
7901 QualType FieldTy = FD->getType();
7910 bool visitArray(
const APValue &Val, QualType Ty, CharUnits Offset) {
7920 for (
unsigned I = 0; I != NumInitializedElts; ++I) {
7922 if (!visit(SubObj, CAT->
getElementType(), Offset + I * ElemWidth))
7929 for (
unsigned I = NumInitializedElts; I != ArraySize; ++I) {
7930 if (!visit(Filler, CAT->
getElementType(), Offset + I * ElemWidth))
7938 bool visitComplex(
const APValue &Val, QualType Ty, CharUnits Offset) {
7939 const ComplexType *ComplexTy = Ty->
castAs<ComplexType>();
7946 Offset + (0 * EltSizeChars)))
7949 Offset + (1 * EltSizeChars)))
7953 Offset + (0 * EltSizeChars)))
7956 Offset + (1 * EltSizeChars)))
7963 bool visitVector(
const APValue &Val, QualType Ty, CharUnits Offset) {
7964 const VectorType *VTy = Ty->
castAs<VectorType>();
7979 llvm::APInt Res = llvm::APInt::getZero(NElts);
7980 for (
unsigned I = 0; I < NElts; ++I) {
7982 assert(EltAsInt.isUnsigned() && EltAsInt.getBitWidth() == 1 &&
7983 "bool vector element must be 1-bit unsigned integer!");
7985 Res.insertBits(EltAsInt, BigEndian ? (NElts - I - 1) : I);
7988 SmallVector<uint8_t, 8> Bytes(NElts / 8);
7989 llvm::StoreIntToMemory(Res, &*Bytes.begin(), NElts / 8);
7990 Buffer.writeObject(Offset, Bytes);
7995 for (
unsigned I = 0; I < NElts; ++I) {
7996 if (!visit(Val.
getVectorElt(I), EltTy, Offset + I * EltSizeChars))
8004 bool visitInt(
const APSInt &Val, QualType Ty, CharUnits Offset) {
8005 APSInt AdjustedVal = Val;
8006 unsigned Width = AdjustedVal.getBitWidth();
8009 AdjustedVal = AdjustedVal.extend(Width);
8012 SmallVector<uint8_t, 8> Bytes(Width / 8);
8013 llvm::StoreIntToMemory(AdjustedVal, &*Bytes.begin(), Width / 8);
8014 Buffer.writeObject(Offset, Bytes);
8018 bool visitFloat(
const APFloat &Val, QualType Ty, CharUnits Offset) {
8019 APSInt AsInt(Val.bitcastToAPInt());
8020 return visitInt(AsInt, Ty, Offset);
8024 static std::optional<BitCastBuffer>
8027 APValueToBufferConverter Converter(Info, DstSize, BCE);
8029 return std::nullopt;
8030 return Converter.Buffer;
8035class BufferToAPValueConverter {
8037 const BitCastBuffer &Buffer;
8040 BufferToAPValueConverter(EvalInfo &Info,
const BitCastBuffer &Buffer,
8042 : Info(Info), Buffer(Buffer), BCE(BCE) {}
8047 std::nullopt_t unsupportedType(QualType Ty) {
8049 diag::note_constexpr_bit_cast_unsupported_type)
8051 return std::nullopt;
8054 std::nullopt_t unrepresentableValue(QualType Ty,
const APSInt &Val) {
8056 diag::note_constexpr_bit_cast_unrepresentable_value)
8058 return std::nullopt;
8061 std::optional<APValue> visit(
const BuiltinType *
T, CharUnits Offset,
8062 const EnumType *EnumSugar =
nullptr) {
8065 return APValue((Expr *)
nullptr,
8067 APValue::NoLValuePath{},
true);
8076 const llvm::fltSemantics &Semantics =
8078 unsigned NumBits = llvm::APFloatBase::getSizeInBits(Semantics);
8079 assert(NumBits % 8 == 0);
8085 SmallVector<uint8_t, 8> Bytes;
8086 if (!Buffer.readObject(Offset,
SizeOf, Bytes)) {
8089 bool IsStdByte = EnumSugar && EnumSugar->isStdByteType();
8093 if (!IsStdByte && !IsUChar) {
8094 QualType DisplayType(EnumSugar ? (
const Type *)EnumSugar :
T, 0);
8096 diag::note_constexpr_bit_cast_indet_dest)
8097 << DisplayType << Info.Ctx.
getLangOpts().CharIsSigned;
8098 return std::nullopt;
8105 llvm::LoadIntFromMemory(Val, &*Bytes.begin(), Bytes.size());
8110 unsigned IntWidth = Info.Ctx.
getIntWidth(QualType(
T, 0));
8111 if (IntWidth != Val.getBitWidth()) {
8112 APSInt Truncated = Val.trunc(IntWidth);
8113 if (Truncated.extend(Val.getBitWidth()) != Val)
8114 return unrepresentableValue(QualType(
T, 0), Val);
8122 const llvm::fltSemantics &Semantics =
8127 return unsupportedType(QualType(
T, 0));
8130 std::optional<APValue> visit(
const RecordType *RTy, CharUnits Offset) {
8131 const RecordDecl *RD = RTy->getAsRecordDecl();
8134 unsigned NumBases = 0;
8135 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
8136 NumBases = CXXRD->getNumBases();
8138 APValue ResultVal(APValue::UninitStruct(), NumBases,
8142 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
8143 for (
size_t I = 0, E = CXXRD->getNumBases(); I != E; ++I) {
8144 const CXXBaseSpecifier &BS = CXXRD->bases_begin()[I];
8147 std::optional<APValue> SubObj = visitType(
8150 return std::nullopt;
8151 ResultVal.getStructBase(I) = *SubObj;
8156 unsigned FieldIdx = 0;
8157 for (FieldDecl *FD : RD->
fields()) {
8160 if (FD->isBitField()) {
8162 diag::note_constexpr_bit_cast_unsupported_bitfield);
8163 return std::nullopt;
8167 assert(FieldOffsetBits % Info.Ctx.
getCharWidth() == 0);
8169 CharUnits FieldOffset =
8172 QualType FieldTy = FD->getType();
8173 std::optional<APValue> SubObj = visitType(FieldTy, FieldOffset);
8175 return std::nullopt;
8176 ResultVal.getStructField(FieldIdx) = *SubObj;
8183 std::optional<APValue> visit(
const EnumType *Ty, CharUnits Offset) {
8184 QualType RepresentationType =
8185 Ty->getDecl()->getDefinitionOrSelf()->getIntegerType();
8186 assert(!RepresentationType.
isNull() &&
8187 "enum forward decl should be caught by Sema");
8188 const auto *AsBuiltin =
8192 return visit(AsBuiltin, Offset, Ty);
8195 std::optional<APValue> visit(
const ConstantArrayType *Ty, CharUnits Offset) {
8199 APValue ArrayValue(APValue::UninitArray(), Size, Size);
8200 for (
size_t I = 0; I !=
Size; ++I) {
8201 std::optional<APValue> ElementValue =
8204 return std::nullopt;
8205 ArrayValue.getArrayInitializedElt(I) = std::move(*ElementValue);
8211 std::optional<APValue> visit(
const ComplexType *Ty, CharUnits Offset) {
8216 std::optional<APValue> Values[2];
8217 for (
unsigned I = 0; I != 2; ++I) {
8218 Values[I] = visitType(Ty->
getElementType(), Offset + I * ElementWidth);
8220 return std::nullopt;
8224 return APValue(Values[0]->getInt(), Values[1]->getInt());
8225 return APValue(Values[0]->getFloat(), Values[1]->getFloat());
8228 std::optional<APValue> visit(
const VectorType *VTy, CharUnits Offset) {
8234 SmallVector<APValue, 4> Elts;
8235 Elts.reserve(NElts);
8247 SmallVector<uint8_t, 8> Bytes;
8248 Bytes.reserve(NElts / 8);
8250 return std::nullopt;
8252 APSInt SValInt(NElts,
true);
8253 llvm::LoadIntFromMemory(SValInt, &*Bytes.begin(), Bytes.size());
8255 for (
unsigned I = 0; I < NElts; ++I) {
8257 SValInt.extractBits(1, (BigEndian ? NElts - I - 1 : I) * EltSize);
8265 for (
unsigned I = 0; I < NElts; ++I) {
8266 std::optional<APValue> EltValue =
8267 visitType(EltTy, Offset + I * EltSizeChars);
8269 return std::nullopt;
8270 Elts.push_back(std::move(*EltValue));
8274 return APValue(Elts.data(), Elts.size());
8277 std::optional<APValue> visit(
const Type *Ty, CharUnits Offset) {
8278 return unsupportedType(QualType(Ty, 0));
8281 std::optional<APValue> visitType(QualType Ty, CharUnits Offset) {
8285#define TYPE(Class, Base) \
8287 return visit(cast<Class##Type>(Can.getTypePtr()), Offset);
8288#define ABSTRACT_TYPE(Class, Base)
8289#define NON_CANONICAL_TYPE(Class, Base) \
8291 llvm_unreachable("non-canonical type should be impossible!");
8292#define DEPENDENT_TYPE(Class, Base) \
8295 "dependent types aren't supported in the constant evaluator!");
8296#define NON_CANONICAL_UNLESS_DEPENDENT(Class, Base) \
8298 llvm_unreachable("either dependent or not canonical!");
8299#include "clang/AST/TypeNodes.inc"
8301 llvm_unreachable(
"Unhandled Type::TypeClass");
8306 static std::optional<APValue> convert(EvalInfo &Info, BitCastBuffer &Buffer,
8308 BufferToAPValueConverter Converter(Info, Buffer, BCE);
8313static bool checkBitCastConstexprEligibilityType(SourceLocation Loc,
8314 QualType Ty, EvalInfo *Info,
8315 const ASTContext &Ctx,
8316 bool CheckingDest) {
8319 auto diag = [&](
int Reason) {
8321 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_invalid_type)
8322 << CheckingDest << (Reason == 4) << Reason;
8325 auto note = [&](
int Construct, QualType NoteTy, SourceLocation NoteLoc) {
8327 Info->Note(NoteLoc, diag::note_constexpr_bit_cast_invalid_subtype)
8328 << NoteTy << Construct << Ty;
8342 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(
Record)) {
8343 for (CXXBaseSpecifier &BS : CXXRD->bases())
8344 if (!checkBitCastConstexprEligibilityType(Loc, BS.
getType(), Info, Ctx,
8348 for (FieldDecl *FD :
Record->fields()) {
8349 if (FD->getType()->isReferenceType())
8351 if (!checkBitCastConstexprEligibilityType(Loc, FD->getType(), Info, Ctx,
8353 return note(0, FD->getType(), FD->getBeginLoc());
8359 Info, Ctx, CheckingDest))
8362 if (
const auto *VTy = Ty->
getAs<VectorType>()) {
8374 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_invalid_vector)
8375 << QualType(VTy, 0) << EltSize << NElts << Ctx.
getCharWidth();
8385 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_unsupported_type)
8394static bool checkBitCastConstexprEligibility(EvalInfo *Info,
8395 const ASTContext &Ctx,
8397 bool DestOK = checkBitCastConstexprEligibilityType(
8399 bool SourceOK = DestOK && checkBitCastConstexprEligibilityType(
8405static bool handleRValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
8409 "no host or target supports non 8-bit chars");
8411 if (!checkBitCastConstexprEligibility(&Info, Info.Ctx, BCE))
8415 std::optional<BitCastBuffer> Buffer =
8416 APValueToBufferConverter::convert(Info, SourceRValue, BCE);
8421 std::optional<APValue> MaybeDestValue =
8422 BufferToAPValueConverter::convert(Info, *Buffer, BCE);
8423 if (!MaybeDestValue)
8426 DestValue = std::move(*MaybeDestValue);
8430static bool handleLValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
8434 "no host or target supports non 8-bit chars");
8436 "LValueToRValueBitcast requires an lvalue operand!");
8438 LValue SourceLValue;
8440 SourceLValue.setFrom(Info.Ctx, SourceValue);
8443 SourceRValue,
true))
8446 return handleRValueToRValueBitCast(Info, DestValue, SourceRValue, BCE);
8449template <
class Derived>
8450class ExprEvaluatorBase
8451 :
public ConstStmtVisitor<Derived, bool> {
8453 Derived &getDerived() {
return static_cast<Derived&
>(*this); }
8454 bool DerivedSuccess(
const APValue &
V,
const Expr *E) {
8455 return getDerived().Success(
V, E);
8457 bool DerivedZeroInitialization(
const Expr *E) {
8458 return getDerived().ZeroInitialization(E);
8464 template<
typename ConditionalOperator>
8465 void CheckPotentialConstantConditional(
const ConditionalOperator *E) {
8466 assert(Info.checkingPotentialConstantExpression());
8469 SmallVector<PartialDiagnosticAt, 8>
Diag;
8471 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
8478 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
8485 Error(E, diag::note_constexpr_conditional_never_const);
8489 template<
typename ConditionalOperator>
8490 bool HandleConditionalOperator(
const ConditionalOperator *E) {
8493 if (Info.checkingPotentialConstantExpression() && Info.noteFailure()) {
8494 CheckPotentialConstantConditional(E);
8497 if (Info.noteFailure()) {
8505 return StmtVisitorTy::Visit(EvalExpr);
8510 typedef ConstStmtVisitor<Derived, bool> StmtVisitorTy;
8511 typedef ExprEvaluatorBase ExprEvaluatorBaseTy;
8513 OptionalDiagnostic CCEDiag(
const Expr *E,
diag::kind D) {
8514 return Info.CCEDiag(E, D);
8517 bool ZeroInitialization(
const Expr *E) {
return Error(E); }
8519 bool IsConstantEvaluatedBuiltinCall(
const CallExpr *E) {
8521 return BuiltinOp != 0 &&
8526 ExprEvaluatorBase(EvalInfo &Info) : Info(Info) {}
8528 EvalInfo &getEvalInfo() {
return Info; }
8536 bool Error(
const Expr *E) {
8537 return Error(E, diag::note_invalid_subexpr_in_const_expr);
8540 bool VisitStmt(
const Stmt *) {
8541 llvm_unreachable(
"Expression evaluator should not be called on stmts");
8543 bool VisitExpr(
const Expr *E) {
8547 bool VisitEmbedExpr(
const EmbedExpr *E) {
8548 const auto It = E->
begin();
8549 return StmtVisitorTy::Visit(*It);
8552 bool VisitPredefinedExpr(
const PredefinedExpr *E) {
8555 bool VisitConstantExpr(
const ConstantExpr *E) {
8559 return StmtVisitorTy::Visit(E->
getSubExpr());
8562 bool VisitParenExpr(
const ParenExpr *E)
8563 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8564 bool VisitUnaryExtension(
const UnaryOperator *E)
8565 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8566 bool VisitUnaryPlus(
const UnaryOperator *E)
8567 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8568 bool VisitChooseExpr(
const ChooseExpr *E)
8570 bool VisitGenericSelectionExpr(
const GenericSelectionExpr *E)
8572 bool VisitSubstNonTypeTemplateParmExpr(
const SubstNonTypeTemplateParmExpr *E)
8574 bool VisitCXXDefaultArgExpr(
const CXXDefaultArgExpr *E) {
8575 TempVersionRAII RAII(*Info.CurrentCall);
8576 SourceLocExprScopeGuard Guard(E, Info.CurrentCall->CurSourceLocExprScope);
8577 return StmtVisitorTy::Visit(E->
getExpr());
8579 bool VisitCXXDefaultInitExpr(
const CXXDefaultInitExpr *E) {
8580 TempVersionRAII RAII(*Info.CurrentCall);
8584 SourceLocExprScopeGuard Guard(E, Info.CurrentCall->CurSourceLocExprScope);
8585 return StmtVisitorTy::Visit(E->
getExpr());
8588 bool VisitExprWithCleanups(
const ExprWithCleanups *E) {
8589 FullExpressionRAII Scope(Info);
8590 return StmtVisitorTy::Visit(E->
getSubExpr()) && Scope.destroy();
8595 bool VisitCXXBindTemporaryExpr(
const CXXBindTemporaryExpr *E) {
8596 return StmtVisitorTy::Visit(E->
getSubExpr());
8599 bool VisitCXXReinterpretCastExpr(
const CXXReinterpretCastExpr *E) {
8600 CCEDiag(E, diag::note_constexpr_invalid_cast)
8601 << diag::ConstexprInvalidCastKind::Reinterpret;
8602 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8604 bool VisitCXXDynamicCastExpr(
const CXXDynamicCastExpr *E) {
8606 CCEDiag(E, diag::note_constexpr_invalid_cast)
8607 << diag::ConstexprInvalidCastKind::Dynamic;
8608 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8610 bool VisitBuiltinBitCastExpr(
const BuiltinBitCastExpr *E) {
8611 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8614 bool VisitBinaryOperator(
const BinaryOperator *E) {
8620 VisitIgnoredValue(E->
getLHS());
8621 return StmtVisitorTy::Visit(E->
getRHS());
8631 return DerivedSuccess(
Result, E);
8636 bool VisitCXXRewrittenBinaryOperator(
const CXXRewrittenBinaryOperator *E) {
8640 bool VisitBinaryConditionalOperator(
const BinaryConditionalOperator *E) {
8644 if (!
Evaluate(Info.CurrentCall->createTemporary(
8647 ScopeKind::FullExpression, CommonLV),
8651 return HandleConditionalOperator(E);
8654 bool VisitConditionalOperator(
const ConditionalOperator *E) {
8655 bool IsBcpCall =
false;
8660 if (
const CallExpr *CallCE =
8662 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
8669 if (Info.checkingPotentialConstantExpression() && IsBcpCall)
8672 FoldConstant Fold(Info, IsBcpCall);
8673 if (!HandleConditionalOperator(E)) {
8674 Fold.keepDiagnostics();
8681 bool VisitOpaqueValueExpr(
const OpaqueValueExpr *E) {
8682 if (
APValue *
Value = Info.CurrentCall->getCurrentTemporary(E);
8684 return DerivedSuccess(*
Value, E);
8690 assert(0 &&
"OpaqueValueExpr recursively refers to itself");
8693 return StmtVisitorTy::Visit(Source);
8696 bool VisitPseudoObjectExpr(
const PseudoObjectExpr *E) {
8697 for (
const Expr *SemE : E->
semantics()) {
8698 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
8707 if (OVE->isUnique())
8711 if (!
Evaluate(Info.CurrentCall->createTemporary(
8712 OVE, getStorageType(Info.Ctx, OVE),
8713 ScopeKind::FullExpression, LV),
8714 Info, OVE->getSourceExpr()))
8717 if (!StmtVisitorTy::Visit(SemE))
8727 bool VisitCallExpr(
const CallExpr *E) {
8729 if (!handleCallExpr(E,
Result,
nullptr))
8731 return DerivedSuccess(
Result, E);
8735 const LValue *ResultSlot) {
8736 CallScopeRAII CallScope(Info);
8739 QualType CalleeType =
Callee->getType();
8741 const FunctionDecl *FD =
nullptr;
8742 LValue *
This =
nullptr, ObjectArg;
8744 bool HasQualifier =
false;
8750 const CXXMethodDecl *
Member =
nullptr;
8751 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(Callee)) {
8755 Member = dyn_cast<CXXMethodDecl>(ME->getMemberDecl());
8757 return Error(Callee);
8759 HasQualifier = ME->hasQualifier();
8760 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(Callee)) {
8762 const ValueDecl *D =
8766 Member = dyn_cast<CXXMethodDecl>(D);
8768 return Error(Callee);
8770 }
else if (
const auto *PDE = dyn_cast<CXXPseudoDestructorExpr>(Callee)) {
8771 if (!Info.getLangOpts().CPlusPlus20)
8772 Info.CCEDiag(PDE, diag::note_constexpr_pseudo_destructor);
8776 return Error(Callee);
8783 if (!CalleeLV.getLValueOffset().isZero())
8784 return Error(Callee);
8785 if (CalleeLV.isNullPointer()) {
8786 Info.FFDiag(Callee, diag::note_constexpr_null_callee)
8787 <<
const_cast<Expr *
>(
Callee);
8790 FD = dyn_cast_or_null<FunctionDecl>(
8791 CalleeLV.getLValueBase().dyn_cast<
const ValueDecl *>());
8793 return Error(Callee);
8803 auto *OCE = dyn_cast<CXXOperatorCallExpr>(E);
8804 if (OCE && OCE->isAssignmentOp()) {
8805 assert(Args.size() == 2 &&
"wrong number of arguments in assignment");
8806 Call = Info.CurrentCall->createCall(FD);
8807 bool HasThis =
false;
8808 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FD))
8809 HasThis = MD->isImplicitObjectMemberFunction();
8817 const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD);
8837 if (Info.getLangOpts().CPlusPlus20 && OCE &&
8838 OCE->getOperator() == OO_Equal && MD->
isTrivial() &&
8842 Args = Args.slice(1);
8848 const CXXRecordDecl *ClosureClass = MD->
getParent();
8850 ClosureClass->
captures().empty() &&
8851 "Number of captures must be zero for conversion to function-ptr");
8853 const CXXMethodDecl *LambdaCallOp =
8862 "A generic lambda's static-invoker function must be a "
8863 "template specialization");
8865 FunctionTemplateDecl *CallOpTemplate =
8867 void *InsertPos =
nullptr;
8868 FunctionDecl *CorrespondingCallOpSpecialization =
8870 assert(CorrespondingCallOpSpecialization &&
8871 "We must always have a function call operator specialization "
8872 "that corresponds to our static invoker specialization");
8874 FD = CorrespondingCallOpSpecialization;
8883 return CallScope.destroy();
8893 Call = Info.CurrentCall->createCall(FD);
8899 SmallVector<QualType, 4> CovariantAdjustmentPath;
8901 auto *NamedMember = dyn_cast<CXXMethodDecl>(FD);
8902 if (NamedMember && NamedMember->isVirtual() && !HasQualifier) {
8905 CovariantAdjustmentPath);
8908 }
else if (NamedMember && NamedMember->isImplicitObjectMemberFunction()) {
8918 if (
auto *DD = dyn_cast<CXXDestructorDecl>(FD)) {
8919 assert(This &&
"no 'this' pointer for destructor call");
8922 CallScope.destroy();
8939 if (!CovariantAdjustmentPath.empty() &&
8941 CovariantAdjustmentPath))
8944 return CallScope.destroy();
8947 bool VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E) {
8950 bool VisitInitListExpr(
const InitListExpr *E) {
8952 return DerivedZeroInitialization(E);
8954 return StmtVisitorTy::Visit(E->
getInit(0));
8957 bool VisitImplicitValueInitExpr(
const ImplicitValueInitExpr *E) {
8958 return DerivedZeroInitialization(E);
8960 bool VisitCXXScalarValueInitExpr(
const CXXScalarValueInitExpr *E) {
8961 return DerivedZeroInitialization(E);
8963 bool VisitCXXNullPtrLiteralExpr(
const CXXNullPtrLiteralExpr *E) {
8964 return DerivedZeroInitialization(E);
8968 bool VisitMemberExpr(
const MemberExpr *E) {
8970 "missing temporary materialization conversion");
8971 assert(!E->
isArrow() &&
"missing call to bound member function?");
8979 const FieldDecl *FD = dyn_cast<FieldDecl>(E->
getMemberDecl());
8980 if (!FD)
return Error(E);
8984 "record / field mismatch");
8989 CompleteObject Obj(APValue::LValueBase(), &Val, BaseTy);
8990 SubobjectDesignator Designator(BaseTy);
8991 Designator.addDeclUnchecked(FD);
8995 DerivedSuccess(
Result, E);
8998 bool VisitExtVectorElementExpr(
const ExtVectorElementExpr *E) {
9004 SmallVector<uint32_t, 4> Indices;
9006 if (Indices.size() == 1) {
9008 return DerivedSuccess(Val.
getVectorElt(Indices[0]), E);
9011 SmallVector<APValue, 4> Elts;
9012 for (
unsigned I = 0; I < Indices.size(); ++I) {
9015 APValue VecResult(Elts.data(), Indices.size());
9016 return DerivedSuccess(VecResult, E);
9023 bool VisitCastExpr(
const CastExpr *E) {
9028 case CK_AtomicToNonAtomic: {
9035 return DerivedSuccess(AtomicVal, E);
9039 case CK_UserDefinedConversion:
9040 return StmtVisitorTy::Visit(E->
getSubExpr());
9042 case CK_HLSLArrayRValue: {
9048 return DerivedSuccess(Val, E);
9059 return DerivedSuccess(RVal, E);
9061 case CK_LValueToRValue: {
9070 return DerivedSuccess(RVal, E);
9072 case CK_LValueToRValueBitCast: {
9073 APValue DestValue, SourceValue;
9076 if (!handleLValueToRValueBitCast(Info, DestValue, SourceValue, E))
9078 return DerivedSuccess(DestValue, E);
9081 case CK_AddressSpaceConversion: {
9085 return DerivedSuccess(
Value, E);
9092 bool VisitUnaryPostInc(
const UnaryOperator *UO) {
9093 return VisitUnaryPostIncDec(UO);
9095 bool VisitUnaryPostDec(
const UnaryOperator *UO) {
9096 return VisitUnaryPostIncDec(UO);
9098 bool VisitUnaryPostIncDec(
const UnaryOperator *UO) {
9099 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9109 return DerivedSuccess(RVal, UO);
9112 bool VisitStmtExpr(
const StmtExpr *E) {
9115 llvm::SaveAndRestore NotCheckingForUB(Info.CheckingForUndefinedBehavior,
9122 BlockScopeRAII Scope(Info);
9127 const Expr *FinalExpr = dyn_cast<Expr>(*BI);
9129 Info.FFDiag((*BI)->getBeginLoc(),
9130 diag::note_constexpr_stmt_expr_unsupported);
9133 return this->Visit(FinalExpr) && Scope.destroy();
9139 if (ESR != ESR_Succeeded) {
9143 if (ESR != ESR_Failed)
9144 Info.FFDiag((*BI)->getBeginLoc(),
9145 diag::note_constexpr_stmt_expr_unsupported);
9150 llvm_unreachable(
"Return from function from the loop above.");
9153 bool VisitPackIndexingExpr(
const PackIndexingExpr *E) {
9158 void VisitIgnoredValue(
const Expr *E) {
9163 void VisitIgnoredBaseExpression(
const Expr *E) {
9166 if (Info.getLangOpts().MSVCCompat && !E->
HasSideEffects(Info.Ctx))
9168 VisitIgnoredValue(E);
9178template<
class Derived>
9179class LValueExprEvaluatorBase
9180 :
public ExprEvaluatorBase<Derived> {
9184 typedef LValueExprEvaluatorBase LValueExprEvaluatorBaseTy;
9185 typedef ExprEvaluatorBase<Derived> ExprEvaluatorBaseTy;
9187 bool Success(APValue::LValueBase B) {
9192 bool evaluatePointer(
const Expr *E, LValue &
Result) {
9197 LValueExprEvaluatorBase(EvalInfo &Info, LValue &
Result,
bool InvalidBaseOK)
9199 InvalidBaseOK(InvalidBaseOK) {}
9202 Result.setFrom(this->Info.Ctx,
V);
9206 bool VisitMemberExpr(
const MemberExpr *E) {
9218 EvalOK = this->Visit(E->
getBase());
9229 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(E->
getMemberDecl())) {
9232 "record / field mismatch");
9236 }
else if (
const IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(MD)) {
9240 return this->
Error(E);
9252 bool VisitBinaryOperator(
const BinaryOperator *E) {
9255 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
9263 bool VisitCastExpr(
const CastExpr *E) {
9266 return ExprEvaluatorBaseTy::VisitCastExpr(E);
9268 case CK_DerivedToBase:
9269 case CK_UncheckedDerivedToBase:
9316class LValueExprEvaluator
9317 :
public LValueExprEvaluatorBase<LValueExprEvaluator> {
9319 LValueExprEvaluator(EvalInfo &Info, LValue &
Result,
bool InvalidBaseOK) :
9320 LValueExprEvaluatorBaseTy(Info,
Result, InvalidBaseOK) {}
9322 bool VisitVarDecl(
const Expr *E,
const VarDecl *VD);
9323 bool VisitUnaryPreIncDec(
const UnaryOperator *UO);
9325 bool VisitCallExpr(
const CallExpr *E);
9326 bool VisitDeclRefExpr(
const DeclRefExpr *E);
9327 bool VisitPredefinedExpr(
const PredefinedExpr *E) {
return Success(E); }
9328 bool VisitMaterializeTemporaryExpr(
const MaterializeTemporaryExpr *E);
9329 bool VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E);
9330 bool VisitMemberExpr(
const MemberExpr *E);
9331 bool VisitStringLiteral(
const StringLiteral *E) {
9332 return Success(APValue::LValueBase(
9333 E, 0, Info.getASTContext().getNextStringLiteralVersion()));
9335 bool VisitObjCEncodeExpr(
const ObjCEncodeExpr *E) {
return Success(E); }
9336 bool VisitCXXTypeidExpr(
const CXXTypeidExpr *E);
9337 bool VisitCXXUuidofExpr(
const CXXUuidofExpr *E);
9338 bool VisitArraySubscriptExpr(
const ArraySubscriptExpr *E);
9339 bool VisitExtVectorElementExpr(
const ExtVectorElementExpr *E);
9340 bool VisitUnaryDeref(
const UnaryOperator *E);
9341 bool VisitUnaryReal(
const UnaryOperator *E);
9342 bool VisitUnaryImag(
const UnaryOperator *E);
9343 bool VisitUnaryPreInc(
const UnaryOperator *UO) {
9344 return VisitUnaryPreIncDec(UO);
9346 bool VisitUnaryPreDec(
const UnaryOperator *UO) {
9347 return VisitUnaryPreIncDec(UO);
9349 bool VisitBinAssign(
const BinaryOperator *BO);
9350 bool VisitCompoundAssignOperator(
const CompoundAssignOperator *CAO);
9352 bool VisitCastExpr(
const CastExpr *E) {
9355 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
9357 case CK_LValueBitCast:
9358 this->CCEDiag(E, diag::note_constexpr_invalid_cast)
9359 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
9363 Result.Designator.setInvalid();
9366 case CK_BaseToDerived:
9383 bool LValueToRValueConversion) {
9387 assert(Info.CurrentCall->This ==
nullptr &&
9388 "This should not be set for a static call operator");
9396 if (
Self->getType()->isReferenceType()) {
9397 APValue *RefValue = Info.getParamSlot(Info.CurrentCall->Arguments,
Self);
9399 Result.setFrom(Info.Ctx, *RefValue);
9401 const ParmVarDecl *VD = Info.CurrentCall->Arguments.getOrigParam(
Self);
9402 CallStackFrame *Frame =
9403 Info.getCallFrameAndDepth(Info.CurrentCall->Arguments.CallIndex)
9405 unsigned Version = Info.CurrentCall->Arguments.Version;
9406 Result.set({VD, Frame->Index, Version});
9409 Result = *Info.CurrentCall->This;
9419 if (LValueToRValueConversion) {
9423 Result.setFrom(Info.Ctx, RVal);
9434 bool InvalidBaseOK) {
9438 return LValueExprEvaluator(Info, Result, InvalidBaseOK).Visit(E);
9441bool LValueExprEvaluator::VisitDeclRefExpr(
const DeclRefExpr *E) {
9442 const ValueDecl *D = E->
getDecl();
9454 if (Info.checkingPotentialConstantExpression())
9457 if (
auto *FD = Info.CurrentCall->LambdaCaptureFields.lookup(D)) {
9464 if (
isa<FunctionDecl, MSGuidDecl, TemplateParamObjectDecl,
9465 UnnamedGlobalConstantDecl>(D))
9467 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
9468 return VisitVarDecl(E, VD);
9469 if (
const BindingDecl *BD = dyn_cast<BindingDecl>(D))
9470 return Visit(BD->getBinding());
9474bool LValueExprEvaluator::VisitVarDecl(
const Expr *E,
const VarDecl *VD) {
9475 CallStackFrame *Frame =
nullptr;
9476 unsigned Version = 0;
9484 CallStackFrame *CurrFrame = Info.CurrentCall;
9489 if (
auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
9490 if (CurrFrame->Arguments) {
9491 VD = CurrFrame->Arguments.getOrigParam(PVD);
9493 Info.getCallFrameAndDepth(CurrFrame->Arguments.CallIndex).first;
9494 Version = CurrFrame->Arguments.Version;
9498 Version = CurrFrame->getCurrentTemporaryVersion(VD);
9505 Result.set({VD, Frame->Index, Version});
9511 if (!Info.getLangOpts().CPlusPlus11) {
9512 Info.CCEDiag(E, diag::note_constexpr_ltor_non_integral, 1)
9514 Info.Note(VD->
getLocation(), diag::note_declared_at);
9523 Result.AllowConstexprUnknown =
true;
9530bool LValueExprEvaluator::VisitCallExpr(
const CallExpr *E) {
9531 if (!IsConstantEvaluatedBuiltinCall(E))
9532 return ExprEvaluatorBaseTy::VisitCallExpr(E);
9537 case Builtin::BIas_const:
9538 case Builtin::BIforward:
9539 case Builtin::BIforward_like:
9540 case Builtin::BImove:
9541 case Builtin::BImove_if_noexcept:
9543 return Visit(E->
getArg(0));
9547 return ExprEvaluatorBaseTy::VisitCallExpr(E);
9550bool LValueExprEvaluator::VisitMaterializeTemporaryExpr(
9551 const MaterializeTemporaryExpr *E) {
9559 for (
const Expr *E : CommaLHSs)
9568 if (Info.EvalMode == EvaluationMode::ConstantFold)
9575 Value = &Info.CurrentCall->createTemporary(
9591 for (
unsigned I = Adjustments.size(); I != 0; ) {
9593 switch (Adjustments[I].Kind) {
9598 Type = Adjustments[I].DerivedToBase.BasePath->getType();
9604 Type = Adjustments[I].Field->getType();
9609 Adjustments[I].Ptr.RHS))
9611 Type = Adjustments[I].Ptr.MPT->getPointeeType();
9620LValueExprEvaluator::VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E) {
9621 assert((!Info.getLangOpts().CPlusPlus || E->
isFileScope()) &&
9622 "lvalue compound literal in c++?");
9634 assert(!Info.getLangOpts().CPlusPlus);
9636 ScopeKind::Block,
Result);
9648bool LValueExprEvaluator::VisitCXXTypeidExpr(
const CXXTypeidExpr *E) {
9649 TypeInfoLValue TypeInfo;
9658 Info.CCEDiag(E, diag::note_constexpr_typeid_polymorphic)
9666 std::optional<DynamicType> DynType =
9671 TypeInfo = TypeInfoLValue(
9678bool LValueExprEvaluator::VisitCXXUuidofExpr(
const CXXUuidofExpr *E) {
9682bool LValueExprEvaluator::VisitMemberExpr(
const MemberExpr *E) {
9684 if (
const VarDecl *VD = dyn_cast<VarDecl>(E->
getMemberDecl())) {
9685 VisitIgnoredBaseExpression(E->
getBase());
9686 return VisitVarDecl(E, VD);
9690 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(E->
getMemberDecl())) {
9691 if (MD->isStatic()) {
9692 VisitIgnoredBaseExpression(E->
getBase());
9698 return LValueExprEvaluatorBaseTy::VisitMemberExpr(E);
9701bool LValueExprEvaluator::VisitExtVectorElementExpr(
9702 const ExtVectorElementExpr *E) {
9707 if (!Info.noteFailure())
9715 if (Indices.size() > 1)
9719 Result.setFrom(Info.Ctx, Val);
9723 const auto *VT = BaseType->
castAs<VectorType>();
9725 VT->getNumElements(), Indices[0]);
9731bool LValueExprEvaluator::VisitArraySubscriptExpr(
const ArraySubscriptExpr *E) {
9741 if (!Info.noteFailure())
9747 if (!Info.noteFailure())
9753 Result.setFrom(Info.Ctx, Val);
9755 VT->getNumElements(), Index.getExtValue());
9763 for (
const Expr *SubExpr : {E->
getLHS(), E->
getRHS()}) {
9764 if (SubExpr == E->
getBase() ? !evaluatePointer(SubExpr,
Result)
9766 if (!Info.noteFailure())
9776bool LValueExprEvaluator::VisitUnaryDeref(
const UnaryOperator *E) {
9787 Info.noteUndefinedBehavior();
9790bool LValueExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
9799bool LValueExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
9801 "lvalue __imag__ on scalar?");
9808bool LValueExprEvaluator::VisitUnaryPreIncDec(
const UnaryOperator *UO) {
9809 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9820bool LValueExprEvaluator::VisitCompoundAssignOperator(
9821 const CompoundAssignOperator *CAO) {
9822 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9830 if (!Info.noteFailure())
9845bool LValueExprEvaluator::VisitBinAssign(
const BinaryOperator *E) {
9846 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9854 if (!Info.noteFailure())
9862 if (Info.getLangOpts().CPlusPlus20 &&
9878 llvm::APInt &Result) {
9879 assert(isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
9880 "Can't get the size of a non alloc_size function");
9881 const auto *
Base = LVal.getLValueBase().get<
const Expr *>();
9883 std::optional<llvm::APInt> Size =
9884 CE->evaluateBytesReturnedByAllocSizeCall(Ctx);
9888 Result = std::move(*Size);
9907 dyn_cast_or_null<VarDecl>(
Base.dyn_cast<
const ValueDecl *>());
9912 if (!
Init ||
Init->getType().isNull())
9915 const Expr *E =
Init->IgnoreParens();
9916 if (!tryUnwrapAllocSizeCall(E))
9921 Result.setInvalid(E);
9924 Result.addUnsizedArray(Info, E, Pointee);
9929class PointerExprEvaluator
9930 :
public ExprEvaluatorBase<PointerExprEvaluator> {
9939 bool evaluateLValue(
const Expr *E, LValue &
Result) {
9943 bool evaluatePointer(
const Expr *E, LValue &
Result) {
9947 bool visitNonBuiltinCallExpr(
const CallExpr *E);
9950 PointerExprEvaluator(EvalInfo &info, LValue &
Result,
bool InvalidBaseOK)
9952 InvalidBaseOK(InvalidBaseOK) {}
9958 bool ZeroInitialization(
const Expr *E) {
9963 bool VisitBinaryOperator(
const BinaryOperator *E);
9964 bool VisitCastExpr(
const CastExpr* E);
9965 bool VisitUnaryAddrOf(
const UnaryOperator *E);
9966 bool VisitObjCStringLiteral(
const ObjCStringLiteral *E)
9968 bool VisitObjCBoxedExpr(
const ObjCBoxedExpr *E) {
9971 if (Info.noteFailure())
9975 bool VisitAddrLabelExpr(
const AddrLabelExpr *E)
9977 bool VisitCallExpr(
const CallExpr *E);
9978 bool VisitBuiltinCallExpr(
const CallExpr *E,
unsigned BuiltinOp);
9979 bool VisitBlockExpr(
const BlockExpr *E) {
9984 bool VisitCXXThisExpr(
const CXXThisExpr *E) {
9985 auto DiagnoseInvalidUseOfThis = [&] {
9986 if (Info.getLangOpts().CPlusPlus11)
9987 Info.FFDiag(E, diag::note_constexpr_this) << E->
isImplicit();
9993 if (Info.checkingPotentialConstantExpression())
9996 bool IsExplicitLambda =
9998 if (!IsExplicitLambda) {
9999 if (!Info.CurrentCall->This) {
10000 DiagnoseInvalidUseOfThis();
10004 Result = *Info.CurrentCall->This;
10012 if (!Info.CurrentCall->LambdaThisCaptureField) {
10013 if (IsExplicitLambda && !Info.CurrentCall->This) {
10014 DiagnoseInvalidUseOfThis();
10023 Info, E,
Result, MD, Info.CurrentCall->LambdaThisCaptureField,
10029 bool VisitCXXNewExpr(
const CXXNewExpr *E);
10031 bool VisitSourceLocExpr(
const SourceLocExpr *E) {
10032 assert(!E->
isIntType() &&
"SourceLocExpr isn't a pointer type?");
10034 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.
getDefaultExpr());
10035 Result.setFrom(Info.Ctx, LValResult);
10039 bool VisitEmbedExpr(
const EmbedExpr *E) {
10040 llvm::report_fatal_error(
"Not yet implemented for ExprConstant.cpp");
10044 bool VisitSYCLUniqueStableNameExpr(
const SYCLUniqueStableNameExpr *E) {
10045 std::string ResultStr = E->
ComputeName(Info.Ctx);
10049 ResultStr.size() + 1);
10051 CharTy, Size,
nullptr, ArraySizeModifier::Normal, 0);
10053 StringLiteral *SL =
10054 StringLiteral::Create(Info.Ctx, ResultStr, StringLiteralKind::Ordinary,
10057 evaluateLValue(SL,
Result);
10067 bool InvalidBaseOK) {
10070 return PointerExprEvaluator(Info, Result, InvalidBaseOK).Visit(E);
10073bool PointerExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
10076 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
10078 const Expr *PExp = E->
getLHS();
10079 const Expr *IExp = E->
getRHS();
10081 std::swap(PExp, IExp);
10083 bool EvalPtrOK = evaluatePointer(PExp,
Result);
10084 if (!EvalPtrOK && !Info.noteFailure())
10087 llvm::APSInt Offset;
10098bool PointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
10107 if (!FnII || !FnII->
isStr(
"current"))
10110 const auto *RD = dyn_cast<RecordDecl>(FD->
getParent());
10118bool PointerExprEvaluator::VisitCastExpr(
const CastExpr *E) {
10125 case CK_CPointerToObjCPointerCast:
10126 case CK_BlockPointerToObjCPointerCast:
10127 case CK_AnyPointerToBlockPointerCast:
10128 case CK_AddressSpaceConversion:
10129 if (!Visit(SubExpr))
10135 CCEDiag(E, diag::note_constexpr_invalid_cast)
10136 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
10138 Result.Designator.setInvalid();
10146 bool HasValidResult = !
Result.InvalidBase && !
Result.Designator.Invalid &&
10148 bool VoidPtrCastMaybeOK =
10160 if (VoidPtrCastMaybeOK &&
10161 (Info.getStdAllocatorCaller(
"allocate") ||
10163 Info.getLangOpts().CPlusPlus26)) {
10167 Info.getLangOpts().CPlusPlus) {
10168 if (HasValidResult)
10169 CCEDiag(E, diag::note_constexpr_invalid_void_star_cast)
10170 << SubExpr->
getType() << Info.getLangOpts().CPlusPlus26
10171 <<
Result.Designator.getType(Info.Ctx).getCanonicalType()
10174 CCEDiag(E, diag::note_constexpr_invalid_cast)
10175 << diag::ConstexprInvalidCastKind::CastFrom
10178 CCEDiag(E, diag::note_constexpr_invalid_cast)
10179 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
10181 Result.Designator.setInvalid();
10185 ZeroInitialization(E);
10188 case CK_DerivedToBase:
10189 case CK_UncheckedDerivedToBase:
10201 case CK_BaseToDerived:
10213 case CK_NullToPointer:
10215 return ZeroInitialization(E);
10217 case CK_IntegralToPointer: {
10218 CCEDiag(E, diag::note_constexpr_invalid_cast)
10219 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
10226 if (
Value.isInt()) {
10228 uint64_t N =
Value.getInt().extOrTrunc(Size).getZExtValue();
10232 Result.Base = (Expr *)
nullptr;
10233 Result.InvalidBase =
false;
10235 Result.Designator.setInvalid();
10236 Result.IsNullPtr =
false;
10244 if (!
Value.isLValue())
10253 case CK_ArrayToPointerDecay: {
10255 if (!evaluateLValue(SubExpr,
Result))
10259 SubExpr, SubExpr->
getType(), ScopeKind::FullExpression,
Result);
10265 if (
auto *CAT = dyn_cast<ConstantArrayType>(AT))
10266 Result.addArray(Info, E, CAT);
10268 Result.addUnsizedArray(Info, E, AT->getElementType());
10272 case CK_FunctionToPointerDecay:
10273 return evaluateLValue(SubExpr,
Result);
10275 case CK_LValueToRValue: {
10284 return InvalidBaseOK &&
10290 return ExprEvaluatorBaseTy::VisitCastExpr(E);
10298 T =
T.getNonReferenceType();
10300 if (
T.getQualifiers().hasUnaligned())
10303 const bool AlignOfReturnsPreferred =
10304 Ctx.
getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver7;
10309 if (ExprKind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
10312 else if (ExprKind == UETT_AlignOf)
10315 llvm_unreachable(
"GetAlignOfType on a non-alignment ExprKind");
10328 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
10332 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(E))
10342 if (
const auto *E =
Value.Base.dyn_cast<
const Expr *>())
10350 EvalInfo &Info,
APSInt &Alignment) {
10353 if (Alignment < 0 || !Alignment.isPowerOf2()) {
10354 Info.FFDiag(E, diag::note_constexpr_invalid_alignment) << Alignment;
10357 unsigned SrcWidth = Info.Ctx.
getIntWidth(ForType);
10358 APSInt MaxValue(APInt::getOneBitSet(SrcWidth, SrcWidth - 1));
10359 if (APSInt::compareValues(Alignment, MaxValue) > 0) {
10360 Info.FFDiag(E, diag::note_constexpr_alignment_too_big)
10361 << MaxValue << ForType << Alignment;
10367 APSInt(Alignment.zextOrTrunc(SrcWidth),
true);
10368 assert(APSInt::compareValues(Alignment, ExtAlignment) == 0 &&
10369 "Alignment should not be changed by ext/trunc");
10370 Alignment = ExtAlignment;
10371 assert(Alignment.getBitWidth() == SrcWidth);
10376bool PointerExprEvaluator::visitNonBuiltinCallExpr(
const CallExpr *E) {
10377 if (ExprEvaluatorBaseTy::VisitCallExpr(E))
10385 Result.addUnsizedArray(Info, E, PointeeTy);
10389bool PointerExprEvaluator::VisitCallExpr(
const CallExpr *E) {
10390 if (!IsConstantEvaluatedBuiltinCall(E))
10391 return visitNonBuiltinCallExpr(E);
10398 return T->isCharType() ||
T->isChar8Type();
10401bool PointerExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *E,
10402 unsigned BuiltinOp) {
10406 switch (BuiltinOp) {
10407 case Builtin::BIaddressof:
10408 case Builtin::BI__addressof:
10409 case Builtin::BI__builtin_addressof:
10411 case Builtin::BI__builtin_assume_aligned: {
10418 LValue OffsetResult(
Result);
10430 int64_t AdditionalOffset = -Offset.getZExtValue();
10435 if (OffsetResult.Base) {
10438 if (BaseAlignment < Align) {
10439 Result.Designator.setInvalid();
10440 CCEDiag(E->
getArg(0), diag::note_constexpr_baa_insufficient_alignment)
10447 if (OffsetResult.Offset.alignTo(Align) != OffsetResult.Offset) {
10448 Result.Designator.setInvalid();
10452 diag::note_constexpr_baa_insufficient_alignment)
10455 diag::note_constexpr_baa_value_insufficient_alignment))
10456 << OffsetResult.Offset.getQuantity() << Align.
getQuantity();
10462 case Builtin::BI__builtin_align_up:
10463 case Builtin::BI__builtin_align_down: {
10483 assert(Alignment.getBitWidth() <= 64 &&
10484 "Cannot handle > 64-bit address-space");
10485 uint64_t Alignment64 = Alignment.getZExtValue();
10487 BuiltinOp == Builtin::BI__builtin_align_down
10488 ? llvm::alignDown(
Result.Offset.getQuantity(), Alignment64)
10489 : llvm::alignTo(
Result.Offset.getQuantity(), Alignment64));
10495 Info.FFDiag(E->
getArg(0), diag::note_constexpr_alignment_adjust)
10499 case Builtin::BI__builtin_operator_new:
10501 case Builtin::BI__builtin_launder:
10503 case Builtin::BIstrchr:
10504 case Builtin::BIwcschr:
10505 case Builtin::BImemchr:
10506 case Builtin::BIwmemchr:
10507 if (Info.getLangOpts().CPlusPlus11)
10508 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
10512 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
10514 case Builtin::BI__builtin_strchr:
10515 case Builtin::BI__builtin_wcschr:
10516 case Builtin::BI__builtin_memchr:
10517 case Builtin::BI__builtin_char_memchr:
10518 case Builtin::BI__builtin_wmemchr: {
10519 if (!Visit(E->
getArg(0)))
10525 if (BuiltinOp != Builtin::BIstrchr &&
10526 BuiltinOp != Builtin::BIwcschr &&
10527 BuiltinOp != Builtin::BI__builtin_strchr &&
10528 BuiltinOp != Builtin::BI__builtin_wcschr) {
10532 MaxLength = N.getZExtValue();
10535 if (MaxLength == 0u)
10536 return ZeroInitialization(E);
10537 if (!
Result.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
10538 Result.Designator.Invalid)
10540 QualType CharTy =
Result.Designator.getType(Info.Ctx);
10541 bool IsRawByte = BuiltinOp == Builtin::BImemchr ||
10542 BuiltinOp == Builtin::BI__builtin_memchr;
10543 assert(IsRawByte ||
10548 Info.FFDiag(E, diag::note_constexpr_ltor_incomplete_type) << CharTy;
10554 Info.FFDiag(E, diag::note_constexpr_memchr_unsupported)
10561 bool StopAtNull =
false;
10562 switch (BuiltinOp) {
10563 case Builtin::BIstrchr:
10564 case Builtin::BI__builtin_strchr:
10571 return ZeroInitialization(E);
10574 case Builtin::BImemchr:
10575 case Builtin::BI__builtin_memchr:
10576 case Builtin::BI__builtin_char_memchr:
10580 DesiredVal = Desired.trunc(Info.Ctx.
getCharWidth()).getZExtValue();
10583 case Builtin::BIwcschr:
10584 case Builtin::BI__builtin_wcschr:
10587 case Builtin::BIwmemchr:
10588 case Builtin::BI__builtin_wmemchr:
10590 DesiredVal = Desired.getZExtValue();
10594 for (; MaxLength; --MaxLength) {
10599 if (Char.
getInt().getZExtValue() == DesiredVal)
10601 if (StopAtNull && !Char.
getInt())
10607 return ZeroInitialization(E);
10610 case Builtin::BImemcpy:
10611 case Builtin::BImemmove:
10612 case Builtin::BIwmemcpy:
10613 case Builtin::BIwmemmove:
10614 if (Info.getLangOpts().CPlusPlus11)
10615 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
10619 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
10621 case Builtin::BI__builtin_memcpy:
10622 case Builtin::BI__builtin_memmove:
10623 case Builtin::BI__builtin_wmemcpy:
10624 case Builtin::BI__builtin_wmemmove: {
10625 bool WChar = BuiltinOp == Builtin::BIwmemcpy ||
10626 BuiltinOp == Builtin::BIwmemmove ||
10627 BuiltinOp == Builtin::BI__builtin_wmemcpy ||
10628 BuiltinOp == Builtin::BI__builtin_wmemmove;
10629 bool Move = BuiltinOp == Builtin::BImemmove ||
10630 BuiltinOp == Builtin::BIwmemmove ||
10631 BuiltinOp == Builtin::BI__builtin_memmove ||
10632 BuiltinOp == Builtin::BI__builtin_wmemmove;
10635 if (!Visit(E->
getArg(0)))
10646 assert(!N.isSigned() &&
"memcpy and friends take an unsigned size");
10656 if (!Src.Base || !Dest.Base) {
10658 (!Src.Base ? Src : Dest).moveInto(Val);
10659 Info.FFDiag(E, diag::note_constexpr_memcpy_null)
10660 <<
Move << WChar << !!Src.Base
10664 if (Src.Designator.Invalid || Dest.Designator.Invalid)
10670 QualType
T = Dest.Designator.getType(Info.Ctx);
10671 QualType SrcT = Src.Designator.getType(Info.Ctx);
10674 Info.FFDiag(E, diag::note_constexpr_memcpy_type_pun) <<
Move << SrcT <<
T;
10678 Info.FFDiag(E, diag::note_constexpr_memcpy_incomplete_type) <<
Move <<
T;
10681 if (!
T.isTriviallyCopyableType(Info.Ctx)) {
10682 Info.FFDiag(E, diag::note_constexpr_memcpy_nontrivial) <<
Move <<
T;
10692 llvm::APInt OrigN = N;
10693 llvm::APInt::udivrem(OrigN, TSize, N, Remainder);
10695 Info.FFDiag(E, diag::note_constexpr_memcpy_unsupported)
10697 << (unsigned)TSize;
10705 uint64_t RemainingSrcSize = Src.Designator.validIndexAdjustments().second;
10706 uint64_t RemainingDestSize = Dest.Designator.validIndexAdjustments().second;
10707 if (N.ugt(RemainingSrcSize) || N.ugt(RemainingDestSize)) {
10708 Info.FFDiag(E, diag::note_constexpr_memcpy_unsupported)
10709 <<
Move << WChar << (N.ugt(RemainingSrcSize) ? 1 : 2) <<
T
10713 uint64_t NElems = N.getZExtValue();
10719 uint64_t SrcOffset = Src.getLValueOffset().getQuantity();
10720 uint64_t DestOffset = Dest.getLValueOffset().getQuantity();
10721 if (DestOffset >= SrcOffset && DestOffset - SrcOffset < NBytes) {
10724 Info.FFDiag(E, diag::note_constexpr_memcpy_overlap) << WChar;
10732 }
else if (!Move && SrcOffset >= DestOffset &&
10733 SrcOffset - DestOffset < NBytes) {
10735 Info.FFDiag(E, diag::note_constexpr_memcpy_overlap) << WChar;
10764 QualType AllocType);
10767 const CXXConstructExpr *CCE,
10768 QualType AllocType);
10770bool PointerExprEvaluator::VisitCXXNewExpr(
const CXXNewExpr *E) {
10771 if (!Info.getLangOpts().CPlusPlus20)
10772 Info.CCEDiag(E, diag::note_constexpr_new);
10775 if (Info.SpeculativeEvaluationDepth)
10780 QualType TargetType = AllocType;
10782 bool IsNothrow =
false;
10783 bool IsPlacement =
false;
10801 }
else if (OperatorNew->isReservedGlobalPlacementOperator()) {
10802 if (Info.CurrentCall->isStdFunction() || Info.getLangOpts().CPlusPlus26 ||
10803 (Info.CurrentCall->CanEvalMSConstexpr &&
10804 OperatorNew->hasAttr<MSConstexprAttr>())) {
10807 if (
Result.Designator.Invalid)
10810 IsPlacement =
true;
10812 Info.FFDiag(E, diag::note_constexpr_new_placement)
10817 Info.FFDiag(E, diag::note_constexpr_new_placement)
10820 }
else if (!OperatorNew
10821 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
10822 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
10828 const InitListExpr *ResizedArrayILE =
nullptr;
10829 const CXXConstructExpr *ResizedArrayCCE =
nullptr;
10830 bool ValueInit =
false;
10832 if (std::optional<const Expr *> ArraySize = E->
getArraySize()) {
10833 const Expr *Stripped = *ArraySize;
10834 for (;
auto *ICE = dyn_cast<ImplicitCastExpr>(Stripped);
10835 Stripped = ICE->getSubExpr())
10836 if (ICE->getCastKind() != CK_NoOp &&
10837 ICE->getCastKind() != CK_IntegralCast)
10850 return ZeroInitialization(E);
10852 Info.FFDiag(*ArraySize, diag::note_constexpr_new_negative)
10853 <<
ArrayBound << (*ArraySize)->getSourceRange();
10859 if (!Info.CheckArraySize(ArraySize.value()->getExprLoc(),
10864 return ZeroInitialization(E);
10876 }
else if (
auto *CCE = dyn_cast<CXXConstructExpr>(
Init)) {
10877 ResizedArrayCCE = CCE;
10880 assert(CAT &&
"unexpected type for array initializer");
10884 llvm::APInt InitBound = CAT->
getSize().zext(Bits);
10885 llvm::APInt AllocBound =
ArrayBound.zext(Bits);
10886 if (InitBound.ugt(AllocBound)) {
10888 return ZeroInitialization(E);
10890 Info.FFDiag(*ArraySize, diag::note_constexpr_new_too_small)
10891 <<
toString(AllocBound, 10,
false)
10893 << (*ArraySize)->getSourceRange();
10899 if (InitBound != AllocBound)
10904 ArraySizeModifier::Normal, 0);
10907 "array allocation with non-array new");
10913 struct FindObjectHandler {
10916 QualType AllocType;
10920 typedef bool result_type;
10921 bool failed() {
return false; }
10922 bool checkConst(QualType QT) {
10924 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
10929 bool found(
APValue &Subobj, QualType SubobjType) {
10930 if (!checkConst(SubobjType))
10934 unsigned SubobjectSize = 1;
10935 unsigned AllocSize = 1;
10936 if (
auto *CAT = dyn_cast<ConstantArrayType>(AllocType))
10938 if (
auto *CAT = dyn_cast<ConstantArrayType>(SubobjType))
10940 if (SubobjectSize < AllocSize ||
10943 Info.FFDiag(E, diag::note_constexpr_placement_new_wrong_type)
10944 << SubobjType << AllocType;
10951 Info.FFDiag(E, diag::note_constexpr_construct_complex_elem);
10954 bool found(APFloat &
Value, QualType SubobjType) {
10955 Info.FFDiag(E, diag::note_constexpr_construct_complex_elem);
10958 } Handler = {Info, E, AllocType, AK,
nullptr};
10964 Val = Handler.Value;
10973 Val = Info.createHeapAlloc(E, AllocType,
Result);
10979 ImplicitValueInitExpr VIE(AllocType);
10982 }
else if (ResizedArrayILE) {
10986 }
else if (ResizedArrayCCE) {
11009class MemberPointerExprEvaluator
11010 :
public ExprEvaluatorBase<MemberPointerExprEvaluator> {
11013 bool Success(
const ValueDecl *D) {
11019 MemberPointerExprEvaluator(EvalInfo &Info, MemberPtr &
Result)
11026 bool ZeroInitialization(
const Expr *E) {
11027 return Success((
const ValueDecl*)
nullptr);
11030 bool VisitCastExpr(
const CastExpr *E);
11031 bool VisitUnaryAddrOf(
const UnaryOperator *E);
11039 return MemberPointerExprEvaluator(Info, Result).Visit(E);
11042bool MemberPointerExprEvaluator::VisitCastExpr(
const CastExpr *E) {
11045 return ExprEvaluatorBaseTy::VisitCastExpr(E);
11047 case CK_NullToMemberPointer:
11049 return ZeroInitialization(E);
11051 case CK_BaseToDerivedMemberPointer: {
11059 typedef std::reverse_iterator<CastExpr::path_const_iterator> ReverseIter;
11061 PathI != PathE; ++PathI) {
11062 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
11063 const CXXRecordDecl *Derived = (*PathI)->getType()->getAsCXXRecordDecl();
11064 if (!
Result.castToDerived(Derived))
11068 ->
castAs<MemberPointerType>()
11069 ->getMostRecentCXXRecordDecl()))
11074 case CK_DerivedToBaseMemberPointer:
11078 PathE = E->
path_end(); PathI != PathE; ++PathI) {
11079 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
11080 const CXXRecordDecl *
Base = (*PathI)->getType()->getAsCXXRecordDecl();
11081 if (!
Result.castToBase(Base))
11088bool MemberPointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
11099 class RecordExprEvaluator
11100 :
public ExprEvaluatorBase<RecordExprEvaluator> {
11101 const LValue &
This;
11105 RecordExprEvaluator(EvalInfo &info,
const LValue &This,
APValue &
Result)
11112 bool ZeroInitialization(
const Expr *E) {
11113 return ZeroInitialization(E, E->
getType());
11115 bool ZeroInitialization(
const Expr *E, QualType
T);
11117 bool VisitCallExpr(
const CallExpr *E) {
11118 return handleCallExpr(E,
Result, &This);
11120 bool VisitCastExpr(
const CastExpr *E);
11121 bool VisitInitListExpr(
const InitListExpr *E);
11122 bool VisitCXXConstructExpr(
const CXXConstructExpr *E) {
11123 return VisitCXXConstructExpr(E, E->
getType());
11126 bool VisitCXXInheritedCtorInitExpr(
const CXXInheritedCtorInitExpr *E);
11127 bool VisitCXXConstructExpr(
const CXXConstructExpr *E, QualType
T);
11128 bool VisitCXXStdInitializerListExpr(
const CXXStdInitializerListExpr *E);
11129 bool VisitBinCmp(
const BinaryOperator *E);
11130 bool VisitCXXParenListInitExpr(
const CXXParenListInitExpr *E);
11131 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
11132 ArrayRef<Expr *> Args);
11146 assert(!RD->
isUnion() &&
"Expected non-union class type");
11155 unsigned Index = 0;
11157 End = CD->
bases_end(); I != End; ++I, ++Index) {
11159 LValue Subobject =
This;
11163 Result.getStructBase(Index)))
11168 for (
const auto *I : RD->
fields()) {
11170 if (I->isUnnamedBitField() || I->getType()->isReferenceType())
11173 LValue Subobject =
This;
11179 Result.getStructField(I->getFieldIndex()), Info, Subobject, &VIE))
11186bool RecordExprEvaluator::ZeroInitialization(
const Expr *E, QualType
T) {
11193 while (I != RD->
field_end() && (*I)->isUnnamedBitField())
11200 LValue Subobject =
This;
11204 ImplicitValueInitExpr VIE(I->getType());
11209 Info.FFDiag(E, diag::note_constexpr_virtual_base) << RD;
11216bool RecordExprEvaluator::VisitCastExpr(
const CastExpr *E) {
11219 return ExprEvaluatorBaseTy::VisitCastExpr(E);
11221 case CK_ConstructorConversion:
11224 case CK_DerivedToBase:
11225 case CK_UncheckedDerivedToBase: {
11236 PathE = E->
path_end(); PathI != PathE; ++PathI) {
11237 assert(!(*PathI)->isVirtual() &&
"record rvalue with virtual base");
11238 const CXXRecordDecl *
Base = (*PathI)->getType()->getAsCXXRecordDecl();
11245 case CK_HLSLAggregateSplatCast: {
11265 case CK_HLSLElementwiseCast: {
11284bool RecordExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
11287 return VisitCXXParenListOrInitListExpr(E, E->
inits());
11290bool RecordExprEvaluator::VisitCXXParenListOrInitListExpr(
11295 auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
11297 EvalInfo::EvaluatingConstructorRAII EvalObj(
11299 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries},
11300 CXXRD && CXXRD->getNumBases());
11303 const FieldDecl *
Field;
11304 if (
auto *ILE = dyn_cast<InitListExpr>(ExprToVisit)) {
11305 Field = ILE->getInitializedFieldInUnion();
11306 }
else if (
auto *PLIE = dyn_cast<CXXParenListInitExpr>(ExprToVisit)) {
11307 Field = PLIE->getInitializedFieldInUnion();
11310 "Expression is neither an init list nor a C++ paren list");
11322 ImplicitValueInitExpr VIE(
Field->getType());
11323 const Expr *InitExpr = Args.empty() ? &VIE : Args[0];
11325 LValue Subobject =
This;
11330 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
11334 if (
Field->isBitField())
11344 Result =
APValue(APValue::UninitStruct(), CXXRD ? CXXRD->getNumBases() : 0,
11346 unsigned ElementNo = 0;
11350 if (CXXRD && CXXRD->getNumBases()) {
11351 for (
const auto &Base : CXXRD->bases()) {
11352 assert(ElementNo < Args.size() &&
"missing init for base class");
11353 const Expr *
Init = Args[ElementNo];
11355 LValue Subobject =
This;
11361 if (!Info.noteFailure())
11368 EvalObj.finishedConstructingBases();
11372 for (
const auto *Field : RD->
fields()) {
11375 if (
Field->isUnnamedBitField())
11378 LValue Subobject =
This;
11380 bool HaveInit = ElementNo < Args.size();
11385 Subobject, Field, &Layout))
11390 ImplicitValueInitExpr VIE(HaveInit ? Info.Ctx.
IntTy :
Field->getType());
11391 const Expr *
Init = HaveInit ? Args[ElementNo++] : &VIE;
11393 if (
Field->getType()->isIncompleteArrayType()) {
11398 Info.FFDiag(
Init, diag::note_constexpr_unsupported_flexible_array);
11405 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
11409 if (
Field->getType()->isReferenceType()) {
11413 if (!Info.noteFailure())
11418 (
Field->isBitField() &&
11420 if (!Info.noteFailure())
11426 EvalObj.finishedConstructingFields();
11431bool RecordExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E,
11441 return ZeroInitialization(E,
T);
11459 const Expr *SrcObj = E->
getArg(0);
11462 if (
const MaterializeTemporaryExpr *ME =
11463 dyn_cast<MaterializeTemporaryExpr>(SrcObj))
11464 return Visit(ME->getSubExpr());
11467 if (ZeroInit && !ZeroInitialization(E,
T))
11476bool RecordExprEvaluator::VisitCXXInheritedCtorInitExpr(
11477 const CXXInheritedCtorInitExpr *E) {
11478 if (!Info.CurrentCall) {
11479 assert(Info.checkingPotentialConstantExpression());
11498bool RecordExprEvaluator::VisitCXXStdInitializerListExpr(
11499 const CXXStdInitializerListExpr *E) {
11500 const ConstantArrayType *ArrayType =
11507 assert(ArrayType &&
"unexpected type for array initializer");
11510 Array.addArray(Info, E, ArrayType);
11514 Array.moveInto(
Result.getStructField(0));
11518 assert(Field !=
Record->field_end() &&
11521 "Expected std::initializer_list first field to be const E *");
11523 assert(Field !=
Record->field_end() &&
11524 "Expected std::initializer_list to have two fields");
11533 "Expected std::initializer_list second field to be const E *");
11538 Array.moveInto(
Result.getStructField(1));
11541 assert(++Field ==
Record->field_end() &&
11542 "Expected std::initializer_list to only have two fields");
11547bool RecordExprEvaluator::VisitLambdaExpr(
const LambdaExpr *E) {
11552 const size_t NumFields =
11557 "The number of lambda capture initializers should equal the number of "
11558 "fields within the closure type");
11566 for (
const auto *Field : ClosureClass->
fields()) {
11569 Expr *
const CurFieldInit = *CaptureInitIt++;
11576 LValue Subobject =
This;
11583 if (!Info.keepEvaluatingAfterFailure())
11592 APValue &Result, EvalInfo &Info) {
11595 "can't evaluate expression as a record rvalue");
11596 return RecordExprEvaluator(Info,
This, Result).Visit(E);
11607class TemporaryExprEvaluator
11608 :
public LValueExprEvaluatorBase<TemporaryExprEvaluator> {
11610 TemporaryExprEvaluator(EvalInfo &Info, LValue &
Result) :
11611 LValueExprEvaluatorBaseTy(Info,
Result,
false) {}
11614 bool VisitConstructExpr(
const Expr *E) {
11620 bool VisitCastExpr(
const CastExpr *E) {
11623 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
11625 case CK_ConstructorConversion:
11629 bool VisitInitListExpr(
const InitListExpr *E) {
11630 return VisitConstructExpr(E);
11632 bool VisitCXXConstructExpr(
const CXXConstructExpr *E) {
11633 return VisitConstructExpr(E);
11635 bool VisitCallExpr(
const CallExpr *E) {
11636 return VisitConstructExpr(E);
11638 bool VisitCXXStdInitializerListExpr(
const CXXStdInitializerListExpr *E) {
11639 return VisitConstructExpr(E);
11642 return VisitConstructExpr(E);
11651 return TemporaryExprEvaluator(Info, Result).Visit(E);
11659 class VectorExprEvaluator
11660 :
public ExprEvaluatorBase<VectorExprEvaluator> {
11667 bool Success(ArrayRef<APValue>
V,
const Expr *E) {
11668 assert(
V.size() == E->
getType()->
castAs<VectorType>()->getNumElements());
11674 assert(
V.isVector());
11678 bool ZeroInitialization(
const Expr *E);
11680 bool VisitUnaryReal(
const UnaryOperator *E)
11682 bool VisitCastExpr(
const CastExpr* E);
11683 bool VisitInitListExpr(
const InitListExpr *E);
11684 bool VisitUnaryImag(
const UnaryOperator *E);
11685 bool VisitBinaryOperator(
const BinaryOperator *E);
11686 bool VisitUnaryOperator(
const UnaryOperator *E);
11687 bool VisitCallExpr(
const CallExpr *E);
11688 bool VisitConvertVectorExpr(
const ConvertVectorExpr *E);
11689 bool VisitShuffleVectorExpr(
const ShuffleVectorExpr *E);
11698 "not a vector prvalue");
11699 return VectorExprEvaluator(Info, Result).Visit(E);
11703 assert(Val.
isVector() &&
"expected vector APValue");
11707 llvm::APInt
Result(NumElts, 0);
11709 for (
unsigned I = 0; I < NumElts; ++I) {
11711 assert(Elt.
isInt() &&
"expected integer element in bool vector");
11713 if (Elt.
getInt().getBoolValue())
11720bool VectorExprEvaluator::VisitCastExpr(
const CastExpr *E) {
11721 const VectorType *VTy = E->
getType()->
castAs<VectorType>();
11725 QualType SETy = SE->
getType();
11728 case CK_VectorSplat: {
11734 Val =
APValue(std::move(IntResult));
11739 Val =
APValue(std::move(FloatResult));
11756 Info.FFDiag(E, diag::note_constexpr_invalid_cast)
11757 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
11762 if (!handleRValueToRValueBitCast(Info,
Result, SVal, E))
11767 case CK_HLSLVectorTruncation: {
11772 for (
unsigned I = 0; I < NElts; I++)
11776 case CK_HLSLAggregateSplatCast: {
11793 case CK_HLSLElementwiseCast: {
11806 return Success(ResultEls, E);
11809 return ExprEvaluatorBaseTy::VisitCastExpr(E);
11814VectorExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
11831 unsigned CountInits = 0, CountElts = 0;
11832 while (CountElts < NumElements) {
11834 if (CountInits < NumInits
11840 for (
unsigned j = 0; j < vlen; j++)
11844 llvm::APSInt sInt(32);
11845 if (CountInits < NumInits) {
11850 Elements.push_back(
APValue(sInt));
11853 llvm::APFloat f(0.0);
11854 if (CountInits < NumInits) {
11859 Elements.push_back(
APValue(f));
11868VectorExprEvaluator::ZeroInitialization(
const Expr *E) {
11872 if (EltTy->isIntegerType())
11882bool VectorExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
11884 return ZeroInitialization(E);
11887bool VectorExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
11889 assert(Op != BO_PtrMemD && Op != BO_PtrMemI && Op != BO_Cmp &&
11890 "Operation not supported on vector types");
11892 if (Op == BO_Comma)
11893 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
11895 Expr *LHS = E->
getLHS();
11896 Expr *RHS = E->
getRHS();
11899 "Must both be vector types");
11902 assert(LHS->
getType()->
castAs<VectorType>()->getNumElements() ==
11906 "All operands must be the same size.");
11910 bool LHSOK =
Evaluate(LHSValue, Info, LHS);
11911 if (!LHSOK && !Info.noteFailure())
11913 if (!
Evaluate(RHSValue, Info, RHS) || !LHSOK)
11935 "Vector can only be int or float type");
11943 "Vector operator ~ can only be int");
11944 Elt.
getInt().flipAllBits();
11954 "Vector can only be int or float type");
11960 EltResult.setAllBits();
11962 EltResult.clearAllBits();
11968 return std::nullopt;
11972bool VectorExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
11978 const QualType ResultEltTy = VD->getElementType();
11982 if (!
Evaluate(SubExprValue, Info, SubExpr))
11995 "Vector length doesn't match type?");
11998 for (
unsigned EltNum = 0; EltNum < VD->getNumElements(); ++EltNum) {
12000 Info.Ctx, ResultEltTy, Op, SubExprValue.
getVectorElt(EltNum));
12003 ResultElements.push_back(*Elt);
12005 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12014 Result =
APValue(APFloat(0.0));
12016 DestTy, Result.getFloat());
12027 Result.getFloat());
12032 DestTy, Result.getInt());
12036 Info.FFDiag(E, diag::err_convertvector_constexpr_unsupported_vector_cast)
12037 << SourceTy << DestTy;
12042 llvm::function_ref<APInt(
const APSInt &)> PackFn) {
12051 assert(LHSVecLen != 0 && LHSVecLen == RHSVecLen &&
12052 "pack builtin LHSVecLen must equal to RHSVecLen");
12061 const unsigned SrcPerLane = 128 / SrcBits;
12062 const unsigned Lanes = LHSVecLen * SrcBits / 128;
12065 Out.reserve(LHSVecLen + RHSVecLen);
12067 for (
unsigned Lane = 0; Lane != Lanes; ++Lane) {
12068 unsigned base = Lane * SrcPerLane;
12069 for (
unsigned I = 0; I != SrcPerLane; ++I)
12072 for (
unsigned I = 0; I != SrcPerLane; ++I)
12077 Result =
APValue(Out.data(), Out.size());
12083 llvm::function_ref<std::pair<unsigned, int>(
unsigned,
unsigned)>
12090 unsigned ShuffleMask = 0;
12092 bool IsVectorMask =
false;
12093 bool IsSingleOperand = (
Call->getNumArgs() == 2);
12095 if (IsSingleOperand) {
12098 IsVectorMask =
true;
12107 ShuffleMask =
static_cast<unsigned>(MaskImm.getZExtValue());
12117 IsVectorMask =
true;
12126 ShuffleMask =
static_cast<unsigned>(MaskImm.getZExtValue());
12137 ResultElements.reserve(NumElts);
12139 for (
unsigned DstIdx = 0; DstIdx != NumElts; ++DstIdx) {
12140 if (IsVectorMask) {
12141 ShuffleMask =
static_cast<unsigned>(
12142 MaskVector.getVectorElt(DstIdx).getInt().getZExtValue());
12144 auto [SrcVecIdx, SrcIdx] = GetSourceIndex(DstIdx, ShuffleMask);
12150 ResultElements.push_back(
12157 ResultElements.push_back(
APValue());
12160 const APValue &Src = (SrcVecIdx == 0) ? A : B;
12165 Out =
APValue(ResultElements.data(), ResultElements.size());
12169bool VectorExprEvaluator::VisitCallExpr(
const CallExpr *E) {
12170 if (!IsConstantEvaluatedBuiltinCall(E))
12171 return ExprEvaluatorBaseTy::VisitCallExpr(E);
12173 auto EvaluateBinOpExpr =
12175 APValue SourceLHS, SourceRHS;
12181 QualType DestEltTy = DestTy->getElementType();
12182 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
12185 ResultElements.reserve(SourceLen);
12187 if (SourceRHS.
isInt()) {
12189 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12191 ResultElements.push_back(
12195 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12198 ResultElements.push_back(
12208 case Builtin::BI__builtin_elementwise_popcount:
12209 case Builtin::BI__builtin_elementwise_bitreverse: {
12214 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12217 ResultElements.reserve(SourceLen);
12219 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12222 case Builtin::BI__builtin_elementwise_popcount:
12223 ResultElements.push_back(
APValue(
12227 case Builtin::BI__builtin_elementwise_bitreverse:
12228 ResultElements.push_back(
12235 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12237 case Builtin::BI__builtin_elementwise_abs: {
12242 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12245 ResultElements.reserve(SourceLen);
12247 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12252 CurrentEle.getInt().
abs(),
12253 DestEltTy->isUnsignedIntegerOrEnumerationType()));
12254 ResultElements.push_back(Val);
12257 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12260 case Builtin::BI__builtin_elementwise_add_sat:
12261 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12262 return LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS);
12265 case Builtin::BI__builtin_elementwise_sub_sat:
12266 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12267 return LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
12270 case X86::BI__builtin_ia32_extract128i256:
12271 case X86::BI__builtin_ia32_vextractf128_pd256:
12272 case X86::BI__builtin_ia32_vextractf128_ps256:
12273 case X86::BI__builtin_ia32_vextractf128_si256: {
12274 APValue SourceVec, SourceImm;
12283 unsigned RetLen = RetVT->getNumElements();
12284 unsigned Idx = SourceImm.
getInt().getZExtValue() & 1;
12287 ResultElements.reserve(RetLen);
12289 for (
unsigned I = 0; I < RetLen; I++)
12290 ResultElements.push_back(SourceVec.
getVectorElt(Idx * RetLen + I));
12295 case X86::BI__builtin_ia32_extracti32x4_256_mask:
12296 case X86::BI__builtin_ia32_extractf32x4_256_mask:
12297 case X86::BI__builtin_ia32_extracti32x4_mask:
12298 case X86::BI__builtin_ia32_extractf32x4_mask:
12299 case X86::BI__builtin_ia32_extracti32x8_mask:
12300 case X86::BI__builtin_ia32_extractf32x8_mask:
12301 case X86::BI__builtin_ia32_extracti64x2_256_mask:
12302 case X86::BI__builtin_ia32_extractf64x2_256_mask:
12303 case X86::BI__builtin_ia32_extracti64x2_512_mask:
12304 case X86::BI__builtin_ia32_extractf64x2_512_mask:
12305 case X86::BI__builtin_ia32_extracti64x4_mask:
12306 case X86::BI__builtin_ia32_extractf64x4_mask: {
12317 unsigned RetLen = RetVT->getNumElements();
12322 unsigned Lanes = SrcLen / RetLen;
12323 unsigned Lane =
static_cast<unsigned>(Imm.getZExtValue() % Lanes);
12324 unsigned Base = Lane * RetLen;
12327 ResultElements.reserve(RetLen);
12328 for (
unsigned I = 0; I < RetLen; ++I) {
12330 ResultElements.push_back(SourceVec.
getVectorElt(Base + I));
12334 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12337 case clang::X86::BI__builtin_ia32_pavgb128:
12338 case clang::X86::BI__builtin_ia32_pavgw128:
12339 case clang::X86::BI__builtin_ia32_pavgb256:
12340 case clang::X86::BI__builtin_ia32_pavgw256:
12341 case clang::X86::BI__builtin_ia32_pavgb512:
12342 case clang::X86::BI__builtin_ia32_pavgw512:
12343 return EvaluateBinOpExpr(llvm::APIntOps::avgCeilU);
12345 case clang::X86::BI__builtin_ia32_pmulhrsw128:
12346 case clang::X86::BI__builtin_ia32_pmulhrsw256:
12347 case clang::X86::BI__builtin_ia32_pmulhrsw512:
12348 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12349 return (llvm::APIntOps::mulsExtended(LHS, RHS).ashr(14) + 1)
12350 .extractBits(16, 1);
12353 case clang::X86::BI__builtin_ia32_pmaddubsw128:
12354 case clang::X86::BI__builtin_ia32_pmaddubsw256:
12355 case clang::X86::BI__builtin_ia32_pmaddubsw512:
12356 case clang::X86::BI__builtin_ia32_pmaddwd128:
12357 case clang::X86::BI__builtin_ia32_pmaddwd256:
12358 case clang::X86::BI__builtin_ia32_pmaddwd512: {
12359 APValue SourceLHS, SourceRHS;
12365 QualType DestEltTy = DestTy->getElementType();
12367 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
12369 ResultElements.reserve(SourceLen / 2);
12371 for (
unsigned EltNum = 0; EltNum < SourceLen; EltNum += 2) {
12376 unsigned BitWidth = 2 * LoLHS.getBitWidth();
12379 case clang::X86::BI__builtin_ia32_pmaddubsw128:
12380 case clang::X86::BI__builtin_ia32_pmaddubsw256:
12381 case clang::X86::BI__builtin_ia32_pmaddubsw512:
12382 ResultElements.push_back(
APValue(
12383 APSInt((LoLHS.zext(BitWidth) * LoRHS.sext(BitWidth))
12384 .sadd_sat((HiLHS.zext(BitWidth) * HiRHS.sext(BitWidth))),
12387 case clang::X86::BI__builtin_ia32_pmaddwd128:
12388 case clang::X86::BI__builtin_ia32_pmaddwd256:
12389 case clang::X86::BI__builtin_ia32_pmaddwd512:
12390 ResultElements.push_back(
12391 APValue(
APSInt((LoLHS.sext(BitWidth) * LoRHS.sext(BitWidth)) +
12392 (HiLHS.sext(BitWidth) * HiRHS.sext(BitWidth)),
12398 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12401 case clang::X86::BI__builtin_ia32_pmulhuw128:
12402 case clang::X86::BI__builtin_ia32_pmulhuw256:
12403 case clang::X86::BI__builtin_ia32_pmulhuw512:
12404 return EvaluateBinOpExpr(llvm::APIntOps::mulhu);
12406 case clang::X86::BI__builtin_ia32_pmulhw128:
12407 case clang::X86::BI__builtin_ia32_pmulhw256:
12408 case clang::X86::BI__builtin_ia32_pmulhw512:
12409 return EvaluateBinOpExpr(llvm::APIntOps::mulhs);
12411 case clang::X86::BI__builtin_ia32_psllv2di:
12412 case clang::X86::BI__builtin_ia32_psllv4di:
12413 case clang::X86::BI__builtin_ia32_psllv4si:
12414 case clang::X86::BI__builtin_ia32_psllv8di:
12415 case clang::X86::BI__builtin_ia32_psllv8hi:
12416 case clang::X86::BI__builtin_ia32_psllv8si:
12417 case clang::X86::BI__builtin_ia32_psllv16hi:
12418 case clang::X86::BI__builtin_ia32_psllv16si:
12419 case clang::X86::BI__builtin_ia32_psllv32hi:
12420 case clang::X86::BI__builtin_ia32_psllwi128:
12421 case clang::X86::BI__builtin_ia32_pslldi128:
12422 case clang::X86::BI__builtin_ia32_psllqi128:
12423 case clang::X86::BI__builtin_ia32_psllwi256:
12424 case clang::X86::BI__builtin_ia32_pslldi256:
12425 case clang::X86::BI__builtin_ia32_psllqi256:
12426 case clang::X86::BI__builtin_ia32_psllwi512:
12427 case clang::X86::BI__builtin_ia32_pslldi512:
12428 case clang::X86::BI__builtin_ia32_psllqi512:
12429 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12430 if (RHS.uge(LHS.getBitWidth())) {
12431 return APInt::getZero(LHS.getBitWidth());
12433 return LHS.shl(RHS.getZExtValue());
12436 case clang::X86::BI__builtin_ia32_psrav4si:
12437 case clang::X86::BI__builtin_ia32_psrav8di:
12438 case clang::X86::BI__builtin_ia32_psrav8hi:
12439 case clang::X86::BI__builtin_ia32_psrav8si:
12440 case clang::X86::BI__builtin_ia32_psrav16hi:
12441 case clang::X86::BI__builtin_ia32_psrav16si:
12442 case clang::X86::BI__builtin_ia32_psrav32hi:
12443 case clang::X86::BI__builtin_ia32_psravq128:
12444 case clang::X86::BI__builtin_ia32_psravq256:
12445 case clang::X86::BI__builtin_ia32_psrawi128:
12446 case clang::X86::BI__builtin_ia32_psradi128:
12447 case clang::X86::BI__builtin_ia32_psraqi128:
12448 case clang::X86::BI__builtin_ia32_psrawi256:
12449 case clang::X86::BI__builtin_ia32_psradi256:
12450 case clang::X86::BI__builtin_ia32_psraqi256:
12451 case clang::X86::BI__builtin_ia32_psrawi512:
12452 case clang::X86::BI__builtin_ia32_psradi512:
12453 case clang::X86::BI__builtin_ia32_psraqi512:
12454 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12455 if (RHS.uge(LHS.getBitWidth())) {
12456 return LHS.ashr(LHS.getBitWidth() - 1);
12458 return LHS.ashr(RHS.getZExtValue());
12461 case clang::X86::BI__builtin_ia32_psrlv2di:
12462 case clang::X86::BI__builtin_ia32_psrlv4di:
12463 case clang::X86::BI__builtin_ia32_psrlv4si:
12464 case clang::X86::BI__builtin_ia32_psrlv8di:
12465 case clang::X86::BI__builtin_ia32_psrlv8hi:
12466 case clang::X86::BI__builtin_ia32_psrlv8si:
12467 case clang::X86::BI__builtin_ia32_psrlv16hi:
12468 case clang::X86::BI__builtin_ia32_psrlv16si:
12469 case clang::X86::BI__builtin_ia32_psrlv32hi:
12470 case clang::X86::BI__builtin_ia32_psrlwi128:
12471 case clang::X86::BI__builtin_ia32_psrldi128:
12472 case clang::X86::BI__builtin_ia32_psrlqi128:
12473 case clang::X86::BI__builtin_ia32_psrlwi256:
12474 case clang::X86::BI__builtin_ia32_psrldi256:
12475 case clang::X86::BI__builtin_ia32_psrlqi256:
12476 case clang::X86::BI__builtin_ia32_psrlwi512:
12477 case clang::X86::BI__builtin_ia32_psrldi512:
12478 case clang::X86::BI__builtin_ia32_psrlqi512:
12479 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12480 if (RHS.uge(LHS.getBitWidth())) {
12481 return APInt::getZero(LHS.getBitWidth());
12483 return LHS.lshr(RHS.getZExtValue());
12485 case X86::BI__builtin_ia32_packsswb128:
12486 case X86::BI__builtin_ia32_packsswb256:
12487 case X86::BI__builtin_ia32_packsswb512:
12488 case X86::BI__builtin_ia32_packssdw128:
12489 case X86::BI__builtin_ia32_packssdw256:
12490 case X86::BI__builtin_ia32_packssdw512:
12492 return APSInt(Src).truncSSat(Src.getBitWidth() / 2);
12494 case X86::BI__builtin_ia32_packusdw128:
12495 case X86::BI__builtin_ia32_packusdw256:
12496 case X86::BI__builtin_ia32_packusdw512:
12497 case X86::BI__builtin_ia32_packuswb128:
12498 case X86::BI__builtin_ia32_packuswb256:
12499 case X86::BI__builtin_ia32_packuswb512:
12501 unsigned DstBits = Src.getBitWidth() / 2;
12502 if (Src.isNegative())
12503 return APInt::getZero(DstBits);
12504 if (Src.isIntN(DstBits))
12506 return APInt::getAllOnes(DstBits);
12508 case clang::X86::BI__builtin_ia32_pmuldq128:
12509 case clang::X86::BI__builtin_ia32_pmuldq256:
12510 case clang::X86::BI__builtin_ia32_pmuldq512:
12511 case clang::X86::BI__builtin_ia32_pmuludq128:
12512 case clang::X86::BI__builtin_ia32_pmuludq256:
12513 case clang::X86::BI__builtin_ia32_pmuludq512: {
12514 APValue SourceLHS, SourceRHS;
12521 ResultElements.reserve(SourceLen / 2);
12523 for (
unsigned EltNum = 0; EltNum < SourceLen; EltNum += 2) {
12528 case clang::X86::BI__builtin_ia32_pmuludq128:
12529 case clang::X86::BI__builtin_ia32_pmuludq256:
12530 case clang::X86::BI__builtin_ia32_pmuludq512:
12531 ResultElements.push_back(
12532 APValue(
APSInt(llvm::APIntOps::muluExtended(LHS, RHS),
true)));
12534 case clang::X86::BI__builtin_ia32_pmuldq128:
12535 case clang::X86::BI__builtin_ia32_pmuldq256:
12536 case clang::X86::BI__builtin_ia32_pmuldq512:
12537 ResultElements.push_back(
12538 APValue(
APSInt(llvm::APIntOps::mulsExtended(LHS, RHS),
false)));
12543 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12546 case X86::BI__builtin_ia32_vpmadd52luq128:
12547 case X86::BI__builtin_ia32_vpmadd52luq256:
12548 case X86::BI__builtin_ia32_vpmadd52luq512: {
12557 ResultElements.reserve(ALen);
12559 for (
unsigned EltNum = 0; EltNum < ALen; EltNum += 1) {
12562 APInt CElt =
C.getVectorElt(EltNum).getInt().trunc(52);
12563 APSInt ResElt(AElt + (BElt * CElt).zext(64),
false);
12564 ResultElements.push_back(
APValue(ResElt));
12567 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12569 case X86::BI__builtin_ia32_vpmadd52huq128:
12570 case X86::BI__builtin_ia32_vpmadd52huq256:
12571 case X86::BI__builtin_ia32_vpmadd52huq512: {
12580 ResultElements.reserve(ALen);
12582 for (
unsigned EltNum = 0; EltNum < ALen; EltNum += 1) {
12585 APInt CElt =
C.getVectorElt(EltNum).getInt().trunc(52);
12586 APSInt ResElt(AElt + llvm::APIntOps::mulhu(BElt, CElt).zext(64),
false);
12587 ResultElements.push_back(
APValue(ResElt));
12590 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12593 case clang::X86::BI__builtin_ia32_vprotbi:
12594 case clang::X86::BI__builtin_ia32_vprotdi:
12595 case clang::X86::BI__builtin_ia32_vprotqi:
12596 case clang::X86::BI__builtin_ia32_vprotwi:
12597 case clang::X86::BI__builtin_ia32_prold128:
12598 case clang::X86::BI__builtin_ia32_prold256:
12599 case clang::X86::BI__builtin_ia32_prold512:
12600 case clang::X86::BI__builtin_ia32_prolq128:
12601 case clang::X86::BI__builtin_ia32_prolq256:
12602 case clang::X86::BI__builtin_ia32_prolq512:
12603 return EvaluateBinOpExpr(
12604 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS.rotl(RHS); });
12606 case clang::X86::BI__builtin_ia32_prord128:
12607 case clang::X86::BI__builtin_ia32_prord256:
12608 case clang::X86::BI__builtin_ia32_prord512:
12609 case clang::X86::BI__builtin_ia32_prorq128:
12610 case clang::X86::BI__builtin_ia32_prorq256:
12611 case clang::X86::BI__builtin_ia32_prorq512:
12612 return EvaluateBinOpExpr(
12613 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS.rotr(RHS); });
12615 case Builtin::BI__builtin_elementwise_max:
12616 case Builtin::BI__builtin_elementwise_min: {
12617 APValue SourceLHS, SourceRHS;
12622 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12629 ResultElements.reserve(SourceLen);
12631 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12635 case Builtin::BI__builtin_elementwise_max:
12636 ResultElements.push_back(
12640 case Builtin::BI__builtin_elementwise_min:
12641 ResultElements.push_back(
12648 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12650 case X86::BI__builtin_ia32_vpshldd128:
12651 case X86::BI__builtin_ia32_vpshldd256:
12652 case X86::BI__builtin_ia32_vpshldd512:
12653 case X86::BI__builtin_ia32_vpshldq128:
12654 case X86::BI__builtin_ia32_vpshldq256:
12655 case X86::BI__builtin_ia32_vpshldq512:
12656 case X86::BI__builtin_ia32_vpshldw128:
12657 case X86::BI__builtin_ia32_vpshldw256:
12658 case X86::BI__builtin_ia32_vpshldw512: {
12659 APValue SourceHi, SourceLo, SourceAmt;
12665 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12668 ResultElements.reserve(SourceLen);
12671 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12674 APInt R = llvm::APIntOps::fshl(Hi, Lo, Amt);
12675 ResultElements.push_back(
12679 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12681 case X86::BI__builtin_ia32_vpshrdd128:
12682 case X86::BI__builtin_ia32_vpshrdd256:
12683 case X86::BI__builtin_ia32_vpshrdd512:
12684 case X86::BI__builtin_ia32_vpshrdq128:
12685 case X86::BI__builtin_ia32_vpshrdq256:
12686 case X86::BI__builtin_ia32_vpshrdq512:
12687 case X86::BI__builtin_ia32_vpshrdw128:
12688 case X86::BI__builtin_ia32_vpshrdw256:
12689 case X86::BI__builtin_ia32_vpshrdw512: {
12691 APValue SourceHi, SourceLo, SourceAmt;
12697 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12700 ResultElements.reserve(SourceLen);
12703 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12706 APInt R = llvm::APIntOps::fshr(Hi, Lo, Amt);
12707 ResultElements.push_back(
12711 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12713 case X86::BI__builtin_ia32_vpconflictsi_128:
12714 case X86::BI__builtin_ia32_vpconflictsi_256:
12715 case X86::BI__builtin_ia32_vpconflictsi_512:
12716 case X86::BI__builtin_ia32_vpconflictdi_128:
12717 case X86::BI__builtin_ia32_vpconflictdi_256:
12718 case X86::BI__builtin_ia32_vpconflictdi_512: {
12726 ResultElements.reserve(SourceLen);
12729 bool DestUnsigned =
12730 VecT->getElementType()->isUnsignedIntegerOrEnumerationType();
12732 for (
unsigned I = 0; I != SourceLen; ++I) {
12735 APInt ConflictMask(EltI.
getInt().getBitWidth(), 0);
12736 for (
unsigned J = 0; J != I; ++J) {
12738 ConflictMask.setBitVal(J, EltI.
getInt() == EltJ.
getInt());
12740 ResultElements.push_back(
APValue(
APSInt(ConflictMask, DestUnsigned)));
12742 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12744 case X86::BI__builtin_ia32_blendpd:
12745 case X86::BI__builtin_ia32_blendpd256:
12746 case X86::BI__builtin_ia32_blendps:
12747 case X86::BI__builtin_ia32_blendps256:
12748 case X86::BI__builtin_ia32_pblendw128:
12749 case X86::BI__builtin_ia32_pblendw256:
12750 case X86::BI__builtin_ia32_pblendd128:
12751 case X86::BI__builtin_ia32_pblendd256: {
12752 APValue SourceF, SourceT, SourceC;
12761 ResultElements.reserve(SourceLen);
12762 for (
unsigned EltNum = 0; EltNum != SourceLen; ++EltNum) {
12765 ResultElements.push_back(
C[EltNum % 8] ?
T : F);
12768 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12771 case X86::BI__builtin_ia32_psignb128:
12772 case X86::BI__builtin_ia32_psignb256:
12773 case X86::BI__builtin_ia32_psignw128:
12774 case X86::BI__builtin_ia32_psignw256:
12775 case X86::BI__builtin_ia32_psignd128:
12776 case X86::BI__builtin_ia32_psignd256:
12777 return EvaluateBinOpExpr([](
const APInt &AElem,
const APInt &BElem) {
12778 if (BElem.isZero())
12779 return APInt::getZero(AElem.getBitWidth());
12780 if (BElem.isNegative())
12785 case X86::BI__builtin_ia32_blendvpd:
12786 case X86::BI__builtin_ia32_blendvpd256:
12787 case X86::BI__builtin_ia32_blendvps:
12788 case X86::BI__builtin_ia32_blendvps256:
12789 case X86::BI__builtin_ia32_pblendvb128:
12790 case X86::BI__builtin_ia32_pblendvb256: {
12792 APValue SourceF, SourceT, SourceC;
12800 ResultElements.reserve(SourceLen);
12802 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12806 APInt M =
C.isInt() ? (
APInt)
C.getInt() :
C.getFloat().bitcastToAPInt();
12807 ResultElements.push_back(M.isNegative() ?
T : F);
12810 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12812 case X86::BI__builtin_ia32_selectb_128:
12813 case X86::BI__builtin_ia32_selectb_256:
12814 case X86::BI__builtin_ia32_selectb_512:
12815 case X86::BI__builtin_ia32_selectw_128:
12816 case X86::BI__builtin_ia32_selectw_256:
12817 case X86::BI__builtin_ia32_selectw_512:
12818 case X86::BI__builtin_ia32_selectd_128:
12819 case X86::BI__builtin_ia32_selectd_256:
12820 case X86::BI__builtin_ia32_selectd_512:
12821 case X86::BI__builtin_ia32_selectq_128:
12822 case X86::BI__builtin_ia32_selectq_256:
12823 case X86::BI__builtin_ia32_selectq_512:
12824 case X86::BI__builtin_ia32_selectph_128:
12825 case X86::BI__builtin_ia32_selectph_256:
12826 case X86::BI__builtin_ia32_selectph_512:
12827 case X86::BI__builtin_ia32_selectpbf_128:
12828 case X86::BI__builtin_ia32_selectpbf_256:
12829 case X86::BI__builtin_ia32_selectpbf_512:
12830 case X86::BI__builtin_ia32_selectps_128:
12831 case X86::BI__builtin_ia32_selectps_256:
12832 case X86::BI__builtin_ia32_selectps_512:
12833 case X86::BI__builtin_ia32_selectpd_128:
12834 case X86::BI__builtin_ia32_selectpd_256:
12835 case X86::BI__builtin_ia32_selectpd_512: {
12837 APValue SourceMask, SourceLHS, SourceRHS;
12846 ResultElements.reserve(SourceLen);
12848 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12851 ResultElements.push_back(Mask[EltNum] ? LHS : RHS);
12854 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12856 case X86::BI__builtin_ia32_shufps:
12857 case X86::BI__builtin_ia32_shufps256:
12858 case X86::BI__builtin_ia32_shufps512: {
12862 [](
unsigned DstIdx,
12863 unsigned ShuffleMask) -> std::pair<unsigned, int> {
12864 constexpr unsigned LaneBits = 128u;
12865 unsigned NumElemPerLane = LaneBits / 32;
12866 unsigned NumSelectableElems = NumElemPerLane / 2;
12867 unsigned BitsPerElem = 2;
12868 unsigned IndexMask = (1u << BitsPerElem) - 1;
12869 unsigned MaskBits = 8;
12870 unsigned Lane = DstIdx / NumElemPerLane;
12871 unsigned ElemInLane = DstIdx % NumElemPerLane;
12872 unsigned LaneOffset = Lane * NumElemPerLane;
12873 unsigned BitIndex = (DstIdx * BitsPerElem) % MaskBits;
12874 unsigned SrcIdx = (ElemInLane < NumSelectableElems) ? 0 : 1;
12875 unsigned Index = (ShuffleMask >> BitIndex) & IndexMask;
12876 return {SrcIdx,
static_cast<int>(LaneOffset + Index)};
12881 case X86::BI__builtin_ia32_shufpd:
12882 case X86::BI__builtin_ia32_shufpd256:
12883 case X86::BI__builtin_ia32_shufpd512: {
12887 [](
unsigned DstIdx,
12888 unsigned ShuffleMask) -> std::pair<unsigned, int> {
12889 constexpr unsigned LaneBits = 128u;
12890 unsigned NumElemPerLane = LaneBits / 64;
12891 unsigned NumSelectableElems = NumElemPerLane / 2;
12892 unsigned BitsPerElem = 1;
12893 unsigned IndexMask = (1u << BitsPerElem) - 1;
12894 unsigned MaskBits = 8;
12895 unsigned Lane = DstIdx / NumElemPerLane;
12896 unsigned ElemInLane = DstIdx % NumElemPerLane;
12897 unsigned LaneOffset = Lane * NumElemPerLane;
12898 unsigned BitIndex = (DstIdx * BitsPerElem) % MaskBits;
12899 unsigned SrcIdx = (ElemInLane < NumSelectableElems) ? 0 : 1;
12900 unsigned Index = (ShuffleMask >> BitIndex) & IndexMask;
12901 return {SrcIdx,
static_cast<int>(LaneOffset + Index)};
12906 case X86::BI__builtin_ia32_insertps128: {
12910 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
12912 if ((Mask & (1 << DstIdx)) != 0) {
12917 unsigned SrcElem = (Mask >> 6) & 0x3;
12918 unsigned DstElem = (Mask >> 4) & 0x3;
12919 if (DstIdx == DstElem) {
12921 return {1,
static_cast<int>(SrcElem)};
12924 return {0,
static_cast<int>(DstIdx)};
12930 case X86::BI__builtin_ia32_pshufb128:
12931 case X86::BI__builtin_ia32_pshufb256:
12932 case X86::BI__builtin_ia32_pshufb512: {
12936 [](
unsigned DstIdx,
12937 unsigned ShuffleMask) -> std::pair<unsigned, int> {
12938 uint8_t Ctlb =
static_cast<uint8_t
>(ShuffleMask);
12940 return std::make_pair(0, -1);
12942 unsigned LaneBase = (DstIdx / 16) * 16;
12943 unsigned SrcOffset = Ctlb & 0x0F;
12944 unsigned SrcIdx = LaneBase + SrcOffset;
12945 return std::make_pair(0,
static_cast<int>(SrcIdx));
12951 case X86::BI__builtin_ia32_pshuflw:
12952 case X86::BI__builtin_ia32_pshuflw256:
12953 case X86::BI__builtin_ia32_pshuflw512: {
12957 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
12958 constexpr unsigned LaneBits = 128u;
12959 constexpr unsigned ElemBits = 16u;
12960 constexpr unsigned LaneElts = LaneBits / ElemBits;
12961 constexpr unsigned HalfSize = 4;
12962 unsigned LaneBase = (DstIdx / LaneElts) * LaneElts;
12963 unsigned LaneIdx = DstIdx % LaneElts;
12964 if (LaneIdx < HalfSize) {
12965 unsigned Sel = (Mask >> (2 * LaneIdx)) & 0x3;
12966 return std::make_pair(0,
static_cast<int>(LaneBase + Sel));
12968 return std::make_pair(0,
static_cast<int>(DstIdx));
12974 case X86::BI__builtin_ia32_pshufhw:
12975 case X86::BI__builtin_ia32_pshufhw256:
12976 case X86::BI__builtin_ia32_pshufhw512: {
12980 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
12981 constexpr unsigned LaneBits = 128u;
12982 constexpr unsigned ElemBits = 16u;
12983 constexpr unsigned LaneElts = LaneBits / ElemBits;
12984 constexpr unsigned HalfSize = 4;
12985 unsigned LaneBase = (DstIdx / LaneElts) * LaneElts;
12986 unsigned LaneIdx = DstIdx % LaneElts;
12987 if (LaneIdx >= HalfSize) {
12988 unsigned Rel = LaneIdx - HalfSize;
12989 unsigned Sel = (Mask >> (2 * Rel)) & 0x3;
12990 return std::make_pair(
12991 0,
static_cast<int>(LaneBase + HalfSize + Sel));
12993 return std::make_pair(0,
static_cast<int>(DstIdx));
12999 case X86::BI__builtin_ia32_pshufd:
13000 case X86::BI__builtin_ia32_pshufd256:
13001 case X86::BI__builtin_ia32_pshufd512: {
13005 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13006 constexpr unsigned LaneBits = 128u;
13007 constexpr unsigned ElemBits = 32u;
13008 constexpr unsigned LaneElts = LaneBits / ElemBits;
13009 unsigned LaneBase = (DstIdx / LaneElts) * LaneElts;
13010 unsigned LaneIdx = DstIdx % LaneElts;
13011 unsigned Sel = (Mask >> (2 * LaneIdx)) & 0x3;
13012 return std::make_pair(0,
static_cast<int>(LaneBase + Sel));
13018 case X86::BI__builtin_ia32_phminposuw128: {
13025 unsigned ElemBitWidth = Info.Ctx.
getTypeSize(ElemQT);
13027 APInt MinIndex(ElemBitWidth, 0);
13029 for (
unsigned I = 1; I != SourceLen; ++I) {
13031 if (MinVal.ugt(Val)) {
13040 ->isUnsignedIntegerOrEnumerationType();
13043 Result.reserve(SourceLen);
13045 Result.emplace_back(
APSInt(MinIndex, ResultUnsigned));
13046 for (
unsigned I = 0; I != SourceLen - 2; ++I) {
13052 case X86::BI__builtin_ia32_pternlogd128_mask:
13053 case X86::BI__builtin_ia32_pternlogd256_mask:
13054 case X86::BI__builtin_ia32_pternlogd512_mask:
13055 case X86::BI__builtin_ia32_pternlogq128_mask:
13056 case X86::BI__builtin_ia32_pternlogq256_mask:
13057 case X86::BI__builtin_ia32_pternlogq512_mask: {
13058 APValue AValue, BValue, CValue, ImmValue, UValue;
13066 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13072 ResultElements.reserve(ResultLen);
13074 for (
unsigned EltNum = 0; EltNum < ResultLen; ++EltNum) {
13080 unsigned BitWidth = ALane.getBitWidth();
13081 APInt ResLane(BitWidth, 0);
13083 for (
unsigned Bit = 0; Bit < BitWidth; ++Bit) {
13084 unsigned ABit = ALane[Bit];
13085 unsigned BBit = BLane[Bit];
13086 unsigned CBit = CLane[Bit];
13088 unsigned Idx = (ABit << 2) | (BBit << 1) | CBit;
13089 ResLane.setBitVal(Bit, Imm[Idx]);
13091 ResultElements.push_back(
APValue(
APSInt(ResLane, DestUnsigned)));
13093 ResultElements.push_back(
APValue(
APSInt(ALane, DestUnsigned)));
13096 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13098 case X86::BI__builtin_ia32_pternlogd128_maskz:
13099 case X86::BI__builtin_ia32_pternlogd256_maskz:
13100 case X86::BI__builtin_ia32_pternlogd512_maskz:
13101 case X86::BI__builtin_ia32_pternlogq128_maskz:
13102 case X86::BI__builtin_ia32_pternlogq256_maskz:
13103 case X86::BI__builtin_ia32_pternlogq512_maskz: {
13104 APValue AValue, BValue, CValue, ImmValue, UValue;
13112 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13118 ResultElements.reserve(ResultLen);
13120 for (
unsigned EltNum = 0; EltNum < ResultLen; ++EltNum) {
13125 unsigned BitWidth = ALane.getBitWidth();
13126 APInt ResLane(BitWidth, 0);
13129 for (
unsigned Bit = 0; Bit < BitWidth; ++Bit) {
13130 unsigned ABit = ALane[Bit];
13131 unsigned BBit = BLane[Bit];
13132 unsigned CBit = CLane[Bit];
13134 unsigned Idx = (ABit << 2) | (BBit << 1) | CBit;
13135 ResLane.setBitVal(Bit, Imm[Idx]);
13138 ResultElements.push_back(
APValue(
APSInt(ResLane, DestUnsigned)));
13140 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13143 case Builtin::BI__builtin_elementwise_clzg:
13144 case Builtin::BI__builtin_elementwise_ctzg: {
13146 std::optional<APValue> Fallback;
13153 Fallback = FallbackTmp;
13156 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13159 ResultElements.reserve(SourceLen);
13161 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13166 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
13168 Builtin::BI__builtin_elementwise_ctzg);
13171 ResultElements.push_back(Fallback->getVectorElt(EltNum));
13175 case Builtin::BI__builtin_elementwise_clzg:
13176 ResultElements.push_back(
APValue(
13180 case Builtin::BI__builtin_elementwise_ctzg:
13181 ResultElements.push_back(
APValue(
13188 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13191 case Builtin::BI__builtin_elementwise_fma: {
13192 APValue SourceX, SourceY, SourceZ;
13200 ResultElements.reserve(SourceLen);
13202 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13207 (void)
Result.fusedMultiplyAdd(Y, Z, RM);
13210 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13213 case clang::X86::BI__builtin_ia32_phaddw128:
13214 case clang::X86::BI__builtin_ia32_phaddw256:
13215 case clang::X86::BI__builtin_ia32_phaddd128:
13216 case clang::X86::BI__builtin_ia32_phaddd256:
13217 case clang::X86::BI__builtin_ia32_phaddsw128:
13218 case clang::X86::BI__builtin_ia32_phaddsw256:
13220 case clang::X86::BI__builtin_ia32_phsubw128:
13221 case clang::X86::BI__builtin_ia32_phsubw256:
13222 case clang::X86::BI__builtin_ia32_phsubd128:
13223 case clang::X86::BI__builtin_ia32_phsubd256:
13224 case clang::X86::BI__builtin_ia32_phsubsw128:
13225 case clang::X86::BI__builtin_ia32_phsubsw256: {
13226 APValue SourceLHS, SourceRHS;
13230 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13234 unsigned EltBits = Info.Ctx.
getIntWidth(DestEltTy);
13235 unsigned EltsPerLane = 128 / EltBits;
13237 ResultElements.reserve(NumElts);
13239 for (
unsigned LaneStart = 0; LaneStart != NumElts;
13240 LaneStart += EltsPerLane) {
13241 for (
unsigned I = 0; I != EltsPerLane; I += 2) {
13245 case clang::X86::BI__builtin_ia32_phaddw128:
13246 case clang::X86::BI__builtin_ia32_phaddw256:
13247 case clang::X86::BI__builtin_ia32_phaddd128:
13248 case clang::X86::BI__builtin_ia32_phaddd256: {
13249 APSInt Res(LHSA + LHSB, DestUnsigned);
13250 ResultElements.push_back(
APValue(Res));
13253 case clang::X86::BI__builtin_ia32_phaddsw128:
13254 case clang::X86::BI__builtin_ia32_phaddsw256: {
13255 APSInt Res(LHSA.sadd_sat(LHSB));
13256 ResultElements.push_back(
APValue(Res));
13259 case clang::X86::BI__builtin_ia32_phsubw128:
13260 case clang::X86::BI__builtin_ia32_phsubw256:
13261 case clang::X86::BI__builtin_ia32_phsubd128:
13262 case clang::X86::BI__builtin_ia32_phsubd256: {
13263 APSInt Res(LHSA - LHSB, DestUnsigned);
13264 ResultElements.push_back(
APValue(Res));
13267 case clang::X86::BI__builtin_ia32_phsubsw128:
13268 case clang::X86::BI__builtin_ia32_phsubsw256: {
13269 APSInt Res(LHSA.ssub_sat(LHSB));
13270 ResultElements.push_back(
APValue(Res));
13275 for (
unsigned I = 0; I != EltsPerLane; I += 2) {
13279 case clang::X86::BI__builtin_ia32_phaddw128:
13280 case clang::X86::BI__builtin_ia32_phaddw256:
13281 case clang::X86::BI__builtin_ia32_phaddd128:
13282 case clang::X86::BI__builtin_ia32_phaddd256: {
13283 APSInt Res(RHSA + RHSB, DestUnsigned);
13284 ResultElements.push_back(
APValue(Res));
13287 case clang::X86::BI__builtin_ia32_phaddsw128:
13288 case clang::X86::BI__builtin_ia32_phaddsw256: {
13289 APSInt Res(RHSA.sadd_sat(RHSB));
13290 ResultElements.push_back(
APValue(Res));
13293 case clang::X86::BI__builtin_ia32_phsubw128:
13294 case clang::X86::BI__builtin_ia32_phsubw256:
13295 case clang::X86::BI__builtin_ia32_phsubd128:
13296 case clang::X86::BI__builtin_ia32_phsubd256: {
13297 APSInt Res(RHSA - RHSB, DestUnsigned);
13298 ResultElements.push_back(
APValue(Res));
13301 case clang::X86::BI__builtin_ia32_phsubsw128:
13302 case clang::X86::BI__builtin_ia32_phsubsw256: {
13303 APSInt Res(RHSA.ssub_sat(RHSB));
13304 ResultElements.push_back(
APValue(Res));
13310 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13312 case clang::X86::BI__builtin_ia32_haddpd:
13313 case clang::X86::BI__builtin_ia32_haddps:
13314 case clang::X86::BI__builtin_ia32_haddps256:
13315 case clang::X86::BI__builtin_ia32_haddpd256:
13316 case clang::X86::BI__builtin_ia32_hsubpd:
13317 case clang::X86::BI__builtin_ia32_hsubps:
13318 case clang::X86::BI__builtin_ia32_hsubps256:
13319 case clang::X86::BI__builtin_ia32_hsubpd256: {
13320 APValue SourceLHS, SourceRHS;
13326 ResultElements.reserve(NumElts);
13328 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13329 unsigned EltBits = Info.Ctx.
getTypeSize(DestEltTy);
13330 unsigned NumLanes = NumElts * EltBits / 128;
13331 unsigned NumElemsPerLane = NumElts / NumLanes;
13332 unsigned HalfElemsPerLane = NumElemsPerLane / 2;
13334 for (
unsigned L = 0; L != NumElts; L += NumElemsPerLane) {
13335 for (
unsigned I = 0; I != HalfElemsPerLane; ++I) {
13339 case clang::X86::BI__builtin_ia32_haddpd:
13340 case clang::X86::BI__builtin_ia32_haddps:
13341 case clang::X86::BI__builtin_ia32_haddps256:
13342 case clang::X86::BI__builtin_ia32_haddpd256:
13343 LHSA.add(LHSB, RM);
13345 case clang::X86::BI__builtin_ia32_hsubpd:
13346 case clang::X86::BI__builtin_ia32_hsubps:
13347 case clang::X86::BI__builtin_ia32_hsubps256:
13348 case clang::X86::BI__builtin_ia32_hsubpd256:
13349 LHSA.subtract(LHSB, RM);
13352 ResultElements.push_back(
APValue(LHSA));
13354 for (
unsigned I = 0; I != HalfElemsPerLane; ++I) {
13358 case clang::X86::BI__builtin_ia32_haddpd:
13359 case clang::X86::BI__builtin_ia32_haddps:
13360 case clang::X86::BI__builtin_ia32_haddps256:
13361 case clang::X86::BI__builtin_ia32_haddpd256:
13362 RHSA.add(RHSB, RM);
13364 case clang::X86::BI__builtin_ia32_hsubpd:
13365 case clang::X86::BI__builtin_ia32_hsubps:
13366 case clang::X86::BI__builtin_ia32_hsubps256:
13367 case clang::X86::BI__builtin_ia32_hsubpd256:
13368 RHSA.subtract(RHSB, RM);
13371 ResultElements.push_back(
APValue(RHSA));
13374 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13376 case clang::X86::BI__builtin_ia32_addsubpd:
13377 case clang::X86::BI__builtin_ia32_addsubps:
13378 case clang::X86::BI__builtin_ia32_addsubpd256:
13379 case clang::X86::BI__builtin_ia32_addsubps256: {
13382 APValue SourceLHS, SourceRHS;
13388 ResultElements.reserve(NumElems);
13391 for (
unsigned I = 0; I != NumElems; ++I) {
13396 LHS.subtract(RHS, RM);
13401 ResultElements.push_back(
APValue(LHS));
13403 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13405 case Builtin::BI__builtin_elementwise_fshl:
13406 case Builtin::BI__builtin_elementwise_fshr: {
13407 APValue SourceHi, SourceLo, SourceShift;
13413 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13419 ResultElements.reserve(SourceLen);
13420 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13425 case Builtin::BI__builtin_elementwise_fshl:
13426 ResultElements.push_back(
APValue(
13427 APSInt(llvm::APIntOps::fshl(Hi, Lo, Shift), Hi.isUnsigned())));
13429 case Builtin::BI__builtin_elementwise_fshr:
13430 ResultElements.push_back(
APValue(
13431 APSInt(llvm::APIntOps::fshr(Hi, Lo, Shift), Hi.isUnsigned())));
13436 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13439 case X86::BI__builtin_ia32_insertf32x4_256:
13440 case X86::BI__builtin_ia32_inserti32x4_256:
13441 case X86::BI__builtin_ia32_insertf64x2_256:
13442 case X86::BI__builtin_ia32_inserti64x2_256:
13443 case X86::BI__builtin_ia32_insertf32x4:
13444 case X86::BI__builtin_ia32_inserti32x4:
13445 case X86::BI__builtin_ia32_insertf64x2_512:
13446 case X86::BI__builtin_ia32_inserti64x2_512:
13447 case X86::BI__builtin_ia32_insertf32x8:
13448 case X86::BI__builtin_ia32_inserti32x8:
13449 case X86::BI__builtin_ia32_insertf64x4:
13450 case X86::BI__builtin_ia32_inserti64x4:
13451 case X86::BI__builtin_ia32_vinsertf128_ps256:
13452 case X86::BI__builtin_ia32_vinsertf128_pd256:
13453 case X86::BI__builtin_ia32_vinsertf128_si256:
13454 case X86::BI__builtin_ia32_insert128i256: {
13455 APValue SourceDst, SourceSub;
13467 assert(SubLen != 0 && DstLen != 0 && (DstLen % SubLen) == 0);
13468 unsigned NumLanes = DstLen / SubLen;
13469 unsigned LaneIdx = (Imm.getZExtValue() % NumLanes) * SubLen;
13472 ResultElements.reserve(DstLen);
13474 for (
unsigned EltNum = 0; EltNum < DstLen; ++EltNum) {
13475 if (EltNum >= LaneIdx && EltNum < LaneIdx + SubLen)
13476 ResultElements.push_back(SourceSub.
getVectorElt(EltNum - LaneIdx));
13478 ResultElements.push_back(SourceDst.
getVectorElt(EltNum));
13481 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13484 case clang::X86::BI__builtin_ia32_vec_set_v4hi:
13485 case clang::X86::BI__builtin_ia32_vec_set_v16qi:
13486 case clang::X86::BI__builtin_ia32_vec_set_v8hi:
13487 case clang::X86::BI__builtin_ia32_vec_set_v4si:
13488 case clang::X86::BI__builtin_ia32_vec_set_v2di:
13489 case clang::X86::BI__builtin_ia32_vec_set_v32qi:
13490 case clang::X86::BI__builtin_ia32_vec_set_v16hi:
13491 case clang::X86::BI__builtin_ia32_vec_set_v8si:
13492 case clang::X86::BI__builtin_ia32_vec_set_v4di: {
13500 QualType ElemTy = E->
getType()->
castAs<VectorType>()->getElementType();
13501 unsigned ElemWidth = Info.Ctx.
getIntWidth(ElemTy);
13503 Scalar.setIsUnsigned(ElemUnsigned);
13509 static_cast<unsigned>(IndexAPS.getZExtValue() & (NumElems - 1));
13512 Elems.reserve(NumElems);
13513 for (
unsigned ElemNum = 0; ElemNum != NumElems; ++ElemNum)
13514 Elems.push_back(ElemNum == Index ? ElemAV : VecVal.
getVectorElt(ElemNum));
13519 case X86::BI__builtin_ia32_pslldqi128_byteshift:
13520 case X86::BI__builtin_ia32_pslldqi256_byteshift:
13521 case X86::BI__builtin_ia32_pslldqi512_byteshift: {
13525 [](
unsigned DstIdx,
unsigned Shift) -> std::pair<unsigned, int> {
13526 unsigned LaneBase = (DstIdx / 16) * 16;
13527 unsigned LaneIdx = DstIdx % 16;
13528 if (LaneIdx < Shift)
13529 return std::make_pair(0, -1);
13531 return std::make_pair(
13532 0,
static_cast<int>(LaneBase + LaneIdx - Shift));
13538 case X86::BI__builtin_ia32_psrldqi128_byteshift:
13539 case X86::BI__builtin_ia32_psrldqi256_byteshift:
13540 case X86::BI__builtin_ia32_psrldqi512_byteshift: {
13544 [](
unsigned DstIdx,
unsigned Shift) -> std::pair<unsigned, int> {
13545 unsigned LaneBase = (DstIdx / 16) * 16;
13546 unsigned LaneIdx = DstIdx % 16;
13547 if (LaneIdx + Shift < 16)
13548 return std::make_pair(
13549 0,
static_cast<int>(LaneBase + LaneIdx + Shift));
13551 return std::make_pair(0, -1);
13557 case X86::BI__builtin_ia32_palignr128:
13558 case X86::BI__builtin_ia32_palignr256:
13559 case X86::BI__builtin_ia32_palignr512: {
13563 unsigned VecIdx = 1;
13566 int Lane = DstIdx / 16;
13567 int Offset = DstIdx % 16;
13570 unsigned ShiftedIdx = Offset + (
Shift & 0xFF);
13571 if (ShiftedIdx < 16) {
13572 ElemIdx = ShiftedIdx + (Lane * 16);
13573 }
else if (ShiftedIdx < 32) {
13575 ElemIdx = (ShiftedIdx - 16) + (Lane * 16);
13578 return std::pair<unsigned, int>{VecIdx, ElemIdx};
13583 case X86::BI__builtin_ia32_permvarsi256:
13584 case X86::BI__builtin_ia32_permvarsf256:
13585 case X86::BI__builtin_ia32_permvardf512:
13586 case X86::BI__builtin_ia32_permvardi512:
13587 case X86::BI__builtin_ia32_permvarhi128: {
13590 [](
unsigned DstIdx,
unsigned ShuffleMask) {
13591 int Offset = ShuffleMask & 0x7;
13592 return std::pair<unsigned, int>{0, Offset};
13597 case X86::BI__builtin_ia32_permvarqi128:
13598 case X86::BI__builtin_ia32_permvarhi256:
13599 case X86::BI__builtin_ia32_permvarsi512:
13600 case X86::BI__builtin_ia32_permvarsf512: {
13603 [](
unsigned DstIdx,
unsigned ShuffleMask) {
13604 int Offset = ShuffleMask & 0xF;
13605 return std::pair<unsigned, int>{0, Offset};
13610 case X86::BI__builtin_ia32_permvardi256:
13611 case X86::BI__builtin_ia32_permvardf256: {
13614 [](
unsigned DstIdx,
unsigned ShuffleMask) {
13615 int Offset = ShuffleMask & 0x3;
13616 return std::pair<unsigned, int>{0, Offset};
13621 case X86::BI__builtin_ia32_permvarqi256:
13622 case X86::BI__builtin_ia32_permvarhi512: {
13625 [](
unsigned DstIdx,
unsigned ShuffleMask) {
13626 int Offset = ShuffleMask & 0x1F;
13627 return std::pair<unsigned, int>{0, Offset};
13632 case X86::BI__builtin_ia32_permvarqi512: {
13635 [](
unsigned DstIdx,
unsigned ShuffleMask) {
13636 int Offset = ShuffleMask & 0x3F;
13637 return std::pair<unsigned, int>{0, Offset};
13642 case X86::BI__builtin_ia32_vpermi2varq128:
13643 case X86::BI__builtin_ia32_vpermi2varpd128: {
13646 [](
unsigned DstIdx,
unsigned ShuffleMask) {
13647 int Offset = ShuffleMask & 0x1;
13648 unsigned SrcIdx = (ShuffleMask >> 1) & 0x1;
13649 return std::pair<unsigned, int>{SrcIdx, Offset};
13654 case X86::BI__builtin_ia32_vpermi2vard128:
13655 case X86::BI__builtin_ia32_vpermi2varps128:
13656 case X86::BI__builtin_ia32_vpermi2varq256:
13657 case X86::BI__builtin_ia32_vpermi2varpd256: {
13660 [](
unsigned DstIdx,
unsigned ShuffleMask) {
13661 int Offset = ShuffleMask & 0x3;
13662 unsigned SrcIdx = (ShuffleMask >> 2) & 0x1;
13663 return std::pair<unsigned, int>{SrcIdx, Offset};
13668 case X86::BI__builtin_ia32_vpermi2varhi128:
13669 case X86::BI__builtin_ia32_vpermi2vard256:
13670 case X86::BI__builtin_ia32_vpermi2varps256:
13671 case X86::BI__builtin_ia32_vpermi2varq512:
13672 case X86::BI__builtin_ia32_vpermi2varpd512: {
13675 [](
unsigned DstIdx,
unsigned ShuffleMask) {
13676 int Offset = ShuffleMask & 0x7;
13677 unsigned SrcIdx = (ShuffleMask >> 3) & 0x1;
13678 return std::pair<unsigned, int>{SrcIdx, Offset};
13683 case X86::BI__builtin_ia32_vpermi2varqi128:
13684 case X86::BI__builtin_ia32_vpermi2varhi256:
13685 case X86::BI__builtin_ia32_vpermi2vard512:
13686 case X86::BI__builtin_ia32_vpermi2varps512: {
13689 [](
unsigned DstIdx,
unsigned ShuffleMask) {
13690 int Offset = ShuffleMask & 0xF;
13691 unsigned SrcIdx = (ShuffleMask >> 4) & 0x1;
13692 return std::pair<unsigned, int>{SrcIdx, Offset};
13697 case X86::BI__builtin_ia32_vpermi2varqi256:
13698 case X86::BI__builtin_ia32_vpermi2varhi512: {
13701 [](
unsigned DstIdx,
unsigned ShuffleMask) {
13702 int Offset = ShuffleMask & 0x1F;
13703 unsigned SrcIdx = (ShuffleMask >> 5) & 0x1;
13704 return std::pair<unsigned, int>{SrcIdx, Offset};
13709 case X86::BI__builtin_ia32_vpermi2varqi512: {
13712 [](
unsigned DstIdx,
unsigned ShuffleMask) {
13713 int Offset = ShuffleMask & 0x3F;
13714 unsigned SrcIdx = (ShuffleMask >> 6) & 0x1;
13715 return std::pair<unsigned, int>{SrcIdx, Offset};
13723bool VectorExprEvaluator::VisitConvertVectorExpr(
const ConvertVectorExpr *E) {
13729 QualType DestTy = E->
getType()->
castAs<VectorType>()->getElementType();
13730 QualType SourceTy = SourceVecType->
castAs<VectorType>()->getElementType();
13736 ResultElements.reserve(SourceLen);
13737 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13742 ResultElements.push_back(std::move(Elt));
13745 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13750 APValue const &VecVal2,
unsigned EltNum,
13752 unsigned const TotalElementsInInputVector1 = VecVal1.
getVectorLength();
13753 unsigned const TotalElementsInInputVector2 = VecVal2.
getVectorLength();
13756 int64_t
index = IndexVal.getExtValue();
13763 E, diag::err_shufflevector_minus_one_is_undefined_behavior_constexpr)
13769 index >= TotalElementsInInputVector1 + TotalElementsInInputVector2)
13770 llvm_unreachable(
"Out of bounds shuffle index");
13772 if (
index >= TotalElementsInInputVector1)
13779bool VectorExprEvaluator::VisitShuffleVectorExpr(
const ShuffleVectorExpr *E) {
13784 const Expr *Vec1 = E->
getExpr(0);
13788 const Expr *Vec2 = E->
getExpr(1);
13792 VectorType
const *DestVecTy = E->
getType()->
castAs<VectorType>();
13798 ResultElements.reserve(TotalElementsInOutputVector);
13799 for (
unsigned EltNum = 0; EltNum < TotalElementsInOutputVector; ++EltNum) {
13803 ResultElements.push_back(std::move(Elt));
13806 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13814 class ArrayExprEvaluator
13815 :
public ExprEvaluatorBase<ArrayExprEvaluator> {
13816 const LValue &
This;
13820 ArrayExprEvaluator(EvalInfo &Info,
const LValue &This,
APValue &
Result)
13824 assert(
V.isArray() &&
"expected array");
13829 bool ZeroInitialization(
const Expr *E) {
13830 const ConstantArrayType *CAT =
13845 if (!
Result.hasArrayFiller())
13849 LValue Subobject =
This;
13850 Subobject.addArray(Info, E, CAT);
13855 bool VisitCallExpr(
const CallExpr *E) {
13856 return handleCallExpr(E,
Result, &This);
13858 bool VisitCastExpr(
const CastExpr *E);
13859 bool VisitInitListExpr(
const InitListExpr *E,
13860 QualType AllocType = QualType());
13861 bool VisitArrayInitLoopExpr(
const ArrayInitLoopExpr *E);
13862 bool VisitCXXConstructExpr(
const CXXConstructExpr *E);
13863 bool VisitCXXConstructExpr(
const CXXConstructExpr *E,
13864 const LValue &Subobject,
13866 bool VisitStringLiteral(
const StringLiteral *E,
13867 QualType AllocType = QualType()) {
13871 bool VisitCXXParenListInitExpr(
const CXXParenListInitExpr *E);
13872 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
13873 ArrayRef<Expr *> Args,
13874 const Expr *ArrayFiller,
13875 QualType AllocType = QualType());
13880 APValue &Result, EvalInfo &Info) {
13883 "not an array prvalue");
13884 return ArrayExprEvaluator(Info,
This, Result).Visit(E);
13892 "not an array prvalue");
13893 return ArrayExprEvaluator(Info,
This, Result)
13894 .VisitInitListExpr(ILE, AllocType);
13903 "not an array prvalue");
13904 return ArrayExprEvaluator(Info,
This, Result)
13905 .VisitCXXConstructExpr(CCE,
This, &Result, AllocType);
13914 if (
const InitListExpr *ILE = dyn_cast<InitListExpr>(FillerExpr)) {
13915 for (
unsigned I = 0, E = ILE->
getNumInits(); I != E; ++I) {
13920 if (ILE->hasArrayFiller() &&
13929bool ArrayExprEvaluator::VisitCastExpr(
const CastExpr *E) {
13934 return ExprEvaluatorBaseTy::VisitCastExpr(E);
13935 case CK_HLSLAggregateSplatCast: {
13955 case CK_HLSLElementwiseCast: {
13972bool ArrayExprEvaluator::VisitInitListExpr(
const InitListExpr *E,
13973 QualType AllocType) {
13987 return VisitStringLiteral(SL, AllocType);
13992 "transparent array list initialization is not string literal init?");
13998bool ArrayExprEvaluator::VisitCXXParenListOrInitListExpr(
14000 QualType AllocType) {
14006 assert((!
Result.isArray() ||
Result.getArrayInitializedElts() == 0) &&
14007 "zero-initialized array shouldn't have any initialized elts");
14012 unsigned NumEltsToInit = Args.size();
14017 if (NumEltsToInit != NumElts &&
14019 NumEltsToInit = NumElts;
14021 for (
auto *
Init : Args) {
14022 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts()))
14023 NumEltsToInit += EmbedS->getDataElementCount() - 1;
14025 if (NumEltsToInit > NumElts)
14026 NumEltsToInit = NumElts;
14029 LLVM_DEBUG(llvm::dbgs() <<
"The number of elements to initialize: "
14030 << NumEltsToInit <<
".\n");
14032 Result =
APValue(APValue::UninitArray(), NumEltsToInit, NumElts);
14037 for (
unsigned I = 0, E =
Result.getArrayInitializedElts(); I != E; ++I)
14038 Result.getArrayInitializedElt(I) = Filler;
14039 if (
Result.hasArrayFiller())
14043 LValue Subobject =
This;
14044 Subobject.addArray(Info, ExprToVisit, CAT);
14045 auto Eval = [&](
const Expr *
Init,
unsigned ArrayIndex) {
14046 if (
Init->isValueDependent())
14050 Subobject,
Init) ||
14053 if (!Info.noteFailure())
14059 unsigned ArrayIndex = 0;
14062 for (
unsigned Index = 0; Index != NumEltsToInit; ++Index) {
14063 const Expr *
Init = Index < Args.size() ? Args[Index] : ArrayFiller;
14064 if (ArrayIndex >= NumEltsToInit)
14066 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
14067 StringLiteral *SL = EmbedS->getDataStringLiteral();
14068 for (
unsigned I = EmbedS->getStartingElementPos(),
14069 N = EmbedS->getDataElementCount();
14070 I != EmbedS->getStartingElementPos() + N; ++I) {
14076 const FPOptions FPO =
14082 Result.getArrayInitializedElt(ArrayIndex) =
APValue(FValue);
14087 if (!Eval(
Init, ArrayIndex))
14093 if (!
Result.hasArrayFiller())
14098 assert(ArrayFiller &&
"no array filler for incomplete init list");
14104bool ArrayExprEvaluator::VisitArrayInitLoopExpr(
const ArrayInitLoopExpr *E) {
14107 !
Evaluate(Info.CurrentCall->createTemporary(
14110 ScopeKind::FullExpression, CommonLV),
14117 Result =
APValue(APValue::UninitArray(), Elements, Elements);
14119 LValue Subobject =
This;
14120 Subobject.addArray(Info, E, CAT);
14123 for (EvalInfo::ArrayInitLoopIndex Index(Info); Index != Elements; ++Index) {
14132 FullExpressionRAII Scope(Info);
14138 if (!Info.noteFailure())
14150bool ArrayExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E) {
14151 return VisitCXXConstructExpr(E, This, &
Result, E->
getType());
14154bool ArrayExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E,
14155 const LValue &Subobject,
14158 bool HadZeroInit =
Value->hasValue();
14165 HadZeroInit &&
Value->hasArrayFiller() ?
Value->getArrayFiller()
14168 *
Value =
APValue(APValue::UninitArray(), 0, FinalSize);
14169 if (FinalSize == 0)
14175 LValue ArrayElt = Subobject;
14176 ArrayElt.addArray(Info, E, CAT);
14182 for (
const unsigned N : {1u, FinalSize}) {
14183 unsigned OldElts =
Value->getArrayInitializedElts();
14188 APValue NewValue(APValue::UninitArray(), N, FinalSize);
14189 for (
unsigned I = 0; I < OldElts; ++I)
14190 NewValue.getArrayInitializedElt(I).swap(
14191 Value->getArrayInitializedElt(I));
14192 Value->swap(NewValue);
14195 for (
unsigned I = OldElts; I < N; ++I)
14196 Value->getArrayInitializedElt(I) = Filler;
14198 if (HasTrivialConstructor && N == FinalSize && FinalSize != 1) {
14201 APValue &FirstResult =
Value->getArrayInitializedElt(0);
14202 for (
unsigned I = OldElts; I < FinalSize; ++I)
14203 Value->getArrayInitializedElt(I) = FirstResult;
14205 for (
unsigned I = OldElts; I < N; ++I) {
14206 if (!VisitCXXConstructExpr(E, ArrayElt,
14207 &
Value->getArrayInitializedElt(I),
14214 if (Info.EvalStatus.
Diag && !Info.EvalStatus.
Diag->empty() &&
14215 !Info.keepEvaluatingAfterFailure())
14224 if (!
Type->isRecordType())
14227 return RecordExprEvaluator(Info, Subobject, *
Value)
14228 .VisitCXXConstructExpr(E,
Type);
14231bool ArrayExprEvaluator::VisitCXXParenListInitExpr(
14232 const CXXParenListInitExpr *E) {
14234 "Expression result is not a constant array type");
14236 return VisitCXXParenListOrInitListExpr(E, E->
getInitExprs(),
14249class IntExprEvaluator
14250 :
public ExprEvaluatorBase<IntExprEvaluator> {
14253 IntExprEvaluator(EvalInfo &info,
APValue &result)
14254 : ExprEvaluatorBaseTy(info),
Result(result) {}
14258 "Invalid evaluation result.");
14260 "Invalid evaluation result.");
14262 "Invalid evaluation result.");
14266 bool Success(
const llvm::APSInt &SI,
const Expr *E) {
14272 "Invalid evaluation result.");
14274 "Invalid evaluation result.");
14276 Result.getInt().setIsUnsigned(
14280 bool Success(
const llvm::APInt &I,
const Expr *E) {
14286 "Invalid evaluation result.");
14294 bool Success(CharUnits Size,
const Expr *E) {
14301 if (
V.isLValue() ||
V.isAddrLabelDiff() ||
V.isIndeterminate() ||
14302 V.allowConstexprUnknown()) {
14309 bool ZeroInitialization(
const Expr *E) {
return Success(0, E); }
14311 friend std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &,
14318 bool VisitIntegerLiteral(
const IntegerLiteral *E) {
14321 bool VisitCharacterLiteral(
const CharacterLiteral *E) {
14325 bool CheckReferencedDecl(
const Expr *E,
const Decl *D);
14326 bool VisitDeclRefExpr(
const DeclRefExpr *E) {
14327 if (CheckReferencedDecl(E, E->
getDecl()))
14330 return ExprEvaluatorBaseTy::VisitDeclRefExpr(E);
14332 bool VisitMemberExpr(
const MemberExpr *E) {
14334 VisitIgnoredBaseExpression(E->
getBase());
14338 return ExprEvaluatorBaseTy::VisitMemberExpr(E);
14341 bool VisitCallExpr(
const CallExpr *E);
14342 bool VisitBuiltinCallExpr(
const CallExpr *E,
unsigned BuiltinOp);
14343 bool VisitBinaryOperator(
const BinaryOperator *E);
14344 bool VisitOffsetOfExpr(
const OffsetOfExpr *E);
14345 bool VisitUnaryOperator(
const UnaryOperator *E);
14347 bool VisitCastExpr(
const CastExpr* E);
14348 bool VisitUnaryExprOrTypeTraitExpr(
const UnaryExprOrTypeTraitExpr *E);
14350 bool VisitCXXBoolLiteralExpr(
const CXXBoolLiteralExpr *E) {
14354 bool VisitObjCBoolLiteralExpr(
const ObjCBoolLiteralExpr *E) {
14358 bool VisitArrayInitIndexExpr(
const ArrayInitIndexExpr *E) {
14359 if (Info.ArrayInitIndex ==
uint64_t(-1)) {
14365 return Success(Info.ArrayInitIndex, E);
14369 bool VisitGNUNullExpr(
const GNUNullExpr *E) {
14370 return ZeroInitialization(E);
14373 bool VisitTypeTraitExpr(
const TypeTraitExpr *E) {
14382 bool VisitArrayTypeTraitExpr(
const ArrayTypeTraitExpr *E) {
14386 bool VisitExpressionTraitExpr(
const ExpressionTraitExpr *E) {
14390 bool VisitOpenACCAsteriskSizeExpr(
const OpenACCAsteriskSizeExpr *E) {
14397 bool VisitUnaryReal(
const UnaryOperator *E);
14398 bool VisitUnaryImag(
const UnaryOperator *E);
14400 bool VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E);
14401 bool VisitSizeOfPackExpr(
const SizeOfPackExpr *E);
14402 bool VisitSourceLocExpr(
const SourceLocExpr *E);
14403 bool VisitConceptSpecializationExpr(
const ConceptSpecializationExpr *E);
14408class FixedPointExprEvaluator
14409 :
public ExprEvaluatorBase<FixedPointExprEvaluator> {
14413 FixedPointExprEvaluator(EvalInfo &info,
APValue &result)
14414 : ExprEvaluatorBaseTy(info),
Result(result) {}
14416 bool Success(
const llvm::APInt &I,
const Expr *E) {
14427 return Success(
V.getFixedPoint(), E);
14430 bool Success(
const APFixedPoint &
V,
const Expr *E) {
14433 "Invalid evaluation result.");
14438 bool ZeroInitialization(
const Expr *E) {
14446 bool VisitFixedPointLiteral(
const FixedPointLiteral *E) {
14450 bool VisitCastExpr(
const CastExpr *E);
14451 bool VisitUnaryOperator(
const UnaryOperator *E);
14452 bool VisitBinaryOperator(
const BinaryOperator *E);
14468 return IntExprEvaluator(Info, Result).Visit(E);
14476 if (!Val.
isInt()) {
14479 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
14486bool IntExprEvaluator::VisitSourceLocExpr(
const SourceLocExpr *E) {
14488 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.
getDefaultExpr());
14497 if (!FixedPointExprEvaluator(Info, Val).Visit(E))
14516 Result = APFixedPoint(Val, FXSema);
14527bool IntExprEvaluator::CheckReferencedDecl(
const Expr* E,
const Decl* D) {
14529 if (
const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(D)) {
14531 bool SameSign = (ECD->getInitVal().isSigned()
14533 bool SameWidth = (ECD->getInitVal().
getBitWidth()
14535 if (SameSign && SameWidth)
14536 return Success(ECD->getInitVal(), E);
14540 llvm::APSInt Val = ECD->getInitVal();
14542 Val.setIsSigned(!ECD->getInitVal().isSigned());
14555 assert(!
T->isDependentType() &&
"unexpected dependent type");
14560#define TYPE(ID, BASE)
14561#define DEPENDENT_TYPE(ID, BASE) case Type::ID:
14562#define NON_CANONICAL_TYPE(ID, BASE) case Type::ID:
14563#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(ID, BASE) case Type::ID:
14564#include "clang/AST/TypeNodes.inc"
14566 case Type::DeducedTemplateSpecialization:
14567 llvm_unreachable(
"unexpected non-canonical or dependent type");
14569 case Type::Builtin:
14571#define BUILTIN_TYPE(ID, SINGLETON_ID)
14572#define SIGNED_TYPE(ID, SINGLETON_ID) \
14573 case BuiltinType::ID: return GCCTypeClass::Integer;
14574#define FLOATING_TYPE(ID, SINGLETON_ID) \
14575 case BuiltinType::ID: return GCCTypeClass::RealFloat;
14576#define PLACEHOLDER_TYPE(ID, SINGLETON_ID) \
14577 case BuiltinType::ID: break;
14578#include "clang/AST/BuiltinTypes.def"
14579 case BuiltinType::Void:
14582 case BuiltinType::Bool:
14585 case BuiltinType::Char_U:
14586 case BuiltinType::UChar:
14587 case BuiltinType::WChar_U:
14588 case BuiltinType::Char8:
14589 case BuiltinType::Char16:
14590 case BuiltinType::Char32:
14591 case BuiltinType::UShort:
14592 case BuiltinType::UInt:
14593 case BuiltinType::ULong:
14594 case BuiltinType::ULongLong:
14595 case BuiltinType::UInt128:
14598 case BuiltinType::UShortAccum:
14599 case BuiltinType::UAccum:
14600 case BuiltinType::ULongAccum:
14601 case BuiltinType::UShortFract:
14602 case BuiltinType::UFract:
14603 case BuiltinType::ULongFract:
14604 case BuiltinType::SatUShortAccum:
14605 case BuiltinType::SatUAccum:
14606 case BuiltinType::SatULongAccum:
14607 case BuiltinType::SatUShortFract:
14608 case BuiltinType::SatUFract:
14609 case BuiltinType::SatULongFract:
14612 case BuiltinType::NullPtr:
14614 case BuiltinType::ObjCId:
14615 case BuiltinType::ObjCClass:
14616 case BuiltinType::ObjCSel:
14617#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
14618 case BuiltinType::Id:
14619#include "clang/Basic/OpenCLImageTypes.def"
14620#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
14621 case BuiltinType::Id:
14622#include "clang/Basic/OpenCLExtensionTypes.def"
14623 case BuiltinType::OCLSampler:
14624 case BuiltinType::OCLEvent:
14625 case BuiltinType::OCLClkEvent:
14626 case BuiltinType::OCLQueue:
14627 case BuiltinType::OCLReserveID:
14628#define SVE_TYPE(Name, Id, SingletonId) \
14629 case BuiltinType::Id:
14630#include "clang/Basic/AArch64ACLETypes.def"
14631#define PPC_VECTOR_TYPE(Name, Id, Size) \
14632 case BuiltinType::Id:
14633#include "clang/Basic/PPCTypes.def"
14634#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
14635#include "clang/Basic/RISCVVTypes.def"
14636#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
14637#include "clang/Basic/WebAssemblyReferenceTypes.def"
14638#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
14639#include "clang/Basic/AMDGPUTypes.def"
14640#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
14641#include "clang/Basic/HLSLIntangibleTypes.def"
14644 case BuiltinType::Dependent:
14645 llvm_unreachable(
"unexpected dependent type");
14647 llvm_unreachable(
"unexpected placeholder type");
14652 case Type::Pointer:
14653 case Type::ConstantArray:
14654 case Type::VariableArray:
14655 case Type::IncompleteArray:
14656 case Type::FunctionNoProto:
14657 case Type::FunctionProto:
14658 case Type::ArrayParameter:
14661 case Type::MemberPointer:
14666 case Type::Complex:
14679 case Type::ExtVector:
14682 case Type::BlockPointer:
14683 case Type::ConstantMatrix:
14684 case Type::ObjCObject:
14685 case Type::ObjCInterface:
14686 case Type::ObjCObjectPointer:
14688 case Type::HLSLAttributedResource:
14689 case Type::HLSLInlineSpirv:
14697 case Type::LValueReference:
14698 case Type::RValueReference:
14699 llvm_unreachable(
"invalid type for expression");
14702 llvm_unreachable(
"unexpected type class");
14727 if (
Base.isNull()) {
14730 }
else if (
const Expr *E =
Base.dyn_cast<
const Expr *>()) {
14749 SpeculativeEvaluationRAII SpeculativeEval(Info);
14754 FoldConstant Fold(Info,
true);
14772 if (ArgType->isIntegralOrEnumerationType() || ArgType->isFloatingType() ||
14773 ArgType->isAnyComplexType() || ArgType->isPointerType() ||
14774 ArgType->isNullPtrType()) {
14777 Fold.keepDiagnostics();
14786 return V.hasValue();
14797 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
14821 const auto *Cast = dyn_cast<CastExpr>(NoParens);
14822 if (Cast ==
nullptr)
14827 auto CastKind = Cast->getCastKind();
14829 CastKind != CK_AddressSpaceConversion)
14832 const auto *SubExpr = Cast->getSubExpr();
14854 assert(!LVal.Designator.Invalid);
14856 auto IsLastOrInvalidFieldDecl = [&Ctx](
const FieldDecl *FD) {
14864 auto &
Base = LVal.getLValueBase();
14865 if (
auto *ME = dyn_cast_or_null<MemberExpr>(
Base.dyn_cast<
const Expr *>())) {
14866 if (
auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
14867 if (!IsLastOrInvalidFieldDecl(FD))
14869 }
else if (
auto *IFD = dyn_cast<IndirectFieldDecl>(ME->getMemberDecl())) {
14870 for (
auto *FD : IFD->chain()) {
14879 if (LVal.Designator.FirstEntryIsAnUnsizedArray) {
14883 if (BaseType->isIncompleteArrayType())
14889 for (
unsigned E = LVal.Designator.Entries.size(); I != E; ++I) {
14890 const auto &Entry = LVal.Designator.Entries[I];
14891 if (BaseType->isArrayType()) {
14897 uint64_t Index = Entry.getAsArrayIndex();
14901 }
else if (BaseType->isAnyComplexType()) {
14902 const auto *CT = BaseType->castAs<
ComplexType>();
14903 uint64_t Index = Entry.getAsArrayIndex();
14906 BaseType = CT->getElementType();
14907 }
else if (
auto *FD = getAsField(Entry)) {
14908 if (!IsLastOrInvalidFieldDecl(FD))
14912 assert(getAsBaseClass(Entry) &&
"Expecting cast to a base class");
14924 if (LVal.Designator.Invalid)
14927 if (!LVal.Designator.Entries.empty())
14928 return LVal.Designator.isMostDerivedAnUnsizedArray();
14930 if (!LVal.InvalidBase)
14942 const SubobjectDesignator &
Designator = LVal.Designator;
14954 auto isFlexibleArrayMember = [&] {
14956 FAMKind StrictFlexArraysLevel =
14959 if (
Designator.isMostDerivedAnUnsizedArray())
14962 if (StrictFlexArraysLevel == FAMKind::Default)
14965 if (
Designator.getMostDerivedArraySize() == 0 &&
14966 StrictFlexArraysLevel != FAMKind::IncompleteOnly)
14969 if (
Designator.getMostDerivedArraySize() == 1 &&
14970 StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete)
14976 return LVal.InvalidBase &&
14978 Designator.MostDerivedIsArrayElement && isFlexibleArrayMember() &&
14986 auto CharUnitsMax = std::numeric_limits<CharUnits::QuantityType>::max();
14987 if (Int.ugt(CharUnitsMax))
14997 if (!
T.isNull() &&
T->isStructureType() &&
14998 T->castAsRecordDecl()->hasFlexibleArrayMember())
14999 if (
const auto *
V = LV.getLValueBase().dyn_cast<
const ValueDecl *>())
15000 if (
const auto *VD = dyn_cast<VarDecl>(
V))
15012 unsigned Type,
const LValue &LVal,
15031 if (!(
Type & 1) || LVal.Designator.Invalid || DetermineForCompleteObject) {
15033 if (
Type == 3 && !DetermineForCompleteObject)
15036 llvm::APInt APEndOffset;
15037 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
15041 if (LVal.InvalidBase)
15045 const bool Ret = CheckedHandleSizeof(BaseTy, EndOffset);
15051 const SubobjectDesignator &
Designator = LVal.Designator;
15063 llvm::APInt APEndOffset;
15064 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
15076 if (!CheckedHandleSizeof(
Designator.MostDerivedType, BytesPerElem))
15082 int64_t ElemsRemaining;
15085 uint64_t ArraySize =
Designator.getMostDerivedArraySize();
15086 uint64_t ArrayIndex =
Designator.Entries.back().getAsArrayIndex();
15087 ElemsRemaining = ArraySize <= ArrayIndex ? 0 : ArraySize - ArrayIndex;
15089 ElemsRemaining =
Designator.isOnePastTheEnd() ? 0 : 1;
15092 EndOffset = LVal.getLValueOffset() + BytesPerElem * ElemsRemaining;
15102 EvalInfo &Info, uint64_t &Size) {
15109 SpeculativeEvaluationRAII SpeculativeEval(Info);
15110 IgnoreSideEffectsRAII Fold(Info);
15118 LVal.setFrom(Info.Ctx, RVal);
15126 if (LVal.getLValueOffset().isNegative()) {
15137 if (EndOffset <= LVal.getLValueOffset())
15140 Size = (EndOffset - LVal.getLValueOffset()).getQuantity();
15144bool IntExprEvaluator::VisitCallExpr(
const CallExpr *E) {
15145 if (!IsConstantEvaluatedBuiltinCall(E))
15146 return ExprEvaluatorBaseTy::VisitCallExpr(E);
15163 Info.FFDiag(E->
getArg(0));
15169 assert(SrcInt.getBitWidth() >= Alignment.getBitWidth() &&
15170 "Bit widths must be the same");
15177bool IntExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *E,
15178 unsigned BuiltinOp) {
15179 auto EvalTestOp = [&](llvm::function_ref<
bool(
const APInt &,
const APInt &)>
15181 APValue SourceLHS, SourceRHS;
15189 unsigned LaneWidth = Info.Ctx.
getTypeSize(ElemQT);
15191 APInt AWide(LaneWidth * SourceLen, 0);
15192 APInt BWide(LaneWidth * SourceLen, 0);
15194 for (
unsigned I = 0; I != SourceLen; ++I) {
15197 if (ElemQT->isIntegerType()) {
15200 }
else if (ElemQT->isFloatingType()) {
15208 AWide.insertBits(ALane, I * LaneWidth);
15209 BWide.insertBits(BLane, I * LaneWidth);
15214 auto HandleMaskBinOp =
15227 switch (BuiltinOp) {
15231 case Builtin::BI__builtin_dynamic_object_size:
15232 case Builtin::BI__builtin_object_size: {
15236 assert(
Type <= 3 &&
"unexpected type");
15247 switch (Info.EvalMode) {
15248 case EvaluationMode::ConstantExpression:
15249 case EvaluationMode::ConstantFold:
15250 case EvaluationMode::IgnoreSideEffects:
15253 case EvaluationMode::ConstantExpressionUnevaluated:
15258 llvm_unreachable(
"unexpected EvalMode");
15261 case Builtin::BI__builtin_os_log_format_buffer_size: {
15262 analyze_os_log::OSLogBufferLayout Layout;
15267 case Builtin::BI__builtin_is_aligned: {
15275 Ptr.setFrom(Info.Ctx, Src);
15281 assert(Alignment.isPowerOf2());
15294 Info.FFDiag(E->
getArg(0), diag::note_constexpr_alignment_compute)
15298 assert(Src.
isInt());
15299 return Success((Src.
getInt() & (Alignment - 1)) == 0 ? 1 : 0, E);
15301 case Builtin::BI__builtin_align_up: {
15309 APSInt((Src.
getInt() + (Alignment - 1)) & ~(Alignment - 1),
15310 Src.
getInt().isUnsigned());
15311 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
15312 return Success(AlignedVal, E);
15314 case Builtin::BI__builtin_align_down: {
15323 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
15324 return Success(AlignedVal, E);
15327 case Builtin::BI__builtin_bitreverse8:
15328 case Builtin::BI__builtin_bitreverse16:
15329 case Builtin::BI__builtin_bitreverse32:
15330 case Builtin::BI__builtin_bitreverse64:
15331 case Builtin::BI__builtin_elementwise_bitreverse: {
15336 return Success(Val.reverseBits(), E);
15338 case Builtin::BI__builtin_bswapg:
15339 case Builtin::BI__builtin_bswap16:
15340 case Builtin::BI__builtin_bswap32:
15341 case Builtin::BI__builtin_bswap64: {
15345 if (Val.getBitWidth() == 8)
15348 return Success(Val.byteSwap(), E);
15351 case Builtin::BI__builtin_classify_type:
15354 case Builtin::BI__builtin_clrsb:
15355 case Builtin::BI__builtin_clrsbl:
15356 case Builtin::BI__builtin_clrsbll: {
15361 return Success(Val.getBitWidth() - Val.getSignificantBits(), E);
15364 case Builtin::BI__builtin_clz:
15365 case Builtin::BI__builtin_clzl:
15366 case Builtin::BI__builtin_clzll:
15367 case Builtin::BI__builtin_clzs:
15368 case Builtin::BI__builtin_clzg:
15369 case Builtin::BI__builtin_elementwise_clzg:
15370 case Builtin::BI__lzcnt16:
15371 case Builtin::BI__lzcnt:
15372 case Builtin::BI__lzcnt64: {
15383 std::optional<APSInt> Fallback;
15384 if ((BuiltinOp == Builtin::BI__builtin_clzg ||
15385 BuiltinOp == Builtin::BI__builtin_elementwise_clzg) &&
15390 Fallback = FallbackTemp;
15395 return Success(*Fallback, E);
15400 bool ZeroIsUndefined = BuiltinOp != Builtin::BI__lzcnt16 &&
15401 BuiltinOp != Builtin::BI__lzcnt &&
15402 BuiltinOp != Builtin::BI__lzcnt64;
15404 if (BuiltinOp == Builtin::BI__builtin_elementwise_clzg) {
15405 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
15409 if (ZeroIsUndefined)
15413 return Success(Val.countl_zero(), E);
15416 case Builtin::BI__builtin_constant_p: {
15417 const Expr *Arg = E->
getArg(0);
15426 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
15430 case Builtin::BI__noop:
15434 case Builtin::BI__builtin_is_constant_evaluated: {
15435 const auto *
Callee = Info.CurrentCall->getCallee();
15436 if (Info.InConstantContext && !Info.CheckingPotentialConstantExpression &&
15437 (Info.CallStackDepth == 1 ||
15438 (Info.CallStackDepth == 2 &&
Callee->isInStdNamespace() &&
15439 Callee->getIdentifier() &&
15440 Callee->getIdentifier()->isStr(
"is_constant_evaluated")))) {
15442 if (Info.EvalStatus.
Diag)
15443 Info.report((Info.CallStackDepth == 1)
15445 : Info.CurrentCall->getCallRange().getBegin(),
15446 diag::warn_is_constant_evaluated_always_true_constexpr)
15447 << (Info.CallStackDepth == 1 ?
"__builtin_is_constant_evaluated"
15448 :
"std::is_constant_evaluated");
15451 return Success(Info.InConstantContext, E);
15454 case Builtin::BI__builtin_is_within_lifetime:
15455 if (
auto result = EvaluateBuiltinIsWithinLifetime(*
this, E))
15459 case Builtin::BI__builtin_ctz:
15460 case Builtin::BI__builtin_ctzl:
15461 case Builtin::BI__builtin_ctzll:
15462 case Builtin::BI__builtin_ctzs:
15463 case Builtin::BI__builtin_ctzg:
15464 case Builtin::BI__builtin_elementwise_ctzg: {
15475 std::optional<APSInt> Fallback;
15476 if ((BuiltinOp == Builtin::BI__builtin_ctzg ||
15477 BuiltinOp == Builtin::BI__builtin_elementwise_ctzg) &&
15482 Fallback = FallbackTemp;
15487 return Success(*Fallback, E);
15489 if (BuiltinOp == Builtin::BI__builtin_elementwise_ctzg) {
15490 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
15496 return Success(Val.countr_zero(), E);
15499 case Builtin::BI__builtin_eh_return_data_regno: {
15505 case Builtin::BI__builtin_elementwise_abs: {
15510 return Success(Val.abs(), E);
15513 case Builtin::BI__builtin_expect:
15514 case Builtin::BI__builtin_expect_with_probability:
15515 return Visit(E->
getArg(0));
15517 case Builtin::BI__builtin_ptrauth_string_discriminator: {
15524 case Builtin::BI__builtin_infer_alloc_token: {
15530 E, diag::note_constexpr_infer_alloc_token_type_inference_failed);
15533 return Error(E, diag::note_constexpr_infer_alloc_token_no_metadata);
15535 Info.getLangOpts().AllocTokenMode.value_or(llvm::DefaultAllocTokenMode);
15538 Info.getLangOpts().AllocTokenMax.value_or(~0ULL >> (64 - BitWidth));
15539 auto MaybeToken = llvm::getAllocToken(Mode, *ATMD, MaxTokens);
15541 return Error(E, diag::note_constexpr_infer_alloc_token_stateful_mode);
15542 return Success(llvm::APInt(BitWidth, *MaybeToken), E);
15545 case Builtin::BI__builtin_ffs:
15546 case Builtin::BI__builtin_ffsl:
15547 case Builtin::BI__builtin_ffsll: {
15552 unsigned N = Val.countr_zero();
15553 return Success(N == Val.getBitWidth() ? 0 : N + 1, E);
15556 case Builtin::BI__builtin_fpclassify: {
15561 switch (Val.getCategory()) {
15562 case APFloat::fcNaN: Arg = 0;
break;
15563 case APFloat::fcInfinity: Arg = 1;
break;
15564 case APFloat::fcNormal: Arg = Val.isDenormal() ? 3 : 2;
break;
15565 case APFloat::fcZero: Arg = 4;
break;
15567 return Visit(E->
getArg(Arg));
15570 case Builtin::BI__builtin_isinf_sign: {
15573 Success(Val.isInfinity() ? (Val.isNegative() ? -1 : 1) : 0, E);
15576 case Builtin::BI__builtin_isinf: {
15579 Success(Val.isInfinity() ? 1 : 0, E);
15582 case Builtin::BI__builtin_isfinite: {
15585 Success(Val.isFinite() ? 1 : 0, E);
15588 case Builtin::BI__builtin_isnan: {
15591 Success(Val.isNaN() ? 1 : 0, E);
15594 case Builtin::BI__builtin_isnormal: {
15597 Success(Val.isNormal() ? 1 : 0, E);
15600 case Builtin::BI__builtin_issubnormal: {
15603 Success(Val.isDenormal() ? 1 : 0, E);
15606 case Builtin::BI__builtin_iszero: {
15609 Success(Val.isZero() ? 1 : 0, E);
15612 case Builtin::BI__builtin_signbit:
15613 case Builtin::BI__builtin_signbitf:
15614 case Builtin::BI__builtin_signbitl: {
15617 Success(Val.isNegative() ? 1 : 0, E);
15620 case Builtin::BI__builtin_isgreater:
15621 case Builtin::BI__builtin_isgreaterequal:
15622 case Builtin::BI__builtin_isless:
15623 case Builtin::BI__builtin_islessequal:
15624 case Builtin::BI__builtin_islessgreater:
15625 case Builtin::BI__builtin_isunordered: {
15634 switch (BuiltinOp) {
15635 case Builtin::BI__builtin_isgreater:
15637 case Builtin::BI__builtin_isgreaterequal:
15639 case Builtin::BI__builtin_isless:
15641 case Builtin::BI__builtin_islessequal:
15643 case Builtin::BI__builtin_islessgreater: {
15644 APFloat::cmpResult cmp = LHS.compare(RHS);
15645 return cmp == APFloat::cmpResult::cmpLessThan ||
15646 cmp == APFloat::cmpResult::cmpGreaterThan;
15648 case Builtin::BI__builtin_isunordered:
15649 return LHS.compare(RHS) == APFloat::cmpResult::cmpUnordered;
15651 llvm_unreachable(
"Unexpected builtin ID: Should be a floating "
15652 "point comparison function");
15660 case Builtin::BI__builtin_issignaling: {
15663 Success(Val.isSignaling() ? 1 : 0, E);
15666 case Builtin::BI__builtin_isfpclass: {
15670 unsigned Test =
static_cast<llvm::FPClassTest
>(MaskVal.getZExtValue());
15673 Success((Val.classify() & Test) ? 1 : 0, E);
15676 case Builtin::BI__builtin_parity:
15677 case Builtin::BI__builtin_parityl:
15678 case Builtin::BI__builtin_parityll: {
15683 return Success(Val.popcount() % 2, E);
15686 case Builtin::BI__builtin_abs:
15687 case Builtin::BI__builtin_labs:
15688 case Builtin::BI__builtin_llabs: {
15692 if (Val ==
APSInt(APInt::getSignedMinValue(Val.getBitWidth()),
15695 if (Val.isNegative())
15700 case Builtin::BI__builtin_popcount:
15701 case Builtin::BI__builtin_popcountl:
15702 case Builtin::BI__builtin_popcountll:
15703 case Builtin::BI__builtin_popcountg:
15704 case Builtin::BI__builtin_elementwise_popcount:
15705 case Builtin::BI__popcnt16:
15706 case Builtin::BI__popcnt:
15707 case Builtin::BI__popcnt64: {
15718 return Success(Val.popcount(), E);
15721 case Builtin::BI__builtin_rotateleft8:
15722 case Builtin::BI__builtin_rotateleft16:
15723 case Builtin::BI__builtin_rotateleft32:
15724 case Builtin::BI__builtin_rotateleft64:
15725 case Builtin::BI_rotl8:
15726 case Builtin::BI_rotl16:
15727 case Builtin::BI_rotl:
15728 case Builtin::BI_lrotl:
15729 case Builtin::BI_rotl64: {
15735 return Success(Val.rotl(Amt), E);
15738 case Builtin::BI__builtin_rotateright8:
15739 case Builtin::BI__builtin_rotateright16:
15740 case Builtin::BI__builtin_rotateright32:
15741 case Builtin::BI__builtin_rotateright64:
15742 case Builtin::BI_rotr8:
15743 case Builtin::BI_rotr16:
15744 case Builtin::BI_rotr:
15745 case Builtin::BI_lrotr:
15746 case Builtin::BI_rotr64: {
15752 return Success(Val.rotr(Amt), E);
15755 case Builtin::BI__builtin_elementwise_add_sat: {
15761 APInt Result = LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS);
15764 case Builtin::BI__builtin_elementwise_sub_sat: {
15770 APInt Result = LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
15773 case Builtin::BI__builtin_elementwise_max: {
15782 case Builtin::BI__builtin_elementwise_min: {
15791 case Builtin::BI__builtin_elementwise_fshl:
15792 case Builtin::BI__builtin_elementwise_fshr: {
15799 switch (BuiltinOp) {
15800 case Builtin::BI__builtin_elementwise_fshl: {
15801 APSInt Result(llvm::APIntOps::fshl(Hi, Lo, Shift), Hi.isUnsigned());
15804 case Builtin::BI__builtin_elementwise_fshr: {
15805 APSInt Result(llvm::APIntOps::fshr(Hi, Lo, Shift), Hi.isUnsigned());
15809 llvm_unreachable(
"Fully covered switch above");
15811 case Builtin::BIstrlen:
15812 case Builtin::BIwcslen:
15814 if (Info.getLangOpts().CPlusPlus11)
15815 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
15819 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
15821 case Builtin::BI__builtin_strlen:
15822 case Builtin::BI__builtin_wcslen: {
15831 case Builtin::BIstrcmp:
15832 case Builtin::BIwcscmp:
15833 case Builtin::BIstrncmp:
15834 case Builtin::BIwcsncmp:
15835 case Builtin::BImemcmp:
15836 case Builtin::BIbcmp:
15837 case Builtin::BIwmemcmp:
15839 if (Info.getLangOpts().CPlusPlus11)
15840 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
15844 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
15846 case Builtin::BI__builtin_strcmp:
15847 case Builtin::BI__builtin_wcscmp:
15848 case Builtin::BI__builtin_strncmp:
15849 case Builtin::BI__builtin_wcsncmp:
15850 case Builtin::BI__builtin_memcmp:
15851 case Builtin::BI__builtin_bcmp:
15852 case Builtin::BI__builtin_wmemcmp: {
15853 LValue String1, String2;
15859 if (BuiltinOp != Builtin::BIstrcmp &&
15860 BuiltinOp != Builtin::BIwcscmp &&
15861 BuiltinOp != Builtin::BI__builtin_strcmp &&
15862 BuiltinOp != Builtin::BI__builtin_wcscmp) {
15866 MaxLength = N.getZExtValue();
15870 if (MaxLength == 0u)
15873 if (!String1.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
15874 !String2.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
15875 String1.Designator.Invalid || String2.Designator.Invalid)
15878 QualType CharTy1 = String1.Designator.getType(Info.Ctx);
15879 QualType CharTy2 = String2.Designator.getType(Info.Ctx);
15881 bool IsRawByte = BuiltinOp == Builtin::BImemcmp ||
15882 BuiltinOp == Builtin::BIbcmp ||
15883 BuiltinOp == Builtin::BI__builtin_memcmp ||
15884 BuiltinOp == Builtin::BI__builtin_bcmp;
15886 assert(IsRawByte ||
15896 Info.FFDiag(E, diag::note_constexpr_memcmp_unsupported)
15902 const auto &ReadCurElems = [&](
APValue &Char1,
APValue &Char2) {
15905 Char1.
isInt() && Char2.isInt();
15907 const auto &AdvanceElems = [&] {
15913 (BuiltinOp != Builtin::BImemcmp && BuiltinOp != Builtin::BIbcmp &&
15914 BuiltinOp != Builtin::BIwmemcmp &&
15915 BuiltinOp != Builtin::BI__builtin_memcmp &&
15916 BuiltinOp != Builtin::BI__builtin_bcmp &&
15917 BuiltinOp != Builtin::BI__builtin_wmemcmp);
15918 bool IsWide = BuiltinOp == Builtin::BIwcscmp ||
15919 BuiltinOp == Builtin::BIwcsncmp ||
15920 BuiltinOp == Builtin::BIwmemcmp ||
15921 BuiltinOp == Builtin::BI__builtin_wcscmp ||
15922 BuiltinOp == Builtin::BI__builtin_wcsncmp ||
15923 BuiltinOp == Builtin::BI__builtin_wmemcmp;
15925 for (; MaxLength; --MaxLength) {
15927 if (!ReadCurElems(Char1, Char2))
15935 if (StopAtNull && !Char1.
getInt())
15937 assert(!(StopAtNull && !Char2.
getInt()));
15938 if (!AdvanceElems())
15945 case Builtin::BI__atomic_always_lock_free:
15946 case Builtin::BI__atomic_is_lock_free:
15947 case Builtin::BI__c11_atomic_is_lock_free: {
15963 if (
Size.isPowerOfTwo()) {
15965 unsigned InlineWidthBits =
15968 if (BuiltinOp == Builtin::BI__c11_atomic_is_lock_free ||
15974 const Expr *PtrArg = E->
getArg(1);
15980 IntResult.isAligned(
Size.getAsAlign()))
15984 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(PtrArg)) {
15987 if (ICE->getCastKind() == CK_BitCast)
15988 PtrArg = ICE->getSubExpr();
15991 if (
auto PtrTy = PtrArg->
getType()->
getAs<PointerType>()) {
16002 return BuiltinOp == Builtin::BI__atomic_always_lock_free ?
16005 case Builtin::BI__builtin_addcb:
16006 case Builtin::BI__builtin_addcs:
16007 case Builtin::BI__builtin_addc:
16008 case Builtin::BI__builtin_addcl:
16009 case Builtin::BI__builtin_addcll:
16010 case Builtin::BI__builtin_subcb:
16011 case Builtin::BI__builtin_subcs:
16012 case Builtin::BI__builtin_subc:
16013 case Builtin::BI__builtin_subcl:
16014 case Builtin::BI__builtin_subcll: {
16015 LValue CarryOutLValue;
16027 bool FirstOverflowed =
false;
16028 bool SecondOverflowed =
false;
16029 switch (BuiltinOp) {
16031 llvm_unreachable(
"Invalid value for BuiltinOp");
16032 case Builtin::BI__builtin_addcb:
16033 case Builtin::BI__builtin_addcs:
16034 case Builtin::BI__builtin_addc:
16035 case Builtin::BI__builtin_addcl:
16036 case Builtin::BI__builtin_addcll:
16038 LHS.uadd_ov(RHS, FirstOverflowed).uadd_ov(CarryIn, SecondOverflowed);
16040 case Builtin::BI__builtin_subcb:
16041 case Builtin::BI__builtin_subcs:
16042 case Builtin::BI__builtin_subc:
16043 case Builtin::BI__builtin_subcl:
16044 case Builtin::BI__builtin_subcll:
16046 LHS.usub_ov(RHS, FirstOverflowed).usub_ov(CarryIn, SecondOverflowed);
16052 CarryOut = (
uint64_t)(FirstOverflowed | SecondOverflowed);
16058 case Builtin::BI__builtin_add_overflow:
16059 case Builtin::BI__builtin_sub_overflow:
16060 case Builtin::BI__builtin_mul_overflow:
16061 case Builtin::BI__builtin_sadd_overflow:
16062 case Builtin::BI__builtin_uadd_overflow:
16063 case Builtin::BI__builtin_uaddl_overflow:
16064 case Builtin::BI__builtin_uaddll_overflow:
16065 case Builtin::BI__builtin_usub_overflow:
16066 case Builtin::BI__builtin_usubl_overflow:
16067 case Builtin::BI__builtin_usubll_overflow:
16068 case Builtin::BI__builtin_umul_overflow:
16069 case Builtin::BI__builtin_umull_overflow:
16070 case Builtin::BI__builtin_umulll_overflow:
16071 case Builtin::BI__builtin_saddl_overflow:
16072 case Builtin::BI__builtin_saddll_overflow:
16073 case Builtin::BI__builtin_ssub_overflow:
16074 case Builtin::BI__builtin_ssubl_overflow:
16075 case Builtin::BI__builtin_ssubll_overflow:
16076 case Builtin::BI__builtin_smul_overflow:
16077 case Builtin::BI__builtin_smull_overflow:
16078 case Builtin::BI__builtin_smulll_overflow: {
16079 LValue ResultLValue;
16089 bool DidOverflow =
false;
16092 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
16093 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
16094 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
16095 bool IsSigned = LHS.isSigned() || RHS.isSigned() ||
16097 bool AllSigned = LHS.isSigned() && RHS.isSigned() &&
16099 uint64_t LHSSize = LHS.getBitWidth();
16100 uint64_t RHSSize = RHS.getBitWidth();
16102 uint64_t MaxBits = std::max(std::max(LHSSize, RHSSize), ResultSize);
16108 if (IsSigned && !AllSigned)
16111 LHS =
APSInt(LHS.extOrTrunc(MaxBits), !IsSigned);
16112 RHS =
APSInt(RHS.extOrTrunc(MaxBits), !IsSigned);
16117 switch (BuiltinOp) {
16119 llvm_unreachable(
"Invalid value for BuiltinOp");
16120 case Builtin::BI__builtin_add_overflow:
16121 case Builtin::BI__builtin_sadd_overflow:
16122 case Builtin::BI__builtin_saddl_overflow:
16123 case Builtin::BI__builtin_saddll_overflow:
16124 case Builtin::BI__builtin_uadd_overflow:
16125 case Builtin::BI__builtin_uaddl_overflow:
16126 case Builtin::BI__builtin_uaddll_overflow:
16127 Result = LHS.isSigned() ? LHS.sadd_ov(RHS, DidOverflow)
16128 : LHS.uadd_ov(RHS, DidOverflow);
16130 case Builtin::BI__builtin_sub_overflow:
16131 case Builtin::BI__builtin_ssub_overflow:
16132 case Builtin::BI__builtin_ssubl_overflow:
16133 case Builtin::BI__builtin_ssubll_overflow:
16134 case Builtin::BI__builtin_usub_overflow:
16135 case Builtin::BI__builtin_usubl_overflow:
16136 case Builtin::BI__builtin_usubll_overflow:
16137 Result = LHS.isSigned() ? LHS.ssub_ov(RHS, DidOverflow)
16138 : LHS.usub_ov(RHS, DidOverflow);
16140 case Builtin::BI__builtin_mul_overflow:
16141 case Builtin::BI__builtin_smul_overflow:
16142 case Builtin::BI__builtin_smull_overflow:
16143 case Builtin::BI__builtin_smulll_overflow:
16144 case Builtin::BI__builtin_umul_overflow:
16145 case Builtin::BI__builtin_umull_overflow:
16146 case Builtin::BI__builtin_umulll_overflow:
16147 Result = LHS.isSigned() ? LHS.smul_ov(RHS, DidOverflow)
16148 : LHS.umul_ov(RHS, DidOverflow);
16154 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
16155 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
16156 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
16165 if (!APSInt::isSameValue(Temp,
Result))
16166 DidOverflow =
true;
16173 return Success(DidOverflow, E);
16176 case Builtin::BI__builtin_reduce_add:
16177 case Builtin::BI__builtin_reduce_mul:
16178 case Builtin::BI__builtin_reduce_and:
16179 case Builtin::BI__builtin_reduce_or:
16180 case Builtin::BI__builtin_reduce_xor:
16181 case Builtin::BI__builtin_reduce_min:
16182 case Builtin::BI__builtin_reduce_max: {
16189 for (
unsigned EltNum = 1; EltNum < SourceLen; ++EltNum) {
16190 switch (BuiltinOp) {
16193 case Builtin::BI__builtin_reduce_add: {
16196 Reduced.getBitWidth() + 1, std::plus<APSInt>(), Reduced))
16200 case Builtin::BI__builtin_reduce_mul: {
16203 Reduced.getBitWidth() * 2, std::multiplies<APSInt>(), Reduced))
16207 case Builtin::BI__builtin_reduce_and: {
16211 case Builtin::BI__builtin_reduce_or: {
16215 case Builtin::BI__builtin_reduce_xor: {
16219 case Builtin::BI__builtin_reduce_min: {
16223 case Builtin::BI__builtin_reduce_max: {
16233 case clang::X86::BI__builtin_ia32_addcarryx_u32:
16234 case clang::X86::BI__builtin_ia32_addcarryx_u64:
16235 case clang::X86::BI__builtin_ia32_subborrow_u32:
16236 case clang::X86::BI__builtin_ia32_subborrow_u64: {
16237 LValue ResultLValue;
16238 APSInt CarryIn, LHS, RHS;
16246 bool IsAdd = BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u32 ||
16247 BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u64;
16249 unsigned BitWidth = LHS.getBitWidth();
16250 unsigned CarryInBit = CarryIn.ugt(0) ? 1 : 0;
16253 ? (LHS.zext(BitWidth + 1) + (RHS.zext(BitWidth + 1) + CarryInBit))
16254 : (LHS.zext(BitWidth + 1) - (RHS.zext(BitWidth + 1) + CarryInBit));
16256 APInt Result = ExResult.extractBits(BitWidth, 0);
16257 uint64_t CarryOut = ExResult.extractBitsAsZExtValue(1, BitWidth);
16265 case clang::X86::BI__builtin_ia32_movmskps:
16266 case clang::X86::BI__builtin_ia32_movmskpd:
16267 case clang::X86::BI__builtin_ia32_pmovmskb128:
16268 case clang::X86::BI__builtin_ia32_pmovmskb256:
16269 case clang::X86::BI__builtin_ia32_movmskps256:
16270 case clang::X86::BI__builtin_ia32_movmskpd256: {
16281 for (
unsigned I = 0; I != SourceLen; ++I) {
16283 if (ElemQT->isIntegerType()) {
16285 }
else if (ElemQT->isRealFloatingType()) {
16290 Result.setBitVal(I, Elem.isNegative());
16295 case clang::X86::BI__builtin_ia32_bextr_u32:
16296 case clang::X86::BI__builtin_ia32_bextr_u64:
16297 case clang::X86::BI__builtin_ia32_bextri_u32:
16298 case clang::X86::BI__builtin_ia32_bextri_u64: {
16304 unsigned BitWidth = Val.getBitWidth();
16306 uint64_t Length = Idx.extractBitsAsZExtValue(8, 8);
16307 Length = Length > BitWidth ? BitWidth : Length;
16310 if (Length == 0 || Shift >= BitWidth)
16314 Result &= llvm::maskTrailingOnes<uint64_t>(Length);
16318 case clang::X86::BI__builtin_ia32_bzhi_si:
16319 case clang::X86::BI__builtin_ia32_bzhi_di: {
16325 unsigned BitWidth = Val.getBitWidth();
16326 unsigned Index = Idx.extractBitsAsZExtValue(8, 0);
16327 if (Index < BitWidth)
16328 Val.clearHighBits(BitWidth - Index);
16332 case clang::X86::BI__builtin_ia32_ktestcqi:
16333 case clang::X86::BI__builtin_ia32_ktestchi:
16334 case clang::X86::BI__builtin_ia32_ktestcsi:
16335 case clang::X86::BI__builtin_ia32_ktestcdi: {
16341 return Success((~A & B) == 0, E);
16344 case clang::X86::BI__builtin_ia32_ktestzqi:
16345 case clang::X86::BI__builtin_ia32_ktestzhi:
16346 case clang::X86::BI__builtin_ia32_ktestzsi:
16347 case clang::X86::BI__builtin_ia32_ktestzdi: {
16353 return Success((A & B) == 0, E);
16356 case clang::X86::BI__builtin_ia32_kortestcqi:
16357 case clang::X86::BI__builtin_ia32_kortestchi:
16358 case clang::X86::BI__builtin_ia32_kortestcsi:
16359 case clang::X86::BI__builtin_ia32_kortestcdi: {
16365 return Success(~(A | B) == 0, E);
16368 case clang::X86::BI__builtin_ia32_kortestzqi:
16369 case clang::X86::BI__builtin_ia32_kortestzhi:
16370 case clang::X86::BI__builtin_ia32_kortestzsi:
16371 case clang::X86::BI__builtin_ia32_kortestzdi: {
16377 return Success((A | B) == 0, E);
16380 case clang::X86::BI__builtin_ia32_kunpckhi:
16381 case clang::X86::BI__builtin_ia32_kunpckdi:
16382 case clang::X86::BI__builtin_ia32_kunpcksi: {
16390 unsigned BW = A.getBitWidth();
16391 APSInt Result(A.trunc(BW / 2).concat(B.trunc(BW / 2)), A.isUnsigned());
16395 case clang::X86::BI__builtin_ia32_lzcnt_u16:
16396 case clang::X86::BI__builtin_ia32_lzcnt_u32:
16397 case clang::X86::BI__builtin_ia32_lzcnt_u64: {
16401 return Success(Val.countLeadingZeros(), E);
16404 case clang::X86::BI__builtin_ia32_tzcnt_u16:
16405 case clang::X86::BI__builtin_ia32_tzcnt_u32:
16406 case clang::X86::BI__builtin_ia32_tzcnt_u64: {
16410 return Success(Val.countTrailingZeros(), E);
16413 case clang::X86::BI__builtin_ia32_pdep_si:
16414 case clang::X86::BI__builtin_ia32_pdep_di: {
16420 unsigned BitWidth = Val.getBitWidth();
16422 for (
unsigned I = 0, P = 0; I != BitWidth; ++I)
16424 Result.setBitVal(I, Val[P++]);
16428 case clang::X86::BI__builtin_ia32_pext_si:
16429 case clang::X86::BI__builtin_ia32_pext_di: {
16435 unsigned BitWidth = Val.getBitWidth();
16437 for (
unsigned I = 0, P = 0; I != BitWidth; ++I)
16439 Result.setBitVal(P++, Val[I]);
16442 case X86::BI__builtin_ia32_ptestz128:
16443 case X86::BI__builtin_ia32_ptestz256:
16444 case X86::BI__builtin_ia32_vtestzps:
16445 case X86::BI__builtin_ia32_vtestzps256:
16446 case X86::BI__builtin_ia32_vtestzpd:
16447 case X86::BI__builtin_ia32_vtestzpd256: {
16449 [](
const APInt &A,
const APInt &B) {
return (A & B) == 0; });
16451 case X86::BI__builtin_ia32_ptestc128:
16452 case X86::BI__builtin_ia32_ptestc256:
16453 case X86::BI__builtin_ia32_vtestcps:
16454 case X86::BI__builtin_ia32_vtestcps256:
16455 case X86::BI__builtin_ia32_vtestcpd:
16456 case X86::BI__builtin_ia32_vtestcpd256: {
16458 [](
const APInt &A,
const APInt &B) {
return (~A & B) == 0; });
16460 case X86::BI__builtin_ia32_ptestnzc128:
16461 case X86::BI__builtin_ia32_ptestnzc256:
16462 case X86::BI__builtin_ia32_vtestnzcps:
16463 case X86::BI__builtin_ia32_vtestnzcps256:
16464 case X86::BI__builtin_ia32_vtestnzcpd:
16465 case X86::BI__builtin_ia32_vtestnzcpd256: {
16466 return EvalTestOp([](
const APInt &A,
const APInt &B) {
16467 return ((A & B) != 0) && ((~A & B) != 0);
16470 case X86::BI__builtin_ia32_kandqi:
16471 case X86::BI__builtin_ia32_kandhi:
16472 case X86::BI__builtin_ia32_kandsi:
16473 case X86::BI__builtin_ia32_kanddi: {
16474 return HandleMaskBinOp(
16475 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS & RHS; });
16478 case X86::BI__builtin_ia32_kandnqi:
16479 case X86::BI__builtin_ia32_kandnhi:
16480 case X86::BI__builtin_ia32_kandnsi:
16481 case X86::BI__builtin_ia32_kandndi: {
16482 return HandleMaskBinOp(
16483 [](
const APSInt &LHS,
const APSInt &RHS) {
return ~LHS & RHS; });
16486 case X86::BI__builtin_ia32_korqi:
16487 case X86::BI__builtin_ia32_korhi:
16488 case X86::BI__builtin_ia32_korsi:
16489 case X86::BI__builtin_ia32_kordi: {
16490 return HandleMaskBinOp(
16491 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS | RHS; });
16494 case X86::BI__builtin_ia32_kxnorqi:
16495 case X86::BI__builtin_ia32_kxnorhi:
16496 case X86::BI__builtin_ia32_kxnorsi:
16497 case X86::BI__builtin_ia32_kxnordi: {
16498 return HandleMaskBinOp(
16499 [](
const APSInt &LHS,
const APSInt &RHS) {
return ~(LHS ^ RHS); });
16502 case X86::BI__builtin_ia32_kxorqi:
16503 case X86::BI__builtin_ia32_kxorhi:
16504 case X86::BI__builtin_ia32_kxorsi:
16505 case X86::BI__builtin_ia32_kxordi: {
16506 return HandleMaskBinOp(
16507 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS ^ RHS; });
16510 case X86::BI__builtin_ia32_knotqi:
16511 case X86::BI__builtin_ia32_knothi:
16512 case X86::BI__builtin_ia32_knotsi:
16513 case X86::BI__builtin_ia32_knotdi: {
16521 case X86::BI__builtin_ia32_kaddqi:
16522 case X86::BI__builtin_ia32_kaddhi:
16523 case X86::BI__builtin_ia32_kaddsi:
16524 case X86::BI__builtin_ia32_kadddi: {
16525 return HandleMaskBinOp(
16526 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS + RHS; });
16529 case clang::X86::BI__builtin_ia32_vec_ext_v4hi:
16530 case clang::X86::BI__builtin_ia32_vec_ext_v16qi:
16531 case clang::X86::BI__builtin_ia32_vec_ext_v8hi:
16532 case clang::X86::BI__builtin_ia32_vec_ext_v4si:
16533 case clang::X86::BI__builtin_ia32_vec_ext_v2di:
16534 case clang::X86::BI__builtin_ia32_vec_ext_v32qi:
16535 case clang::X86::BI__builtin_ia32_vec_ext_v16hi:
16536 case clang::X86::BI__builtin_ia32_vec_ext_v8si:
16537 case clang::X86::BI__builtin_ia32_vec_ext_v4di: {
16544 unsigned Idx =
static_cast<unsigned>(IdxAPS.getZExtValue() & (N - 1));
16548 case clang::X86::BI__builtin_ia32_cmpb128_mask:
16549 case clang::X86::BI__builtin_ia32_cmpw128_mask:
16550 case clang::X86::BI__builtin_ia32_cmpd128_mask:
16551 case clang::X86::BI__builtin_ia32_cmpq128_mask:
16552 case clang::X86::BI__builtin_ia32_cmpb256_mask:
16553 case clang::X86::BI__builtin_ia32_cmpw256_mask:
16554 case clang::X86::BI__builtin_ia32_cmpd256_mask:
16555 case clang::X86::BI__builtin_ia32_cmpq256_mask:
16556 case clang::X86::BI__builtin_ia32_cmpb512_mask:
16557 case clang::X86::BI__builtin_ia32_cmpw512_mask:
16558 case clang::X86::BI__builtin_ia32_cmpd512_mask:
16559 case clang::X86::BI__builtin_ia32_cmpq512_mask:
16560 case clang::X86::BI__builtin_ia32_ucmpb128_mask:
16561 case clang::X86::BI__builtin_ia32_ucmpw128_mask:
16562 case clang::X86::BI__builtin_ia32_ucmpd128_mask:
16563 case clang::X86::BI__builtin_ia32_ucmpq128_mask:
16564 case clang::X86::BI__builtin_ia32_ucmpb256_mask:
16565 case clang::X86::BI__builtin_ia32_ucmpw256_mask:
16566 case clang::X86::BI__builtin_ia32_ucmpd256_mask:
16567 case clang::X86::BI__builtin_ia32_ucmpq256_mask:
16568 case clang::X86::BI__builtin_ia32_ucmpb512_mask:
16569 case clang::X86::BI__builtin_ia32_ucmpw512_mask:
16570 case clang::X86::BI__builtin_ia32_ucmpd512_mask:
16571 case clang::X86::BI__builtin_ia32_ucmpq512_mask: {
16575 (BuiltinOp >= clang::X86::BI__builtin_ia32_ucmpb128_mask &&
16576 BuiltinOp <= clang::X86::BI__builtin_ia32_ucmpq512_mask);
16589 unsigned RetWidth = Mask.getBitWidth();
16591 APSInt RetMask(llvm::APInt(RetWidth, 0),
true);
16593 for (
unsigned ElemNum = 0; ElemNum < VectorLen; ++ElemNum) {
16598 switch (
Opcode.getExtValue() & 0x7) {
16603 Result = IsUnsigned ? A.ult(B) : A.slt(B);
16606 Result = IsUnsigned ? A.ule(B) : A.sle(B);
16615 Result = IsUnsigned ? A.uge(B) : A.sge(B);
16618 Result = IsUnsigned ? A.ugt(B) : A.sgt(B);
16625 RetMask.setBitVal(ElemNum, Mask[ElemNum] &&
Result);
16636 const LValue &LV) {
16639 if (!LV.getLValueBase())
16644 if (!LV.getLValueDesignator().Invalid &&
16645 !LV.getLValueDesignator().isOnePastTheEnd())
16655 if (LV.getLValueDesignator().Invalid)
16661 return LV.getLValueOffset() == Size;
16671class DataRecursiveIntBinOpEvaluator {
16672 struct EvalResult {
16674 bool Failed =
false;
16676 EvalResult() =
default;
16678 void swap(EvalResult &RHS) {
16680 Failed = RHS.Failed;
16681 RHS.Failed =
false;
16687 EvalResult LHSResult;
16688 enum { AnyExprKind, BinOpKind, BinOpVisitedLHSKind }
Kind;
16691 Job(Job &&) =
default;
16693 void startSpeculativeEval(EvalInfo &Info) {
16694 SpecEvalRAII = SpeculativeEvaluationRAII(Info);
16698 SpeculativeEvaluationRAII SpecEvalRAII;
16701 SmallVector<Job, 16> Queue;
16703 IntExprEvaluator &IntEval;
16708 DataRecursiveIntBinOpEvaluator(IntExprEvaluator &IntEval,
APValue &
Result)
16709 : IntEval(IntEval), Info(IntEval.getEvalInfo()), FinalResult(
Result) { }
16715 static bool shouldEnqueue(
const BinaryOperator *E) {
16722 bool Traverse(
const BinaryOperator *E) {
16724 EvalResult PrevResult;
16725 while (!Queue.empty())
16726 process(PrevResult);
16728 if (PrevResult.Failed)
return false;
16730 FinalResult.
swap(PrevResult.Val);
16741 bool Error(
const Expr *E) {
16742 return IntEval.Error(E);
16745 return IntEval.Error(E, D);
16748 OptionalDiagnostic CCEDiag(
const Expr *E,
diag::kind D) {
16749 return Info.CCEDiag(E, D);
16753 bool VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
16754 bool &SuppressRHSDiags);
16756 bool VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
16759 void EvaluateExpr(
const Expr *E, EvalResult &
Result) {
16765 void process(EvalResult &
Result);
16767 void enqueue(
const Expr *E) {
16769 Queue.resize(Queue.size()+1);
16770 Queue.back().E = E;
16771 Queue.back().Kind = Job::AnyExprKind;
16777bool DataRecursiveIntBinOpEvaluator::
16778 VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
16779 bool &SuppressRHSDiags) {
16782 if (LHSResult.Failed)
16783 return Info.noteSideEffect();
16792 if (LHSAsBool == (E->
getOpcode() == BO_LOr)) {
16793 Success(LHSAsBool, E, LHSResult.Val);
16797 LHSResult.Failed =
true;
16801 if (!Info.noteSideEffect())
16807 SuppressRHSDiags =
true;
16816 if (LHSResult.Failed && !Info.noteFailure())
16827 assert(!LVal.
hasLValuePath() &&
"have designator for integer lvalue");
16829 uint64_t Offset64 = Offset.getQuantity();
16830 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
16832 : Offset64 + Index64);
16835bool DataRecursiveIntBinOpEvaluator::
16836 VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
16839 if (RHSResult.Failed)
16846 bool lhsResult, rhsResult;
16861 if (rhsResult == (E->
getOpcode() == BO_LOr))
16872 if (LHSResult.Failed || RHSResult.Failed)
16875 const APValue &LHSVal = LHSResult.Val;
16876 const APValue &RHSVal = RHSResult.Val;
16900 if (!LHSExpr || !RHSExpr)
16902 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
16903 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
16904 if (!LHSAddrExpr || !RHSAddrExpr)
16929void DataRecursiveIntBinOpEvaluator::process(EvalResult &
Result) {
16930 Job &job = Queue.back();
16932 switch (job.Kind) {
16933 case Job::AnyExprKind: {
16934 if (
const BinaryOperator *Bop = dyn_cast<BinaryOperator>(job.E)) {
16935 if (shouldEnqueue(Bop)) {
16936 job.Kind = Job::BinOpKind;
16937 enqueue(Bop->getLHS());
16942 EvaluateExpr(job.E,
Result);
16947 case Job::BinOpKind: {
16949 bool SuppressRHSDiags =
false;
16950 if (!VisitBinOpLHSOnly(
Result, Bop, SuppressRHSDiags)) {
16954 if (SuppressRHSDiags)
16955 job.startSpeculativeEval(Info);
16956 job.LHSResult.swap(
Result);
16957 job.Kind = Job::BinOpVisitedLHSKind;
16962 case Job::BinOpVisitedLHSKind: {
16966 Result.Failed = !VisitBinOp(job.LHSResult, RHS, Bop,
Result.Val);
16972 llvm_unreachable(
"Invalid Job::Kind!");
16976enum class CmpResult {
16985template <
class SuccessCB,
class AfterCB>
16988 SuccessCB &&
Success, AfterCB &&DoAfter) {
16993 "unsupported binary expression evaluation");
16995 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
17009 if (!LHSOK && !Info.noteFailure())
17014 return Success(CmpResult::Less, E);
17016 return Success(CmpResult::Greater, E);
17017 return Success(CmpResult::Equal, E);
17025 if (!LHSOK && !Info.noteFailure())
17030 return Success(CmpResult::Less, E);
17032 return Success(CmpResult::Greater, E);
17033 return Success(CmpResult::Equal, E);
17037 ComplexValue LHS, RHS;
17046 LHS.makeComplexFloat();
17047 LHS.FloatImag = APFloat(LHS.FloatReal.getSemantics());
17052 if (!LHSOK && !Info.noteFailure())
17058 RHS.makeComplexFloat();
17059 RHS.FloatImag = APFloat(RHS.FloatReal.getSemantics());
17063 if (LHS.isComplexFloat()) {
17064 APFloat::cmpResult CR_r =
17065 LHS.getComplexFloatReal().compare(RHS.getComplexFloatReal());
17066 APFloat::cmpResult CR_i =
17067 LHS.getComplexFloatImag().compare(RHS.getComplexFloatImag());
17068 bool IsEqual = CR_r == APFloat::cmpEqual && CR_i == APFloat::cmpEqual;
17069 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal, E);
17071 assert(IsEquality &&
"invalid complex comparison");
17072 bool IsEqual = LHS.getComplexIntReal() == RHS.getComplexIntReal() &&
17073 LHS.getComplexIntImag() == RHS.getComplexIntImag();
17074 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal, E);
17080 APFloat RHS(0.0), LHS(0.0);
17083 if (!LHSOK && !Info.noteFailure())
17090 llvm::APFloatBase::cmpResult APFloatCmpResult = LHS.compare(RHS);
17091 if (!Info.InConstantContext &&
17092 APFloatCmpResult == APFloat::cmpUnordered &&
17095 Info.FFDiag(E, diag::note_constexpr_float_arithmetic_strict);
17098 auto GetCmpRes = [&]() {
17099 switch (APFloatCmpResult) {
17100 case APFloat::cmpEqual:
17101 return CmpResult::Equal;
17102 case APFloat::cmpLessThan:
17103 return CmpResult::Less;
17104 case APFloat::cmpGreaterThan:
17105 return CmpResult::Greater;
17106 case APFloat::cmpUnordered:
17107 return CmpResult::Unordered;
17109 llvm_unreachable(
"Unrecognised APFloat::cmpResult enum");
17111 return Success(GetCmpRes(), E);
17115 LValue LHSValue, RHSValue;
17118 if (!LHSOK && !Info.noteFailure())
17129 if (Info.checkingPotentialConstantExpression() &&
17130 (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown))
17132 auto DiagComparison = [&] (
unsigned DiagID,
bool Reversed =
false) {
17133 std::string LHS = LHSValue.toString(Info.Ctx, E->
getLHS()->
getType());
17134 std::string RHS = RHSValue.toString(Info.Ctx, E->
getRHS()->
getType());
17135 Info.FFDiag(E, DiagID)
17142 return DiagComparison(
17143 diag::note_constexpr_pointer_comparison_unspecified);
17149 if ((!LHSValue.Base && !LHSValue.Offset.
isZero()) ||
17150 (!RHSValue.Base && !RHSValue.Offset.
isZero()))
17151 return DiagComparison(diag::note_constexpr_pointer_constant_comparison,
17165 return DiagComparison(diag::note_constexpr_literal_comparison);
17167 return DiagComparison(diag::note_constexpr_opaque_call_comparison,
17172 return DiagComparison(diag::note_constexpr_pointer_weak_comparison,
17176 if (LHSValue.Base && LHSValue.Offset.
isZero() &&
17178 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
17180 if (RHSValue.Base && RHSValue.Offset.
isZero() &&
17182 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
17188 return DiagComparison(
17189 diag::note_constexpr_pointer_comparison_zero_sized);
17190 if (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown)
17191 return DiagComparison(
17192 diag::note_constexpr_pointer_comparison_unspecified);
17194 return Success(CmpResult::Unequal, E);
17197 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
17198 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
17200 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
17201 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
17211 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid && IsRelational) {
17212 bool WasArrayIndex;
17215 :
getType(LHSValue.Base).getNonReferenceType(),
17216 LHSDesignator, RHSDesignator, WasArrayIndex);
17223 if (!WasArrayIndex && Mismatch < LHSDesignator.Entries.size() &&
17224 Mismatch < RHSDesignator.Entries.size()) {
17225 const FieldDecl *LF = getAsField(LHSDesignator.Entries[Mismatch]);
17226 const FieldDecl *RF = getAsField(RHSDesignator.Entries[Mismatch]);
17228 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_classes);
17230 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
17231 << getAsBaseClass(LHSDesignator.Entries[Mismatch])
17234 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
17235 << getAsBaseClass(RHSDesignator.Entries[Mismatch])
17240 diag::note_constexpr_pointer_comparison_differing_access)
17251 assert(PtrSize <= 64 &&
"Unexpected pointer width");
17252 uint64_t Mask = ~0ULL >> (64 - PtrSize);
17253 CompareLHS &= Mask;
17254 CompareRHS &= Mask;
17259 if (!LHSValue.Base.
isNull() && IsRelational) {
17264 uint64_t OffsetLimit = Size.getQuantity();
17265 if (CompareLHS > OffsetLimit || CompareRHS > OffsetLimit)
17269 if (CompareLHS < CompareRHS)
17270 return Success(CmpResult::Less, E);
17271 if (CompareLHS > CompareRHS)
17272 return Success(CmpResult::Greater, E);
17273 return Success(CmpResult::Equal, E);
17277 assert(IsEquality &&
"unexpected member pointer operation");
17280 MemberPtr LHSValue, RHSValue;
17283 if (!LHSOK && !Info.noteFailure())
17291 if (LHSValue.getDecl() && LHSValue.getDecl()->isWeak()) {
17292 Info.FFDiag(E, diag::note_constexpr_mem_pointer_weak_comparison)
17293 << LHSValue.getDecl();
17296 if (RHSValue.getDecl() && RHSValue.getDecl()->isWeak()) {
17297 Info.FFDiag(E, diag::note_constexpr_mem_pointer_weak_comparison)
17298 << RHSValue.getDecl();
17305 if (!LHSValue.getDecl() || !RHSValue.getDecl()) {
17306 bool Equal = !LHSValue.getDecl() && !RHSValue.getDecl();
17307 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal, E);
17312 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(LHSValue.getDecl()))
17313 if (MD->isVirtual())
17314 Info.CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
17315 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(RHSValue.getDecl()))
17316 if (MD->isVirtual())
17317 Info.CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
17323 bool Equal = LHSValue == RHSValue;
17324 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal, E);
17329 assert(RHSTy->
isNullPtrType() &&
"missing pointer conversion");
17337 return Success(CmpResult::Equal, E);
17343bool RecordExprEvaluator::VisitBinCmp(
const BinaryOperator *E) {
17347 auto OnSuccess = [&](CmpResult CR,
const BinaryOperator *E) {
17350 case CmpResult::Unequal:
17351 llvm_unreachable(
"should never produce Unequal for three-way comparison");
17352 case CmpResult::Less:
17353 CCR = ComparisonCategoryResult::Less;
17355 case CmpResult::Equal:
17356 CCR = ComparisonCategoryResult::Equal;
17358 case CmpResult::Greater:
17359 CCR = ComparisonCategoryResult::Greater;
17361 case CmpResult::Unordered:
17362 CCR = ComparisonCategoryResult::Unordered;
17367 const ComparisonCategoryInfo &CmpInfo =
17376 ConstantExprKind::Normal);
17379 return ExprEvaluatorBaseTy::VisitBinCmp(E);
17383bool RecordExprEvaluator::VisitCXXParenListInitExpr(
17384 const CXXParenListInitExpr *E) {
17385 return VisitCXXParenListOrInitListExpr(E, E->
getInitExprs());
17388bool IntExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
17393 if (!Info.noteFailure())
17397 if (DataRecursiveIntBinOpEvaluator::shouldEnqueue(E))
17398 return DataRecursiveIntBinOpEvaluator(*
this,
Result).Traverse(E);
17402 "DataRecursiveIntBinOpEvaluator should have handled integral types");
17407 auto OnSuccess = [&](CmpResult CR,
const BinaryOperator *E) {
17408 assert((CR != CmpResult::Unequal || E->
isEqualityOp()) &&
17409 "should only produce Unequal for equality comparisons");
17410 bool IsEqual = CR == CmpResult::Equal,
17411 IsLess = CR == CmpResult::Less,
17412 IsGreater = CR == CmpResult::Greater;
17416 llvm_unreachable(
"unsupported binary operator");
17419 return Success(IsEqual == (Op == BO_EQ), E);
17423 return Success(IsGreater, E);
17425 return Success(IsEqual || IsLess, E);
17427 return Success(IsEqual || IsGreater, E);
17431 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
17440 LValue LHSValue, RHSValue;
17443 if (!LHSOK && !Info.noteFailure())
17452 if (Info.checkingPotentialConstantExpression() &&
17453 (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown))
17456 const Expr *LHSExpr = LHSValue.Base.
dyn_cast<
const Expr *>();
17457 const Expr *RHSExpr = RHSValue.Base.
dyn_cast<
const Expr *>();
17459 auto DiagArith = [&](
unsigned DiagID) {
17460 std::string LHS = LHSValue.toString(Info.Ctx, E->
getLHS()->
getType());
17461 std::string RHS = RHSValue.toString(Info.Ctx, E->
getRHS()->
getType());
17462 Info.FFDiag(E, DiagID) << LHS << RHS;
17463 if (LHSExpr && LHSExpr == RHSExpr)
17465 diag::note_constexpr_repeated_literal_eval)
17470 if (!LHSExpr || !RHSExpr)
17471 return DiagArith(diag::note_constexpr_pointer_arith_unspecified);
17474 return DiagArith(diag::note_constexpr_literal_arith);
17476 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
17477 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
17478 if (!LHSAddrExpr || !RHSAddrExpr)
17486 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
17487 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
17489 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
17490 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
17496 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid &&
17499 Info.CCEDiag(E, diag::note_constexpr_pointer_subtraction_not_same_array);
17504 CharUnits ElementSize;
17511 if (ElementSize.
isZero()) {
17512 Info.FFDiag(E, diag::note_constexpr_pointer_subtraction_zero_size)
17529 APSInt TrueResult = (LHS - RHS) / ElemSize;
17532 if (
Result.extend(65) != TrueResult &&
17538 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
17543bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr(
17544 const UnaryExprOrTypeTraitExpr *E) {
17546 case UETT_PreferredAlignOf:
17547 case UETT_AlignOf: {
17556 case UETT_PtrAuthTypeDiscriminator: {
17562 case UETT_VecStep: {
17566 unsigned n = Ty->
castAs<VectorType>()->getNumElements();
17578 case UETT_DataSizeOf:
17579 case UETT_SizeOf: {
17583 if (
const ReferenceType *Ref = SrcTy->
getAs<ReferenceType>())
17594 case UETT_OpenMPRequiredSimdAlign:
17601 case UETT_VectorElements: {
17605 if (
const auto *VT = Ty->
getAs<VectorType>())
17609 if (Info.InConstantContext)
17610 Info.CCEDiag(E, diag::note_constexpr_non_const_vectorelements)
17615 case UETT_CountOf: {
17621 if (
const auto *CAT =
17633 if (VAT->getElementType()->isArrayType()) {
17636 if (!VAT->getSizeExpr()) {
17641 std::optional<APSInt> Res =
17642 VAT->getSizeExpr()->getIntegerConstantExpr(Info.Ctx);
17648 Res->getZExtValue()};
17660 llvm_unreachable(
"unknown expr/type trait");
17663bool IntExprEvaluator::VisitOffsetOfExpr(
const OffsetOfExpr *OOE) {
17669 for (
unsigned i = 0; i != n; ++i) {
17682 Result += IdxResult.getSExtValue() * ElementSize;
17687 FieldDecl *MemberDecl = ON.
getField();
17694 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
17701 llvm_unreachable(
"dependent __builtin_offsetof");
17704 CXXBaseSpecifier *BaseSpec = ON.
getBase();
17716 CurrentType = BaseSpec->
getType();
17730bool IntExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
17749 if (Info.checkingForUndefinedBehavior())
17751 diag::warn_integer_constant_overflow)
17779bool IntExprEvaluator::VisitCastExpr(
const CastExpr *E) {
17781 QualType DestType = E->
getType();
17782 QualType SrcType = SubExpr->
getType();
17785 case CK_BaseToDerived:
17786 case CK_DerivedToBase:
17787 case CK_UncheckedDerivedToBase:
17790 case CK_ArrayToPointerDecay:
17791 case CK_FunctionToPointerDecay:
17792 case CK_NullToPointer:
17793 case CK_NullToMemberPointer:
17794 case CK_BaseToDerivedMemberPointer:
17795 case CK_DerivedToBaseMemberPointer:
17796 case CK_ReinterpretMemberPointer:
17797 case CK_ConstructorConversion:
17798 case CK_IntegralToPointer:
17800 case CK_VectorSplat:
17801 case CK_IntegralToFloating:
17802 case CK_FloatingCast:
17803 case CK_CPointerToObjCPointerCast:
17804 case CK_BlockPointerToObjCPointerCast:
17805 case CK_AnyPointerToBlockPointerCast:
17806 case CK_ObjCObjectLValueCast:
17807 case CK_FloatingRealToComplex:
17808 case CK_FloatingComplexToReal:
17809 case CK_FloatingComplexCast:
17810 case CK_FloatingComplexToIntegralComplex:
17811 case CK_IntegralRealToComplex:
17812 case CK_IntegralComplexCast:
17813 case CK_IntegralComplexToFloatingComplex:
17814 case CK_BuiltinFnToFnPtr:
17815 case CK_ZeroToOCLOpaqueType:
17816 case CK_NonAtomicToAtomic:
17817 case CK_AddressSpaceConversion:
17818 case CK_IntToOCLSampler:
17819 case CK_FloatingToFixedPoint:
17820 case CK_FixedPointToFloating:
17821 case CK_FixedPointCast:
17822 case CK_IntegralToFixedPoint:
17823 case CK_MatrixCast:
17824 case CK_HLSLAggregateSplatCast:
17825 llvm_unreachable(
"invalid cast kind for integral value");
17829 case CK_LValueBitCast:
17830 case CK_ARCProduceObject:
17831 case CK_ARCConsumeObject:
17832 case CK_ARCReclaimReturnedObject:
17833 case CK_ARCExtendBlockObject:
17834 case CK_CopyAndAutoreleaseBlockObject:
17837 case CK_UserDefinedConversion:
17838 case CK_LValueToRValue:
17839 case CK_AtomicToNonAtomic:
17841 case CK_LValueToRValueBitCast:
17842 case CK_HLSLArrayRValue:
17843 return ExprEvaluatorBaseTy::VisitCastExpr(E);
17845 case CK_MemberPointerToBoolean:
17846 case CK_PointerToBoolean:
17847 case CK_IntegralToBoolean:
17848 case CK_FloatingToBoolean:
17849 case CK_BooleanToSignedIntegral:
17850 case CK_FloatingComplexToBoolean:
17851 case CK_IntegralComplexToBoolean: {
17856 if (BoolResult && E->
getCastKind() == CK_BooleanToSignedIntegral)
17858 return Success(IntResult, E);
17861 case CK_FixedPointToIntegral: {
17866 llvm::APSInt
Result = Src.convertToInt(
17874 case CK_FixedPointToBoolean: {
17877 if (!
Evaluate(Val, Info, SubExpr))
17882 case CK_IntegralCast: {
17883 if (!Visit(SubExpr))
17892 if (
Result.isAddrLabelDiff())
17910 if (!ED->isFixed()) {
17914 ED->getValueRange(
Max,
Min);
17917 if (ED->getNumNegativeBits() &&
17918 (
Max.slt(
Result.getInt().getSExtValue()) ||
17919 Min.sgt(
Result.getInt().getSExtValue())))
17920 Info.CCEDiag(E, diag::note_constexpr_unscoped_enum_out_of_range)
17921 << llvm::toString(
Result.getInt(), 10) <<
Min.getSExtValue()
17922 <<
Max.getSExtValue() << ED;
17923 else if (!ED->getNumNegativeBits() &&
17924 Max.ult(
Result.getInt().getZExtValue()))
17925 Info.CCEDiag(E, diag::note_constexpr_unscoped_enum_out_of_range)
17926 << llvm::toString(
Result.getInt(), 10) <<
Min.getZExtValue()
17927 <<
Max.getZExtValue() << ED;
17935 case CK_PointerToIntegral: {
17936 CCEDiag(E, diag::note_constexpr_invalid_cast)
17937 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
17944 if (LV.getLValueBase()) {
17952 LV.Designator.setInvalid();
17960 if (!
V.toIntegralConstant(AsInt, SrcType, Info.Ctx))
17961 llvm_unreachable(
"Can't cast this!");
17966 case CK_IntegralComplexToReal: {
17970 return Success(
C.getComplexIntReal(), E);
17973 case CK_FloatingToIntegral: {
17983 case CK_HLSLVectorTruncation: {
17989 case CK_HLSLElementwiseCast: {
18002 return Success(ResultVal, E);
18006 llvm_unreachable(
"unknown cast resulting in integral value");
18009bool IntExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
18014 if (!LV.isComplexInt())
18016 return Success(LV.getComplexIntReal(), E);
18022bool IntExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
18027 if (!LV.isComplexInt())
18029 return Success(LV.getComplexIntImag(), E);
18036bool IntExprEvaluator::VisitSizeOfPackExpr(
const SizeOfPackExpr *E) {
18040bool IntExprEvaluator::VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E) {
18044bool IntExprEvaluator::VisitConceptSpecializationExpr(
18045 const ConceptSpecializationExpr *E) {
18049bool IntExprEvaluator::VisitRequiresExpr(
const RequiresExpr *E) {
18053bool FixedPointExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
18063 if (!
Result.isFixedPoint())
18066 APFixedPoint Negated =
Result.getFixedPoint().negate(&Overflowed);
18080bool FixedPointExprEvaluator::VisitCastExpr(
const CastExpr *E) {
18082 QualType DestType = E->
getType();
18084 "Expected destination type to be a fixed point type");
18088 case CK_FixedPointCast: {
18093 APFixedPoint
Result = Src.convert(DestFXSema, &Overflowed);
18095 if (Info.checkingForUndefinedBehavior())
18097 diag::warn_fixedpoint_constant_overflow)
18104 case CK_IntegralToFixedPoint: {
18110 APFixedPoint IntResult = APFixedPoint::getFromIntValue(
18114 if (Info.checkingForUndefinedBehavior())
18116 diag::warn_fixedpoint_constant_overflow)
18117 << IntResult.toString() << E->
getType();
18122 return Success(IntResult, E);
18124 case CK_FloatingToFixedPoint: {
18130 APFixedPoint
Result = APFixedPoint::getFromFloatValue(
18134 if (Info.checkingForUndefinedBehavior())
18136 diag::warn_fixedpoint_constant_overflow)
18145 case CK_LValueToRValue:
18146 return ExprEvaluatorBaseTy::VisitCastExpr(E);
18152bool FixedPointExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
18154 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
18156 const Expr *LHS = E->
getLHS();
18157 const Expr *RHS = E->
getRHS();
18168 bool OpOverflow =
false, ConversionOverflow =
false;
18169 APFixedPoint
Result(LHSFX.getSemantics());
18172 Result = LHSFX.add(RHSFX, &OpOverflow)
18173 .convert(ResultFXSema, &ConversionOverflow);
18177 Result = LHSFX.sub(RHSFX, &OpOverflow)
18178 .convert(ResultFXSema, &ConversionOverflow);
18182 Result = LHSFX.mul(RHSFX, &OpOverflow)
18183 .convert(ResultFXSema, &ConversionOverflow);
18187 if (RHSFX.getValue() == 0) {
18188 Info.FFDiag(E, diag::note_expr_divide_by_zero);
18191 Result = LHSFX.div(RHSFX, &OpOverflow)
18192 .convert(ResultFXSema, &ConversionOverflow);
18198 llvm::APSInt RHSVal = RHSFX.getValue();
18201 LHSSema.getWidth() - (unsigned)LHSSema.hasUnsignedPadding();
18202 unsigned Amt = RHSVal.getLimitedValue(ShiftBW - 1);
18206 if (RHSVal.isNegative())
18207 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHSVal;
18208 else if (Amt != RHSVal)
18209 Info.CCEDiag(E, diag::note_constexpr_large_shift)
18210 << RHSVal << E->
getType() << ShiftBW;
18213 Result = LHSFX.shl(Amt, &OpOverflow);
18215 Result = LHSFX.shr(Amt, &OpOverflow);
18221 if (OpOverflow || ConversionOverflow) {
18222 if (Info.checkingForUndefinedBehavior())
18224 diag::warn_fixedpoint_constant_overflow)
18237class FloatExprEvaluator
18238 :
public ExprEvaluatorBase<FloatExprEvaluator> {
18241 FloatExprEvaluator(EvalInfo &info, APFloat &result)
18242 : ExprEvaluatorBaseTy(info),
Result(result) {}
18249 bool ZeroInitialization(
const Expr *E) {
18254 bool VisitCallExpr(
const CallExpr *E);
18256 bool VisitUnaryOperator(
const UnaryOperator *E);
18257 bool VisitBinaryOperator(
const BinaryOperator *E);
18258 bool VisitFloatingLiteral(
const FloatingLiteral *E);
18259 bool VisitCastExpr(
const CastExpr *E);
18261 bool VisitUnaryReal(
const UnaryOperator *E);
18262 bool VisitUnaryImag(
const UnaryOperator *E);
18271 return FloatExprEvaluator(Info, Result).Visit(E);
18278 llvm::APFloat &Result) {
18280 if (!S)
return false;
18282 const llvm::fltSemantics &Sem = Context.getFloatTypeSemantics(ResultTy);
18288 fill = llvm::APInt(32, 0);
18289 else if (S->
getString().getAsInteger(0, fill))
18292 if (Context.getTargetInfo().isNan2008()) {
18294 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
18296 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
18304 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
18306 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
18312bool FloatExprEvaluator::VisitCallExpr(
const CallExpr *E) {
18313 if (!IsConstantEvaluatedBuiltinCall(E))
18314 return ExprEvaluatorBaseTy::VisitCallExpr(E);
18320 case Builtin::BI__builtin_huge_val:
18321 case Builtin::BI__builtin_huge_valf:
18322 case Builtin::BI__builtin_huge_vall:
18323 case Builtin::BI__builtin_huge_valf16:
18324 case Builtin::BI__builtin_huge_valf128:
18325 case Builtin::BI__builtin_inf:
18326 case Builtin::BI__builtin_inff:
18327 case Builtin::BI__builtin_infl:
18328 case Builtin::BI__builtin_inff16:
18329 case Builtin::BI__builtin_inff128: {
18330 const llvm::fltSemantics &Sem =
18332 Result = llvm::APFloat::getInf(Sem);
18336 case Builtin::BI__builtin_nans:
18337 case Builtin::BI__builtin_nansf:
18338 case Builtin::BI__builtin_nansl:
18339 case Builtin::BI__builtin_nansf16:
18340 case Builtin::BI__builtin_nansf128:
18346 case Builtin::BI__builtin_nan:
18347 case Builtin::BI__builtin_nanf:
18348 case Builtin::BI__builtin_nanl:
18349 case Builtin::BI__builtin_nanf16:
18350 case Builtin::BI__builtin_nanf128:
18358 case Builtin::BI__builtin_elementwise_abs:
18359 case Builtin::BI__builtin_fabs:
18360 case Builtin::BI__builtin_fabsf:
18361 case Builtin::BI__builtin_fabsl:
18362 case Builtin::BI__builtin_fabsf128:
18371 if (
Result.isNegative())
18375 case Builtin::BI__arithmetic_fence:
18382 case Builtin::BI__builtin_copysign:
18383 case Builtin::BI__builtin_copysignf:
18384 case Builtin::BI__builtin_copysignl:
18385 case Builtin::BI__builtin_copysignf128: {
18394 case Builtin::BI__builtin_fmax:
18395 case Builtin::BI__builtin_fmaxf:
18396 case Builtin::BI__builtin_fmaxl:
18397 case Builtin::BI__builtin_fmaxf16:
18398 case Builtin::BI__builtin_fmaxf128: {
18407 case Builtin::BI__builtin_fmin:
18408 case Builtin::BI__builtin_fminf:
18409 case Builtin::BI__builtin_fminl:
18410 case Builtin::BI__builtin_fminf16:
18411 case Builtin::BI__builtin_fminf128: {
18420 case Builtin::BI__builtin_fmaximum_num:
18421 case Builtin::BI__builtin_fmaximum_numf:
18422 case Builtin::BI__builtin_fmaximum_numl:
18423 case Builtin::BI__builtin_fmaximum_numf16:
18424 case Builtin::BI__builtin_fmaximum_numf128: {
18433 case Builtin::BI__builtin_fminimum_num:
18434 case Builtin::BI__builtin_fminimum_numf:
18435 case Builtin::BI__builtin_fminimum_numl:
18436 case Builtin::BI__builtin_fminimum_numf16:
18437 case Builtin::BI__builtin_fminimum_numf128: {
18446 case Builtin::BI__builtin_elementwise_fma: {
18451 APFloat SourceY(0.), SourceZ(0.);
18457 (void)
Result.fusedMultiplyAdd(SourceY, SourceZ, RM);
18461 case clang::X86::BI__builtin_ia32_vec_ext_v4sf: {
18468 unsigned Idx =
static_cast<unsigned>(IdxAPS.getZExtValue() & (N - 1));
18474bool FloatExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
18486bool FloatExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
18497 Result = llvm::APFloat::getZero(Sem);
18501bool FloatExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
18503 default:
return Error(E);
18517bool FloatExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
18519 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
18523 if (!LHSOK && !Info.noteFailure())
18529bool FloatExprEvaluator::VisitFloatingLiteral(
const FloatingLiteral *E) {
18534bool FloatExprEvaluator::VisitCastExpr(
const CastExpr *E) {
18539 return ExprEvaluatorBaseTy::VisitCastExpr(E);
18541 case CK_HLSLAggregateSplatCast:
18542 llvm_unreachable(
"invalid cast kind for floating value");
18544 case CK_IntegralToFloating: {
18553 case CK_FixedPointToFloating: {
18562 case CK_FloatingCast: {
18563 if (!Visit(SubExpr))
18569 case CK_FloatingComplexToReal: {
18573 Result =
V.getComplexFloatReal();
18576 case CK_HLSLVectorTruncation: {
18582 case CK_HLSLElementwiseCast: {
18597 return Success(ResultVal, E);
18607class ComplexExprEvaluator
18608 :
public ExprEvaluatorBase<ComplexExprEvaluator> {
18612 ComplexExprEvaluator(EvalInfo &info, ComplexValue &
Result)
18620 bool ZeroInitialization(
const Expr *E);
18626 bool VisitImaginaryLiteral(
const ImaginaryLiteral *E);
18627 bool VisitCastExpr(
const CastExpr *E);
18628 bool VisitBinaryOperator(
const BinaryOperator *E);
18629 bool VisitUnaryOperator(
const UnaryOperator *E);
18630 bool VisitInitListExpr(
const InitListExpr *E);
18631 bool VisitCallExpr(
const CallExpr *E);
18639 return ComplexExprEvaluator(Info, Result).Visit(E);
18642bool ComplexExprEvaluator::ZeroInitialization(
const Expr *E) {
18643 QualType ElemTy = E->
getType()->
castAs<ComplexType>()->getElementType();
18645 Result.makeComplexFloat();
18650 Result.makeComplexInt();
18658bool ComplexExprEvaluator::VisitImaginaryLiteral(
const ImaginaryLiteral *E) {
18662 Result.makeComplexFloat();
18671 "Unexpected imaginary literal.");
18673 Result.makeComplexInt();
18678 Result.IntReal =
APSInt(Imag.getBitWidth(), !Imag.isSigned());
18683bool ComplexExprEvaluator::VisitCastExpr(
const CastExpr *E) {
18687 case CK_BaseToDerived:
18688 case CK_DerivedToBase:
18689 case CK_UncheckedDerivedToBase:
18692 case CK_ArrayToPointerDecay:
18693 case CK_FunctionToPointerDecay:
18694 case CK_NullToPointer:
18695 case CK_NullToMemberPointer:
18696 case CK_BaseToDerivedMemberPointer:
18697 case CK_DerivedToBaseMemberPointer:
18698 case CK_MemberPointerToBoolean:
18699 case CK_ReinterpretMemberPointer:
18700 case CK_ConstructorConversion:
18701 case CK_IntegralToPointer:
18702 case CK_PointerToIntegral:
18703 case CK_PointerToBoolean:
18705 case CK_VectorSplat:
18706 case CK_IntegralCast:
18707 case CK_BooleanToSignedIntegral:
18708 case CK_IntegralToBoolean:
18709 case CK_IntegralToFloating:
18710 case CK_FloatingToIntegral:
18711 case CK_FloatingToBoolean:
18712 case CK_FloatingCast:
18713 case CK_CPointerToObjCPointerCast:
18714 case CK_BlockPointerToObjCPointerCast:
18715 case CK_AnyPointerToBlockPointerCast:
18716 case CK_ObjCObjectLValueCast:
18717 case CK_FloatingComplexToReal:
18718 case CK_FloatingComplexToBoolean:
18719 case CK_IntegralComplexToReal:
18720 case CK_IntegralComplexToBoolean:
18721 case CK_ARCProduceObject:
18722 case CK_ARCConsumeObject:
18723 case CK_ARCReclaimReturnedObject:
18724 case CK_ARCExtendBlockObject:
18725 case CK_CopyAndAutoreleaseBlockObject:
18726 case CK_BuiltinFnToFnPtr:
18727 case CK_ZeroToOCLOpaqueType:
18728 case CK_NonAtomicToAtomic:
18729 case CK_AddressSpaceConversion:
18730 case CK_IntToOCLSampler:
18731 case CK_FloatingToFixedPoint:
18732 case CK_FixedPointToFloating:
18733 case CK_FixedPointCast:
18734 case CK_FixedPointToBoolean:
18735 case CK_FixedPointToIntegral:
18736 case CK_IntegralToFixedPoint:
18737 case CK_MatrixCast:
18738 case CK_HLSLVectorTruncation:
18739 case CK_HLSLElementwiseCast:
18740 case CK_HLSLAggregateSplatCast:
18741 llvm_unreachable(
"invalid cast kind for complex value");
18743 case CK_LValueToRValue:
18744 case CK_AtomicToNonAtomic:
18746 case CK_LValueToRValueBitCast:
18747 case CK_HLSLArrayRValue:
18748 return ExprEvaluatorBaseTy::VisitCastExpr(E);
18751 case CK_LValueBitCast:
18752 case CK_UserDefinedConversion:
18755 case CK_FloatingRealToComplex: {
18760 Result.makeComplexFloat();
18765 case CK_FloatingComplexCast: {
18769 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
18777 case CK_FloatingComplexToIntegralComplex: {
18781 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
18784 Result.makeComplexInt();
18791 case CK_IntegralRealToComplex: {
18796 Result.makeComplexInt();
18797 Result.IntImag =
APSInt(Real.getBitWidth(), !Real.isSigned());
18801 case CK_IntegralComplexCast: {
18805 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
18814 case CK_IntegralComplexToFloatingComplex: {
18820 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
18823 Result.makeComplexFloat();
18825 To,
Result.FloatReal) &&
18831 llvm_unreachable(
"unknown cast resulting in complex value");
18835 APFloat &ResR, APFloat &ResI) {
18841 APFloat AC = A *
C;
18842 APFloat BD = B * D;
18843 APFloat AD = A * D;
18844 APFloat BC = B *
C;
18847 if (ResR.isNaN() && ResI.isNaN()) {
18848 bool Recalc =
false;
18849 if (A.isInfinity() || B.isInfinity()) {
18850 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
18852 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
18855 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
18857 D = APFloat::copySign(APFloat(D.getSemantics()), D);
18860 if (
C.isInfinity() || D.isInfinity()) {
18861 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
18863 D = APFloat::copySign(APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0),
18866 A = APFloat::copySign(APFloat(A.getSemantics()), A);
18868 B = APFloat::copySign(APFloat(B.getSemantics()), B);
18871 if (!Recalc && (AC.isInfinity() || BD.isInfinity() || AD.isInfinity() ||
18872 BC.isInfinity())) {
18874 A = APFloat::copySign(APFloat(A.getSemantics()), A);
18876 B = APFloat::copySign(APFloat(B.getSemantics()), B);
18878 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
18880 D = APFloat::copySign(APFloat(D.getSemantics()), D);
18884 ResR = APFloat::getInf(A.getSemantics()) * (A *
C - B * D);
18885 ResI = APFloat::getInf(A.getSemantics()) * (A * D + B *
C);
18891 APFloat &ResR, APFloat &ResI) {
18898 APFloat MaxCD = maxnum(
abs(
C),
abs(D));
18899 if (MaxCD.isFinite()) {
18900 DenomLogB =
ilogb(MaxCD);
18901 C =
scalbn(
C, -DenomLogB, APFloat::rmNearestTiesToEven);
18902 D =
scalbn(D, -DenomLogB, APFloat::rmNearestTiesToEven);
18904 APFloat Denom =
C *
C + D * D;
18906 scalbn((A *
C + B * D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
18908 scalbn((B *
C - A * D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
18909 if (ResR.isNaN() && ResI.isNaN()) {
18910 if (Denom.isPosZero() && (!A.isNaN() || !B.isNaN())) {
18911 ResR = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * A;
18912 ResI = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * B;
18913 }
else if ((A.isInfinity() || B.isInfinity()) &&
C.isFinite() &&
18915 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
18917 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
18919 ResR = APFloat::getInf(ResR.getSemantics()) * (A *
C + B * D);
18920 ResI = APFloat::getInf(ResI.getSemantics()) * (B *
C - A * D);
18921 }
else if (MaxCD.isInfinity() && A.isFinite() && B.isFinite()) {
18922 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
18924 D = APFloat::copySign(APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0),
18926 ResR = APFloat::getZero(ResR.getSemantics()) * (A *
C + B * D);
18927 ResI = APFloat::getZero(ResI.getSemantics()) * (B *
C - A * D);
18932bool ComplexExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
18934 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
18938 bool LHSReal =
false, RHSReal =
false;
18946 Result.makeComplexFloat();
18950 LHSOK = Visit(E->
getLHS());
18952 if (!LHSOK && !Info.noteFailure())
18958 APFloat &Real = RHS.FloatReal;
18961 RHS.makeComplexFloat();
18962 RHS.FloatImag =
APFloat(Real.getSemantics());
18966 assert(!(LHSReal && RHSReal) &&
18967 "Cannot have both operands of a complex operation be real.");
18969 default:
return Error(E);
18971 if (
Result.isComplexFloat()) {
18972 Result.getComplexFloatReal().add(RHS.getComplexFloatReal(),
18973 APFloat::rmNearestTiesToEven);
18975 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
18977 Result.getComplexFloatImag().add(RHS.getComplexFloatImag(),
18978 APFloat::rmNearestTiesToEven);
18980 Result.getComplexIntReal() += RHS.getComplexIntReal();
18981 Result.getComplexIntImag() += RHS.getComplexIntImag();
18985 if (
Result.isComplexFloat()) {
18986 Result.getComplexFloatReal().subtract(RHS.getComplexFloatReal(),
18987 APFloat::rmNearestTiesToEven);
18989 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
18990 Result.getComplexFloatImag().changeSign();
18991 }
else if (!RHSReal) {
18992 Result.getComplexFloatImag().subtract(RHS.getComplexFloatImag(),
18993 APFloat::rmNearestTiesToEven);
18996 Result.getComplexIntReal() -= RHS.getComplexIntReal();
18997 Result.getComplexIntImag() -= RHS.getComplexIntImag();
19001 if (
Result.isComplexFloat()) {
19006 ComplexValue LHS =
Result;
19007 APFloat &A = LHS.getComplexFloatReal();
19008 APFloat &B = LHS.getComplexFloatImag();
19009 APFloat &
C = RHS.getComplexFloatReal();
19010 APFloat &D = RHS.getComplexFloatImag();
19014 assert(!RHSReal &&
"Cannot have two real operands for a complex op!");
19022 }
else if (RHSReal) {
19034 ComplexValue LHS =
Result;
19035 Result.getComplexIntReal() =
19036 (LHS.getComplexIntReal() * RHS.getComplexIntReal() -
19037 LHS.getComplexIntImag() * RHS.getComplexIntImag());
19038 Result.getComplexIntImag() =
19039 (LHS.getComplexIntReal() * RHS.getComplexIntImag() +
19040 LHS.getComplexIntImag() * RHS.getComplexIntReal());
19044 if (
Result.isComplexFloat()) {
19049 ComplexValue LHS =
Result;
19050 APFloat &A = LHS.getComplexFloatReal();
19051 APFloat &B = LHS.getComplexFloatImag();
19052 APFloat &
C = RHS.getComplexFloatReal();
19053 APFloat &D = RHS.getComplexFloatImag();
19067 B = APFloat::getZero(A.getSemantics());
19072 ComplexValue LHS =
Result;
19073 APSInt Den = RHS.getComplexIntReal() * RHS.getComplexIntReal() +
19074 RHS.getComplexIntImag() * RHS.getComplexIntImag();
19076 return Error(E, diag::note_expr_divide_by_zero);
19078 Result.getComplexIntReal() =
19079 (LHS.getComplexIntReal() * RHS.getComplexIntReal() +
19080 LHS.getComplexIntImag() * RHS.getComplexIntImag()) / Den;
19081 Result.getComplexIntImag() =
19082 (LHS.getComplexIntImag() * RHS.getComplexIntReal() -
19083 LHS.getComplexIntReal() * RHS.getComplexIntImag()) / Den;
19091bool ComplexExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
19105 if (
Result.isComplexFloat()) {
19106 Result.getComplexFloatReal().changeSign();
19107 Result.getComplexFloatImag().changeSign();
19110 Result.getComplexIntReal() = -
Result.getComplexIntReal();
19111 Result.getComplexIntImag() = -
Result.getComplexIntImag();
19115 if (
Result.isComplexFloat())
19116 Result.getComplexFloatImag().changeSign();
19118 Result.getComplexIntImag() = -
Result.getComplexIntImag();
19123bool ComplexExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
19126 Result.makeComplexFloat();
19132 Result.makeComplexInt();
19140 return ExprEvaluatorBaseTy::VisitInitListExpr(E);
19143bool ComplexExprEvaluator::VisitCallExpr(
const CallExpr *E) {
19144 if (!IsConstantEvaluatedBuiltinCall(E))
19145 return ExprEvaluatorBaseTy::VisitCallExpr(E);
19148 case Builtin::BI__builtin_complex:
19149 Result.makeComplexFloat();
19167class AtomicExprEvaluator :
19168 public ExprEvaluatorBase<AtomicExprEvaluator> {
19169 const LValue *
This;
19172 AtomicExprEvaluator(EvalInfo &Info,
const LValue *This,
APValue &
Result)
19180 bool ZeroInitialization(
const Expr *E) {
19181 ImplicitValueInitExpr VIE(
19189 bool VisitCastExpr(
const CastExpr *E) {
19192 return ExprEvaluatorBaseTy::VisitCastExpr(E);
19193 case CK_NullToPointer:
19195 return ZeroInitialization(E);
19196 case CK_NonAtomicToAtomic:
19208 return AtomicExprEvaluator(Info,
This, Result).Visit(E);
19217class VoidExprEvaluator
19218 :
public ExprEvaluatorBase<VoidExprEvaluator> {
19220 VoidExprEvaluator(EvalInfo &Info) : ExprEvaluatorBaseTy(Info) {}
19224 bool ZeroInitialization(
const Expr *E) {
return true; }
19226 bool VisitCastExpr(
const CastExpr *E) {
19229 return ExprEvaluatorBaseTy::VisitCastExpr(E);
19236 bool VisitCallExpr(
const CallExpr *E) {
19237 if (!IsConstantEvaluatedBuiltinCall(E))
19238 return ExprEvaluatorBaseTy::VisitCallExpr(E);
19241 case Builtin::BI__assume:
19242 case Builtin::BI__builtin_assume:
19246 case Builtin::BI__builtin_operator_delete:
19254 bool VisitCXXDeleteExpr(
const CXXDeleteExpr *E);
19258bool VoidExprEvaluator::VisitCXXDeleteExpr(
const CXXDeleteExpr *E) {
19260 if (Info.SpeculativeEvaluationDepth)
19264 if (!OperatorDelete
19265 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
19266 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
19276 if (
Pointer.Designator.Invalid)
19280 if (
Pointer.isNullPointer()) {
19284 if (!Info.getLangOpts().CPlusPlus20)
19285 Info.CCEDiag(E, diag::note_constexpr_new);
19293 QualType AllocType =
Pointer.Base.getDynamicAllocType();
19299 Info.FFDiag(E, diag::note_constexpr_delete_base_nonvirt_dtor)
19308 if (VirtualDelete &&
19310 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
19311 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
19318 (*Alloc)->Value, AllocType))
19321 if (!Info.HeapAllocs.erase(
Pointer.Base.dyn_cast<DynamicAllocLValue>())) {
19326 Info.FFDiag(E, diag::note_constexpr_double_delete);
19336 return VoidExprEvaluator(Info).Visit(E);
19348 if (E->
isGLValue() ||
T->isFunctionType()) {
19352 LV.moveInto(Result);
19353 }
else if (
T->isVectorType()) {
19356 }
else if (
T->isIntegralOrEnumerationType()) {
19357 if (!IntExprEvaluator(Info, Result).Visit(E))
19359 }
else if (
T->hasPointerRepresentation()) {
19363 LV.moveInto(Result);
19364 }
else if (
T->isRealFloatingType()) {
19365 llvm::APFloat F(0.0);
19369 }
else if (
T->isAnyComplexType()) {
19373 C.moveInto(Result);
19374 }
else if (
T->isFixedPointType()) {
19375 if (!FixedPointExprEvaluator(Info, Result).Visit(E))
return false;
19376 }
else if (
T->isMemberPointerType()) {
19380 P.moveInto(Result);
19382 }
else if (
T->isArrayType()) {
19385 Info.CurrentCall->createTemporary(E,
T, ScopeKind::FullExpression, LV);
19389 }
else if (
T->isRecordType()) {
19392 Info.CurrentCall->createTemporary(E,
T, ScopeKind::FullExpression, LV);
19396 }
else if (
T->isVoidType()) {
19397 if (!Info.getLangOpts().CPlusPlus11)
19398 Info.CCEDiag(E, diag::note_constexpr_nonliteral)
19402 }
else if (
T->isAtomicType()) {
19403 QualType Unqual =
T.getAtomicUnqualifiedType();
19407 E, Unqual, ScopeKind::FullExpression, LV);
19415 }
else if (Info.getLangOpts().CPlusPlus11) {
19416 Info.FFDiag(E, diag::note_constexpr_nonliteral) << E->
getType();
19419 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
19430 const Expr *E,
bool AllowNonLiteralTypes) {
19446 if (
T->isArrayType())
19448 else if (
T->isRecordType())
19450 else if (
T->isAtomicType()) {
19451 QualType Unqual =
T.getAtomicUnqualifiedType();
19472 if (Info.EnableNewConstInterp) {
19476 ConstantExprKind::Normal);
19485 LV.setFrom(Info.Ctx, Result);
19492 ConstantExprKind::Normal) &&
19500 if (
const auto *L = dyn_cast<IntegerLiteral>(Exp)) {
19502 APValue(
APSInt(L->getValue(), L->getType()->isUnsignedIntegerType()));
19507 if (
const auto *L = dyn_cast<CXXBoolLiteralExpr>(Exp)) {
19513 if (
const auto *FL = dyn_cast<FloatingLiteral>(Exp)) {
19514 Result =
APValue(FL->getValue());
19519 if (
const auto *L = dyn_cast<CharacterLiteral>(Exp)) {
19525 if (
const auto *CE = dyn_cast<ConstantExpr>(Exp)) {
19526 if (CE->hasAPValueResult()) {
19527 APValue APV = CE->getAPValueResult();
19529 Result = std::move(APV);
19605 bool InConstantContext)
const {
19607 "Expression evaluator can't be called on a dependent expression.");
19608 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsRValue");
19610 Info.InConstantContext = InConstantContext;
19611 return ::EvaluateAsRValue(
this,
Result, Ctx, Info);
19615 bool InConstantContext)
const {
19617 "Expression evaluator can't be called on a dependent expression.");
19618 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsBooleanCondition");
19626 bool InConstantContext)
const {
19628 "Expression evaluator can't be called on a dependent expression.");
19629 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsInt");
19631 Info.InConstantContext = InConstantContext;
19632 return ::EvaluateAsInt(
this,
Result, Ctx, AllowSideEffects, Info);
19637 bool InConstantContext)
const {
19639 "Expression evaluator can't be called on a dependent expression.");
19640 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFixedPoint");
19642 Info.InConstantContext = InConstantContext;
19643 return ::EvaluateAsFixedPoint(
this,
Result, Ctx, AllowSideEffects, Info);
19648 bool InConstantContext)
const {
19650 "Expression evaluator can't be called on a dependent expression.");
19652 if (!
getType()->isRealFloatingType())
19655 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFloat");
19667 bool InConstantContext)
const {
19669 "Expression evaluator can't be called on a dependent expression.");
19671 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsLValue");
19673 Info.InConstantContext = InConstantContext;
19677 if (Info.EnableNewConstInterp) {
19679 ConstantExprKind::Normal))
19682 LV.setFrom(Ctx,
Result.Val);
19685 ConstantExprKind::Normal, CheckedTemps);
19688 if (!
EvaluateLValue(
this, LV, Info) || !Info.discardCleanups() ||
19689 Result.HasSideEffects ||
19692 ConstantExprKind::Normal, CheckedTemps))
19695 LV.moveInto(
Result.Val);
19702 bool IsConstantDestruction) {
19703 EvalInfo Info(Ctx, EStatus,
19706 Info.setEvaluatingDecl(
Base, DestroyedValue,
19707 EvalInfo::EvaluatingDeclKind::Dtor);
19708 Info.InConstantContext = IsConstantDestruction;
19717 if (!Info.discardCleanups())
19718 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
19726 "Expression evaluator can't be called on a dependent expression.");
19732 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsConstantExpr");
19734 EvalInfo Info(Ctx,
Result, EM);
19735 Info.InConstantContext =
true;
19737 if (Info.EnableNewConstInterp) {
19741 getStorageType(Ctx,
this),
Result.Val, Kind);
19746 if (Kind == ConstantExprKind::ClassTemplateArgument)
19762 FullExpressionRAII
Scope(Info);
19767 if (!Info.discardCleanups())
19768 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
19778 if (Kind == ConstantExprKind::ClassTemplateArgument &&
19781 Result.HasSideEffects)) {
19793 bool IsConstantInitialization)
const {
19795 "Expression evaluator can't be called on a dependent expression.");
19796 assert(VD &&
"Need a valid VarDecl");
19798 llvm::TimeTraceScope TimeScope(
"EvaluateAsInitializer", [&] {
19800 llvm::raw_string_ostream OS(Name);
19806 EStatus.
Diag = &Notes;
19808 EvalInfo Info(Ctx, EStatus,
19809 (IsConstantInitialization &&
19813 Info.setEvaluatingDecl(VD,
Value);
19814 Info.InConstantContext = IsConstantInitialization;
19819 if (Info.EnableNewConstInterp) {
19820 auto &InterpCtx =
const_cast<ASTContext &
>(Ctx).getInterpContext();
19821 if (!InterpCtx.evaluateAsInitializer(Info, VD,
this,
Value))
19825 ConstantExprKind::Normal);
19840 FullExpressionRAII
Scope(Info);
19843 EStatus.HasSideEffects)
19849 Info.performLifetimeExtension();
19851 if (!Info.discardCleanups())
19852 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
19856 ConstantExprKind::Normal) &&
19863 EStatus.
Diag = &Notes;
19880 IsConstantDestruction) ||
19892 "Expression evaluator can't be called on a dependent expression.");
19901 "Expression evaluator can't be called on a dependent expression.");
19903 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstInt");
19906 Info.InConstantContext =
true;
19910 assert(
Result &&
"Could not evaluate expression");
19911 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
19913 return EVResult.Val.getInt();
19919 "Expression evaluator can't be called on a dependent expression.");
19921 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstIntCheckOverflow");
19923 EVResult.Diag =
Diag;
19925 Info.InConstantContext =
true;
19926 Info.CheckingForUndefinedBehavior =
true;
19930 assert(
Result &&
"Could not evaluate expression");
19931 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
19933 return EVResult.Val.getInt();
19938 "Expression evaluator can't be called on a dependent expression.");
19940 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateForOverflow");
19945 Info.CheckingForUndefinedBehavior =
true;
19951 assert(
Val.isLValue());
19977 IK_ICEIfUnevaluated,
19993static ICEDiag
Worst(ICEDiag A, ICEDiag B) {
return A.Kind >= B.Kind ? A : B; }
20000 Info.InConstantContext =
true;
20009 assert(!E->
isValueDependent() &&
"Should not see value dependent exprs!");
20014#define ABSTRACT_STMT(Node)
20015#define STMT(Node, Base) case Expr::Node##Class:
20016#define EXPR(Node, Base)
20017#include "clang/AST/StmtNodes.inc"
20018 case Expr::PredefinedExprClass:
20019 case Expr::FloatingLiteralClass:
20020 case Expr::ImaginaryLiteralClass:
20021 case Expr::StringLiteralClass:
20022 case Expr::ArraySubscriptExprClass:
20023 case Expr::MatrixSubscriptExprClass:
20024 case Expr::ArraySectionExprClass:
20025 case Expr::OMPArrayShapingExprClass:
20026 case Expr::OMPIteratorExprClass:
20027 case Expr::MemberExprClass:
20028 case Expr::CompoundAssignOperatorClass:
20029 case Expr::CompoundLiteralExprClass:
20030 case Expr::ExtVectorElementExprClass:
20031 case Expr::DesignatedInitExprClass:
20032 case Expr::ArrayInitLoopExprClass:
20033 case Expr::ArrayInitIndexExprClass:
20034 case Expr::NoInitExprClass:
20035 case Expr::DesignatedInitUpdateExprClass:
20036 case Expr::ImplicitValueInitExprClass:
20037 case Expr::ParenListExprClass:
20038 case Expr::VAArgExprClass:
20039 case Expr::AddrLabelExprClass:
20040 case Expr::StmtExprClass:
20041 case Expr::CXXMemberCallExprClass:
20042 case Expr::CUDAKernelCallExprClass:
20043 case Expr::CXXAddrspaceCastExprClass:
20044 case Expr::CXXDynamicCastExprClass:
20045 case Expr::CXXTypeidExprClass:
20046 case Expr::CXXUuidofExprClass:
20047 case Expr::MSPropertyRefExprClass:
20048 case Expr::MSPropertySubscriptExprClass:
20049 case Expr::CXXNullPtrLiteralExprClass:
20050 case Expr::UserDefinedLiteralClass:
20051 case Expr::CXXThisExprClass:
20052 case Expr::CXXThrowExprClass:
20053 case Expr::CXXNewExprClass:
20054 case Expr::CXXDeleteExprClass:
20055 case Expr::CXXPseudoDestructorExprClass:
20056 case Expr::UnresolvedLookupExprClass:
20057 case Expr::RecoveryExprClass:
20058 case Expr::DependentScopeDeclRefExprClass:
20059 case Expr::CXXConstructExprClass:
20060 case Expr::CXXInheritedCtorInitExprClass:
20061 case Expr::CXXStdInitializerListExprClass:
20062 case Expr::CXXBindTemporaryExprClass:
20063 case Expr::ExprWithCleanupsClass:
20064 case Expr::CXXTemporaryObjectExprClass:
20065 case Expr::CXXUnresolvedConstructExprClass:
20066 case Expr::CXXDependentScopeMemberExprClass:
20067 case Expr::UnresolvedMemberExprClass:
20068 case Expr::ObjCStringLiteralClass:
20069 case Expr::ObjCBoxedExprClass:
20070 case Expr::ObjCArrayLiteralClass:
20071 case Expr::ObjCDictionaryLiteralClass:
20072 case Expr::ObjCEncodeExprClass:
20073 case Expr::ObjCMessageExprClass:
20074 case Expr::ObjCSelectorExprClass:
20075 case Expr::ObjCProtocolExprClass:
20076 case Expr::ObjCIvarRefExprClass:
20077 case Expr::ObjCPropertyRefExprClass:
20078 case Expr::ObjCSubscriptRefExprClass:
20079 case Expr::ObjCIsaExprClass:
20080 case Expr::ObjCAvailabilityCheckExprClass:
20081 case Expr::ShuffleVectorExprClass:
20082 case Expr::ConvertVectorExprClass:
20083 case Expr::BlockExprClass:
20085 case Expr::OpaqueValueExprClass:
20086 case Expr::PackExpansionExprClass:
20087 case Expr::SubstNonTypeTemplateParmPackExprClass:
20088 case Expr::FunctionParmPackExprClass:
20089 case Expr::AsTypeExprClass:
20090 case Expr::ObjCIndirectCopyRestoreExprClass:
20091 case Expr::MaterializeTemporaryExprClass:
20092 case Expr::PseudoObjectExprClass:
20093 case Expr::AtomicExprClass:
20094 case Expr::LambdaExprClass:
20095 case Expr::CXXFoldExprClass:
20096 case Expr::CoawaitExprClass:
20097 case Expr::DependentCoawaitExprClass:
20098 case Expr::CoyieldExprClass:
20099 case Expr::SYCLUniqueStableNameExprClass:
20100 case Expr::CXXParenListInitExprClass:
20101 case Expr::HLSLOutArgExprClass:
20104 case Expr::InitListExprClass: {
20115 case Expr::SizeOfPackExprClass:
20116 case Expr::GNUNullExprClass:
20117 case Expr::SourceLocExprClass:
20118 case Expr::EmbedExprClass:
20119 case Expr::OpenACCAsteriskSizeExprClass:
20122 case Expr::PackIndexingExprClass:
20125 case Expr::SubstNonTypeTemplateParmExprClass:
20129 case Expr::ConstantExprClass:
20132 case Expr::ParenExprClass:
20134 case Expr::GenericSelectionExprClass:
20136 case Expr::IntegerLiteralClass:
20137 case Expr::FixedPointLiteralClass:
20138 case Expr::CharacterLiteralClass:
20139 case Expr::ObjCBoolLiteralExprClass:
20140 case Expr::CXXBoolLiteralExprClass:
20141 case Expr::CXXScalarValueInitExprClass:
20142 case Expr::TypeTraitExprClass:
20143 case Expr::ConceptSpecializationExprClass:
20144 case Expr::RequiresExprClass:
20145 case Expr::ArrayTypeTraitExprClass:
20146 case Expr::ExpressionTraitExprClass:
20147 case Expr::CXXNoexceptExprClass:
20149 case Expr::CallExprClass:
20150 case Expr::CXXOperatorCallExprClass: {
20159 case Expr::CXXRewrittenBinaryOperatorClass:
20162 case Expr::DeclRefExprClass: {
20176 const VarDecl *VD = dyn_cast<VarDecl>(D);
20183 case Expr::UnaryOperatorClass: {
20206 llvm_unreachable(
"invalid unary operator class");
20208 case Expr::OffsetOfExprClass: {
20217 case Expr::UnaryExprOrTypeTraitExprClass: {
20219 if ((Exp->
getKind() == UETT_SizeOf) &&
20222 if (Exp->
getKind() == UETT_CountOf) {
20229 if (VAT->getElementType()->isArrayType())
20241 case Expr::BinaryOperatorClass: {
20286 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE) {
20289 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
20290 if (REval.isSigned() && REval.isAllOnes()) {
20292 if (LEval.isMinSignedValue())
20293 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
20301 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE)
20302 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
20308 return Worst(LHSResult, RHSResult);
20314 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICEIfUnevaluated) {
20324 return Worst(LHSResult, RHSResult);
20327 llvm_unreachable(
"invalid binary operator kind");
20329 case Expr::ImplicitCastExprClass:
20330 case Expr::CStyleCastExprClass:
20331 case Expr::CXXFunctionalCastExprClass:
20332 case Expr::CXXStaticCastExprClass:
20333 case Expr::CXXReinterpretCastExprClass:
20334 case Expr::CXXConstCastExprClass:
20335 case Expr::ObjCBridgedCastExprClass: {
20342 APSInt IgnoredVal(DestWidth, !DestSigned);
20347 if (FL->getValue().convertToInteger(IgnoredVal,
20348 llvm::APFloat::rmTowardZero,
20349 &Ignored) & APFloat::opInvalidOp)
20355 case CK_LValueToRValue:
20356 case CK_AtomicToNonAtomic:
20357 case CK_NonAtomicToAtomic:
20359 case CK_IntegralToBoolean:
20360 case CK_IntegralCast:
20366 case Expr::BinaryConditionalOperatorClass: {
20369 if (CommonResult.Kind == IK_NotICE)
return CommonResult;
20371 if (FalseResult.Kind == IK_NotICE)
return FalseResult;
20372 if (CommonResult.Kind == IK_ICEIfUnevaluated)
return CommonResult;
20373 if (FalseResult.Kind == IK_ICEIfUnevaluated &&
20375 return FalseResult;
20377 case Expr::ConditionalOperatorClass: {
20385 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
20388 if (CondResult.Kind == IK_NotICE)
20394 if (TrueResult.Kind == IK_NotICE)
20396 if (FalseResult.Kind == IK_NotICE)
20397 return FalseResult;
20398 if (CondResult.Kind == IK_ICEIfUnevaluated)
20400 if (TrueResult.Kind == IK_ICE && FalseResult.Kind == IK_ICE)
20406 return FalseResult;
20409 case Expr::CXXDefaultArgExprClass:
20411 case Expr::CXXDefaultInitExprClass:
20413 case Expr::ChooseExprClass: {
20416 case Expr::BuiltinBitCastExprClass: {
20417 if (!checkBitCastConstexprEligibility(
nullptr, Ctx,
cast<CastExpr>(E)))
20423 llvm_unreachable(
"Invalid StmtClass!");
20429 llvm::APSInt *
Value) {
20437 if (!Result.isInt())
20446 "Expression evaluator can't be called on a dependent expression.");
20448 ExprTimeTraceScope TimeScope(
this, Ctx,
"isIntegerConstantExpr");
20454 if (D.Kind != IK_ICE)
20459std::optional<llvm::APSInt>
20463 return std::nullopt;
20470 return std::nullopt;
20474 return std::nullopt;
20483 Info.InConstantContext =
true;
20486 llvm_unreachable(
"ICE cannot be evaluated!");
20493 "Expression evaluator can't be called on a dependent expression.");
20495 return CheckICE(
this, Ctx).Kind == IK_ICE;
20500 "Expression evaluator can't be called on a dependent expression.");
20517 Status.Diag = &Diags;
20524 Info.discardCleanups() && !Status.HasSideEffects;
20526 return IsConstExpr && Diags.empty();
20534 "Expression evaluator can't be called on a dependent expression.");
20536 llvm::TimeTraceScope TimeScope(
"EvaluateWithSubstitution", [&] {
20538 llvm::raw_string_ostream OS(Name);
20546 Info.InConstantContext =
true;
20549 const LValue *ThisPtr =
nullptr;
20552 auto *MD = dyn_cast<CXXMethodDecl>(Callee);
20553 assert(MD &&
"Don't provide `this` for non-methods.");
20554 assert(MD->isImplicitObjectMemberFunction() &&
20555 "Don't provide `this` for methods without an implicit object.");
20557 if (!
This->isValueDependent() &&
20560 ThisPtr = &ThisVal;
20567 CallRef
Call = Info.CurrentCall->createCall(Callee);
20570 unsigned Idx = I - Args.begin();
20571 if (Idx >= Callee->getNumParams())
20573 const ParmVarDecl *PVD = Callee->getParamDecl(Idx);
20574 if ((*I)->isValueDependent() ||
20578 if (
APValue *Slot = Info.getParamSlot(
Call, PVD))
20589 Info.discardCleanups();
20593 CallStackFrame Frame(Info, Callee->getLocation(), Callee, ThisPtr,
This,
20596 FullExpressionRAII
Scope(Info);
20610 llvm::TimeTraceScope TimeScope(
"isPotentialConstantExpr", [&] {
20612 llvm::raw_string_ostream OS(Name);
20619 Status.
Diag = &Diags;
20623 Info.InConstantContext =
true;
20624 Info.CheckingPotentialConstantExpression =
true;
20627 if (Info.EnableNewConstInterp) {
20629 return Diags.empty();
20640 This.set({&VIE, Info.CurrentCall->Index});
20648 Info.setEvaluatingDecl(
This.getLValueBase(), Scratch);
20654 &VIE, Args, CallRef(), FD->
getBody(), Info, Scratch,
20658 return Diags.empty();
20666 "Expression evaluator can't be called on a dependent expression.");
20669 Status.
Diag = &Diags;
20673 Info.InConstantContext =
true;
20674 Info.CheckingPotentialConstantExpression =
true;
20676 if (Info.EnableNewConstInterp) {
20678 return Diags.empty();
20683 nullptr, CallRef());
20687 return Diags.empty();
20691 unsigned Type)
const {
20692 if (!
getType()->isPointerType())
20701 EvalInfo &Info, std::string *StringResult) {
20713 if (
const StringLiteral *S = dyn_cast_or_null<StringLiteral>(
20714 String.getLValueBase().dyn_cast<
const Expr *>())) {
20717 if (Off >= 0 && (uint64_t)Off <= (uint64_t)Str.size() &&
20721 Str = Str.substr(Off);
20723 StringRef::size_type Pos = Str.find(0);
20724 if (Pos != StringRef::npos)
20725 Str = Str.substr(0, Pos);
20727 Result = Str.size();
20729 *StringResult = Str;
20737 for (uint64_t Strlen = 0; ; ++Strlen) {
20745 }
else if (StringResult)
20746 StringResult->push_back(Char.
getInt().getExtValue());
20756 std::string StringResult;
20758 if (Info.EnableNewConstInterp) {
20760 return std::nullopt;
20761 return StringResult;
20765 return StringResult;
20766 return std::nullopt;
20769template <
typename T>
20771 const Expr *SizeExpression,
20772 const Expr *PtrExpression,
20776 Info.InConstantContext =
true;
20778 if (Info.EnableNewConstInterp)
20780 PtrExpression, Result);
20783 FullExpressionRAII
Scope(Info);
20788 uint64_t Size = SizeValue.getZExtValue();
20791 if constexpr (std::is_same_v<APValue, T>)
20794 if (Size < Result.max_size())
20795 Result.reserve(Size);
20801 for (uint64_t I = 0; I < Size; ++I) {
20807 if constexpr (std::is_same_v<APValue, T>) {
20808 Result.getArrayInitializedElt(I) = std::move(Char);
20812 assert(
C.getBitWidth() <= 8 &&
20813 "string element not representable in char");
20815 Result.push_back(
static_cast<char>(
C.getExtValue()));
20826 const Expr *SizeExpression,
20830 PtrExpression, Ctx, Status);
20834 const Expr *SizeExpression,
20838 PtrExpression, Ctx, Status);
20845 if (Info.EnableNewConstInterp)
20852struct IsWithinLifetimeHandler {
20855 using result_type = std::optional<bool>;
20856 std::optional<bool> failed() {
return std::nullopt; }
20857 template <
typename T>
20858 std::optional<bool> found(
T &Subobj,
QualType SubobjType) {
20863std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &IEE,
20864 const CallExpr *E) {
20865 EvalInfo &Info = IEE.Info;
20870 if (!Info.InConstantContext)
20871 return std::nullopt;
20873 const Expr *Arg = E->
getArg(0);
20875 return std::nullopt;
20878 return std::nullopt;
20880 if (Val.allowConstexprUnknown())
20884 bool CalledFromStd =
false;
20885 const auto *
Callee = Info.CurrentCall->getCallee();
20886 if (Callee &&
Callee->isInStdNamespace()) {
20887 const IdentifierInfo *Identifier =
Callee->getIdentifier();
20888 CalledFromStd = Identifier && Identifier->
isStr(
"is_within_lifetime");
20890 Info.CCEDiag(CalledFromStd ? Info.CurrentCall->getCallRange().getBegin()
20892 diag::err_invalid_is_within_lifetime)
20893 << (CalledFromStd ?
"std::is_within_lifetime"
20894 :
"__builtin_is_within_lifetime")
20896 return std::nullopt;
20906 if (Val.isNullPointer() || Val.getLValueBase().isNull())
20908 QualType
T = Val.getLValueBase().getType();
20910 "Pointers to functions should have been typed as function pointers "
20911 "which would have been rejected earlier");
20914 if (Val.getLValueDesignator().isOnePastTheEnd())
20916 assert(Val.getLValueDesignator().isValidSubobject() &&
20917 "Unchecked case for valid subobject");
20921 CompleteObject CO =
20925 if (Info.EvaluatingDeclValue && CO.Value == Info.EvaluatingDeclValue)
20930 IsWithinLifetimeHandler handler{Info};
20931 return findSubobject(Info, E, CO, Val.getLValueDesignator(), handler);
Defines the clang::ASTContext interface.
This file provides some common utility functions for processing Lambda related AST Constructs.
Defines enum values for all the target-independent builtin functions.
static Address castToBase(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy, Address OriginalBaseAddress, llvm::Value *Addr)
static uint32_t getBitWidth(const Expr *E)
static Decl::Kind getKind(const Decl *D)
GCCTypeClass
Values returned by __builtin_classify_type, chosen to match the values produced by GCC's builtin.
@ PointerToMemberFunction
static bool isRead(AccessKinds AK)
static bool EvaluateCharRangeAsStringImpl(const Expr *, T &Result, const Expr *SizeExpression, const Expr *PtrExpression, ASTContext &Ctx, Expr::EvalResult &Status)
static bool EvaluateBuiltinStrLen(const Expr *E, uint64_t &Result, EvalInfo &Info, std::string *StringResult=nullptr)
static bool isValidIndeterminateAccess(AccessKinds AK)
Is this kind of access valid on an indeterminate object value?
static unsigned elementwiseSize(EvalInfo &Info, QualType BaseTy)
static bool EvaluateMemberPointer(const Expr *E, MemberPtr &Result, EvalInfo &Info)
static bool hasUnacceptableSideEffect(Expr::EvalStatus &Result, Expr::SideEffectsKind SEK)
static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E, AccessKinds AK, const LValue &LVal, QualType LValType)
Find the complete object to which an LValue refers.
static bool evaluateLValueAsAllocSize(EvalInfo &Info, APValue::LValueBase Base, LValue &Result)
Attempts to evaluate the given LValueBase as the result of a call to a function with the alloc_size a...
static const CXXMethodDecl * HandleVirtualDispatch(EvalInfo &Info, const Expr *E, LValue &This, const CXXMethodDecl *Found, llvm::SmallVectorImpl< QualType > &CovariantAdjustmentPath)
Perform virtual dispatch.
static bool EvaluateVarDecl(EvalInfo &Info, const VarDecl *VD)
static bool CheckEvaluationResult(CheckEvaluationResultKind CERK, EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value, ConstantExprKind Kind, const FieldDecl *SubobjectDecl, CheckedTemporaries &CheckedTemps)
static bool HandleLValueComplexElement(EvalInfo &Info, const Expr *E, LValue &LVal, QualType EltTy, bool Imag)
Update an lvalue to refer to a component of a complex number.
static bool evalPackBuiltin(const CallExpr *E, EvalInfo &Info, APValue &Result, llvm::function_ref< APInt(const APSInt &)> PackFn)
static bool HandleSizeof(EvalInfo &Info, SourceLocation Loc, QualType Type, CharUnits &Size, SizeOfType SOT=SizeOfType::SizeOf)
Get the size of the given type in char units.
static bool HandleConstructorCall(const Expr *E, const LValue &This, CallRef Call, const CXXConstructorDecl *Definition, EvalInfo &Info, APValue &Result)
Evaluate a constructor call.
static bool hlslElementwiseCastHelper(EvalInfo &Info, const Expr *E, QualType DestTy, SmallVectorImpl< APValue > &SrcVals, SmallVectorImpl< QualType > &SrcTypes)
static bool ShouldPropagateBreakContinue(EvalInfo &Info, const Stmt *LoopOrSwitch, ArrayRef< BlockScopeRAII * > Scopes, EvalStmtResult &ESR)
Helper to implement named break/continue.
static EvalStmtResult EvaluateLoopBody(StmtResult &Result, EvalInfo &Info, const Stmt *Body, const SwitchCase *Case=nullptr)
Evaluate the body of a loop, and translate the result as appropriate.
static bool EvaluatePointer(const Expr *E, LValue &Result, EvalInfo &Info, bool InvalidBaseOK=false)
static bool CheckTrivialDefaultConstructor(EvalInfo &Info, SourceLocation Loc, const CXXConstructorDecl *CD, bool IsValueInitialization)
CheckTrivialDefaultConstructor - Check whether a constructor is a trivial default constructor.
static bool EvaluateVector(const Expr *E, APValue &Result, EvalInfo &Info)
static const ValueDecl * GetLValueBaseDecl(const LValue &LVal)
static bool TryEvaluateBuiltinNaN(const ASTContext &Context, QualType ResultTy, const Expr *Arg, bool SNaN, llvm::APFloat &Result)
static const Expr * ignorePointerCastsAndParens(const Expr *E)
A more selective version of E->IgnoreParenCasts for tryEvaluateBuiltinObjectSize. This ignores some c...
static bool isAnyAccess(AccessKinds AK)
static bool EvaluateComparisonBinaryOperator(EvalInfo &Info, const BinaryOperator *E, SuccessCB &&Success, AfterCB &&DoAfter)
static bool HandleClassZeroInitialization(EvalInfo &Info, const Expr *E, const RecordDecl *RD, const LValue &This, APValue &Result)
Perform zero-initialization on an object of non-union class type. C++11 [dcl.init]p5: To zero-initial...
static bool EvaluateComplex(const Expr *E, ComplexValue &Res, EvalInfo &Info)
static bool CheckMemoryLeaks(EvalInfo &Info)
Enforce C++2a [expr.const]/4.17, which disallows new-expressions unless "the allocated storage is dea...
static bool handleScalarCast(EvalInfo &Info, const FPOptions FPO, const Expr *E, QualType SourceTy, QualType DestTy, APValue const &Original, APValue &Result)
static ICEDiag CheckEvalInICE(const Expr *E, const ASTContext &Ctx)
static llvm::APInt ConvertBoolVectorToInt(const APValue &Val)
static bool flattenAPValue(EvalInfo &Info, const Expr *E, APValue Value, QualType BaseTy, SmallVectorImpl< APValue > &Elements, SmallVectorImpl< QualType > &Types, unsigned Size)
static bool hlslAggSplatHelper(EvalInfo &Info, const Expr *E, APValue &SrcVal, QualType &SrcTy)
static bool isBaseClassPublic(const CXXRecordDecl *Derived, const CXXRecordDecl *Base)
Determine whether Base, which is known to be a direct base class of Derived, is a public base class.
static bool hasVirtualDestructor(QualType T)
static bool HandleOverflow(EvalInfo &Info, const Expr *E, const T &SrcValue, QualType DestType)
static CharUnits getBaseAlignment(EvalInfo &Info, const LValue &Value)
static bool HandleLValueIndirectMember(EvalInfo &Info, const Expr *E, LValue &LVal, const IndirectFieldDecl *IFD)
Update LVal to refer to the given indirect field.
static ICEDiag Worst(ICEDiag A, ICEDiag B)
static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E, const VarDecl *VD, CallStackFrame *Frame, unsigned Version, APValue *&Result)
Try to evaluate the initializer for a variable declaration.
static bool handleDefaultInitValue(QualType T, APValue &Result)
Get the value to use for a default-initialized object of type T.
static bool HandleLValueVectorElement(EvalInfo &Info, const Expr *E, LValue &LVal, QualType EltTy, uint64_t Size, uint64_t Idx)
static void NoteLValueLocation(EvalInfo &Info, APValue::LValueBase Base)
static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc, QualType Type, const LValue &LVal, ConstantExprKind Kind, CheckedTemporaries &CheckedTemps)
Check that this reference or pointer core constant expression is a valid value for an address or refe...
static bool CheckedIntArithmetic(EvalInfo &Info, const Expr *E, const APSInt &LHS, const APSInt &RHS, unsigned BitWidth, Operation Op, APSInt &Result)
Perform the given integer operation, which is known to need at most BitWidth bits,...
static bool EvaluateTemporary(const Expr *E, LValue &Result, EvalInfo &Info)
Evaluate an expression of record type as a temporary.
static bool EvaluateArray(const Expr *E, const LValue &This, APValue &Result, EvalInfo &Info)
static bool truncateBitfieldValue(EvalInfo &Info, const Expr *E, APValue &Value, const FieldDecl *FD)
static bool handleVectorShuffle(EvalInfo &Info, const ShuffleVectorExpr *E, QualType ElemType, APValue const &VecVal1, APValue const &VecVal2, unsigned EltNum, APValue &Result)
static bool handleVectorElementCast(EvalInfo &Info, const FPOptions FPO, const Expr *E, QualType SourceTy, QualType DestTy, APValue const &Original, APValue &Result)
static const ValueDecl * HandleMemberPointerAccess(EvalInfo &Info, QualType LVType, LValue &LV, const Expr *RHS, bool IncludeMember=true)
HandleMemberPointerAccess - Evaluate a member access operation and build an lvalue referring to the r...
static bool HandleBaseToDerivedCast(EvalInfo &Info, const CastExpr *E, LValue &Result)
HandleBaseToDerivedCast - Apply the given base-to-derived cast operation on the provided lvalue,...
static bool EvaluateFloat(const Expr *E, APFloat &Result, EvalInfo &Info)
static bool IsOpaqueConstantCall(const CallExpr *E)
Should this call expression be treated as forming an opaque constant?
static bool CheckMemberPointerConstantExpression(EvalInfo &Info, SourceLocation Loc, QualType Type, const APValue &Value, ConstantExprKind Kind)
Member pointers are constant expressions unless they point to a non-virtual dllimport member function...
static bool EvaluateAsInt(const Expr *E, Expr::EvalResult &ExprResult, const ASTContext &Ctx, Expr::SideEffectsKind AllowSideEffects, EvalInfo &Info)
static bool handleLValueToRValueConversion(EvalInfo &Info, const Expr *Conv, QualType Type, const LValue &LVal, APValue &RVal, bool WantObjectRepresentation=false)
Perform an lvalue-to-rvalue conversion on the given glvalue.
static bool handleElementwiseCast(EvalInfo &Info, const Expr *E, const FPOptions FPO, SmallVectorImpl< APValue > &Elements, SmallVectorImpl< QualType > &SrcTypes, SmallVectorImpl< QualType > &DestTypes, SmallVectorImpl< APValue > &Results)
static bool refersToCompleteObject(const LValue &LVal)
Tests to see if the LValue has a user-specified designator (that isn't necessarily valid)....
static bool AreElementsOfSameArray(QualType ObjType, const SubobjectDesignator &A, const SubobjectDesignator &B)
Determine whether the given subobject designators refer to elements of the same array object.
static bool EvaluateDecompositionDeclInit(EvalInfo &Info, const DecompositionDecl *DD)
static bool IsWeakLValue(const LValue &Value)
static bool EvaluateArrayNewConstructExpr(EvalInfo &Info, LValue &This, APValue &Result, const CXXConstructExpr *CCE, QualType AllocType)
static bool EvaluateRecord(const Expr *E, const LValue &This, APValue &Result, EvalInfo &Info)
static bool handleAssignment(EvalInfo &Info, const Expr *E, const LValue &LVal, QualType LValType, APValue &Val)
Perform an assignment of Val to LVal. Takes ownership of Val.
static bool CastToDerivedClass(EvalInfo &Info, const Expr *E, LValue &Result, const RecordDecl *TruncatedType, unsigned TruncatedElements)
Cast an lvalue referring to a base subobject to a derived class, by truncating the lvalue's path to t...
static bool EvaluateIgnoredValue(EvalInfo &Info, const Expr *E)
Evaluate an expression to see if it had side-effects, and discard its result.
static bool constructAggregate(EvalInfo &Info, const FPOptions FPO, const Expr *E, APValue &Result, QualType ResultType, SmallVectorImpl< APValue > &Elements, SmallVectorImpl< QualType > &ElTypes)
static void addFlexibleArrayMemberInitSize(EvalInfo &Info, const QualType &T, const LValue &LV, CharUnits &Size)
If we're evaluating the object size of an instance of a struct that contains a flexible array member,...
static bool HandleLValueBasePath(EvalInfo &Info, const CastExpr *E, QualType Type, LValue &Result)
static bool evalShuffleGeneric(EvalInfo &Info, const CallExpr *Call, APValue &Out, llvm::function_ref< std::pair< unsigned, int >(unsigned, unsigned)> GetSourceIndex)
static QualType getSubobjectType(QualType ObjType, QualType SubobjType, bool IsMutable=false)
static bool EvaluateFixedPointOrInteger(const Expr *E, APFixedPoint &Result, EvalInfo &Info)
Evaluate an integer or fixed point expression into an APResult.
static bool HandleIntToFloatCast(EvalInfo &Info, const Expr *E, const FPOptions FPO, QualType SrcType, const APSInt &Value, QualType DestType, APFloat &Result)
static const CXXRecordDecl * getBaseClassType(SubobjectDesignator &Designator, unsigned PathLength)
static bool CastToBaseClass(EvalInfo &Info, const Expr *E, LValue &Result, const CXXRecordDecl *DerivedRD, const CXXRecordDecl *BaseRD)
Cast an lvalue referring to a derived class to a known base subobject.
static bool HandleLValueBase(EvalInfo &Info, const Expr *E, LValue &Obj, const CXXRecordDecl *DerivedDecl, const CXXBaseSpecifier *Base)
static bool HandleConversionToBool(const APValue &Val, bool &Result)
CharUnits GetAlignOfExpr(const ASTContext &Ctx, const Expr *E, UnaryExprOrTypeTrait ExprKind)
static bool isModification(AccessKinds AK)
static bool handleCompareOpForVector(const APValue &LHSValue, BinaryOperatorKind Opcode, const APValue &RHSValue, APInt &Result)
static bool MaybeElementDependentArrayFiller(const Expr *FillerExpr)
static bool EvaluateObjectArgument(EvalInfo &Info, const Expr *Object, LValue &This)
Build an lvalue for the object argument of a member function call.
static bool CheckLiteralType(EvalInfo &Info, const Expr *E, const LValue *This=nullptr)
Check that this core constant expression is of literal type, and if not, produce an appropriate diagn...
static bool EvaluateInteger(const Expr *E, APSInt &Result, EvalInfo &Info)
CheckEvaluationResultKind
static bool isZeroSized(const LValue &Value)
static APSInt extractStringLiteralCharacter(EvalInfo &Info, const Expr *Lit, uint64_t Index)
Extract the value of a character from a string literal.
static bool modifySubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, const SubobjectDesignator &Sub, APValue &NewVal)
Update the designated sub-object of an rvalue to the given value.
static bool EvaluateCPlusPlus11IntegralConstantExpr(const ASTContext &Ctx, const Expr *E, llvm::APSInt *Value)
Evaluate an expression as a C++11 integral constant expression.
static CharUnits GetAlignOfType(const ASTContext &Ctx, QualType T, UnaryExprOrTypeTrait ExprKind)
static bool getBuiltinAlignArguments(const CallExpr *E, EvalInfo &Info, APValue &Val, APSInt &Alignment)
static bool HandleLValueArrayAdjustment(EvalInfo &Info, const Expr *E, LValue &LVal, QualType EltTy, APSInt Adjustment)
Update a pointer value to model pointer arithmetic.
static bool extractSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, const SubobjectDesignator &Sub, APValue &Result, AccessKinds AK=AK_Read)
Extract the designated sub-object of an rvalue.
static bool HandleLValueMember(EvalInfo &Info, const Expr *E, LValue &LVal, const FieldDecl *FD, const ASTRecordLayout *RL=nullptr)
Update LVal to refer to the given field, which must be a member of the type currently described by LV...
static void addOrSubLValueAsInteger(APValue &LVal, const APSInt &Index, bool IsSub)
static bool IsDeclSourceLocationCurrent(const FunctionDecl *FD)
void HandleComplexComplexDiv(APFloat A, APFloat B, APFloat C, APFloat D, APFloat &ResR, APFloat &ResI)
static bool handleTrivialCopy(EvalInfo &Info, const ParmVarDecl *Param, const Expr *E, APValue &Result, bool CopyObjectRepresentation)
Perform a trivial copy from Param, which is the parameter of a copy or move constructor or assignment...
static bool checkFloatingPointResult(EvalInfo &Info, const Expr *E, APFloat::opStatus St)
Check if the given evaluation result is allowed for constant evaluation.
static bool EvaluateBuiltinConstantPForLValue(const APValue &LV)
EvaluateBuiltinConstantPForLValue - Determine the result of __builtin_constant_p when applied to the ...
static bool EvaluateBuiltinConstantP(EvalInfo &Info, const Expr *Arg)
EvaluateBuiltinConstantP - Evaluate __builtin_constant_p as similarly to GCC as we can manage.
static bool checkNonVirtualMemberCallThisPointer(EvalInfo &Info, const Expr *E, const LValue &This, const CXXMethodDecl *NamedMember)
Check that the pointee of the 'this' pointer in a member function call is either within its lifetime ...
static bool CheckConstantExpression(EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value, ConstantExprKind Kind)
Check that this core constant expression value is a valid value for a constant expression.
static bool EvaluateAsBooleanCondition(const Expr *E, bool &Result, EvalInfo &Info)
static std::optional< DynamicType > ComputeDynamicType(EvalInfo &Info, const Expr *E, LValue &This, AccessKinds AK)
Determine the dynamic type of an object.
static bool EvaluateDecl(EvalInfo &Info, const Decl *D, bool EvaluateConditionDecl=false)
static void expandArray(APValue &Array, unsigned Index)
static bool handleLogicalOpForVector(const APInt &LHSValue, BinaryOperatorKind Opcode, const APInt &RHSValue, APInt &Result)
static unsigned FindDesignatorMismatch(QualType ObjType, const SubobjectDesignator &A, const SubobjectDesignator &B, bool &WasArrayIndex)
Find the position where two subobject designators diverge, or equivalently the length of the common i...
static bool isOnePastTheEndOfCompleteObject(const ASTContext &Ctx, const LValue &LV)
Determine whether this is a pointer past the end of the complete object referred to by the lvalue.
static unsigned getBaseIndex(const CXXRecordDecl *Derived, const CXXRecordDecl *Base)
Get the base index of the given base class within an APValue representing the given derived class.
static bool EvaluateFixedPoint(const Expr *E, APFixedPoint &Result, EvalInfo &Info)
Evaluate only a fixed point expression into an APResult.
void HandleComplexComplexMul(APFloat A, APFloat B, APFloat C, APFloat D, APFloat &ResR, APFloat &ResI)
static bool tryEvaluateBuiltinObjectSize(const Expr *E, unsigned Type, EvalInfo &Info, uint64_t &Size)
Tries to evaluate the __builtin_object_size for E. If successful, returns true and stores the result ...
static bool EvalPointerValueAsBool(const APValue &Value, bool &Result)
static bool handleVectorVectorBinOp(EvalInfo &Info, const BinaryOperator *E, BinaryOperatorKind Opcode, APValue &LHSValue, const APValue &RHSValue)
static const FunctionDecl * getVirtualOperatorDelete(QualType T)
static bool isDesignatorAtObjectEnd(const ASTContext &Ctx, const LValue &LVal)
Checks to see if the given LValue's Designator is at the end of the LValue's record layout....
static bool CheckArraySize(EvalInfo &Info, const ConstantArrayType *CAT, SourceLocation CallLoc={})
static bool EvaluateInPlace(APValue &Result, EvalInfo &Info, const LValue &This, const Expr *E, bool AllowNonLiteralTypes=false)
EvaluateInPlace - Evaluate an expression in-place in an APValue. In some cases, the in-place evaluati...
static bool handleFloatFloatBinOp(EvalInfo &Info, const BinaryOperator *E, APFloat &LHS, BinaryOperatorKind Opcode, const APFloat &RHS)
Perform the given binary floating-point operation, in-place, on LHS.
static std::optional< DynAlloc * > CheckDeleteKind(EvalInfo &Info, const Expr *E, const LValue &Pointer, DynAlloc::Kind DeallocKind)
Check that the given object is a suitable pointer to a heap allocation that still exists and is of th...
static bool EvaluateLValue(const Expr *E, LValue &Result, EvalInfo &Info, bool InvalidBaseOK=false)
Evaluate an expression as an lvalue. This can be legitimately called on expressions which are not glv...
static bool FastEvaluateAsRValue(const Expr *Exp, APValue &Result, const ASTContext &Ctx, bool &IsConst)
static bool HandleCovariantReturnAdjustment(EvalInfo &Info, const Expr *E, APValue &Result, ArrayRef< QualType > Path)
Perform the adjustment from a value returned by a virtual function to a value of the statically expec...
static 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...
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)
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
llvm::MachO::Record Record
Implements a partial diagnostic which may not be emitted.
llvm::DenseMap< Stmt *, Stmt * > MapTy
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
Expr * getExpr()
Get 'expr' part of the associated expression/statement.
static QualType getPointeeType(const MemRegion *R)
Enumerates target-specific builtins in their own namespaces within namespace clang.
Defines the clang::TypeLoc interface and its subclasses.
C Language Family Type Representation.
__DEVICE__ long long abs(long long __n)
a trap message and trap category.
llvm::APInt getValue() const
unsigned getVersion() const
QualType getDynamicAllocType() const
QualType getTypeInfoType() const
static LValueBase getTypeInfo(TypeInfoLValue LV, QualType TypeInfo)
static LValueBase getDynamicAlloc(DynamicAllocLValue LV, QualType Type)
A non-discriminated union of a base, field, or array index.
BaseOrMemberType getAsBaseOrMember() const
static LValuePathEntry ArrayIndex(uint64_t Index)
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
bool hasArrayFiller() const
const LValueBase getLValueBase() const
APValue & getArrayInitializedElt(unsigned I)
void swap(APValue &RHS)
Swaps the contents of this and the given APValue.
APValue & getStructField(unsigned i)
const FieldDecl * getUnionField() const
APSInt & getComplexIntImag()
bool isComplexInt() const
llvm::PointerIntPair< const Decl *, 1, bool > BaseOrMemberType
A FieldDecl or CXXRecordDecl, along with a flag indicating whether we mean a virtual or non-virtual b...
ValueKind getKind() const
unsigned getArrayInitializedElts() const
static APValue IndeterminateValue()
APFixedPoint & getFixedPoint()
bool hasLValuePath() const
const ValueDecl * getMemberPointerDecl() const
APValue & getUnionValue()
CharUnits & getLValueOffset()
void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const
bool isComplexFloat() const
APValue & getVectorElt(unsigned I)
APValue & getArrayFiller()
unsigned getVectorLength() const
void setUnion(const FieldDecl *Field, const APValue &Value)
bool isIndeterminate() const
unsigned getArraySize() const
bool allowConstexprUnknown() const
std::string getAsString(const ASTContext &Ctx, QualType Ty) const
bool isFixedPoint() const
@ Indeterminate
This object has an indeterminate value (C++ [basic.indet]).
@ None
There is no such object (it's outside its lifetime).
APSInt & getComplexIntReal()
APFloat & getComplexFloatImag()
APFloat & getComplexFloatReal()
APValue & getStructBase(unsigned i)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
SourceManager & getSourceManager()
const ConstantArrayType * getAsConstantArrayType(QualType T) const
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
unsigned getIntWidth(QualType T) const
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
static CanQualType getCanonicalType(QualType T)
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
void getObjCEncodingForType(QualType T, std::string &S, const FieldDecl *Field=nullptr, QualType *NotEncodedT=nullptr) const
Emit the Objective-CC type encoding for the given type T into S.
uint64_t getTargetNullPointerValue(QualType QT) const
Get target-dependent integer value for null pointer which is used for constant folding.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
unsigned getPreferredTypeAlign(QualType T) const
Return the "preferred" alignment of the specified type T for the current target, in bits.
bool hasSameFunctionTypeIgnoringExceptionSpec(QualType T, QualType U) const
Determine whether two function types are the same, ignoring exception specifications in cases where t...
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
Builtin::Context & BuiltinInfo
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, const Expr *SizeExpr, ArraySizeModifier ASM, unsigned IndexTypeQuals) const
Return the unique reference to the type for a constant array of the specified element type.
const LangOptions & getLangOpts() const
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
ComparisonCategories CompCategories
Types and expressions required to build C++2a three-way comparisons using operator<=>,...
QualType getIntTypeForBitwidth(unsigned DestWidth, unsigned Signed) const
getIntTypeForBitwidth - sets integer QualTy according to specified details: bitwidth,...
unsigned getOpenMPDefaultSimdAlign(QualType T) const
Get default simd alignment of the specified complete type in bits.
TypeInfoChars getTypeInfoDataSizeInChars(QualType T) const
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
const clang::PrintingPolicy & getPrintingPolicy() const
llvm::FixedPointSemantics getFixedPointSemantics(QualType Ty) const
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
static bool hasSameType(QualType T1, QualType T2)
Determine whether the given types T1 and T2 are equivalent.
llvm::APSInt MakeIntValue(uint64_t Value, QualType Type) const
Make an APSInt of the appropriate width and signedness for the given Value and integer Type.
const VariableArrayType * getAsVariableArrayType(QualType T) const
bool hasSimilarType(QualType T1, QualType T2) const
Determine if two types are similar, according to the C++ rules.
DiagnosticsEngine & getDiagnostics() const
interp::Context & getInterpContext()
Returns the clang bytecode interpreter context.
QualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
const TargetInfo & getTargetInfo() const
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
CanQualType getCanonicalTagType(const TagDecl *TD) const
static bool hasSameUnqualifiedType(QualType T1, QualType T2)
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
uint16_t getPointerAuthTypeDiscriminator(QualType T)
Return the "other" type-specific discriminator for the given type.
uint64_t getCharWidth() const
Return the size of the character type, in bits.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
unsigned getFieldCount() const
getFieldCount - Get the number of fields in the layout.
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - Get the offset, in chars, for the given base class.
LabelDecl * getLabel() const
OpaqueValueExpr * getCommonExpr() const
Get the common subexpression shared by all initializations (the source array).
Expr * getSubExpr() const
Get the initializer to use for each array element.
Expr * getLHS()
An array access can be written A[4] or 4[A] (both are equivalent).
uint64_t getValue() const
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
QualType getValueType() const
Gets the type contained by this atomic type, i.e.
Attr - This represents one attribute.
BinaryConditionalOperator - The GNU extension to the conditional operator which allows the middle ope...
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression which will be evaluated if the condition evaluates to false; ...
OpaqueValueExpr * getOpaqueValue() const
getOpaqueValue - Return the opaque value placeholder.
Expr * getCommon() const
getCommon - Return the common expression, written to the left of the condition.
A builtin binary operation expression such as "x + y" or "x <= y".
static bool isLogicalOp(Opcode Opc)
static bool isRelationalOp(Opcode Opc)
static bool isComparisonOp(Opcode Opc)
static Opcode getOpForCompoundAssignment(Opcode Opc)
SourceLocation getExprLoc() const
static bool isAdditiveOp(Opcode Opc)
static bool isPtrMemOp(Opcode Opc)
predicates to categorize the respective opcodes.
static bool isAssignmentOp(Opcode Opc)
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
static bool isEqualityOp(Opcode Opc)
bool hasCaptures() const
True if this block (or its nested blocks) captures anything of local storage from its enclosing scope...
const BlockDecl * getBlockDecl() const
std::string getQuotedName(unsigned ID) const
Return the identifier name for the specified builtin inside single quotes for a diagnostic,...
bool isConstantEvaluated(unsigned ID) const
Return true if this function can be constant evaluated by Clang frontend.
AccessSpecifier Access
The access along this inheritance path.
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
bool isAmbiguous(CanQualType BaseType)
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.
Expr ** getArgs()
Retrieve the call arguments.
QualType getCallReturnType(const ASTContext &Ctx) const
getCallReturnType - Get the return type of the call expr.
QualType withConst() const
Retrieves a version of this type with const applied.
const T * getTypePtr() const
Retrieve the underlying type pointer, which refers to a canonical type.
CaseStmt - Represent a case statement.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
path_iterator path_begin()
unsigned path_size() const
CastKind getCastKind() const
const CXXBaseSpecifier *const * path_const_iterator
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operation.
CharUnits - This is an opaque type for sizes expressed in character units.
bool isPowerOfTwo() const
isPowerOfTwo - Test whether the quantity is a power of two.
CharUnits alignmentAtOffset(CharUnits offset) const
Given that this is a non-zero alignment value, what is the alignment at the given offset?
bool isZero() const
isZero - Test whether the quantity equals zero.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
unsigned getValue() const
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
const ComparisonCategoryInfo & getInfoForType(QualType Ty) const
Return the comparison category information as specified by getCategoryForType(Ty).
const ValueInfo * getValueInfo(ComparisonCategoryResult ValueKind) const
ComparisonCategoryResult makeWeakResult(ComparisonCategoryResult Res) const
Converts the specified result kind into the correct result kind for this category.
Complex values, per C99 6.2.5p11.
QualType getElementType() const
CompoundAssignOperator - For compound assignments (e.g.
QualType getComputationLHSType() const
CompoundLiteralExpr - [C99 6.5.2.5].
bool hasStaticStorage() const
APValue & getOrCreateStaticValue(ASTContext &Ctx) const
const Expr * getInitializer() const
CompoundStmt - This represents a group of statements like { stmt stmt }.
Stmt *const * const_body_iterator
body_iterator body_begin()
bool isSatisfied() const
Whether or not the concept with the given arguments was satisfied when the expression was created.
ConditionalOperator - The ?
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
Expr * getCond() const
getCond - Return the expression representing the condition for the ?
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
Represents the canonical version of C arrays with a specified constant size.
unsigned getSizeBitWidth() const
Return the bit width of the size type.
static unsigned getNumAddressingBits(const ASTContext &Context, QualType ElementType, const llvm::APInt &NumElements)
Determine the number of bits required to address a member of.
static unsigned getMaxSizeBits(const ASTContext &Context)
Determine the maximum number of active bits that an array's size can require, which limits the maximu...
uint64_t getLimitedSize() const
Return the size zero-extended to uint64_t or UINT64_MAX if the value is larger than UINT64_MAX.
bool isZeroSize() const
Return true if the size is zero.
const Expr * getSizeExpr() const
Return a pointer to the size expression.
llvm::APInt getSize() const
Return the constant array size as an APInt.
uint64_t getZExtSize() const
Return the size zero-extended as a uint64_t.
APValue getAPValueResult() const
bool hasAPValueResult() const
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
Represents the current source location and context used to determine the value of the source location...
const Expr * getDefaultExpr() const
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool Equals(const DeclContext *DC) const
Determine whether this declaration context is equivalent to the declaration context DC.
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
A reference to a declared variable, function, enum, etc.
bool refersToEnclosingVariableOrCapture() const
Does this DeclRefExpr refer to an enclosing local or a captured variable?
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Decl - This represents one declaration (or definition), e.g.
bool isInStdNamespace() const
ASTContext & getASTContext() const LLVM_READONLY
bool isInvalidDecl() const
SourceLocation getLocation() const
DeclContext * getDeclContext()
AccessSpecifier getAccess() const
bool isAnyOperatorNew() const
A decomposition declaration.
auto flat_bindings() const
Designator - A designator in a C99 designated initializer.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
DoStmt - This represents a 'do/while' stmt.
Symbolic representation of a dynamic allocation.
static unsigned getMaxIndex()
ChildElementIter< false > begin()
ExplicitCastExpr - An explicit cast written in the source code.
QualType getTypeAsWritten() const
getTypeAsWritten - Returns the type that this expression is casting to, as written in the source code...
This represents one expression.
const Expr * skipRValueSubobjectAdjustments(SmallVectorImpl< const Expr * > &CommaLHS, SmallVectorImpl< SubobjectAdjustment > &Adjustments) const
Walk outwards from an expression we want to bind a reference to and find the expression whose lifetim...
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
static bool isPotentialConstantExpr(const FunctionDecl *FD, SmallVectorImpl< PartialDiagnosticAt > &Diags)
isPotentialConstantExpr - Return true if this function's definition might be usable in a constant exp...
bool isIntegerConstantExpr(const ASTContext &Ctx) const
static bool isPotentialConstantExprUnevaluated(Expr *E, const FunctionDecl *FD, SmallVectorImpl< PartialDiagnosticAt > &Diags)
isPotentialConstantExprUnevaluated - Return true if this expression might be usable in a constant exp...
@ SE_AllowSideEffects
Allow any unmodeled side effect.
@ SE_AllowUndefinedBehavior
Allow UB that we can give a value, but not arbitrary unmodeled side effects.
bool isCXX11ConstantExpr(const ASTContext &Ctx, APValue *Result=nullptr) const
isCXX11ConstantExpr - Return true if this expression is a constant expression in C++11.
bool EvaluateCharRangeAsString(std::string &Result, const Expr *SizeExpression, const Expr *PtrExpression, ASTContext &Ctx, EvalResult &Status) const
llvm::APSInt EvaluateKnownConstIntCheckOverflow(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
bool isValueDependent() const
Determines whether the value of this expression depends on.
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
bool tryEvaluateStrLen(uint64_t &Result, ASTContext &Ctx) const
If the current Expr is a pointer, this will try to statically determine the strlen of the string poin...
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Returns the set of floating point options that apply to this expression.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
bool containsErrors() const
Whether this expression contains subexpressions which had errors.
bool EvaluateAsFloat(llvm::APFloat &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsFloat - Return true if this is a constant which we can fold and convert to a floating point...
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsLValue - Evaluate an expression to see if we can fold it to an lvalue with link time known ...
bool EvaluateAsFixedPoint(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsFixedPoint - Return true if this is a constant which we can fold and convert to a fixed poi...
bool isEvaluatable(const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
isEvaluatable - Call EvaluateAsRValue to see if this expression can be constant folded without side-e...
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language.
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...
bool HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects=true) const
HasSideEffects - This routine returns true for all those expressions which have any effect other than...
bool EvaluateAsConstantExpr(EvalResult &Result, const ASTContext &Ctx, ConstantExprKind Kind=ConstantExprKind::Normal) const
Evaluate an expression that is required to be a constant expression.
std::optional< std::string > tryEvaluateString(ASTContext &Ctx) const
If the current Expr can be evaluated to a pointer to a null-terminated constant string,...
bool EvaluateAsBooleanCondition(bool &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsBooleanCondition - Return true if this is a constant which we can fold and convert to a boo...
bool isTemporaryObject(ASTContext &Ctx, const CXXRecordDecl *TempTy) const
Determine whether the result of this expression is a temporary object of the given class type.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
bool tryEvaluateObjectSize(uint64_t &Result, ASTContext &Ctx, unsigned Type) const
If the current Expr is a pointer, this will try to statically determine the number of bytes available...
bool isCXX98IntegralConstantExpr(const ASTContext &Ctx) const
isCXX98IntegralConstantExpr - Return true if this expression is an integral constant expression in C+...
bool EvaluateWithSubstitution(APValue &Value, ASTContext &Ctx, const FunctionDecl *Callee, ArrayRef< const Expr * > Args, const Expr *This=nullptr) const
EvaluateWithSubstitution - Evaluate an expression as if from the context of a call to the given funct...
bool EvaluateAsInitializer(APValue &Result, const ASTContext &Ctx, const VarDecl *VD, SmallVectorImpl< PartialDiagnosticAt > &Notes, bool IsConstantInitializer) const
EvaluateAsInitializer - Evaluate an expression as if it were the initializer of the given declaration...
void EvaluateForOverflow(const ASTContext &Ctx) const
bool isArrow() const
isArrow - Return true if the base expression is a pointer to vector, return false if the base express...
void getEncodedElementAccess(SmallVectorImpl< uint32_t > &Elts) const
getEncodedElementAccess - Encode the elements accessed into an llvm aggregate Constant of ConstantInt...
const Expr * getBase() const
bool isFPConstrained() const
LangOptions::FPExceptionModeKind getExceptionMode() const
RoundingMode getRoundingMode() const
Represents a member of a struct/union/class.
bool isBitField() const
Determines whether this field is a bitfield.
unsigned getBitWidthValue() const
Computes the bit width of this field, if this is a bit field.
unsigned getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
FieldDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this field.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
llvm::APInt getValue() const
Returns an internal integer representation of the literal.
llvm::APFloat getValue() const
ForStmt - This represents a 'for (init;cond;inc)' stmt.
VarDecl * getConditionVariable() const
Retrieve the variable declared in this "for" statement, if any.
const Expr * getSubExpr() const
Represents a function declaration or definition.
const ParmVarDecl * getParamDecl(unsigned i) const
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
bool isFunctionTemplateSpecialization() const
Determine whether this function is a function template specialization.
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
bool hasCXXExplicitFunctionObjectParameter() const
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
ArrayRef< ParmVarDecl * >::const_iterator param_const_iterator
bool isConstexpr() const
Whether this is a (C++11) constexpr function or constexpr constructor.
bool isUsableAsGlobalAllocationFunctionInConstantEvaluation(UnsignedOrNone *AlignmentParam=nullptr, bool *IsNothrow=nullptr) const
Determines whether this function is one of the replaceable global allocation functions described in i...
bool isDefaulted() const
Whether this function is defaulted.
void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override
Appends a human-readable name for this declaration into the given stream.
FunctionDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
Expr * getResultExpr()
Return the result expression of this controlling expression.
One of these records is kept for each identifier that is lexed.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
IfStmt - This represents an if/then/else.
bool isNonNegatedConsteval() const
VarDecl * getConditionVariable()
Retrieve the variable declared in this "if" statement, if any.
const Expr * getSubExpr() const
Represents an implicitly-generated value initialization of an object of a given type.
Represents a field injected from an anonymous union/struct into the parent scope.
ArrayRef< NamedDecl * > chain() const
Describes an C or C++ initializer list.
bool isTransparent() const
Is this a transparent initializer list (that is, an InitListExpr that is purely syntactic,...
bool isStringLiteralInit() const
Is this an initializer for an array of characters, initialized by a string literal or an @encode?
unsigned getNumInits() const
Expr * getArrayFiller()
If this initializer list initializes an array with more elements than there are initializers in the l...
const Expr * getInit(unsigned Init) const
ArrayRef< Expr * > inits()
capture_init_iterator capture_init_end()
Retrieve the iterator pointing one past the last initialization argument for this lambda expression.
capture_init_iterator capture_init_begin()
Retrieve the first initialization argument for this lambda expression (which initializes the first ca...
CXXRecordDecl * getLambdaClass() const
Retrieve the class that corresponds to the lambda.
StrictFlexArraysLevelKind
@ FPE_Ignore
Assume that floating-point exceptions are masked.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
StorageDuration getStorageDuration() const
Retrieve the storage duration for the materialized temporary.
Expr * getSubExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue.
APValue * getOrCreateValue(bool MayCreate) const
Get the storage for the constant value of a materialized temporary of static storage duration.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
void printQualifiedName(raw_ostream &OS) const
Returns a human-readable qualified name for this declaration, like A::B::i, for i being member of nam...
bool isExpressibleAsConstantInitializer() const
Expr * getIndexExpr(unsigned Idx)
const OffsetOfNode & getComponent(unsigned Idx) const
TypeSourceInfo * getTypeSourceInfo() const
unsigned getNumComponents() const
unsigned getArrayExprIndex() const
For an array element node, returns the index into the array of expressions.
FieldDecl * getField() const
For a field offsetof node, returns the field.
@ Array
An index into an array.
@ Identifier
A field in a dependent type, known only by its name.
@ Base
An implicit indirection through a C++ base class, when the field found is in a base class.
Kind getKind() const
Determine what kind of offsetof node this is.
CXXBaseSpecifier * getBase() const
For a base class node, returns the base specifier.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
Expr * getSelectedExpr() const
const Expr * getSubExpr() const
Represents a parameter to a function.
unsigned getFunctionScopeIndex() const
Returns the index of this parameter in its prototype or method scope.
bool isExplicitObjectParameter() const
PointerType - C99 6.7.5.1 - Pointer Declarators.
StringLiteral * getFunctionName()
Expr * getResultExpr()
Return the result-bearing expression, or null if there is none.
ArrayRef< Expr * > semantics()
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
QualType withConst() const
void addConst()
Add the const type qualifier to this QualType.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
void removeLocalVolatile()
void addVolatile()
Add the volatile type qualifier to this QualType.
bool isConstQualified() const
Determine whether this type is const-qualified.
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after.
unsigned getCVRQualifiers() const
Retrieve the set of CVR (const-volatile-restrict) qualifiers applied to this type.
Represents a struct/union/class.
field_iterator field_end() const
field_range fields() const
specific_decl_iterator< FieldDecl > field_iterator
bool isAnonymousStructOrUnion() const
Whether this is an anonymous struct or union.
field_iterator field_begin() const
bool isSatisfied() const
Whether or not the requires clause is satisfied.
SourceLocation getLocation() const
std::string ComputeName(ASTContext &Context) const
Scope - A scope is a transient data structure that is used while parsing the program.
ShuffleVectorExpr - clang-specific builtin-in function __builtin_shufflevector.
llvm::APSInt getShuffleMaskIdx(unsigned N) const
unsigned getNumSubExprs() const
getNumSubExprs - Return the size of the SubExprs array.
Expr * getExpr(unsigned Index)
getExpr - Return the Expr at the specified index.
unsigned getPackLength() const
Retrieve the length of the parameter pack.
APValue EvaluateInContext(const ASTContext &Ctx, const Expr *DefaultExpr) const
Return the result of evaluating this SourceLocExpr in the specified (and possibly null) default argum...
Encodes a location in the source.
A trivial tuple used to represent a source range.
SourceLocation getBegin() const
std::string printToString(const SourceManager &SM) const
CompoundStmt * getSubStmt()
Stmt - This represents one statement.
StmtClass getStmtClass() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
SourceLocation getBeginLoc() const LLVM_READONLY
StringLiteral - This represents a string literal expression, e.g.
unsigned getLength() const
StringRef getBytes() const
Allow access to clients that need the byte representation, such as ASTWriterStmt::VisitStringLiteral(...
uint32_t getCodeUnit(size_t i) const
StringRef getString() const
unsigned getCharByteWidth() const
Expr * getReplacement() const
const SwitchCase * getNextSwitchCase() const
SwitchStmt - This represents a 'switch' stmt.
VarDecl * getConditionVariable()
Retrieve the variable declared in this "switch" statement, if any.
SwitchCase * getSwitchCaseList()
TagDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
unsigned getMaxAtomicInlineWidth() const
Return the maximum width lock-free atomic operation which can be inlined given the supported features...
virtual int getEHDataRegisterNumber(unsigned RegNo) const
Return the register number that __builtin_eh_return_regno would return with the specified argument.
unsigned getCharWidth() const
unsigned size() const
Retrieve the number of template arguments in this template argument list.
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
@ Type
The template argument is a type.
Symbolic representation of typeid(T) for some type T.
QualType getType() const
Return the type wrapped by this type source info.
bool getBoolValue() const
const APValue & getAPValue() const
bool isStoredAsBoolean() const
The base class of the type hierarchy.
bool isBooleanType() const
bool isFunctionReferenceType() const
bool isMFloat8Type() const
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
bool isPackedVectorBoolType(const ASTContext &ctx) const
bool isLiteralType(const ASTContext &Ctx) const
Return true if this is a literal type (C++11 [basic.types]p10)
bool isIncompleteArrayType() const
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
bool isComplexType() const
isComplexType() does not include complex integers (a GCC extension).
const ArrayType * castAsArrayTypeUnsafe() const
A variant of castAs<> for array type which silently discards qualifiers from the outermost type.
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
bool isIntegralOrUnscopedEnumerationType() const
Determine whether this type is an integral or unscoped enumeration type.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isConstantArrayType() const
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isVoidPointerType() const
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6....
bool isFunctionPointerType() const
bool isPointerType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isEnumeralType() const
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
bool isVariableArrayType() const
bool isSveVLSBuiltinType() const
Determines if this is a sizeless type supported by the 'arm_sve_vector_bits' type attribute,...
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
bool isExtVectorBoolType() const
bool isMemberDataPointerType() const
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
RecordDecl * castAsRecordDecl() const
bool isAnyComplexType() const
bool isFixedPointType() const
Return true if this is a fixed point type according to ISO/IEC JTC1 SC22 WG14 N1169.
bool isMemberPointerType() const
bool isAtomicType() const
bool isComplexIntegerType() const
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isObjectType() const
Determine whether this type is an object type.
EnumDecl * getAsEnumDecl() const
Retrieves the EnumDecl this type refers to.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
bool isFunctionType() const
bool isVectorType() const
bool isRealFloatingType() const
Floating point categories.
bool isFloatingType() const
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
const T * castAsCanonical() const
Return this type's canonical type cast to the specified type.
bool isAnyPointerType() const
TypeClass getTypeClass() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isNullPtrType() const
bool isRecordType() const
bool isSizelessVectorType() const
Returns true for all scalable vector types.
bool hasPointerRepresentation() const
Whether this type is represented natively as a pointer.
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
QualType getArgumentType() const
SourceLocation getBeginLoc() const LLVM_READONLY
QualType getTypeOfArgument() const
Gets the argument type, or the type of the argument expression, whichever is appropriate.
bool isArgumentType() const
UnaryExprOrTypeTrait getKind() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
SourceLocation getExprLoc() const
Expr * getSubExpr() const
static bool isIncrementOp(Opcode Op)
bool canOverflow() const
Returns true if the unary operator can cause an overflow.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
bool isWeak() const
Determine whether this symbol is weakly-imported, or declared with the weak or weak-ref attr.
Represents a variable declaration or definition.
bool isConstexpr() const
Whether this variable is (C++11) constexpr.
bool hasICEInitializer(const ASTContext &Context) const
Determine whether the initializer of this variable is an integer constant expression.
bool isInitCapture() const
Whether this variable is the implicit variable for a lambda init-capture.
APValue * evaluateValue() const
Attempt to evaluate the value of the initializer attached to this declaration, and produce notes expl...
CharUnits getFlexibleArrayInitChars(const ASTContext &Ctx) const
If hasFlexibleArrayInit is true, compute the number of additional bytes necessary to store those elem...
bool hasConstantInitialization() const
Determine whether this variable has constant initialization.
VarDecl * getDefinition(ASTContext &)
Get the real (not just tentative) definition for this declaration.
bool mightBeUsableInConstantExpressions(const ASTContext &C) const
Determine whether this variable's value might be usable in a constant expression, according to the re...
EvaluatedStmt * ensureEvaluatedStmt() const
Convert the initializer for this declaration to the elaborated EvaluatedStmt form,...
bool evaluateDestruction(SmallVectorImpl< PartialDiagnosticAt > &Notes) const
Evaluate the destruction of this variable to determine if it constitutes constant destruction.
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
ThreadStorageClassSpecifier getTSCSpec() const
const Expr * getInit() const
APValue * getEvaluatedValue() const
Return the already-evaluated value of this variable's initializer, or NULL if the value is not yet kn...
bool hasLocalStorage() const
Returns true if a variable with function scope is a non-static local variable.
DefinitionKind hasDefinition(ASTContext &) const
Check whether this variable is defined in this translation unit.
bool isLocalVarDecl() const
Returns true for local variable declarations other than parameters.
bool isUsableInConstantExpressions(const ASTContext &C) const
Determine whether this variable's value can be used in a constant expression, according to the releva...
const Expr * getAnyInitializer() const
Get the initializer for this variable, no matter which declaration it is attached to.
Expr * getSizeExpr() const
Represents a GCC generic vector type.
unsigned getNumElements() const
QualType getElementType() const
WhileStmt - This represents a 'while' stmt.
VarDecl * getConditionVariable()
Retrieve the variable declared in this "while" statement, if any.
bool evaluateCharRange(State &Parent, const Expr *SizeExpr, const Expr *PtrExpr, APValue &Result)
bool evaluateString(State &Parent, const Expr *E, std::string &Result)
Evaluate.
bool evaluateStrlen(State &Parent, const Expr *E, uint64_t &Result)
Evalute.
void isPotentialConstantExprUnevaluated(State &Parent, const Expr *E, const FunctionDecl *FD)
bool isPotentialConstantExpr(State &Parent, const FunctionDecl *FD)
Checks if a function is a potential constant expression.
bool evaluateAsRValue(State &Parent, const Expr *E, APValue &Result)
Evaluates a toplevel expression as an rvalue.
bool evaluate(State &Parent, const Expr *E, APValue &Result, ConstantExprKind Kind)
Like evaluateAsRvalue(), but does no implicit lvalue-to-rvalue conversion.
Base class for stack frames, shared between VM and walker.
Interface for the VM to interact with the AST walker's context.
Defines the clang::TargetInfo interface.
bool computeOSLogBufferLayout(clang::ASTContext &Ctx, const clang::CallExpr *E, OSLogBufferLayout &layout)
static const FunctionDecl * getCallee(const CXXConstructExpr &D)
uint32_t Literal
Literals are represented as positive integers.
unsigned kind
All of the diagnostics that can be emitted by the frontend.
std::optional< llvm::AllocTokenMetadata > getAllocTokenMetadata(QualType T, const ASTContext &Ctx)
Get the information required for construction of an allocation token ID.
QualType inferPossibleType(const CallExpr *E, const ASTContext &Ctx, const CastExpr *CastE)
Infer the possible allocated type from an allocation call expression.
bool NE(InterpState &S, CodePtr OpPC)
llvm::FixedPointSemantics FixedPointSemantics
bool This(InterpState &S, CodePtr OpPC)
bool Alloc(InterpState &S, CodePtr OpPC, const Descriptor *Desc)
std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl
All declarations that can appear in a module declaration.
AccessKind
This enum distinguishes between different ways to access (read or write) a variable.
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
bool isa(CodeGen::Address addr)
bool hasSpecificAttr(const Container &container)
@ NonNull
Values of this type can never be null.
@ Success
Annotation was successful.
Expr::ConstantExprKind ConstantExprKind
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
bool operator==(const CallGraphNode::CallRecord &LHS, const CallGraphNode::CallRecord &RHS)
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
bool isLambdaCallWithExplicitObjectParameter(const DeclContext *DC)
UnaryExprOrTypeTrait
Names for the "expression or type" traits.
ComparisonCategoryResult
An enumeration representing the possible results of a three-way comparison.
CheckSubobjectKind
The order of this enum is important for diagnostics.
@ SD_Static
Static storage duration.
@ SD_FullExpression
Full-expression storage duration (for temporaries).
bool isLambdaCallOperator(const CXXMethodDecl *MD)
@ Result
The result type of a method or function.
AccessKinds
Kinds of access we can perform on an object, for diagnostics.
@ AK_ReadObjectRepresentation
const FunctionProtoType * T
@ Type
The name was classified as a type.
CastKind
CastKind - The kind of operation required for a conversion.
llvm::hash_code hash_value(const CustomizableOptional< T > &O)
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs.
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
@ ConstantFold
Fold the expression to a constant.
@ ConstantExpressionUnevaluated
Evaluate as a constant expression.
@ ConstantExpression
Evaluate as a constant expression.
@ IgnoreSideEffects
Evaluate in any way we know how.
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
U cast(CodeGen::Address addr)
@ None
The alignment was not explicit in code.
@ ArrayBound
Array bound in array declarator or new-expression.
@ Class
The "class" keyword introduces the elaborated-type-specifier.
ActionResult< Expr * > ExprResult
@ Other
Other implicit parameter.
ActionResult< Stmt * > StmtResult
Diagnostic wrappers for TextAPI types for error reporting.
hash_code hash_value(const clang::tooling::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)