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 Builtin::BI__builtin_elementwise_fshl:
13377 case Builtin::BI__builtin_elementwise_fshr: {
13378 APValue SourceHi, SourceLo, SourceShift;
13384 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13390 ResultElements.reserve(SourceLen);
13391 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13396 case Builtin::BI__builtin_elementwise_fshl:
13397 ResultElements.push_back(
APValue(
13398 APSInt(llvm::APIntOps::fshl(Hi, Lo, Shift), Hi.isUnsigned())));
13400 case Builtin::BI__builtin_elementwise_fshr:
13401 ResultElements.push_back(
APValue(
13402 APSInt(llvm::APIntOps::fshr(Hi, Lo, Shift), Hi.isUnsigned())));
13407 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13410 case X86::BI__builtin_ia32_insertf32x4_256:
13411 case X86::BI__builtin_ia32_inserti32x4_256:
13412 case X86::BI__builtin_ia32_insertf64x2_256:
13413 case X86::BI__builtin_ia32_inserti64x2_256:
13414 case X86::BI__builtin_ia32_insertf32x4:
13415 case X86::BI__builtin_ia32_inserti32x4:
13416 case X86::BI__builtin_ia32_insertf64x2_512:
13417 case X86::BI__builtin_ia32_inserti64x2_512:
13418 case X86::BI__builtin_ia32_insertf32x8:
13419 case X86::BI__builtin_ia32_inserti32x8:
13420 case X86::BI__builtin_ia32_insertf64x4:
13421 case X86::BI__builtin_ia32_inserti64x4:
13422 case X86::BI__builtin_ia32_vinsertf128_ps256:
13423 case X86::BI__builtin_ia32_vinsertf128_pd256:
13424 case X86::BI__builtin_ia32_vinsertf128_si256:
13425 case X86::BI__builtin_ia32_insert128i256: {
13426 APValue SourceDst, SourceSub;
13438 assert(SubLen != 0 && DstLen != 0 && (DstLen % SubLen) == 0);
13439 unsigned NumLanes = DstLen / SubLen;
13440 unsigned LaneIdx = (Imm.getZExtValue() % NumLanes) * SubLen;
13443 ResultElements.reserve(DstLen);
13445 for (
unsigned EltNum = 0; EltNum < DstLen; ++EltNum) {
13446 if (EltNum >= LaneIdx && EltNum < LaneIdx + SubLen)
13447 ResultElements.push_back(SourceSub.
getVectorElt(EltNum - LaneIdx));
13449 ResultElements.push_back(SourceDst.
getVectorElt(EltNum));
13452 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13455 case clang::X86::BI__builtin_ia32_vec_set_v4hi:
13456 case clang::X86::BI__builtin_ia32_vec_set_v16qi:
13457 case clang::X86::BI__builtin_ia32_vec_set_v8hi:
13458 case clang::X86::BI__builtin_ia32_vec_set_v4si:
13459 case clang::X86::BI__builtin_ia32_vec_set_v2di:
13460 case clang::X86::BI__builtin_ia32_vec_set_v32qi:
13461 case clang::X86::BI__builtin_ia32_vec_set_v16hi:
13462 case clang::X86::BI__builtin_ia32_vec_set_v8si:
13463 case clang::X86::BI__builtin_ia32_vec_set_v4di: {
13471 QualType ElemTy = E->
getType()->
castAs<VectorType>()->getElementType();
13472 unsigned ElemWidth = Info.Ctx.
getIntWidth(ElemTy);
13474 Scalar.setIsUnsigned(ElemUnsigned);
13480 static_cast<unsigned>(IndexAPS.getZExtValue() & (NumElems - 1));
13483 Elems.reserve(NumElems);
13484 for (
unsigned ElemNum = 0; ElemNum != NumElems; ++ElemNum)
13485 Elems.push_back(ElemNum == Index ? ElemAV : VecVal.
getVectorElt(ElemNum));
13490 case X86::BI__builtin_ia32_pslldqi128_byteshift:
13491 case X86::BI__builtin_ia32_pslldqi256_byteshift:
13492 case X86::BI__builtin_ia32_pslldqi512_byteshift: {
13496 [](
unsigned DstIdx,
unsigned Shift) -> std::pair<unsigned, int> {
13497 unsigned LaneBase = (DstIdx / 16) * 16;
13498 unsigned LaneIdx = DstIdx % 16;
13499 if (LaneIdx < Shift)
13500 return std::make_pair(0, -1);
13502 return std::make_pair(
13503 0,
static_cast<int>(LaneBase + LaneIdx - Shift));
13509 case X86::BI__builtin_ia32_psrldqi128_byteshift:
13510 case X86::BI__builtin_ia32_psrldqi256_byteshift:
13511 case X86::BI__builtin_ia32_psrldqi512_byteshift: {
13515 [](
unsigned DstIdx,
unsigned Shift) -> std::pair<unsigned, int> {
13516 unsigned LaneBase = (DstIdx / 16) * 16;
13517 unsigned LaneIdx = DstIdx % 16;
13518 if (LaneIdx + Shift < 16)
13519 return std::make_pair(
13520 0,
static_cast<int>(LaneBase + LaneIdx + Shift));
13522 return std::make_pair(0, -1);
13528 case X86::BI__builtin_ia32_palignr128:
13529 case X86::BI__builtin_ia32_palignr256:
13530 case X86::BI__builtin_ia32_palignr512: {
13534 unsigned VecIdx = 1;
13537 int Lane = DstIdx / 16;
13538 int Offset = DstIdx % 16;
13541 unsigned ShiftedIdx = Offset + (
Shift & 0xFF);
13542 if (ShiftedIdx < 16) {
13543 ElemIdx = ShiftedIdx + (Lane * 16);
13544 }
else if (ShiftedIdx < 32) {
13546 ElemIdx = (ShiftedIdx - 16) + (Lane * 16);
13549 return std::pair<unsigned, int>{VecIdx, ElemIdx};
13554 case X86::BI__builtin_ia32_vpermi2varq128:
13555 case X86::BI__builtin_ia32_vpermi2varpd128: {
13558 [](
unsigned DstIdx,
unsigned ShuffleMask) {
13559 int Offset = ShuffleMask & 0x1;
13560 unsigned SrcIdx = (ShuffleMask >> 1) & 0x1;
13561 return std::pair<unsigned, int>{SrcIdx, Offset};
13566 case X86::BI__builtin_ia32_vpermi2vard128:
13567 case X86::BI__builtin_ia32_vpermi2varps128:
13568 case X86::BI__builtin_ia32_vpermi2varq256:
13569 case X86::BI__builtin_ia32_vpermi2varpd256: {
13572 [](
unsigned DstIdx,
unsigned ShuffleMask) {
13573 int Offset = ShuffleMask & 0x3;
13574 unsigned SrcIdx = (ShuffleMask >> 2) & 0x1;
13575 return std::pair<unsigned, int>{SrcIdx, Offset};
13580 case X86::BI__builtin_ia32_vpermi2varhi128:
13581 case X86::BI__builtin_ia32_vpermi2vard256:
13582 case X86::BI__builtin_ia32_vpermi2varps256:
13583 case X86::BI__builtin_ia32_vpermi2varq512:
13584 case X86::BI__builtin_ia32_vpermi2varpd512: {
13587 [](
unsigned DstIdx,
unsigned ShuffleMask) {
13588 int Offset = ShuffleMask & 0x7;
13589 unsigned SrcIdx = (ShuffleMask >> 3) & 0x1;
13590 return std::pair<unsigned, int>{SrcIdx, Offset};
13595 case X86::BI__builtin_ia32_vpermi2varqi128:
13596 case X86::BI__builtin_ia32_vpermi2varhi256:
13597 case X86::BI__builtin_ia32_vpermi2vard512:
13598 case X86::BI__builtin_ia32_vpermi2varps512: {
13601 [](
unsigned DstIdx,
unsigned ShuffleMask) {
13602 int Offset = ShuffleMask & 0xF;
13603 unsigned SrcIdx = (ShuffleMask >> 4) & 0x1;
13604 return std::pair<unsigned, int>{SrcIdx, Offset};
13609 case X86::BI__builtin_ia32_vpermi2varqi256:
13610 case X86::BI__builtin_ia32_vpermi2varhi512: {
13613 [](
unsigned DstIdx,
unsigned ShuffleMask) {
13614 int Offset = ShuffleMask & 0x1F;
13615 unsigned SrcIdx = (ShuffleMask >> 5) & 0x1;
13616 return std::pair<unsigned, int>{SrcIdx, Offset};
13621 case X86::BI__builtin_ia32_vpermi2varqi512: {
13624 [](
unsigned DstIdx,
unsigned ShuffleMask) {
13625 int Offset = ShuffleMask & 0x3F;
13626 unsigned SrcIdx = (ShuffleMask >> 6) & 0x1;
13627 return std::pair<unsigned, int>{SrcIdx, Offset};
13635bool VectorExprEvaluator::VisitConvertVectorExpr(
const ConvertVectorExpr *E) {
13641 QualType DestTy = E->
getType()->
castAs<VectorType>()->getElementType();
13642 QualType SourceTy = SourceVecType->
castAs<VectorType>()->getElementType();
13648 ResultElements.reserve(SourceLen);
13649 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13654 ResultElements.push_back(std::move(Elt));
13657 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13662 APValue const &VecVal2,
unsigned EltNum,
13664 unsigned const TotalElementsInInputVector1 = VecVal1.
getVectorLength();
13665 unsigned const TotalElementsInInputVector2 = VecVal2.
getVectorLength();
13668 int64_t
index = IndexVal.getExtValue();
13675 E, diag::err_shufflevector_minus_one_is_undefined_behavior_constexpr)
13681 index >= TotalElementsInInputVector1 + TotalElementsInInputVector2)
13682 llvm_unreachable(
"Out of bounds shuffle index");
13684 if (
index >= TotalElementsInInputVector1)
13691bool VectorExprEvaluator::VisitShuffleVectorExpr(
const ShuffleVectorExpr *E) {
13696 const Expr *Vec1 = E->
getExpr(0);
13700 const Expr *Vec2 = E->
getExpr(1);
13704 VectorType
const *DestVecTy = E->
getType()->
castAs<VectorType>();
13710 ResultElements.reserve(TotalElementsInOutputVector);
13711 for (
unsigned EltNum = 0; EltNum < TotalElementsInOutputVector; ++EltNum) {
13715 ResultElements.push_back(std::move(Elt));
13718 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13726 class ArrayExprEvaluator
13727 :
public ExprEvaluatorBase<ArrayExprEvaluator> {
13728 const LValue &
This;
13732 ArrayExprEvaluator(EvalInfo &Info,
const LValue &This,
APValue &
Result)
13736 assert(
V.isArray() &&
"expected array");
13741 bool ZeroInitialization(
const Expr *E) {
13742 const ConstantArrayType *CAT =
13757 if (!
Result.hasArrayFiller())
13761 LValue Subobject =
This;
13762 Subobject.addArray(Info, E, CAT);
13767 bool VisitCallExpr(
const CallExpr *E) {
13768 return handleCallExpr(E,
Result, &This);
13770 bool VisitCastExpr(
const CastExpr *E);
13771 bool VisitInitListExpr(
const InitListExpr *E,
13772 QualType AllocType = QualType());
13773 bool VisitArrayInitLoopExpr(
const ArrayInitLoopExpr *E);
13774 bool VisitCXXConstructExpr(
const CXXConstructExpr *E);
13775 bool VisitCXXConstructExpr(
const CXXConstructExpr *E,
13776 const LValue &Subobject,
13778 bool VisitStringLiteral(
const StringLiteral *E,
13779 QualType AllocType = QualType()) {
13783 bool VisitCXXParenListInitExpr(
const CXXParenListInitExpr *E);
13784 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
13785 ArrayRef<Expr *> Args,
13786 const Expr *ArrayFiller,
13787 QualType AllocType = QualType());
13792 APValue &Result, EvalInfo &Info) {
13795 "not an array prvalue");
13796 return ArrayExprEvaluator(Info,
This, Result).Visit(E);
13804 "not an array prvalue");
13805 return ArrayExprEvaluator(Info,
This, Result)
13806 .VisitInitListExpr(ILE, AllocType);
13815 "not an array prvalue");
13816 return ArrayExprEvaluator(Info,
This, Result)
13817 .VisitCXXConstructExpr(CCE,
This, &Result, AllocType);
13826 if (
const InitListExpr *ILE = dyn_cast<InitListExpr>(FillerExpr)) {
13827 for (
unsigned I = 0, E = ILE->
getNumInits(); I != E; ++I) {
13832 if (ILE->hasArrayFiller() &&
13841bool ArrayExprEvaluator::VisitCastExpr(
const CastExpr *E) {
13846 return ExprEvaluatorBaseTy::VisitCastExpr(E);
13847 case CK_HLSLAggregateSplatCast: {
13867 case CK_HLSLElementwiseCast: {
13884bool ArrayExprEvaluator::VisitInitListExpr(
const InitListExpr *E,
13885 QualType AllocType) {
13899 return VisitStringLiteral(SL, AllocType);
13904 "transparent array list initialization is not string literal init?");
13910bool ArrayExprEvaluator::VisitCXXParenListOrInitListExpr(
13912 QualType AllocType) {
13918 assert((!
Result.isArray() ||
Result.getArrayInitializedElts() == 0) &&
13919 "zero-initialized array shouldn't have any initialized elts");
13924 unsigned NumEltsToInit = Args.size();
13929 if (NumEltsToInit != NumElts &&
13931 NumEltsToInit = NumElts;
13933 for (
auto *
Init : Args) {
13934 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts()))
13935 NumEltsToInit += EmbedS->getDataElementCount() - 1;
13937 if (NumEltsToInit > NumElts)
13938 NumEltsToInit = NumElts;
13941 LLVM_DEBUG(llvm::dbgs() <<
"The number of elements to initialize: "
13942 << NumEltsToInit <<
".\n");
13944 Result =
APValue(APValue::UninitArray(), NumEltsToInit, NumElts);
13949 for (
unsigned I = 0, E =
Result.getArrayInitializedElts(); I != E; ++I)
13950 Result.getArrayInitializedElt(I) = Filler;
13951 if (
Result.hasArrayFiller())
13955 LValue Subobject =
This;
13956 Subobject.addArray(Info, ExprToVisit, CAT);
13957 auto Eval = [&](
const Expr *
Init,
unsigned ArrayIndex) {
13958 if (
Init->isValueDependent())
13962 Subobject,
Init) ||
13965 if (!Info.noteFailure())
13971 unsigned ArrayIndex = 0;
13974 for (
unsigned Index = 0; Index != NumEltsToInit; ++Index) {
13975 const Expr *
Init = Index < Args.size() ? Args[Index] : ArrayFiller;
13976 if (ArrayIndex >= NumEltsToInit)
13978 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
13979 StringLiteral *SL = EmbedS->getDataStringLiteral();
13980 for (
unsigned I = EmbedS->getStartingElementPos(),
13981 N = EmbedS->getDataElementCount();
13982 I != EmbedS->getStartingElementPos() + N; ++I) {
13988 const FPOptions FPO =
13994 Result.getArrayInitializedElt(ArrayIndex) =
APValue(FValue);
13999 if (!Eval(
Init, ArrayIndex))
14005 if (!
Result.hasArrayFiller())
14010 assert(ArrayFiller &&
"no array filler for incomplete init list");
14016bool ArrayExprEvaluator::VisitArrayInitLoopExpr(
const ArrayInitLoopExpr *E) {
14019 !
Evaluate(Info.CurrentCall->createTemporary(
14022 ScopeKind::FullExpression, CommonLV),
14029 Result =
APValue(APValue::UninitArray(), Elements, Elements);
14031 LValue Subobject =
This;
14032 Subobject.addArray(Info, E, CAT);
14035 for (EvalInfo::ArrayInitLoopIndex Index(Info); Index != Elements; ++Index) {
14044 FullExpressionRAII Scope(Info);
14050 if (!Info.noteFailure())
14062bool ArrayExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E) {
14063 return VisitCXXConstructExpr(E, This, &
Result, E->
getType());
14066bool ArrayExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E,
14067 const LValue &Subobject,
14070 bool HadZeroInit =
Value->hasValue();
14077 HadZeroInit &&
Value->hasArrayFiller() ?
Value->getArrayFiller()
14080 *
Value =
APValue(APValue::UninitArray(), 0, FinalSize);
14081 if (FinalSize == 0)
14087 LValue ArrayElt = Subobject;
14088 ArrayElt.addArray(Info, E, CAT);
14094 for (
const unsigned N : {1u, FinalSize}) {
14095 unsigned OldElts =
Value->getArrayInitializedElts();
14100 APValue NewValue(APValue::UninitArray(), N, FinalSize);
14101 for (
unsigned I = 0; I < OldElts; ++I)
14102 NewValue.getArrayInitializedElt(I).swap(
14103 Value->getArrayInitializedElt(I));
14104 Value->swap(NewValue);
14107 for (
unsigned I = OldElts; I < N; ++I)
14108 Value->getArrayInitializedElt(I) = Filler;
14110 if (HasTrivialConstructor && N == FinalSize && FinalSize != 1) {
14113 APValue &FirstResult =
Value->getArrayInitializedElt(0);
14114 for (
unsigned I = OldElts; I < FinalSize; ++I)
14115 Value->getArrayInitializedElt(I) = FirstResult;
14117 for (
unsigned I = OldElts; I < N; ++I) {
14118 if (!VisitCXXConstructExpr(E, ArrayElt,
14119 &
Value->getArrayInitializedElt(I),
14126 if (Info.EvalStatus.
Diag && !Info.EvalStatus.
Diag->empty() &&
14127 !Info.keepEvaluatingAfterFailure())
14136 if (!
Type->isRecordType())
14139 return RecordExprEvaluator(Info, Subobject, *
Value)
14140 .VisitCXXConstructExpr(E,
Type);
14143bool ArrayExprEvaluator::VisitCXXParenListInitExpr(
14144 const CXXParenListInitExpr *E) {
14146 "Expression result is not a constant array type");
14148 return VisitCXXParenListOrInitListExpr(E, E->
getInitExprs(),
14161class IntExprEvaluator
14162 :
public ExprEvaluatorBase<IntExprEvaluator> {
14165 IntExprEvaluator(EvalInfo &info,
APValue &result)
14166 : ExprEvaluatorBaseTy(info),
Result(result) {}
14170 "Invalid evaluation result.");
14172 "Invalid evaluation result.");
14174 "Invalid evaluation result.");
14178 bool Success(
const llvm::APSInt &SI,
const Expr *E) {
14184 "Invalid evaluation result.");
14186 "Invalid evaluation result.");
14188 Result.getInt().setIsUnsigned(
14192 bool Success(
const llvm::APInt &I,
const Expr *E) {
14198 "Invalid evaluation result.");
14206 bool Success(CharUnits Size,
const Expr *E) {
14213 if (
V.isLValue() ||
V.isAddrLabelDiff() ||
V.isIndeterminate() ||
14214 V.allowConstexprUnknown()) {
14221 bool ZeroInitialization(
const Expr *E) {
return Success(0, E); }
14223 friend std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &,
14230 bool VisitIntegerLiteral(
const IntegerLiteral *E) {
14233 bool VisitCharacterLiteral(
const CharacterLiteral *E) {
14237 bool CheckReferencedDecl(
const Expr *E,
const Decl *D);
14238 bool VisitDeclRefExpr(
const DeclRefExpr *E) {
14239 if (CheckReferencedDecl(E, E->
getDecl()))
14242 return ExprEvaluatorBaseTy::VisitDeclRefExpr(E);
14244 bool VisitMemberExpr(
const MemberExpr *E) {
14246 VisitIgnoredBaseExpression(E->
getBase());
14250 return ExprEvaluatorBaseTy::VisitMemberExpr(E);
14253 bool VisitCallExpr(
const CallExpr *E);
14254 bool VisitBuiltinCallExpr(
const CallExpr *E,
unsigned BuiltinOp);
14255 bool VisitBinaryOperator(
const BinaryOperator *E);
14256 bool VisitOffsetOfExpr(
const OffsetOfExpr *E);
14257 bool VisitUnaryOperator(
const UnaryOperator *E);
14259 bool VisitCastExpr(
const CastExpr* E);
14260 bool VisitUnaryExprOrTypeTraitExpr(
const UnaryExprOrTypeTraitExpr *E);
14262 bool VisitCXXBoolLiteralExpr(
const CXXBoolLiteralExpr *E) {
14266 bool VisitObjCBoolLiteralExpr(
const ObjCBoolLiteralExpr *E) {
14270 bool VisitArrayInitIndexExpr(
const ArrayInitIndexExpr *E) {
14271 if (Info.ArrayInitIndex ==
uint64_t(-1)) {
14277 return Success(Info.ArrayInitIndex, E);
14281 bool VisitGNUNullExpr(
const GNUNullExpr *E) {
14282 return ZeroInitialization(E);
14285 bool VisitTypeTraitExpr(
const TypeTraitExpr *E) {
14294 bool VisitArrayTypeTraitExpr(
const ArrayTypeTraitExpr *E) {
14298 bool VisitExpressionTraitExpr(
const ExpressionTraitExpr *E) {
14302 bool VisitOpenACCAsteriskSizeExpr(
const OpenACCAsteriskSizeExpr *E) {
14309 bool VisitUnaryReal(
const UnaryOperator *E);
14310 bool VisitUnaryImag(
const UnaryOperator *E);
14312 bool VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E);
14313 bool VisitSizeOfPackExpr(
const SizeOfPackExpr *E);
14314 bool VisitSourceLocExpr(
const SourceLocExpr *E);
14315 bool VisitConceptSpecializationExpr(
const ConceptSpecializationExpr *E);
14320class FixedPointExprEvaluator
14321 :
public ExprEvaluatorBase<FixedPointExprEvaluator> {
14325 FixedPointExprEvaluator(EvalInfo &info,
APValue &result)
14326 : ExprEvaluatorBaseTy(info),
Result(result) {}
14328 bool Success(
const llvm::APInt &I,
const Expr *E) {
14339 return Success(
V.getFixedPoint(), E);
14342 bool Success(
const APFixedPoint &
V,
const Expr *E) {
14345 "Invalid evaluation result.");
14350 bool ZeroInitialization(
const Expr *E) {
14358 bool VisitFixedPointLiteral(
const FixedPointLiteral *E) {
14362 bool VisitCastExpr(
const CastExpr *E);
14363 bool VisitUnaryOperator(
const UnaryOperator *E);
14364 bool VisitBinaryOperator(
const BinaryOperator *E);
14380 return IntExprEvaluator(Info, Result).Visit(E);
14388 if (!Val.
isInt()) {
14391 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
14398bool IntExprEvaluator::VisitSourceLocExpr(
const SourceLocExpr *E) {
14400 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.
getDefaultExpr());
14409 if (!FixedPointExprEvaluator(Info, Val).Visit(E))
14428 Result = APFixedPoint(Val, FXSema);
14439bool IntExprEvaluator::CheckReferencedDecl(
const Expr* E,
const Decl* D) {
14441 if (
const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(D)) {
14443 bool SameSign = (ECD->getInitVal().isSigned()
14445 bool SameWidth = (ECD->getInitVal().
getBitWidth()
14447 if (SameSign && SameWidth)
14448 return Success(ECD->getInitVal(), E);
14452 llvm::APSInt Val = ECD->getInitVal();
14454 Val.setIsSigned(!ECD->getInitVal().isSigned());
14467 assert(!
T->isDependentType() &&
"unexpected dependent type");
14472#define TYPE(ID, BASE)
14473#define DEPENDENT_TYPE(ID, BASE) case Type::ID:
14474#define NON_CANONICAL_TYPE(ID, BASE) case Type::ID:
14475#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(ID, BASE) case Type::ID:
14476#include "clang/AST/TypeNodes.inc"
14478 case Type::DeducedTemplateSpecialization:
14479 llvm_unreachable(
"unexpected non-canonical or dependent type");
14481 case Type::Builtin:
14483#define BUILTIN_TYPE(ID, SINGLETON_ID)
14484#define SIGNED_TYPE(ID, SINGLETON_ID) \
14485 case BuiltinType::ID: return GCCTypeClass::Integer;
14486#define FLOATING_TYPE(ID, SINGLETON_ID) \
14487 case BuiltinType::ID: return GCCTypeClass::RealFloat;
14488#define PLACEHOLDER_TYPE(ID, SINGLETON_ID) \
14489 case BuiltinType::ID: break;
14490#include "clang/AST/BuiltinTypes.def"
14491 case BuiltinType::Void:
14494 case BuiltinType::Bool:
14497 case BuiltinType::Char_U:
14498 case BuiltinType::UChar:
14499 case BuiltinType::WChar_U:
14500 case BuiltinType::Char8:
14501 case BuiltinType::Char16:
14502 case BuiltinType::Char32:
14503 case BuiltinType::UShort:
14504 case BuiltinType::UInt:
14505 case BuiltinType::ULong:
14506 case BuiltinType::ULongLong:
14507 case BuiltinType::UInt128:
14510 case BuiltinType::UShortAccum:
14511 case BuiltinType::UAccum:
14512 case BuiltinType::ULongAccum:
14513 case BuiltinType::UShortFract:
14514 case BuiltinType::UFract:
14515 case BuiltinType::ULongFract:
14516 case BuiltinType::SatUShortAccum:
14517 case BuiltinType::SatUAccum:
14518 case BuiltinType::SatULongAccum:
14519 case BuiltinType::SatUShortFract:
14520 case BuiltinType::SatUFract:
14521 case BuiltinType::SatULongFract:
14524 case BuiltinType::NullPtr:
14526 case BuiltinType::ObjCId:
14527 case BuiltinType::ObjCClass:
14528 case BuiltinType::ObjCSel:
14529#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
14530 case BuiltinType::Id:
14531#include "clang/Basic/OpenCLImageTypes.def"
14532#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
14533 case BuiltinType::Id:
14534#include "clang/Basic/OpenCLExtensionTypes.def"
14535 case BuiltinType::OCLSampler:
14536 case BuiltinType::OCLEvent:
14537 case BuiltinType::OCLClkEvent:
14538 case BuiltinType::OCLQueue:
14539 case BuiltinType::OCLReserveID:
14540#define SVE_TYPE(Name, Id, SingletonId) \
14541 case BuiltinType::Id:
14542#include "clang/Basic/AArch64ACLETypes.def"
14543#define PPC_VECTOR_TYPE(Name, Id, Size) \
14544 case BuiltinType::Id:
14545#include "clang/Basic/PPCTypes.def"
14546#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
14547#include "clang/Basic/RISCVVTypes.def"
14548#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
14549#include "clang/Basic/WebAssemblyReferenceTypes.def"
14550#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
14551#include "clang/Basic/AMDGPUTypes.def"
14552#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
14553#include "clang/Basic/HLSLIntangibleTypes.def"
14556 case BuiltinType::Dependent:
14557 llvm_unreachable(
"unexpected dependent type");
14559 llvm_unreachable(
"unexpected placeholder type");
14564 case Type::Pointer:
14565 case Type::ConstantArray:
14566 case Type::VariableArray:
14567 case Type::IncompleteArray:
14568 case Type::FunctionNoProto:
14569 case Type::FunctionProto:
14570 case Type::ArrayParameter:
14573 case Type::MemberPointer:
14578 case Type::Complex:
14591 case Type::ExtVector:
14594 case Type::BlockPointer:
14595 case Type::ConstantMatrix:
14596 case Type::ObjCObject:
14597 case Type::ObjCInterface:
14598 case Type::ObjCObjectPointer:
14600 case Type::HLSLAttributedResource:
14601 case Type::HLSLInlineSpirv:
14609 case Type::LValueReference:
14610 case Type::RValueReference:
14611 llvm_unreachable(
"invalid type for expression");
14614 llvm_unreachable(
"unexpected type class");
14639 if (
Base.isNull()) {
14642 }
else if (
const Expr *E =
Base.dyn_cast<
const Expr *>()) {
14661 SpeculativeEvaluationRAII SpeculativeEval(Info);
14666 FoldConstant Fold(Info,
true);
14684 if (ArgType->isIntegralOrEnumerationType() || ArgType->isFloatingType() ||
14685 ArgType->isAnyComplexType() || ArgType->isPointerType() ||
14686 ArgType->isNullPtrType()) {
14689 Fold.keepDiagnostics();
14698 return V.hasValue();
14709 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
14733 const auto *Cast = dyn_cast<CastExpr>(NoParens);
14734 if (Cast ==
nullptr)
14739 auto CastKind = Cast->getCastKind();
14741 CastKind != CK_AddressSpaceConversion)
14744 const auto *SubExpr = Cast->getSubExpr();
14766 assert(!LVal.Designator.Invalid);
14768 auto IsLastOrInvalidFieldDecl = [&Ctx](
const FieldDecl *FD) {
14776 auto &
Base = LVal.getLValueBase();
14777 if (
auto *ME = dyn_cast_or_null<MemberExpr>(
Base.dyn_cast<
const Expr *>())) {
14778 if (
auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
14779 if (!IsLastOrInvalidFieldDecl(FD))
14781 }
else if (
auto *IFD = dyn_cast<IndirectFieldDecl>(ME->getMemberDecl())) {
14782 for (
auto *FD : IFD->chain()) {
14791 if (LVal.Designator.FirstEntryIsAnUnsizedArray) {
14795 if (BaseType->isIncompleteArrayType())
14801 for (
unsigned E = LVal.Designator.Entries.size(); I != E; ++I) {
14802 const auto &Entry = LVal.Designator.Entries[I];
14803 if (BaseType->isArrayType()) {
14809 uint64_t Index = Entry.getAsArrayIndex();
14813 }
else if (BaseType->isAnyComplexType()) {
14814 const auto *CT = BaseType->castAs<
ComplexType>();
14815 uint64_t Index = Entry.getAsArrayIndex();
14818 BaseType = CT->getElementType();
14819 }
else if (
auto *FD = getAsField(Entry)) {
14820 if (!IsLastOrInvalidFieldDecl(FD))
14824 assert(getAsBaseClass(Entry) &&
"Expecting cast to a base class");
14836 if (LVal.Designator.Invalid)
14839 if (!LVal.Designator.Entries.empty())
14840 return LVal.Designator.isMostDerivedAnUnsizedArray();
14842 if (!LVal.InvalidBase)
14854 const SubobjectDesignator &
Designator = LVal.Designator;
14866 auto isFlexibleArrayMember = [&] {
14868 FAMKind StrictFlexArraysLevel =
14871 if (
Designator.isMostDerivedAnUnsizedArray())
14874 if (StrictFlexArraysLevel == FAMKind::Default)
14877 if (
Designator.getMostDerivedArraySize() == 0 &&
14878 StrictFlexArraysLevel != FAMKind::IncompleteOnly)
14881 if (
Designator.getMostDerivedArraySize() == 1 &&
14882 StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete)
14888 return LVal.InvalidBase &&
14890 Designator.MostDerivedIsArrayElement && isFlexibleArrayMember() &&
14898 auto CharUnitsMax = std::numeric_limits<CharUnits::QuantityType>::max();
14899 if (Int.ugt(CharUnitsMax))
14909 if (!
T.isNull() &&
T->isStructureType() &&
14910 T->castAsRecordDecl()->hasFlexibleArrayMember())
14911 if (
const auto *
V = LV.getLValueBase().dyn_cast<
const ValueDecl *>())
14912 if (
const auto *VD = dyn_cast<VarDecl>(
V))
14924 unsigned Type,
const LValue &LVal,
14943 if (!(
Type & 1) || LVal.Designator.Invalid || DetermineForCompleteObject) {
14945 if (
Type == 3 && !DetermineForCompleteObject)
14948 llvm::APInt APEndOffset;
14949 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
14953 if (LVal.InvalidBase)
14957 const bool Ret = CheckedHandleSizeof(BaseTy, EndOffset);
14963 const SubobjectDesignator &
Designator = LVal.Designator;
14975 llvm::APInt APEndOffset;
14976 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
14988 if (!CheckedHandleSizeof(
Designator.MostDerivedType, BytesPerElem))
14994 int64_t ElemsRemaining;
14997 uint64_t ArraySize =
Designator.getMostDerivedArraySize();
14998 uint64_t ArrayIndex =
Designator.Entries.back().getAsArrayIndex();
14999 ElemsRemaining = ArraySize <= ArrayIndex ? 0 : ArraySize - ArrayIndex;
15001 ElemsRemaining =
Designator.isOnePastTheEnd() ? 0 : 1;
15004 EndOffset = LVal.getLValueOffset() + BytesPerElem * ElemsRemaining;
15014 EvalInfo &Info, uint64_t &Size) {
15021 SpeculativeEvaluationRAII SpeculativeEval(Info);
15022 IgnoreSideEffectsRAII Fold(Info);
15030 LVal.setFrom(Info.Ctx, RVal);
15038 if (LVal.getLValueOffset().isNegative()) {
15049 if (EndOffset <= LVal.getLValueOffset())
15052 Size = (EndOffset - LVal.getLValueOffset()).getQuantity();
15056bool IntExprEvaluator::VisitCallExpr(
const CallExpr *E) {
15057 if (!IsConstantEvaluatedBuiltinCall(E))
15058 return ExprEvaluatorBaseTy::VisitCallExpr(E);
15075 Info.FFDiag(E->
getArg(0));
15081 assert(SrcInt.getBitWidth() >= Alignment.getBitWidth() &&
15082 "Bit widths must be the same");
15089bool IntExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *E,
15090 unsigned BuiltinOp) {
15091 auto EvalTestOp = [&](llvm::function_ref<
bool(
const APInt &,
const APInt &)>
15093 APValue SourceLHS, SourceRHS;
15101 unsigned LaneWidth = Info.Ctx.
getTypeSize(ElemQT);
15103 APInt AWide(LaneWidth * SourceLen, 0);
15104 APInt BWide(LaneWidth * SourceLen, 0);
15106 for (
unsigned I = 0; I != SourceLen; ++I) {
15109 if (ElemQT->isIntegerType()) {
15112 }
else if (ElemQT->isFloatingType()) {
15120 AWide.insertBits(ALane, I * LaneWidth);
15121 BWide.insertBits(BLane, I * LaneWidth);
15126 auto HandleMaskBinOp =
15139 switch (BuiltinOp) {
15143 case Builtin::BI__builtin_dynamic_object_size:
15144 case Builtin::BI__builtin_object_size: {
15148 assert(
Type <= 3 &&
"unexpected type");
15159 switch (Info.EvalMode) {
15160 case EvaluationMode::ConstantExpression:
15161 case EvaluationMode::ConstantFold:
15162 case EvaluationMode::IgnoreSideEffects:
15165 case EvaluationMode::ConstantExpressionUnevaluated:
15170 llvm_unreachable(
"unexpected EvalMode");
15173 case Builtin::BI__builtin_os_log_format_buffer_size: {
15174 analyze_os_log::OSLogBufferLayout Layout;
15179 case Builtin::BI__builtin_is_aligned: {
15187 Ptr.setFrom(Info.Ctx, Src);
15193 assert(Alignment.isPowerOf2());
15206 Info.FFDiag(E->
getArg(0), diag::note_constexpr_alignment_compute)
15210 assert(Src.
isInt());
15211 return Success((Src.
getInt() & (Alignment - 1)) == 0 ? 1 : 0, E);
15213 case Builtin::BI__builtin_align_up: {
15221 APSInt((Src.
getInt() + (Alignment - 1)) & ~(Alignment - 1),
15222 Src.
getInt().isUnsigned());
15223 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
15224 return Success(AlignedVal, E);
15226 case Builtin::BI__builtin_align_down: {
15235 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
15236 return Success(AlignedVal, E);
15239 case Builtin::BI__builtin_bitreverse8:
15240 case Builtin::BI__builtin_bitreverse16:
15241 case Builtin::BI__builtin_bitreverse32:
15242 case Builtin::BI__builtin_bitreverse64:
15243 case Builtin::BI__builtin_elementwise_bitreverse: {
15248 return Success(Val.reverseBits(), E);
15251 case Builtin::BI__builtin_bswap16:
15252 case Builtin::BI__builtin_bswap32:
15253 case Builtin::BI__builtin_bswap64: {
15258 return Success(Val.byteSwap(), E);
15261 case Builtin::BI__builtin_classify_type:
15264 case Builtin::BI__builtin_clrsb:
15265 case Builtin::BI__builtin_clrsbl:
15266 case Builtin::BI__builtin_clrsbll: {
15271 return Success(Val.getBitWidth() - Val.getSignificantBits(), E);
15274 case Builtin::BI__builtin_clz:
15275 case Builtin::BI__builtin_clzl:
15276 case Builtin::BI__builtin_clzll:
15277 case Builtin::BI__builtin_clzs:
15278 case Builtin::BI__builtin_clzg:
15279 case Builtin::BI__builtin_elementwise_clzg:
15280 case Builtin::BI__lzcnt16:
15281 case Builtin::BI__lzcnt:
15282 case Builtin::BI__lzcnt64: {
15293 std::optional<APSInt> Fallback;
15294 if ((BuiltinOp == Builtin::BI__builtin_clzg ||
15295 BuiltinOp == Builtin::BI__builtin_elementwise_clzg) &&
15300 Fallback = FallbackTemp;
15305 return Success(*Fallback, E);
15310 bool ZeroIsUndefined = BuiltinOp != Builtin::BI__lzcnt16 &&
15311 BuiltinOp != Builtin::BI__lzcnt &&
15312 BuiltinOp != Builtin::BI__lzcnt64;
15314 if (BuiltinOp == Builtin::BI__builtin_elementwise_clzg) {
15315 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
15319 if (ZeroIsUndefined)
15323 return Success(Val.countl_zero(), E);
15326 case Builtin::BI__builtin_constant_p: {
15327 const Expr *Arg = E->
getArg(0);
15336 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
15340 case Builtin::BI__noop:
15344 case Builtin::BI__builtin_is_constant_evaluated: {
15345 const auto *
Callee = Info.CurrentCall->getCallee();
15346 if (Info.InConstantContext && !Info.CheckingPotentialConstantExpression &&
15347 (Info.CallStackDepth == 1 ||
15348 (Info.CallStackDepth == 2 &&
Callee->isInStdNamespace() &&
15349 Callee->getIdentifier() &&
15350 Callee->getIdentifier()->isStr(
"is_constant_evaluated")))) {
15352 if (Info.EvalStatus.
Diag)
15353 Info.report((Info.CallStackDepth == 1)
15355 : Info.CurrentCall->getCallRange().getBegin(),
15356 diag::warn_is_constant_evaluated_always_true_constexpr)
15357 << (Info.CallStackDepth == 1 ?
"__builtin_is_constant_evaluated"
15358 :
"std::is_constant_evaluated");
15361 return Success(Info.InConstantContext, E);
15364 case Builtin::BI__builtin_is_within_lifetime:
15365 if (
auto result = EvaluateBuiltinIsWithinLifetime(*
this, E))
15369 case Builtin::BI__builtin_ctz:
15370 case Builtin::BI__builtin_ctzl:
15371 case Builtin::BI__builtin_ctzll:
15372 case Builtin::BI__builtin_ctzs:
15373 case Builtin::BI__builtin_ctzg:
15374 case Builtin::BI__builtin_elementwise_ctzg: {
15385 std::optional<APSInt> Fallback;
15386 if ((BuiltinOp == Builtin::BI__builtin_ctzg ||
15387 BuiltinOp == Builtin::BI__builtin_elementwise_ctzg) &&
15392 Fallback = FallbackTemp;
15397 return Success(*Fallback, E);
15399 if (BuiltinOp == Builtin::BI__builtin_elementwise_ctzg) {
15400 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
15406 return Success(Val.countr_zero(), E);
15409 case Builtin::BI__builtin_eh_return_data_regno: {
15415 case Builtin::BI__builtin_elementwise_abs: {
15420 return Success(Val.abs(), E);
15423 case Builtin::BI__builtin_expect:
15424 case Builtin::BI__builtin_expect_with_probability:
15425 return Visit(E->
getArg(0));
15427 case Builtin::BI__builtin_ptrauth_string_discriminator: {
15434 case Builtin::BI__builtin_infer_alloc_token: {
15440 E, diag::note_constexpr_infer_alloc_token_type_inference_failed);
15443 return Error(E, diag::note_constexpr_infer_alloc_token_no_metadata);
15445 Info.getLangOpts().AllocTokenMode.value_or(llvm::DefaultAllocTokenMode);
15448 Info.getLangOpts().AllocTokenMax.value_or(~0ULL >> (64 - BitWidth));
15449 auto MaybeToken = llvm::getAllocToken(Mode, *ATMD, MaxTokens);
15451 return Error(E, diag::note_constexpr_infer_alloc_token_stateful_mode);
15452 return Success(llvm::APInt(BitWidth, *MaybeToken), E);
15455 case Builtin::BI__builtin_ffs:
15456 case Builtin::BI__builtin_ffsl:
15457 case Builtin::BI__builtin_ffsll: {
15462 unsigned N = Val.countr_zero();
15463 return Success(N == Val.getBitWidth() ? 0 : N + 1, E);
15466 case Builtin::BI__builtin_fpclassify: {
15471 switch (Val.getCategory()) {
15472 case APFloat::fcNaN: Arg = 0;
break;
15473 case APFloat::fcInfinity: Arg = 1;
break;
15474 case APFloat::fcNormal: Arg = Val.isDenormal() ? 3 : 2;
break;
15475 case APFloat::fcZero: Arg = 4;
break;
15477 return Visit(E->
getArg(Arg));
15480 case Builtin::BI__builtin_isinf_sign: {
15483 Success(Val.isInfinity() ? (Val.isNegative() ? -1 : 1) : 0, E);
15486 case Builtin::BI__builtin_isinf: {
15489 Success(Val.isInfinity() ? 1 : 0, E);
15492 case Builtin::BI__builtin_isfinite: {
15495 Success(Val.isFinite() ? 1 : 0, E);
15498 case Builtin::BI__builtin_isnan: {
15501 Success(Val.isNaN() ? 1 : 0, E);
15504 case Builtin::BI__builtin_isnormal: {
15507 Success(Val.isNormal() ? 1 : 0, E);
15510 case Builtin::BI__builtin_issubnormal: {
15513 Success(Val.isDenormal() ? 1 : 0, E);
15516 case Builtin::BI__builtin_iszero: {
15519 Success(Val.isZero() ? 1 : 0, E);
15522 case Builtin::BI__builtin_signbit:
15523 case Builtin::BI__builtin_signbitf:
15524 case Builtin::BI__builtin_signbitl: {
15527 Success(Val.isNegative() ? 1 : 0, E);
15530 case Builtin::BI__builtin_isgreater:
15531 case Builtin::BI__builtin_isgreaterequal:
15532 case Builtin::BI__builtin_isless:
15533 case Builtin::BI__builtin_islessequal:
15534 case Builtin::BI__builtin_islessgreater:
15535 case Builtin::BI__builtin_isunordered: {
15544 switch (BuiltinOp) {
15545 case Builtin::BI__builtin_isgreater:
15547 case Builtin::BI__builtin_isgreaterequal:
15549 case Builtin::BI__builtin_isless:
15551 case Builtin::BI__builtin_islessequal:
15553 case Builtin::BI__builtin_islessgreater: {
15554 APFloat::cmpResult cmp = LHS.compare(RHS);
15555 return cmp == APFloat::cmpResult::cmpLessThan ||
15556 cmp == APFloat::cmpResult::cmpGreaterThan;
15558 case Builtin::BI__builtin_isunordered:
15559 return LHS.compare(RHS) == APFloat::cmpResult::cmpUnordered;
15561 llvm_unreachable(
"Unexpected builtin ID: Should be a floating "
15562 "point comparison function");
15570 case Builtin::BI__builtin_issignaling: {
15573 Success(Val.isSignaling() ? 1 : 0, E);
15576 case Builtin::BI__builtin_isfpclass: {
15580 unsigned Test =
static_cast<llvm::FPClassTest
>(MaskVal.getZExtValue());
15583 Success((Val.classify() & Test) ? 1 : 0, E);
15586 case Builtin::BI__builtin_parity:
15587 case Builtin::BI__builtin_parityl:
15588 case Builtin::BI__builtin_parityll: {
15593 return Success(Val.popcount() % 2, E);
15596 case Builtin::BI__builtin_abs:
15597 case Builtin::BI__builtin_labs:
15598 case Builtin::BI__builtin_llabs: {
15602 if (Val ==
APSInt(APInt::getSignedMinValue(Val.getBitWidth()),
15605 if (Val.isNegative())
15610 case Builtin::BI__builtin_popcount:
15611 case Builtin::BI__builtin_popcountl:
15612 case Builtin::BI__builtin_popcountll:
15613 case Builtin::BI__builtin_popcountg:
15614 case Builtin::BI__builtin_elementwise_popcount:
15615 case Builtin::BI__popcnt16:
15616 case Builtin::BI__popcnt:
15617 case Builtin::BI__popcnt64: {
15628 return Success(Val.popcount(), E);
15631 case Builtin::BI__builtin_rotateleft8:
15632 case Builtin::BI__builtin_rotateleft16:
15633 case Builtin::BI__builtin_rotateleft32:
15634 case Builtin::BI__builtin_rotateleft64:
15635 case Builtin::BI_rotl8:
15636 case Builtin::BI_rotl16:
15637 case Builtin::BI_rotl:
15638 case Builtin::BI_lrotl:
15639 case Builtin::BI_rotl64: {
15645 return Success(Val.rotl(Amt), E);
15648 case Builtin::BI__builtin_rotateright8:
15649 case Builtin::BI__builtin_rotateright16:
15650 case Builtin::BI__builtin_rotateright32:
15651 case Builtin::BI__builtin_rotateright64:
15652 case Builtin::BI_rotr8:
15653 case Builtin::BI_rotr16:
15654 case Builtin::BI_rotr:
15655 case Builtin::BI_lrotr:
15656 case Builtin::BI_rotr64: {
15662 return Success(Val.rotr(Amt), E);
15665 case Builtin::BI__builtin_elementwise_add_sat: {
15671 APInt Result = LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS);
15674 case Builtin::BI__builtin_elementwise_sub_sat: {
15680 APInt Result = LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
15683 case Builtin::BI__builtin_elementwise_max: {
15692 case Builtin::BI__builtin_elementwise_min: {
15701 case Builtin::BI__builtin_elementwise_fshl:
15702 case Builtin::BI__builtin_elementwise_fshr: {
15709 switch (BuiltinOp) {
15710 case Builtin::BI__builtin_elementwise_fshl: {
15711 APSInt Result(llvm::APIntOps::fshl(Hi, Lo, Shift), Hi.isUnsigned());
15714 case Builtin::BI__builtin_elementwise_fshr: {
15715 APSInt Result(llvm::APIntOps::fshr(Hi, Lo, Shift), Hi.isUnsigned());
15719 llvm_unreachable(
"Fully covered switch above");
15721 case Builtin::BIstrlen:
15722 case Builtin::BIwcslen:
15724 if (Info.getLangOpts().CPlusPlus11)
15725 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
15729 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
15731 case Builtin::BI__builtin_strlen:
15732 case Builtin::BI__builtin_wcslen: {
15741 case Builtin::BIstrcmp:
15742 case Builtin::BIwcscmp:
15743 case Builtin::BIstrncmp:
15744 case Builtin::BIwcsncmp:
15745 case Builtin::BImemcmp:
15746 case Builtin::BIbcmp:
15747 case Builtin::BIwmemcmp:
15749 if (Info.getLangOpts().CPlusPlus11)
15750 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
15754 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
15756 case Builtin::BI__builtin_strcmp:
15757 case Builtin::BI__builtin_wcscmp:
15758 case Builtin::BI__builtin_strncmp:
15759 case Builtin::BI__builtin_wcsncmp:
15760 case Builtin::BI__builtin_memcmp:
15761 case Builtin::BI__builtin_bcmp:
15762 case Builtin::BI__builtin_wmemcmp: {
15763 LValue String1, String2;
15769 if (BuiltinOp != Builtin::BIstrcmp &&
15770 BuiltinOp != Builtin::BIwcscmp &&
15771 BuiltinOp != Builtin::BI__builtin_strcmp &&
15772 BuiltinOp != Builtin::BI__builtin_wcscmp) {
15776 MaxLength = N.getZExtValue();
15780 if (MaxLength == 0u)
15783 if (!String1.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
15784 !String2.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
15785 String1.Designator.Invalid || String2.Designator.Invalid)
15788 QualType CharTy1 = String1.Designator.getType(Info.Ctx);
15789 QualType CharTy2 = String2.Designator.getType(Info.Ctx);
15791 bool IsRawByte = BuiltinOp == Builtin::BImemcmp ||
15792 BuiltinOp == Builtin::BIbcmp ||
15793 BuiltinOp == Builtin::BI__builtin_memcmp ||
15794 BuiltinOp == Builtin::BI__builtin_bcmp;
15796 assert(IsRawByte ||
15806 Info.FFDiag(E, diag::note_constexpr_memcmp_unsupported)
15812 const auto &ReadCurElems = [&](
APValue &Char1,
APValue &Char2) {
15815 Char1.
isInt() && Char2.isInt();
15817 const auto &AdvanceElems = [&] {
15823 (BuiltinOp != Builtin::BImemcmp && BuiltinOp != Builtin::BIbcmp &&
15824 BuiltinOp != Builtin::BIwmemcmp &&
15825 BuiltinOp != Builtin::BI__builtin_memcmp &&
15826 BuiltinOp != Builtin::BI__builtin_bcmp &&
15827 BuiltinOp != Builtin::BI__builtin_wmemcmp);
15828 bool IsWide = BuiltinOp == Builtin::BIwcscmp ||
15829 BuiltinOp == Builtin::BIwcsncmp ||
15830 BuiltinOp == Builtin::BIwmemcmp ||
15831 BuiltinOp == Builtin::BI__builtin_wcscmp ||
15832 BuiltinOp == Builtin::BI__builtin_wcsncmp ||
15833 BuiltinOp == Builtin::BI__builtin_wmemcmp;
15835 for (; MaxLength; --MaxLength) {
15837 if (!ReadCurElems(Char1, Char2))
15845 if (StopAtNull && !Char1.
getInt())
15847 assert(!(StopAtNull && !Char2.
getInt()));
15848 if (!AdvanceElems())
15855 case Builtin::BI__atomic_always_lock_free:
15856 case Builtin::BI__atomic_is_lock_free:
15857 case Builtin::BI__c11_atomic_is_lock_free: {
15873 if (
Size.isPowerOfTwo()) {
15875 unsigned InlineWidthBits =
15878 if (BuiltinOp == Builtin::BI__c11_atomic_is_lock_free ||
15884 const Expr *PtrArg = E->
getArg(1);
15890 IntResult.isAligned(
Size.getAsAlign()))
15894 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(PtrArg)) {
15897 if (ICE->getCastKind() == CK_BitCast)
15898 PtrArg = ICE->getSubExpr();
15901 if (
auto PtrTy = PtrArg->
getType()->
getAs<PointerType>()) {
15912 return BuiltinOp == Builtin::BI__atomic_always_lock_free ?
15915 case Builtin::BI__builtin_addcb:
15916 case Builtin::BI__builtin_addcs:
15917 case Builtin::BI__builtin_addc:
15918 case Builtin::BI__builtin_addcl:
15919 case Builtin::BI__builtin_addcll:
15920 case Builtin::BI__builtin_subcb:
15921 case Builtin::BI__builtin_subcs:
15922 case Builtin::BI__builtin_subc:
15923 case Builtin::BI__builtin_subcl:
15924 case Builtin::BI__builtin_subcll: {
15925 LValue CarryOutLValue;
15937 bool FirstOverflowed =
false;
15938 bool SecondOverflowed =
false;
15939 switch (BuiltinOp) {
15941 llvm_unreachable(
"Invalid value for BuiltinOp");
15942 case Builtin::BI__builtin_addcb:
15943 case Builtin::BI__builtin_addcs:
15944 case Builtin::BI__builtin_addc:
15945 case Builtin::BI__builtin_addcl:
15946 case Builtin::BI__builtin_addcll:
15948 LHS.uadd_ov(RHS, FirstOverflowed).uadd_ov(CarryIn, SecondOverflowed);
15950 case Builtin::BI__builtin_subcb:
15951 case Builtin::BI__builtin_subcs:
15952 case Builtin::BI__builtin_subc:
15953 case Builtin::BI__builtin_subcl:
15954 case Builtin::BI__builtin_subcll:
15956 LHS.usub_ov(RHS, FirstOverflowed).usub_ov(CarryIn, SecondOverflowed);
15962 CarryOut = (
uint64_t)(FirstOverflowed | SecondOverflowed);
15968 case Builtin::BI__builtin_add_overflow:
15969 case Builtin::BI__builtin_sub_overflow:
15970 case Builtin::BI__builtin_mul_overflow:
15971 case Builtin::BI__builtin_sadd_overflow:
15972 case Builtin::BI__builtin_uadd_overflow:
15973 case Builtin::BI__builtin_uaddl_overflow:
15974 case Builtin::BI__builtin_uaddll_overflow:
15975 case Builtin::BI__builtin_usub_overflow:
15976 case Builtin::BI__builtin_usubl_overflow:
15977 case Builtin::BI__builtin_usubll_overflow:
15978 case Builtin::BI__builtin_umul_overflow:
15979 case Builtin::BI__builtin_umull_overflow:
15980 case Builtin::BI__builtin_umulll_overflow:
15981 case Builtin::BI__builtin_saddl_overflow:
15982 case Builtin::BI__builtin_saddll_overflow:
15983 case Builtin::BI__builtin_ssub_overflow:
15984 case Builtin::BI__builtin_ssubl_overflow:
15985 case Builtin::BI__builtin_ssubll_overflow:
15986 case Builtin::BI__builtin_smul_overflow:
15987 case Builtin::BI__builtin_smull_overflow:
15988 case Builtin::BI__builtin_smulll_overflow: {
15989 LValue ResultLValue;
15999 bool DidOverflow =
false;
16002 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
16003 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
16004 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
16005 bool IsSigned = LHS.isSigned() || RHS.isSigned() ||
16007 bool AllSigned = LHS.isSigned() && RHS.isSigned() &&
16009 uint64_t LHSSize = LHS.getBitWidth();
16010 uint64_t RHSSize = RHS.getBitWidth();
16012 uint64_t MaxBits = std::max(std::max(LHSSize, RHSSize), ResultSize);
16018 if (IsSigned && !AllSigned)
16021 LHS =
APSInt(LHS.extOrTrunc(MaxBits), !IsSigned);
16022 RHS =
APSInt(RHS.extOrTrunc(MaxBits), !IsSigned);
16027 switch (BuiltinOp) {
16029 llvm_unreachable(
"Invalid value for BuiltinOp");
16030 case Builtin::BI__builtin_add_overflow:
16031 case Builtin::BI__builtin_sadd_overflow:
16032 case Builtin::BI__builtin_saddl_overflow:
16033 case Builtin::BI__builtin_saddll_overflow:
16034 case Builtin::BI__builtin_uadd_overflow:
16035 case Builtin::BI__builtin_uaddl_overflow:
16036 case Builtin::BI__builtin_uaddll_overflow:
16037 Result = LHS.isSigned() ? LHS.sadd_ov(RHS, DidOverflow)
16038 : LHS.uadd_ov(RHS, DidOverflow);
16040 case Builtin::BI__builtin_sub_overflow:
16041 case Builtin::BI__builtin_ssub_overflow:
16042 case Builtin::BI__builtin_ssubl_overflow:
16043 case Builtin::BI__builtin_ssubll_overflow:
16044 case Builtin::BI__builtin_usub_overflow:
16045 case Builtin::BI__builtin_usubl_overflow:
16046 case Builtin::BI__builtin_usubll_overflow:
16047 Result = LHS.isSigned() ? LHS.ssub_ov(RHS, DidOverflow)
16048 : LHS.usub_ov(RHS, DidOverflow);
16050 case Builtin::BI__builtin_mul_overflow:
16051 case Builtin::BI__builtin_smul_overflow:
16052 case Builtin::BI__builtin_smull_overflow:
16053 case Builtin::BI__builtin_smulll_overflow:
16054 case Builtin::BI__builtin_umul_overflow:
16055 case Builtin::BI__builtin_umull_overflow:
16056 case Builtin::BI__builtin_umulll_overflow:
16057 Result = LHS.isSigned() ? LHS.smul_ov(RHS, DidOverflow)
16058 : LHS.umul_ov(RHS, DidOverflow);
16064 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
16065 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
16066 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
16075 if (!APSInt::isSameValue(Temp,
Result))
16076 DidOverflow =
true;
16083 return Success(DidOverflow, E);
16086 case Builtin::BI__builtin_reduce_add:
16087 case Builtin::BI__builtin_reduce_mul:
16088 case Builtin::BI__builtin_reduce_and:
16089 case Builtin::BI__builtin_reduce_or:
16090 case Builtin::BI__builtin_reduce_xor:
16091 case Builtin::BI__builtin_reduce_min:
16092 case Builtin::BI__builtin_reduce_max: {
16099 for (
unsigned EltNum = 1; EltNum < SourceLen; ++EltNum) {
16100 switch (BuiltinOp) {
16103 case Builtin::BI__builtin_reduce_add: {
16106 Reduced.getBitWidth() + 1, std::plus<APSInt>(), Reduced))
16110 case Builtin::BI__builtin_reduce_mul: {
16113 Reduced.getBitWidth() * 2, std::multiplies<APSInt>(), Reduced))
16117 case Builtin::BI__builtin_reduce_and: {
16121 case Builtin::BI__builtin_reduce_or: {
16125 case Builtin::BI__builtin_reduce_xor: {
16129 case Builtin::BI__builtin_reduce_min: {
16133 case Builtin::BI__builtin_reduce_max: {
16143 case clang::X86::BI__builtin_ia32_addcarryx_u32:
16144 case clang::X86::BI__builtin_ia32_addcarryx_u64:
16145 case clang::X86::BI__builtin_ia32_subborrow_u32:
16146 case clang::X86::BI__builtin_ia32_subborrow_u64: {
16147 LValue ResultLValue;
16148 APSInt CarryIn, LHS, RHS;
16156 bool IsAdd = BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u32 ||
16157 BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u64;
16159 unsigned BitWidth = LHS.getBitWidth();
16160 unsigned CarryInBit = CarryIn.ugt(0) ? 1 : 0;
16163 ? (LHS.zext(BitWidth + 1) + (RHS.zext(BitWidth + 1) + CarryInBit))
16164 : (LHS.zext(BitWidth + 1) - (RHS.zext(BitWidth + 1) + CarryInBit));
16166 APInt Result = ExResult.extractBits(BitWidth, 0);
16167 uint64_t CarryOut = ExResult.extractBitsAsZExtValue(1, BitWidth);
16175 case clang::X86::BI__builtin_ia32_movmskps:
16176 case clang::X86::BI__builtin_ia32_movmskpd:
16177 case clang::X86::BI__builtin_ia32_pmovmskb128:
16178 case clang::X86::BI__builtin_ia32_pmovmskb256:
16179 case clang::X86::BI__builtin_ia32_movmskps256:
16180 case clang::X86::BI__builtin_ia32_movmskpd256: {
16191 for (
unsigned I = 0; I != SourceLen; ++I) {
16193 if (ElemQT->isIntegerType()) {
16195 }
else if (ElemQT->isRealFloatingType()) {
16200 Result.setBitVal(I, Elem.isNegative());
16205 case clang::X86::BI__builtin_ia32_bextr_u32:
16206 case clang::X86::BI__builtin_ia32_bextr_u64:
16207 case clang::X86::BI__builtin_ia32_bextri_u32:
16208 case clang::X86::BI__builtin_ia32_bextri_u64: {
16214 unsigned BitWidth = Val.getBitWidth();
16216 uint64_t Length = Idx.extractBitsAsZExtValue(8, 8);
16217 Length = Length > BitWidth ? BitWidth : Length;
16220 if (Length == 0 || Shift >= BitWidth)
16224 Result &= llvm::maskTrailingOnes<uint64_t>(Length);
16228 case clang::X86::BI__builtin_ia32_bzhi_si:
16229 case clang::X86::BI__builtin_ia32_bzhi_di: {
16235 unsigned BitWidth = Val.getBitWidth();
16236 unsigned Index = Idx.extractBitsAsZExtValue(8, 0);
16237 if (Index < BitWidth)
16238 Val.clearHighBits(BitWidth - Index);
16242 case clang::X86::BI__builtin_ia32_ktestcqi:
16243 case clang::X86::BI__builtin_ia32_ktestchi:
16244 case clang::X86::BI__builtin_ia32_ktestcsi:
16245 case clang::X86::BI__builtin_ia32_ktestcdi: {
16251 return Success((~A & B) == 0, E);
16254 case clang::X86::BI__builtin_ia32_ktestzqi:
16255 case clang::X86::BI__builtin_ia32_ktestzhi:
16256 case clang::X86::BI__builtin_ia32_ktestzsi:
16257 case clang::X86::BI__builtin_ia32_ktestzdi: {
16263 return Success((A & B) == 0, E);
16266 case clang::X86::BI__builtin_ia32_kortestcqi:
16267 case clang::X86::BI__builtin_ia32_kortestchi:
16268 case clang::X86::BI__builtin_ia32_kortestcsi:
16269 case clang::X86::BI__builtin_ia32_kortestcdi: {
16275 return Success(~(A | B) == 0, E);
16278 case clang::X86::BI__builtin_ia32_kortestzqi:
16279 case clang::X86::BI__builtin_ia32_kortestzhi:
16280 case clang::X86::BI__builtin_ia32_kortestzsi:
16281 case clang::X86::BI__builtin_ia32_kortestzdi: {
16287 return Success((A | B) == 0, E);
16290 case clang::X86::BI__builtin_ia32_lzcnt_u16:
16291 case clang::X86::BI__builtin_ia32_lzcnt_u32:
16292 case clang::X86::BI__builtin_ia32_lzcnt_u64: {
16296 return Success(Val.countLeadingZeros(), E);
16299 case clang::X86::BI__builtin_ia32_tzcnt_u16:
16300 case clang::X86::BI__builtin_ia32_tzcnt_u32:
16301 case clang::X86::BI__builtin_ia32_tzcnt_u64: {
16305 return Success(Val.countTrailingZeros(), E);
16308 case clang::X86::BI__builtin_ia32_pdep_si:
16309 case clang::X86::BI__builtin_ia32_pdep_di: {
16315 unsigned BitWidth = Val.getBitWidth();
16317 for (
unsigned I = 0, P = 0; I != BitWidth; ++I)
16319 Result.setBitVal(I, Val[P++]);
16323 case clang::X86::BI__builtin_ia32_pext_si:
16324 case clang::X86::BI__builtin_ia32_pext_di: {
16330 unsigned BitWidth = Val.getBitWidth();
16332 for (
unsigned I = 0, P = 0; I != BitWidth; ++I)
16334 Result.setBitVal(P++, Val[I]);
16337 case X86::BI__builtin_ia32_ptestz128:
16338 case X86::BI__builtin_ia32_ptestz256:
16339 case X86::BI__builtin_ia32_vtestzps:
16340 case X86::BI__builtin_ia32_vtestzps256:
16341 case X86::BI__builtin_ia32_vtestzpd:
16342 case X86::BI__builtin_ia32_vtestzpd256: {
16344 [](
const APInt &A,
const APInt &B) {
return (A & B) == 0; });
16346 case X86::BI__builtin_ia32_ptestc128:
16347 case X86::BI__builtin_ia32_ptestc256:
16348 case X86::BI__builtin_ia32_vtestcps:
16349 case X86::BI__builtin_ia32_vtestcps256:
16350 case X86::BI__builtin_ia32_vtestcpd:
16351 case X86::BI__builtin_ia32_vtestcpd256: {
16353 [](
const APInt &A,
const APInt &B) {
return (~A & B) == 0; });
16355 case X86::BI__builtin_ia32_ptestnzc128:
16356 case X86::BI__builtin_ia32_ptestnzc256:
16357 case X86::BI__builtin_ia32_vtestnzcps:
16358 case X86::BI__builtin_ia32_vtestnzcps256:
16359 case X86::BI__builtin_ia32_vtestnzcpd:
16360 case X86::BI__builtin_ia32_vtestnzcpd256: {
16361 return EvalTestOp([](
const APInt &A,
const APInt &B) {
16362 return ((A & B) != 0) && ((~A & B) != 0);
16365 case X86::BI__builtin_ia32_kandqi:
16366 case X86::BI__builtin_ia32_kandhi:
16367 case X86::BI__builtin_ia32_kandsi:
16368 case X86::BI__builtin_ia32_kanddi: {
16369 return HandleMaskBinOp(
16370 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS & RHS; });
16373 case X86::BI__builtin_ia32_kandnqi:
16374 case X86::BI__builtin_ia32_kandnhi:
16375 case X86::BI__builtin_ia32_kandnsi:
16376 case X86::BI__builtin_ia32_kandndi: {
16377 return HandleMaskBinOp(
16378 [](
const APSInt &LHS,
const APSInt &RHS) {
return ~LHS & RHS; });
16381 case X86::BI__builtin_ia32_korqi:
16382 case X86::BI__builtin_ia32_korhi:
16383 case X86::BI__builtin_ia32_korsi:
16384 case X86::BI__builtin_ia32_kordi: {
16385 return HandleMaskBinOp(
16386 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS | RHS; });
16389 case X86::BI__builtin_ia32_kxnorqi:
16390 case X86::BI__builtin_ia32_kxnorhi:
16391 case X86::BI__builtin_ia32_kxnorsi:
16392 case X86::BI__builtin_ia32_kxnordi: {
16393 return HandleMaskBinOp(
16394 [](
const APSInt &LHS,
const APSInt &RHS) {
return ~(LHS ^ RHS); });
16397 case X86::BI__builtin_ia32_kxorqi:
16398 case X86::BI__builtin_ia32_kxorhi:
16399 case X86::BI__builtin_ia32_kxorsi:
16400 case X86::BI__builtin_ia32_kxordi: {
16401 return HandleMaskBinOp(
16402 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS ^ RHS; });
16405 case X86::BI__builtin_ia32_knotqi:
16406 case X86::BI__builtin_ia32_knothi:
16407 case X86::BI__builtin_ia32_knotsi:
16408 case X86::BI__builtin_ia32_knotdi: {
16416 case X86::BI__builtin_ia32_kaddqi:
16417 case X86::BI__builtin_ia32_kaddhi:
16418 case X86::BI__builtin_ia32_kaddsi:
16419 case X86::BI__builtin_ia32_kadddi: {
16420 return HandleMaskBinOp(
16421 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS + RHS; });
16424 case clang::X86::BI__builtin_ia32_vec_ext_v4hi:
16425 case clang::X86::BI__builtin_ia32_vec_ext_v16qi:
16426 case clang::X86::BI__builtin_ia32_vec_ext_v8hi:
16427 case clang::X86::BI__builtin_ia32_vec_ext_v4si:
16428 case clang::X86::BI__builtin_ia32_vec_ext_v2di:
16429 case clang::X86::BI__builtin_ia32_vec_ext_v32qi:
16430 case clang::X86::BI__builtin_ia32_vec_ext_v16hi:
16431 case clang::X86::BI__builtin_ia32_vec_ext_v8si:
16432 case clang::X86::BI__builtin_ia32_vec_ext_v4di: {
16439 unsigned Idx =
static_cast<unsigned>(IdxAPS.getZExtValue() & (N - 1));
16443 case clang::X86::BI__builtin_ia32_cmpb128_mask:
16444 case clang::X86::BI__builtin_ia32_cmpw128_mask:
16445 case clang::X86::BI__builtin_ia32_cmpd128_mask:
16446 case clang::X86::BI__builtin_ia32_cmpq128_mask:
16447 case clang::X86::BI__builtin_ia32_cmpb256_mask:
16448 case clang::X86::BI__builtin_ia32_cmpw256_mask:
16449 case clang::X86::BI__builtin_ia32_cmpd256_mask:
16450 case clang::X86::BI__builtin_ia32_cmpq256_mask:
16451 case clang::X86::BI__builtin_ia32_cmpb512_mask:
16452 case clang::X86::BI__builtin_ia32_cmpw512_mask:
16453 case clang::X86::BI__builtin_ia32_cmpd512_mask:
16454 case clang::X86::BI__builtin_ia32_cmpq512_mask:
16455 case clang::X86::BI__builtin_ia32_ucmpb128_mask:
16456 case clang::X86::BI__builtin_ia32_ucmpw128_mask:
16457 case clang::X86::BI__builtin_ia32_ucmpd128_mask:
16458 case clang::X86::BI__builtin_ia32_ucmpq128_mask:
16459 case clang::X86::BI__builtin_ia32_ucmpb256_mask:
16460 case clang::X86::BI__builtin_ia32_ucmpw256_mask:
16461 case clang::X86::BI__builtin_ia32_ucmpd256_mask:
16462 case clang::X86::BI__builtin_ia32_ucmpq256_mask:
16463 case clang::X86::BI__builtin_ia32_ucmpb512_mask:
16464 case clang::X86::BI__builtin_ia32_ucmpw512_mask:
16465 case clang::X86::BI__builtin_ia32_ucmpd512_mask:
16466 case clang::X86::BI__builtin_ia32_ucmpq512_mask: {
16470 (BuiltinOp >= clang::X86::BI__builtin_ia32_ucmpb128_mask &&
16471 BuiltinOp <= clang::X86::BI__builtin_ia32_ucmpq512_mask);
16484 unsigned RetWidth = Mask.getBitWidth();
16486 APSInt RetMask(llvm::APInt(RetWidth, 0),
true);
16488 for (
unsigned ElemNum = 0; ElemNum < VectorLen; ++ElemNum) {
16493 switch (
Opcode.getExtValue() & 0x7) {
16498 Result = IsUnsigned ? A.ult(B) : A.slt(B);
16501 Result = IsUnsigned ? A.ule(B) : A.sle(B);
16510 Result = IsUnsigned ? A.uge(B) : A.sge(B);
16513 Result = IsUnsigned ? A.ugt(B) : A.sgt(B);
16520 RetMask.setBitVal(ElemNum, Mask[ElemNum] &&
Result);
16531 const LValue &LV) {
16534 if (!LV.getLValueBase())
16539 if (!LV.getLValueDesignator().Invalid &&
16540 !LV.getLValueDesignator().isOnePastTheEnd())
16550 if (LV.getLValueDesignator().Invalid)
16556 return LV.getLValueOffset() == Size;
16566class DataRecursiveIntBinOpEvaluator {
16567 struct EvalResult {
16569 bool Failed =
false;
16571 EvalResult() =
default;
16573 void swap(EvalResult &RHS) {
16575 Failed = RHS.Failed;
16576 RHS.Failed =
false;
16582 EvalResult LHSResult;
16583 enum { AnyExprKind, BinOpKind, BinOpVisitedLHSKind }
Kind;
16586 Job(Job &&) =
default;
16588 void startSpeculativeEval(EvalInfo &Info) {
16589 SpecEvalRAII = SpeculativeEvaluationRAII(Info);
16593 SpeculativeEvaluationRAII SpecEvalRAII;
16596 SmallVector<Job, 16> Queue;
16598 IntExprEvaluator &IntEval;
16603 DataRecursiveIntBinOpEvaluator(IntExprEvaluator &IntEval,
APValue &
Result)
16604 : IntEval(IntEval), Info(IntEval.getEvalInfo()), FinalResult(
Result) { }
16610 static bool shouldEnqueue(
const BinaryOperator *E) {
16617 bool Traverse(
const BinaryOperator *E) {
16619 EvalResult PrevResult;
16620 while (!Queue.empty())
16621 process(PrevResult);
16623 if (PrevResult.Failed)
return false;
16625 FinalResult.
swap(PrevResult.Val);
16636 bool Error(
const Expr *E) {
16637 return IntEval.Error(E);
16640 return IntEval.Error(E, D);
16643 OptionalDiagnostic CCEDiag(
const Expr *E,
diag::kind D) {
16644 return Info.CCEDiag(E, D);
16648 bool VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
16649 bool &SuppressRHSDiags);
16651 bool VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
16654 void EvaluateExpr(
const Expr *E, EvalResult &
Result) {
16660 void process(EvalResult &
Result);
16662 void enqueue(
const Expr *E) {
16664 Queue.resize(Queue.size()+1);
16665 Queue.back().E = E;
16666 Queue.back().Kind = Job::AnyExprKind;
16672bool DataRecursiveIntBinOpEvaluator::
16673 VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
16674 bool &SuppressRHSDiags) {
16677 if (LHSResult.Failed)
16678 return Info.noteSideEffect();
16687 if (LHSAsBool == (E->
getOpcode() == BO_LOr)) {
16688 Success(LHSAsBool, E, LHSResult.Val);
16692 LHSResult.Failed =
true;
16696 if (!Info.noteSideEffect())
16702 SuppressRHSDiags =
true;
16711 if (LHSResult.Failed && !Info.noteFailure())
16722 assert(!LVal.
hasLValuePath() &&
"have designator for integer lvalue");
16724 uint64_t Offset64 = Offset.getQuantity();
16725 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
16727 : Offset64 + Index64);
16730bool DataRecursiveIntBinOpEvaluator::
16731 VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
16734 if (RHSResult.Failed)
16741 bool lhsResult, rhsResult;
16756 if (rhsResult == (E->
getOpcode() == BO_LOr))
16767 if (LHSResult.Failed || RHSResult.Failed)
16770 const APValue &LHSVal = LHSResult.Val;
16771 const APValue &RHSVal = RHSResult.Val;
16795 if (!LHSExpr || !RHSExpr)
16797 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
16798 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
16799 if (!LHSAddrExpr || !RHSAddrExpr)
16824void DataRecursiveIntBinOpEvaluator::process(EvalResult &
Result) {
16825 Job &job = Queue.back();
16827 switch (job.Kind) {
16828 case Job::AnyExprKind: {
16829 if (
const BinaryOperator *Bop = dyn_cast<BinaryOperator>(job.E)) {
16830 if (shouldEnqueue(Bop)) {
16831 job.Kind = Job::BinOpKind;
16832 enqueue(Bop->getLHS());
16837 EvaluateExpr(job.E,
Result);
16842 case Job::BinOpKind: {
16844 bool SuppressRHSDiags =
false;
16845 if (!VisitBinOpLHSOnly(
Result, Bop, SuppressRHSDiags)) {
16849 if (SuppressRHSDiags)
16850 job.startSpeculativeEval(Info);
16851 job.LHSResult.swap(
Result);
16852 job.Kind = Job::BinOpVisitedLHSKind;
16857 case Job::BinOpVisitedLHSKind: {
16861 Result.Failed = !VisitBinOp(job.LHSResult, RHS, Bop,
Result.Val);
16867 llvm_unreachable(
"Invalid Job::Kind!");
16871enum class CmpResult {
16880template <
class SuccessCB,
class AfterCB>
16883 SuccessCB &&
Success, AfterCB &&DoAfter) {
16888 "unsupported binary expression evaluation");
16890 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
16904 if (!LHSOK && !Info.noteFailure())
16909 return Success(CmpResult::Less, E);
16911 return Success(CmpResult::Greater, E);
16912 return Success(CmpResult::Equal, E);
16920 if (!LHSOK && !Info.noteFailure())
16925 return Success(CmpResult::Less, E);
16927 return Success(CmpResult::Greater, E);
16928 return Success(CmpResult::Equal, E);
16932 ComplexValue LHS, RHS;
16941 LHS.makeComplexFloat();
16942 LHS.FloatImag = APFloat(LHS.FloatReal.getSemantics());
16947 if (!LHSOK && !Info.noteFailure())
16953 RHS.makeComplexFloat();
16954 RHS.FloatImag = APFloat(RHS.FloatReal.getSemantics());
16958 if (LHS.isComplexFloat()) {
16959 APFloat::cmpResult CR_r =
16960 LHS.getComplexFloatReal().compare(RHS.getComplexFloatReal());
16961 APFloat::cmpResult CR_i =
16962 LHS.getComplexFloatImag().compare(RHS.getComplexFloatImag());
16963 bool IsEqual = CR_r == APFloat::cmpEqual && CR_i == APFloat::cmpEqual;
16964 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal, E);
16966 assert(IsEquality &&
"invalid complex comparison");
16967 bool IsEqual = LHS.getComplexIntReal() == RHS.getComplexIntReal() &&
16968 LHS.getComplexIntImag() == RHS.getComplexIntImag();
16969 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal, E);
16975 APFloat RHS(0.0), LHS(0.0);
16978 if (!LHSOK && !Info.noteFailure())
16985 llvm::APFloatBase::cmpResult APFloatCmpResult = LHS.compare(RHS);
16986 if (!Info.InConstantContext &&
16987 APFloatCmpResult == APFloat::cmpUnordered &&
16990 Info.FFDiag(E, diag::note_constexpr_float_arithmetic_strict);
16993 auto GetCmpRes = [&]() {
16994 switch (APFloatCmpResult) {
16995 case APFloat::cmpEqual:
16996 return CmpResult::Equal;
16997 case APFloat::cmpLessThan:
16998 return CmpResult::Less;
16999 case APFloat::cmpGreaterThan:
17000 return CmpResult::Greater;
17001 case APFloat::cmpUnordered:
17002 return CmpResult::Unordered;
17004 llvm_unreachable(
"Unrecognised APFloat::cmpResult enum");
17006 return Success(GetCmpRes(), E);
17010 LValue LHSValue, RHSValue;
17013 if (!LHSOK && !Info.noteFailure())
17024 if (Info.checkingPotentialConstantExpression() &&
17025 (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown))
17027 auto DiagComparison = [&] (
unsigned DiagID,
bool Reversed =
false) {
17028 std::string LHS = LHSValue.toString(Info.Ctx, E->
getLHS()->
getType());
17029 std::string RHS = RHSValue.toString(Info.Ctx, E->
getRHS()->
getType());
17030 Info.FFDiag(E, DiagID)
17037 return DiagComparison(
17038 diag::note_constexpr_pointer_comparison_unspecified);
17044 if ((!LHSValue.Base && !LHSValue.Offset.
isZero()) ||
17045 (!RHSValue.Base && !RHSValue.Offset.
isZero()))
17046 return DiagComparison(diag::note_constexpr_pointer_constant_comparison,
17060 return DiagComparison(diag::note_constexpr_literal_comparison);
17062 return DiagComparison(diag::note_constexpr_opaque_call_comparison,
17067 return DiagComparison(diag::note_constexpr_pointer_weak_comparison,
17071 if (LHSValue.Base && LHSValue.Offset.
isZero() &&
17073 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
17075 if (RHSValue.Base && RHSValue.Offset.
isZero() &&
17077 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
17083 return DiagComparison(
17084 diag::note_constexpr_pointer_comparison_zero_sized);
17085 if (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown)
17086 return DiagComparison(
17087 diag::note_constexpr_pointer_comparison_unspecified);
17089 return Success(CmpResult::Unequal, E);
17092 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
17093 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
17095 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
17096 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
17106 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid && IsRelational) {
17107 bool WasArrayIndex;
17110 :
getType(LHSValue.Base).getNonReferenceType(),
17111 LHSDesignator, RHSDesignator, WasArrayIndex);
17118 if (!WasArrayIndex && Mismatch < LHSDesignator.Entries.size() &&
17119 Mismatch < RHSDesignator.Entries.size()) {
17120 const FieldDecl *LF = getAsField(LHSDesignator.Entries[Mismatch]);
17121 const FieldDecl *RF = getAsField(RHSDesignator.Entries[Mismatch]);
17123 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_classes);
17125 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
17126 << getAsBaseClass(LHSDesignator.Entries[Mismatch])
17129 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
17130 << getAsBaseClass(RHSDesignator.Entries[Mismatch])
17135 diag::note_constexpr_pointer_comparison_differing_access)
17146 assert(PtrSize <= 64 &&
"Unexpected pointer width");
17147 uint64_t Mask = ~0ULL >> (64 - PtrSize);
17148 CompareLHS &= Mask;
17149 CompareRHS &= Mask;
17154 if (!LHSValue.Base.
isNull() && IsRelational) {
17159 uint64_t OffsetLimit = Size.getQuantity();
17160 if (CompareLHS > OffsetLimit || CompareRHS > OffsetLimit)
17164 if (CompareLHS < CompareRHS)
17165 return Success(CmpResult::Less, E);
17166 if (CompareLHS > CompareRHS)
17167 return Success(CmpResult::Greater, E);
17168 return Success(CmpResult::Equal, E);
17172 assert(IsEquality &&
"unexpected member pointer operation");
17175 MemberPtr LHSValue, RHSValue;
17178 if (!LHSOK && !Info.noteFailure())
17186 if (LHSValue.getDecl() && LHSValue.getDecl()->isWeak()) {
17187 Info.FFDiag(E, diag::note_constexpr_mem_pointer_weak_comparison)
17188 << LHSValue.getDecl();
17191 if (RHSValue.getDecl() && RHSValue.getDecl()->isWeak()) {
17192 Info.FFDiag(E, diag::note_constexpr_mem_pointer_weak_comparison)
17193 << RHSValue.getDecl();
17200 if (!LHSValue.getDecl() || !RHSValue.getDecl()) {
17201 bool Equal = !LHSValue.getDecl() && !RHSValue.getDecl();
17202 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal, E);
17207 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(LHSValue.getDecl()))
17208 if (MD->isVirtual())
17209 Info.CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
17210 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(RHSValue.getDecl()))
17211 if (MD->isVirtual())
17212 Info.CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
17218 bool Equal = LHSValue == RHSValue;
17219 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal, E);
17224 assert(RHSTy->
isNullPtrType() &&
"missing pointer conversion");
17232 return Success(CmpResult::Equal, E);
17238bool RecordExprEvaluator::VisitBinCmp(
const BinaryOperator *E) {
17242 auto OnSuccess = [&](CmpResult CR,
const BinaryOperator *E) {
17245 case CmpResult::Unequal:
17246 llvm_unreachable(
"should never produce Unequal for three-way comparison");
17247 case CmpResult::Less:
17248 CCR = ComparisonCategoryResult::Less;
17250 case CmpResult::Equal:
17251 CCR = ComparisonCategoryResult::Equal;
17253 case CmpResult::Greater:
17254 CCR = ComparisonCategoryResult::Greater;
17256 case CmpResult::Unordered:
17257 CCR = ComparisonCategoryResult::Unordered;
17262 const ComparisonCategoryInfo &CmpInfo =
17271 ConstantExprKind::Normal);
17274 return ExprEvaluatorBaseTy::VisitBinCmp(E);
17278bool RecordExprEvaluator::VisitCXXParenListInitExpr(
17279 const CXXParenListInitExpr *E) {
17280 return VisitCXXParenListOrInitListExpr(E, E->
getInitExprs());
17283bool IntExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
17288 if (!Info.noteFailure())
17292 if (DataRecursiveIntBinOpEvaluator::shouldEnqueue(E))
17293 return DataRecursiveIntBinOpEvaluator(*
this,
Result).Traverse(E);
17297 "DataRecursiveIntBinOpEvaluator should have handled integral types");
17302 auto OnSuccess = [&](CmpResult CR,
const BinaryOperator *E) {
17303 assert((CR != CmpResult::Unequal || E->
isEqualityOp()) &&
17304 "should only produce Unequal for equality comparisons");
17305 bool IsEqual = CR == CmpResult::Equal,
17306 IsLess = CR == CmpResult::Less,
17307 IsGreater = CR == CmpResult::Greater;
17311 llvm_unreachable(
"unsupported binary operator");
17314 return Success(IsEqual == (Op == BO_EQ), E);
17318 return Success(IsGreater, E);
17320 return Success(IsEqual || IsLess, E);
17322 return Success(IsEqual || IsGreater, E);
17326 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
17335 LValue LHSValue, RHSValue;
17338 if (!LHSOK && !Info.noteFailure())
17347 if (Info.checkingPotentialConstantExpression() &&
17348 (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown))
17351 const Expr *LHSExpr = LHSValue.Base.
dyn_cast<
const Expr *>();
17352 const Expr *RHSExpr = RHSValue.Base.
dyn_cast<
const Expr *>();
17354 auto DiagArith = [&](
unsigned DiagID) {
17355 std::string LHS = LHSValue.toString(Info.Ctx, E->
getLHS()->
getType());
17356 std::string RHS = RHSValue.toString(Info.Ctx, E->
getRHS()->
getType());
17357 Info.FFDiag(E, DiagID) << LHS << RHS;
17358 if (LHSExpr && LHSExpr == RHSExpr)
17360 diag::note_constexpr_repeated_literal_eval)
17365 if (!LHSExpr || !RHSExpr)
17366 return DiagArith(diag::note_constexpr_pointer_arith_unspecified);
17369 return DiagArith(diag::note_constexpr_literal_arith);
17371 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
17372 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
17373 if (!LHSAddrExpr || !RHSAddrExpr)
17381 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
17382 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
17384 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
17385 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
17391 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid &&
17394 Info.CCEDiag(E, diag::note_constexpr_pointer_subtraction_not_same_array);
17399 CharUnits ElementSize;
17406 if (ElementSize.
isZero()) {
17407 Info.FFDiag(E, diag::note_constexpr_pointer_subtraction_zero_size)
17424 APSInt TrueResult = (LHS - RHS) / ElemSize;
17427 if (
Result.extend(65) != TrueResult &&
17433 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
17438bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr(
17439 const UnaryExprOrTypeTraitExpr *E) {
17441 case UETT_PreferredAlignOf:
17442 case UETT_AlignOf: {
17451 case UETT_PtrAuthTypeDiscriminator: {
17457 case UETT_VecStep: {
17461 unsigned n = Ty->
castAs<VectorType>()->getNumElements();
17473 case UETT_DataSizeOf:
17474 case UETT_SizeOf: {
17478 if (
const ReferenceType *Ref = SrcTy->
getAs<ReferenceType>())
17489 case UETT_OpenMPRequiredSimdAlign:
17496 case UETT_VectorElements: {
17500 if (
const auto *VT = Ty->
getAs<VectorType>())
17504 if (Info.InConstantContext)
17505 Info.CCEDiag(E, diag::note_constexpr_non_const_vectorelements)
17510 case UETT_CountOf: {
17516 if (
const auto *CAT =
17528 if (VAT->getElementType()->isArrayType()) {
17531 if (!VAT->getSizeExpr()) {
17536 std::optional<APSInt> Res =
17537 VAT->getSizeExpr()->getIntegerConstantExpr(Info.Ctx);
17543 Res->getZExtValue()};
17555 llvm_unreachable(
"unknown expr/type trait");
17558bool IntExprEvaluator::VisitOffsetOfExpr(
const OffsetOfExpr *OOE) {
17564 for (
unsigned i = 0; i != n; ++i) {
17577 Result += IdxResult.getSExtValue() * ElementSize;
17582 FieldDecl *MemberDecl = ON.
getField();
17589 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
17596 llvm_unreachable(
"dependent __builtin_offsetof");
17599 CXXBaseSpecifier *BaseSpec = ON.
getBase();
17611 CurrentType = BaseSpec->
getType();
17625bool IntExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
17644 if (Info.checkingForUndefinedBehavior())
17646 diag::warn_integer_constant_overflow)
17674bool IntExprEvaluator::VisitCastExpr(
const CastExpr *E) {
17676 QualType DestType = E->
getType();
17677 QualType SrcType = SubExpr->
getType();
17680 case CK_BaseToDerived:
17681 case CK_DerivedToBase:
17682 case CK_UncheckedDerivedToBase:
17685 case CK_ArrayToPointerDecay:
17686 case CK_FunctionToPointerDecay:
17687 case CK_NullToPointer:
17688 case CK_NullToMemberPointer:
17689 case CK_BaseToDerivedMemberPointer:
17690 case CK_DerivedToBaseMemberPointer:
17691 case CK_ReinterpretMemberPointer:
17692 case CK_ConstructorConversion:
17693 case CK_IntegralToPointer:
17695 case CK_VectorSplat:
17696 case CK_IntegralToFloating:
17697 case CK_FloatingCast:
17698 case CK_CPointerToObjCPointerCast:
17699 case CK_BlockPointerToObjCPointerCast:
17700 case CK_AnyPointerToBlockPointerCast:
17701 case CK_ObjCObjectLValueCast:
17702 case CK_FloatingRealToComplex:
17703 case CK_FloatingComplexToReal:
17704 case CK_FloatingComplexCast:
17705 case CK_FloatingComplexToIntegralComplex:
17706 case CK_IntegralRealToComplex:
17707 case CK_IntegralComplexCast:
17708 case CK_IntegralComplexToFloatingComplex:
17709 case CK_BuiltinFnToFnPtr:
17710 case CK_ZeroToOCLOpaqueType:
17711 case CK_NonAtomicToAtomic:
17712 case CK_AddressSpaceConversion:
17713 case CK_IntToOCLSampler:
17714 case CK_FloatingToFixedPoint:
17715 case CK_FixedPointToFloating:
17716 case CK_FixedPointCast:
17717 case CK_IntegralToFixedPoint:
17718 case CK_MatrixCast:
17719 case CK_HLSLAggregateSplatCast:
17720 llvm_unreachable(
"invalid cast kind for integral value");
17724 case CK_LValueBitCast:
17725 case CK_ARCProduceObject:
17726 case CK_ARCConsumeObject:
17727 case CK_ARCReclaimReturnedObject:
17728 case CK_ARCExtendBlockObject:
17729 case CK_CopyAndAutoreleaseBlockObject:
17732 case CK_UserDefinedConversion:
17733 case CK_LValueToRValue:
17734 case CK_AtomicToNonAtomic:
17736 case CK_LValueToRValueBitCast:
17737 case CK_HLSLArrayRValue:
17738 return ExprEvaluatorBaseTy::VisitCastExpr(E);
17740 case CK_MemberPointerToBoolean:
17741 case CK_PointerToBoolean:
17742 case CK_IntegralToBoolean:
17743 case CK_FloatingToBoolean:
17744 case CK_BooleanToSignedIntegral:
17745 case CK_FloatingComplexToBoolean:
17746 case CK_IntegralComplexToBoolean: {
17751 if (BoolResult && E->
getCastKind() == CK_BooleanToSignedIntegral)
17753 return Success(IntResult, E);
17756 case CK_FixedPointToIntegral: {
17761 llvm::APSInt
Result = Src.convertToInt(
17769 case CK_FixedPointToBoolean: {
17772 if (!
Evaluate(Val, Info, SubExpr))
17777 case CK_IntegralCast: {
17778 if (!Visit(SubExpr))
17787 if (
Result.isAddrLabelDiff())
17805 if (!ED->isFixed()) {
17809 ED->getValueRange(
Max,
Min);
17812 if (ED->getNumNegativeBits() &&
17813 (
Max.slt(
Result.getInt().getSExtValue()) ||
17814 Min.sgt(
Result.getInt().getSExtValue())))
17815 Info.CCEDiag(E, diag::note_constexpr_unscoped_enum_out_of_range)
17816 << llvm::toString(
Result.getInt(), 10) <<
Min.getSExtValue()
17817 <<
Max.getSExtValue() << ED;
17818 else if (!ED->getNumNegativeBits() &&
17819 Max.ult(
Result.getInt().getZExtValue()))
17820 Info.CCEDiag(E, diag::note_constexpr_unscoped_enum_out_of_range)
17821 << llvm::toString(
Result.getInt(), 10) <<
Min.getZExtValue()
17822 <<
Max.getZExtValue() << ED;
17830 case CK_PointerToIntegral: {
17831 CCEDiag(E, diag::note_constexpr_invalid_cast)
17832 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
17839 if (LV.getLValueBase()) {
17847 LV.Designator.setInvalid();
17855 if (!
V.toIntegralConstant(AsInt, SrcType, Info.Ctx))
17856 llvm_unreachable(
"Can't cast this!");
17861 case CK_IntegralComplexToReal: {
17865 return Success(
C.getComplexIntReal(), E);
17868 case CK_FloatingToIntegral: {
17878 case CK_HLSLVectorTruncation: {
17884 case CK_HLSLElementwiseCast: {
17897 return Success(ResultVal, E);
17901 llvm_unreachable(
"unknown cast resulting in integral value");
17904bool IntExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
17909 if (!LV.isComplexInt())
17911 return Success(LV.getComplexIntReal(), E);
17917bool IntExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
17922 if (!LV.isComplexInt())
17924 return Success(LV.getComplexIntImag(), E);
17931bool IntExprEvaluator::VisitSizeOfPackExpr(
const SizeOfPackExpr *E) {
17935bool IntExprEvaluator::VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E) {
17939bool IntExprEvaluator::VisitConceptSpecializationExpr(
17940 const ConceptSpecializationExpr *E) {
17944bool IntExprEvaluator::VisitRequiresExpr(
const RequiresExpr *E) {
17948bool FixedPointExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
17958 if (!
Result.isFixedPoint())
17961 APFixedPoint Negated =
Result.getFixedPoint().negate(&Overflowed);
17975bool FixedPointExprEvaluator::VisitCastExpr(
const CastExpr *E) {
17977 QualType DestType = E->
getType();
17979 "Expected destination type to be a fixed point type");
17983 case CK_FixedPointCast: {
17988 APFixedPoint
Result = Src.convert(DestFXSema, &Overflowed);
17990 if (Info.checkingForUndefinedBehavior())
17992 diag::warn_fixedpoint_constant_overflow)
17999 case CK_IntegralToFixedPoint: {
18005 APFixedPoint IntResult = APFixedPoint::getFromIntValue(
18009 if (Info.checkingForUndefinedBehavior())
18011 diag::warn_fixedpoint_constant_overflow)
18012 << IntResult.toString() << E->
getType();
18017 return Success(IntResult, E);
18019 case CK_FloatingToFixedPoint: {
18025 APFixedPoint
Result = APFixedPoint::getFromFloatValue(
18029 if (Info.checkingForUndefinedBehavior())
18031 diag::warn_fixedpoint_constant_overflow)
18040 case CK_LValueToRValue:
18041 return ExprEvaluatorBaseTy::VisitCastExpr(E);
18047bool FixedPointExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
18049 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
18051 const Expr *LHS = E->
getLHS();
18052 const Expr *RHS = E->
getRHS();
18063 bool OpOverflow =
false, ConversionOverflow =
false;
18064 APFixedPoint
Result(LHSFX.getSemantics());
18067 Result = LHSFX.add(RHSFX, &OpOverflow)
18068 .convert(ResultFXSema, &ConversionOverflow);
18072 Result = LHSFX.sub(RHSFX, &OpOverflow)
18073 .convert(ResultFXSema, &ConversionOverflow);
18077 Result = LHSFX.mul(RHSFX, &OpOverflow)
18078 .convert(ResultFXSema, &ConversionOverflow);
18082 if (RHSFX.getValue() == 0) {
18083 Info.FFDiag(E, diag::note_expr_divide_by_zero);
18086 Result = LHSFX.div(RHSFX, &OpOverflow)
18087 .convert(ResultFXSema, &ConversionOverflow);
18093 llvm::APSInt RHSVal = RHSFX.getValue();
18096 LHSSema.getWidth() - (unsigned)LHSSema.hasUnsignedPadding();
18097 unsigned Amt = RHSVal.getLimitedValue(ShiftBW - 1);
18101 if (RHSVal.isNegative())
18102 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHSVal;
18103 else if (Amt != RHSVal)
18104 Info.CCEDiag(E, diag::note_constexpr_large_shift)
18105 << RHSVal << E->
getType() << ShiftBW;
18108 Result = LHSFX.shl(Amt, &OpOverflow);
18110 Result = LHSFX.shr(Amt, &OpOverflow);
18116 if (OpOverflow || ConversionOverflow) {
18117 if (Info.checkingForUndefinedBehavior())
18119 diag::warn_fixedpoint_constant_overflow)
18132class FloatExprEvaluator
18133 :
public ExprEvaluatorBase<FloatExprEvaluator> {
18136 FloatExprEvaluator(EvalInfo &info, APFloat &result)
18137 : ExprEvaluatorBaseTy(info),
Result(result) {}
18144 bool ZeroInitialization(
const Expr *E) {
18149 bool VisitCallExpr(
const CallExpr *E);
18151 bool VisitUnaryOperator(
const UnaryOperator *E);
18152 bool VisitBinaryOperator(
const BinaryOperator *E);
18153 bool VisitFloatingLiteral(
const FloatingLiteral *E);
18154 bool VisitCastExpr(
const CastExpr *E);
18156 bool VisitUnaryReal(
const UnaryOperator *E);
18157 bool VisitUnaryImag(
const UnaryOperator *E);
18166 return FloatExprEvaluator(Info, Result).Visit(E);
18173 llvm::APFloat &Result) {
18175 if (!S)
return false;
18177 const llvm::fltSemantics &Sem = Context.getFloatTypeSemantics(ResultTy);
18183 fill = llvm::APInt(32, 0);
18184 else if (S->
getString().getAsInteger(0, fill))
18187 if (Context.getTargetInfo().isNan2008()) {
18189 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
18191 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
18199 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
18201 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
18207bool FloatExprEvaluator::VisitCallExpr(
const CallExpr *E) {
18208 if (!IsConstantEvaluatedBuiltinCall(E))
18209 return ExprEvaluatorBaseTy::VisitCallExpr(E);
18215 case Builtin::BI__builtin_huge_val:
18216 case Builtin::BI__builtin_huge_valf:
18217 case Builtin::BI__builtin_huge_vall:
18218 case Builtin::BI__builtin_huge_valf16:
18219 case Builtin::BI__builtin_huge_valf128:
18220 case Builtin::BI__builtin_inf:
18221 case Builtin::BI__builtin_inff:
18222 case Builtin::BI__builtin_infl:
18223 case Builtin::BI__builtin_inff16:
18224 case Builtin::BI__builtin_inff128: {
18225 const llvm::fltSemantics &Sem =
18227 Result = llvm::APFloat::getInf(Sem);
18231 case Builtin::BI__builtin_nans:
18232 case Builtin::BI__builtin_nansf:
18233 case Builtin::BI__builtin_nansl:
18234 case Builtin::BI__builtin_nansf16:
18235 case Builtin::BI__builtin_nansf128:
18241 case Builtin::BI__builtin_nan:
18242 case Builtin::BI__builtin_nanf:
18243 case Builtin::BI__builtin_nanl:
18244 case Builtin::BI__builtin_nanf16:
18245 case Builtin::BI__builtin_nanf128:
18253 case Builtin::BI__builtin_elementwise_abs:
18254 case Builtin::BI__builtin_fabs:
18255 case Builtin::BI__builtin_fabsf:
18256 case Builtin::BI__builtin_fabsl:
18257 case Builtin::BI__builtin_fabsf128:
18266 if (
Result.isNegative())
18270 case Builtin::BI__arithmetic_fence:
18277 case Builtin::BI__builtin_copysign:
18278 case Builtin::BI__builtin_copysignf:
18279 case Builtin::BI__builtin_copysignl:
18280 case Builtin::BI__builtin_copysignf128: {
18289 case Builtin::BI__builtin_fmax:
18290 case Builtin::BI__builtin_fmaxf:
18291 case Builtin::BI__builtin_fmaxl:
18292 case Builtin::BI__builtin_fmaxf16:
18293 case Builtin::BI__builtin_fmaxf128: {
18302 case Builtin::BI__builtin_fmin:
18303 case Builtin::BI__builtin_fminf:
18304 case Builtin::BI__builtin_fminl:
18305 case Builtin::BI__builtin_fminf16:
18306 case Builtin::BI__builtin_fminf128: {
18315 case Builtin::BI__builtin_fmaximum_num:
18316 case Builtin::BI__builtin_fmaximum_numf:
18317 case Builtin::BI__builtin_fmaximum_numl:
18318 case Builtin::BI__builtin_fmaximum_numf16:
18319 case Builtin::BI__builtin_fmaximum_numf128: {
18328 case Builtin::BI__builtin_fminimum_num:
18329 case Builtin::BI__builtin_fminimum_numf:
18330 case Builtin::BI__builtin_fminimum_numl:
18331 case Builtin::BI__builtin_fminimum_numf16:
18332 case Builtin::BI__builtin_fminimum_numf128: {
18341 case Builtin::BI__builtin_elementwise_fma: {
18346 APFloat SourceY(0.), SourceZ(0.);
18352 (void)
Result.fusedMultiplyAdd(SourceY, SourceZ, RM);
18356 case clang::X86::BI__builtin_ia32_vec_ext_v4sf: {
18363 unsigned Idx =
static_cast<unsigned>(IdxAPS.getZExtValue() & (N - 1));
18369bool FloatExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
18381bool FloatExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
18392 Result = llvm::APFloat::getZero(Sem);
18396bool FloatExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
18398 default:
return Error(E);
18412bool FloatExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
18414 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
18418 if (!LHSOK && !Info.noteFailure())
18424bool FloatExprEvaluator::VisitFloatingLiteral(
const FloatingLiteral *E) {
18429bool FloatExprEvaluator::VisitCastExpr(
const CastExpr *E) {
18434 return ExprEvaluatorBaseTy::VisitCastExpr(E);
18436 case CK_HLSLAggregateSplatCast:
18437 llvm_unreachable(
"invalid cast kind for floating value");
18439 case CK_IntegralToFloating: {
18448 case CK_FixedPointToFloating: {
18457 case CK_FloatingCast: {
18458 if (!Visit(SubExpr))
18464 case CK_FloatingComplexToReal: {
18468 Result =
V.getComplexFloatReal();
18471 case CK_HLSLVectorTruncation: {
18477 case CK_HLSLElementwiseCast: {
18492 return Success(ResultVal, E);
18502class ComplexExprEvaluator
18503 :
public ExprEvaluatorBase<ComplexExprEvaluator> {
18507 ComplexExprEvaluator(EvalInfo &info, ComplexValue &
Result)
18515 bool ZeroInitialization(
const Expr *E);
18521 bool VisitImaginaryLiteral(
const ImaginaryLiteral *E);
18522 bool VisitCastExpr(
const CastExpr *E);
18523 bool VisitBinaryOperator(
const BinaryOperator *E);
18524 bool VisitUnaryOperator(
const UnaryOperator *E);
18525 bool VisitInitListExpr(
const InitListExpr *E);
18526 bool VisitCallExpr(
const CallExpr *E);
18534 return ComplexExprEvaluator(Info, Result).Visit(E);
18537bool ComplexExprEvaluator::ZeroInitialization(
const Expr *E) {
18538 QualType ElemTy = E->
getType()->
castAs<ComplexType>()->getElementType();
18540 Result.makeComplexFloat();
18545 Result.makeComplexInt();
18553bool ComplexExprEvaluator::VisitImaginaryLiteral(
const ImaginaryLiteral *E) {
18557 Result.makeComplexFloat();
18566 "Unexpected imaginary literal.");
18568 Result.makeComplexInt();
18573 Result.IntReal =
APSInt(Imag.getBitWidth(), !Imag.isSigned());
18578bool ComplexExprEvaluator::VisitCastExpr(
const CastExpr *E) {
18582 case CK_BaseToDerived:
18583 case CK_DerivedToBase:
18584 case CK_UncheckedDerivedToBase:
18587 case CK_ArrayToPointerDecay:
18588 case CK_FunctionToPointerDecay:
18589 case CK_NullToPointer:
18590 case CK_NullToMemberPointer:
18591 case CK_BaseToDerivedMemberPointer:
18592 case CK_DerivedToBaseMemberPointer:
18593 case CK_MemberPointerToBoolean:
18594 case CK_ReinterpretMemberPointer:
18595 case CK_ConstructorConversion:
18596 case CK_IntegralToPointer:
18597 case CK_PointerToIntegral:
18598 case CK_PointerToBoolean:
18600 case CK_VectorSplat:
18601 case CK_IntegralCast:
18602 case CK_BooleanToSignedIntegral:
18603 case CK_IntegralToBoolean:
18604 case CK_IntegralToFloating:
18605 case CK_FloatingToIntegral:
18606 case CK_FloatingToBoolean:
18607 case CK_FloatingCast:
18608 case CK_CPointerToObjCPointerCast:
18609 case CK_BlockPointerToObjCPointerCast:
18610 case CK_AnyPointerToBlockPointerCast:
18611 case CK_ObjCObjectLValueCast:
18612 case CK_FloatingComplexToReal:
18613 case CK_FloatingComplexToBoolean:
18614 case CK_IntegralComplexToReal:
18615 case CK_IntegralComplexToBoolean:
18616 case CK_ARCProduceObject:
18617 case CK_ARCConsumeObject:
18618 case CK_ARCReclaimReturnedObject:
18619 case CK_ARCExtendBlockObject:
18620 case CK_CopyAndAutoreleaseBlockObject:
18621 case CK_BuiltinFnToFnPtr:
18622 case CK_ZeroToOCLOpaqueType:
18623 case CK_NonAtomicToAtomic:
18624 case CK_AddressSpaceConversion:
18625 case CK_IntToOCLSampler:
18626 case CK_FloatingToFixedPoint:
18627 case CK_FixedPointToFloating:
18628 case CK_FixedPointCast:
18629 case CK_FixedPointToBoolean:
18630 case CK_FixedPointToIntegral:
18631 case CK_IntegralToFixedPoint:
18632 case CK_MatrixCast:
18633 case CK_HLSLVectorTruncation:
18634 case CK_HLSLElementwiseCast:
18635 case CK_HLSLAggregateSplatCast:
18636 llvm_unreachable(
"invalid cast kind for complex value");
18638 case CK_LValueToRValue:
18639 case CK_AtomicToNonAtomic:
18641 case CK_LValueToRValueBitCast:
18642 case CK_HLSLArrayRValue:
18643 return ExprEvaluatorBaseTy::VisitCastExpr(E);
18646 case CK_LValueBitCast:
18647 case CK_UserDefinedConversion:
18650 case CK_FloatingRealToComplex: {
18655 Result.makeComplexFloat();
18660 case CK_FloatingComplexCast: {
18664 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
18672 case CK_FloatingComplexToIntegralComplex: {
18676 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
18679 Result.makeComplexInt();
18686 case CK_IntegralRealToComplex: {
18691 Result.makeComplexInt();
18692 Result.IntImag =
APSInt(Real.getBitWidth(), !Real.isSigned());
18696 case CK_IntegralComplexCast: {
18700 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
18709 case CK_IntegralComplexToFloatingComplex: {
18715 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
18718 Result.makeComplexFloat();
18720 To,
Result.FloatReal) &&
18726 llvm_unreachable(
"unknown cast resulting in complex value");
18730 APFloat &ResR, APFloat &ResI) {
18736 APFloat AC = A *
C;
18737 APFloat BD = B * D;
18738 APFloat AD = A * D;
18739 APFloat BC = B *
C;
18742 if (ResR.isNaN() && ResI.isNaN()) {
18743 bool Recalc =
false;
18744 if (A.isInfinity() || B.isInfinity()) {
18745 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
18747 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
18750 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
18752 D = APFloat::copySign(APFloat(D.getSemantics()), D);
18755 if (
C.isInfinity() || D.isInfinity()) {
18756 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
18758 D = APFloat::copySign(APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0),
18761 A = APFloat::copySign(APFloat(A.getSemantics()), A);
18763 B = APFloat::copySign(APFloat(B.getSemantics()), B);
18766 if (!Recalc && (AC.isInfinity() || BD.isInfinity() || AD.isInfinity() ||
18767 BC.isInfinity())) {
18769 A = APFloat::copySign(APFloat(A.getSemantics()), A);
18771 B = APFloat::copySign(APFloat(B.getSemantics()), B);
18773 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
18775 D = APFloat::copySign(APFloat(D.getSemantics()), D);
18779 ResR = APFloat::getInf(A.getSemantics()) * (A *
C - B * D);
18780 ResI = APFloat::getInf(A.getSemantics()) * (A * D + B *
C);
18786 APFloat &ResR, APFloat &ResI) {
18793 APFloat MaxCD = maxnum(
abs(
C),
abs(D));
18794 if (MaxCD.isFinite()) {
18795 DenomLogB =
ilogb(MaxCD);
18796 C =
scalbn(
C, -DenomLogB, APFloat::rmNearestTiesToEven);
18797 D =
scalbn(D, -DenomLogB, APFloat::rmNearestTiesToEven);
18799 APFloat Denom =
C *
C + D * D;
18801 scalbn((A *
C + B * D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
18803 scalbn((B *
C - A * D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
18804 if (ResR.isNaN() && ResI.isNaN()) {
18805 if (Denom.isPosZero() && (!A.isNaN() || !B.isNaN())) {
18806 ResR = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * A;
18807 ResI = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * B;
18808 }
else if ((A.isInfinity() || B.isInfinity()) &&
C.isFinite() &&
18810 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
18812 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
18814 ResR = APFloat::getInf(ResR.getSemantics()) * (A *
C + B * D);
18815 ResI = APFloat::getInf(ResI.getSemantics()) * (B *
C - A * D);
18816 }
else if (MaxCD.isInfinity() && A.isFinite() && B.isFinite()) {
18817 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
18819 D = APFloat::copySign(APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0),
18821 ResR = APFloat::getZero(ResR.getSemantics()) * (A *
C + B * D);
18822 ResI = APFloat::getZero(ResI.getSemantics()) * (B *
C - A * D);
18827bool ComplexExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
18829 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
18833 bool LHSReal =
false, RHSReal =
false;
18841 Result.makeComplexFloat();
18845 LHSOK = Visit(E->
getLHS());
18847 if (!LHSOK && !Info.noteFailure())
18853 APFloat &Real = RHS.FloatReal;
18856 RHS.makeComplexFloat();
18857 RHS.FloatImag =
APFloat(Real.getSemantics());
18861 assert(!(LHSReal && RHSReal) &&
18862 "Cannot have both operands of a complex operation be real.");
18864 default:
return Error(E);
18866 if (
Result.isComplexFloat()) {
18867 Result.getComplexFloatReal().add(RHS.getComplexFloatReal(),
18868 APFloat::rmNearestTiesToEven);
18870 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
18872 Result.getComplexFloatImag().add(RHS.getComplexFloatImag(),
18873 APFloat::rmNearestTiesToEven);
18875 Result.getComplexIntReal() += RHS.getComplexIntReal();
18876 Result.getComplexIntImag() += RHS.getComplexIntImag();
18880 if (
Result.isComplexFloat()) {
18881 Result.getComplexFloatReal().subtract(RHS.getComplexFloatReal(),
18882 APFloat::rmNearestTiesToEven);
18884 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
18885 Result.getComplexFloatImag().changeSign();
18886 }
else if (!RHSReal) {
18887 Result.getComplexFloatImag().subtract(RHS.getComplexFloatImag(),
18888 APFloat::rmNearestTiesToEven);
18891 Result.getComplexIntReal() -= RHS.getComplexIntReal();
18892 Result.getComplexIntImag() -= RHS.getComplexIntImag();
18896 if (
Result.isComplexFloat()) {
18901 ComplexValue LHS =
Result;
18902 APFloat &A = LHS.getComplexFloatReal();
18903 APFloat &B = LHS.getComplexFloatImag();
18904 APFloat &
C = RHS.getComplexFloatReal();
18905 APFloat &D = RHS.getComplexFloatImag();
18909 assert(!RHSReal &&
"Cannot have two real operands for a complex op!");
18917 }
else if (RHSReal) {
18929 ComplexValue LHS =
Result;
18930 Result.getComplexIntReal() =
18931 (LHS.getComplexIntReal() * RHS.getComplexIntReal() -
18932 LHS.getComplexIntImag() * RHS.getComplexIntImag());
18933 Result.getComplexIntImag() =
18934 (LHS.getComplexIntReal() * RHS.getComplexIntImag() +
18935 LHS.getComplexIntImag() * RHS.getComplexIntReal());
18939 if (
Result.isComplexFloat()) {
18944 ComplexValue LHS =
Result;
18945 APFloat &A = LHS.getComplexFloatReal();
18946 APFloat &B = LHS.getComplexFloatImag();
18947 APFloat &
C = RHS.getComplexFloatReal();
18948 APFloat &D = RHS.getComplexFloatImag();
18962 B = APFloat::getZero(A.getSemantics());
18967 ComplexValue LHS =
Result;
18968 APSInt Den = RHS.getComplexIntReal() * RHS.getComplexIntReal() +
18969 RHS.getComplexIntImag() * RHS.getComplexIntImag();
18971 return Error(E, diag::note_expr_divide_by_zero);
18973 Result.getComplexIntReal() =
18974 (LHS.getComplexIntReal() * RHS.getComplexIntReal() +
18975 LHS.getComplexIntImag() * RHS.getComplexIntImag()) / Den;
18976 Result.getComplexIntImag() =
18977 (LHS.getComplexIntImag() * RHS.getComplexIntReal() -
18978 LHS.getComplexIntReal() * RHS.getComplexIntImag()) / Den;
18986bool ComplexExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
19000 if (
Result.isComplexFloat()) {
19001 Result.getComplexFloatReal().changeSign();
19002 Result.getComplexFloatImag().changeSign();
19005 Result.getComplexIntReal() = -
Result.getComplexIntReal();
19006 Result.getComplexIntImag() = -
Result.getComplexIntImag();
19010 if (
Result.isComplexFloat())
19011 Result.getComplexFloatImag().changeSign();
19013 Result.getComplexIntImag() = -
Result.getComplexIntImag();
19018bool ComplexExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
19021 Result.makeComplexFloat();
19027 Result.makeComplexInt();
19035 return ExprEvaluatorBaseTy::VisitInitListExpr(E);
19038bool ComplexExprEvaluator::VisitCallExpr(
const CallExpr *E) {
19039 if (!IsConstantEvaluatedBuiltinCall(E))
19040 return ExprEvaluatorBaseTy::VisitCallExpr(E);
19043 case Builtin::BI__builtin_complex:
19044 Result.makeComplexFloat();
19062class AtomicExprEvaluator :
19063 public ExprEvaluatorBase<AtomicExprEvaluator> {
19064 const LValue *
This;
19067 AtomicExprEvaluator(EvalInfo &Info,
const LValue *This,
APValue &
Result)
19075 bool ZeroInitialization(
const Expr *E) {
19076 ImplicitValueInitExpr VIE(
19084 bool VisitCastExpr(
const CastExpr *E) {
19087 return ExprEvaluatorBaseTy::VisitCastExpr(E);
19088 case CK_NullToPointer:
19090 return ZeroInitialization(E);
19091 case CK_NonAtomicToAtomic:
19103 return AtomicExprEvaluator(Info,
This, Result).Visit(E);
19112class VoidExprEvaluator
19113 :
public ExprEvaluatorBase<VoidExprEvaluator> {
19115 VoidExprEvaluator(EvalInfo &Info) : ExprEvaluatorBaseTy(Info) {}
19119 bool ZeroInitialization(
const Expr *E) {
return true; }
19121 bool VisitCastExpr(
const CastExpr *E) {
19124 return ExprEvaluatorBaseTy::VisitCastExpr(E);
19131 bool VisitCallExpr(
const CallExpr *E) {
19132 if (!IsConstantEvaluatedBuiltinCall(E))
19133 return ExprEvaluatorBaseTy::VisitCallExpr(E);
19136 case Builtin::BI__assume:
19137 case Builtin::BI__builtin_assume:
19141 case Builtin::BI__builtin_operator_delete:
19149 bool VisitCXXDeleteExpr(
const CXXDeleteExpr *E);
19153bool VoidExprEvaluator::VisitCXXDeleteExpr(
const CXXDeleteExpr *E) {
19155 if (Info.SpeculativeEvaluationDepth)
19159 if (!OperatorDelete
19160 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
19161 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
19171 if (
Pointer.Designator.Invalid)
19175 if (
Pointer.isNullPointer()) {
19179 if (!Info.getLangOpts().CPlusPlus20)
19180 Info.CCEDiag(E, diag::note_constexpr_new);
19188 QualType AllocType =
Pointer.Base.getDynamicAllocType();
19194 Info.FFDiag(E, diag::note_constexpr_delete_base_nonvirt_dtor)
19203 if (VirtualDelete &&
19205 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
19206 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
19213 (*Alloc)->Value, AllocType))
19216 if (!Info.HeapAllocs.erase(
Pointer.Base.dyn_cast<DynamicAllocLValue>())) {
19221 Info.FFDiag(E, diag::note_constexpr_double_delete);
19231 return VoidExprEvaluator(Info).Visit(E);
19243 if (E->
isGLValue() ||
T->isFunctionType()) {
19247 LV.moveInto(Result);
19248 }
else if (
T->isVectorType()) {
19251 }
else if (
T->isIntegralOrEnumerationType()) {
19252 if (!IntExprEvaluator(Info, Result).Visit(E))
19254 }
else if (
T->hasPointerRepresentation()) {
19258 LV.moveInto(Result);
19259 }
else if (
T->isRealFloatingType()) {
19260 llvm::APFloat F(0.0);
19264 }
else if (
T->isAnyComplexType()) {
19268 C.moveInto(Result);
19269 }
else if (
T->isFixedPointType()) {
19270 if (!FixedPointExprEvaluator(Info, Result).Visit(E))
return false;
19271 }
else if (
T->isMemberPointerType()) {
19275 P.moveInto(Result);
19277 }
else if (
T->isArrayType()) {
19280 Info.CurrentCall->createTemporary(E,
T, ScopeKind::FullExpression, LV);
19284 }
else if (
T->isRecordType()) {
19287 Info.CurrentCall->createTemporary(E,
T, ScopeKind::FullExpression, LV);
19291 }
else if (
T->isVoidType()) {
19292 if (!Info.getLangOpts().CPlusPlus11)
19293 Info.CCEDiag(E, diag::note_constexpr_nonliteral)
19297 }
else if (
T->isAtomicType()) {
19298 QualType Unqual =
T.getAtomicUnqualifiedType();
19302 E, Unqual, ScopeKind::FullExpression, LV);
19310 }
else if (Info.getLangOpts().CPlusPlus11) {
19311 Info.FFDiag(E, diag::note_constexpr_nonliteral) << E->
getType();
19314 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
19325 const Expr *E,
bool AllowNonLiteralTypes) {
19341 if (
T->isArrayType())
19343 else if (
T->isRecordType())
19345 else if (
T->isAtomicType()) {
19346 QualType Unqual =
T.getAtomicUnqualifiedType();
19367 if (Info.EnableNewConstInterp) {
19371 ConstantExprKind::Normal);
19380 LV.setFrom(Info.Ctx, Result);
19387 ConstantExprKind::Normal) &&
19395 if (
const auto *L = dyn_cast<IntegerLiteral>(Exp)) {
19397 APValue(
APSInt(L->getValue(), L->getType()->isUnsignedIntegerType()));
19402 if (
const auto *L = dyn_cast<CXXBoolLiteralExpr>(Exp)) {
19408 if (
const auto *FL = dyn_cast<FloatingLiteral>(Exp)) {
19409 Result =
APValue(FL->getValue());
19414 if (
const auto *L = dyn_cast<CharacterLiteral>(Exp)) {
19420 if (
const auto *CE = dyn_cast<ConstantExpr>(Exp)) {
19421 if (CE->hasAPValueResult()) {
19422 APValue APV = CE->getAPValueResult();
19424 Result = std::move(APV);
19500 bool InConstantContext)
const {
19502 "Expression evaluator can't be called on a dependent expression.");
19503 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsRValue");
19505 Info.InConstantContext = InConstantContext;
19506 return ::EvaluateAsRValue(
this,
Result, Ctx, Info);
19510 bool InConstantContext)
const {
19512 "Expression evaluator can't be called on a dependent expression.");
19513 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsBooleanCondition");
19521 bool InConstantContext)
const {
19523 "Expression evaluator can't be called on a dependent expression.");
19524 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsInt");
19526 Info.InConstantContext = InConstantContext;
19527 return ::EvaluateAsInt(
this,
Result, Ctx, AllowSideEffects, Info);
19532 bool InConstantContext)
const {
19534 "Expression evaluator can't be called on a dependent expression.");
19535 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFixedPoint");
19537 Info.InConstantContext = InConstantContext;
19538 return ::EvaluateAsFixedPoint(
this,
Result, Ctx, AllowSideEffects, Info);
19543 bool InConstantContext)
const {
19545 "Expression evaluator can't be called on a dependent expression.");
19547 if (!
getType()->isRealFloatingType())
19550 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFloat");
19562 bool InConstantContext)
const {
19564 "Expression evaluator can't be called on a dependent expression.");
19566 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsLValue");
19568 Info.InConstantContext = InConstantContext;
19572 if (Info.EnableNewConstInterp) {
19574 ConstantExprKind::Normal))
19577 LV.setFrom(Ctx,
Result.Val);
19580 ConstantExprKind::Normal, CheckedTemps);
19583 if (!
EvaluateLValue(
this, LV, Info) || !Info.discardCleanups() ||
19584 Result.HasSideEffects ||
19587 ConstantExprKind::Normal, CheckedTemps))
19590 LV.moveInto(
Result.Val);
19597 bool IsConstantDestruction) {
19598 EvalInfo Info(Ctx, EStatus,
19601 Info.setEvaluatingDecl(
Base, DestroyedValue,
19602 EvalInfo::EvaluatingDeclKind::Dtor);
19603 Info.InConstantContext = IsConstantDestruction;
19612 if (!Info.discardCleanups())
19613 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
19621 "Expression evaluator can't be called on a dependent expression.");
19627 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsConstantExpr");
19629 EvalInfo Info(Ctx,
Result, EM);
19630 Info.InConstantContext =
true;
19632 if (Info.EnableNewConstInterp) {
19636 getStorageType(Ctx,
this),
Result.Val, Kind);
19641 if (Kind == ConstantExprKind::ClassTemplateArgument)
19657 FullExpressionRAII
Scope(Info);
19662 if (!Info.discardCleanups())
19663 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
19673 if (Kind == ConstantExprKind::ClassTemplateArgument &&
19676 Result.HasSideEffects)) {
19688 bool IsConstantInitialization)
const {
19690 "Expression evaluator can't be called on a dependent expression.");
19691 assert(VD &&
"Need a valid VarDecl");
19693 llvm::TimeTraceScope TimeScope(
"EvaluateAsInitializer", [&] {
19695 llvm::raw_string_ostream OS(Name);
19701 EStatus.
Diag = &Notes;
19703 EvalInfo Info(Ctx, EStatus,
19704 (IsConstantInitialization &&
19708 Info.setEvaluatingDecl(VD,
Value);
19709 Info.InConstantContext = IsConstantInitialization;
19714 if (Info.EnableNewConstInterp) {
19715 auto &InterpCtx =
const_cast<ASTContext &
>(Ctx).getInterpContext();
19716 if (!InterpCtx.evaluateAsInitializer(Info, VD,
this,
Value))
19720 ConstantExprKind::Normal);
19735 FullExpressionRAII
Scope(Info);
19738 EStatus.HasSideEffects)
19744 Info.performLifetimeExtension();
19746 if (!Info.discardCleanups())
19747 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
19751 ConstantExprKind::Normal) &&
19758 EStatus.
Diag = &Notes;
19775 IsConstantDestruction) ||
19787 "Expression evaluator can't be called on a dependent expression.");
19796 "Expression evaluator can't be called on a dependent expression.");
19798 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstInt");
19801 Info.InConstantContext =
true;
19805 assert(
Result &&
"Could not evaluate expression");
19806 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
19808 return EVResult.Val.getInt();
19814 "Expression evaluator can't be called on a dependent expression.");
19816 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstIntCheckOverflow");
19818 EVResult.Diag =
Diag;
19820 Info.InConstantContext =
true;
19821 Info.CheckingForUndefinedBehavior =
true;
19825 assert(
Result &&
"Could not evaluate expression");
19826 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
19828 return EVResult.Val.getInt();
19833 "Expression evaluator can't be called on a dependent expression.");
19835 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateForOverflow");
19840 Info.CheckingForUndefinedBehavior =
true;
19846 assert(
Val.isLValue());
19872 IK_ICEIfUnevaluated,
19888static ICEDiag
Worst(ICEDiag A, ICEDiag B) {
return A.Kind >= B.Kind ? A : B; }
19895 Info.InConstantContext =
true;
19904 assert(!E->
isValueDependent() &&
"Should not see value dependent exprs!");
19909#define ABSTRACT_STMT(Node)
19910#define STMT(Node, Base) case Expr::Node##Class:
19911#define EXPR(Node, Base)
19912#include "clang/AST/StmtNodes.inc"
19913 case Expr::PredefinedExprClass:
19914 case Expr::FloatingLiteralClass:
19915 case Expr::ImaginaryLiteralClass:
19916 case Expr::StringLiteralClass:
19917 case Expr::ArraySubscriptExprClass:
19918 case Expr::MatrixSubscriptExprClass:
19919 case Expr::ArraySectionExprClass:
19920 case Expr::OMPArrayShapingExprClass:
19921 case Expr::OMPIteratorExprClass:
19922 case Expr::MemberExprClass:
19923 case Expr::CompoundAssignOperatorClass:
19924 case Expr::CompoundLiteralExprClass:
19925 case Expr::ExtVectorElementExprClass:
19926 case Expr::DesignatedInitExprClass:
19927 case Expr::ArrayInitLoopExprClass:
19928 case Expr::ArrayInitIndexExprClass:
19929 case Expr::NoInitExprClass:
19930 case Expr::DesignatedInitUpdateExprClass:
19931 case Expr::ImplicitValueInitExprClass:
19932 case Expr::ParenListExprClass:
19933 case Expr::VAArgExprClass:
19934 case Expr::AddrLabelExprClass:
19935 case Expr::StmtExprClass:
19936 case Expr::CXXMemberCallExprClass:
19937 case Expr::CUDAKernelCallExprClass:
19938 case Expr::CXXAddrspaceCastExprClass:
19939 case Expr::CXXDynamicCastExprClass:
19940 case Expr::CXXTypeidExprClass:
19941 case Expr::CXXUuidofExprClass:
19942 case Expr::MSPropertyRefExprClass:
19943 case Expr::MSPropertySubscriptExprClass:
19944 case Expr::CXXNullPtrLiteralExprClass:
19945 case Expr::UserDefinedLiteralClass:
19946 case Expr::CXXThisExprClass:
19947 case Expr::CXXThrowExprClass:
19948 case Expr::CXXNewExprClass:
19949 case Expr::CXXDeleteExprClass:
19950 case Expr::CXXPseudoDestructorExprClass:
19951 case Expr::UnresolvedLookupExprClass:
19952 case Expr::RecoveryExprClass:
19953 case Expr::DependentScopeDeclRefExprClass:
19954 case Expr::CXXConstructExprClass:
19955 case Expr::CXXInheritedCtorInitExprClass:
19956 case Expr::CXXStdInitializerListExprClass:
19957 case Expr::CXXBindTemporaryExprClass:
19958 case Expr::ExprWithCleanupsClass:
19959 case Expr::CXXTemporaryObjectExprClass:
19960 case Expr::CXXUnresolvedConstructExprClass:
19961 case Expr::CXXDependentScopeMemberExprClass:
19962 case Expr::UnresolvedMemberExprClass:
19963 case Expr::ObjCStringLiteralClass:
19964 case Expr::ObjCBoxedExprClass:
19965 case Expr::ObjCArrayLiteralClass:
19966 case Expr::ObjCDictionaryLiteralClass:
19967 case Expr::ObjCEncodeExprClass:
19968 case Expr::ObjCMessageExprClass:
19969 case Expr::ObjCSelectorExprClass:
19970 case Expr::ObjCProtocolExprClass:
19971 case Expr::ObjCIvarRefExprClass:
19972 case Expr::ObjCPropertyRefExprClass:
19973 case Expr::ObjCSubscriptRefExprClass:
19974 case Expr::ObjCIsaExprClass:
19975 case Expr::ObjCAvailabilityCheckExprClass:
19976 case Expr::ShuffleVectorExprClass:
19977 case Expr::ConvertVectorExprClass:
19978 case Expr::BlockExprClass:
19980 case Expr::OpaqueValueExprClass:
19981 case Expr::PackExpansionExprClass:
19982 case Expr::SubstNonTypeTemplateParmPackExprClass:
19983 case Expr::FunctionParmPackExprClass:
19984 case Expr::AsTypeExprClass:
19985 case Expr::ObjCIndirectCopyRestoreExprClass:
19986 case Expr::MaterializeTemporaryExprClass:
19987 case Expr::PseudoObjectExprClass:
19988 case Expr::AtomicExprClass:
19989 case Expr::LambdaExprClass:
19990 case Expr::CXXFoldExprClass:
19991 case Expr::CoawaitExprClass:
19992 case Expr::DependentCoawaitExprClass:
19993 case Expr::CoyieldExprClass:
19994 case Expr::SYCLUniqueStableNameExprClass:
19995 case Expr::CXXParenListInitExprClass:
19996 case Expr::HLSLOutArgExprClass:
19999 case Expr::InitListExprClass: {
20010 case Expr::SizeOfPackExprClass:
20011 case Expr::GNUNullExprClass:
20012 case Expr::SourceLocExprClass:
20013 case Expr::EmbedExprClass:
20014 case Expr::OpenACCAsteriskSizeExprClass:
20017 case Expr::PackIndexingExprClass:
20020 case Expr::SubstNonTypeTemplateParmExprClass:
20024 case Expr::ConstantExprClass:
20027 case Expr::ParenExprClass:
20029 case Expr::GenericSelectionExprClass:
20031 case Expr::IntegerLiteralClass:
20032 case Expr::FixedPointLiteralClass:
20033 case Expr::CharacterLiteralClass:
20034 case Expr::ObjCBoolLiteralExprClass:
20035 case Expr::CXXBoolLiteralExprClass:
20036 case Expr::CXXScalarValueInitExprClass:
20037 case Expr::TypeTraitExprClass:
20038 case Expr::ConceptSpecializationExprClass:
20039 case Expr::RequiresExprClass:
20040 case Expr::ArrayTypeTraitExprClass:
20041 case Expr::ExpressionTraitExprClass:
20042 case Expr::CXXNoexceptExprClass:
20044 case Expr::CallExprClass:
20045 case Expr::CXXOperatorCallExprClass: {
20054 case Expr::CXXRewrittenBinaryOperatorClass:
20057 case Expr::DeclRefExprClass: {
20071 const VarDecl *VD = dyn_cast<VarDecl>(D);
20078 case Expr::UnaryOperatorClass: {
20101 llvm_unreachable(
"invalid unary operator class");
20103 case Expr::OffsetOfExprClass: {
20112 case Expr::UnaryExprOrTypeTraitExprClass: {
20114 if ((Exp->
getKind() == UETT_SizeOf) &&
20117 if (Exp->
getKind() == UETT_CountOf) {
20124 if (VAT->getElementType()->isArrayType())
20136 case Expr::BinaryOperatorClass: {
20181 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE) {
20184 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
20185 if (REval.isSigned() && REval.isAllOnes()) {
20187 if (LEval.isMinSignedValue())
20188 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
20196 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE)
20197 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
20203 return Worst(LHSResult, RHSResult);
20209 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICEIfUnevaluated) {
20219 return Worst(LHSResult, RHSResult);
20222 llvm_unreachable(
"invalid binary operator kind");
20224 case Expr::ImplicitCastExprClass:
20225 case Expr::CStyleCastExprClass:
20226 case Expr::CXXFunctionalCastExprClass:
20227 case Expr::CXXStaticCastExprClass:
20228 case Expr::CXXReinterpretCastExprClass:
20229 case Expr::CXXConstCastExprClass:
20230 case Expr::ObjCBridgedCastExprClass: {
20237 APSInt IgnoredVal(DestWidth, !DestSigned);
20242 if (FL->getValue().convertToInteger(IgnoredVal,
20243 llvm::APFloat::rmTowardZero,
20244 &Ignored) & APFloat::opInvalidOp)
20250 case CK_LValueToRValue:
20251 case CK_AtomicToNonAtomic:
20252 case CK_NonAtomicToAtomic:
20254 case CK_IntegralToBoolean:
20255 case CK_IntegralCast:
20261 case Expr::BinaryConditionalOperatorClass: {
20264 if (CommonResult.Kind == IK_NotICE)
return CommonResult;
20266 if (FalseResult.Kind == IK_NotICE)
return FalseResult;
20267 if (CommonResult.Kind == IK_ICEIfUnevaluated)
return CommonResult;
20268 if (FalseResult.Kind == IK_ICEIfUnevaluated &&
20270 return FalseResult;
20272 case Expr::ConditionalOperatorClass: {
20280 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
20283 if (CondResult.Kind == IK_NotICE)
20289 if (TrueResult.Kind == IK_NotICE)
20291 if (FalseResult.Kind == IK_NotICE)
20292 return FalseResult;
20293 if (CondResult.Kind == IK_ICEIfUnevaluated)
20295 if (TrueResult.Kind == IK_ICE && FalseResult.Kind == IK_ICE)
20301 return FalseResult;
20304 case Expr::CXXDefaultArgExprClass:
20306 case Expr::CXXDefaultInitExprClass:
20308 case Expr::ChooseExprClass: {
20311 case Expr::BuiltinBitCastExprClass: {
20312 if (!checkBitCastConstexprEligibility(
nullptr, Ctx,
cast<CastExpr>(E)))
20318 llvm_unreachable(
"Invalid StmtClass!");
20324 llvm::APSInt *
Value) {
20332 if (!Result.isInt())
20341 "Expression evaluator can't be called on a dependent expression.");
20343 ExprTimeTraceScope TimeScope(
this, Ctx,
"isIntegerConstantExpr");
20349 if (D.Kind != IK_ICE)
20354std::optional<llvm::APSInt>
20358 return std::nullopt;
20365 return std::nullopt;
20369 return std::nullopt;
20378 Info.InConstantContext =
true;
20381 llvm_unreachable(
"ICE cannot be evaluated!");
20388 "Expression evaluator can't be called on a dependent expression.");
20390 return CheckICE(
this, Ctx).Kind == IK_ICE;
20395 "Expression evaluator can't be called on a dependent expression.");
20412 Status.Diag = &Diags;
20419 Info.discardCleanups() && !Status.HasSideEffects;
20421 return IsConstExpr && Diags.empty();
20429 "Expression evaluator can't be called on a dependent expression.");
20431 llvm::TimeTraceScope TimeScope(
"EvaluateWithSubstitution", [&] {
20433 llvm::raw_string_ostream OS(Name);
20441 Info.InConstantContext =
true;
20444 const LValue *ThisPtr =
nullptr;
20447 auto *MD = dyn_cast<CXXMethodDecl>(Callee);
20448 assert(MD &&
"Don't provide `this` for non-methods.");
20449 assert(MD->isImplicitObjectMemberFunction() &&
20450 "Don't provide `this` for methods without an implicit object.");
20452 if (!
This->isValueDependent() &&
20455 ThisPtr = &ThisVal;
20462 CallRef
Call = Info.CurrentCall->createCall(Callee);
20465 unsigned Idx = I - Args.begin();
20466 if (Idx >= Callee->getNumParams())
20468 const ParmVarDecl *PVD = Callee->getParamDecl(Idx);
20469 if ((*I)->isValueDependent() ||
20473 if (
APValue *Slot = Info.getParamSlot(
Call, PVD))
20484 Info.discardCleanups();
20488 CallStackFrame Frame(Info, Callee->getLocation(), Callee, ThisPtr,
This,
20491 FullExpressionRAII
Scope(Info);
20505 llvm::TimeTraceScope TimeScope(
"isPotentialConstantExpr", [&] {
20507 llvm::raw_string_ostream OS(Name);
20514 Status.
Diag = &Diags;
20518 Info.InConstantContext =
true;
20519 Info.CheckingPotentialConstantExpression =
true;
20522 if (Info.EnableNewConstInterp) {
20524 return Diags.empty();
20535 This.set({&VIE, Info.CurrentCall->Index});
20543 Info.setEvaluatingDecl(
This.getLValueBase(), Scratch);
20549 &VIE, Args, CallRef(), FD->
getBody(), Info, Scratch,
20553 return Diags.empty();
20561 "Expression evaluator can't be called on a dependent expression.");
20564 Status.
Diag = &Diags;
20568 Info.InConstantContext =
true;
20569 Info.CheckingPotentialConstantExpression =
true;
20571 if (Info.EnableNewConstInterp) {
20573 return Diags.empty();
20578 nullptr, CallRef());
20582 return Diags.empty();
20586 unsigned Type)
const {
20587 if (!
getType()->isPointerType())
20596 EvalInfo &Info, std::string *StringResult) {
20608 if (
const StringLiteral *S = dyn_cast_or_null<StringLiteral>(
20609 String.getLValueBase().dyn_cast<
const Expr *>())) {
20612 if (Off >= 0 && (uint64_t)Off <= (uint64_t)Str.size() &&
20616 Str = Str.substr(Off);
20618 StringRef::size_type Pos = Str.find(0);
20619 if (Pos != StringRef::npos)
20620 Str = Str.substr(0, Pos);
20622 Result = Str.size();
20624 *StringResult = Str;
20632 for (uint64_t Strlen = 0; ; ++Strlen) {
20640 }
else if (StringResult)
20641 StringResult->push_back(Char.
getInt().getExtValue());
20651 std::string StringResult;
20653 if (Info.EnableNewConstInterp) {
20655 return std::nullopt;
20656 return StringResult;
20660 return StringResult;
20661 return std::nullopt;
20664template <
typename T>
20666 const Expr *SizeExpression,
20667 const Expr *PtrExpression,
20671 Info.InConstantContext =
true;
20673 if (Info.EnableNewConstInterp)
20675 PtrExpression, Result);
20678 FullExpressionRAII
Scope(Info);
20683 uint64_t Size = SizeValue.getZExtValue();
20686 if constexpr (std::is_same_v<APValue, T>)
20689 if (Size < Result.max_size())
20690 Result.reserve(Size);
20696 for (uint64_t I = 0; I < Size; ++I) {
20702 if constexpr (std::is_same_v<APValue, T>) {
20703 Result.getArrayInitializedElt(I) = std::move(Char);
20707 assert(
C.getBitWidth() <= 8 &&
20708 "string element not representable in char");
20710 Result.push_back(
static_cast<char>(
C.getExtValue()));
20721 const Expr *SizeExpression,
20725 PtrExpression, Ctx, Status);
20729 const Expr *SizeExpression,
20733 PtrExpression, Ctx, Status);
20740 if (Info.EnableNewConstInterp)
20747struct IsWithinLifetimeHandler {
20750 using result_type = std::optional<bool>;
20751 std::optional<bool> failed() {
return std::nullopt; }
20752 template <
typename T>
20753 std::optional<bool> found(
T &Subobj,
QualType SubobjType) {
20758std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &IEE,
20759 const CallExpr *E) {
20760 EvalInfo &Info = IEE.Info;
20765 if (!Info.InConstantContext)
20766 return std::nullopt;
20768 const Expr *Arg = E->
getArg(0);
20770 return std::nullopt;
20773 return std::nullopt;
20775 if (Val.allowConstexprUnknown())
20779 bool CalledFromStd =
false;
20780 const auto *
Callee = Info.CurrentCall->getCallee();
20781 if (Callee &&
Callee->isInStdNamespace()) {
20782 const IdentifierInfo *Identifier =
Callee->getIdentifier();
20783 CalledFromStd = Identifier && Identifier->
isStr(
"is_within_lifetime");
20785 Info.CCEDiag(CalledFromStd ? Info.CurrentCall->getCallRange().getBegin()
20787 diag::err_invalid_is_within_lifetime)
20788 << (CalledFromStd ?
"std::is_within_lifetime"
20789 :
"__builtin_is_within_lifetime")
20791 return std::nullopt;
20801 if (Val.isNullPointer() || Val.getLValueBase().isNull())
20803 QualType
T = Val.getLValueBase().getType();
20805 "Pointers to functions should have been typed as function pointers "
20806 "which would have been rejected earlier");
20809 if (Val.getLValueDesignator().isOnePastTheEnd())
20811 assert(Val.getLValueDesignator().isValidSubobject() &&
20812 "Unchecked case for valid subobject");
20816 CompleteObject CO =
20820 if (Info.EvaluatingDeclValue && CO.Value == Info.EvaluatingDeclValue)
20825 IsWithinLifetimeHandler handler{Info};
20826 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)