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(
3835struct CompleteObject {
3837 APValue::LValueBase
Base;
3847 bool mayAccessMutableMembers(EvalInfo &Info,
AccessKinds AK)
const {
3858 if (!Info.getLangOpts().CPlusPlus14 &&
3859 AK != AccessKinds::AK_IsWithinLifetime)
3864 explicit operator bool()
const {
return !
Type.isNull(); }
3869 bool IsMutable =
false) {
3883template <
typename Sub
objectHandler>
3884static typename SubobjectHandler::result_type
3886 const SubobjectDesignator &Sub, SubobjectHandler &handler) {
3889 return handler.failed();
3890 if (Sub.isOnePastTheEnd() || Sub.isMostDerivedAnUnsizedArray()) {
3891 if (Info.getLangOpts().CPlusPlus11)
3892 Info.FFDiag(E, Sub.isOnePastTheEnd()
3893 ? diag::note_constexpr_access_past_end
3894 : diag::note_constexpr_access_unsized_array)
3895 << handler.AccessKind;
3898 return handler.failed();
3904 const FieldDecl *VolatileField =
nullptr;
3907 for (
unsigned I = 0, N = Sub.Entries.size(); ; ++I) {
3918 if (!Info.checkingPotentialConstantExpression())
3919 Info.FFDiag(E, diag::note_constexpr_access_uninit)
3922 return handler.failed();
3930 Info.isEvaluatingCtorDtor(
3931 Obj.Base,
ArrayRef(Sub.Entries.begin(), Sub.Entries.begin() + I)) !=
3932 ConstructionPhase::None) {
3942 if (Info.getLangOpts().CPlusPlus) {
3946 if (VolatileField) {
3949 Decl = VolatileField;
3952 Loc = VD->getLocation();
3959 Info.FFDiag(E, diag::note_constexpr_access_volatile_obj, 1)
3960 << handler.AccessKind << DiagKind <<
Decl;
3961 Info.Note(Loc, diag::note_constexpr_volatile_here) << DiagKind;
3963 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
3965 return handler.failed();
3973 !Obj.mayAccessMutableMembers(Info, handler.AccessKind) &&
3975 return handler.failed();
3979 if (!handler.found(*O, ObjType))
3991 LastField =
nullptr;
3996 "vla in literal type?");
3997 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
3998 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT);
3999 CAT && CAT->
getSize().ule(Index)) {
4002 if (Info.getLangOpts().CPlusPlus11)
4003 Info.FFDiag(E, diag::note_constexpr_access_past_end)
4004 << handler.AccessKind;
4007 return handler.failed();
4014 else if (!
isRead(handler.AccessKind)) {
4015 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT);
4017 return handler.failed();
4025 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4027 if (Info.getLangOpts().CPlusPlus11)
4028 Info.FFDiag(E, diag::note_constexpr_access_past_end)
4029 << handler.AccessKind;
4032 return handler.failed();
4038 assert(I == N - 1 &&
"extracting subobject of scalar?");
4048 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4049 unsigned NumElements = VT->getNumElements();
4050 if (Index == NumElements) {
4051 if (Info.getLangOpts().CPlusPlus11)
4052 Info.FFDiag(E, diag::note_constexpr_access_past_end)
4053 << handler.AccessKind;
4056 return handler.failed();
4059 if (Index > NumElements) {
4060 Info.CCEDiag(E, diag::note_constexpr_array_index)
4061 << Index << 0 << NumElements;
4062 return handler.failed();
4065 ObjType = VT->getElementType();
4066 assert(I == N - 1 &&
"extracting subobject of scalar?");
4068 }
else if (
const FieldDecl *Field = getAsField(Sub.Entries[I])) {
4069 if (Field->isMutable() &&
4070 !Obj.mayAccessMutableMembers(Info, handler.AccessKind)) {
4071 Info.FFDiag(E, diag::note_constexpr_access_mutable, 1)
4072 << handler.AccessKind << Field;
4073 Info.Note(Field->getLocation(), diag::note_declared_at);
4074 return handler.failed();
4083 if (I == N - 1 && handler.AccessKind ==
AK_Construct) {
4094 Info.FFDiag(E, diag::note_constexpr_access_inactive_union_member)
4095 << handler.AccessKind << Field << !UnionField << UnionField;
4096 return handler.failed();
4105 if (Field->getType().isVolatileQualified())
4106 VolatileField = Field;
4119struct ExtractSubobjectHandler {
4125 typedef bool result_type;
4126 bool failed() {
return false; }
4127 bool found(
APValue &Subobj, QualType SubobjType) {
4137 bool found(APFloat &
Value, QualType SubobjType) {
4146 const CompleteObject &Obj,
4147 const SubobjectDesignator &Sub,
APValue &Result,
4150 ExtractSubobjectHandler Handler = {Info, E, Result, AK};
4155struct ModifySubobjectHandler {
4160 typedef bool result_type;
4163 bool checkConst(QualType QT) {
4166 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
4172 bool failed() {
return false; }
4173 bool found(
APValue &Subobj, QualType SubobjType) {
4174 if (!checkConst(SubobjType))
4177 Subobj.
swap(NewVal);
4181 if (!checkConst(SubobjType))
4183 if (!NewVal.
isInt()) {
4191 bool found(APFloat &
Value, QualType SubobjType) {
4192 if (!checkConst(SubobjType))
4200const AccessKinds ModifySubobjectHandler::AccessKind;
4204 const CompleteObject &Obj,
4205 const SubobjectDesignator &Sub,
4207 ModifySubobjectHandler Handler = { Info, NewVal, E };
4214 const SubobjectDesignator &A,
4215 const SubobjectDesignator &B,
4216 bool &WasArrayIndex) {
4217 unsigned I = 0, N = std::min(A.Entries.size(), B.Entries.size());
4218 for (; I != N; ++I) {
4222 if (A.Entries[I].getAsArrayIndex() != B.Entries[I].getAsArrayIndex()) {
4223 WasArrayIndex =
true;
4231 if (A.Entries[I].getAsBaseOrMember() !=
4232 B.Entries[I].getAsBaseOrMember()) {
4233 WasArrayIndex =
false;
4236 if (
const FieldDecl *FD = getAsField(A.Entries[I]))
4238 ObjType = FD->getType();
4244 WasArrayIndex =
false;
4251 const SubobjectDesignator &A,
4252 const SubobjectDesignator &B) {
4253 if (A.Entries.size() != B.Entries.size())
4256 bool IsArray = A.MostDerivedIsArrayElement;
4257 if (IsArray && A.MostDerivedPathLength != A.Entries.size())
4266 return CommonLength >= A.Entries.size() - IsArray;
4273 if (LVal.InvalidBase) {
4275 return CompleteObject();
4280 Info.FFDiag(E, diag::note_constexpr_dereferencing_null);
4282 Info.FFDiag(E, diag::note_constexpr_access_null) << AK;
4283 return CompleteObject();
4286 CallStackFrame *Frame =
nullptr;
4288 if (LVal.getLValueCallIndex()) {
4289 std::tie(Frame, Depth) =
4290 Info.getCallFrameAndDepth(LVal.getLValueCallIndex());
4292 Info.FFDiag(E, diag::note_constexpr_lifetime_ended, 1)
4295 return CompleteObject();
4306 if (Info.getLangOpts().CPlusPlus)
4307 Info.FFDiag(E, diag::note_constexpr_access_volatile_type)
4311 return CompleteObject();
4318 if (Info.getLangOpts().CPlusPlus14 && LVal.Base == Info.EvaluatingDecl &&
4322 BaseVal = Info.EvaluatingDeclValue;
4325 if (
auto *GD = dyn_cast<MSGuidDecl>(D)) {
4328 Info.FFDiag(E, diag::note_constexpr_modify_global);
4329 return CompleteObject();
4333 Info.FFDiag(E, diag::note_constexpr_unsupported_layout)
4335 return CompleteObject();
4337 return CompleteObject(LVal.Base, &
V, GD->getType());
4341 if (
auto *GCD = dyn_cast<UnnamedGlobalConstantDecl>(D)) {
4343 Info.FFDiag(E, diag::note_constexpr_modify_global);
4344 return CompleteObject();
4346 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&GCD->getValue()),
4351 if (
auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
4353 Info.FFDiag(E, diag::note_constexpr_modify_global);
4354 return CompleteObject();
4356 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&TPO->getValue()),
4367 const VarDecl *VD = dyn_cast<VarDecl>(D);
4374 return CompleteObject();
4377 bool IsConstant = BaseType.isConstant(Info.Ctx);
4378 bool ConstexprVar =
false;
4379 if (
const auto *VD = dyn_cast_if_present<VarDecl>(
4391 }
else if (Info.getLangOpts().CPlusPlus14 &&
4398 Info.FFDiag(E, diag::note_constexpr_modify_global);
4399 return CompleteObject();
4402 }
else if (Info.getLangOpts().C23 && ConstexprVar) {
4404 return CompleteObject();
4405 }
else if (BaseType->isIntegralOrEnumerationType()) {
4408 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4409 if (Info.getLangOpts().CPlusPlus) {
4410 Info.FFDiag(E, diag::note_constexpr_ltor_non_const_int, 1) << VD;
4411 Info.Note(VD->
getLocation(), diag::note_declared_at);
4415 return CompleteObject();
4417 }
else if (!IsAccess) {
4418 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4419 }
else if ((IsConstant || BaseType->isReferenceType()) &&
4420 Info.checkingPotentialConstantExpression() &&
4421 BaseType->isLiteralType(Info.Ctx) && !VD->
hasDefinition()) {
4423 }
else if (IsConstant) {
4427 if (Info.getLangOpts().CPlusPlus) {
4428 Info.CCEDiag(E, Info.getLangOpts().CPlusPlus11
4429 ? diag::note_constexpr_ltor_non_constexpr
4430 : diag::note_constexpr_ltor_non_integral, 1)
4432 Info.Note(VD->
getLocation(), diag::note_declared_at);
4438 if (Info.getLangOpts().CPlusPlus) {
4439 Info.FFDiag(E, Info.getLangOpts().CPlusPlus11
4440 ? diag::note_constexpr_ltor_non_constexpr
4441 : diag::note_constexpr_ltor_non_integral, 1)
4443 Info.Note(VD->
getLocation(), diag::note_declared_at);
4447 return CompleteObject();
4456 return CompleteObject();
4461 if (!Info.checkingPotentialConstantExpression()) {
4462 Info.FFDiag(E, diag::note_constexpr_access_unknown_variable, 1)
4464 Info.Note(VD->getLocation(), diag::note_declared_at);
4466 return CompleteObject();
4469 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
4471 Info.FFDiag(E, diag::note_constexpr_access_deleted_object) << AK;
4472 return CompleteObject();
4474 return CompleteObject(LVal.Base, &(*Alloc)->Value,
4484 dyn_cast_or_null<MaterializeTemporaryExpr>(
Base)) {
4485 assert(MTE->getStorageDuration() ==
SD_Static &&
4486 "should have a frame for a non-global materialized temporary");
4513 if (!MTE->isUsableInConstantExpressions(Info.Ctx) &&
4516 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4517 Info.FFDiag(E, diag::note_constexpr_access_static_temporary, 1) << AK;
4518 Info.Note(MTE->getExprLoc(), diag::note_constexpr_temporary_here);
4519 return CompleteObject();
4522 BaseVal = MTE->getOrCreateValue(
false);
4523 assert(BaseVal &&
"got reference to unevaluated temporary");
4525 dyn_cast_or_null<CompoundLiteralExpr>(
Base)) {
4541 !CLETy.isConstant(Info.Ctx)) {
4543 Info.Note(CLE->getExprLoc(), diag::note_declared_at);
4544 return CompleteObject();
4547 BaseVal = &CLE->getStaticValue();
4550 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4553 Info.FFDiag(E, diag::note_constexpr_access_unreadable_object)
4558 return CompleteObject();
4562 assert(BaseVal &&
"missing value for temporary");
4573 unsigned VisibleDepth = Depth;
4574 if (llvm::isa_and_nonnull<ParmVarDecl>(
4577 if ((Frame && Info.getLangOpts().CPlusPlus14 &&
4579 (
isModification(AK) && VisibleDepth < Info.SpeculativeEvaluationDepth))
4580 return CompleteObject();
4582 return CompleteObject(LVal.getLValueBase(), BaseVal, BaseType);
4601 const LValue &LVal,
APValue &RVal,
4602 bool WantObjectRepresentation =
false) {
4603 if (LVal.Designator.Invalid)
4612 if (
Base && !LVal.getLValueCallIndex() && !
Type.isVolatileQualified()) {
4616 assert(LVal.Designator.Entries.size() <= 1 &&
4617 "Can only read characters from string literals");
4618 if (LVal.Designator.Entries.empty()) {
4625 if (LVal.Designator.isOnePastTheEnd()) {
4626 if (Info.getLangOpts().CPlusPlus11)
4627 Info.FFDiag(Conv, diag::note_constexpr_access_past_end) << AK;
4632 uint64_t CharIndex = LVal.Designator.Entries[0].getAsArrayIndex();
4639 return Obj &&
extractSubobject(Info, Conv, Obj, LVal.Designator, RVal, AK);
4645 if (LVal.Designator.Invalid)
4648 if (!Info.getLangOpts().CPlusPlus14) {
4658struct CompoundAssignSubobjectHandler {
4660 const CompoundAssignOperator *E;
4661 QualType PromotedLHSType;
4667 typedef bool result_type;
4669 bool checkConst(QualType QT) {
4672 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
4678 bool failed() {
return false; }
4679 bool found(
APValue &Subobj, QualType SubobjType) {
4682 return found(Subobj.
getInt(), SubobjType);
4684 return found(Subobj.
getFloat(), SubobjType);
4691 return foundPointer(Subobj, SubobjType);
4693 return foundVector(Subobj, SubobjType);
4695 Info.FFDiag(E, diag::note_constexpr_access_uninit)
4706 bool foundVector(
APValue &
Value, QualType SubobjType) {
4707 if (!checkConst(SubobjType))
4718 if (!checkConst(SubobjType))
4740 PromotedLHSType, FValue) &&
4749 bool found(APFloat &
Value, QualType SubobjType) {
4750 return checkConst(SubobjType) &&
4756 bool foundPointer(
APValue &Subobj, QualType SubobjType) {
4757 if (!checkConst(SubobjType))
4760 QualType PointeeType;
4761 if (
const PointerType *PT = SubobjType->
getAs<PointerType>())
4765 (Opcode != BO_Add && Opcode != BO_Sub)) {
4771 if (Opcode == BO_Sub)
4775 LVal.setFrom(Info.Ctx, Subobj);
4778 LVal.moveInto(Subobj);
4784const AccessKinds CompoundAssignSubobjectHandler::AccessKind;
4789 const LValue &LVal,
QualType LValType,
4793 if (LVal.Designator.Invalid)
4796 if (!Info.getLangOpts().CPlusPlus14) {
4802 CompoundAssignSubobjectHandler Handler = { Info, E, PromotedLValType, Opcode,
4804 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
4808struct IncDecSubobjectHandler {
4810 const UnaryOperator *E;
4814 typedef bool result_type;
4816 bool checkConst(QualType QT) {
4819 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
4825 bool failed() {
return false; }
4826 bool found(
APValue &Subobj, QualType SubobjType) {
4836 return found(Subobj.
getInt(), SubobjType);
4838 return found(Subobj.
getFloat(), SubobjType);
4841 SubobjType->
castAs<ComplexType>()->getElementType()
4845 SubobjType->
castAs<ComplexType>()->getElementType()
4848 return foundPointer(Subobj, SubobjType);
4856 if (!checkConst(SubobjType))
4878 bool WasNegative =
Value.isNegative();
4890 unsigned BitWidth =
Value.getBitWidth();
4891 APSInt ActualValue(
Value.sext(BitWidth + 1),
false);
4892 ActualValue.setBit(BitWidth);
4898 bool found(APFloat &
Value, QualType SubobjType) {
4899 if (!checkConst(SubobjType))
4906 APFloat::opStatus St;
4908 St =
Value.add(One, RM);
4910 St =
Value.subtract(One, RM);
4913 bool foundPointer(
APValue &Subobj, QualType SubobjType) {
4914 if (!checkConst(SubobjType))
4917 QualType PointeeType;
4918 if (
const PointerType *PT = SubobjType->
getAs<PointerType>())
4926 LVal.setFrom(Info.Ctx, Subobj);
4930 LVal.moveInto(Subobj);
4939 if (LVal.Designator.Invalid)
4942 if (!Info.getLangOpts().CPlusPlus14) {
4950 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
4956 if (Object->getType()->isPointerType() && Object->isPRValue())
4959 if (Object->isGLValue())
4962 if (Object->getType()->isLiteralType(Info.Ctx))
4965 if (Object->getType()->isRecordType() && Object->isPRValue())
4968 Info.FFDiag(Object, diag::note_constexpr_nonliteral) << Object->getType();
4987 bool IncludeMember =
true) {
4994 if (!MemPtr.getDecl()) {
5000 if (MemPtr.isDerivedMember()) {
5007 if (LV.Designator.MostDerivedPathLength + MemPtr.Path.size() >
5008 LV.Designator.Entries.size()) {
5012 unsigned PathLengthToMember =
5013 LV.Designator.Entries.size() - MemPtr.Path.size();
5014 for (
unsigned I = 0, N = MemPtr.Path.size(); I != N; ++I) {
5016 LV.Designator.Entries[PathLengthToMember + I]);
5033 (PathLengthToMember > LV.Designator.MostDerivedPathLength)
5034 ? getAsBaseClass(LV.Designator.Entries[PathLengthToMember - 1])
5036 const CXXRecordDecl *LastMPDecl = MemPtr.getContainingRecord();
5044 PathLengthToMember))
5046 }
else if (!MemPtr.Path.empty()) {
5048 LV.Designator.Entries.reserve(LV.Designator.Entries.size() +
5049 MemPtr.Path.size() + IncludeMember);
5055 assert(RD &&
"member pointer access on non-class-type expression");
5057 for (
unsigned I = 1, N = MemPtr.Path.size(); I != N; ++I) {
5065 MemPtr.getContainingRecord()))
5070 if (IncludeMember) {
5071 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(MemPtr.getDecl())) {
5075 dyn_cast<IndirectFieldDecl>(MemPtr.getDecl())) {
5079 llvm_unreachable(
"can't construct reference to bound member function");
5083 return MemPtr.getDecl();
5089 bool IncludeMember =
true) {
5093 if (Info.noteFailure()) {
5101 BO->
getRHS(), IncludeMember);
5108 SubobjectDesignator &D = Result.Designator;
5109 if (D.Invalid || !Result.checkNullPointer(Info, E,
CSK_Derived))
5116 auto InvalidCast = [&]() {
5117 if (!Info.checkingPotentialConstantExpression() ||
5118 !Result.AllowConstexprUnknown) {
5119 Info.CCEDiag(E, diag::note_constexpr_invalid_downcast)
5120 << D.MostDerivedType << TargetQT;
5126 if (D.MostDerivedPathLength + E->
path_size() > D.Entries.size())
5127 return InvalidCast();
5131 unsigned NewEntriesSize = D.Entries.size() - E->
path_size();
5134 if (NewEntriesSize == D.MostDerivedPathLength)
5137 FinalType = getAsBaseClass(D.Entries[NewEntriesSize - 1]);
5139 return InvalidCast();
5151 if (!Result.isAbsent())
5154 if (
auto *RD =
T->getAsCXXRecordDecl()) {
5155 if (RD->isInvalidDecl()) {
5159 if (RD->isUnion()) {
5164 std::distance(RD->field_begin(), RD->field_end()));
5168 End = RD->bases_end();
5169 I != End; ++I, ++Index)
5173 for (
const auto *I : RD->fields()) {
5174 if (I->isUnnamedBitField())
5177 I->getType(), Result.getStructField(I->getFieldIndex()));
5183 dyn_cast_or_null<ConstantArrayType>(
T->getAsArrayTypeUnsafe())) {
5185 if (Result.hasArrayFiller())
5197enum EvalStmtResult {
5226 if (!Result.Designator.Invalid && Result.Designator.isOnePastTheEnd()) {
5232 Result.moveInto(Val);
5244 APValue &Val = Info.CurrentCall->createTemporary(VD, VD->
getType(),
5245 ScopeKind::Block, Result);
5250 return Info.noteSideEffect();
5271 const DecompositionDecl *DD);
5274 bool EvaluateConditionDecl =
false) {
5276 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
5280 EvaluateConditionDecl && DD)
5290 if (
auto *VD = BD->getHoldingVar())
5298 if (
auto *DD = dyn_cast_if_present<DecompositionDecl>(VD)) {
5307 if (Info.noteSideEffect())
5309 assert(E->
containsErrors() &&
"valid value-dependent expression should never "
5310 "reach invalid code path.");
5317 if (
Cond->isValueDependent())
5319 FullExpressionRAII
Scope(Info);
5326 return Scope.destroy();
5339struct TempVersionRAII {
5340 CallStackFrame &Frame;
5342 TempVersionRAII(CallStackFrame &Frame) : Frame(Frame) {
5343 Frame.pushTempVersion();
5346 ~TempVersionRAII() {
5347 Frame.popTempVersion();
5355 const SwitchCase *SC =
nullptr);
5361 const Stmt *LoopOrSwitch,
5363 EvalStmtResult &ESR) {
5367 if (!IsSwitch && ESR == ESR_Succeeded) {
5372 if (ESR != ESR_Break && ESR != ESR_Continue)
5376 bool CanBreakOrContinue = !IsSwitch || ESR == ESR_Break;
5377 const Stmt *StackTop = Info.BreakContinueStack.back();
5378 if (CanBreakOrContinue && (StackTop ==
nullptr || StackTop == LoopOrSwitch)) {
5379 Info.BreakContinueStack.pop_back();
5380 if (ESR == ESR_Break)
5381 ESR = ESR_Succeeded;
5386 for (BlockScopeRAII *S : Scopes) {
5387 if (!S->destroy()) {
5399 BlockScopeRAII
Scope(Info);
5401 EvalStmtResult ESR =
EvaluateStmt(Result, Info, Body, Case);
5402 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5411 BlockScopeRAII
Scope(Info);
5418 if (ESR != ESR_Succeeded) {
5419 if (ESR != ESR_Failed && !
Scope.destroy())
5425 FullExpressionRAII CondScope(Info);
5440 if (!CondScope.destroy())
5465 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5469 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5476 llvm_unreachable(
"Should have been converted to Succeeded");
5482 case ESR_CaseNotFound:
5485 Info.FFDiag(
Found->getBeginLoc(),
5486 diag::note_constexpr_stmt_expr_unsupported);
5489 llvm_unreachable(
"Invalid EvalStmtResult!");
5499 Info.CCEDiag(VD->
getLocation(), diag::note_constexpr_static_local)
5509 if (!Info.nextStep(S))
5516 case Stmt::CompoundStmtClass:
5520 case Stmt::LabelStmtClass:
5521 case Stmt::AttributedStmtClass:
5522 case Stmt::DoStmtClass:
5525 case Stmt::CaseStmtClass:
5526 case Stmt::DefaultStmtClass:
5531 case Stmt::IfStmtClass: {
5538 BlockScopeRAII
Scope(Info);
5544 if (ESR != ESR_CaseNotFound) {
5545 assert(ESR != ESR_Succeeded);
5556 if (ESR == ESR_Failed)
5558 if (ESR != ESR_CaseNotFound)
5559 return Scope.destroy() ? ESR : ESR_Failed;
5561 return ESR_CaseNotFound;
5564 if (ESR == ESR_Failed)
5566 if (ESR != ESR_CaseNotFound)
5567 return Scope.destroy() ? ESR : ESR_Failed;
5568 return ESR_CaseNotFound;
5571 case Stmt::WhileStmtClass: {
5572 EvalStmtResult ESR =
5576 if (ESR != ESR_Continue)
5581 case Stmt::ForStmtClass: {
5583 BlockScopeRAII
Scope(Info);
5589 if (ESR != ESR_CaseNotFound) {
5590 assert(ESR != ESR_Succeeded);
5595 EvalStmtResult ESR =
5599 if (ESR != ESR_Continue)
5601 if (
const auto *Inc = FS->
getInc()) {
5602 if (Inc->isValueDependent()) {
5606 FullExpressionRAII IncScope(Info);
5614 case Stmt::DeclStmtClass: {
5618 for (
const auto *D : DS->
decls()) {
5619 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
5622 if (VD->hasLocalStorage() && !VD->getInit())
5630 return ESR_CaseNotFound;
5634 return ESR_CaseNotFound;
5640 if (
const Expr *E = dyn_cast<Expr>(S)) {
5649 FullExpressionRAII
Scope(Info);
5653 return ESR_Succeeded;
5659 case Stmt::NullStmtClass:
5660 return ESR_Succeeded;
5662 case Stmt::DeclStmtClass: {
5664 for (
const auto *D : DS->
decls()) {
5665 const VarDecl *VD = dyn_cast_or_null<VarDecl>(D);
5669 FullExpressionRAII
Scope(Info);
5671 !Info.noteFailure())
5673 if (!
Scope.destroy())
5676 return ESR_Succeeded;
5679 case Stmt::ReturnStmtClass: {
5681 FullExpressionRAII
Scope(Info);
5690 :
Evaluate(Result.Value, Info, RetExpr)))
5692 return Scope.destroy() ? ESR_Returned : ESR_Failed;
5695 case Stmt::CompoundStmtClass: {
5696 BlockScopeRAII
Scope(Info);
5699 for (
const auto *BI : CS->
body()) {
5700 EvalStmtResult ESR =
EvaluateStmt(Result, Info, BI, Case);
5701 if (ESR == ESR_Succeeded)
5703 else if (ESR != ESR_CaseNotFound) {
5704 if (ESR != ESR_Failed && !
Scope.destroy())
5710 return ESR_CaseNotFound;
5711 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5714 case Stmt::IfStmtClass: {
5718 BlockScopeRAII
Scope(Info);
5721 if (ESR != ESR_Succeeded) {
5722 if (ESR != ESR_Failed && !
Scope.destroy())
5732 if (!Info.InConstantContext)
5739 EvalStmtResult ESR =
EvaluateStmt(Result, Info, SubStmt);
5740 if (ESR != ESR_Succeeded) {
5741 if (ESR != ESR_Failed && !
Scope.destroy())
5746 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5749 case Stmt::WhileStmtClass: {
5752 BlockScopeRAII
Scope(Info);
5764 if (ESR != ESR_Continue) {
5765 if (ESR != ESR_Failed && !
Scope.destroy())
5769 if (!
Scope.destroy())
5772 return ESR_Succeeded;
5775 case Stmt::DoStmtClass: {
5782 if (ESR != ESR_Continue)
5791 FullExpressionRAII CondScope(Info);
5793 !CondScope.destroy())
5796 return ESR_Succeeded;
5799 case Stmt::ForStmtClass: {
5801 BlockScopeRAII ForScope(Info);
5804 if (ESR != ESR_Succeeded) {
5805 if (ESR != ESR_Failed && !ForScope.destroy())
5811 BlockScopeRAII IterScope(Info);
5812 bool Continue =
true;
5818 if (!IterScope.destroy())
5826 if (ESR != ESR_Continue) {
5827 if (ESR != ESR_Failed && (!IterScope.destroy() || !ForScope.destroy()))
5832 if (
const auto *Inc = FS->
getInc()) {
5833 if (Inc->isValueDependent()) {
5837 FullExpressionRAII IncScope(Info);
5843 if (!IterScope.destroy())
5846 return ForScope.destroy() ? ESR_Succeeded : ESR_Failed;
5849 case Stmt::CXXForRangeStmtClass: {
5851 BlockScopeRAII
Scope(Info);
5856 if (ESR != ESR_Succeeded) {
5857 if (ESR != ESR_Failed && !
Scope.destroy())
5865 if (ESR != ESR_Succeeded) {
5866 if (ESR != ESR_Failed && !
Scope.destroy())
5878 if (ESR != ESR_Succeeded) {
5879 if (ESR != ESR_Failed && !
Scope.destroy())
5884 if (ESR != ESR_Succeeded) {
5885 if (ESR != ESR_Failed && !
Scope.destroy())
5898 bool Continue =
true;
5899 FullExpressionRAII CondExpr(Info);
5907 BlockScopeRAII InnerScope(Info);
5909 if (ESR != ESR_Succeeded) {
5910 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
5919 if (ESR != ESR_Continue) {
5920 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
5933 if (!InnerScope.destroy())
5937 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5940 case Stmt::SwitchStmtClass:
5943 case Stmt::ContinueStmtClass:
5944 case Stmt::BreakStmtClass: {
5946 Info.BreakContinueStack.push_back(B->getNamedLoopOrSwitch());
5950 case Stmt::LabelStmtClass:
5953 case Stmt::AttributedStmtClass: {
5955 const auto *SS = AS->getSubStmt();
5956 MSConstexprContextRAII ConstexprContext(
5960 auto LO = Info.getASTContext().getLangOpts();
5961 if (LO.CXXAssumptions && !LO.MSVCCompat) {
5962 for (
auto *
Attr : AS->getAttrs()) {
5963 auto *AA = dyn_cast<CXXAssumeAttr>(
Attr);
5967 auto *Assumption = AA->getAssumption();
5968 if (Assumption->isValueDependent())
5971 if (Assumption->HasSideEffects(Info.getASTContext()))
5978 Info.CCEDiag(Assumption->getExprLoc(),
5979 diag::note_constexpr_assumption_failed);
5988 case Stmt::CaseStmtClass:
5989 case Stmt::DefaultStmtClass:
5991 case Stmt::CXXTryStmtClass:
6003 bool IsValueInitialization) {
6010 if (!CD->
isConstexpr() && !IsValueInitialization) {
6011 if (Info.getLangOpts().CPlusPlus11) {
6014 Info.CCEDiag(Loc, diag::note_constexpr_invalid_function, 1)
6016 Info.Note(CD->
getLocation(), diag::note_declared_at);
6018 Info.CCEDiag(Loc, diag::note_invalid_subexpr_in_const_expr);
6032 if (Info.checkingPotentialConstantExpression() && !
Definition &&
6040 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6049 Info.CCEDiag(CallLoc, diag::note_constexpr_virtual_call);
6052 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6058 (
Definition->isConstexpr() || (Info.CurrentCall->CanEvalMSConstexpr &&
6068 StringRef Name = DiagDecl->
getName();
6070 Name ==
"__assert_rtn" || Name ==
"__assert_fail" || Name ==
"_wassert";
6072 Info.FFDiag(CallLoc, diag::note_constexpr_assert_failed);
6077 if (Info.getLangOpts().CPlusPlus11) {
6080 auto *CD = dyn_cast<CXXConstructorDecl>(DiagDecl);
6081 if (CD && CD->isInheritingConstructor()) {
6082 auto *Inherited = CD->getInheritedConstructor().getConstructor();
6083 if (!Inherited->isConstexpr())
6084 DiagDecl = CD = Inherited;
6090 if (CD && CD->isInheritingConstructor())
6091 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_inhctor, 1)
6092 << CD->getInheritedConstructor().getConstructor()->getParent();
6094 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_function, 1)
6096 Info.Note(DiagDecl->
getLocation(), diag::note_declared_at);
6098 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6104struct CheckDynamicTypeHandler {
6106 typedef bool result_type;
6107 bool failed() {
return false; }
6108 bool found(
APValue &Subobj, QualType SubobjType) {
return true; }
6109 bool found(
APSInt &
Value, QualType SubobjType) {
return true; }
6110 bool found(APFloat &
Value, QualType SubobjType) {
return true; }
6118 if (
This.Designator.Invalid)
6130 if (
This.Designator.isOnePastTheEnd() ||
6131 This.Designator.isMostDerivedAnUnsizedArray()) {
6132 Info.FFDiag(E,
This.Designator.isOnePastTheEnd()
6133 ? diag::note_constexpr_access_past_end
6134 : diag::note_constexpr_access_unsized_array)
6137 }
else if (Polymorphic) {
6140 if (!Info.checkingPotentialConstantExpression() ||
6141 !
This.AllowConstexprUnknown) {
6146 Info.FFDiag(E, diag::note_constexpr_polymorphic_unknown_dynamic_type)
6154 CheckDynamicTypeHandler Handler{AK};
6177 unsigned PathLength) {
6178 assert(PathLength >=
Designator.MostDerivedPathLength && PathLength <=
6179 Designator.Entries.size() &&
"invalid path length");
6180 return (PathLength ==
Designator.MostDerivedPathLength)
6181 ?
Designator.MostDerivedType->getAsCXXRecordDecl()
6182 : getAsBaseClass(
Designator.Entries[PathLength - 1]);
6195 return std::nullopt;
6197 if (
This.Designator.Invalid)
6198 return std::nullopt;
6207 This.Designator.MostDerivedType->getAsCXXRecordDecl();
6208 if (!Class || Class->getNumVBases()) {
6210 return std::nullopt;
6218 for (
unsigned PathLength =
This.Designator.MostDerivedPathLength;
6219 PathLength <= Path.size(); ++PathLength) {
6220 switch (Info.isEvaluatingCtorDtor(
This.getLValueBase(),
6221 Path.slice(0, PathLength))) {
6222 case ConstructionPhase::Bases:
6223 case ConstructionPhase::DestroyingBases:
6228 case ConstructionPhase::None:
6229 case ConstructionPhase::AfterBases:
6230 case ConstructionPhase::AfterFields:
6231 case ConstructionPhase::Destroying:
6243 return std::nullopt;
6261 unsigned PathLength = DynType->PathLength;
6262 for (; PathLength <=
This.Designator.Entries.size(); ++PathLength) {
6265 Found->getCorrespondingMethodDeclaredInClass(Class,
false);
6275 if (Callee->isPureVirtual()) {
6276 Info.FFDiag(E, diag::note_constexpr_pure_virtual_call, 1) << Callee;
6277 Info.Note(Callee->getLocation(), diag::note_declared_at);
6284 Found->getReturnType())) {
6285 CovariantAdjustmentPath.push_back(Callee->getReturnType());
6286 for (
unsigned CovariantPathLength = PathLength + 1;
6287 CovariantPathLength !=
This.Designator.Entries.size();
6288 ++CovariantPathLength) {
6292 Found->getCorrespondingMethodDeclaredInClass(NextClass,
false);
6294 Next->getReturnType(), CovariantAdjustmentPath.back()))
6295 CovariantAdjustmentPath.push_back(
Next->getReturnType());
6298 CovariantAdjustmentPath.back()))
6299 CovariantAdjustmentPath.push_back(
Found->getReturnType());
6315 assert(Result.isLValue() &&
6316 "unexpected kind of APValue for covariant return");
6317 if (Result.isNullPointer())
6321 LVal.setFrom(Info.Ctx, Result);
6323 const CXXRecordDecl *OldClass = Path[0]->getPointeeCXXRecordDecl();
6324 for (
unsigned I = 1; I != Path.size(); ++I) {
6325 const CXXRecordDecl *NewClass = Path[I]->getPointeeCXXRecordDecl();
6326 assert(OldClass && NewClass &&
"unexpected kind of covariant return");
6327 if (OldClass != NewClass &&
6330 OldClass = NewClass;
6333 LVal.moveInto(Result);
6342 auto *BaseClass = BaseSpec.getType()->getAsCXXRecordDecl();
6344 return BaseSpec.getAccessSpecifier() ==
AS_public;
6346 llvm_unreachable(
"Base is not a direct base of Derived");
6356 SubobjectDesignator &D = Ptr.Designator;
6362 if (Ptr.isNullPointer() && !E->
isGLValue())
6368 std::optional<DynamicType> DynType =
6380 assert(
C &&
"dynamic_cast target is not void pointer nor class");
6388 Ptr.setNull(Info.Ctx, E->
getType());
6395 DynType->Type->isDerivedFrom(
C)))
6397 else if (!Paths || Paths->begin() == Paths->end())
6399 else if (Paths->isAmbiguous(CQT))
6402 assert(Paths->front().Access !=
AS_public &&
"why did the cast fail?");
6405 Info.FFDiag(E, diag::note_constexpr_dynamic_cast_to_reference_failed)
6406 << DiagKind << Ptr.Designator.getType(Info.Ctx)
6415 for (
int PathLength = Ptr.Designator.Entries.size();
6416 PathLength >= (
int)DynType->PathLength; --PathLength) {
6421 if (PathLength > (
int)DynType->PathLength &&
6424 return RuntimeCheckFailed(
nullptr);
6431 if (DynType->Type->isDerivedFrom(
C, Paths) && !Paths.
isAmbiguous(CQT) &&
6444 return RuntimeCheckFailed(&Paths);
6448struct StartLifetimeOfUnionMemberHandler {
6450 const Expr *LHSExpr;
6451 const FieldDecl *
Field;
6453 bool Failed =
false;
6456 typedef bool result_type;
6457 bool failed() {
return Failed; }
6458 bool found(
APValue &Subobj, QualType SubobjType) {
6473 }
else if (DuringInit) {
6477 Info.FFDiag(LHSExpr,
6478 diag::note_constexpr_union_member_change_during_init);
6487 llvm_unreachable(
"wrong value kind for union object");
6489 bool found(APFloat &
Value, QualType SubobjType) {
6490 llvm_unreachable(
"wrong value kind for union object");
6495const AccessKinds StartLifetimeOfUnionMemberHandler::AccessKind;
6502 const Expr *LHSExpr,
6503 const LValue &LHS) {
6504 if (LHS.InvalidBase || LHS.Designator.Invalid)
6510 unsigned PathLength = LHS.Designator.Entries.size();
6511 for (
const Expr *E = LHSExpr; E !=
nullptr;) {
6513 if (
auto *ME = dyn_cast<MemberExpr>(E)) {
6514 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
6517 if (!FD || FD->getType()->isReferenceType())
6521 if (FD->getParent()->isUnion()) {
6526 FD->getType()->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
6527 if (!RD || RD->hasTrivialDefaultConstructor())
6528 UnionPathLengths.push_back({PathLength - 1, FD});
6534 LHS.Designator.Entries[PathLength]
6535 .getAsBaseOrMember().getPointer()));
6539 }
else if (
auto *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
6541 auto *
Base = ASE->getBase()->IgnoreImplicit();
6542 if (!
Base->getType()->isArrayType())
6548 }
else if (
auto *ICE = dyn_cast<ImplicitCastExpr>(E)) {
6551 if (ICE->getCastKind() == CK_NoOp)
6553 if (ICE->getCastKind() != CK_DerivedToBase &&
6554 ICE->getCastKind() != CK_UncheckedDerivedToBase)
6558 if (Elt->isVirtual()) {
6567 LHS.Designator.Entries[PathLength]
6568 .getAsBaseOrMember().getPointer()));
6578 if (UnionPathLengths.empty())
6583 CompleteObject Obj =
6587 for (std::pair<unsigned, const FieldDecl *> LengthAndField :
6588 llvm::reverse(UnionPathLengths)) {
6590 SubobjectDesignator D = LHS.Designator;
6591 D.truncate(Info.Ctx, LHS.Base, LengthAndField.first);
6593 bool DuringInit = Info.isEvaluatingCtorDtor(LHS.Base, D.Entries) ==
6594 ConstructionPhase::AfterBases;
6595 StartLifetimeOfUnionMemberHandler StartLifetime{
6596 Info, LHSExpr, LengthAndField.second, DuringInit};
6605 CallRef
Call, EvalInfo &Info,
bool NonNull =
false,
6606 APValue **EvaluatedArg =
nullptr) {
6613 APValue &
V = PVD ? Info.CurrentCall->createParam(
Call, PVD, LV)
6614 : Info.CurrentCall->createTemporary(Arg, Arg->
getType(),
6615 ScopeKind::Call, LV);
6621 if (
NonNull &&
V.isLValue() &&
V.isNullPointer()) {
6622 Info.CCEDiag(Arg, diag::note_non_null_attribute_failed);
6635 bool RightToLeft =
false,
6636 LValue *ObjectArg =
nullptr) {
6638 llvm::SmallBitVector ForbiddenNullArgs;
6639 if (Callee->hasAttr<NonNullAttr>()) {
6640 ForbiddenNullArgs.resize(Args.size());
6641 for (
const auto *
Attr : Callee->specific_attrs<NonNullAttr>()) {
6642 if (!
Attr->args_size()) {
6643 ForbiddenNullArgs.set();
6646 for (
auto Idx :
Attr->args()) {
6647 unsigned ASTIdx = Idx.getASTIndex();
6648 if (ASTIdx >= Args.size())
6650 ForbiddenNullArgs[ASTIdx] =
true;
6654 for (
unsigned I = 0; I < Args.size(); I++) {
6655 unsigned Idx = RightToLeft ? Args.size() - I - 1 : I;
6657 Idx < Callee->getNumParams() ? Callee->getParamDecl(Idx) :
nullptr;
6658 bool NonNull = !ForbiddenNullArgs.empty() && ForbiddenNullArgs[Idx];
6663 if (!Info.noteFailure())
6668 ObjectArg->setFrom(Info.Ctx, *That);
6677 bool CopyObjectRepresentation) {
6679 CallStackFrame *Frame = Info.CurrentCall;
6680 APValue *RefValue = Info.getParamSlot(Frame->Arguments, Param);
6688 RefLValue.setFrom(Info.Ctx, *RefValue);
6691 CopyObjectRepresentation);
6697 const LValue *ObjectArg,
const Expr *E,
6699 const Stmt *Body, EvalInfo &Info,
6700 APValue &Result,
const LValue *ResultSlot) {
6701 if (!Info.CheckCallLimit(CallLoc))
6730 ObjectArg->moveInto(Result);
6739 if (!Info.checkingPotentialConstantExpression())
6741 Frame.LambdaThisCaptureField);
6744 StmtResult Ret = {Result, ResultSlot};
6746 if (ESR == ESR_Succeeded) {
6747 if (Callee->getReturnType()->isVoidType())
6749 Info.FFDiag(Callee->getEndLoc(), diag::note_constexpr_no_return);
6751 return ESR == ESR_Returned;
6758 EvalInfo &Info,
APValue &Result) {
6760 if (!Info.CheckCallLimit(CallLoc))
6765 Info.FFDiag(CallLoc, diag::note_constexpr_virtual_base) << RD;
6769 EvalInfo::EvaluatingConstructorRAII EvalObj(
6771 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries},
6778 StmtResult Ret = {RetVal,
nullptr};
6783 if ((*I)->getInit()->isValueDependent()) {
6787 FullExpressionRAII InitScope(Info);
6789 !InitScope.destroy())
6812 if (!Result.hasValue()) {
6825 BlockScopeRAII LifetimeExtendedScope(Info);
6828 unsigned BasesSeen = 0;
6833 auto SkipToField = [&](
FieldDecl *FD,
bool Indirect) {
6838 assert(Indirect &&
"fields out of order?");
6844 assert(FieldIt != RD->
field_end() &&
"missing field?");
6845 if (!FieldIt->isUnnamedBitField())
6848 Result.getStructField(FieldIt->getFieldIndex()));
6853 LValue Subobject =
This;
6854 LValue SubobjectParent =
This;
6859 if (I->isBaseInitializer()) {
6860 QualType BaseType(I->getBaseClass(), 0);
6864 assert(!BaseIt->
isVirtual() &&
"virtual base for literal type");
6866 "base class initializers not in expected order");
6870 BaseType->getAsCXXRecordDecl(), &Layout))
6872 Value = &Result.getStructBase(BasesSeen++);
6873 }
else if ((FD = I->getMember())) {
6878 Value = &Result.getUnionValue();
6880 SkipToField(FD,
false);
6886 auto IndirectFieldChain = IFD->chain();
6887 for (
auto *
C : IndirectFieldChain) {
6896 (
Value->isUnion() &&
6909 if (
C == IndirectFieldChain.back())
6910 SubobjectParent = Subobject;
6916 if (
C == IndirectFieldChain.front() && !RD->
isUnion())
6917 SkipToField(FD,
true);
6922 llvm_unreachable(
"unknown base initializer kind");
6929 if (
Init->isValueDependent()) {
6933 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &SubobjectParent,
6935 FullExpressionRAII InitScope(Info);
6941 if (!Info.noteFailure())
6950 if (!Info.noteFailure())
6958 if (I->isBaseInitializer() && BasesSeen == RD->
getNumBases())
6959 EvalObj.finishedConstructingBases();
6964 for (; FieldIt != RD->
field_end(); ++FieldIt) {
6965 if (!FieldIt->isUnnamedBitField())
6968 Result.getStructField(FieldIt->getFieldIndex()));
6972 EvalObj.finishedConstructingFields();
6976 LifetimeExtendedScope.destroy();
6982 EvalInfo &Info,
APValue &Result) {
6983 CallScopeRAII CallScope(Info);
6989 CallScope.destroy();
6999 if (
Value.isAbsent() && !
T->isNullPtrType()) {
7001 This.moveInto(Printable);
7003 diag::note_constexpr_destroy_out_of_lifetime)
7020 LValue ElemLV =
This;
7021 ElemLV.addArray(Info, &LocE, CAT);
7028 if (Size && Size >
Value.getArrayInitializedElts())
7033 for (Size =
Value.getArraySize(); Size != 0; --Size) {
7034 APValue &Elem =
Value.getArrayInitializedElt(Size - 1);
7047 if (
T.isDestructedType()) {
7049 diag::note_constexpr_unsupported_destruction)
7059 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_virtual_base) << RD;
7084 if (!Info.CheckCallLimit(CallRange.
getBegin()))
7093 CallStackFrame Frame(Info, CallRange,
Definition, &
This,
nullptr,
7098 EvalInfo::EvaluatingDestructorRAII EvalObj(
7100 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries});
7101 if (!EvalObj.DidInsert) {
7108 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_double_destroy);
7115 StmtResult Ret = {RetVal,
nullptr};
7128 for (
const FieldDecl *FD : llvm::reverse(Fields)) {
7129 if (FD->isUnnamedBitField())
7132 LValue Subobject =
This;
7136 APValue *SubobjectValue = &
Value.getStructField(FD->getFieldIndex());
7143 EvalObj.startedDestroyingBases();
7150 LValue Subobject =
This;
7152 BaseType->getAsCXXRecordDecl(), &Layout))
7155 APValue *SubobjectValue = &
Value.getStructBase(BasesLeft);
7160 assert(BasesLeft == 0 &&
"NumBases was wrong?");
7168struct DestroyObjectHandler {
7174 typedef bool result_type;
7175 bool failed() {
return false; }
7176 bool found(
APValue &Subobj, QualType SubobjType) {
7181 Info.FFDiag(E, diag::note_constexpr_destroy_complex_elem);
7184 bool found(APFloat &
Value, QualType SubobjType) {
7185 Info.FFDiag(E, diag::note_constexpr_destroy_complex_elem);
7217 if (Info.checkingPotentialConstantExpression() ||
7218 Info.SpeculativeEvaluationDepth)
7222 auto Caller = Info.getStdAllocatorCaller(
"allocate");
7224 Info.FFDiag(E->
getExprLoc(), Info.getLangOpts().CPlusPlus20
7225 ? diag::note_constexpr_new_untyped
7226 : diag::note_constexpr_new);
7230 QualType ElemType = Caller.ElemType;
7233 diag::note_constexpr_new_not_complete_object_type)
7241 bool IsNothrow =
false;
7242 for (
unsigned I = 1, N = E->
getNumArgs(); I != N; ++I) {
7250 APInt Size, Remainder;
7251 APInt ElemSizeAP(ByteSize.getBitWidth(), ElemSize.
getQuantity());
7252 APInt::udivrem(ByteSize, ElemSizeAP, Size, Remainder);
7253 if (Remainder != 0) {
7255 Info.FFDiag(E->
getExprLoc(), diag::note_constexpr_operator_new_bad_size)
7256 << ByteSize <<
APSInt(ElemSizeAP,
true) << ElemType;
7260 if (!Info.CheckArraySize(E->
getBeginLoc(), ByteSize.getActiveBits(),
7261 Size.getZExtValue(), !IsNothrow)) {
7263 Result.setNull(Info.Ctx, E->
getType());
7271 APValue *Val = Info.createHeapAlloc(Caller.Call, AllocType, Result);
7280 return DD->isVirtual();
7287 return DD->isVirtual() ? DD->getOperatorDelete() :
nullptr;
7298 DynAlloc::Kind DeallocKind) {
7299 auto PointerAsString = [&] {
7305 Info.FFDiag(E, diag::note_constexpr_delete_not_heap_alloc)
7306 << PointerAsString();
7309 return std::nullopt;
7312 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
7314 Info.FFDiag(E, diag::note_constexpr_double_delete);
7315 return std::nullopt;
7318 if (DeallocKind != (*Alloc)->getKind()) {
7320 Info.FFDiag(E, diag::note_constexpr_new_delete_mismatch)
7321 << DeallocKind << (*Alloc)->getKind() << AllocType;
7323 return std::nullopt;
7326 bool Subobject =
false;
7327 if (DeallocKind == DynAlloc::New) {
7328 Subobject =
Pointer.Designator.MostDerivedPathLength != 0 ||
7329 Pointer.Designator.isOnePastTheEnd();
7331 Subobject =
Pointer.Designator.Entries.size() != 1 ||
7332 Pointer.Designator.Entries[0].getAsArrayIndex() != 0;
7335 Info.FFDiag(E, diag::note_constexpr_delete_subobject)
7336 << PointerAsString() <<
Pointer.Designator.isOnePastTheEnd();
7337 return std::nullopt;
7345 if (Info.checkingPotentialConstantExpression() ||
7346 Info.SpeculativeEvaluationDepth)
7350 if (!Info.getStdAllocatorCaller(
"deallocate")) {
7358 for (
unsigned I = 1, N = E->
getNumArgs(); I != N; ++I)
7361 if (
Pointer.Designator.Invalid)
7366 if (
Pointer.isNullPointer()) {
7367 Info.CCEDiag(E->
getExprLoc(), diag::note_constexpr_deallocate_null);
7383class BitCastBuffer {
7389 SmallVector<std::optional<unsigned char>, 32> Bytes;
7391 static_assert(std::numeric_limits<unsigned char>::digits >= 8,
7392 "Need at least 8 bit unsigned char");
7394 bool TargetIsLittleEndian;
7397 BitCastBuffer(CharUnits Width,
bool TargetIsLittleEndian)
7398 : Bytes(Width.getQuantity()),
7399 TargetIsLittleEndian(TargetIsLittleEndian) {}
7401 [[nodiscard]]
bool readObject(CharUnits Offset, CharUnits Width,
7402 SmallVectorImpl<unsigned char> &Output)
const {
7403 for (CharUnits I = Offset, E = Offset + Width; I != E; ++I) {
7406 if (!Bytes[I.getQuantity()])
7408 Output.push_back(*Bytes[I.getQuantity()]);
7410 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
7411 std::reverse(Output.begin(), Output.end());
7415 void writeObject(CharUnits Offset, SmallVectorImpl<unsigned char> &Input) {
7416 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
7417 std::reverse(Input.begin(), Input.end());
7420 for (
unsigned char Byte : Input) {
7421 assert(!Bytes[Offset.
getQuantity() + Index] &&
"overwriting a byte?");
7427 size_t size() {
return Bytes.size(); }
7432class APValueToBufferConverter {
7434 BitCastBuffer Buffer;
7437 APValueToBufferConverter(EvalInfo &Info, CharUnits ObjectWidth,
7440 Buffer(ObjectWidth, Info.Ctx.getTargetInfo().isLittleEndian()),
7443 bool visit(
const APValue &Val, QualType Ty) {
7448 bool visit(
const APValue &Val, QualType Ty, CharUnits Offset) {
7449 assert((
size_t)Offset.
getQuantity() <= Buffer.size());
7462 return visitInt(Val.
getInt(), Ty, Offset);
7464 return visitFloat(Val.
getFloat(), Ty, Offset);
7466 return visitArray(Val, Ty, Offset);
7468 return visitRecord(Val, Ty, Offset);
7470 return visitVector(Val, Ty, Offset);
7474 return visitComplex(Val, Ty, Offset);
7482 diag::note_constexpr_bit_cast_unsupported_type)
7488 llvm_unreachable(
"LValue subobject in bit_cast?");
7490 llvm_unreachable(
"Unhandled APValue::ValueKind");
7493 bool visitRecord(
const APValue &Val, QualType Ty, CharUnits Offset) {
7498 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
7499 for (
size_t I = 0, E = CXXRD->getNumBases(); I != E; ++I) {
7500 const CXXBaseSpecifier &BS = CXXRD->bases_begin()[I];
7505 if (!
Base.isStruct())
7508 if (!visitRecord(Base, BS.
getType(),
7515 unsigned FieldIdx = 0;
7516 for (FieldDecl *FD : RD->
fields()) {
7517 if (FD->isBitField()) {
7519 diag::note_constexpr_bit_cast_unsupported_bitfield);
7525 assert(FieldOffsetBits % Info.Ctx.
getCharWidth() == 0 &&
7526 "only bit-fields can have sub-char alignment");
7527 CharUnits FieldOffset =
7529 QualType FieldTy = FD->getType();
7538 bool visitArray(
const APValue &Val, QualType Ty, CharUnits Offset) {
7548 for (
unsigned I = 0; I != NumInitializedElts; ++I) {
7550 if (!visit(SubObj, CAT->
getElementType(), Offset + I * ElemWidth))
7557 for (
unsigned I = NumInitializedElts; I != ArraySize; ++I) {
7558 if (!visit(Filler, CAT->
getElementType(), Offset + I * ElemWidth))
7566 bool visitComplex(
const APValue &Val, QualType Ty, CharUnits Offset) {
7567 const ComplexType *ComplexTy = Ty->
castAs<ComplexType>();
7574 Offset + (0 * EltSizeChars)))
7577 Offset + (1 * EltSizeChars)))
7581 Offset + (0 * EltSizeChars)))
7584 Offset + (1 * EltSizeChars)))
7591 bool visitVector(
const APValue &Val, QualType Ty, CharUnits Offset) {
7592 const VectorType *VTy = Ty->
castAs<VectorType>();
7607 llvm::APInt Res = llvm::APInt::getZero(NElts);
7608 for (
unsigned I = 0; I < NElts; ++I) {
7610 assert(EltAsInt.isUnsigned() && EltAsInt.getBitWidth() == 1 &&
7611 "bool vector element must be 1-bit unsigned integer!");
7613 Res.insertBits(EltAsInt, BigEndian ? (NElts - I - 1) : I);
7616 SmallVector<uint8_t, 8> Bytes(NElts / 8);
7617 llvm::StoreIntToMemory(Res, &*Bytes.begin(), NElts / 8);
7618 Buffer.writeObject(Offset, Bytes);
7623 for (
unsigned I = 0; I < NElts; ++I) {
7624 if (!visit(Val.
getVectorElt(I), EltTy, Offset + I * EltSizeChars))
7632 bool visitInt(
const APSInt &Val, QualType Ty, CharUnits Offset) {
7633 APSInt AdjustedVal = Val;
7634 unsigned Width = AdjustedVal.getBitWidth();
7637 AdjustedVal = AdjustedVal.extend(Width);
7640 SmallVector<uint8_t, 8> Bytes(Width / 8);
7641 llvm::StoreIntToMemory(AdjustedVal, &*Bytes.begin(), Width / 8);
7642 Buffer.writeObject(Offset, Bytes);
7646 bool visitFloat(
const APFloat &Val, QualType Ty, CharUnits Offset) {
7647 APSInt AsInt(Val.bitcastToAPInt());
7648 return visitInt(AsInt, Ty, Offset);
7652 static std::optional<BitCastBuffer>
7655 APValueToBufferConverter Converter(Info, DstSize, BCE);
7657 return std::nullopt;
7658 return Converter.Buffer;
7663class BufferToAPValueConverter {
7665 const BitCastBuffer &Buffer;
7668 BufferToAPValueConverter(EvalInfo &Info,
const BitCastBuffer &Buffer,
7670 : Info(Info), Buffer(Buffer), BCE(BCE) {}
7675 std::nullopt_t unsupportedType(QualType Ty) {
7677 diag::note_constexpr_bit_cast_unsupported_type)
7679 return std::nullopt;
7682 std::nullopt_t unrepresentableValue(QualType Ty,
const APSInt &Val) {
7684 diag::note_constexpr_bit_cast_unrepresentable_value)
7686 return std::nullopt;
7689 std::optional<APValue> visit(
const BuiltinType *
T, CharUnits Offset,
7690 const EnumType *EnumSugar =
nullptr) {
7693 return APValue((Expr *)
nullptr,
7695 APValue::NoLValuePath{},
true);
7704 const llvm::fltSemantics &Semantics =
7706 unsigned NumBits = llvm::APFloatBase::getSizeInBits(Semantics);
7707 assert(NumBits % 8 == 0);
7713 SmallVector<uint8_t, 8> Bytes;
7714 if (!Buffer.readObject(Offset,
SizeOf, Bytes)) {
7717 bool IsStdByte = EnumSugar && EnumSugar->isStdByteType();
7721 if (!IsStdByte && !IsUChar) {
7722 QualType DisplayType(EnumSugar ? (
const Type *)EnumSugar :
T, 0);
7724 diag::note_constexpr_bit_cast_indet_dest)
7725 << DisplayType << Info.Ctx.
getLangOpts().CharIsSigned;
7726 return std::nullopt;
7733 llvm::LoadIntFromMemory(Val, &*Bytes.begin(), Bytes.size());
7738 unsigned IntWidth = Info.Ctx.
getIntWidth(QualType(
T, 0));
7739 if (IntWidth != Val.getBitWidth()) {
7740 APSInt Truncated = Val.trunc(IntWidth);
7741 if (Truncated.extend(Val.getBitWidth()) != Val)
7742 return unrepresentableValue(QualType(
T, 0), Val);
7750 const llvm::fltSemantics &Semantics =
7755 return unsupportedType(QualType(
T, 0));
7758 std::optional<APValue> visit(
const RecordType *RTy, CharUnits Offset) {
7759 const RecordDecl *RD = RTy->getAsRecordDecl();
7762 unsigned NumBases = 0;
7763 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
7764 NumBases = CXXRD->getNumBases();
7766 APValue ResultVal(APValue::UninitStruct(), NumBases,
7770 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
7771 for (
size_t I = 0, E = CXXRD->getNumBases(); I != E; ++I) {
7772 const CXXBaseSpecifier &BS = CXXRD->bases_begin()[I];
7775 std::optional<APValue> SubObj = visitType(
7778 return std::nullopt;
7779 ResultVal.getStructBase(I) = *SubObj;
7784 unsigned FieldIdx = 0;
7785 for (FieldDecl *FD : RD->
fields()) {
7788 if (FD->isBitField()) {
7790 diag::note_constexpr_bit_cast_unsupported_bitfield);
7791 return std::nullopt;
7795 assert(FieldOffsetBits % Info.Ctx.
getCharWidth() == 0);
7797 CharUnits FieldOffset =
7800 QualType FieldTy = FD->getType();
7801 std::optional<APValue> SubObj = visitType(FieldTy, FieldOffset);
7803 return std::nullopt;
7804 ResultVal.getStructField(FieldIdx) = *SubObj;
7811 std::optional<APValue> visit(
const EnumType *Ty, CharUnits Offset) {
7812 QualType RepresentationType =
7813 Ty->getDecl()->getDefinitionOrSelf()->getIntegerType();
7814 assert(!RepresentationType.
isNull() &&
7815 "enum forward decl should be caught by Sema");
7816 const auto *AsBuiltin =
7820 return visit(AsBuiltin, Offset, Ty);
7823 std::optional<APValue> visit(
const ConstantArrayType *Ty, CharUnits Offset) {
7827 APValue ArrayValue(APValue::UninitArray(), Size, Size);
7828 for (
size_t I = 0; I !=
Size; ++I) {
7829 std::optional<APValue> ElementValue =
7832 return std::nullopt;
7833 ArrayValue.getArrayInitializedElt(I) = std::move(*ElementValue);
7839 std::optional<APValue> visit(
const ComplexType *Ty, CharUnits Offset) {
7844 std::optional<APValue> Values[2];
7845 for (
unsigned I = 0; I != 2; ++I) {
7846 Values[I] = visitType(Ty->
getElementType(), Offset + I * ElementWidth);
7848 return std::nullopt;
7852 return APValue(Values[0]->getInt(), Values[1]->getInt());
7853 return APValue(Values[0]->getFloat(), Values[1]->getFloat());
7856 std::optional<APValue> visit(
const VectorType *VTy, CharUnits Offset) {
7862 SmallVector<APValue, 4> Elts;
7863 Elts.reserve(NElts);
7875 SmallVector<uint8_t, 8> Bytes;
7876 Bytes.reserve(NElts / 8);
7878 return std::nullopt;
7880 APSInt SValInt(NElts,
true);
7881 llvm::LoadIntFromMemory(SValInt, &*Bytes.begin(), Bytes.size());
7883 for (
unsigned I = 0; I < NElts; ++I) {
7885 SValInt.extractBits(1, (BigEndian ? NElts - I - 1 : I) * EltSize);
7893 for (
unsigned I = 0; I < NElts; ++I) {
7894 std::optional<APValue> EltValue =
7895 visitType(EltTy, Offset + I * EltSizeChars);
7897 return std::nullopt;
7898 Elts.push_back(std::move(*EltValue));
7902 return APValue(Elts.data(), Elts.size());
7905 std::optional<APValue> visit(
const Type *Ty, CharUnits Offset) {
7906 return unsupportedType(QualType(Ty, 0));
7909 std::optional<APValue> visitType(QualType Ty, CharUnits Offset) {
7913#define TYPE(Class, Base) \
7915 return visit(cast<Class##Type>(Can.getTypePtr()), Offset);
7916#define ABSTRACT_TYPE(Class, Base)
7917#define NON_CANONICAL_TYPE(Class, Base) \
7919 llvm_unreachable("non-canonical type should be impossible!");
7920#define DEPENDENT_TYPE(Class, Base) \
7923 "dependent types aren't supported in the constant evaluator!");
7924#define NON_CANONICAL_UNLESS_DEPENDENT(Class, Base) \
7926 llvm_unreachable("either dependent or not canonical!");
7927#include "clang/AST/TypeNodes.inc"
7929 llvm_unreachable(
"Unhandled Type::TypeClass");
7934 static std::optional<APValue> convert(EvalInfo &Info, BitCastBuffer &Buffer,
7936 BufferToAPValueConverter Converter(Info, Buffer, BCE);
7941static bool checkBitCastConstexprEligibilityType(SourceLocation Loc,
7942 QualType Ty, EvalInfo *Info,
7943 const ASTContext &Ctx,
7944 bool CheckingDest) {
7947 auto diag = [&](
int Reason) {
7949 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_invalid_type)
7950 << CheckingDest << (Reason == 4) << Reason;
7953 auto note = [&](
int Construct, QualType NoteTy, SourceLocation NoteLoc) {
7955 Info->Note(NoteLoc, diag::note_constexpr_bit_cast_invalid_subtype)
7956 << NoteTy << Construct << Ty;
7970 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(
Record)) {
7971 for (CXXBaseSpecifier &BS : CXXRD->bases())
7972 if (!checkBitCastConstexprEligibilityType(Loc, BS.
getType(), Info, Ctx,
7976 for (FieldDecl *FD :
Record->fields()) {
7977 if (FD->getType()->isReferenceType())
7979 if (!checkBitCastConstexprEligibilityType(Loc, FD->getType(), Info, Ctx,
7981 return note(0, FD->getType(), FD->getBeginLoc());
7987 Info, Ctx, CheckingDest))
7990 if (
const auto *VTy = Ty->
getAs<VectorType>()) {
8002 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_invalid_vector)
8003 << QualType(VTy, 0) << EltSize << NElts << Ctx.
getCharWidth();
8013 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_unsupported_type)
8022static bool checkBitCastConstexprEligibility(EvalInfo *Info,
8023 const ASTContext &Ctx,
8025 bool DestOK = checkBitCastConstexprEligibilityType(
8027 bool SourceOK = DestOK && checkBitCastConstexprEligibilityType(
8033static bool handleRValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
8037 "no host or target supports non 8-bit chars");
8039 if (!checkBitCastConstexprEligibility(&Info, Info.Ctx, BCE))
8043 std::optional<BitCastBuffer> Buffer =
8044 APValueToBufferConverter::convert(Info, SourceRValue, BCE);
8049 std::optional<APValue> MaybeDestValue =
8050 BufferToAPValueConverter::convert(Info, *Buffer, BCE);
8051 if (!MaybeDestValue)
8054 DestValue = std::move(*MaybeDestValue);
8058static bool handleLValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
8062 "no host or target supports non 8-bit chars");
8064 "LValueToRValueBitcast requires an lvalue operand!");
8066 LValue SourceLValue;
8068 SourceLValue.setFrom(Info.Ctx, SourceValue);
8071 SourceRValue,
true))
8074 return handleRValueToRValueBitCast(Info, DestValue, SourceRValue, BCE);
8077template <
class Derived>
8078class ExprEvaluatorBase
8079 :
public ConstStmtVisitor<Derived, bool> {
8081 Derived &getDerived() {
return static_cast<Derived&
>(*this); }
8082 bool DerivedSuccess(
const APValue &
V,
const Expr *E) {
8083 return getDerived().Success(
V, E);
8085 bool DerivedZeroInitialization(
const Expr *E) {
8086 return getDerived().ZeroInitialization(E);
8092 template<
typename ConditionalOperator>
8093 void CheckPotentialConstantConditional(
const ConditionalOperator *E) {
8094 assert(Info.checkingPotentialConstantExpression());
8097 SmallVector<PartialDiagnosticAt, 8>
Diag;
8099 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
8106 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
8113 Error(E, diag::note_constexpr_conditional_never_const);
8117 template<
typename ConditionalOperator>
8118 bool HandleConditionalOperator(
const ConditionalOperator *E) {
8121 if (Info.checkingPotentialConstantExpression() && Info.noteFailure()) {
8122 CheckPotentialConstantConditional(E);
8125 if (Info.noteFailure()) {
8133 return StmtVisitorTy::Visit(EvalExpr);
8138 typedef ConstStmtVisitor<Derived, bool> StmtVisitorTy;
8139 typedef ExprEvaluatorBase ExprEvaluatorBaseTy;
8141 OptionalDiagnostic CCEDiag(
const Expr *E,
diag::kind D) {
8142 return Info.CCEDiag(E, D);
8145 bool ZeroInitialization(
const Expr *E) {
return Error(E); }
8147 bool IsConstantEvaluatedBuiltinCall(
const CallExpr *E) {
8149 return BuiltinOp != 0 &&
8154 ExprEvaluatorBase(EvalInfo &Info) : Info(Info) {}
8156 EvalInfo &getEvalInfo() {
return Info; }
8164 bool Error(
const Expr *E) {
8165 return Error(E, diag::note_invalid_subexpr_in_const_expr);
8168 bool VisitStmt(
const Stmt *) {
8169 llvm_unreachable(
"Expression evaluator should not be called on stmts");
8171 bool VisitExpr(
const Expr *E) {
8175 bool VisitEmbedExpr(
const EmbedExpr *E) {
8176 const auto It = E->
begin();
8177 return StmtVisitorTy::Visit(*It);
8180 bool VisitPredefinedExpr(
const PredefinedExpr *E) {
8183 bool VisitConstantExpr(
const ConstantExpr *E) {
8187 return StmtVisitorTy::Visit(E->
getSubExpr());
8190 bool VisitParenExpr(
const ParenExpr *E)
8191 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8192 bool VisitUnaryExtension(
const UnaryOperator *E)
8193 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8194 bool VisitUnaryPlus(
const UnaryOperator *E)
8195 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8196 bool VisitChooseExpr(
const ChooseExpr *E)
8198 bool VisitGenericSelectionExpr(
const GenericSelectionExpr *E)
8200 bool VisitSubstNonTypeTemplateParmExpr(
const SubstNonTypeTemplateParmExpr *E)
8202 bool VisitCXXDefaultArgExpr(
const CXXDefaultArgExpr *E) {
8203 TempVersionRAII RAII(*Info.CurrentCall);
8204 SourceLocExprScopeGuard Guard(E, Info.CurrentCall->CurSourceLocExprScope);
8205 return StmtVisitorTy::Visit(E->
getExpr());
8207 bool VisitCXXDefaultInitExpr(
const CXXDefaultInitExpr *E) {
8208 TempVersionRAII RAII(*Info.CurrentCall);
8212 SourceLocExprScopeGuard Guard(E, Info.CurrentCall->CurSourceLocExprScope);
8213 return StmtVisitorTy::Visit(E->
getExpr());
8216 bool VisitExprWithCleanups(
const ExprWithCleanups *E) {
8217 FullExpressionRAII Scope(Info);
8218 return StmtVisitorTy::Visit(E->
getSubExpr()) && Scope.destroy();
8223 bool VisitCXXBindTemporaryExpr(
const CXXBindTemporaryExpr *E) {
8224 return StmtVisitorTy::Visit(E->
getSubExpr());
8227 bool VisitCXXReinterpretCastExpr(
const CXXReinterpretCastExpr *E) {
8228 CCEDiag(E, diag::note_constexpr_invalid_cast)
8229 << diag::ConstexprInvalidCastKind::Reinterpret;
8230 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8232 bool VisitCXXDynamicCastExpr(
const CXXDynamicCastExpr *E) {
8234 CCEDiag(E, diag::note_constexpr_invalid_cast)
8235 << diag::ConstexprInvalidCastKind::Dynamic;
8236 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8238 bool VisitBuiltinBitCastExpr(
const BuiltinBitCastExpr *E) {
8239 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8242 bool VisitBinaryOperator(
const BinaryOperator *E) {
8248 VisitIgnoredValue(E->
getLHS());
8249 return StmtVisitorTy::Visit(E->
getRHS());
8259 return DerivedSuccess(
Result, E);
8264 bool VisitCXXRewrittenBinaryOperator(
const CXXRewrittenBinaryOperator *E) {
8268 bool VisitBinaryConditionalOperator(
const BinaryConditionalOperator *E) {
8272 if (!
Evaluate(Info.CurrentCall->createTemporary(
8275 ScopeKind::FullExpression, CommonLV),
8279 return HandleConditionalOperator(E);
8282 bool VisitConditionalOperator(
const ConditionalOperator *E) {
8283 bool IsBcpCall =
false;
8288 if (
const CallExpr *CallCE =
8290 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
8297 if (Info.checkingPotentialConstantExpression() && IsBcpCall)
8300 FoldConstant Fold(Info, IsBcpCall);
8301 if (!HandleConditionalOperator(E)) {
8302 Fold.keepDiagnostics();
8309 bool VisitOpaqueValueExpr(
const OpaqueValueExpr *E) {
8310 if (
APValue *
Value = Info.CurrentCall->getCurrentTemporary(E);
8312 return DerivedSuccess(*
Value, E);
8318 assert(0 &&
"OpaqueValueExpr recursively refers to itself");
8321 return StmtVisitorTy::Visit(Source);
8324 bool VisitPseudoObjectExpr(
const PseudoObjectExpr *E) {
8325 for (
const Expr *SemE : E->
semantics()) {
8326 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
8335 if (OVE->isUnique())
8339 if (!
Evaluate(Info.CurrentCall->createTemporary(
8340 OVE, getStorageType(Info.Ctx, OVE),
8341 ScopeKind::FullExpression, LV),
8342 Info, OVE->getSourceExpr()))
8345 if (!StmtVisitorTy::Visit(SemE))
8355 bool VisitCallExpr(
const CallExpr *E) {
8357 if (!handleCallExpr(E,
Result,
nullptr))
8359 return DerivedSuccess(
Result, E);
8363 const LValue *ResultSlot) {
8364 CallScopeRAII CallScope(Info);
8367 QualType CalleeType =
Callee->getType();
8369 const FunctionDecl *FD =
nullptr;
8370 LValue *
This =
nullptr, ObjectArg;
8372 bool HasQualifier =
false;
8378 const CXXMethodDecl *
Member =
nullptr;
8379 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(Callee)) {
8383 Member = dyn_cast<CXXMethodDecl>(ME->getMemberDecl());
8385 return Error(Callee);
8387 HasQualifier = ME->hasQualifier();
8388 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(Callee)) {
8390 const ValueDecl *D =
8394 Member = dyn_cast<CXXMethodDecl>(D);
8396 return Error(Callee);
8398 }
else if (
const auto *PDE = dyn_cast<CXXPseudoDestructorExpr>(Callee)) {
8399 if (!Info.getLangOpts().CPlusPlus20)
8400 Info.CCEDiag(PDE, diag::note_constexpr_pseudo_destructor);
8404 return Error(Callee);
8411 if (!CalleeLV.getLValueOffset().isZero())
8412 return Error(Callee);
8413 if (CalleeLV.isNullPointer()) {
8414 Info.FFDiag(Callee, diag::note_constexpr_null_callee)
8415 <<
const_cast<Expr *
>(
Callee);
8418 FD = dyn_cast_or_null<FunctionDecl>(
8419 CalleeLV.getLValueBase().dyn_cast<
const ValueDecl *>());
8421 return Error(Callee);
8431 auto *OCE = dyn_cast<CXXOperatorCallExpr>(E);
8432 if (OCE && OCE->isAssignmentOp()) {
8433 assert(Args.size() == 2 &&
"wrong number of arguments in assignment");
8434 Call = Info.CurrentCall->createCall(FD);
8435 bool HasThis =
false;
8436 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FD))
8437 HasThis = MD->isImplicitObjectMemberFunction();
8445 const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD);
8465 if (Info.getLangOpts().CPlusPlus20 && OCE &&
8466 OCE->getOperator() == OO_Equal && MD->
isTrivial() &&
8470 Args = Args.slice(1);
8476 const CXXRecordDecl *ClosureClass = MD->
getParent();
8478 ClosureClass->
captures().empty() &&
8479 "Number of captures must be zero for conversion to function-ptr");
8481 const CXXMethodDecl *LambdaCallOp =
8490 "A generic lambda's static-invoker function must be a "
8491 "template specialization");
8493 FunctionTemplateDecl *CallOpTemplate =
8495 void *InsertPos =
nullptr;
8496 FunctionDecl *CorrespondingCallOpSpecialization =
8498 assert(CorrespondingCallOpSpecialization &&
8499 "We must always have a function call operator specialization "
8500 "that corresponds to our static invoker specialization");
8502 FD = CorrespondingCallOpSpecialization;
8511 return CallScope.destroy();
8521 Call = Info.CurrentCall->createCall(FD);
8527 SmallVector<QualType, 4> CovariantAdjustmentPath;
8529 auto *NamedMember = dyn_cast<CXXMethodDecl>(FD);
8530 if (NamedMember && NamedMember->isVirtual() && !HasQualifier) {
8533 CovariantAdjustmentPath);
8536 }
else if (NamedMember && NamedMember->isImplicitObjectMemberFunction()) {
8546 if (
auto *DD = dyn_cast<CXXDestructorDecl>(FD)) {
8547 assert(This &&
"no 'this' pointer for destructor call");
8550 CallScope.destroy();
8567 if (!CovariantAdjustmentPath.empty() &&
8569 CovariantAdjustmentPath))
8572 return CallScope.destroy();
8575 bool VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E) {
8578 bool VisitInitListExpr(
const InitListExpr *E) {
8580 return DerivedZeroInitialization(E);
8582 return StmtVisitorTy::Visit(E->
getInit(0));
8585 bool VisitImplicitValueInitExpr(
const ImplicitValueInitExpr *E) {
8586 return DerivedZeroInitialization(E);
8588 bool VisitCXXScalarValueInitExpr(
const CXXScalarValueInitExpr *E) {
8589 return DerivedZeroInitialization(E);
8591 bool VisitCXXNullPtrLiteralExpr(
const CXXNullPtrLiteralExpr *E) {
8592 return DerivedZeroInitialization(E);
8596 bool VisitMemberExpr(
const MemberExpr *E) {
8598 "missing temporary materialization conversion");
8599 assert(!E->
isArrow() &&
"missing call to bound member function?");
8607 const FieldDecl *FD = dyn_cast<FieldDecl>(E->
getMemberDecl());
8608 if (!FD)
return Error(E);
8612 "record / field mismatch");
8617 CompleteObject Obj(APValue::LValueBase(), &Val, BaseTy);
8618 SubobjectDesignator Designator(BaseTy);
8619 Designator.addDeclUnchecked(FD);
8623 DerivedSuccess(
Result, E);
8626 bool VisitExtVectorElementExpr(
const ExtVectorElementExpr *E) {
8632 SmallVector<uint32_t, 4> Indices;
8634 if (Indices.size() == 1) {
8636 return DerivedSuccess(Val.
getVectorElt(Indices[0]), E);
8639 SmallVector<APValue, 4> Elts;
8640 for (
unsigned I = 0; I < Indices.size(); ++I) {
8643 APValue VecResult(Elts.data(), Indices.size());
8644 return DerivedSuccess(VecResult, E);
8651 bool VisitCastExpr(
const CastExpr *E) {
8656 case CK_AtomicToNonAtomic: {
8663 return DerivedSuccess(AtomicVal, E);
8667 case CK_UserDefinedConversion:
8668 return StmtVisitorTy::Visit(E->
getSubExpr());
8670 case CK_LValueToRValue: {
8679 return DerivedSuccess(RVal, E);
8681 case CK_LValueToRValueBitCast: {
8682 APValue DestValue, SourceValue;
8685 if (!handleLValueToRValueBitCast(Info, DestValue, SourceValue, E))
8687 return DerivedSuccess(DestValue, E);
8690 case CK_AddressSpaceConversion: {
8694 return DerivedSuccess(
Value, E);
8701 bool VisitUnaryPostInc(
const UnaryOperator *UO) {
8702 return VisitUnaryPostIncDec(UO);
8704 bool VisitUnaryPostDec(
const UnaryOperator *UO) {
8705 return VisitUnaryPostIncDec(UO);
8707 bool VisitUnaryPostIncDec(
const UnaryOperator *UO) {
8708 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
8718 return DerivedSuccess(RVal, UO);
8721 bool VisitStmtExpr(
const StmtExpr *E) {
8724 llvm::SaveAndRestore NotCheckingForUB(Info.CheckingForUndefinedBehavior,
8731 BlockScopeRAII Scope(Info);
8736 const Expr *FinalExpr = dyn_cast<Expr>(*BI);
8738 Info.FFDiag((*BI)->getBeginLoc(),
8739 diag::note_constexpr_stmt_expr_unsupported);
8742 return this->Visit(FinalExpr) && Scope.destroy();
8748 if (ESR != ESR_Succeeded) {
8752 if (ESR != ESR_Failed)
8753 Info.FFDiag((*BI)->getBeginLoc(),
8754 diag::note_constexpr_stmt_expr_unsupported);
8759 llvm_unreachable(
"Return from function from the loop above.");
8762 bool VisitPackIndexingExpr(
const PackIndexingExpr *E) {
8767 void VisitIgnoredValue(
const Expr *E) {
8772 void VisitIgnoredBaseExpression(
const Expr *E) {
8775 if (Info.getLangOpts().MSVCCompat && !E->
HasSideEffects(Info.Ctx))
8777 VisitIgnoredValue(E);
8787template<
class Derived>
8788class LValueExprEvaluatorBase
8789 :
public ExprEvaluatorBase<Derived> {
8793 typedef LValueExprEvaluatorBase LValueExprEvaluatorBaseTy;
8794 typedef ExprEvaluatorBase<Derived> ExprEvaluatorBaseTy;
8796 bool Success(APValue::LValueBase B) {
8801 bool evaluatePointer(
const Expr *E, LValue &
Result) {
8806 LValueExprEvaluatorBase(EvalInfo &Info, LValue &
Result,
bool InvalidBaseOK)
8808 InvalidBaseOK(InvalidBaseOK) {}
8811 Result.setFrom(this->Info.Ctx,
V);
8815 bool VisitMemberExpr(
const MemberExpr *E) {
8827 EvalOK = this->Visit(E->
getBase());
8838 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(E->
getMemberDecl())) {
8841 "record / field mismatch");
8845 }
else if (
const IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(MD)) {
8849 return this->
Error(E);
8861 bool VisitBinaryOperator(
const BinaryOperator *E) {
8864 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
8872 bool VisitCastExpr(
const CastExpr *E) {
8875 return ExprEvaluatorBaseTy::VisitCastExpr(E);
8877 case CK_DerivedToBase:
8878 case CK_UncheckedDerivedToBase:
8925class LValueExprEvaluator
8926 :
public LValueExprEvaluatorBase<LValueExprEvaluator> {
8928 LValueExprEvaluator(EvalInfo &Info, LValue &
Result,
bool InvalidBaseOK) :
8929 LValueExprEvaluatorBaseTy(Info,
Result, InvalidBaseOK) {}
8931 bool VisitVarDecl(
const Expr *E,
const VarDecl *VD);
8932 bool VisitUnaryPreIncDec(
const UnaryOperator *UO);
8934 bool VisitCallExpr(
const CallExpr *E);
8935 bool VisitDeclRefExpr(
const DeclRefExpr *E);
8936 bool VisitPredefinedExpr(
const PredefinedExpr *E) {
return Success(E); }
8937 bool VisitMaterializeTemporaryExpr(
const MaterializeTemporaryExpr *E);
8938 bool VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E);
8939 bool VisitMemberExpr(
const MemberExpr *E);
8940 bool VisitStringLiteral(
const StringLiteral *E) {
8941 return Success(APValue::LValueBase(
8942 E, 0, Info.getASTContext().getNextStringLiteralVersion()));
8944 bool VisitObjCEncodeExpr(
const ObjCEncodeExpr *E) {
return Success(E); }
8945 bool VisitCXXTypeidExpr(
const CXXTypeidExpr *E);
8946 bool VisitCXXUuidofExpr(
const CXXUuidofExpr *E);
8947 bool VisitArraySubscriptExpr(
const ArraySubscriptExpr *E);
8948 bool VisitExtVectorElementExpr(
const ExtVectorElementExpr *E);
8949 bool VisitUnaryDeref(
const UnaryOperator *E);
8950 bool VisitUnaryReal(
const UnaryOperator *E);
8951 bool VisitUnaryImag(
const UnaryOperator *E);
8952 bool VisitUnaryPreInc(
const UnaryOperator *UO) {
8953 return VisitUnaryPreIncDec(UO);
8955 bool VisitUnaryPreDec(
const UnaryOperator *UO) {
8956 return VisitUnaryPreIncDec(UO);
8958 bool VisitBinAssign(
const BinaryOperator *BO);
8959 bool VisitCompoundAssignOperator(
const CompoundAssignOperator *CAO);
8961 bool VisitCastExpr(
const CastExpr *E) {
8964 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
8966 case CK_LValueBitCast:
8967 this->CCEDiag(E, diag::note_constexpr_invalid_cast)
8968 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
8972 Result.Designator.setInvalid();
8975 case CK_BaseToDerived:
8992 bool LValueToRValueConversion) {
8996 assert(Info.CurrentCall->This ==
nullptr &&
8997 "This should not be set for a static call operator");
9005 if (
Self->getType()->isReferenceType()) {
9006 APValue *RefValue = Info.getParamSlot(Info.CurrentCall->Arguments,
Self);
9008 Result.setFrom(Info.Ctx, *RefValue);
9010 const ParmVarDecl *VD = Info.CurrentCall->Arguments.getOrigParam(
Self);
9011 CallStackFrame *Frame =
9012 Info.getCallFrameAndDepth(Info.CurrentCall->Arguments.CallIndex)
9014 unsigned Version = Info.CurrentCall->Arguments.Version;
9015 Result.set({VD, Frame->Index, Version});
9018 Result = *Info.CurrentCall->This;
9028 if (LValueToRValueConversion) {
9032 Result.setFrom(Info.Ctx, RVal);
9043 bool InvalidBaseOK) {
9047 return LValueExprEvaluator(Info, Result, InvalidBaseOK).Visit(E);
9050bool LValueExprEvaluator::VisitDeclRefExpr(
const DeclRefExpr *E) {
9051 const ValueDecl *D = E->
getDecl();
9063 if (Info.checkingPotentialConstantExpression())
9066 if (
auto *FD = Info.CurrentCall->LambdaCaptureFields.lookup(D)) {
9073 if (
isa<FunctionDecl, MSGuidDecl, TemplateParamObjectDecl,
9074 UnnamedGlobalConstantDecl>(D))
9076 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
9077 return VisitVarDecl(E, VD);
9078 if (
const BindingDecl *BD = dyn_cast<BindingDecl>(D))
9079 return Visit(BD->getBinding());
9083bool LValueExprEvaluator::VisitVarDecl(
const Expr *E,
const VarDecl *VD) {
9084 CallStackFrame *Frame =
nullptr;
9085 unsigned Version = 0;
9093 CallStackFrame *CurrFrame = Info.CurrentCall;
9098 if (
auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
9099 if (CurrFrame->Arguments) {
9100 VD = CurrFrame->Arguments.getOrigParam(PVD);
9102 Info.getCallFrameAndDepth(CurrFrame->Arguments.CallIndex).first;
9103 Version = CurrFrame->Arguments.Version;
9107 Version = CurrFrame->getCurrentTemporaryVersion(VD);
9114 Result.set({VD, Frame->Index, Version});
9120 if (!Info.getLangOpts().CPlusPlus11) {
9121 Info.CCEDiag(E, diag::note_constexpr_ltor_non_integral, 1)
9123 Info.Note(VD->
getLocation(), diag::note_declared_at);
9132 Result.AllowConstexprUnknown =
true;
9139bool LValueExprEvaluator::VisitCallExpr(
const CallExpr *E) {
9140 if (!IsConstantEvaluatedBuiltinCall(E))
9141 return ExprEvaluatorBaseTy::VisitCallExpr(E);
9146 case Builtin::BIas_const:
9147 case Builtin::BIforward:
9148 case Builtin::BIforward_like:
9149 case Builtin::BImove:
9150 case Builtin::BImove_if_noexcept:
9152 return Visit(E->
getArg(0));
9156 return ExprEvaluatorBaseTy::VisitCallExpr(E);
9159bool LValueExprEvaluator::VisitMaterializeTemporaryExpr(
9160 const MaterializeTemporaryExpr *E) {
9168 for (
const Expr *E : CommaLHSs)
9177 if (Info.EvalMode == EvaluationMode::ConstantFold)
9184 Value = &Info.CurrentCall->createTemporary(
9200 for (
unsigned I = Adjustments.size(); I != 0; ) {
9202 switch (Adjustments[I].Kind) {
9207 Type = Adjustments[I].DerivedToBase.BasePath->getType();
9213 Type = Adjustments[I].Field->getType();
9218 Adjustments[I].Ptr.RHS))
9220 Type = Adjustments[I].Ptr.MPT->getPointeeType();
9229LValueExprEvaluator::VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E) {
9230 assert((!Info.getLangOpts().CPlusPlus || E->
isFileScope()) &&
9231 "lvalue compound literal in c++?");
9243 assert(!Info.getLangOpts().CPlusPlus);
9245 ScopeKind::Block,
Result);
9257bool LValueExprEvaluator::VisitCXXTypeidExpr(
const CXXTypeidExpr *E) {
9258 TypeInfoLValue TypeInfo;
9267 Info.CCEDiag(E, diag::note_constexpr_typeid_polymorphic)
9275 std::optional<DynamicType> DynType =
9280 TypeInfo = TypeInfoLValue(
9287bool LValueExprEvaluator::VisitCXXUuidofExpr(
const CXXUuidofExpr *E) {
9291bool LValueExprEvaluator::VisitMemberExpr(
const MemberExpr *E) {
9293 if (
const VarDecl *VD = dyn_cast<VarDecl>(E->
getMemberDecl())) {
9294 VisitIgnoredBaseExpression(E->
getBase());
9295 return VisitVarDecl(E, VD);
9299 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(E->
getMemberDecl())) {
9300 if (MD->isStatic()) {
9301 VisitIgnoredBaseExpression(E->
getBase());
9307 return LValueExprEvaluatorBaseTy::VisitMemberExpr(E);
9310bool LValueExprEvaluator::VisitExtVectorElementExpr(
9311 const ExtVectorElementExpr *E) {
9316 if (!Info.noteFailure())
9324 if (Indices.size() > 1)
9328 Result.setFrom(Info.Ctx, Val);
9332 const auto *VT = BaseType->
castAs<VectorType>();
9334 VT->getNumElements(), Indices[0]);
9340bool LValueExprEvaluator::VisitArraySubscriptExpr(
const ArraySubscriptExpr *E) {
9350 if (!Info.noteFailure())
9356 if (!Info.noteFailure())
9362 Result.setFrom(Info.Ctx, Val);
9364 VT->getNumElements(), Index.getExtValue());
9372 for (
const Expr *SubExpr : {E->
getLHS(), E->
getRHS()}) {
9373 if (SubExpr == E->
getBase() ? !evaluatePointer(SubExpr,
Result)
9375 if (!Info.noteFailure())
9385bool LValueExprEvaluator::VisitUnaryDeref(
const UnaryOperator *E) {
9396 Info.noteUndefinedBehavior();
9399bool LValueExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
9408bool LValueExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
9410 "lvalue __imag__ on scalar?");
9417bool LValueExprEvaluator::VisitUnaryPreIncDec(
const UnaryOperator *UO) {
9418 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9429bool LValueExprEvaluator::VisitCompoundAssignOperator(
9430 const CompoundAssignOperator *CAO) {
9431 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9439 if (!Info.noteFailure())
9454bool LValueExprEvaluator::VisitBinAssign(
const BinaryOperator *E) {
9455 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9463 if (!Info.noteFailure())
9471 if (Info.getLangOpts().CPlusPlus20 &&
9487 llvm::APInt &Result) {
9488 assert(isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
9489 "Can't get the size of a non alloc_size function");
9490 const auto *
Base = LVal.getLValueBase().get<
const Expr *>();
9492 std::optional<llvm::APInt> Size =
9493 CE->evaluateBytesReturnedByAllocSizeCall(Ctx);
9497 Result = std::move(*Size);
9516 dyn_cast_or_null<VarDecl>(
Base.dyn_cast<
const ValueDecl *>());
9521 if (!
Init ||
Init->getType().isNull())
9524 const Expr *E =
Init->IgnoreParens();
9525 if (!tryUnwrapAllocSizeCall(E))
9530 Result.setInvalid(E);
9533 Result.addUnsizedArray(Info, E, Pointee);
9538class PointerExprEvaluator
9539 :
public ExprEvaluatorBase<PointerExprEvaluator> {
9548 bool evaluateLValue(
const Expr *E, LValue &
Result) {
9552 bool evaluatePointer(
const Expr *E, LValue &
Result) {
9556 bool visitNonBuiltinCallExpr(
const CallExpr *E);
9559 PointerExprEvaluator(EvalInfo &info, LValue &
Result,
bool InvalidBaseOK)
9561 InvalidBaseOK(InvalidBaseOK) {}
9567 bool ZeroInitialization(
const Expr *E) {
9572 bool VisitBinaryOperator(
const BinaryOperator *E);
9573 bool VisitCastExpr(
const CastExpr* E);
9574 bool VisitUnaryAddrOf(
const UnaryOperator *E);
9575 bool VisitObjCStringLiteral(
const ObjCStringLiteral *E)
9577 bool VisitObjCBoxedExpr(
const ObjCBoxedExpr *E) {
9580 if (Info.noteFailure())
9584 bool VisitAddrLabelExpr(
const AddrLabelExpr *E)
9586 bool VisitCallExpr(
const CallExpr *E);
9587 bool VisitBuiltinCallExpr(
const CallExpr *E,
unsigned BuiltinOp);
9588 bool VisitBlockExpr(
const BlockExpr *E) {
9593 bool VisitCXXThisExpr(
const CXXThisExpr *E) {
9594 auto DiagnoseInvalidUseOfThis = [&] {
9595 if (Info.getLangOpts().CPlusPlus11)
9596 Info.FFDiag(E, diag::note_constexpr_this) << E->
isImplicit();
9602 if (Info.checkingPotentialConstantExpression())
9605 bool IsExplicitLambda =
9607 if (!IsExplicitLambda) {
9608 if (!Info.CurrentCall->This) {
9609 DiagnoseInvalidUseOfThis();
9613 Result = *Info.CurrentCall->This;
9621 if (!Info.CurrentCall->LambdaThisCaptureField) {
9622 if (IsExplicitLambda && !Info.CurrentCall->This) {
9623 DiagnoseInvalidUseOfThis();
9632 Info, E,
Result, MD, Info.CurrentCall->LambdaThisCaptureField,
9638 bool VisitCXXNewExpr(
const CXXNewExpr *E);
9640 bool VisitSourceLocExpr(
const SourceLocExpr *E) {
9641 assert(!E->
isIntType() &&
"SourceLocExpr isn't a pointer type?");
9643 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.
getDefaultExpr());
9644 Result.setFrom(Info.Ctx, LValResult);
9648 bool VisitEmbedExpr(
const EmbedExpr *E) {
9649 llvm::report_fatal_error(
"Not yet implemented for ExprConstant.cpp");
9653 bool VisitSYCLUniqueStableNameExpr(
const SYCLUniqueStableNameExpr *E) {
9658 ResultStr.size() + 1);
9660 CharTy, Size,
nullptr, ArraySizeModifier::Normal, 0);
9663 StringLiteral::Create(Info.Ctx, ResultStr, StringLiteralKind::Ordinary,
9666 evaluateLValue(SL,
Result);
9676 bool InvalidBaseOK) {
9679 return PointerExprEvaluator(Info, Result, InvalidBaseOK).Visit(E);
9682bool PointerExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
9685 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
9687 const Expr *PExp = E->
getLHS();
9688 const Expr *IExp = E->
getRHS();
9690 std::swap(PExp, IExp);
9692 bool EvalPtrOK = evaluatePointer(PExp,
Result);
9693 if (!EvalPtrOK && !Info.noteFailure())
9696 llvm::APSInt Offset;
9707bool PointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
9716 if (!FnII || !FnII->
isStr(
"current"))
9719 const auto *RD = dyn_cast<RecordDecl>(FD->
getParent());
9727bool PointerExprEvaluator::VisitCastExpr(
const CastExpr *E) {
9734 case CK_CPointerToObjCPointerCast:
9735 case CK_BlockPointerToObjCPointerCast:
9736 case CK_AnyPointerToBlockPointerCast:
9737 case CK_AddressSpaceConversion:
9738 if (!Visit(SubExpr))
9744 CCEDiag(E, diag::note_constexpr_invalid_cast)
9745 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
9747 Result.Designator.setInvalid();
9755 bool HasValidResult = !
Result.InvalidBase && !
Result.Designator.Invalid &&
9757 bool VoidPtrCastMaybeOK =
9769 if (VoidPtrCastMaybeOK &&
9770 (Info.getStdAllocatorCaller(
"allocate") ||
9772 Info.getLangOpts().CPlusPlus26)) {
9776 Info.getLangOpts().CPlusPlus) {
9778 CCEDiag(E, diag::note_constexpr_invalid_void_star_cast)
9779 << SubExpr->
getType() << Info.getLangOpts().CPlusPlus26
9780 <<
Result.Designator.getType(Info.Ctx).getCanonicalType()
9783 CCEDiag(E, diag::note_constexpr_invalid_cast)
9784 << diag::ConstexprInvalidCastKind::CastFrom
9787 CCEDiag(E, diag::note_constexpr_invalid_cast)
9788 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
9790 Result.Designator.setInvalid();
9794 ZeroInitialization(E);
9797 case CK_DerivedToBase:
9798 case CK_UncheckedDerivedToBase:
9810 case CK_BaseToDerived:
9822 case CK_NullToPointer:
9824 return ZeroInitialization(E);
9826 case CK_IntegralToPointer: {
9827 CCEDiag(E, diag::note_constexpr_invalid_cast)
9828 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
9835 if (
Value.isInt()) {
9837 uint64_t N =
Value.getInt().extOrTrunc(Size).getZExtValue();
9841 Result.Base = (Expr *)
nullptr;
9842 Result.InvalidBase =
false;
9844 Result.Designator.setInvalid();
9845 Result.IsNullPtr =
false;
9853 if (!
Value.isLValue())
9862 case CK_ArrayToPointerDecay: {
9864 if (!evaluateLValue(SubExpr,
Result))
9868 SubExpr, SubExpr->
getType(), ScopeKind::FullExpression,
Result);
9874 if (
auto *CAT = dyn_cast<ConstantArrayType>(AT))
9875 Result.addArray(Info, E, CAT);
9877 Result.addUnsizedArray(Info, E, AT->getElementType());
9881 case CK_FunctionToPointerDecay:
9882 return evaluateLValue(SubExpr,
Result);
9884 case CK_LValueToRValue: {
9893 return InvalidBaseOK &&
9899 return ExprEvaluatorBaseTy::VisitCastExpr(E);
9907 T =
T.getNonReferenceType();
9909 if (
T.getQualifiers().hasUnaligned())
9912 const bool AlignOfReturnsPreferred =
9913 Ctx.
getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver7;
9918 if (ExprKind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
9921 else if (ExprKind == UETT_AlignOf)
9924 llvm_unreachable(
"GetAlignOfType on a non-alignment ExprKind");
9937 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
9941 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(E))
9951 if (
const auto *E =
Value.Base.dyn_cast<
const Expr *>())
9959 EvalInfo &Info,
APSInt &Alignment) {
9962 if (Alignment < 0 || !Alignment.isPowerOf2()) {
9963 Info.FFDiag(E, diag::note_constexpr_invalid_alignment) << Alignment;
9966 unsigned SrcWidth = Info.Ctx.
getIntWidth(ForType);
9967 APSInt MaxValue(APInt::getOneBitSet(SrcWidth, SrcWidth - 1));
9968 if (APSInt::compareValues(Alignment, MaxValue) > 0) {
9969 Info.FFDiag(E, diag::note_constexpr_alignment_too_big)
9970 << MaxValue << ForType << Alignment;
9976 APSInt(Alignment.zextOrTrunc(SrcWidth),
true);
9977 assert(APSInt::compareValues(Alignment, ExtAlignment) == 0 &&
9978 "Alignment should not be changed by ext/trunc");
9979 Alignment = ExtAlignment;
9980 assert(Alignment.getBitWidth() == SrcWidth);
9985bool PointerExprEvaluator::visitNonBuiltinCallExpr(
const CallExpr *E) {
9986 if (ExprEvaluatorBaseTy::VisitCallExpr(E))
9994 Result.addUnsizedArray(Info, E, PointeeTy);
9998bool PointerExprEvaluator::VisitCallExpr(
const CallExpr *E) {
9999 if (!IsConstantEvaluatedBuiltinCall(E))
10000 return visitNonBuiltinCallExpr(E);
10007 return T->isCharType() ||
T->isChar8Type();
10010bool PointerExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *E,
10011 unsigned BuiltinOp) {
10015 switch (BuiltinOp) {
10016 case Builtin::BIaddressof:
10017 case Builtin::BI__addressof:
10018 case Builtin::BI__builtin_addressof:
10020 case Builtin::BI__builtin_assume_aligned: {
10027 LValue OffsetResult(
Result);
10039 int64_t AdditionalOffset = -Offset.getZExtValue();
10044 if (OffsetResult.Base) {
10047 if (BaseAlignment < Align) {
10048 Result.Designator.setInvalid();
10049 CCEDiag(E->
getArg(0), diag::note_constexpr_baa_insufficient_alignment)
10056 if (OffsetResult.Offset.alignTo(Align) != OffsetResult.Offset) {
10057 Result.Designator.setInvalid();
10061 diag::note_constexpr_baa_insufficient_alignment)
10064 diag::note_constexpr_baa_value_insufficient_alignment))
10065 << OffsetResult.Offset.getQuantity() << Align.
getQuantity();
10071 case Builtin::BI__builtin_align_up:
10072 case Builtin::BI__builtin_align_down: {
10092 assert(Alignment.getBitWidth() <= 64 &&
10093 "Cannot handle > 64-bit address-space");
10094 uint64_t Alignment64 = Alignment.getZExtValue();
10096 BuiltinOp == Builtin::BI__builtin_align_down
10097 ? llvm::alignDown(
Result.Offset.getQuantity(), Alignment64)
10098 : llvm::alignTo(
Result.Offset.getQuantity(), Alignment64));
10104 Info.FFDiag(E->
getArg(0), diag::note_constexpr_alignment_adjust)
10108 case Builtin::BI__builtin_operator_new:
10110 case Builtin::BI__builtin_launder:
10112 case Builtin::BIstrchr:
10113 case Builtin::BIwcschr:
10114 case Builtin::BImemchr:
10115 case Builtin::BIwmemchr:
10116 if (Info.getLangOpts().CPlusPlus11)
10117 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
10121 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
10123 case Builtin::BI__builtin_strchr:
10124 case Builtin::BI__builtin_wcschr:
10125 case Builtin::BI__builtin_memchr:
10126 case Builtin::BI__builtin_char_memchr:
10127 case Builtin::BI__builtin_wmemchr: {
10128 if (!Visit(E->
getArg(0)))
10134 if (BuiltinOp != Builtin::BIstrchr &&
10135 BuiltinOp != Builtin::BIwcschr &&
10136 BuiltinOp != Builtin::BI__builtin_strchr &&
10137 BuiltinOp != Builtin::BI__builtin_wcschr) {
10141 MaxLength = N.getZExtValue();
10144 if (MaxLength == 0u)
10145 return ZeroInitialization(E);
10146 if (!
Result.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
10147 Result.Designator.Invalid)
10149 QualType CharTy =
Result.Designator.getType(Info.Ctx);
10150 bool IsRawByte = BuiltinOp == Builtin::BImemchr ||
10151 BuiltinOp == Builtin::BI__builtin_memchr;
10152 assert(IsRawByte ||
10157 Info.FFDiag(E, diag::note_constexpr_ltor_incomplete_type) << CharTy;
10163 Info.FFDiag(E, diag::note_constexpr_memchr_unsupported)
10170 bool StopAtNull =
false;
10171 switch (BuiltinOp) {
10172 case Builtin::BIstrchr:
10173 case Builtin::BI__builtin_strchr:
10180 return ZeroInitialization(E);
10183 case Builtin::BImemchr:
10184 case Builtin::BI__builtin_memchr:
10185 case Builtin::BI__builtin_char_memchr:
10189 DesiredVal = Desired.trunc(Info.Ctx.
getCharWidth()).getZExtValue();
10192 case Builtin::BIwcschr:
10193 case Builtin::BI__builtin_wcschr:
10196 case Builtin::BIwmemchr:
10197 case Builtin::BI__builtin_wmemchr:
10199 DesiredVal = Desired.getZExtValue();
10203 for (; MaxLength; --MaxLength) {
10208 if (Char.
getInt().getZExtValue() == DesiredVal)
10210 if (StopAtNull && !Char.
getInt())
10216 return ZeroInitialization(E);
10219 case Builtin::BImemcpy:
10220 case Builtin::BImemmove:
10221 case Builtin::BIwmemcpy:
10222 case Builtin::BIwmemmove:
10223 if (Info.getLangOpts().CPlusPlus11)
10224 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
10228 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
10230 case Builtin::BI__builtin_memcpy:
10231 case Builtin::BI__builtin_memmove:
10232 case Builtin::BI__builtin_wmemcpy:
10233 case Builtin::BI__builtin_wmemmove: {
10234 bool WChar = BuiltinOp == Builtin::BIwmemcpy ||
10235 BuiltinOp == Builtin::BIwmemmove ||
10236 BuiltinOp == Builtin::BI__builtin_wmemcpy ||
10237 BuiltinOp == Builtin::BI__builtin_wmemmove;
10238 bool Move = BuiltinOp == Builtin::BImemmove ||
10239 BuiltinOp == Builtin::BIwmemmove ||
10240 BuiltinOp == Builtin::BI__builtin_memmove ||
10241 BuiltinOp == Builtin::BI__builtin_wmemmove;
10244 if (!Visit(E->
getArg(0)))
10255 assert(!N.isSigned() &&
"memcpy and friends take an unsigned size");
10265 if (!Src.Base || !Dest.Base) {
10267 (!Src.Base ? Src : Dest).moveInto(Val);
10268 Info.FFDiag(E, diag::note_constexpr_memcpy_null)
10269 <<
Move << WChar << !!Src.Base
10273 if (Src.Designator.Invalid || Dest.Designator.Invalid)
10279 QualType
T = Dest.Designator.getType(Info.Ctx);
10280 QualType SrcT = Src.Designator.getType(Info.Ctx);
10283 Info.FFDiag(E, diag::note_constexpr_memcpy_type_pun) <<
Move << SrcT <<
T;
10287 Info.FFDiag(E, diag::note_constexpr_memcpy_incomplete_type) <<
Move <<
T;
10290 if (!
T.isTriviallyCopyableType(Info.Ctx)) {
10291 Info.FFDiag(E, diag::note_constexpr_memcpy_nontrivial) <<
Move <<
T;
10301 llvm::APInt OrigN = N;
10302 llvm::APInt::udivrem(OrigN, TSize, N, Remainder);
10304 Info.FFDiag(E, diag::note_constexpr_memcpy_unsupported)
10306 << (unsigned)TSize;
10314 uint64_t RemainingSrcSize = Src.Designator.validIndexAdjustments().second;
10315 uint64_t RemainingDestSize = Dest.Designator.validIndexAdjustments().second;
10316 if (N.ugt(RemainingSrcSize) || N.ugt(RemainingDestSize)) {
10317 Info.FFDiag(E, diag::note_constexpr_memcpy_unsupported)
10318 <<
Move << WChar << (N.ugt(RemainingSrcSize) ? 1 : 2) <<
T
10322 uint64_t NElems = N.getZExtValue();
10328 uint64_t SrcOffset = Src.getLValueOffset().getQuantity();
10329 uint64_t DestOffset = Dest.getLValueOffset().getQuantity();
10330 if (DestOffset >= SrcOffset && DestOffset - SrcOffset < NBytes) {
10333 Info.FFDiag(E, diag::note_constexpr_memcpy_overlap) << WChar;
10341 }
else if (!Move && SrcOffset >= DestOffset &&
10342 SrcOffset - DestOffset < NBytes) {
10344 Info.FFDiag(E, diag::note_constexpr_memcpy_overlap) << WChar;
10373 QualType AllocType);
10376 const CXXConstructExpr *CCE,
10377 QualType AllocType);
10379bool PointerExprEvaluator::VisitCXXNewExpr(
const CXXNewExpr *E) {
10380 if (!Info.getLangOpts().CPlusPlus20)
10381 Info.CCEDiag(E, diag::note_constexpr_new);
10384 if (Info.SpeculativeEvaluationDepth)
10389 QualType TargetType = AllocType;
10391 bool IsNothrow =
false;
10392 bool IsPlacement =
false;
10410 }
else if (OperatorNew->isReservedGlobalPlacementOperator()) {
10411 if (Info.CurrentCall->isStdFunction() || Info.getLangOpts().CPlusPlus26 ||
10412 (Info.CurrentCall->CanEvalMSConstexpr &&
10413 OperatorNew->hasAttr<MSConstexprAttr>())) {
10416 if (
Result.Designator.Invalid)
10419 IsPlacement =
true;
10421 Info.FFDiag(E, diag::note_constexpr_new_placement)
10426 Info.FFDiag(E, diag::note_constexpr_new_placement)
10429 }
else if (!OperatorNew
10430 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
10431 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
10437 const InitListExpr *ResizedArrayILE =
nullptr;
10438 const CXXConstructExpr *ResizedArrayCCE =
nullptr;
10439 bool ValueInit =
false;
10441 if (std::optional<const Expr *> ArraySize = E->
getArraySize()) {
10442 const Expr *Stripped = *ArraySize;
10443 for (;
auto *ICE = dyn_cast<ImplicitCastExpr>(Stripped);
10444 Stripped = ICE->getSubExpr())
10445 if (ICE->getCastKind() != CK_NoOp &&
10446 ICE->getCastKind() != CK_IntegralCast)
10459 return ZeroInitialization(E);
10461 Info.FFDiag(*ArraySize, diag::note_constexpr_new_negative)
10462 <<
ArrayBound << (*ArraySize)->getSourceRange();
10468 if (!Info.CheckArraySize(ArraySize.value()->getExprLoc(),
10473 return ZeroInitialization(E);
10485 }
else if (
auto *CCE = dyn_cast<CXXConstructExpr>(
Init)) {
10486 ResizedArrayCCE = CCE;
10489 assert(CAT &&
"unexpected type for array initializer");
10493 llvm::APInt InitBound = CAT->
getSize().zext(Bits);
10494 llvm::APInt AllocBound =
ArrayBound.zext(Bits);
10495 if (InitBound.ugt(AllocBound)) {
10497 return ZeroInitialization(E);
10499 Info.FFDiag(*ArraySize, diag::note_constexpr_new_too_small)
10500 <<
toString(AllocBound, 10,
false)
10502 << (*ArraySize)->getSourceRange();
10508 if (InitBound != AllocBound)
10513 ArraySizeModifier::Normal, 0);
10516 "array allocation with non-array new");
10522 struct FindObjectHandler {
10525 QualType AllocType;
10529 typedef bool result_type;
10530 bool failed() {
return false; }
10531 bool checkConst(QualType QT) {
10533 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
10538 bool found(
APValue &Subobj, QualType SubobjType) {
10539 if (!checkConst(SubobjType))
10543 unsigned SubobjectSize = 1;
10544 unsigned AllocSize = 1;
10545 if (
auto *CAT = dyn_cast<ConstantArrayType>(AllocType))
10547 if (
auto *CAT = dyn_cast<ConstantArrayType>(SubobjType))
10549 if (SubobjectSize < AllocSize ||
10552 Info.FFDiag(E, diag::note_constexpr_placement_new_wrong_type)
10553 << SubobjType << AllocType;
10560 Info.FFDiag(E, diag::note_constexpr_construct_complex_elem);
10563 bool found(APFloat &
Value, QualType SubobjType) {
10564 Info.FFDiag(E, diag::note_constexpr_construct_complex_elem);
10567 } Handler = {Info, E, AllocType, AK,
nullptr};
10573 Val = Handler.Value;
10582 Val = Info.createHeapAlloc(E, AllocType,
Result);
10588 ImplicitValueInitExpr VIE(AllocType);
10591 }
else if (ResizedArrayILE) {
10595 }
else if (ResizedArrayCCE) {
10618class MemberPointerExprEvaluator
10619 :
public ExprEvaluatorBase<MemberPointerExprEvaluator> {
10622 bool Success(
const ValueDecl *D) {
10628 MemberPointerExprEvaluator(EvalInfo &Info, MemberPtr &
Result)
10635 bool ZeroInitialization(
const Expr *E) {
10636 return Success((
const ValueDecl*)
nullptr);
10639 bool VisitCastExpr(
const CastExpr *E);
10640 bool VisitUnaryAddrOf(
const UnaryOperator *E);
10648 return MemberPointerExprEvaluator(Info, Result).Visit(E);
10651bool MemberPointerExprEvaluator::VisitCastExpr(
const CastExpr *E) {
10654 return ExprEvaluatorBaseTy::VisitCastExpr(E);
10656 case CK_NullToMemberPointer:
10658 return ZeroInitialization(E);
10660 case CK_BaseToDerivedMemberPointer: {
10668 typedef std::reverse_iterator<CastExpr::path_const_iterator> ReverseIter;
10670 PathI != PathE; ++PathI) {
10671 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
10672 const CXXRecordDecl *Derived = (*PathI)->getType()->getAsCXXRecordDecl();
10673 if (!
Result.castToDerived(Derived))
10677 ->
castAs<MemberPointerType>()
10678 ->getMostRecentCXXRecordDecl()))
10683 case CK_DerivedToBaseMemberPointer:
10687 PathE = E->
path_end(); PathI != PathE; ++PathI) {
10688 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
10689 const CXXRecordDecl *
Base = (*PathI)->getType()->getAsCXXRecordDecl();
10690 if (!
Result.castToBase(Base))
10697bool MemberPointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
10708 class RecordExprEvaluator
10709 :
public ExprEvaluatorBase<RecordExprEvaluator> {
10710 const LValue &
This;
10714 RecordExprEvaluator(EvalInfo &info,
const LValue &This,
APValue &
Result)
10721 bool ZeroInitialization(
const Expr *E) {
10722 return ZeroInitialization(E, E->
getType());
10724 bool ZeroInitialization(
const Expr *E, QualType
T);
10726 bool VisitCallExpr(
const CallExpr *E) {
10727 return handleCallExpr(E,
Result, &This);
10729 bool VisitCastExpr(
const CastExpr *E);
10730 bool VisitInitListExpr(
const InitListExpr *E);
10731 bool VisitCXXConstructExpr(
const CXXConstructExpr *E) {
10732 return VisitCXXConstructExpr(E, E->
getType());
10735 bool VisitCXXInheritedCtorInitExpr(
const CXXInheritedCtorInitExpr *E);
10736 bool VisitCXXConstructExpr(
const CXXConstructExpr *E, QualType
T);
10737 bool VisitCXXStdInitializerListExpr(
const CXXStdInitializerListExpr *E);
10738 bool VisitBinCmp(
const BinaryOperator *E);
10739 bool VisitCXXParenListInitExpr(
const CXXParenListInitExpr *E);
10740 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
10741 ArrayRef<Expr *> Args);
10755 assert(!RD->
isUnion() &&
"Expected non-union class type");
10764 unsigned Index = 0;
10766 End = CD->
bases_end(); I != End; ++I, ++Index) {
10768 LValue Subobject =
This;
10772 Result.getStructBase(Index)))
10777 for (
const auto *I : RD->
fields()) {
10779 if (I->isUnnamedBitField() || I->getType()->isReferenceType())
10782 LValue Subobject =
This;
10788 Result.getStructField(I->getFieldIndex()), Info, Subobject, &VIE))
10795bool RecordExprEvaluator::ZeroInitialization(
const Expr *E, QualType
T) {
10802 while (I != RD->
field_end() && (*I)->isUnnamedBitField())
10809 LValue Subobject =
This;
10813 ImplicitValueInitExpr VIE(I->getType());
10818 Info.FFDiag(E, diag::note_constexpr_virtual_base) << RD;
10825bool RecordExprEvaluator::VisitCastExpr(
const CastExpr *E) {
10828 return ExprEvaluatorBaseTy::VisitCastExpr(E);
10830 case CK_ConstructorConversion:
10833 case CK_DerivedToBase:
10834 case CK_UncheckedDerivedToBase: {
10845 PathE = E->
path_end(); PathI != PathE; ++PathI) {
10846 assert(!(*PathI)->isVirtual() &&
"record rvalue with virtual base");
10847 const CXXRecordDecl *
Base = (*PathI)->getType()->getAsCXXRecordDecl();
10857bool RecordExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
10860 return VisitCXXParenListOrInitListExpr(E, E->
inits());
10863bool RecordExprEvaluator::VisitCXXParenListOrInitListExpr(
10868 auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
10870 EvalInfo::EvaluatingConstructorRAII EvalObj(
10872 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries},
10873 CXXRD && CXXRD->getNumBases());
10876 const FieldDecl *
Field;
10877 if (
auto *ILE = dyn_cast<InitListExpr>(ExprToVisit)) {
10878 Field = ILE->getInitializedFieldInUnion();
10879 }
else if (
auto *PLIE = dyn_cast<CXXParenListInitExpr>(ExprToVisit)) {
10880 Field = PLIE->getInitializedFieldInUnion();
10883 "Expression is neither an init list nor a C++ paren list");
10895 ImplicitValueInitExpr VIE(
Field->getType());
10896 const Expr *InitExpr = Args.empty() ? &VIE : Args[0];
10898 LValue Subobject =
This;
10903 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
10907 if (
Field->isBitField())
10917 Result =
APValue(APValue::UninitStruct(), CXXRD ? CXXRD->getNumBases() : 0,
10919 unsigned ElementNo = 0;
10923 if (CXXRD && CXXRD->getNumBases()) {
10924 for (
const auto &Base : CXXRD->bases()) {
10925 assert(ElementNo < Args.size() &&
"missing init for base class");
10926 const Expr *
Init = Args[ElementNo];
10928 LValue Subobject =
This;
10934 if (!Info.noteFailure())
10941 EvalObj.finishedConstructingBases();
10945 for (
const auto *Field : RD->
fields()) {
10948 if (
Field->isUnnamedBitField())
10951 LValue Subobject =
This;
10953 bool HaveInit = ElementNo < Args.size();
10958 Subobject, Field, &Layout))
10963 ImplicitValueInitExpr VIE(HaveInit ? Info.Ctx.
IntTy :
Field->getType());
10964 const Expr *
Init = HaveInit ? Args[ElementNo++] : &VIE;
10966 if (
Field->getType()->isIncompleteArrayType()) {
10971 Info.FFDiag(
Init, diag::note_constexpr_unsupported_flexible_array);
10978 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
10982 if (
Field->getType()->isReferenceType()) {
10986 if (!Info.noteFailure())
10991 (
Field->isBitField() &&
10993 if (!Info.noteFailure())
10999 EvalObj.finishedConstructingFields();
11004bool RecordExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E,
11014 return ZeroInitialization(E,
T);
11032 const Expr *SrcObj = E->
getArg(0);
11035 if (
const MaterializeTemporaryExpr *ME =
11036 dyn_cast<MaterializeTemporaryExpr>(SrcObj))
11037 return Visit(ME->getSubExpr());
11040 if (ZeroInit && !ZeroInitialization(E,
T))
11049bool RecordExprEvaluator::VisitCXXInheritedCtorInitExpr(
11050 const CXXInheritedCtorInitExpr *E) {
11051 if (!Info.CurrentCall) {
11052 assert(Info.checkingPotentialConstantExpression());
11071bool RecordExprEvaluator::VisitCXXStdInitializerListExpr(
11072 const CXXStdInitializerListExpr *E) {
11073 const ConstantArrayType *ArrayType =
11080 assert(ArrayType &&
"unexpected type for array initializer");
11083 Array.addArray(Info, E, ArrayType);
11087 Array.moveInto(
Result.getStructField(0));
11091 assert(Field !=
Record->field_end() &&
11094 "Expected std::initializer_list first field to be const E *");
11096 assert(Field !=
Record->field_end() &&
11097 "Expected std::initializer_list to have two fields");
11106 "Expected std::initializer_list second field to be const E *");
11111 Array.moveInto(
Result.getStructField(1));
11114 assert(++Field ==
Record->field_end() &&
11115 "Expected std::initializer_list to only have two fields");
11120bool RecordExprEvaluator::VisitLambdaExpr(
const LambdaExpr *E) {
11125 const size_t NumFields =
11130 "The number of lambda capture initializers should equal the number of "
11131 "fields within the closure type");
11139 for (
const auto *Field : ClosureClass->
fields()) {
11142 Expr *
const CurFieldInit = *CaptureInitIt++;
11149 LValue Subobject =
This;
11156 if (!Info.keepEvaluatingAfterFailure())
11165 APValue &Result, EvalInfo &Info) {
11168 "can't evaluate expression as a record rvalue");
11169 return RecordExprEvaluator(Info,
This, Result).Visit(E);
11180class TemporaryExprEvaluator
11181 :
public LValueExprEvaluatorBase<TemporaryExprEvaluator> {
11183 TemporaryExprEvaluator(EvalInfo &Info, LValue &
Result) :
11184 LValueExprEvaluatorBaseTy(Info,
Result,
false) {}
11187 bool VisitConstructExpr(
const Expr *E) {
11193 bool VisitCastExpr(
const CastExpr *E) {
11196 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
11198 case CK_ConstructorConversion:
11202 bool VisitInitListExpr(
const InitListExpr *E) {
11203 return VisitConstructExpr(E);
11205 bool VisitCXXConstructExpr(
const CXXConstructExpr *E) {
11206 return VisitConstructExpr(E);
11208 bool VisitCallExpr(
const CallExpr *E) {
11209 return VisitConstructExpr(E);
11211 bool VisitCXXStdInitializerListExpr(
const CXXStdInitializerListExpr *E) {
11212 return VisitConstructExpr(E);
11215 return VisitConstructExpr(E);
11224 return TemporaryExprEvaluator(Info, Result).Visit(E);
11232 class VectorExprEvaluator
11233 :
public ExprEvaluatorBase<VectorExprEvaluator> {
11240 bool Success(ArrayRef<APValue>
V,
const Expr *E) {
11241 assert(
V.size() == E->
getType()->
castAs<VectorType>()->getNumElements());
11247 assert(
V.isVector());
11251 bool ZeroInitialization(
const Expr *E);
11253 bool VisitUnaryReal(
const UnaryOperator *E)
11255 bool VisitCastExpr(
const CastExpr* E);
11256 bool VisitInitListExpr(
const InitListExpr *E);
11257 bool VisitUnaryImag(
const UnaryOperator *E);
11258 bool VisitBinaryOperator(
const BinaryOperator *E);
11259 bool VisitUnaryOperator(
const UnaryOperator *E);
11260 bool VisitCallExpr(
const CallExpr *E);
11261 bool VisitConvertVectorExpr(
const ConvertVectorExpr *E);
11262 bool VisitShuffleVectorExpr(
const ShuffleVectorExpr *E);
11271 "not a vector prvalue");
11272 return VectorExprEvaluator(Info, Result).Visit(E);
11276 assert(Val.
isVector() &&
"expected vector APValue");
11280 llvm::APInt
Result(NumElts, 0);
11282 for (
unsigned I = 0; I < NumElts; ++I) {
11284 assert(Elt.
isInt() &&
"expected integer element in bool vector");
11286 if (Elt.
getInt().getBoolValue())
11293bool VectorExprEvaluator::VisitCastExpr(
const CastExpr *E) {
11294 const VectorType *VTy = E->
getType()->
castAs<VectorType>();
11298 QualType SETy = SE->
getType();
11301 case CK_VectorSplat: {
11307 Val =
APValue(std::move(IntResult));
11312 Val =
APValue(std::move(FloatResult));
11329 Info.FFDiag(E, diag::note_constexpr_invalid_cast)
11330 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
11335 if (!handleRValueToRValueBitCast(Info,
Result, SVal, E))
11340 case CK_HLSLVectorTruncation: {
11345 for (
unsigned I = 0; I < NElts; I++)
11350 return ExprEvaluatorBaseTy::VisitCastExpr(E);
11355VectorExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
11372 unsigned CountInits = 0, CountElts = 0;
11373 while (CountElts < NumElements) {
11375 if (CountInits < NumInits
11381 for (
unsigned j = 0; j < vlen; j++)
11385 llvm::APSInt sInt(32);
11386 if (CountInits < NumInits) {
11391 Elements.push_back(
APValue(sInt));
11394 llvm::APFloat f(0.0);
11395 if (CountInits < NumInits) {
11400 Elements.push_back(
APValue(f));
11409VectorExprEvaluator::ZeroInitialization(
const Expr *E) {
11413 if (EltTy->isIntegerType())
11423bool VectorExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
11425 return ZeroInitialization(E);
11428bool VectorExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
11430 assert(Op != BO_PtrMemD && Op != BO_PtrMemI && Op != BO_Cmp &&
11431 "Operation not supported on vector types");
11433 if (Op == BO_Comma)
11434 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
11436 Expr *LHS = E->
getLHS();
11437 Expr *RHS = E->
getRHS();
11440 "Must both be vector types");
11443 assert(LHS->
getType()->
castAs<VectorType>()->getNumElements() ==
11447 "All operands must be the same size.");
11451 bool LHSOK =
Evaluate(LHSValue, Info, LHS);
11452 if (!LHSOK && !Info.noteFailure())
11454 if (!
Evaluate(RHSValue, Info, RHS) || !LHSOK)
11476 "Vector can only be int or float type");
11484 "Vector operator ~ can only be int");
11485 Elt.
getInt().flipAllBits();
11495 "Vector can only be int or float type");
11501 EltResult.setAllBits();
11503 EltResult.clearAllBits();
11509 return std::nullopt;
11513bool VectorExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
11519 const QualType ResultEltTy = VD->getElementType();
11523 if (!
Evaluate(SubExprValue, Info, SubExpr))
11536 "Vector length doesn't match type?");
11539 for (
unsigned EltNum = 0; EltNum < VD->getNumElements(); ++EltNum) {
11541 Info.Ctx, ResultEltTy, Op, SubExprValue.
getVectorElt(EltNum));
11544 ResultElements.push_back(*Elt);
11546 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
11555 Result =
APValue(APFloat(0.0));
11557 DestTy, Result.getFloat());
11568 Result.getFloat());
11573 DestTy, Result.getInt());
11577 Info.FFDiag(E, diag::err_convertvector_constexpr_unsupported_vector_cast)
11578 << SourceTy << DestTy;
11583 llvm::function_ref<APInt(
const APSInt &)> PackFn) {
11592 assert(LHSVecLen != 0 && LHSVecLen == RHSVecLen &&
11593 "pack builtin LHSVecLen must equal to RHSVecLen");
11602 const unsigned SrcPerLane = 128 / SrcBits;
11603 const unsigned Lanes = LHSVecLen * SrcBits / 128;
11606 Out.reserve(LHSVecLen + RHSVecLen);
11608 for (
unsigned Lane = 0; Lane != Lanes; ++Lane) {
11609 unsigned base = Lane * SrcPerLane;
11610 for (
unsigned I = 0; I != SrcPerLane; ++I)
11613 for (
unsigned I = 0; I != SrcPerLane; ++I)
11618 Result =
APValue(Out.data(), Out.size());
11624 llvm::function_ref<std::pair<unsigned, unsigned>(
unsigned,
unsigned)>
11634 unsigned ShuffleMask =
static_cast<unsigned>(MaskImm.getZExtValue());
11643 ResultElements.reserve(NumElts);
11645 for (
unsigned DstIdx = 0; DstIdx != NumElts; ++DstIdx) {
11646 auto [SrcVecIdx, SrcIdx] = GetSourceIndex(DstIdx, ShuffleMask);
11647 const APValue &Src = (SrcVecIdx == 0) ? A : B;
11651 Out =
APValue(ResultElements.data(), ResultElements.size());
11671 ResultElements.reserve(NumElts);
11673 for (
unsigned Idx = 0; Idx != NumElts; ++Idx) {
11676 uint8_t Ctl =
static_cast<uint8_t
>(CtlByte.getZExtValue());
11680 ResultElements.push_back(
Zero);
11682 unsigned LaneBase = (Idx / 16) * 16;
11683 unsigned SrcOffset = Ctl & 0x0F;
11684 unsigned SrcIdx = LaneBase + SrcOffset;
11686 ResultElements.push_back(SrcVec.
getVectorElt(SrcIdx));
11689 Out =
APValue(ResultElements.data(), ResultElements.size());
11694 bool IsShufHW,
APValue &Out) {
11710 unsigned LaneBits = 128u;
11711 unsigned LaneElts = LaneBits / ElemBits;
11712 if (!LaneElts || (NumElts % LaneElts) != 0)
11715 uint8_t Ctl =
static_cast<uint8_t
>(Imm.getZExtValue());
11718 ResultElements.reserve(NumElts);
11720 for (
unsigned Idx = 0; Idx != NumElts; Idx++) {
11721 unsigned LaneBase = (Idx / LaneElts) * LaneElts;
11722 unsigned LaneIdx = Idx % LaneElts;
11723 unsigned SrcIdx = Idx;
11724 unsigned Sel = (Ctl >> (2 * LaneIdx)) & 0x3;
11726 if (ElemBits == 32) {
11727 SrcIdx = LaneBase + Sel;
11729 constexpr unsigned HalfSize = 4;
11730 bool InHigh = LaneIdx >= HalfSize;
11731 if (!IsShufHW && !InHigh) {
11732 SrcIdx = LaneBase + Sel;
11733 }
else if (IsShufHW && InHigh) {
11734 unsigned Rel = LaneIdx - HalfSize;
11735 Sel = (Ctl >> (2 * Rel)) & 0x3;
11736 SrcIdx = LaneBase + HalfSize + Sel;
11743 Out =
APValue(ResultElements.data(), ResultElements.size());
11747bool VectorExprEvaluator::VisitCallExpr(
const CallExpr *E) {
11748 if (!IsConstantEvaluatedBuiltinCall(E))
11749 return ExprEvaluatorBaseTy::VisitCallExpr(E);
11751 auto EvaluateBinOpExpr =
11753 APValue SourceLHS, SourceRHS;
11759 QualType DestEltTy = DestTy->getElementType();
11760 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
11763 ResultElements.reserve(SourceLen);
11765 if (SourceRHS.
isInt()) {
11767 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11769 ResultElements.push_back(
11773 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11776 ResultElements.push_back(
11786 case Builtin::BI__builtin_elementwise_popcount:
11787 case Builtin::BI__builtin_elementwise_bitreverse: {
11792 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
11795 ResultElements.reserve(SourceLen);
11797 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11800 case Builtin::BI__builtin_elementwise_popcount:
11801 ResultElements.push_back(
APValue(
11805 case Builtin::BI__builtin_elementwise_bitreverse:
11806 ResultElements.push_back(
11813 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
11815 case Builtin::BI__builtin_elementwise_abs: {
11820 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
11823 ResultElements.reserve(SourceLen);
11825 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11830 CurrentEle.getInt().
abs(),
11831 DestEltTy->isUnsignedIntegerOrEnumerationType()));
11832 ResultElements.push_back(Val);
11835 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
11838 case Builtin::BI__builtin_elementwise_add_sat:
11839 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
11840 return LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS);
11843 case Builtin::BI__builtin_elementwise_sub_sat:
11844 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
11845 return LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
11848 case X86::BI__builtin_ia32_extract128i256:
11849 case X86::BI__builtin_ia32_vextractf128_pd256:
11850 case X86::BI__builtin_ia32_vextractf128_ps256:
11851 case X86::BI__builtin_ia32_vextractf128_si256: {
11852 APValue SourceVec, SourceImm;
11861 unsigned RetLen = RetVT->getNumElements();
11862 unsigned Idx = SourceImm.
getInt().getZExtValue() & 1;
11865 ResultElements.reserve(RetLen);
11867 for (
unsigned I = 0; I < RetLen; I++)
11868 ResultElements.push_back(SourceVec.
getVectorElt(Idx * RetLen + I));
11873 case X86::BI__builtin_ia32_extracti32x4_256_mask:
11874 case X86::BI__builtin_ia32_extractf32x4_256_mask:
11875 case X86::BI__builtin_ia32_extracti32x4_mask:
11876 case X86::BI__builtin_ia32_extractf32x4_mask:
11877 case X86::BI__builtin_ia32_extracti32x8_mask:
11878 case X86::BI__builtin_ia32_extractf32x8_mask:
11879 case X86::BI__builtin_ia32_extracti64x2_256_mask:
11880 case X86::BI__builtin_ia32_extractf64x2_256_mask:
11881 case X86::BI__builtin_ia32_extracti64x2_512_mask:
11882 case X86::BI__builtin_ia32_extractf64x2_512_mask:
11883 case X86::BI__builtin_ia32_extracti64x4_mask:
11884 case X86::BI__builtin_ia32_extractf64x4_mask: {
11895 unsigned RetLen = RetVT->getNumElements();
11900 unsigned Lanes = SrcLen / RetLen;
11901 unsigned Lane =
static_cast<unsigned>(Imm.getZExtValue() % Lanes);
11902 unsigned Base = Lane * RetLen;
11905 ResultElements.reserve(RetLen);
11906 for (
unsigned I = 0; I < RetLen; ++I) {
11908 ResultElements.push_back(SourceVec.
getVectorElt(Base + I));
11912 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
11915 case clang::X86::BI__builtin_ia32_pavgb128:
11916 case clang::X86::BI__builtin_ia32_pavgw128:
11917 case clang::X86::BI__builtin_ia32_pavgb256:
11918 case clang::X86::BI__builtin_ia32_pavgw256:
11919 case clang::X86::BI__builtin_ia32_pavgb512:
11920 case clang::X86::BI__builtin_ia32_pavgw512:
11921 return EvaluateBinOpExpr(llvm::APIntOps::avgCeilU);
11923 case clang::X86::BI__builtin_ia32_pmulhrsw128:
11924 case clang::X86::BI__builtin_ia32_pmulhrsw256:
11925 case clang::X86::BI__builtin_ia32_pmulhrsw512:
11926 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
11927 return (llvm::APIntOps::mulsExtended(LHS, RHS).ashr(14) + 1)
11928 .extractBits(16, 1);
11931 case clang::X86::BI__builtin_ia32_pmaddubsw128:
11932 case clang::X86::BI__builtin_ia32_pmaddubsw256:
11933 case clang::X86::BI__builtin_ia32_pmaddubsw512:
11934 case clang::X86::BI__builtin_ia32_pmaddwd128:
11935 case clang::X86::BI__builtin_ia32_pmaddwd256:
11936 case clang::X86::BI__builtin_ia32_pmaddwd512: {
11937 APValue SourceLHS, SourceRHS;
11943 QualType DestEltTy = DestTy->getElementType();
11945 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
11947 ResultElements.reserve(SourceLen / 2);
11949 for (
unsigned EltNum = 0; EltNum < SourceLen; EltNum += 2) {
11954 unsigned BitWidth = 2 * LoLHS.getBitWidth();
11957 case clang::X86::BI__builtin_ia32_pmaddubsw128:
11958 case clang::X86::BI__builtin_ia32_pmaddubsw256:
11959 case clang::X86::BI__builtin_ia32_pmaddubsw512:
11960 ResultElements.push_back(
APValue(
11961 APSInt((LoLHS.zext(BitWidth) * LoRHS.sext(BitWidth))
11962 .sadd_sat((HiLHS.zext(BitWidth) * HiRHS.sext(BitWidth))),
11965 case clang::X86::BI__builtin_ia32_pmaddwd128:
11966 case clang::X86::BI__builtin_ia32_pmaddwd256:
11967 case clang::X86::BI__builtin_ia32_pmaddwd512:
11968 ResultElements.push_back(
11969 APValue(
APSInt((LoLHS.sext(BitWidth) * LoRHS.sext(BitWidth)) +
11970 (HiLHS.sext(BitWidth) * HiRHS.sext(BitWidth)),
11976 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
11979 case clang::X86::BI__builtin_ia32_pmulhuw128:
11980 case clang::X86::BI__builtin_ia32_pmulhuw256:
11981 case clang::X86::BI__builtin_ia32_pmulhuw512:
11982 return EvaluateBinOpExpr(llvm::APIntOps::mulhu);
11984 case clang::X86::BI__builtin_ia32_pmulhw128:
11985 case clang::X86::BI__builtin_ia32_pmulhw256:
11986 case clang::X86::BI__builtin_ia32_pmulhw512:
11987 return EvaluateBinOpExpr(llvm::APIntOps::mulhs);
11989 case clang::X86::BI__builtin_ia32_psllv2di:
11990 case clang::X86::BI__builtin_ia32_psllv4di:
11991 case clang::X86::BI__builtin_ia32_psllv4si:
11992 case clang::X86::BI__builtin_ia32_psllv8di:
11993 case clang::X86::BI__builtin_ia32_psllv8hi:
11994 case clang::X86::BI__builtin_ia32_psllv8si:
11995 case clang::X86::BI__builtin_ia32_psllv16hi:
11996 case clang::X86::BI__builtin_ia32_psllv16si:
11997 case clang::X86::BI__builtin_ia32_psllv32hi:
11998 case clang::X86::BI__builtin_ia32_psllwi128:
11999 case clang::X86::BI__builtin_ia32_pslldi128:
12000 case clang::X86::BI__builtin_ia32_psllqi128:
12001 case clang::X86::BI__builtin_ia32_psllwi256:
12002 case clang::X86::BI__builtin_ia32_pslldi256:
12003 case clang::X86::BI__builtin_ia32_psllqi256:
12004 case clang::X86::BI__builtin_ia32_psllwi512:
12005 case clang::X86::BI__builtin_ia32_pslldi512:
12006 case clang::X86::BI__builtin_ia32_psllqi512:
12007 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12008 if (RHS.uge(LHS.getBitWidth())) {
12009 return APInt::getZero(LHS.getBitWidth());
12011 return LHS.shl(RHS.getZExtValue());
12014 case clang::X86::BI__builtin_ia32_psrav4si:
12015 case clang::X86::BI__builtin_ia32_psrav8di:
12016 case clang::X86::BI__builtin_ia32_psrav8hi:
12017 case clang::X86::BI__builtin_ia32_psrav8si:
12018 case clang::X86::BI__builtin_ia32_psrav16hi:
12019 case clang::X86::BI__builtin_ia32_psrav16si:
12020 case clang::X86::BI__builtin_ia32_psrav32hi:
12021 case clang::X86::BI__builtin_ia32_psravq128:
12022 case clang::X86::BI__builtin_ia32_psravq256:
12023 case clang::X86::BI__builtin_ia32_psrawi128:
12024 case clang::X86::BI__builtin_ia32_psradi128:
12025 case clang::X86::BI__builtin_ia32_psraqi128:
12026 case clang::X86::BI__builtin_ia32_psrawi256:
12027 case clang::X86::BI__builtin_ia32_psradi256:
12028 case clang::X86::BI__builtin_ia32_psraqi256:
12029 case clang::X86::BI__builtin_ia32_psrawi512:
12030 case clang::X86::BI__builtin_ia32_psradi512:
12031 case clang::X86::BI__builtin_ia32_psraqi512:
12032 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12033 if (RHS.uge(LHS.getBitWidth())) {
12034 return LHS.ashr(LHS.getBitWidth() - 1);
12036 return LHS.ashr(RHS.getZExtValue());
12039 case clang::X86::BI__builtin_ia32_psrlv2di:
12040 case clang::X86::BI__builtin_ia32_psrlv4di:
12041 case clang::X86::BI__builtin_ia32_psrlv4si:
12042 case clang::X86::BI__builtin_ia32_psrlv8di:
12043 case clang::X86::BI__builtin_ia32_psrlv8hi:
12044 case clang::X86::BI__builtin_ia32_psrlv8si:
12045 case clang::X86::BI__builtin_ia32_psrlv16hi:
12046 case clang::X86::BI__builtin_ia32_psrlv16si:
12047 case clang::X86::BI__builtin_ia32_psrlv32hi:
12048 case clang::X86::BI__builtin_ia32_psrlwi128:
12049 case clang::X86::BI__builtin_ia32_psrldi128:
12050 case clang::X86::BI__builtin_ia32_psrlqi128:
12051 case clang::X86::BI__builtin_ia32_psrlwi256:
12052 case clang::X86::BI__builtin_ia32_psrldi256:
12053 case clang::X86::BI__builtin_ia32_psrlqi256:
12054 case clang::X86::BI__builtin_ia32_psrlwi512:
12055 case clang::X86::BI__builtin_ia32_psrldi512:
12056 case clang::X86::BI__builtin_ia32_psrlqi512:
12057 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12058 if (RHS.uge(LHS.getBitWidth())) {
12059 return APInt::getZero(LHS.getBitWidth());
12061 return LHS.lshr(RHS.getZExtValue());
12063 case X86::BI__builtin_ia32_packsswb128:
12064 case X86::BI__builtin_ia32_packsswb256:
12065 case X86::BI__builtin_ia32_packsswb512:
12066 case X86::BI__builtin_ia32_packssdw128:
12067 case X86::BI__builtin_ia32_packssdw256:
12068 case X86::BI__builtin_ia32_packssdw512:
12070 return APSInt(Src).truncSSat(Src.getBitWidth() / 2);
12072 case X86::BI__builtin_ia32_packusdw128:
12073 case X86::BI__builtin_ia32_packusdw256:
12074 case X86::BI__builtin_ia32_packusdw512:
12075 case X86::BI__builtin_ia32_packuswb128:
12076 case X86::BI__builtin_ia32_packuswb256:
12077 case X86::BI__builtin_ia32_packuswb512:
12079 unsigned DstBits = Src.getBitWidth() / 2;
12080 if (Src.isNegative())
12081 return APInt::getZero(DstBits);
12082 if (Src.isIntN(DstBits))
12084 return APInt::getAllOnes(DstBits);
12086 case clang::X86::BI__builtin_ia32_pmuldq128:
12087 case clang::X86::BI__builtin_ia32_pmuldq256:
12088 case clang::X86::BI__builtin_ia32_pmuldq512:
12089 case clang::X86::BI__builtin_ia32_pmuludq128:
12090 case clang::X86::BI__builtin_ia32_pmuludq256:
12091 case clang::X86::BI__builtin_ia32_pmuludq512: {
12092 APValue SourceLHS, SourceRHS;
12099 ResultElements.reserve(SourceLen / 2);
12101 for (
unsigned EltNum = 0; EltNum < SourceLen; EltNum += 2) {
12106 case clang::X86::BI__builtin_ia32_pmuludq128:
12107 case clang::X86::BI__builtin_ia32_pmuludq256:
12108 case clang::X86::BI__builtin_ia32_pmuludq512:
12109 ResultElements.push_back(
12110 APValue(
APSInt(llvm::APIntOps::muluExtended(LHS, RHS),
true)));
12112 case clang::X86::BI__builtin_ia32_pmuldq128:
12113 case clang::X86::BI__builtin_ia32_pmuldq256:
12114 case clang::X86::BI__builtin_ia32_pmuldq512:
12115 ResultElements.push_back(
12116 APValue(
APSInt(llvm::APIntOps::mulsExtended(LHS, RHS),
false)));
12121 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12124 case X86::BI__builtin_ia32_vpmadd52luq128:
12125 case X86::BI__builtin_ia32_vpmadd52luq256:
12126 case X86::BI__builtin_ia32_vpmadd52luq512: {
12135 ResultElements.reserve(ALen);
12137 for (
unsigned EltNum = 0; EltNum < ALen; EltNum += 1) {
12140 APInt CElt =
C.getVectorElt(EltNum).getInt().trunc(52);
12141 APSInt ResElt(AElt + (BElt * CElt).zext(64),
false);
12142 ResultElements.push_back(
APValue(ResElt));
12145 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12147 case X86::BI__builtin_ia32_vpmadd52huq128:
12148 case X86::BI__builtin_ia32_vpmadd52huq256:
12149 case X86::BI__builtin_ia32_vpmadd52huq512: {
12158 ResultElements.reserve(ALen);
12160 for (
unsigned EltNum = 0; EltNum < ALen; EltNum += 1) {
12163 APInt CElt =
C.getVectorElt(EltNum).getInt().trunc(52);
12164 APSInt ResElt(AElt + llvm::APIntOps::mulhu(BElt, CElt).zext(64),
false);
12165 ResultElements.push_back(
APValue(ResElt));
12168 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12171 case clang::X86::BI__builtin_ia32_vprotbi:
12172 case clang::X86::BI__builtin_ia32_vprotdi:
12173 case clang::X86::BI__builtin_ia32_vprotqi:
12174 case clang::X86::BI__builtin_ia32_vprotwi:
12175 case clang::X86::BI__builtin_ia32_prold128:
12176 case clang::X86::BI__builtin_ia32_prold256:
12177 case clang::X86::BI__builtin_ia32_prold512:
12178 case clang::X86::BI__builtin_ia32_prolq128:
12179 case clang::X86::BI__builtin_ia32_prolq256:
12180 case clang::X86::BI__builtin_ia32_prolq512:
12181 return EvaluateBinOpExpr(
12182 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS.rotl(RHS); });
12184 case clang::X86::BI__builtin_ia32_prord128:
12185 case clang::X86::BI__builtin_ia32_prord256:
12186 case clang::X86::BI__builtin_ia32_prord512:
12187 case clang::X86::BI__builtin_ia32_prorq128:
12188 case clang::X86::BI__builtin_ia32_prorq256:
12189 case clang::X86::BI__builtin_ia32_prorq512:
12190 return EvaluateBinOpExpr(
12191 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS.rotr(RHS); });
12193 case Builtin::BI__builtin_elementwise_max:
12194 case Builtin::BI__builtin_elementwise_min: {
12195 APValue SourceLHS, SourceRHS;
12200 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12207 ResultElements.reserve(SourceLen);
12209 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12213 case Builtin::BI__builtin_elementwise_max:
12214 ResultElements.push_back(
12218 case Builtin::BI__builtin_elementwise_min:
12219 ResultElements.push_back(
12226 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12228 case X86::BI__builtin_ia32_vpshldd128:
12229 case X86::BI__builtin_ia32_vpshldd256:
12230 case X86::BI__builtin_ia32_vpshldd512:
12231 case X86::BI__builtin_ia32_vpshldq128:
12232 case X86::BI__builtin_ia32_vpshldq256:
12233 case X86::BI__builtin_ia32_vpshldq512:
12234 case X86::BI__builtin_ia32_vpshldw128:
12235 case X86::BI__builtin_ia32_vpshldw256:
12236 case X86::BI__builtin_ia32_vpshldw512: {
12237 APValue SourceHi, SourceLo, SourceAmt;
12243 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12246 ResultElements.reserve(SourceLen);
12249 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12252 APInt R = llvm::APIntOps::fshl(Hi, Lo, Amt);
12253 ResultElements.push_back(
12257 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12259 case X86::BI__builtin_ia32_vpshrdd128:
12260 case X86::BI__builtin_ia32_vpshrdd256:
12261 case X86::BI__builtin_ia32_vpshrdd512:
12262 case X86::BI__builtin_ia32_vpshrdq128:
12263 case X86::BI__builtin_ia32_vpshrdq256:
12264 case X86::BI__builtin_ia32_vpshrdq512:
12265 case X86::BI__builtin_ia32_vpshrdw128:
12266 case X86::BI__builtin_ia32_vpshrdw256:
12267 case X86::BI__builtin_ia32_vpshrdw512: {
12269 APValue SourceHi, SourceLo, SourceAmt;
12275 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12278 ResultElements.reserve(SourceLen);
12281 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12284 APInt R = llvm::APIntOps::fshr(Hi, Lo, Amt);
12285 ResultElements.push_back(
12289 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12291 case X86::BI__builtin_ia32_vpconflictsi_128:
12292 case X86::BI__builtin_ia32_vpconflictsi_256:
12293 case X86::BI__builtin_ia32_vpconflictsi_512:
12294 case X86::BI__builtin_ia32_vpconflictdi_128:
12295 case X86::BI__builtin_ia32_vpconflictdi_256:
12296 case X86::BI__builtin_ia32_vpconflictdi_512: {
12304 ResultElements.reserve(SourceLen);
12307 bool DestUnsigned =
12308 VecT->getElementType()->isUnsignedIntegerOrEnumerationType();
12310 for (
unsigned I = 0; I != SourceLen; ++I) {
12313 APInt ConflictMask(EltI.
getInt().getBitWidth(), 0);
12314 for (
unsigned J = 0; J != I; ++J) {
12316 ConflictMask.setBitVal(J, EltI.
getInt() == EltJ.
getInt());
12318 ResultElements.push_back(
APValue(
APSInt(ConflictMask, DestUnsigned)));
12320 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12322 case X86::BI__builtin_ia32_blendpd:
12323 case X86::BI__builtin_ia32_blendpd256:
12324 case X86::BI__builtin_ia32_blendps:
12325 case X86::BI__builtin_ia32_blendps256:
12326 case X86::BI__builtin_ia32_pblendw128:
12327 case X86::BI__builtin_ia32_pblendw256:
12328 case X86::BI__builtin_ia32_pblendd128:
12329 case X86::BI__builtin_ia32_pblendd256: {
12330 APValue SourceF, SourceT, SourceC;
12339 ResultElements.reserve(SourceLen);
12340 for (
unsigned EltNum = 0; EltNum != SourceLen; ++EltNum) {
12343 ResultElements.push_back(
C[EltNum % 8] ?
T : F);
12346 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12349 case X86::BI__builtin_ia32_psignb128:
12350 case X86::BI__builtin_ia32_psignb256:
12351 case X86::BI__builtin_ia32_psignw128:
12352 case X86::BI__builtin_ia32_psignw256:
12353 case X86::BI__builtin_ia32_psignd128:
12354 case X86::BI__builtin_ia32_psignd256:
12355 return EvaluateBinOpExpr([](
const APInt &AElem,
const APInt &BElem) {
12356 if (BElem.isZero())
12357 return APInt::getZero(AElem.getBitWidth());
12358 if (BElem.isNegative())
12363 case X86::BI__builtin_ia32_blendvpd:
12364 case X86::BI__builtin_ia32_blendvpd256:
12365 case X86::BI__builtin_ia32_blendvps:
12366 case X86::BI__builtin_ia32_blendvps256:
12367 case X86::BI__builtin_ia32_pblendvb128:
12368 case X86::BI__builtin_ia32_pblendvb256: {
12370 APValue SourceF, SourceT, SourceC;
12378 ResultElements.reserve(SourceLen);
12380 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12384 APInt M =
C.isInt() ? (
APInt)
C.getInt() :
C.getFloat().bitcastToAPInt();
12385 ResultElements.push_back(M.isNegative() ?
T : F);
12388 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12390 case X86::BI__builtin_ia32_selectb_128:
12391 case X86::BI__builtin_ia32_selectb_256:
12392 case X86::BI__builtin_ia32_selectb_512:
12393 case X86::BI__builtin_ia32_selectw_128:
12394 case X86::BI__builtin_ia32_selectw_256:
12395 case X86::BI__builtin_ia32_selectw_512:
12396 case X86::BI__builtin_ia32_selectd_128:
12397 case X86::BI__builtin_ia32_selectd_256:
12398 case X86::BI__builtin_ia32_selectd_512:
12399 case X86::BI__builtin_ia32_selectq_128:
12400 case X86::BI__builtin_ia32_selectq_256:
12401 case X86::BI__builtin_ia32_selectq_512:
12402 case X86::BI__builtin_ia32_selectph_128:
12403 case X86::BI__builtin_ia32_selectph_256:
12404 case X86::BI__builtin_ia32_selectph_512:
12405 case X86::BI__builtin_ia32_selectpbf_128:
12406 case X86::BI__builtin_ia32_selectpbf_256:
12407 case X86::BI__builtin_ia32_selectpbf_512:
12408 case X86::BI__builtin_ia32_selectps_128:
12409 case X86::BI__builtin_ia32_selectps_256:
12410 case X86::BI__builtin_ia32_selectps_512:
12411 case X86::BI__builtin_ia32_selectpd_128:
12412 case X86::BI__builtin_ia32_selectpd_256:
12413 case X86::BI__builtin_ia32_selectpd_512: {
12415 APValue SourceMask, SourceLHS, SourceRHS;
12424 ResultElements.reserve(SourceLen);
12426 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12429 ResultElements.push_back(Mask[EltNum] ? LHS : RHS);
12432 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12434 case X86::BI__builtin_ia32_shufps:
12435 case X86::BI__builtin_ia32_shufps256:
12436 case X86::BI__builtin_ia32_shufps512: {
12440 [](
unsigned DstIdx,
12441 unsigned ShuffleMask) -> std::pair<unsigned, unsigned> {
12442 constexpr unsigned LaneBits = 128u;
12443 unsigned NumElemPerLane = LaneBits / 32;
12444 unsigned NumSelectableElems = NumElemPerLane / 2;
12445 unsigned BitsPerElem = 2;
12446 unsigned IndexMask = (1u << BitsPerElem) - 1;
12447 unsigned MaskBits = 8;
12448 unsigned Lane = DstIdx / NumElemPerLane;
12449 unsigned ElemInLane = DstIdx % NumElemPerLane;
12450 unsigned LaneOffset = Lane * NumElemPerLane;
12451 unsigned BitIndex = (DstIdx * BitsPerElem) % MaskBits;
12452 unsigned SrcIdx = (ElemInLane < NumSelectableElems) ? 0 : 1;
12453 unsigned Index = (ShuffleMask >> BitIndex) & IndexMask;
12454 return {SrcIdx, LaneOffset + Index};
12459 case X86::BI__builtin_ia32_shufpd:
12460 case X86::BI__builtin_ia32_shufpd256:
12461 case X86::BI__builtin_ia32_shufpd512: {
12465 [](
unsigned DstIdx,
12466 unsigned ShuffleMask) -> std::pair<unsigned, unsigned> {
12467 constexpr unsigned LaneBits = 128u;
12468 unsigned NumElemPerLane = LaneBits / 64;
12469 unsigned NumSelectableElems = NumElemPerLane / 2;
12470 unsigned BitsPerElem = 1;
12471 unsigned IndexMask = (1u << BitsPerElem) - 1;
12472 unsigned MaskBits = 8;
12473 unsigned Lane = DstIdx / NumElemPerLane;
12474 unsigned ElemInLane = DstIdx % NumElemPerLane;
12475 unsigned LaneOffset = Lane * NumElemPerLane;
12476 unsigned BitIndex = (DstIdx * BitsPerElem) % MaskBits;
12477 unsigned SrcIdx = (ElemInLane < NumSelectableElems) ? 0 : 1;
12478 unsigned Index = (ShuffleMask >> BitIndex) & IndexMask;
12479 return {SrcIdx, LaneOffset + Index};
12484 case X86::BI__builtin_ia32_pshufb128:
12485 case X86::BI__builtin_ia32_pshufb256:
12486 case X86::BI__builtin_ia32_pshufb512: {
12493 case X86::BI__builtin_ia32_pshuflw:
12494 case X86::BI__builtin_ia32_pshuflw256:
12495 case X86::BI__builtin_ia32_pshuflw512: {
12502 case X86::BI__builtin_ia32_pshufhw:
12503 case X86::BI__builtin_ia32_pshufhw256:
12504 case X86::BI__builtin_ia32_pshufhw512: {
12511 case X86::BI__builtin_ia32_pshufd:
12512 case X86::BI__builtin_ia32_pshufd256:
12513 case X86::BI__builtin_ia32_pshufd512: {
12520 case X86::BI__builtin_ia32_phminposuw128: {
12527 unsigned ElemBitWidth = Info.Ctx.
getTypeSize(ElemQT);
12529 APInt MinIndex(ElemBitWidth, 0);
12531 for (
unsigned I = 1; I != SourceLen; ++I) {
12533 if (MinVal.ugt(Val)) {
12542 ->isUnsignedIntegerOrEnumerationType();
12545 Result.reserve(SourceLen);
12547 Result.emplace_back(
APSInt(MinIndex, ResultUnsigned));
12548 for (
unsigned I = 0; I != SourceLen - 2; ++I) {
12554 case X86::BI__builtin_ia32_pternlogd128_mask:
12555 case X86::BI__builtin_ia32_pternlogd256_mask:
12556 case X86::BI__builtin_ia32_pternlogd512_mask:
12557 case X86::BI__builtin_ia32_pternlogq128_mask:
12558 case X86::BI__builtin_ia32_pternlogq256_mask:
12559 case X86::BI__builtin_ia32_pternlogq512_mask: {
12560 APValue AValue, BValue, CValue, ImmValue, UValue;
12568 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12574 ResultElements.reserve(ResultLen);
12576 for (
unsigned EltNum = 0; EltNum < ResultLen; ++EltNum) {
12582 unsigned BitWidth = ALane.getBitWidth();
12583 APInt ResLane(BitWidth, 0);
12585 for (
unsigned Bit = 0; Bit < BitWidth; ++Bit) {
12586 unsigned ABit = ALane[Bit];
12587 unsigned BBit = BLane[Bit];
12588 unsigned CBit = CLane[Bit];
12590 unsigned Idx = (ABit << 2) | (BBit << 1) | CBit;
12591 ResLane.setBitVal(Bit, Imm[Idx]);
12593 ResultElements.push_back(
APValue(
APSInt(ResLane, DestUnsigned)));
12595 ResultElements.push_back(
APValue(
APSInt(ALane, DestUnsigned)));
12598 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12600 case X86::BI__builtin_ia32_pternlogd128_maskz:
12601 case X86::BI__builtin_ia32_pternlogd256_maskz:
12602 case X86::BI__builtin_ia32_pternlogd512_maskz:
12603 case X86::BI__builtin_ia32_pternlogq128_maskz:
12604 case X86::BI__builtin_ia32_pternlogq256_maskz:
12605 case X86::BI__builtin_ia32_pternlogq512_maskz: {
12606 APValue AValue, BValue, CValue, ImmValue, UValue;
12614 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12620 ResultElements.reserve(ResultLen);
12622 for (
unsigned EltNum = 0; EltNum < ResultLen; ++EltNum) {
12627 unsigned BitWidth = ALane.getBitWidth();
12628 APInt ResLane(BitWidth, 0);
12631 for (
unsigned Bit = 0; Bit < BitWidth; ++Bit) {
12632 unsigned ABit = ALane[Bit];
12633 unsigned BBit = BLane[Bit];
12634 unsigned CBit = CLane[Bit];
12636 unsigned Idx = (ABit << 2) | (BBit << 1) | CBit;
12637 ResLane.setBitVal(Bit, Imm[Idx]);
12640 ResultElements.push_back(
APValue(
APSInt(ResLane, DestUnsigned)));
12642 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12645 case Builtin::BI__builtin_elementwise_clzg:
12646 case Builtin::BI__builtin_elementwise_ctzg: {
12648 std::optional<APValue> Fallback;
12655 Fallback = FallbackTmp;
12658 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12661 ResultElements.reserve(SourceLen);
12663 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12668 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
12670 Builtin::BI__builtin_elementwise_ctzg);
12673 ResultElements.push_back(Fallback->getVectorElt(EltNum));
12677 case Builtin::BI__builtin_elementwise_clzg:
12678 ResultElements.push_back(
APValue(
12682 case Builtin::BI__builtin_elementwise_ctzg:
12683 ResultElements.push_back(
APValue(
12690 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12693 case Builtin::BI__builtin_elementwise_fma: {
12694 APValue SourceX, SourceY, SourceZ;
12702 ResultElements.reserve(SourceLen);
12704 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12709 (void)
Result.fusedMultiplyAdd(Y, Z, RM);
12712 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12715 case clang::X86::BI__builtin_ia32_phaddw128:
12716 case clang::X86::BI__builtin_ia32_phaddw256:
12717 case clang::X86::BI__builtin_ia32_phaddd128:
12718 case clang::X86::BI__builtin_ia32_phaddd256:
12719 case clang::X86::BI__builtin_ia32_phaddsw128:
12720 case clang::X86::BI__builtin_ia32_phaddsw256:
12722 case clang::X86::BI__builtin_ia32_phsubw128:
12723 case clang::X86::BI__builtin_ia32_phsubw256:
12724 case clang::X86::BI__builtin_ia32_phsubd128:
12725 case clang::X86::BI__builtin_ia32_phsubd256:
12726 case clang::X86::BI__builtin_ia32_phsubsw128:
12727 case clang::X86::BI__builtin_ia32_phsubsw256: {
12728 APValue SourceLHS, SourceRHS;
12732 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12736 unsigned EltBits = Info.Ctx.
getIntWidth(DestEltTy);
12737 unsigned EltsPerLane = 128 / EltBits;
12739 ResultElements.reserve(NumElts);
12741 for (
unsigned LaneStart = 0; LaneStart != NumElts;
12742 LaneStart += EltsPerLane) {
12743 for (
unsigned I = 0; I != EltsPerLane; I += 2) {
12747 case clang::X86::BI__builtin_ia32_phaddw128:
12748 case clang::X86::BI__builtin_ia32_phaddw256:
12749 case clang::X86::BI__builtin_ia32_phaddd128:
12750 case clang::X86::BI__builtin_ia32_phaddd256: {
12751 APSInt Res(LHSA + LHSB, DestUnsigned);
12752 ResultElements.push_back(
APValue(Res));
12755 case clang::X86::BI__builtin_ia32_phaddsw128:
12756 case clang::X86::BI__builtin_ia32_phaddsw256: {
12757 APSInt Res(LHSA.sadd_sat(LHSB));
12758 ResultElements.push_back(
APValue(Res));
12761 case clang::X86::BI__builtin_ia32_phsubw128:
12762 case clang::X86::BI__builtin_ia32_phsubw256:
12763 case clang::X86::BI__builtin_ia32_phsubd128:
12764 case clang::X86::BI__builtin_ia32_phsubd256: {
12765 APSInt Res(LHSA - LHSB, DestUnsigned);
12766 ResultElements.push_back(
APValue(Res));
12769 case clang::X86::BI__builtin_ia32_phsubsw128:
12770 case clang::X86::BI__builtin_ia32_phsubsw256: {
12771 APSInt Res(LHSA.ssub_sat(LHSB));
12772 ResultElements.push_back(
APValue(Res));
12777 for (
unsigned I = 0; I != EltsPerLane; I += 2) {
12781 case clang::X86::BI__builtin_ia32_phaddw128:
12782 case clang::X86::BI__builtin_ia32_phaddw256:
12783 case clang::X86::BI__builtin_ia32_phaddd128:
12784 case clang::X86::BI__builtin_ia32_phaddd256: {
12785 APSInt Res(RHSA + RHSB, DestUnsigned);
12786 ResultElements.push_back(
APValue(Res));
12789 case clang::X86::BI__builtin_ia32_phaddsw128:
12790 case clang::X86::BI__builtin_ia32_phaddsw256: {
12791 APSInt Res(RHSA.sadd_sat(RHSB));
12792 ResultElements.push_back(
APValue(Res));
12795 case clang::X86::BI__builtin_ia32_phsubw128:
12796 case clang::X86::BI__builtin_ia32_phsubw256:
12797 case clang::X86::BI__builtin_ia32_phsubd128:
12798 case clang::X86::BI__builtin_ia32_phsubd256: {
12799 APSInt Res(RHSA - RHSB, DestUnsigned);
12800 ResultElements.push_back(
APValue(Res));
12803 case clang::X86::BI__builtin_ia32_phsubsw128:
12804 case clang::X86::BI__builtin_ia32_phsubsw256: {
12805 APSInt Res(RHSA.ssub_sat(RHSB));
12806 ResultElements.push_back(
APValue(Res));
12812 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12814 case clang::X86::BI__builtin_ia32_haddpd:
12815 case clang::X86::BI__builtin_ia32_haddps:
12816 case clang::X86::BI__builtin_ia32_haddps256:
12817 case clang::X86::BI__builtin_ia32_haddpd256:
12818 case clang::X86::BI__builtin_ia32_hsubpd:
12819 case clang::X86::BI__builtin_ia32_hsubps:
12820 case clang::X86::BI__builtin_ia32_hsubps256:
12821 case clang::X86::BI__builtin_ia32_hsubpd256: {
12822 APValue SourceLHS, SourceRHS;
12828 ResultElements.reserve(NumElts);
12830 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12831 unsigned EltBits = Info.Ctx.
getTypeSize(DestEltTy);
12832 unsigned NumLanes = NumElts * EltBits / 128;
12833 unsigned NumElemsPerLane = NumElts / NumLanes;
12834 unsigned HalfElemsPerLane = NumElemsPerLane / 2;
12836 for (
unsigned L = 0; L != NumElts; L += NumElemsPerLane) {
12837 for (
unsigned I = 0; I != HalfElemsPerLane; ++I) {
12841 case clang::X86::BI__builtin_ia32_haddpd:
12842 case clang::X86::BI__builtin_ia32_haddps:
12843 case clang::X86::BI__builtin_ia32_haddps256:
12844 case clang::X86::BI__builtin_ia32_haddpd256:
12845 LHSA.add(LHSB, RM);
12847 case clang::X86::BI__builtin_ia32_hsubpd:
12848 case clang::X86::BI__builtin_ia32_hsubps:
12849 case clang::X86::BI__builtin_ia32_hsubps256:
12850 case clang::X86::BI__builtin_ia32_hsubpd256:
12851 LHSA.subtract(LHSB, RM);
12854 ResultElements.push_back(
APValue(LHSA));
12856 for (
unsigned I = 0; I != HalfElemsPerLane; ++I) {
12860 case clang::X86::BI__builtin_ia32_haddpd:
12861 case clang::X86::BI__builtin_ia32_haddps:
12862 case clang::X86::BI__builtin_ia32_haddps256:
12863 case clang::X86::BI__builtin_ia32_haddpd256:
12864 RHSA.add(RHSB, RM);
12866 case clang::X86::BI__builtin_ia32_hsubpd:
12867 case clang::X86::BI__builtin_ia32_hsubps:
12868 case clang::X86::BI__builtin_ia32_hsubps256:
12869 case clang::X86::BI__builtin_ia32_hsubpd256:
12870 RHSA.subtract(RHSB, RM);
12873 ResultElements.push_back(
APValue(RHSA));
12876 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12878 case Builtin::BI__builtin_elementwise_fshl:
12879 case Builtin::BI__builtin_elementwise_fshr: {
12880 APValue SourceHi, SourceLo, SourceShift;
12886 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12892 ResultElements.reserve(SourceLen);
12893 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12898 case Builtin::BI__builtin_elementwise_fshl:
12899 ResultElements.push_back(
APValue(
12900 APSInt(llvm::APIntOps::fshl(Hi, Lo, Shift), Hi.isUnsigned())));
12902 case Builtin::BI__builtin_elementwise_fshr:
12903 ResultElements.push_back(
APValue(
12904 APSInt(llvm::APIntOps::fshr(Hi, Lo, Shift), Hi.isUnsigned())));
12909 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12912 case X86::BI__builtin_ia32_insertf32x4_256:
12913 case X86::BI__builtin_ia32_inserti32x4_256:
12914 case X86::BI__builtin_ia32_insertf64x2_256:
12915 case X86::BI__builtin_ia32_inserti64x2_256:
12916 case X86::BI__builtin_ia32_insertf32x4:
12917 case X86::BI__builtin_ia32_inserti32x4:
12918 case X86::BI__builtin_ia32_insertf64x2_512:
12919 case X86::BI__builtin_ia32_inserti64x2_512:
12920 case X86::BI__builtin_ia32_insertf32x8:
12921 case X86::BI__builtin_ia32_inserti32x8:
12922 case X86::BI__builtin_ia32_insertf64x4:
12923 case X86::BI__builtin_ia32_inserti64x4:
12924 case X86::BI__builtin_ia32_vinsertf128_ps256:
12925 case X86::BI__builtin_ia32_vinsertf128_pd256:
12926 case X86::BI__builtin_ia32_vinsertf128_si256:
12927 case X86::BI__builtin_ia32_insert128i256: {
12928 APValue SourceDst, SourceSub;
12940 assert(SubLen != 0 && DstLen != 0 && (DstLen % SubLen) == 0);
12941 unsigned NumLanes = DstLen / SubLen;
12942 unsigned LaneIdx = (Imm.getZExtValue() % NumLanes) * SubLen;
12945 ResultElements.reserve(DstLen);
12947 for (
unsigned EltNum = 0; EltNum < DstLen; ++EltNum) {
12948 if (EltNum >= LaneIdx && EltNum < LaneIdx + SubLen)
12949 ResultElements.push_back(SourceSub.
getVectorElt(EltNum - LaneIdx));
12951 ResultElements.push_back(SourceDst.
getVectorElt(EltNum));
12954 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12957 case clang::X86::BI__builtin_ia32_vec_set_v4hi:
12958 case clang::X86::BI__builtin_ia32_vec_set_v16qi:
12959 case clang::X86::BI__builtin_ia32_vec_set_v8hi:
12960 case clang::X86::BI__builtin_ia32_vec_set_v4si:
12961 case clang::X86::BI__builtin_ia32_vec_set_v2di:
12962 case clang::X86::BI__builtin_ia32_vec_set_v32qi:
12963 case clang::X86::BI__builtin_ia32_vec_set_v16hi:
12964 case clang::X86::BI__builtin_ia32_vec_set_v8si:
12965 case clang::X86::BI__builtin_ia32_vec_set_v4di: {
12973 QualType ElemTy = E->
getType()->
castAs<VectorType>()->getElementType();
12974 unsigned ElemWidth = Info.Ctx.
getIntWidth(ElemTy);
12976 Scalar.setIsUnsigned(ElemUnsigned);
12982 static_cast<unsigned>(IndexAPS.getZExtValue() & (NumElems - 1));
12985 Elems.reserve(NumElems);
12986 for (
unsigned ElemNum = 0; ElemNum != NumElems; ++ElemNum)
12987 Elems.push_back(ElemNum == Index ? ElemAV : VecVal.
getVectorElt(ElemNum));
12992 case X86::BI__builtin_ia32_pslldqi128_byteshift:
12993 case X86::BI__builtin_ia32_pslldqi256_byteshift:
12994 case X86::BI__builtin_ia32_pslldqi512_byteshift: {
13004 unsigned Shift = Imm.getZExtValue() & 0xff;
13007 for (
unsigned Lane = 0; Lane != VecLen; Lane += 16) {
13008 for (
unsigned I = 0; I != 16; ++I) {
13014 ResultElements.push_back(Src.
getVectorElt(Lane + I - Shift));
13019 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13022 case X86::BI__builtin_ia32_psrldqi128_byteshift:
13023 case X86::BI__builtin_ia32_psrldqi256_byteshift:
13024 case X86::BI__builtin_ia32_psrldqi512_byteshift: {
13034 unsigned Shift = Imm.getZExtValue() & 0xff;
13037 for (
unsigned Lane = 0; Lane != VecLen; Lane += 16) {
13038 for (
unsigned I = 0; I != 16; ++I) {
13039 if (I + Shift < 16) {
13040 ResultElements.push_back(Src.
getVectorElt(Lane + I + Shift));
13049 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13054bool VectorExprEvaluator::VisitConvertVectorExpr(
const ConvertVectorExpr *E) {
13060 QualType DestTy = E->
getType()->
castAs<VectorType>()->getElementType();
13061 QualType SourceTy = SourceVecType->
castAs<VectorType>()->getElementType();
13067 ResultElements.reserve(SourceLen);
13068 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13073 ResultElements.push_back(std::move(Elt));
13076 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13081 APValue const &VecVal2,
unsigned EltNum,
13083 unsigned const TotalElementsInInputVector1 = VecVal1.
getVectorLength();
13084 unsigned const TotalElementsInInputVector2 = VecVal2.
getVectorLength();
13087 int64_t
index = IndexVal.getExtValue();
13094 E, diag::err_shufflevector_minus_one_is_undefined_behavior_constexpr)
13100 index >= TotalElementsInInputVector1 + TotalElementsInInputVector2)
13101 llvm_unreachable(
"Out of bounds shuffle index");
13103 if (
index >= TotalElementsInInputVector1)
13110bool VectorExprEvaluator::VisitShuffleVectorExpr(
const ShuffleVectorExpr *E) {
13115 const Expr *Vec1 = E->
getExpr(0);
13119 const Expr *Vec2 = E->
getExpr(1);
13123 VectorType
const *DestVecTy = E->
getType()->
castAs<VectorType>();
13129 ResultElements.reserve(TotalElementsInOutputVector);
13130 for (
unsigned EltNum = 0; EltNum < TotalElementsInOutputVector; ++EltNum) {
13134 ResultElements.push_back(std::move(Elt));
13137 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13145 class ArrayExprEvaluator
13146 :
public ExprEvaluatorBase<ArrayExprEvaluator> {
13147 const LValue &
This;
13151 ArrayExprEvaluator(EvalInfo &Info,
const LValue &This,
APValue &
Result)
13155 assert(
V.isArray() &&
"expected array");
13160 bool ZeroInitialization(
const Expr *E) {
13161 const ConstantArrayType *CAT =
13176 if (!
Result.hasArrayFiller())
13180 LValue Subobject =
This;
13181 Subobject.addArray(Info, E, CAT);
13186 bool VisitCallExpr(
const CallExpr *E) {
13187 return handleCallExpr(E,
Result, &This);
13189 bool VisitInitListExpr(
const InitListExpr *E,
13190 QualType AllocType = QualType());
13191 bool VisitArrayInitLoopExpr(
const ArrayInitLoopExpr *E);
13192 bool VisitCXXConstructExpr(
const CXXConstructExpr *E);
13193 bool VisitCXXConstructExpr(
const CXXConstructExpr *E,
13194 const LValue &Subobject,
13196 bool VisitStringLiteral(
const StringLiteral *E,
13197 QualType AllocType = QualType()) {
13201 bool VisitCXXParenListInitExpr(
const CXXParenListInitExpr *E);
13202 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
13203 ArrayRef<Expr *> Args,
13204 const Expr *ArrayFiller,
13205 QualType AllocType = QualType());
13210 APValue &Result, EvalInfo &Info) {
13213 "not an array prvalue");
13214 return ArrayExprEvaluator(Info,
This, Result).Visit(E);
13222 "not an array prvalue");
13223 return ArrayExprEvaluator(Info,
This, Result)
13224 .VisitInitListExpr(ILE, AllocType);
13233 "not an array prvalue");
13234 return ArrayExprEvaluator(Info,
This, Result)
13235 .VisitCXXConstructExpr(CCE,
This, &Result, AllocType);
13244 if (
const InitListExpr *ILE = dyn_cast<InitListExpr>(FillerExpr)) {
13245 for (
unsigned I = 0, E = ILE->
getNumInits(); I != E; ++I) {
13250 if (ILE->hasArrayFiller() &&
13259bool ArrayExprEvaluator::VisitInitListExpr(
const InitListExpr *E,
13260 QualType AllocType) {
13274 return VisitStringLiteral(SL, AllocType);
13279 "transparent array list initialization is not string literal init?");
13285bool ArrayExprEvaluator::VisitCXXParenListOrInitListExpr(
13287 QualType AllocType) {
13293 assert((!
Result.isArray() ||
Result.getArrayInitializedElts() == 0) &&
13294 "zero-initialized array shouldn't have any initialized elts");
13299 unsigned NumEltsToInit = Args.size();
13304 if (NumEltsToInit != NumElts &&
13306 NumEltsToInit = NumElts;
13308 for (
auto *
Init : Args) {
13309 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts()))
13310 NumEltsToInit += EmbedS->getDataElementCount() - 1;
13312 if (NumEltsToInit > NumElts)
13313 NumEltsToInit = NumElts;
13316 LLVM_DEBUG(llvm::dbgs() <<
"The number of elements to initialize: "
13317 << NumEltsToInit <<
".\n");
13319 Result =
APValue(APValue::UninitArray(), NumEltsToInit, NumElts);
13324 for (
unsigned I = 0, E =
Result.getArrayInitializedElts(); I != E; ++I)
13325 Result.getArrayInitializedElt(I) = Filler;
13326 if (
Result.hasArrayFiller())
13330 LValue Subobject =
This;
13331 Subobject.addArray(Info, ExprToVisit, CAT);
13332 auto Eval = [&](
const Expr *
Init,
unsigned ArrayIndex) {
13333 if (
Init->isValueDependent())
13337 Subobject,
Init) ||
13340 if (!Info.noteFailure())
13346 unsigned ArrayIndex = 0;
13349 for (
unsigned Index = 0; Index != NumEltsToInit; ++Index) {
13350 const Expr *
Init = Index < Args.size() ? Args[Index] : ArrayFiller;
13351 if (ArrayIndex >= NumEltsToInit)
13353 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
13354 StringLiteral *SL = EmbedS->getDataStringLiteral();
13355 for (
unsigned I = EmbedS->getStartingElementPos(),
13356 N = EmbedS->getDataElementCount();
13357 I != EmbedS->getStartingElementPos() + N; ++I) {
13363 const FPOptions FPO =
13369 Result.getArrayInitializedElt(ArrayIndex) =
APValue(FValue);
13374 if (!Eval(
Init, ArrayIndex))
13380 if (!
Result.hasArrayFiller())
13385 assert(ArrayFiller &&
"no array filler for incomplete init list");
13391bool ArrayExprEvaluator::VisitArrayInitLoopExpr(
const ArrayInitLoopExpr *E) {
13394 !
Evaluate(Info.CurrentCall->createTemporary(
13397 ScopeKind::FullExpression, CommonLV),
13404 Result =
APValue(APValue::UninitArray(), Elements, Elements);
13406 LValue Subobject =
This;
13407 Subobject.addArray(Info, E, CAT);
13410 for (EvalInfo::ArrayInitLoopIndex Index(Info); Index != Elements; ++Index) {
13419 FullExpressionRAII Scope(Info);
13425 if (!Info.noteFailure())
13437bool ArrayExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E) {
13438 return VisitCXXConstructExpr(E, This, &
Result, E->
getType());
13441bool ArrayExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E,
13442 const LValue &Subobject,
13445 bool HadZeroInit =
Value->hasValue();
13452 HadZeroInit &&
Value->hasArrayFiller() ?
Value->getArrayFiller()
13455 *
Value =
APValue(APValue::UninitArray(), 0, FinalSize);
13456 if (FinalSize == 0)
13462 LValue ArrayElt = Subobject;
13463 ArrayElt.addArray(Info, E, CAT);
13469 for (
const unsigned N : {1u, FinalSize}) {
13470 unsigned OldElts =
Value->getArrayInitializedElts();
13475 APValue NewValue(APValue::UninitArray(), N, FinalSize);
13476 for (
unsigned I = 0; I < OldElts; ++I)
13477 NewValue.getArrayInitializedElt(I).swap(
13478 Value->getArrayInitializedElt(I));
13479 Value->swap(NewValue);
13482 for (
unsigned I = OldElts; I < N; ++I)
13483 Value->getArrayInitializedElt(I) = Filler;
13485 if (HasTrivialConstructor && N == FinalSize && FinalSize != 1) {
13488 APValue &FirstResult =
Value->getArrayInitializedElt(0);
13489 for (
unsigned I = OldElts; I < FinalSize; ++I)
13490 Value->getArrayInitializedElt(I) = FirstResult;
13492 for (
unsigned I = OldElts; I < N; ++I) {
13493 if (!VisitCXXConstructExpr(E, ArrayElt,
13494 &
Value->getArrayInitializedElt(I),
13501 if (Info.EvalStatus.
Diag && !Info.EvalStatus.
Diag->empty() &&
13502 !Info.keepEvaluatingAfterFailure())
13511 if (!
Type->isRecordType())
13514 return RecordExprEvaluator(Info, Subobject, *
Value)
13515 .VisitCXXConstructExpr(E,
Type);
13518bool ArrayExprEvaluator::VisitCXXParenListInitExpr(
13519 const CXXParenListInitExpr *E) {
13521 "Expression result is not a constant array type");
13523 return VisitCXXParenListOrInitListExpr(E, E->
getInitExprs(),
13536class IntExprEvaluator
13537 :
public ExprEvaluatorBase<IntExprEvaluator> {
13540 IntExprEvaluator(EvalInfo &info,
APValue &result)
13541 : ExprEvaluatorBaseTy(info),
Result(result) {}
13545 "Invalid evaluation result.");
13547 "Invalid evaluation result.");
13549 "Invalid evaluation result.");
13553 bool Success(
const llvm::APSInt &SI,
const Expr *E) {
13559 "Invalid evaluation result.");
13561 "Invalid evaluation result.");
13563 Result.getInt().setIsUnsigned(
13567 bool Success(
const llvm::APInt &I,
const Expr *E) {
13573 "Invalid evaluation result.");
13581 bool Success(CharUnits Size,
const Expr *E) {
13588 if (
V.isLValue() ||
V.isAddrLabelDiff() ||
V.isIndeterminate() ||
13589 V.allowConstexprUnknown()) {
13596 bool ZeroInitialization(
const Expr *E) {
return Success(0, E); }
13598 friend std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &,
13605 bool VisitIntegerLiteral(
const IntegerLiteral *E) {
13608 bool VisitCharacterLiteral(
const CharacterLiteral *E) {
13612 bool CheckReferencedDecl(
const Expr *E,
const Decl *D);
13613 bool VisitDeclRefExpr(
const DeclRefExpr *E) {
13614 if (CheckReferencedDecl(E, E->
getDecl()))
13617 return ExprEvaluatorBaseTy::VisitDeclRefExpr(E);
13619 bool VisitMemberExpr(
const MemberExpr *E) {
13621 VisitIgnoredBaseExpression(E->
getBase());
13625 return ExprEvaluatorBaseTy::VisitMemberExpr(E);
13628 bool VisitCallExpr(
const CallExpr *E);
13629 bool VisitBuiltinCallExpr(
const CallExpr *E,
unsigned BuiltinOp);
13630 bool VisitBinaryOperator(
const BinaryOperator *E);
13631 bool VisitOffsetOfExpr(
const OffsetOfExpr *E);
13632 bool VisitUnaryOperator(
const UnaryOperator *E);
13634 bool VisitCastExpr(
const CastExpr* E);
13635 bool VisitUnaryExprOrTypeTraitExpr(
const UnaryExprOrTypeTraitExpr *E);
13637 bool VisitCXXBoolLiteralExpr(
const CXXBoolLiteralExpr *E) {
13641 bool VisitObjCBoolLiteralExpr(
const ObjCBoolLiteralExpr *E) {
13645 bool VisitArrayInitIndexExpr(
const ArrayInitIndexExpr *E) {
13646 if (Info.ArrayInitIndex ==
uint64_t(-1)) {
13652 return Success(Info.ArrayInitIndex, E);
13656 bool VisitGNUNullExpr(
const GNUNullExpr *E) {
13657 return ZeroInitialization(E);
13660 bool VisitTypeTraitExpr(
const TypeTraitExpr *E) {
13669 bool VisitArrayTypeTraitExpr(
const ArrayTypeTraitExpr *E) {
13673 bool VisitExpressionTraitExpr(
const ExpressionTraitExpr *E) {
13677 bool VisitOpenACCAsteriskSizeExpr(
const OpenACCAsteriskSizeExpr *E) {
13684 bool VisitUnaryReal(
const UnaryOperator *E);
13685 bool VisitUnaryImag(
const UnaryOperator *E);
13687 bool VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E);
13688 bool VisitSizeOfPackExpr(
const SizeOfPackExpr *E);
13689 bool VisitSourceLocExpr(
const SourceLocExpr *E);
13690 bool VisitConceptSpecializationExpr(
const ConceptSpecializationExpr *E);
13695class FixedPointExprEvaluator
13696 :
public ExprEvaluatorBase<FixedPointExprEvaluator> {
13700 FixedPointExprEvaluator(EvalInfo &info,
APValue &result)
13701 : ExprEvaluatorBaseTy(info),
Result(result) {}
13703 bool Success(
const llvm::APInt &I,
const Expr *E) {
13714 return Success(
V.getFixedPoint(), E);
13717 bool Success(
const APFixedPoint &
V,
const Expr *E) {
13720 "Invalid evaluation result.");
13725 bool ZeroInitialization(
const Expr *E) {
13733 bool VisitFixedPointLiteral(
const FixedPointLiteral *E) {
13737 bool VisitCastExpr(
const CastExpr *E);
13738 bool VisitUnaryOperator(
const UnaryOperator *E);
13739 bool VisitBinaryOperator(
const BinaryOperator *E);
13755 return IntExprEvaluator(Info, Result).Visit(E);
13763 if (!Val.
isInt()) {
13766 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
13773bool IntExprEvaluator::VisitSourceLocExpr(
const SourceLocExpr *E) {
13775 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.
getDefaultExpr());
13784 if (!FixedPointExprEvaluator(Info, Val).Visit(E))
13803 Result = APFixedPoint(Val, FXSema);
13814bool IntExprEvaluator::CheckReferencedDecl(
const Expr* E,
const Decl* D) {
13816 if (
const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(D)) {
13818 bool SameSign = (ECD->getInitVal().isSigned()
13820 bool SameWidth = (ECD->getInitVal().
getBitWidth()
13822 if (SameSign && SameWidth)
13823 return Success(ECD->getInitVal(), E);
13827 llvm::APSInt Val = ECD->getInitVal();
13829 Val.setIsSigned(!ECD->getInitVal().isSigned());
13842 assert(!
T->isDependentType() &&
"unexpected dependent type");
13847#define TYPE(ID, BASE)
13848#define DEPENDENT_TYPE(ID, BASE) case Type::ID:
13849#define NON_CANONICAL_TYPE(ID, BASE) case Type::ID:
13850#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(ID, BASE) case Type::ID:
13851#include "clang/AST/TypeNodes.inc"
13853 case Type::DeducedTemplateSpecialization:
13854 llvm_unreachable(
"unexpected non-canonical or dependent type");
13856 case Type::Builtin:
13858#define BUILTIN_TYPE(ID, SINGLETON_ID)
13859#define SIGNED_TYPE(ID, SINGLETON_ID) \
13860 case BuiltinType::ID: return GCCTypeClass::Integer;
13861#define FLOATING_TYPE(ID, SINGLETON_ID) \
13862 case BuiltinType::ID: return GCCTypeClass::RealFloat;
13863#define PLACEHOLDER_TYPE(ID, SINGLETON_ID) \
13864 case BuiltinType::ID: break;
13865#include "clang/AST/BuiltinTypes.def"
13866 case BuiltinType::Void:
13869 case BuiltinType::Bool:
13872 case BuiltinType::Char_U:
13873 case BuiltinType::UChar:
13874 case BuiltinType::WChar_U:
13875 case BuiltinType::Char8:
13876 case BuiltinType::Char16:
13877 case BuiltinType::Char32:
13878 case BuiltinType::UShort:
13879 case BuiltinType::UInt:
13880 case BuiltinType::ULong:
13881 case BuiltinType::ULongLong:
13882 case BuiltinType::UInt128:
13885 case BuiltinType::UShortAccum:
13886 case BuiltinType::UAccum:
13887 case BuiltinType::ULongAccum:
13888 case BuiltinType::UShortFract:
13889 case BuiltinType::UFract:
13890 case BuiltinType::ULongFract:
13891 case BuiltinType::SatUShortAccum:
13892 case BuiltinType::SatUAccum:
13893 case BuiltinType::SatULongAccum:
13894 case BuiltinType::SatUShortFract:
13895 case BuiltinType::SatUFract:
13896 case BuiltinType::SatULongFract:
13899 case BuiltinType::NullPtr:
13901 case BuiltinType::ObjCId:
13902 case BuiltinType::ObjCClass:
13903 case BuiltinType::ObjCSel:
13904#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
13905 case BuiltinType::Id:
13906#include "clang/Basic/OpenCLImageTypes.def"
13907#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
13908 case BuiltinType::Id:
13909#include "clang/Basic/OpenCLExtensionTypes.def"
13910 case BuiltinType::OCLSampler:
13911 case BuiltinType::OCLEvent:
13912 case BuiltinType::OCLClkEvent:
13913 case BuiltinType::OCLQueue:
13914 case BuiltinType::OCLReserveID:
13915#define SVE_TYPE(Name, Id, SingletonId) \
13916 case BuiltinType::Id:
13917#include "clang/Basic/AArch64ACLETypes.def"
13918#define PPC_VECTOR_TYPE(Name, Id, Size) \
13919 case BuiltinType::Id:
13920#include "clang/Basic/PPCTypes.def"
13921#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
13922#include "clang/Basic/RISCVVTypes.def"
13923#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
13924#include "clang/Basic/WebAssemblyReferenceTypes.def"
13925#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
13926#include "clang/Basic/AMDGPUTypes.def"
13927#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
13928#include "clang/Basic/HLSLIntangibleTypes.def"
13931 case BuiltinType::Dependent:
13932 llvm_unreachable(
"unexpected dependent type");
13934 llvm_unreachable(
"unexpected placeholder type");
13939 case Type::Pointer:
13940 case Type::ConstantArray:
13941 case Type::VariableArray:
13942 case Type::IncompleteArray:
13943 case Type::FunctionNoProto:
13944 case Type::FunctionProto:
13945 case Type::ArrayParameter:
13948 case Type::MemberPointer:
13953 case Type::Complex:
13966 case Type::ExtVector:
13969 case Type::BlockPointer:
13970 case Type::ConstantMatrix:
13971 case Type::ObjCObject:
13972 case Type::ObjCInterface:
13973 case Type::ObjCObjectPointer:
13975 case Type::HLSLAttributedResource:
13976 case Type::HLSLInlineSpirv:
13984 case Type::LValueReference:
13985 case Type::RValueReference:
13986 llvm_unreachable(
"invalid type for expression");
13989 llvm_unreachable(
"unexpected type class");
14014 if (
Base.isNull()) {
14017 }
else if (
const Expr *E =
Base.dyn_cast<
const Expr *>()) {
14036 SpeculativeEvaluationRAII SpeculativeEval(Info);
14041 FoldConstant Fold(Info,
true);
14059 if (ArgType->isIntegralOrEnumerationType() || ArgType->isFloatingType() ||
14060 ArgType->isAnyComplexType() || ArgType->isPointerType() ||
14061 ArgType->isNullPtrType()) {
14064 Fold.keepDiagnostics();
14073 return V.hasValue();
14084 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
14108 const auto *Cast = dyn_cast<CastExpr>(NoParens);
14109 if (Cast ==
nullptr)
14114 auto CastKind = Cast->getCastKind();
14116 CastKind != CK_AddressSpaceConversion)
14119 const auto *SubExpr = Cast->getSubExpr();
14141 assert(!LVal.Designator.Invalid);
14143 auto IsLastOrInvalidFieldDecl = [&Ctx](
const FieldDecl *FD) {
14151 auto &
Base = LVal.getLValueBase();
14152 if (
auto *ME = dyn_cast_or_null<MemberExpr>(
Base.dyn_cast<
const Expr *>())) {
14153 if (
auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
14154 if (!IsLastOrInvalidFieldDecl(FD))
14156 }
else if (
auto *IFD = dyn_cast<IndirectFieldDecl>(ME->getMemberDecl())) {
14157 for (
auto *FD : IFD->chain()) {
14166 if (LVal.Designator.FirstEntryIsAnUnsizedArray) {
14170 if (BaseType->isIncompleteArrayType())
14176 for (
unsigned E = LVal.Designator.Entries.size(); I != E; ++I) {
14177 const auto &Entry = LVal.Designator.Entries[I];
14178 if (BaseType->isArrayType()) {
14184 uint64_t Index = Entry.getAsArrayIndex();
14188 }
else if (BaseType->isAnyComplexType()) {
14189 const auto *CT = BaseType->castAs<
ComplexType>();
14190 uint64_t Index = Entry.getAsArrayIndex();
14193 BaseType = CT->getElementType();
14194 }
else if (
auto *FD = getAsField(Entry)) {
14195 if (!IsLastOrInvalidFieldDecl(FD))
14199 assert(getAsBaseClass(Entry) &&
"Expecting cast to a base class");
14211 if (LVal.Designator.Invalid)
14214 if (!LVal.Designator.Entries.empty())
14215 return LVal.Designator.isMostDerivedAnUnsizedArray();
14217 if (!LVal.InvalidBase)
14229 const SubobjectDesignator &
Designator = LVal.Designator;
14241 auto isFlexibleArrayMember = [&] {
14243 FAMKind StrictFlexArraysLevel =
14246 if (
Designator.isMostDerivedAnUnsizedArray())
14249 if (StrictFlexArraysLevel == FAMKind::Default)
14252 if (
Designator.getMostDerivedArraySize() == 0 &&
14253 StrictFlexArraysLevel != FAMKind::IncompleteOnly)
14256 if (
Designator.getMostDerivedArraySize() == 1 &&
14257 StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete)
14263 return LVal.InvalidBase &&
14265 Designator.MostDerivedIsArrayElement && isFlexibleArrayMember() &&
14273 auto CharUnitsMax = std::numeric_limits<CharUnits::QuantityType>::max();
14274 if (Int.ugt(CharUnitsMax))
14284 if (!
T.isNull() &&
T->isStructureType() &&
14285 T->castAsRecordDecl()->hasFlexibleArrayMember())
14286 if (
const auto *
V = LV.getLValueBase().dyn_cast<
const ValueDecl *>())
14287 if (
const auto *VD = dyn_cast<VarDecl>(
V))
14299 unsigned Type,
const LValue &LVal,
14318 if (!(
Type & 1) || LVal.Designator.Invalid || DetermineForCompleteObject) {
14320 if (
Type == 3 && !DetermineForCompleteObject)
14323 llvm::APInt APEndOffset;
14324 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
14328 if (LVal.InvalidBase)
14332 const bool Ret = CheckedHandleSizeof(BaseTy, EndOffset);
14338 const SubobjectDesignator &
Designator = LVal.Designator;
14350 llvm::APInt APEndOffset;
14351 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
14363 if (!CheckedHandleSizeof(
Designator.MostDerivedType, BytesPerElem))
14369 int64_t ElemsRemaining;
14372 uint64_t ArraySize =
Designator.getMostDerivedArraySize();
14373 uint64_t ArrayIndex =
Designator.Entries.back().getAsArrayIndex();
14374 ElemsRemaining = ArraySize <= ArrayIndex ? 0 : ArraySize - ArrayIndex;
14376 ElemsRemaining =
Designator.isOnePastTheEnd() ? 0 : 1;
14379 EndOffset = LVal.getLValueOffset() + BytesPerElem * ElemsRemaining;
14389 EvalInfo &Info, uint64_t &Size) {
14396 SpeculativeEvaluationRAII SpeculativeEval(Info);
14397 IgnoreSideEffectsRAII Fold(Info);
14405 LVal.setFrom(Info.Ctx, RVal);
14413 if (LVal.getLValueOffset().isNegative()) {
14424 if (EndOffset <= LVal.getLValueOffset())
14427 Size = (EndOffset - LVal.getLValueOffset()).getQuantity();
14431bool IntExprEvaluator::VisitCallExpr(
const CallExpr *E) {
14432 if (!IsConstantEvaluatedBuiltinCall(E))
14433 return ExprEvaluatorBaseTy::VisitCallExpr(E);
14450 Info.FFDiag(E->
getArg(0));
14456 assert(SrcInt.getBitWidth() >= Alignment.getBitWidth() &&
14457 "Bit widths must be the same");
14464bool IntExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *E,
14465 unsigned BuiltinOp) {
14466 auto EvalTestOp = [&](llvm::function_ref<
bool(
const APInt &,
const APInt &)>
14468 APValue SourceLHS, SourceRHS;
14476 unsigned LaneWidth = Info.Ctx.
getTypeSize(ElemQT);
14478 APInt AWide(LaneWidth * SourceLen, 0);
14479 APInt BWide(LaneWidth * SourceLen, 0);
14481 for (
unsigned I = 0; I != SourceLen; ++I) {
14484 if (ElemQT->isIntegerType()) {
14487 }
else if (ElemQT->isFloatingType()) {
14495 AWide.insertBits(ALane, I * LaneWidth);
14496 BWide.insertBits(BLane, I * LaneWidth);
14501 auto HandleMaskBinOp =
14514 switch (BuiltinOp) {
14518 case Builtin::BI__builtin_dynamic_object_size:
14519 case Builtin::BI__builtin_object_size: {
14523 assert(
Type <= 3 &&
"unexpected type");
14534 switch (Info.EvalMode) {
14535 case EvaluationMode::ConstantExpression:
14536 case EvaluationMode::ConstantFold:
14537 case EvaluationMode::IgnoreSideEffects:
14540 case EvaluationMode::ConstantExpressionUnevaluated:
14545 llvm_unreachable(
"unexpected EvalMode");
14548 case Builtin::BI__builtin_os_log_format_buffer_size: {
14549 analyze_os_log::OSLogBufferLayout Layout;
14554 case Builtin::BI__builtin_is_aligned: {
14562 Ptr.setFrom(Info.Ctx, Src);
14568 assert(Alignment.isPowerOf2());
14581 Info.FFDiag(E->
getArg(0), diag::note_constexpr_alignment_compute)
14585 assert(Src.
isInt());
14586 return Success((Src.
getInt() & (Alignment - 1)) == 0 ? 1 : 0, E);
14588 case Builtin::BI__builtin_align_up: {
14596 APSInt((Src.
getInt() + (Alignment - 1)) & ~(Alignment - 1),
14597 Src.
getInt().isUnsigned());
14598 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
14599 return Success(AlignedVal, E);
14601 case Builtin::BI__builtin_align_down: {
14610 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
14611 return Success(AlignedVal, E);
14614 case Builtin::BI__builtin_bitreverse8:
14615 case Builtin::BI__builtin_bitreverse16:
14616 case Builtin::BI__builtin_bitreverse32:
14617 case Builtin::BI__builtin_bitreverse64:
14618 case Builtin::BI__builtin_elementwise_bitreverse: {
14623 return Success(Val.reverseBits(), E);
14626 case Builtin::BI__builtin_bswap16:
14627 case Builtin::BI__builtin_bswap32:
14628 case Builtin::BI__builtin_bswap64: {
14633 return Success(Val.byteSwap(), E);
14636 case Builtin::BI__builtin_classify_type:
14639 case Builtin::BI__builtin_clrsb:
14640 case Builtin::BI__builtin_clrsbl:
14641 case Builtin::BI__builtin_clrsbll: {
14646 return Success(Val.getBitWidth() - Val.getSignificantBits(), E);
14649 case Builtin::BI__builtin_clz:
14650 case Builtin::BI__builtin_clzl:
14651 case Builtin::BI__builtin_clzll:
14652 case Builtin::BI__builtin_clzs:
14653 case Builtin::BI__builtin_clzg:
14654 case Builtin::BI__builtin_elementwise_clzg:
14655 case Builtin::BI__lzcnt16:
14656 case Builtin::BI__lzcnt:
14657 case Builtin::BI__lzcnt64: {
14668 std::optional<APSInt> Fallback;
14669 if ((BuiltinOp == Builtin::BI__builtin_clzg ||
14670 BuiltinOp == Builtin::BI__builtin_elementwise_clzg) &&
14675 Fallback = FallbackTemp;
14680 return Success(*Fallback, E);
14685 bool ZeroIsUndefined = BuiltinOp != Builtin::BI__lzcnt16 &&
14686 BuiltinOp != Builtin::BI__lzcnt &&
14687 BuiltinOp != Builtin::BI__lzcnt64;
14689 if (BuiltinOp == Builtin::BI__builtin_elementwise_clzg) {
14690 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
14694 if (ZeroIsUndefined)
14698 return Success(Val.countl_zero(), E);
14701 case Builtin::BI__builtin_constant_p: {
14702 const Expr *Arg = E->
getArg(0);
14711 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
14715 case Builtin::BI__noop:
14719 case Builtin::BI__builtin_is_constant_evaluated: {
14720 const auto *
Callee = Info.CurrentCall->getCallee();
14721 if (Info.InConstantContext && !Info.CheckingPotentialConstantExpression &&
14722 (Info.CallStackDepth == 1 ||
14723 (Info.CallStackDepth == 2 &&
Callee->isInStdNamespace() &&
14724 Callee->getIdentifier() &&
14725 Callee->getIdentifier()->isStr(
"is_constant_evaluated")))) {
14727 if (Info.EvalStatus.
Diag)
14728 Info.report((Info.CallStackDepth == 1)
14730 : Info.CurrentCall->getCallRange().getBegin(),
14731 diag::warn_is_constant_evaluated_always_true_constexpr)
14732 << (Info.CallStackDepth == 1 ?
"__builtin_is_constant_evaluated"
14733 :
"std::is_constant_evaluated");
14736 return Success(Info.InConstantContext, E);
14739 case Builtin::BI__builtin_is_within_lifetime:
14740 if (
auto result = EvaluateBuiltinIsWithinLifetime(*
this, E))
14744 case Builtin::BI__builtin_ctz:
14745 case Builtin::BI__builtin_ctzl:
14746 case Builtin::BI__builtin_ctzll:
14747 case Builtin::BI__builtin_ctzs:
14748 case Builtin::BI__builtin_ctzg:
14749 case Builtin::BI__builtin_elementwise_ctzg: {
14760 std::optional<APSInt> Fallback;
14761 if ((BuiltinOp == Builtin::BI__builtin_ctzg ||
14762 BuiltinOp == Builtin::BI__builtin_elementwise_ctzg) &&
14767 Fallback = FallbackTemp;
14772 return Success(*Fallback, E);
14774 if (BuiltinOp == Builtin::BI__builtin_elementwise_ctzg) {
14775 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
14781 return Success(Val.countr_zero(), E);
14784 case Builtin::BI__builtin_eh_return_data_regno: {
14790 case Builtin::BI__builtin_elementwise_abs: {
14795 return Success(Val.abs(), E);
14798 case Builtin::BI__builtin_expect:
14799 case Builtin::BI__builtin_expect_with_probability:
14800 return Visit(E->
getArg(0));
14802 case Builtin::BI__builtin_ptrauth_string_discriminator: {
14809 case Builtin::BI__builtin_infer_alloc_token: {
14815 E, diag::note_constexpr_infer_alloc_token_type_inference_failed);
14818 return Error(E, diag::note_constexpr_infer_alloc_token_no_metadata);
14820 Info.getLangOpts().AllocTokenMode.value_or(llvm::DefaultAllocTokenMode);
14823 Info.getLangOpts().AllocTokenMax.value_or(~0ULL >> (64 - BitWidth));
14824 auto MaybeToken = llvm::getAllocToken(Mode, *ATMD, MaxTokens);
14826 return Error(E, diag::note_constexpr_infer_alloc_token_stateful_mode);
14827 return Success(llvm::APInt(BitWidth, *MaybeToken), E);
14830 case Builtin::BI__builtin_ffs:
14831 case Builtin::BI__builtin_ffsl:
14832 case Builtin::BI__builtin_ffsll: {
14837 unsigned N = Val.countr_zero();
14838 return Success(N == Val.getBitWidth() ? 0 : N + 1, E);
14841 case Builtin::BI__builtin_fpclassify: {
14846 switch (Val.getCategory()) {
14847 case APFloat::fcNaN: Arg = 0;
break;
14848 case APFloat::fcInfinity: Arg = 1;
break;
14849 case APFloat::fcNormal: Arg = Val.isDenormal() ? 3 : 2;
break;
14850 case APFloat::fcZero: Arg = 4;
break;
14852 return Visit(E->
getArg(Arg));
14855 case Builtin::BI__builtin_isinf_sign: {
14858 Success(Val.isInfinity() ? (Val.isNegative() ? -1 : 1) : 0, E);
14861 case Builtin::BI__builtin_isinf: {
14864 Success(Val.isInfinity() ? 1 : 0, E);
14867 case Builtin::BI__builtin_isfinite: {
14870 Success(Val.isFinite() ? 1 : 0, E);
14873 case Builtin::BI__builtin_isnan: {
14876 Success(Val.isNaN() ? 1 : 0, E);
14879 case Builtin::BI__builtin_isnormal: {
14882 Success(Val.isNormal() ? 1 : 0, E);
14885 case Builtin::BI__builtin_issubnormal: {
14888 Success(Val.isDenormal() ? 1 : 0, E);
14891 case Builtin::BI__builtin_iszero: {
14894 Success(Val.isZero() ? 1 : 0, E);
14897 case Builtin::BI__builtin_signbit:
14898 case Builtin::BI__builtin_signbitf:
14899 case Builtin::BI__builtin_signbitl: {
14902 Success(Val.isNegative() ? 1 : 0, E);
14905 case Builtin::BI__builtin_isgreater:
14906 case Builtin::BI__builtin_isgreaterequal:
14907 case Builtin::BI__builtin_isless:
14908 case Builtin::BI__builtin_islessequal:
14909 case Builtin::BI__builtin_islessgreater:
14910 case Builtin::BI__builtin_isunordered: {
14919 switch (BuiltinOp) {
14920 case Builtin::BI__builtin_isgreater:
14922 case Builtin::BI__builtin_isgreaterequal:
14924 case Builtin::BI__builtin_isless:
14926 case Builtin::BI__builtin_islessequal:
14928 case Builtin::BI__builtin_islessgreater: {
14929 APFloat::cmpResult cmp = LHS.compare(RHS);
14930 return cmp == APFloat::cmpResult::cmpLessThan ||
14931 cmp == APFloat::cmpResult::cmpGreaterThan;
14933 case Builtin::BI__builtin_isunordered:
14934 return LHS.compare(RHS) == APFloat::cmpResult::cmpUnordered;
14936 llvm_unreachable(
"Unexpected builtin ID: Should be a floating "
14937 "point comparison function");
14945 case Builtin::BI__builtin_issignaling: {
14948 Success(Val.isSignaling() ? 1 : 0, E);
14951 case Builtin::BI__builtin_isfpclass: {
14955 unsigned Test =
static_cast<llvm::FPClassTest
>(MaskVal.getZExtValue());
14958 Success((Val.classify() & Test) ? 1 : 0, E);
14961 case Builtin::BI__builtin_parity:
14962 case Builtin::BI__builtin_parityl:
14963 case Builtin::BI__builtin_parityll: {
14968 return Success(Val.popcount() % 2, E);
14971 case Builtin::BI__builtin_abs:
14972 case Builtin::BI__builtin_labs:
14973 case Builtin::BI__builtin_llabs: {
14977 if (Val ==
APSInt(APInt::getSignedMinValue(Val.getBitWidth()),
14980 if (Val.isNegative())
14985 case Builtin::BI__builtin_popcount:
14986 case Builtin::BI__builtin_popcountl:
14987 case Builtin::BI__builtin_popcountll:
14988 case Builtin::BI__builtin_popcountg:
14989 case Builtin::BI__builtin_elementwise_popcount:
14990 case Builtin::BI__popcnt16:
14991 case Builtin::BI__popcnt:
14992 case Builtin::BI__popcnt64: {
15003 return Success(Val.popcount(), E);
15006 case Builtin::BI__builtin_rotateleft8:
15007 case Builtin::BI__builtin_rotateleft16:
15008 case Builtin::BI__builtin_rotateleft32:
15009 case Builtin::BI__builtin_rotateleft64:
15010 case Builtin::BI_rotl8:
15011 case Builtin::BI_rotl16:
15012 case Builtin::BI_rotl:
15013 case Builtin::BI_lrotl:
15014 case Builtin::BI_rotl64: {
15020 return Success(Val.rotl(Amt), E);
15023 case Builtin::BI__builtin_rotateright8:
15024 case Builtin::BI__builtin_rotateright16:
15025 case Builtin::BI__builtin_rotateright32:
15026 case Builtin::BI__builtin_rotateright64:
15027 case Builtin::BI_rotr8:
15028 case Builtin::BI_rotr16:
15029 case Builtin::BI_rotr:
15030 case Builtin::BI_lrotr:
15031 case Builtin::BI_rotr64: {
15037 return Success(Val.rotr(Amt), E);
15040 case Builtin::BI__builtin_elementwise_add_sat: {
15046 APInt Result = LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS);
15049 case Builtin::BI__builtin_elementwise_sub_sat: {
15055 APInt Result = LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
15058 case Builtin::BI__builtin_elementwise_max: {
15067 case Builtin::BI__builtin_elementwise_min: {
15076 case Builtin::BI__builtin_elementwise_fshl:
15077 case Builtin::BI__builtin_elementwise_fshr: {
15084 switch (BuiltinOp) {
15085 case Builtin::BI__builtin_elementwise_fshl: {
15086 APSInt Result(llvm::APIntOps::fshl(Hi, Lo, Shift), Hi.isUnsigned());
15089 case Builtin::BI__builtin_elementwise_fshr: {
15090 APSInt Result(llvm::APIntOps::fshr(Hi, Lo, Shift), Hi.isUnsigned());
15094 llvm_unreachable(
"Fully covered switch above");
15096 case Builtin::BIstrlen:
15097 case Builtin::BIwcslen:
15099 if (Info.getLangOpts().CPlusPlus11)
15100 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
15104 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
15106 case Builtin::BI__builtin_strlen:
15107 case Builtin::BI__builtin_wcslen: {
15116 case Builtin::BIstrcmp:
15117 case Builtin::BIwcscmp:
15118 case Builtin::BIstrncmp:
15119 case Builtin::BIwcsncmp:
15120 case Builtin::BImemcmp:
15121 case Builtin::BIbcmp:
15122 case Builtin::BIwmemcmp:
15124 if (Info.getLangOpts().CPlusPlus11)
15125 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
15129 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
15131 case Builtin::BI__builtin_strcmp:
15132 case Builtin::BI__builtin_wcscmp:
15133 case Builtin::BI__builtin_strncmp:
15134 case Builtin::BI__builtin_wcsncmp:
15135 case Builtin::BI__builtin_memcmp:
15136 case Builtin::BI__builtin_bcmp:
15137 case Builtin::BI__builtin_wmemcmp: {
15138 LValue String1, String2;
15144 if (BuiltinOp != Builtin::BIstrcmp &&
15145 BuiltinOp != Builtin::BIwcscmp &&
15146 BuiltinOp != Builtin::BI__builtin_strcmp &&
15147 BuiltinOp != Builtin::BI__builtin_wcscmp) {
15151 MaxLength = N.getZExtValue();
15155 if (MaxLength == 0u)
15158 if (!String1.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
15159 !String2.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
15160 String1.Designator.Invalid || String2.Designator.Invalid)
15163 QualType CharTy1 = String1.Designator.getType(Info.Ctx);
15164 QualType CharTy2 = String2.Designator.getType(Info.Ctx);
15166 bool IsRawByte = BuiltinOp == Builtin::BImemcmp ||
15167 BuiltinOp == Builtin::BIbcmp ||
15168 BuiltinOp == Builtin::BI__builtin_memcmp ||
15169 BuiltinOp == Builtin::BI__builtin_bcmp;
15171 assert(IsRawByte ||
15181 Info.FFDiag(E, diag::note_constexpr_memcmp_unsupported)
15187 const auto &ReadCurElems = [&](
APValue &Char1,
APValue &Char2) {
15190 Char1.
isInt() && Char2.isInt();
15192 const auto &AdvanceElems = [&] {
15198 (BuiltinOp != Builtin::BImemcmp && BuiltinOp != Builtin::BIbcmp &&
15199 BuiltinOp != Builtin::BIwmemcmp &&
15200 BuiltinOp != Builtin::BI__builtin_memcmp &&
15201 BuiltinOp != Builtin::BI__builtin_bcmp &&
15202 BuiltinOp != Builtin::BI__builtin_wmemcmp);
15203 bool IsWide = BuiltinOp == Builtin::BIwcscmp ||
15204 BuiltinOp == Builtin::BIwcsncmp ||
15205 BuiltinOp == Builtin::BIwmemcmp ||
15206 BuiltinOp == Builtin::BI__builtin_wcscmp ||
15207 BuiltinOp == Builtin::BI__builtin_wcsncmp ||
15208 BuiltinOp == Builtin::BI__builtin_wmemcmp;
15210 for (; MaxLength; --MaxLength) {
15212 if (!ReadCurElems(Char1, Char2))
15220 if (StopAtNull && !Char1.
getInt())
15222 assert(!(StopAtNull && !Char2.
getInt()));
15223 if (!AdvanceElems())
15230 case Builtin::BI__atomic_always_lock_free:
15231 case Builtin::BI__atomic_is_lock_free:
15232 case Builtin::BI__c11_atomic_is_lock_free: {
15248 if (
Size.isPowerOfTwo()) {
15250 unsigned InlineWidthBits =
15253 if (BuiltinOp == Builtin::BI__c11_atomic_is_lock_free ||
15259 const Expr *PtrArg = E->
getArg(1);
15265 IntResult.isAligned(
Size.getAsAlign()))
15269 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(PtrArg)) {
15272 if (ICE->getCastKind() == CK_BitCast)
15273 PtrArg = ICE->getSubExpr();
15276 if (
auto PtrTy = PtrArg->
getType()->
getAs<PointerType>()) {
15287 return BuiltinOp == Builtin::BI__atomic_always_lock_free ?
15290 case Builtin::BI__builtin_addcb:
15291 case Builtin::BI__builtin_addcs:
15292 case Builtin::BI__builtin_addc:
15293 case Builtin::BI__builtin_addcl:
15294 case Builtin::BI__builtin_addcll:
15295 case Builtin::BI__builtin_subcb:
15296 case Builtin::BI__builtin_subcs:
15297 case Builtin::BI__builtin_subc:
15298 case Builtin::BI__builtin_subcl:
15299 case Builtin::BI__builtin_subcll: {
15300 LValue CarryOutLValue;
15312 bool FirstOverflowed =
false;
15313 bool SecondOverflowed =
false;
15314 switch (BuiltinOp) {
15316 llvm_unreachable(
"Invalid value for BuiltinOp");
15317 case Builtin::BI__builtin_addcb:
15318 case Builtin::BI__builtin_addcs:
15319 case Builtin::BI__builtin_addc:
15320 case Builtin::BI__builtin_addcl:
15321 case Builtin::BI__builtin_addcll:
15323 LHS.uadd_ov(RHS, FirstOverflowed).uadd_ov(CarryIn, SecondOverflowed);
15325 case Builtin::BI__builtin_subcb:
15326 case Builtin::BI__builtin_subcs:
15327 case Builtin::BI__builtin_subc:
15328 case Builtin::BI__builtin_subcl:
15329 case Builtin::BI__builtin_subcll:
15331 LHS.usub_ov(RHS, FirstOverflowed).usub_ov(CarryIn, SecondOverflowed);
15337 CarryOut = (
uint64_t)(FirstOverflowed | SecondOverflowed);
15343 case Builtin::BI__builtin_add_overflow:
15344 case Builtin::BI__builtin_sub_overflow:
15345 case Builtin::BI__builtin_mul_overflow:
15346 case Builtin::BI__builtin_sadd_overflow:
15347 case Builtin::BI__builtin_uadd_overflow:
15348 case Builtin::BI__builtin_uaddl_overflow:
15349 case Builtin::BI__builtin_uaddll_overflow:
15350 case Builtin::BI__builtin_usub_overflow:
15351 case Builtin::BI__builtin_usubl_overflow:
15352 case Builtin::BI__builtin_usubll_overflow:
15353 case Builtin::BI__builtin_umul_overflow:
15354 case Builtin::BI__builtin_umull_overflow:
15355 case Builtin::BI__builtin_umulll_overflow:
15356 case Builtin::BI__builtin_saddl_overflow:
15357 case Builtin::BI__builtin_saddll_overflow:
15358 case Builtin::BI__builtin_ssub_overflow:
15359 case Builtin::BI__builtin_ssubl_overflow:
15360 case Builtin::BI__builtin_ssubll_overflow:
15361 case Builtin::BI__builtin_smul_overflow:
15362 case Builtin::BI__builtin_smull_overflow:
15363 case Builtin::BI__builtin_smulll_overflow: {
15364 LValue ResultLValue;
15374 bool DidOverflow =
false;
15377 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
15378 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
15379 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
15380 bool IsSigned = LHS.isSigned() || RHS.isSigned() ||
15382 bool AllSigned = LHS.isSigned() && RHS.isSigned() &&
15384 uint64_t LHSSize = LHS.getBitWidth();
15385 uint64_t RHSSize = RHS.getBitWidth();
15387 uint64_t MaxBits = std::max(std::max(LHSSize, RHSSize), ResultSize);
15393 if (IsSigned && !AllSigned)
15396 LHS =
APSInt(LHS.extOrTrunc(MaxBits), !IsSigned);
15397 RHS =
APSInt(RHS.extOrTrunc(MaxBits), !IsSigned);
15402 switch (BuiltinOp) {
15404 llvm_unreachable(
"Invalid value for BuiltinOp");
15405 case Builtin::BI__builtin_add_overflow:
15406 case Builtin::BI__builtin_sadd_overflow:
15407 case Builtin::BI__builtin_saddl_overflow:
15408 case Builtin::BI__builtin_saddll_overflow:
15409 case Builtin::BI__builtin_uadd_overflow:
15410 case Builtin::BI__builtin_uaddl_overflow:
15411 case Builtin::BI__builtin_uaddll_overflow:
15412 Result = LHS.isSigned() ? LHS.sadd_ov(RHS, DidOverflow)
15413 : LHS.uadd_ov(RHS, DidOverflow);
15415 case Builtin::BI__builtin_sub_overflow:
15416 case Builtin::BI__builtin_ssub_overflow:
15417 case Builtin::BI__builtin_ssubl_overflow:
15418 case Builtin::BI__builtin_ssubll_overflow:
15419 case Builtin::BI__builtin_usub_overflow:
15420 case Builtin::BI__builtin_usubl_overflow:
15421 case Builtin::BI__builtin_usubll_overflow:
15422 Result = LHS.isSigned() ? LHS.ssub_ov(RHS, DidOverflow)
15423 : LHS.usub_ov(RHS, DidOverflow);
15425 case Builtin::BI__builtin_mul_overflow:
15426 case Builtin::BI__builtin_smul_overflow:
15427 case Builtin::BI__builtin_smull_overflow:
15428 case Builtin::BI__builtin_smulll_overflow:
15429 case Builtin::BI__builtin_umul_overflow:
15430 case Builtin::BI__builtin_umull_overflow:
15431 case Builtin::BI__builtin_umulll_overflow:
15432 Result = LHS.isSigned() ? LHS.smul_ov(RHS, DidOverflow)
15433 : LHS.umul_ov(RHS, DidOverflow);
15439 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
15440 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
15441 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
15450 if (!APSInt::isSameValue(Temp,
Result))
15451 DidOverflow =
true;
15458 return Success(DidOverflow, E);
15461 case Builtin::BI__builtin_reduce_add:
15462 case Builtin::BI__builtin_reduce_mul:
15463 case Builtin::BI__builtin_reduce_and:
15464 case Builtin::BI__builtin_reduce_or:
15465 case Builtin::BI__builtin_reduce_xor:
15466 case Builtin::BI__builtin_reduce_min:
15467 case Builtin::BI__builtin_reduce_max: {
15474 for (
unsigned EltNum = 1; EltNum < SourceLen; ++EltNum) {
15475 switch (BuiltinOp) {
15478 case Builtin::BI__builtin_reduce_add: {
15481 Reduced.getBitWidth() + 1, std::plus<APSInt>(), Reduced))
15485 case Builtin::BI__builtin_reduce_mul: {
15488 Reduced.getBitWidth() * 2, std::multiplies<APSInt>(), Reduced))
15492 case Builtin::BI__builtin_reduce_and: {
15496 case Builtin::BI__builtin_reduce_or: {
15500 case Builtin::BI__builtin_reduce_xor: {
15504 case Builtin::BI__builtin_reduce_min: {
15508 case Builtin::BI__builtin_reduce_max: {
15518 case clang::X86::BI__builtin_ia32_addcarryx_u32:
15519 case clang::X86::BI__builtin_ia32_addcarryx_u64:
15520 case clang::X86::BI__builtin_ia32_subborrow_u32:
15521 case clang::X86::BI__builtin_ia32_subborrow_u64: {
15522 LValue ResultLValue;
15523 APSInt CarryIn, LHS, RHS;
15531 bool IsAdd = BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u32 ||
15532 BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u64;
15534 unsigned BitWidth = LHS.getBitWidth();
15535 unsigned CarryInBit = CarryIn.ugt(0) ? 1 : 0;
15538 ? (LHS.zext(BitWidth + 1) + (RHS.zext(BitWidth + 1) + CarryInBit))
15539 : (LHS.zext(BitWidth + 1) - (RHS.zext(BitWidth + 1) + CarryInBit));
15541 APInt Result = ExResult.extractBits(BitWidth, 0);
15542 uint64_t CarryOut = ExResult.extractBitsAsZExtValue(1, BitWidth);
15550 case clang::X86::BI__builtin_ia32_movmskps:
15551 case clang::X86::BI__builtin_ia32_movmskpd:
15552 case clang::X86::BI__builtin_ia32_pmovmskb128:
15553 case clang::X86::BI__builtin_ia32_pmovmskb256:
15554 case clang::X86::BI__builtin_ia32_movmskps256:
15555 case clang::X86::BI__builtin_ia32_movmskpd256: {
15566 for (
unsigned I = 0; I != SourceLen; ++I) {
15568 if (ElemQT->isIntegerType()) {
15570 }
else if (ElemQT->isRealFloatingType()) {
15575 Result.setBitVal(I, Elem.isNegative());
15580 case clang::X86::BI__builtin_ia32_bextr_u32:
15581 case clang::X86::BI__builtin_ia32_bextr_u64:
15582 case clang::X86::BI__builtin_ia32_bextri_u32:
15583 case clang::X86::BI__builtin_ia32_bextri_u64: {
15589 unsigned BitWidth = Val.getBitWidth();
15591 uint64_t Length = Idx.extractBitsAsZExtValue(8, 8);
15592 Length = Length > BitWidth ? BitWidth : Length;
15595 if (Length == 0 || Shift >= BitWidth)
15599 Result &= llvm::maskTrailingOnes<uint64_t>(Length);
15603 case clang::X86::BI__builtin_ia32_bzhi_si:
15604 case clang::X86::BI__builtin_ia32_bzhi_di: {
15610 unsigned BitWidth = Val.getBitWidth();
15611 unsigned Index = Idx.extractBitsAsZExtValue(8, 0);
15612 if (Index < BitWidth)
15613 Val.clearHighBits(BitWidth - Index);
15617 case clang::X86::BI__builtin_ia32_lzcnt_u16:
15618 case clang::X86::BI__builtin_ia32_lzcnt_u32:
15619 case clang::X86::BI__builtin_ia32_lzcnt_u64: {
15623 return Success(Val.countLeadingZeros(), E);
15626 case clang::X86::BI__builtin_ia32_tzcnt_u16:
15627 case clang::X86::BI__builtin_ia32_tzcnt_u32:
15628 case clang::X86::BI__builtin_ia32_tzcnt_u64: {
15632 return Success(Val.countTrailingZeros(), E);
15635 case clang::X86::BI__builtin_ia32_pdep_si:
15636 case clang::X86::BI__builtin_ia32_pdep_di: {
15642 unsigned BitWidth = Val.getBitWidth();
15644 for (
unsigned I = 0, P = 0; I != BitWidth; ++I)
15646 Result.setBitVal(I, Val[P++]);
15650 case clang::X86::BI__builtin_ia32_pext_si:
15651 case clang::X86::BI__builtin_ia32_pext_di: {
15657 unsigned BitWidth = Val.getBitWidth();
15659 for (
unsigned I = 0, P = 0; I != BitWidth; ++I)
15661 Result.setBitVal(P++, Val[I]);
15664 case X86::BI__builtin_ia32_ptestz128:
15665 case X86::BI__builtin_ia32_ptestz256:
15666 case X86::BI__builtin_ia32_vtestzps:
15667 case X86::BI__builtin_ia32_vtestzps256:
15668 case X86::BI__builtin_ia32_vtestzpd:
15669 case X86::BI__builtin_ia32_vtestzpd256: {
15671 [](
const APInt &A,
const APInt &B) {
return (A & B) == 0; });
15673 case X86::BI__builtin_ia32_ptestc128:
15674 case X86::BI__builtin_ia32_ptestc256:
15675 case X86::BI__builtin_ia32_vtestcps:
15676 case X86::BI__builtin_ia32_vtestcps256:
15677 case X86::BI__builtin_ia32_vtestcpd:
15678 case X86::BI__builtin_ia32_vtestcpd256: {
15680 [](
const APInt &A,
const APInt &B) {
return (~A & B) == 0; });
15682 case X86::BI__builtin_ia32_ptestnzc128:
15683 case X86::BI__builtin_ia32_ptestnzc256:
15684 case X86::BI__builtin_ia32_vtestnzcps:
15685 case X86::BI__builtin_ia32_vtestnzcps256:
15686 case X86::BI__builtin_ia32_vtestnzcpd:
15687 case X86::BI__builtin_ia32_vtestnzcpd256: {
15688 return EvalTestOp([](
const APInt &A,
const APInt &B) {
15689 return ((A & B) != 0) && ((~A & B) != 0);
15692 case X86::BI__builtin_ia32_kandqi:
15693 case X86::BI__builtin_ia32_kandhi:
15694 case X86::BI__builtin_ia32_kandsi:
15695 case X86::BI__builtin_ia32_kanddi: {
15696 return HandleMaskBinOp(
15697 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS & RHS; });
15700 case X86::BI__builtin_ia32_kandnqi:
15701 case X86::BI__builtin_ia32_kandnhi:
15702 case X86::BI__builtin_ia32_kandnsi:
15703 case X86::BI__builtin_ia32_kandndi: {
15704 return HandleMaskBinOp(
15705 [](
const APSInt &LHS,
const APSInt &RHS) {
return ~LHS & RHS; });
15708 case X86::BI__builtin_ia32_korqi:
15709 case X86::BI__builtin_ia32_korhi:
15710 case X86::BI__builtin_ia32_korsi:
15711 case X86::BI__builtin_ia32_kordi: {
15712 return HandleMaskBinOp(
15713 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS | RHS; });
15716 case X86::BI__builtin_ia32_kxnorqi:
15717 case X86::BI__builtin_ia32_kxnorhi:
15718 case X86::BI__builtin_ia32_kxnorsi:
15719 case X86::BI__builtin_ia32_kxnordi: {
15720 return HandleMaskBinOp(
15721 [](
const APSInt &LHS,
const APSInt &RHS) {
return ~(LHS ^ RHS); });
15724 case X86::BI__builtin_ia32_kxorqi:
15725 case X86::BI__builtin_ia32_kxorhi:
15726 case X86::BI__builtin_ia32_kxorsi:
15727 case X86::BI__builtin_ia32_kxordi: {
15728 return HandleMaskBinOp(
15729 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS ^ RHS; });
15732 case X86::BI__builtin_ia32_knotqi:
15733 case X86::BI__builtin_ia32_knothi:
15734 case X86::BI__builtin_ia32_knotsi:
15735 case X86::BI__builtin_ia32_knotdi: {
15743 case X86::BI__builtin_ia32_kaddqi:
15744 case X86::BI__builtin_ia32_kaddhi:
15745 case X86::BI__builtin_ia32_kaddsi:
15746 case X86::BI__builtin_ia32_kadddi: {
15747 return HandleMaskBinOp(
15748 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS + RHS; });
15751 case clang::X86::BI__builtin_ia32_vec_ext_v4hi:
15752 case clang::X86::BI__builtin_ia32_vec_ext_v16qi:
15753 case clang::X86::BI__builtin_ia32_vec_ext_v8hi:
15754 case clang::X86::BI__builtin_ia32_vec_ext_v4si:
15755 case clang::X86::BI__builtin_ia32_vec_ext_v2di:
15756 case clang::X86::BI__builtin_ia32_vec_ext_v32qi:
15757 case clang::X86::BI__builtin_ia32_vec_ext_v16hi:
15758 case clang::X86::BI__builtin_ia32_vec_ext_v8si:
15759 case clang::X86::BI__builtin_ia32_vec_ext_v4di: {
15766 unsigned Idx =
static_cast<unsigned>(IdxAPS.getZExtValue() & (N - 1));
15770 case clang::X86::BI__builtin_ia32_cmpb128_mask:
15771 case clang::X86::BI__builtin_ia32_cmpw128_mask:
15772 case clang::X86::BI__builtin_ia32_cmpd128_mask:
15773 case clang::X86::BI__builtin_ia32_cmpq128_mask:
15774 case clang::X86::BI__builtin_ia32_cmpb256_mask:
15775 case clang::X86::BI__builtin_ia32_cmpw256_mask:
15776 case clang::X86::BI__builtin_ia32_cmpd256_mask:
15777 case clang::X86::BI__builtin_ia32_cmpq256_mask:
15778 case clang::X86::BI__builtin_ia32_cmpb512_mask:
15779 case clang::X86::BI__builtin_ia32_cmpw512_mask:
15780 case clang::X86::BI__builtin_ia32_cmpd512_mask:
15781 case clang::X86::BI__builtin_ia32_cmpq512_mask:
15782 case clang::X86::BI__builtin_ia32_ucmpb128_mask:
15783 case clang::X86::BI__builtin_ia32_ucmpw128_mask:
15784 case clang::X86::BI__builtin_ia32_ucmpd128_mask:
15785 case clang::X86::BI__builtin_ia32_ucmpq128_mask:
15786 case clang::X86::BI__builtin_ia32_ucmpb256_mask:
15787 case clang::X86::BI__builtin_ia32_ucmpw256_mask:
15788 case clang::X86::BI__builtin_ia32_ucmpd256_mask:
15789 case clang::X86::BI__builtin_ia32_ucmpq256_mask:
15790 case clang::X86::BI__builtin_ia32_ucmpb512_mask:
15791 case clang::X86::BI__builtin_ia32_ucmpw512_mask:
15792 case clang::X86::BI__builtin_ia32_ucmpd512_mask:
15793 case clang::X86::BI__builtin_ia32_ucmpq512_mask: {
15797 (BuiltinOp >= clang::X86::BI__builtin_ia32_ucmpb128_mask &&
15798 BuiltinOp <= clang::X86::BI__builtin_ia32_ucmpq512_mask);
15811 unsigned RetWidth = Mask.getBitWidth();
15813 APSInt RetMask(llvm::APInt(RetWidth, 0),
true);
15815 for (
unsigned ElemNum = 0; ElemNum < VectorLen; ++ElemNum) {
15820 switch (
Opcode.getExtValue() & 0x7) {
15825 Result = IsUnsigned ? A.ult(B) : A.slt(B);
15828 Result = IsUnsigned ? A.ule(B) : A.sle(B);
15837 Result = IsUnsigned ? A.uge(B) : A.sge(B);
15840 Result = IsUnsigned ? A.ugt(B) : A.sgt(B);
15847 RetMask.setBitVal(ElemNum, Mask[ElemNum] &&
Result);
15858 const LValue &LV) {
15861 if (!LV.getLValueBase())
15866 if (!LV.getLValueDesignator().Invalid &&
15867 !LV.getLValueDesignator().isOnePastTheEnd())
15877 if (LV.getLValueDesignator().Invalid)
15883 return LV.getLValueOffset() == Size;
15893class DataRecursiveIntBinOpEvaluator {
15894 struct EvalResult {
15896 bool Failed =
false;
15898 EvalResult() =
default;
15900 void swap(EvalResult &RHS) {
15902 Failed = RHS.Failed;
15903 RHS.Failed =
false;
15909 EvalResult LHSResult;
15910 enum { AnyExprKind, BinOpKind, BinOpVisitedLHSKind }
Kind;
15913 Job(Job &&) =
default;
15915 void startSpeculativeEval(EvalInfo &Info) {
15916 SpecEvalRAII = SpeculativeEvaluationRAII(Info);
15920 SpeculativeEvaluationRAII SpecEvalRAII;
15923 SmallVector<Job, 16> Queue;
15925 IntExprEvaluator &IntEval;
15930 DataRecursiveIntBinOpEvaluator(IntExprEvaluator &IntEval,
APValue &
Result)
15931 : IntEval(IntEval), Info(IntEval.getEvalInfo()), FinalResult(
Result) { }
15937 static bool shouldEnqueue(
const BinaryOperator *E) {
15944 bool Traverse(
const BinaryOperator *E) {
15946 EvalResult PrevResult;
15947 while (!Queue.empty())
15948 process(PrevResult);
15950 if (PrevResult.Failed)
return false;
15952 FinalResult.
swap(PrevResult.Val);
15963 bool Error(
const Expr *E) {
15964 return IntEval.Error(E);
15967 return IntEval.Error(E, D);
15970 OptionalDiagnostic CCEDiag(
const Expr *E,
diag::kind D) {
15971 return Info.CCEDiag(E, D);
15975 bool VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
15976 bool &SuppressRHSDiags);
15978 bool VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
15981 void EvaluateExpr(
const Expr *E, EvalResult &
Result) {
15987 void process(EvalResult &
Result);
15989 void enqueue(
const Expr *E) {
15991 Queue.resize(Queue.size()+1);
15992 Queue.back().E = E;
15993 Queue.back().Kind = Job::AnyExprKind;
15999bool DataRecursiveIntBinOpEvaluator::
16000 VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
16001 bool &SuppressRHSDiags) {
16004 if (LHSResult.Failed)
16005 return Info.noteSideEffect();
16014 if (LHSAsBool == (E->
getOpcode() == BO_LOr)) {
16015 Success(LHSAsBool, E, LHSResult.Val);
16019 LHSResult.Failed =
true;
16023 if (!Info.noteSideEffect())
16029 SuppressRHSDiags =
true;
16038 if (LHSResult.Failed && !Info.noteFailure())
16049 assert(!LVal.
hasLValuePath() &&
"have designator for integer lvalue");
16051 uint64_t Offset64 = Offset.getQuantity();
16052 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
16054 : Offset64 + Index64);
16057bool DataRecursiveIntBinOpEvaluator::
16058 VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
16061 if (RHSResult.Failed)
16068 bool lhsResult, rhsResult;
16083 if (rhsResult == (E->
getOpcode() == BO_LOr))
16094 if (LHSResult.Failed || RHSResult.Failed)
16097 const APValue &LHSVal = LHSResult.Val;
16098 const APValue &RHSVal = RHSResult.Val;
16122 if (!LHSExpr || !RHSExpr)
16124 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
16125 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
16126 if (!LHSAddrExpr || !RHSAddrExpr)
16151void DataRecursiveIntBinOpEvaluator::process(EvalResult &
Result) {
16152 Job &job = Queue.back();
16154 switch (job.Kind) {
16155 case Job::AnyExprKind: {
16156 if (
const BinaryOperator *Bop = dyn_cast<BinaryOperator>(job.E)) {
16157 if (shouldEnqueue(Bop)) {
16158 job.Kind = Job::BinOpKind;
16159 enqueue(Bop->getLHS());
16164 EvaluateExpr(job.E,
Result);
16169 case Job::BinOpKind: {
16171 bool SuppressRHSDiags =
false;
16172 if (!VisitBinOpLHSOnly(
Result, Bop, SuppressRHSDiags)) {
16176 if (SuppressRHSDiags)
16177 job.startSpeculativeEval(Info);
16178 job.LHSResult.swap(
Result);
16179 job.Kind = Job::BinOpVisitedLHSKind;
16184 case Job::BinOpVisitedLHSKind: {
16188 Result.Failed = !VisitBinOp(job.LHSResult, RHS, Bop,
Result.Val);
16194 llvm_unreachable(
"Invalid Job::Kind!");
16198enum class CmpResult {
16207template <
class SuccessCB,
class AfterCB>
16210 SuccessCB &&
Success, AfterCB &&DoAfter) {
16215 "unsupported binary expression evaluation");
16217 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
16231 if (!LHSOK && !Info.noteFailure())
16236 return Success(CmpResult::Less, E);
16238 return Success(CmpResult::Greater, E);
16239 return Success(CmpResult::Equal, E);
16247 if (!LHSOK && !Info.noteFailure())
16252 return Success(CmpResult::Less, E);
16254 return Success(CmpResult::Greater, E);
16255 return Success(CmpResult::Equal, E);
16259 ComplexValue LHS, RHS;
16268 LHS.makeComplexFloat();
16269 LHS.FloatImag = APFloat(LHS.FloatReal.getSemantics());
16274 if (!LHSOK && !Info.noteFailure())
16280 RHS.makeComplexFloat();
16281 RHS.FloatImag = APFloat(RHS.FloatReal.getSemantics());
16285 if (LHS.isComplexFloat()) {
16286 APFloat::cmpResult CR_r =
16287 LHS.getComplexFloatReal().compare(RHS.getComplexFloatReal());
16288 APFloat::cmpResult CR_i =
16289 LHS.getComplexFloatImag().compare(RHS.getComplexFloatImag());
16290 bool IsEqual = CR_r == APFloat::cmpEqual && CR_i == APFloat::cmpEqual;
16291 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal, E);
16293 assert(IsEquality &&
"invalid complex comparison");
16294 bool IsEqual = LHS.getComplexIntReal() == RHS.getComplexIntReal() &&
16295 LHS.getComplexIntImag() == RHS.getComplexIntImag();
16296 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal, E);
16302 APFloat RHS(0.0), LHS(0.0);
16305 if (!LHSOK && !Info.noteFailure())
16312 llvm::APFloatBase::cmpResult APFloatCmpResult = LHS.compare(RHS);
16313 if (!Info.InConstantContext &&
16314 APFloatCmpResult == APFloat::cmpUnordered &&
16317 Info.FFDiag(E, diag::note_constexpr_float_arithmetic_strict);
16320 auto GetCmpRes = [&]() {
16321 switch (APFloatCmpResult) {
16322 case APFloat::cmpEqual:
16323 return CmpResult::Equal;
16324 case APFloat::cmpLessThan:
16325 return CmpResult::Less;
16326 case APFloat::cmpGreaterThan:
16327 return CmpResult::Greater;
16328 case APFloat::cmpUnordered:
16329 return CmpResult::Unordered;
16331 llvm_unreachable(
"Unrecognised APFloat::cmpResult enum");
16333 return Success(GetCmpRes(), E);
16337 LValue LHSValue, RHSValue;
16340 if (!LHSOK && !Info.noteFailure())
16351 if (Info.checkingPotentialConstantExpression() &&
16352 (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown))
16354 auto DiagComparison = [&] (
unsigned DiagID,
bool Reversed =
false) {
16355 std::string LHS = LHSValue.toString(Info.Ctx, E->
getLHS()->
getType());
16356 std::string RHS = RHSValue.toString(Info.Ctx, E->
getRHS()->
getType());
16357 Info.FFDiag(E, DiagID)
16364 return DiagComparison(
16365 diag::note_constexpr_pointer_comparison_unspecified);
16371 if ((!LHSValue.Base && !LHSValue.Offset.
isZero()) ||
16372 (!RHSValue.Base && !RHSValue.Offset.
isZero()))
16373 return DiagComparison(diag::note_constexpr_pointer_constant_comparison,
16387 return DiagComparison(diag::note_constexpr_literal_comparison);
16389 return DiagComparison(diag::note_constexpr_opaque_call_comparison,
16394 return DiagComparison(diag::note_constexpr_pointer_weak_comparison,
16398 if (LHSValue.Base && LHSValue.Offset.
isZero() &&
16400 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
16402 if (RHSValue.Base && RHSValue.Offset.
isZero() &&
16404 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
16410 return DiagComparison(
16411 diag::note_constexpr_pointer_comparison_zero_sized);
16412 if (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown)
16413 return DiagComparison(
16414 diag::note_constexpr_pointer_comparison_unspecified);
16416 return Success(CmpResult::Unequal, E);
16419 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
16420 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
16422 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
16423 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
16433 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid && IsRelational) {
16434 bool WasArrayIndex;
16437 :
getType(LHSValue.Base).getNonReferenceType(),
16438 LHSDesignator, RHSDesignator, WasArrayIndex);
16445 if (!WasArrayIndex && Mismatch < LHSDesignator.Entries.size() &&
16446 Mismatch < RHSDesignator.Entries.size()) {
16447 const FieldDecl *LF = getAsField(LHSDesignator.Entries[Mismatch]);
16448 const FieldDecl *RF = getAsField(RHSDesignator.Entries[Mismatch]);
16450 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_classes);
16452 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
16453 << getAsBaseClass(LHSDesignator.Entries[Mismatch])
16456 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
16457 << getAsBaseClass(RHSDesignator.Entries[Mismatch])
16462 diag::note_constexpr_pointer_comparison_differing_access)
16473 assert(PtrSize <= 64 &&
"Unexpected pointer width");
16474 uint64_t Mask = ~0ULL >> (64 - PtrSize);
16475 CompareLHS &= Mask;
16476 CompareRHS &= Mask;
16481 if (!LHSValue.Base.
isNull() && IsRelational) {
16486 uint64_t OffsetLimit = Size.getQuantity();
16487 if (CompareLHS > OffsetLimit || CompareRHS > OffsetLimit)
16491 if (CompareLHS < CompareRHS)
16492 return Success(CmpResult::Less, E);
16493 if (CompareLHS > CompareRHS)
16494 return Success(CmpResult::Greater, E);
16495 return Success(CmpResult::Equal, E);
16499 assert(IsEquality &&
"unexpected member pointer operation");
16502 MemberPtr LHSValue, RHSValue;
16505 if (!LHSOK && !Info.noteFailure())
16513 if (LHSValue.getDecl() && LHSValue.getDecl()->isWeak()) {
16514 Info.FFDiag(E, diag::note_constexpr_mem_pointer_weak_comparison)
16515 << LHSValue.getDecl();
16518 if (RHSValue.getDecl() && RHSValue.getDecl()->isWeak()) {
16519 Info.FFDiag(E, diag::note_constexpr_mem_pointer_weak_comparison)
16520 << RHSValue.getDecl();
16527 if (!LHSValue.getDecl() || !RHSValue.getDecl()) {
16528 bool Equal = !LHSValue.getDecl() && !RHSValue.getDecl();
16529 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal, E);
16534 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(LHSValue.getDecl()))
16535 if (MD->isVirtual())
16536 Info.CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
16537 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(RHSValue.getDecl()))
16538 if (MD->isVirtual())
16539 Info.CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
16545 bool Equal = LHSValue == RHSValue;
16546 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal, E);
16551 assert(RHSTy->
isNullPtrType() &&
"missing pointer conversion");
16559 return Success(CmpResult::Equal, E);
16565bool RecordExprEvaluator::VisitBinCmp(
const BinaryOperator *E) {
16569 auto OnSuccess = [&](CmpResult CR,
const BinaryOperator *E) {
16572 case CmpResult::Unequal:
16573 llvm_unreachable(
"should never produce Unequal for three-way comparison");
16574 case CmpResult::Less:
16575 CCR = ComparisonCategoryResult::Less;
16577 case CmpResult::Equal:
16578 CCR = ComparisonCategoryResult::Equal;
16580 case CmpResult::Greater:
16581 CCR = ComparisonCategoryResult::Greater;
16583 case CmpResult::Unordered:
16584 CCR = ComparisonCategoryResult::Unordered;
16589 const ComparisonCategoryInfo &CmpInfo =
16598 ConstantExprKind::Normal);
16601 return ExprEvaluatorBaseTy::VisitBinCmp(E);
16605bool RecordExprEvaluator::VisitCXXParenListInitExpr(
16606 const CXXParenListInitExpr *E) {
16607 return VisitCXXParenListOrInitListExpr(E, E->
getInitExprs());
16610bool IntExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
16615 if (!Info.noteFailure())
16619 if (DataRecursiveIntBinOpEvaluator::shouldEnqueue(E))
16620 return DataRecursiveIntBinOpEvaluator(*
this,
Result).Traverse(E);
16624 "DataRecursiveIntBinOpEvaluator should have handled integral types");
16629 auto OnSuccess = [&](CmpResult CR,
const BinaryOperator *E) {
16630 assert((CR != CmpResult::Unequal || E->
isEqualityOp()) &&
16631 "should only produce Unequal for equality comparisons");
16632 bool IsEqual = CR == CmpResult::Equal,
16633 IsLess = CR == CmpResult::Less,
16634 IsGreater = CR == CmpResult::Greater;
16638 llvm_unreachable(
"unsupported binary operator");
16641 return Success(IsEqual == (Op == BO_EQ), E);
16645 return Success(IsGreater, E);
16647 return Success(IsEqual || IsLess, E);
16649 return Success(IsEqual || IsGreater, E);
16653 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
16662 LValue LHSValue, RHSValue;
16665 if (!LHSOK && !Info.noteFailure())
16674 if (Info.checkingPotentialConstantExpression() &&
16675 (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown))
16678 const Expr *LHSExpr = LHSValue.Base.
dyn_cast<
const Expr *>();
16679 const Expr *RHSExpr = RHSValue.Base.
dyn_cast<
const Expr *>();
16681 auto DiagArith = [&](
unsigned DiagID) {
16682 std::string LHS = LHSValue.toString(Info.Ctx, E->
getLHS()->
getType());
16683 std::string RHS = RHSValue.toString(Info.Ctx, E->
getRHS()->
getType());
16684 Info.FFDiag(E, DiagID) << LHS << RHS;
16685 if (LHSExpr && LHSExpr == RHSExpr)
16687 diag::note_constexpr_repeated_literal_eval)
16692 if (!LHSExpr || !RHSExpr)
16693 return DiagArith(diag::note_constexpr_pointer_arith_unspecified);
16696 return DiagArith(diag::note_constexpr_literal_arith);
16698 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
16699 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
16700 if (!LHSAddrExpr || !RHSAddrExpr)
16708 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
16709 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
16711 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
16712 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
16718 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid &&
16721 Info.CCEDiag(E, diag::note_constexpr_pointer_subtraction_not_same_array);
16726 CharUnits ElementSize;
16733 if (ElementSize.
isZero()) {
16734 Info.FFDiag(E, diag::note_constexpr_pointer_subtraction_zero_size)
16751 APSInt TrueResult = (LHS - RHS) / ElemSize;
16754 if (
Result.extend(65) != TrueResult &&
16760 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
16765bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr(
16766 const UnaryExprOrTypeTraitExpr *E) {
16768 case UETT_PreferredAlignOf:
16769 case UETT_AlignOf: {
16778 case UETT_PtrAuthTypeDiscriminator: {
16784 case UETT_VecStep: {
16788 unsigned n = Ty->
castAs<VectorType>()->getNumElements();
16800 case UETT_DataSizeOf:
16801 case UETT_SizeOf: {
16805 if (
const ReferenceType *Ref = SrcTy->
getAs<ReferenceType>())
16816 case UETT_OpenMPRequiredSimdAlign:
16823 case UETT_VectorElements: {
16827 if (
const auto *VT = Ty->
getAs<VectorType>())
16831 if (Info.InConstantContext)
16832 Info.CCEDiag(E, diag::note_constexpr_non_const_vectorelements)
16837 case UETT_CountOf: {
16843 if (
const auto *CAT =
16855 if (VAT->getElementType()->isArrayType()) {
16858 if (!VAT->getSizeExpr()) {
16863 std::optional<APSInt> Res =
16864 VAT->getSizeExpr()->getIntegerConstantExpr(Info.Ctx);
16870 Res->getZExtValue()};
16882 llvm_unreachable(
"unknown expr/type trait");
16885bool IntExprEvaluator::VisitOffsetOfExpr(
const OffsetOfExpr *OOE) {
16891 for (
unsigned i = 0; i != n; ++i) {
16904 Result += IdxResult.getSExtValue() * ElementSize;
16909 FieldDecl *MemberDecl = ON.
getField();
16916 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
16923 llvm_unreachable(
"dependent __builtin_offsetof");
16926 CXXBaseSpecifier *BaseSpec = ON.
getBase();
16938 CurrentType = BaseSpec->
getType();
16952bool IntExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
16971 if (Info.checkingForUndefinedBehavior())
16973 diag::warn_integer_constant_overflow)
17001bool IntExprEvaluator::VisitCastExpr(
const CastExpr *E) {
17003 QualType DestType = E->
getType();
17004 QualType SrcType = SubExpr->
getType();
17007 case CK_BaseToDerived:
17008 case CK_DerivedToBase:
17009 case CK_UncheckedDerivedToBase:
17012 case CK_ArrayToPointerDecay:
17013 case CK_FunctionToPointerDecay:
17014 case CK_NullToPointer:
17015 case CK_NullToMemberPointer:
17016 case CK_BaseToDerivedMemberPointer:
17017 case CK_DerivedToBaseMemberPointer:
17018 case CK_ReinterpretMemberPointer:
17019 case CK_ConstructorConversion:
17020 case CK_IntegralToPointer:
17022 case CK_VectorSplat:
17023 case CK_IntegralToFloating:
17024 case CK_FloatingCast:
17025 case CK_CPointerToObjCPointerCast:
17026 case CK_BlockPointerToObjCPointerCast:
17027 case CK_AnyPointerToBlockPointerCast:
17028 case CK_ObjCObjectLValueCast:
17029 case CK_FloatingRealToComplex:
17030 case CK_FloatingComplexToReal:
17031 case CK_FloatingComplexCast:
17032 case CK_FloatingComplexToIntegralComplex:
17033 case CK_IntegralRealToComplex:
17034 case CK_IntegralComplexCast:
17035 case CK_IntegralComplexToFloatingComplex:
17036 case CK_BuiltinFnToFnPtr:
17037 case CK_ZeroToOCLOpaqueType:
17038 case CK_NonAtomicToAtomic:
17039 case CK_AddressSpaceConversion:
17040 case CK_IntToOCLSampler:
17041 case CK_FloatingToFixedPoint:
17042 case CK_FixedPointToFloating:
17043 case CK_FixedPointCast:
17044 case CK_IntegralToFixedPoint:
17045 case CK_MatrixCast:
17046 case CK_HLSLAggregateSplatCast:
17047 llvm_unreachable(
"invalid cast kind for integral value");
17051 case CK_LValueBitCast:
17052 case CK_ARCProduceObject:
17053 case CK_ARCConsumeObject:
17054 case CK_ARCReclaimReturnedObject:
17055 case CK_ARCExtendBlockObject:
17056 case CK_CopyAndAutoreleaseBlockObject:
17059 case CK_UserDefinedConversion:
17060 case CK_LValueToRValue:
17061 case CK_AtomicToNonAtomic:
17063 case CK_LValueToRValueBitCast:
17064 case CK_HLSLArrayRValue:
17065 case CK_HLSLElementwiseCast:
17066 return ExprEvaluatorBaseTy::VisitCastExpr(E);
17068 case CK_MemberPointerToBoolean:
17069 case CK_PointerToBoolean:
17070 case CK_IntegralToBoolean:
17071 case CK_FloatingToBoolean:
17072 case CK_BooleanToSignedIntegral:
17073 case CK_FloatingComplexToBoolean:
17074 case CK_IntegralComplexToBoolean: {
17079 if (BoolResult && E->
getCastKind() == CK_BooleanToSignedIntegral)
17081 return Success(IntResult, E);
17084 case CK_FixedPointToIntegral: {
17089 llvm::APSInt
Result = Src.convertToInt(
17097 case CK_FixedPointToBoolean: {
17100 if (!
Evaluate(Val, Info, SubExpr))
17105 case CK_IntegralCast: {
17106 if (!Visit(SubExpr))
17115 if (
Result.isAddrLabelDiff())
17133 if (!ED->isFixed()) {
17137 ED->getValueRange(
Max,
Min);
17140 if (ED->getNumNegativeBits() &&
17141 (
Max.slt(
Result.getInt().getSExtValue()) ||
17142 Min.sgt(
Result.getInt().getSExtValue())))
17143 Info.CCEDiag(E, diag::note_constexpr_unscoped_enum_out_of_range)
17144 << llvm::toString(
Result.getInt(), 10) <<
Min.getSExtValue()
17145 <<
Max.getSExtValue() << ED;
17146 else if (!ED->getNumNegativeBits() &&
17147 Max.ult(
Result.getInt().getZExtValue()))
17148 Info.CCEDiag(E, diag::note_constexpr_unscoped_enum_out_of_range)
17149 << llvm::toString(
Result.getInt(), 10) <<
Min.getZExtValue()
17150 <<
Max.getZExtValue() << ED;
17158 case CK_PointerToIntegral: {
17159 CCEDiag(E, diag::note_constexpr_invalid_cast)
17160 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
17167 if (LV.getLValueBase()) {
17175 LV.Designator.setInvalid();
17183 if (!
V.toIntegralConstant(AsInt, SrcType, Info.Ctx))
17184 llvm_unreachable(
"Can't cast this!");
17189 case CK_IntegralComplexToReal: {
17193 return Success(
C.getComplexIntReal(), E);
17196 case CK_FloatingToIntegral: {
17206 case CK_HLSLVectorTruncation: {
17214 llvm_unreachable(
"unknown cast resulting in integral value");
17217bool IntExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
17222 if (!LV.isComplexInt())
17224 return Success(LV.getComplexIntReal(), E);
17230bool IntExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
17235 if (!LV.isComplexInt())
17237 return Success(LV.getComplexIntImag(), E);
17244bool IntExprEvaluator::VisitSizeOfPackExpr(
const SizeOfPackExpr *E) {
17248bool IntExprEvaluator::VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E) {
17252bool IntExprEvaluator::VisitConceptSpecializationExpr(
17253 const ConceptSpecializationExpr *E) {
17257bool IntExprEvaluator::VisitRequiresExpr(
const RequiresExpr *E) {
17261bool FixedPointExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
17271 if (!
Result.isFixedPoint())
17274 APFixedPoint Negated =
Result.getFixedPoint().negate(&Overflowed);
17288bool FixedPointExprEvaluator::VisitCastExpr(
const CastExpr *E) {
17290 QualType DestType = E->
getType();
17292 "Expected destination type to be a fixed point type");
17296 case CK_FixedPointCast: {
17301 APFixedPoint
Result = Src.convert(DestFXSema, &Overflowed);
17303 if (Info.checkingForUndefinedBehavior())
17305 diag::warn_fixedpoint_constant_overflow)
17312 case CK_IntegralToFixedPoint: {
17318 APFixedPoint IntResult = APFixedPoint::getFromIntValue(
17322 if (Info.checkingForUndefinedBehavior())
17324 diag::warn_fixedpoint_constant_overflow)
17325 << IntResult.toString() << E->
getType();
17330 return Success(IntResult, E);
17332 case CK_FloatingToFixedPoint: {
17338 APFixedPoint
Result = APFixedPoint::getFromFloatValue(
17342 if (Info.checkingForUndefinedBehavior())
17344 diag::warn_fixedpoint_constant_overflow)
17353 case CK_LValueToRValue:
17354 return ExprEvaluatorBaseTy::VisitCastExpr(E);
17360bool FixedPointExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
17362 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
17364 const Expr *LHS = E->
getLHS();
17365 const Expr *RHS = E->
getRHS();
17376 bool OpOverflow =
false, ConversionOverflow =
false;
17377 APFixedPoint
Result(LHSFX.getSemantics());
17380 Result = LHSFX.add(RHSFX, &OpOverflow)
17381 .convert(ResultFXSema, &ConversionOverflow);
17385 Result = LHSFX.sub(RHSFX, &OpOverflow)
17386 .convert(ResultFXSema, &ConversionOverflow);
17390 Result = LHSFX.mul(RHSFX, &OpOverflow)
17391 .convert(ResultFXSema, &ConversionOverflow);
17395 if (RHSFX.getValue() == 0) {
17396 Info.FFDiag(E, diag::note_expr_divide_by_zero);
17399 Result = LHSFX.div(RHSFX, &OpOverflow)
17400 .convert(ResultFXSema, &ConversionOverflow);
17406 llvm::APSInt RHSVal = RHSFX.getValue();
17409 LHSSema.getWidth() - (unsigned)LHSSema.hasUnsignedPadding();
17410 unsigned Amt = RHSVal.getLimitedValue(ShiftBW - 1);
17414 if (RHSVal.isNegative())
17415 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHSVal;
17416 else if (Amt != RHSVal)
17417 Info.CCEDiag(E, diag::note_constexpr_large_shift)
17418 << RHSVal << E->
getType() << ShiftBW;
17421 Result = LHSFX.shl(Amt, &OpOverflow);
17423 Result = LHSFX.shr(Amt, &OpOverflow);
17429 if (OpOverflow || ConversionOverflow) {
17430 if (Info.checkingForUndefinedBehavior())
17432 diag::warn_fixedpoint_constant_overflow)
17445class FloatExprEvaluator
17446 :
public ExprEvaluatorBase<FloatExprEvaluator> {
17449 FloatExprEvaluator(EvalInfo &info, APFloat &result)
17450 : ExprEvaluatorBaseTy(info),
Result(result) {}
17457 bool ZeroInitialization(
const Expr *E) {
17462 bool VisitCallExpr(
const CallExpr *E);
17464 bool VisitUnaryOperator(
const UnaryOperator *E);
17465 bool VisitBinaryOperator(
const BinaryOperator *E);
17466 bool VisitFloatingLiteral(
const FloatingLiteral *E);
17467 bool VisitCastExpr(
const CastExpr *E);
17469 bool VisitUnaryReal(
const UnaryOperator *E);
17470 bool VisitUnaryImag(
const UnaryOperator *E);
17479 return FloatExprEvaluator(Info, Result).Visit(E);
17486 llvm::APFloat &Result) {
17488 if (!S)
return false;
17490 const llvm::fltSemantics &Sem = Context.getFloatTypeSemantics(ResultTy);
17496 fill = llvm::APInt(32, 0);
17497 else if (S->
getString().getAsInteger(0, fill))
17500 if (Context.getTargetInfo().isNan2008()) {
17502 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
17504 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
17512 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
17514 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
17520bool FloatExprEvaluator::VisitCallExpr(
const CallExpr *E) {
17521 if (!IsConstantEvaluatedBuiltinCall(E))
17522 return ExprEvaluatorBaseTy::VisitCallExpr(E);
17528 case Builtin::BI__builtin_huge_val:
17529 case Builtin::BI__builtin_huge_valf:
17530 case Builtin::BI__builtin_huge_vall:
17531 case Builtin::BI__builtin_huge_valf16:
17532 case Builtin::BI__builtin_huge_valf128:
17533 case Builtin::BI__builtin_inf:
17534 case Builtin::BI__builtin_inff:
17535 case Builtin::BI__builtin_infl:
17536 case Builtin::BI__builtin_inff16:
17537 case Builtin::BI__builtin_inff128: {
17538 const llvm::fltSemantics &Sem =
17540 Result = llvm::APFloat::getInf(Sem);
17544 case Builtin::BI__builtin_nans:
17545 case Builtin::BI__builtin_nansf:
17546 case Builtin::BI__builtin_nansl:
17547 case Builtin::BI__builtin_nansf16:
17548 case Builtin::BI__builtin_nansf128:
17554 case Builtin::BI__builtin_nan:
17555 case Builtin::BI__builtin_nanf:
17556 case Builtin::BI__builtin_nanl:
17557 case Builtin::BI__builtin_nanf16:
17558 case Builtin::BI__builtin_nanf128:
17566 case Builtin::BI__builtin_elementwise_abs:
17567 case Builtin::BI__builtin_fabs:
17568 case Builtin::BI__builtin_fabsf:
17569 case Builtin::BI__builtin_fabsl:
17570 case Builtin::BI__builtin_fabsf128:
17579 if (
Result.isNegative())
17583 case Builtin::BI__arithmetic_fence:
17590 case Builtin::BI__builtin_copysign:
17591 case Builtin::BI__builtin_copysignf:
17592 case Builtin::BI__builtin_copysignl:
17593 case Builtin::BI__builtin_copysignf128: {
17602 case Builtin::BI__builtin_fmax:
17603 case Builtin::BI__builtin_fmaxf:
17604 case Builtin::BI__builtin_fmaxl:
17605 case Builtin::BI__builtin_fmaxf16:
17606 case Builtin::BI__builtin_fmaxf128: {
17615 case Builtin::BI__builtin_fmin:
17616 case Builtin::BI__builtin_fminf:
17617 case Builtin::BI__builtin_fminl:
17618 case Builtin::BI__builtin_fminf16:
17619 case Builtin::BI__builtin_fminf128: {
17628 case Builtin::BI__builtin_fmaximum_num:
17629 case Builtin::BI__builtin_fmaximum_numf:
17630 case Builtin::BI__builtin_fmaximum_numl:
17631 case Builtin::BI__builtin_fmaximum_numf16:
17632 case Builtin::BI__builtin_fmaximum_numf128: {
17641 case Builtin::BI__builtin_fminimum_num:
17642 case Builtin::BI__builtin_fminimum_numf:
17643 case Builtin::BI__builtin_fminimum_numl:
17644 case Builtin::BI__builtin_fminimum_numf16:
17645 case Builtin::BI__builtin_fminimum_numf128: {
17654 case Builtin::BI__builtin_elementwise_fma: {
17659 APFloat SourceY(0.), SourceZ(0.);
17665 (void)
Result.fusedMultiplyAdd(SourceY, SourceZ, RM);
17669 case clang::X86::BI__builtin_ia32_vec_ext_v4sf: {
17676 unsigned Idx =
static_cast<unsigned>(IdxAPS.getZExtValue() & (N - 1));
17682bool FloatExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
17694bool FloatExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
17705 Result = llvm::APFloat::getZero(Sem);
17709bool FloatExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
17711 default:
return Error(E);
17725bool FloatExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
17727 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
17731 if (!LHSOK && !Info.noteFailure())
17737bool FloatExprEvaluator::VisitFloatingLiteral(
const FloatingLiteral *E) {
17742bool FloatExprEvaluator::VisitCastExpr(
const CastExpr *E) {
17747 return ExprEvaluatorBaseTy::VisitCastExpr(E);
17749 case CK_IntegralToFloating: {
17758 case CK_FixedPointToFloating: {
17767 case CK_FloatingCast: {
17768 if (!Visit(SubExpr))
17774 case CK_FloatingComplexToReal: {
17778 Result =
V.getComplexFloatReal();
17781 case CK_HLSLVectorTruncation: {
17795class ComplexExprEvaluator
17796 :
public ExprEvaluatorBase<ComplexExprEvaluator> {
17800 ComplexExprEvaluator(EvalInfo &info, ComplexValue &
Result)
17808 bool ZeroInitialization(
const Expr *E);
17814 bool VisitImaginaryLiteral(
const ImaginaryLiteral *E);
17815 bool VisitCastExpr(
const CastExpr *E);
17816 bool VisitBinaryOperator(
const BinaryOperator *E);
17817 bool VisitUnaryOperator(
const UnaryOperator *E);
17818 bool VisitInitListExpr(
const InitListExpr *E);
17819 bool VisitCallExpr(
const CallExpr *E);
17827 return ComplexExprEvaluator(Info, Result).Visit(E);
17830bool ComplexExprEvaluator::ZeroInitialization(
const Expr *E) {
17831 QualType ElemTy = E->
getType()->
castAs<ComplexType>()->getElementType();
17833 Result.makeComplexFloat();
17838 Result.makeComplexInt();
17846bool ComplexExprEvaluator::VisitImaginaryLiteral(
const ImaginaryLiteral *E) {
17850 Result.makeComplexFloat();
17859 "Unexpected imaginary literal.");
17861 Result.makeComplexInt();
17866 Result.IntReal =
APSInt(Imag.getBitWidth(), !Imag.isSigned());
17871bool ComplexExprEvaluator::VisitCastExpr(
const CastExpr *E) {
17875 case CK_BaseToDerived:
17876 case CK_DerivedToBase:
17877 case CK_UncheckedDerivedToBase:
17880 case CK_ArrayToPointerDecay:
17881 case CK_FunctionToPointerDecay:
17882 case CK_NullToPointer:
17883 case CK_NullToMemberPointer:
17884 case CK_BaseToDerivedMemberPointer:
17885 case CK_DerivedToBaseMemberPointer:
17886 case CK_MemberPointerToBoolean:
17887 case CK_ReinterpretMemberPointer:
17888 case CK_ConstructorConversion:
17889 case CK_IntegralToPointer:
17890 case CK_PointerToIntegral:
17891 case CK_PointerToBoolean:
17893 case CK_VectorSplat:
17894 case CK_IntegralCast:
17895 case CK_BooleanToSignedIntegral:
17896 case CK_IntegralToBoolean:
17897 case CK_IntegralToFloating:
17898 case CK_FloatingToIntegral:
17899 case CK_FloatingToBoolean:
17900 case CK_FloatingCast:
17901 case CK_CPointerToObjCPointerCast:
17902 case CK_BlockPointerToObjCPointerCast:
17903 case CK_AnyPointerToBlockPointerCast:
17904 case CK_ObjCObjectLValueCast:
17905 case CK_FloatingComplexToReal:
17906 case CK_FloatingComplexToBoolean:
17907 case CK_IntegralComplexToReal:
17908 case CK_IntegralComplexToBoolean:
17909 case CK_ARCProduceObject:
17910 case CK_ARCConsumeObject:
17911 case CK_ARCReclaimReturnedObject:
17912 case CK_ARCExtendBlockObject:
17913 case CK_CopyAndAutoreleaseBlockObject:
17914 case CK_BuiltinFnToFnPtr:
17915 case CK_ZeroToOCLOpaqueType:
17916 case CK_NonAtomicToAtomic:
17917 case CK_AddressSpaceConversion:
17918 case CK_IntToOCLSampler:
17919 case CK_FloatingToFixedPoint:
17920 case CK_FixedPointToFloating:
17921 case CK_FixedPointCast:
17922 case CK_FixedPointToBoolean:
17923 case CK_FixedPointToIntegral:
17924 case CK_IntegralToFixedPoint:
17925 case CK_MatrixCast:
17926 case CK_HLSLVectorTruncation:
17927 case CK_HLSLElementwiseCast:
17928 case CK_HLSLAggregateSplatCast:
17929 llvm_unreachable(
"invalid cast kind for complex value");
17931 case CK_LValueToRValue:
17932 case CK_AtomicToNonAtomic:
17934 case CK_LValueToRValueBitCast:
17935 case CK_HLSLArrayRValue:
17936 return ExprEvaluatorBaseTy::VisitCastExpr(E);
17939 case CK_LValueBitCast:
17940 case CK_UserDefinedConversion:
17943 case CK_FloatingRealToComplex: {
17948 Result.makeComplexFloat();
17953 case CK_FloatingComplexCast: {
17957 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
17965 case CK_FloatingComplexToIntegralComplex: {
17969 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
17972 Result.makeComplexInt();
17979 case CK_IntegralRealToComplex: {
17984 Result.makeComplexInt();
17985 Result.IntImag =
APSInt(Real.getBitWidth(), !Real.isSigned());
17989 case CK_IntegralComplexCast: {
17993 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
18002 case CK_IntegralComplexToFloatingComplex: {
18008 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
18011 Result.makeComplexFloat();
18013 To,
Result.FloatReal) &&
18019 llvm_unreachable(
"unknown cast resulting in complex value");
18023 APFloat &ResR, APFloat &ResI) {
18029 APFloat AC = A *
C;
18030 APFloat BD = B * D;
18031 APFloat AD = A * D;
18032 APFloat BC = B *
C;
18035 if (ResR.isNaN() && ResI.isNaN()) {
18036 bool Recalc =
false;
18037 if (A.isInfinity() || B.isInfinity()) {
18038 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
18040 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
18043 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
18045 D = APFloat::copySign(APFloat(D.getSemantics()), D);
18048 if (
C.isInfinity() || D.isInfinity()) {
18049 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
18051 D = APFloat::copySign(APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0),
18054 A = APFloat::copySign(APFloat(A.getSemantics()), A);
18056 B = APFloat::copySign(APFloat(B.getSemantics()), B);
18059 if (!Recalc && (AC.isInfinity() || BD.isInfinity() || AD.isInfinity() ||
18060 BC.isInfinity())) {
18062 A = APFloat::copySign(APFloat(A.getSemantics()), A);
18064 B = APFloat::copySign(APFloat(B.getSemantics()), B);
18066 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
18068 D = APFloat::copySign(APFloat(D.getSemantics()), D);
18072 ResR = APFloat::getInf(A.getSemantics()) * (A *
C - B * D);
18073 ResI = APFloat::getInf(A.getSemantics()) * (A * D + B *
C);
18079 APFloat &ResR, APFloat &ResI) {
18086 APFloat MaxCD = maxnum(
abs(
C),
abs(D));
18087 if (MaxCD.isFinite()) {
18088 DenomLogB =
ilogb(MaxCD);
18089 C =
scalbn(
C, -DenomLogB, APFloat::rmNearestTiesToEven);
18090 D =
scalbn(D, -DenomLogB, APFloat::rmNearestTiesToEven);
18092 APFloat Denom =
C *
C + D * D;
18094 scalbn((A *
C + B * D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
18096 scalbn((B *
C - A * D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
18097 if (ResR.isNaN() && ResI.isNaN()) {
18098 if (Denom.isPosZero() && (!A.isNaN() || !B.isNaN())) {
18099 ResR = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * A;
18100 ResI = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * B;
18101 }
else if ((A.isInfinity() || B.isInfinity()) &&
C.isFinite() &&
18103 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
18105 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
18107 ResR = APFloat::getInf(ResR.getSemantics()) * (A *
C + B * D);
18108 ResI = APFloat::getInf(ResI.getSemantics()) * (B *
C - A * D);
18109 }
else if (MaxCD.isInfinity() && A.isFinite() && B.isFinite()) {
18110 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
18112 D = APFloat::copySign(APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0),
18114 ResR = APFloat::getZero(ResR.getSemantics()) * (A *
C + B * D);
18115 ResI = APFloat::getZero(ResI.getSemantics()) * (B *
C - A * D);
18120bool ComplexExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
18122 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
18126 bool LHSReal =
false, RHSReal =
false;
18134 Result.makeComplexFloat();
18138 LHSOK = Visit(E->
getLHS());
18140 if (!LHSOK && !Info.noteFailure())
18146 APFloat &Real = RHS.FloatReal;
18149 RHS.makeComplexFloat();
18150 RHS.FloatImag =
APFloat(Real.getSemantics());
18154 assert(!(LHSReal && RHSReal) &&
18155 "Cannot have both operands of a complex operation be real.");
18157 default:
return Error(E);
18159 if (
Result.isComplexFloat()) {
18160 Result.getComplexFloatReal().add(RHS.getComplexFloatReal(),
18161 APFloat::rmNearestTiesToEven);
18163 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
18165 Result.getComplexFloatImag().add(RHS.getComplexFloatImag(),
18166 APFloat::rmNearestTiesToEven);
18168 Result.getComplexIntReal() += RHS.getComplexIntReal();
18169 Result.getComplexIntImag() += RHS.getComplexIntImag();
18173 if (
Result.isComplexFloat()) {
18174 Result.getComplexFloatReal().subtract(RHS.getComplexFloatReal(),
18175 APFloat::rmNearestTiesToEven);
18177 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
18178 Result.getComplexFloatImag().changeSign();
18179 }
else if (!RHSReal) {
18180 Result.getComplexFloatImag().subtract(RHS.getComplexFloatImag(),
18181 APFloat::rmNearestTiesToEven);
18184 Result.getComplexIntReal() -= RHS.getComplexIntReal();
18185 Result.getComplexIntImag() -= RHS.getComplexIntImag();
18189 if (
Result.isComplexFloat()) {
18194 ComplexValue LHS =
Result;
18195 APFloat &A = LHS.getComplexFloatReal();
18196 APFloat &B = LHS.getComplexFloatImag();
18197 APFloat &
C = RHS.getComplexFloatReal();
18198 APFloat &D = RHS.getComplexFloatImag();
18202 assert(!RHSReal &&
"Cannot have two real operands for a complex op!");
18210 }
else if (RHSReal) {
18222 ComplexValue LHS =
Result;
18223 Result.getComplexIntReal() =
18224 (LHS.getComplexIntReal() * RHS.getComplexIntReal() -
18225 LHS.getComplexIntImag() * RHS.getComplexIntImag());
18226 Result.getComplexIntImag() =
18227 (LHS.getComplexIntReal() * RHS.getComplexIntImag() +
18228 LHS.getComplexIntImag() * RHS.getComplexIntReal());
18232 if (
Result.isComplexFloat()) {
18237 ComplexValue LHS =
Result;
18238 APFloat &A = LHS.getComplexFloatReal();
18239 APFloat &B = LHS.getComplexFloatImag();
18240 APFloat &
C = RHS.getComplexFloatReal();
18241 APFloat &D = RHS.getComplexFloatImag();
18255 B = APFloat::getZero(A.getSemantics());
18260 ComplexValue LHS =
Result;
18261 APSInt Den = RHS.getComplexIntReal() * RHS.getComplexIntReal() +
18262 RHS.getComplexIntImag() * RHS.getComplexIntImag();
18264 return Error(E, diag::note_expr_divide_by_zero);
18266 Result.getComplexIntReal() =
18267 (LHS.getComplexIntReal() * RHS.getComplexIntReal() +
18268 LHS.getComplexIntImag() * RHS.getComplexIntImag()) / Den;
18269 Result.getComplexIntImag() =
18270 (LHS.getComplexIntImag() * RHS.getComplexIntReal() -
18271 LHS.getComplexIntReal() * RHS.getComplexIntImag()) / Den;
18279bool ComplexExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
18293 if (
Result.isComplexFloat()) {
18294 Result.getComplexFloatReal().changeSign();
18295 Result.getComplexFloatImag().changeSign();
18298 Result.getComplexIntReal() = -
Result.getComplexIntReal();
18299 Result.getComplexIntImag() = -
Result.getComplexIntImag();
18303 if (
Result.isComplexFloat())
18304 Result.getComplexFloatImag().changeSign();
18306 Result.getComplexIntImag() = -
Result.getComplexIntImag();
18311bool ComplexExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
18314 Result.makeComplexFloat();
18320 Result.makeComplexInt();
18328 return ExprEvaluatorBaseTy::VisitInitListExpr(E);
18331bool ComplexExprEvaluator::VisitCallExpr(
const CallExpr *E) {
18332 if (!IsConstantEvaluatedBuiltinCall(E))
18333 return ExprEvaluatorBaseTy::VisitCallExpr(E);
18336 case Builtin::BI__builtin_complex:
18337 Result.makeComplexFloat();
18355class AtomicExprEvaluator :
18356 public ExprEvaluatorBase<AtomicExprEvaluator> {
18357 const LValue *
This;
18360 AtomicExprEvaluator(EvalInfo &Info,
const LValue *This,
APValue &
Result)
18368 bool ZeroInitialization(
const Expr *E) {
18369 ImplicitValueInitExpr VIE(
18377 bool VisitCastExpr(
const CastExpr *E) {
18380 return ExprEvaluatorBaseTy::VisitCastExpr(E);
18381 case CK_NullToPointer:
18383 return ZeroInitialization(E);
18384 case CK_NonAtomicToAtomic:
18396 return AtomicExprEvaluator(Info,
This, Result).Visit(E);
18405class VoidExprEvaluator
18406 :
public ExprEvaluatorBase<VoidExprEvaluator> {
18408 VoidExprEvaluator(EvalInfo &Info) : ExprEvaluatorBaseTy(Info) {}
18412 bool ZeroInitialization(
const Expr *E) {
return true; }
18414 bool VisitCastExpr(
const CastExpr *E) {
18417 return ExprEvaluatorBaseTy::VisitCastExpr(E);
18424 bool VisitCallExpr(
const CallExpr *E) {
18425 if (!IsConstantEvaluatedBuiltinCall(E))
18426 return ExprEvaluatorBaseTy::VisitCallExpr(E);
18429 case Builtin::BI__assume:
18430 case Builtin::BI__builtin_assume:
18434 case Builtin::BI__builtin_operator_delete:
18442 bool VisitCXXDeleteExpr(
const CXXDeleteExpr *E);
18446bool VoidExprEvaluator::VisitCXXDeleteExpr(
const CXXDeleteExpr *E) {
18448 if (Info.SpeculativeEvaluationDepth)
18452 if (!OperatorDelete
18453 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
18454 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
18464 if (
Pointer.Designator.Invalid)
18468 if (
Pointer.isNullPointer()) {
18472 if (!Info.getLangOpts().CPlusPlus20)
18473 Info.CCEDiag(E, diag::note_constexpr_new);
18481 QualType AllocType =
Pointer.Base.getDynamicAllocType();
18487 Info.FFDiag(E, diag::note_constexpr_delete_base_nonvirt_dtor)
18496 if (VirtualDelete &&
18498 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
18499 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
18506 (*Alloc)->Value, AllocType))
18509 if (!Info.HeapAllocs.erase(
Pointer.Base.dyn_cast<DynamicAllocLValue>())) {
18514 Info.FFDiag(E, diag::note_constexpr_double_delete);
18524 return VoidExprEvaluator(Info).Visit(E);
18536 if (E->
isGLValue() ||
T->isFunctionType()) {
18540 LV.moveInto(Result);
18541 }
else if (
T->isVectorType()) {
18544 }
else if (
T->isIntegralOrEnumerationType()) {
18545 if (!IntExprEvaluator(Info, Result).Visit(E))
18547 }
else if (
T->hasPointerRepresentation()) {
18551 LV.moveInto(Result);
18552 }
else if (
T->isRealFloatingType()) {
18553 llvm::APFloat F(0.0);
18557 }
else if (
T->isAnyComplexType()) {
18561 C.moveInto(Result);
18562 }
else if (
T->isFixedPointType()) {
18563 if (!FixedPointExprEvaluator(Info, Result).Visit(E))
return false;
18564 }
else if (
T->isMemberPointerType()) {
18568 P.moveInto(Result);
18570 }
else if (
T->isArrayType()) {
18573 Info.CurrentCall->createTemporary(E,
T, ScopeKind::FullExpression, LV);
18577 }
else if (
T->isRecordType()) {
18580 Info.CurrentCall->createTemporary(E,
T, ScopeKind::FullExpression, LV);
18584 }
else if (
T->isVoidType()) {
18585 if (!Info.getLangOpts().CPlusPlus11)
18586 Info.CCEDiag(E, diag::note_constexpr_nonliteral)
18590 }
else if (
T->isAtomicType()) {
18591 QualType Unqual =
T.getAtomicUnqualifiedType();
18595 E, Unqual, ScopeKind::FullExpression, LV);
18603 }
else if (Info.getLangOpts().CPlusPlus11) {
18604 Info.FFDiag(E, diag::note_constexpr_nonliteral) << E->
getType();
18607 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
18618 const Expr *E,
bool AllowNonLiteralTypes) {
18634 if (
T->isArrayType())
18636 else if (
T->isRecordType())
18638 else if (
T->isAtomicType()) {
18639 QualType Unqual =
T.getAtomicUnqualifiedType();
18660 if (Info.EnableNewConstInterp) {
18664 ConstantExprKind::Normal);
18673 LV.setFrom(Info.Ctx, Result);
18680 ConstantExprKind::Normal) &&
18688 if (
const auto *L = dyn_cast<IntegerLiteral>(Exp)) {
18690 APValue(
APSInt(L->getValue(), L->getType()->isUnsignedIntegerType()));
18695 if (
const auto *L = dyn_cast<CXXBoolLiteralExpr>(Exp)) {
18701 if (
const auto *FL = dyn_cast<FloatingLiteral>(Exp)) {
18702 Result =
APValue(FL->getValue());
18707 if (
const auto *L = dyn_cast<CharacterLiteral>(Exp)) {
18713 if (
const auto *CE = dyn_cast<ConstantExpr>(Exp)) {
18714 if (CE->hasAPValueResult()) {
18715 APValue APV = CE->getAPValueResult();
18717 Result = std::move(APV);
18793 bool InConstantContext)
const {
18795 "Expression evaluator can't be called on a dependent expression.");
18796 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsRValue");
18798 Info.InConstantContext = InConstantContext;
18799 return ::EvaluateAsRValue(
this,
Result, Ctx, Info);
18803 bool InConstantContext)
const {
18805 "Expression evaluator can't be called on a dependent expression.");
18806 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsBooleanCondition");
18814 bool InConstantContext)
const {
18816 "Expression evaluator can't be called on a dependent expression.");
18817 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsInt");
18819 Info.InConstantContext = InConstantContext;
18820 return ::EvaluateAsInt(
this,
Result, Ctx, AllowSideEffects, Info);
18825 bool InConstantContext)
const {
18827 "Expression evaluator can't be called on a dependent expression.");
18828 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFixedPoint");
18830 Info.InConstantContext = InConstantContext;
18831 return ::EvaluateAsFixedPoint(
this,
Result, Ctx, AllowSideEffects, Info);
18836 bool InConstantContext)
const {
18838 "Expression evaluator can't be called on a dependent expression.");
18840 if (!
getType()->isRealFloatingType())
18843 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFloat");
18855 bool InConstantContext)
const {
18857 "Expression evaluator can't be called on a dependent expression.");
18859 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsLValue");
18861 Info.InConstantContext = InConstantContext;
18865 if (Info.EnableNewConstInterp) {
18867 ConstantExprKind::Normal))
18870 LV.setFrom(Ctx,
Result.Val);
18873 ConstantExprKind::Normal, CheckedTemps);
18876 if (!
EvaluateLValue(
this, LV, Info) || !Info.discardCleanups() ||
18877 Result.HasSideEffects ||
18880 ConstantExprKind::Normal, CheckedTemps))
18883 LV.moveInto(
Result.Val);
18890 bool IsConstantDestruction) {
18891 EvalInfo Info(Ctx, EStatus,
18894 Info.setEvaluatingDecl(
Base, DestroyedValue,
18895 EvalInfo::EvaluatingDeclKind::Dtor);
18896 Info.InConstantContext = IsConstantDestruction;
18905 if (!Info.discardCleanups())
18906 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
18914 "Expression evaluator can't be called on a dependent expression.");
18920 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsConstantExpr");
18922 EvalInfo Info(Ctx,
Result, EM);
18923 Info.InConstantContext =
true;
18925 if (Info.EnableNewConstInterp) {
18929 getStorageType(Ctx,
this),
Result.Val, Kind);
18934 if (Kind == ConstantExprKind::ClassTemplateArgument)
18950 FullExpressionRAII
Scope(Info);
18955 if (!Info.discardCleanups())
18956 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
18966 if (Kind == ConstantExprKind::ClassTemplateArgument &&
18969 Result.HasSideEffects)) {
18981 bool IsConstantInitialization)
const {
18983 "Expression evaluator can't be called on a dependent expression.");
18984 assert(VD &&
"Need a valid VarDecl");
18986 llvm::TimeTraceScope TimeScope(
"EvaluateAsInitializer", [&] {
18988 llvm::raw_string_ostream OS(Name);
18994 EStatus.
Diag = &Notes;
18996 EvalInfo Info(Ctx, EStatus,
18997 (IsConstantInitialization &&
19001 Info.setEvaluatingDecl(VD,
Value);
19002 Info.InConstantContext = IsConstantInitialization;
19007 if (Info.EnableNewConstInterp) {
19008 auto &InterpCtx =
const_cast<ASTContext &
>(Ctx).getInterpContext();
19009 if (!InterpCtx.evaluateAsInitializer(Info, VD,
this,
Value))
19013 ConstantExprKind::Normal);
19028 FullExpressionRAII
Scope(Info);
19031 EStatus.HasSideEffects)
19037 Info.performLifetimeExtension();
19039 if (!Info.discardCleanups())
19040 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
19044 ConstantExprKind::Normal) &&
19051 EStatus.
Diag = &Notes;
19068 IsConstantDestruction) ||
19080 "Expression evaluator can't be called on a dependent expression.");
19089 "Expression evaluator can't be called on a dependent expression.");
19091 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstInt");
19094 Info.InConstantContext =
true;
19098 assert(
Result &&
"Could not evaluate expression");
19099 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
19101 return EVResult.Val.getInt();
19107 "Expression evaluator can't be called on a dependent expression.");
19109 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstIntCheckOverflow");
19111 EVResult.Diag =
Diag;
19113 Info.InConstantContext =
true;
19114 Info.CheckingForUndefinedBehavior =
true;
19118 assert(
Result &&
"Could not evaluate expression");
19119 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
19121 return EVResult.Val.getInt();
19126 "Expression evaluator can't be called on a dependent expression.");
19128 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateForOverflow");
19133 Info.CheckingForUndefinedBehavior =
true;
19139 assert(
Val.isLValue());
19165 IK_ICEIfUnevaluated,
19181static ICEDiag
Worst(ICEDiag A, ICEDiag B) {
return A.Kind >= B.Kind ? A : B; }
19188 Info.InConstantContext =
true;
19197 assert(!E->
isValueDependent() &&
"Should not see value dependent exprs!");
19202#define ABSTRACT_STMT(Node)
19203#define STMT(Node, Base) case Expr::Node##Class:
19204#define EXPR(Node, Base)
19205#include "clang/AST/StmtNodes.inc"
19206 case Expr::PredefinedExprClass:
19207 case Expr::FloatingLiteralClass:
19208 case Expr::ImaginaryLiteralClass:
19209 case Expr::StringLiteralClass:
19210 case Expr::ArraySubscriptExprClass:
19211 case Expr::MatrixSubscriptExprClass:
19212 case Expr::ArraySectionExprClass:
19213 case Expr::OMPArrayShapingExprClass:
19214 case Expr::OMPIteratorExprClass:
19215 case Expr::MemberExprClass:
19216 case Expr::CompoundAssignOperatorClass:
19217 case Expr::CompoundLiteralExprClass:
19218 case Expr::ExtVectorElementExprClass:
19219 case Expr::DesignatedInitExprClass:
19220 case Expr::ArrayInitLoopExprClass:
19221 case Expr::ArrayInitIndexExprClass:
19222 case Expr::NoInitExprClass:
19223 case Expr::DesignatedInitUpdateExprClass:
19224 case Expr::ImplicitValueInitExprClass:
19225 case Expr::ParenListExprClass:
19226 case Expr::VAArgExprClass:
19227 case Expr::AddrLabelExprClass:
19228 case Expr::StmtExprClass:
19229 case Expr::CXXMemberCallExprClass:
19230 case Expr::CUDAKernelCallExprClass:
19231 case Expr::CXXAddrspaceCastExprClass:
19232 case Expr::CXXDynamicCastExprClass:
19233 case Expr::CXXTypeidExprClass:
19234 case Expr::CXXUuidofExprClass:
19235 case Expr::MSPropertyRefExprClass:
19236 case Expr::MSPropertySubscriptExprClass:
19237 case Expr::CXXNullPtrLiteralExprClass:
19238 case Expr::UserDefinedLiteralClass:
19239 case Expr::CXXThisExprClass:
19240 case Expr::CXXThrowExprClass:
19241 case Expr::CXXNewExprClass:
19242 case Expr::CXXDeleteExprClass:
19243 case Expr::CXXPseudoDestructorExprClass:
19244 case Expr::UnresolvedLookupExprClass:
19245 case Expr::RecoveryExprClass:
19246 case Expr::DependentScopeDeclRefExprClass:
19247 case Expr::CXXConstructExprClass:
19248 case Expr::CXXInheritedCtorInitExprClass:
19249 case Expr::CXXStdInitializerListExprClass:
19250 case Expr::CXXBindTemporaryExprClass:
19251 case Expr::ExprWithCleanupsClass:
19252 case Expr::CXXTemporaryObjectExprClass:
19253 case Expr::CXXUnresolvedConstructExprClass:
19254 case Expr::CXXDependentScopeMemberExprClass:
19255 case Expr::UnresolvedMemberExprClass:
19256 case Expr::ObjCStringLiteralClass:
19257 case Expr::ObjCBoxedExprClass:
19258 case Expr::ObjCArrayLiteralClass:
19259 case Expr::ObjCDictionaryLiteralClass:
19260 case Expr::ObjCEncodeExprClass:
19261 case Expr::ObjCMessageExprClass:
19262 case Expr::ObjCSelectorExprClass:
19263 case Expr::ObjCProtocolExprClass:
19264 case Expr::ObjCIvarRefExprClass:
19265 case Expr::ObjCPropertyRefExprClass:
19266 case Expr::ObjCSubscriptRefExprClass:
19267 case Expr::ObjCIsaExprClass:
19268 case Expr::ObjCAvailabilityCheckExprClass:
19269 case Expr::ShuffleVectorExprClass:
19270 case Expr::ConvertVectorExprClass:
19271 case Expr::BlockExprClass:
19273 case Expr::OpaqueValueExprClass:
19274 case Expr::PackExpansionExprClass:
19275 case Expr::SubstNonTypeTemplateParmPackExprClass:
19276 case Expr::FunctionParmPackExprClass:
19277 case Expr::AsTypeExprClass:
19278 case Expr::ObjCIndirectCopyRestoreExprClass:
19279 case Expr::MaterializeTemporaryExprClass:
19280 case Expr::PseudoObjectExprClass:
19281 case Expr::AtomicExprClass:
19282 case Expr::LambdaExprClass:
19283 case Expr::CXXFoldExprClass:
19284 case Expr::CoawaitExprClass:
19285 case Expr::DependentCoawaitExprClass:
19286 case Expr::CoyieldExprClass:
19287 case Expr::SYCLUniqueStableNameExprClass:
19288 case Expr::CXXParenListInitExprClass:
19289 case Expr::HLSLOutArgExprClass:
19292 case Expr::InitListExprClass: {
19303 case Expr::SizeOfPackExprClass:
19304 case Expr::GNUNullExprClass:
19305 case Expr::SourceLocExprClass:
19306 case Expr::EmbedExprClass:
19307 case Expr::OpenACCAsteriskSizeExprClass:
19310 case Expr::PackIndexingExprClass:
19313 case Expr::SubstNonTypeTemplateParmExprClass:
19317 case Expr::ConstantExprClass:
19320 case Expr::ParenExprClass:
19322 case Expr::GenericSelectionExprClass:
19324 case Expr::IntegerLiteralClass:
19325 case Expr::FixedPointLiteralClass:
19326 case Expr::CharacterLiteralClass:
19327 case Expr::ObjCBoolLiteralExprClass:
19328 case Expr::CXXBoolLiteralExprClass:
19329 case Expr::CXXScalarValueInitExprClass:
19330 case Expr::TypeTraitExprClass:
19331 case Expr::ConceptSpecializationExprClass:
19332 case Expr::RequiresExprClass:
19333 case Expr::ArrayTypeTraitExprClass:
19334 case Expr::ExpressionTraitExprClass:
19335 case Expr::CXXNoexceptExprClass:
19337 case Expr::CallExprClass:
19338 case Expr::CXXOperatorCallExprClass: {
19347 case Expr::CXXRewrittenBinaryOperatorClass:
19350 case Expr::DeclRefExprClass: {
19364 const VarDecl *VD = dyn_cast<VarDecl>(D);
19371 case Expr::UnaryOperatorClass: {
19394 llvm_unreachable(
"invalid unary operator class");
19396 case Expr::OffsetOfExprClass: {
19405 case Expr::UnaryExprOrTypeTraitExprClass: {
19407 if ((Exp->
getKind() == UETT_SizeOf) &&
19410 if (Exp->
getKind() == UETT_CountOf) {
19417 if (VAT->getElementType()->isArrayType())
19429 case Expr::BinaryOperatorClass: {
19474 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE) {
19477 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
19478 if (REval.isSigned() && REval.isAllOnes()) {
19480 if (LEval.isMinSignedValue())
19481 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
19489 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE)
19490 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
19496 return Worst(LHSResult, RHSResult);
19502 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICEIfUnevaluated) {
19512 return Worst(LHSResult, RHSResult);
19515 llvm_unreachable(
"invalid binary operator kind");
19517 case Expr::ImplicitCastExprClass:
19518 case Expr::CStyleCastExprClass:
19519 case Expr::CXXFunctionalCastExprClass:
19520 case Expr::CXXStaticCastExprClass:
19521 case Expr::CXXReinterpretCastExprClass:
19522 case Expr::CXXConstCastExprClass:
19523 case Expr::ObjCBridgedCastExprClass: {
19530 APSInt IgnoredVal(DestWidth, !DestSigned);
19535 if (FL->getValue().convertToInteger(IgnoredVal,
19536 llvm::APFloat::rmTowardZero,
19537 &Ignored) & APFloat::opInvalidOp)
19543 case CK_LValueToRValue:
19544 case CK_AtomicToNonAtomic:
19545 case CK_NonAtomicToAtomic:
19547 case CK_IntegralToBoolean:
19548 case CK_IntegralCast:
19554 case Expr::BinaryConditionalOperatorClass: {
19557 if (CommonResult.Kind == IK_NotICE)
return CommonResult;
19559 if (FalseResult.Kind == IK_NotICE)
return FalseResult;
19560 if (CommonResult.Kind == IK_ICEIfUnevaluated)
return CommonResult;
19561 if (FalseResult.Kind == IK_ICEIfUnevaluated &&
19563 return FalseResult;
19565 case Expr::ConditionalOperatorClass: {
19573 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
19576 if (CondResult.Kind == IK_NotICE)
19582 if (TrueResult.Kind == IK_NotICE)
19584 if (FalseResult.Kind == IK_NotICE)
19585 return FalseResult;
19586 if (CondResult.Kind == IK_ICEIfUnevaluated)
19588 if (TrueResult.Kind == IK_ICE && FalseResult.Kind == IK_ICE)
19594 return FalseResult;
19597 case Expr::CXXDefaultArgExprClass:
19599 case Expr::CXXDefaultInitExprClass:
19601 case Expr::ChooseExprClass: {
19604 case Expr::BuiltinBitCastExprClass: {
19605 if (!checkBitCastConstexprEligibility(
nullptr, Ctx,
cast<CastExpr>(E)))
19611 llvm_unreachable(
"Invalid StmtClass!");
19617 llvm::APSInt *
Value) {
19625 if (!Result.isInt())
19634 "Expression evaluator can't be called on a dependent expression.");
19636 ExprTimeTraceScope TimeScope(
this, Ctx,
"isIntegerConstantExpr");
19642 if (D.Kind != IK_ICE)
19647std::optional<llvm::APSInt>
19651 return std::nullopt;
19658 return std::nullopt;
19662 return std::nullopt;
19671 Info.InConstantContext =
true;
19674 llvm_unreachable(
"ICE cannot be evaluated!");
19681 "Expression evaluator can't be called on a dependent expression.");
19683 return CheckICE(
this, Ctx).Kind == IK_ICE;
19688 "Expression evaluator can't be called on a dependent expression.");
19705 Status.Diag = &Diags;
19712 Info.discardCleanups() && !Status.HasSideEffects;
19714 return IsConstExpr && Diags.empty();
19722 "Expression evaluator can't be called on a dependent expression.");
19724 llvm::TimeTraceScope TimeScope(
"EvaluateWithSubstitution", [&] {
19726 llvm::raw_string_ostream OS(Name);
19734 Info.InConstantContext =
true;
19737 const LValue *ThisPtr =
nullptr;
19740 auto *MD = dyn_cast<CXXMethodDecl>(Callee);
19741 assert(MD &&
"Don't provide `this` for non-methods.");
19742 assert(MD->isImplicitObjectMemberFunction() &&
19743 "Don't provide `this` for methods without an implicit object.");
19745 if (!
This->isValueDependent() &&
19748 ThisPtr = &ThisVal;
19755 CallRef
Call = Info.CurrentCall->createCall(Callee);
19758 unsigned Idx = I - Args.begin();
19759 if (Idx >= Callee->getNumParams())
19761 const ParmVarDecl *PVD = Callee->getParamDecl(Idx);
19762 if ((*I)->isValueDependent() ||
19766 if (
APValue *Slot = Info.getParamSlot(
Call, PVD))
19777 Info.discardCleanups();
19781 CallStackFrame Frame(Info, Callee->getLocation(), Callee, ThisPtr,
This,
19784 FullExpressionRAII
Scope(Info);
19798 llvm::TimeTraceScope TimeScope(
"isPotentialConstantExpr", [&] {
19800 llvm::raw_string_ostream OS(Name);
19807 Status.
Diag = &Diags;
19811 Info.InConstantContext =
true;
19812 Info.CheckingPotentialConstantExpression =
true;
19815 if (Info.EnableNewConstInterp) {
19817 return Diags.empty();
19828 This.set({&VIE, Info.CurrentCall->Index});
19836 Info.setEvaluatingDecl(
This.getLValueBase(), Scratch);
19842 &VIE, Args, CallRef(), FD->
getBody(), Info, Scratch,
19846 return Diags.empty();
19854 "Expression evaluator can't be called on a dependent expression.");
19857 Status.
Diag = &Diags;
19861 Info.InConstantContext =
true;
19862 Info.CheckingPotentialConstantExpression =
true;
19864 if (Info.EnableNewConstInterp) {
19866 return Diags.empty();
19871 nullptr, CallRef());
19875 return Diags.empty();
19879 unsigned Type)
const {
19880 if (!
getType()->isPointerType())
19889 EvalInfo &Info, std::string *StringResult) {
19901 if (
const StringLiteral *S = dyn_cast_or_null<StringLiteral>(
19902 String.getLValueBase().dyn_cast<
const Expr *>())) {
19905 if (Off >= 0 && (uint64_t)Off <= (uint64_t)Str.size() &&
19909 Str = Str.substr(Off);
19911 StringRef::size_type Pos = Str.find(0);
19912 if (Pos != StringRef::npos)
19913 Str = Str.substr(0, Pos);
19915 Result = Str.size();
19917 *StringResult = Str;
19925 for (uint64_t Strlen = 0; ; ++Strlen) {
19933 }
else if (StringResult)
19934 StringResult->push_back(Char.
getInt().getExtValue());
19944 std::string StringResult;
19946 if (Info.EnableNewConstInterp) {
19948 return std::nullopt;
19949 return StringResult;
19953 return StringResult;
19954 return std::nullopt;
19957template <
typename T>
19959 const Expr *SizeExpression,
19960 const Expr *PtrExpression,
19964 Info.InConstantContext =
true;
19966 if (Info.EnableNewConstInterp)
19968 PtrExpression, Result);
19971 FullExpressionRAII
Scope(Info);
19976 uint64_t Size = SizeValue.getZExtValue();
19979 if constexpr (std::is_same_v<APValue, T>)
19982 if (Size < Result.max_size())
19983 Result.reserve(Size);
19989 for (uint64_t I = 0; I < Size; ++I) {
19995 if constexpr (std::is_same_v<APValue, T>) {
19996 Result.getArrayInitializedElt(I) = std::move(Char);
20000 assert(
C.getBitWidth() <= 8 &&
20001 "string element not representable in char");
20003 Result.push_back(
static_cast<char>(
C.getExtValue()));
20014 const Expr *SizeExpression,
20018 PtrExpression, Ctx, Status);
20022 const Expr *SizeExpression,
20026 PtrExpression, Ctx, Status);
20033 if (Info.EnableNewConstInterp)
20040struct IsWithinLifetimeHandler {
20043 using result_type = std::optional<bool>;
20044 std::optional<bool> failed() {
return std::nullopt; }
20045 template <
typename T>
20046 std::optional<bool> found(
T &Subobj,
QualType SubobjType) {
20051std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &IEE,
20052 const CallExpr *E) {
20053 EvalInfo &Info = IEE.Info;
20058 if (!Info.InConstantContext)
20059 return std::nullopt;
20061 const Expr *Arg = E->
getArg(0);
20063 return std::nullopt;
20066 return std::nullopt;
20068 if (Val.allowConstexprUnknown())
20072 bool CalledFromStd =
false;
20073 const auto *
Callee = Info.CurrentCall->getCallee();
20074 if (Callee &&
Callee->isInStdNamespace()) {
20075 const IdentifierInfo *Identifier =
Callee->getIdentifier();
20076 CalledFromStd = Identifier && Identifier->
isStr(
"is_within_lifetime");
20078 Info.CCEDiag(CalledFromStd ? Info.CurrentCall->getCallRange().getBegin()
20080 diag::err_invalid_is_within_lifetime)
20081 << (CalledFromStd ?
"std::is_within_lifetime"
20082 :
"__builtin_is_within_lifetime")
20084 return std::nullopt;
20094 if (Val.isNullPointer() || Val.getLValueBase().isNull())
20096 QualType
T = Val.getLValueBase().getType();
20098 "Pointers to functions should have been typed as function pointers "
20099 "which would have been rejected earlier");
20102 if (Val.getLValueDesignator().isOnePastTheEnd())
20104 assert(Val.getLValueDesignator().isValidSubobject() &&
20105 "Unchecked case for valid subobject");
20109 CompleteObject CO =
20113 if (Info.EvaluatingDeclValue && CO.Value == Info.EvaluatingDeclValue)
20118 IsWithinLifetimeHandler handler{Info};
20119 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 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 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 evalPshufbBuiltin(EvalInfo &Info, const CallExpr *Call, APValue &Out)
static ICEDiag CheckEvalInICE(const Expr *E, const ASTContext &Ctx)
static llvm::APInt ConvertBoolVectorToInt(const APValue &Val)
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 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 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 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 evalPshufBuiltin(EvalInfo &Info, const CallExpr *Call, bool IsShufHW, APValue &Out)
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 evalShuffleGeneric(EvalInfo &Info, const CallExpr *Call, APValue &Out, llvm::function_ref< std::pair< unsigned, unsigned >(unsigned, unsigned)> GetSourceIndex)
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<=>,...
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)