57#include "llvm/ADT/APFixedPoint.h"
58#include "llvm/ADT/Sequence.h"
59#include "llvm/ADT/SmallBitVector.h"
60#include "llvm/ADT/StringExtras.h"
61#include "llvm/Support/Casting.h"
62#include "llvm/Support/Debug.h"
63#include "llvm/Support/SaveAndRestore.h"
64#include "llvm/Support/SipHash.h"
65#include "llvm/Support/TimeProfiler.h"
66#include "llvm/Support/raw_ostream.h"
72#define DEBUG_TYPE "exprconstant"
75using llvm::APFixedPoint;
79using llvm::FixedPointSemantics;
86 using SourceLocExprScopeGuard =
121 static const CallExpr *tryUnwrapAllocSizeCall(
const Expr *E) {
129 if (
const auto *FE = dyn_cast<FullExpr>(E))
132 if (
const auto *Cast = dyn_cast<CastExpr>(E))
133 E = Cast->getSubExpr()->IgnoreParens();
135 if (
const auto *CE = dyn_cast<CallExpr>(E))
136 return CE->getCalleeAllocSizeAttr() ? CE :
nullptr;
143 const auto *E =
Base.dyn_cast<
const Expr *>();
144 return E && E->getType()->isPointerType() && tryUnwrapAllocSizeCall(E);
152 case ConstantExprKind::Normal:
153 case ConstantExprKind::ClassTemplateArgument:
154 case ConstantExprKind::ImmediateInvocation:
159 case ConstantExprKind::NonClassTemplateArgument:
162 llvm_unreachable(
"unknown ConstantExprKind");
167 case ConstantExprKind::Normal:
168 case ConstantExprKind::ImmediateInvocation:
171 case ConstantExprKind::ClassTemplateArgument:
172 case ConstantExprKind::NonClassTemplateArgument:
175 llvm_unreachable(
"unknown ConstantExprKind");
181 static const uint64_t AssumedSizeForUnsizedArray =
182 std::numeric_limits<uint64_t>::max() / 2;
192 bool &FirstEntryIsUnsizedArray) {
195 assert(!isBaseAnAllocSizeCall(
Base) &&
196 "Unsized arrays shouldn't appear here");
197 unsigned MostDerivedLength = 0;
202 for (
unsigned I = 0, N = Path.size(); I != N; ++I) {
206 MostDerivedLength = I + 1;
209 if (
auto *CAT = dyn_cast<ConstantArrayType>(AT)) {
210 ArraySize = CAT->getZExtSize();
212 assert(I == 0 &&
"unexpected unsized array designator");
213 FirstEntryIsUnsizedArray =
true;
214 ArraySize = AssumedSizeForUnsizedArray;
220 MostDerivedLength = I + 1;
223 Type = VT->getElementType();
224 ArraySize = VT->getNumElements();
225 MostDerivedLength = I + 1;
227 }
else if (
const FieldDecl *FD = getAsField(Path[I])) {
228 Type = FD->getType();
230 MostDerivedLength = I + 1;
238 return MostDerivedLength;
242 struct SubobjectDesignator {
246 LLVM_PREFERRED_TYPE(
bool)
250 LLVM_PREFERRED_TYPE(
bool)
251 unsigned IsOnePastTheEnd : 1;
254 LLVM_PREFERRED_TYPE(
bool)
255 unsigned FirstEntryIsAnUnsizedArray : 1;
258 LLVM_PREFERRED_TYPE(
bool)
259 unsigned MostDerivedIsArrayElement : 1;
263 unsigned MostDerivedPathLength : 28;
272 uint64_t MostDerivedArraySize;
281 SubobjectDesignator() :
Invalid(
true) {}
284 :
Invalid(
false), IsOnePastTheEnd(
false),
285 FirstEntryIsAnUnsizedArray(
false), MostDerivedIsArrayElement(
false),
286 MostDerivedPathLength(0), MostDerivedArraySize(0),
287 MostDerivedType(
T.isNull() ?
QualType() :
T.getNonReferenceType()) {}
290 :
Invalid(!
V.isLValue() || !
V.hasLValuePath()), IsOnePastTheEnd(
false),
291 FirstEntryIsAnUnsizedArray(
false), MostDerivedIsArrayElement(
false),
292 MostDerivedPathLength(0), MostDerivedArraySize(0) {
293 assert(
V.isLValue() &&
"Non-LValue used to make an LValue designator?");
295 IsOnePastTheEnd =
V.isLValueOnePastTheEnd();
296 llvm::append_range(Entries,
V.getLValuePath());
297 if (
V.getLValueBase()) {
298 bool IsArray =
false;
299 bool FirstIsUnsizedArray =
false;
300 MostDerivedPathLength = findMostDerivedSubobject(
301 Ctx,
V.getLValueBase(),
V.getLValuePath(), MostDerivedArraySize,
302 MostDerivedType, IsArray, FirstIsUnsizedArray);
303 MostDerivedIsArrayElement = IsArray;
304 FirstEntryIsAnUnsizedArray = FirstIsUnsizedArray;
310 unsigned NewLength) {
314 assert(
Base &&
"cannot truncate path for null pointer");
315 assert(NewLength <= Entries.size() &&
"not a truncation");
317 if (NewLength == Entries.size())
319 Entries.resize(NewLength);
321 bool IsArray =
false;
322 bool FirstIsUnsizedArray =
false;
323 MostDerivedPathLength = findMostDerivedSubobject(
324 Ctx,
Base, Entries, MostDerivedArraySize, MostDerivedType, IsArray,
325 FirstIsUnsizedArray);
326 MostDerivedIsArrayElement = IsArray;
327 FirstEntryIsAnUnsizedArray = FirstIsUnsizedArray;
337 bool isMostDerivedAnUnsizedArray()
const {
338 assert(!
Invalid &&
"Calling this makes no sense on invalid designators");
339 return Entries.size() == 1 && FirstEntryIsAnUnsizedArray;
344 uint64_t getMostDerivedArraySize()
const {
345 assert(!isMostDerivedAnUnsizedArray() &&
"Unsized array has no size");
346 return MostDerivedArraySize;
350 bool isOnePastTheEnd()
const {
354 if (!isMostDerivedAnUnsizedArray() && MostDerivedIsArrayElement &&
355 Entries[MostDerivedPathLength - 1].getAsArrayIndex() ==
356 MostDerivedArraySize)
364 std::pair<uint64_t, uint64_t> validIndexAdjustments() {
365 if (
Invalid || isMostDerivedAnUnsizedArray())
371 bool IsArray = MostDerivedPathLength == Entries.size() &&
372 MostDerivedIsArrayElement;
373 uint64_t ArrayIndex = IsArray ? Entries.back().getAsArrayIndex()
374 : (uint64_t)IsOnePastTheEnd;
376 IsArray ? getMostDerivedArraySize() : (uint64_t)1;
377 return {ArrayIndex, ArraySize - ArrayIndex};
381 bool isValidSubobject()
const {
384 return !isOnePastTheEnd();
392 assert(!
Invalid &&
"invalid designator has no subobject type");
393 return MostDerivedPathLength == Entries.size()
404 MostDerivedIsArrayElement =
true;
406 MostDerivedPathLength = Entries.size();
410 void addUnsizedArrayUnchecked(
QualType ElemTy) {
413 MostDerivedType = ElemTy;
414 MostDerivedIsArrayElement =
true;
418 MostDerivedArraySize = AssumedSizeForUnsizedArray;
419 MostDerivedPathLength = Entries.size();
423 void addDeclUnchecked(
const Decl *D,
bool Virtual =
false) {
427 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
428 MostDerivedType = FD->getType();
429 MostDerivedIsArrayElement =
false;
430 MostDerivedArraySize = 0;
431 MostDerivedPathLength = Entries.size();
435 void addComplexUnchecked(
QualType EltTy,
bool Imag) {
440 MostDerivedType = EltTy;
441 MostDerivedIsArrayElement =
true;
442 MostDerivedArraySize = 2;
443 MostDerivedPathLength = Entries.size();
446 void addVectorElementUnchecked(
QualType EltTy, uint64_t Size,
449 MostDerivedType = EltTy;
450 MostDerivedPathLength = Entries.size();
451 MostDerivedArraySize = 0;
452 MostDerivedIsArrayElement =
false;
455 void diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info,
const Expr *E);
456 void diagnosePointerArithmetic(EvalInfo &Info,
const Expr *E,
459 void adjustIndex(EvalInfo &Info,
const Expr *E,
APSInt N,
const LValue &LV);
463 enum class ScopeKind {
471 CallRef() : OrigCallee(), CallIndex(0), Version() {}
472 CallRef(
const FunctionDecl *Callee,
unsigned CallIndex,
unsigned Version)
473 : OrigCallee(Callee), CallIndex(CallIndex), Version(Version) {}
475 explicit operator bool()
const {
return OrigCallee; }
501 CallStackFrame *Caller;
523 typedef std::pair<const void *, unsigned> MapKeyTy;
524 typedef std::map<MapKeyTy, APValue>
MapTy;
536 unsigned CurTempVersion = TempVersionStack.back();
538 unsigned getTempVersion()
const {
return TempVersionStack.back(); }
540 void pushTempVersion() {
541 TempVersionStack.push_back(++CurTempVersion);
544 void popTempVersion() {
545 TempVersionStack.pop_back();
549 return {Callee, Index, ++CurTempVersion};
560 llvm::DenseMap<const ValueDecl *, FieldDecl *> LambdaCaptureFields;
561 FieldDecl *LambdaThisCaptureField =
nullptr;
563 CallStackFrame(EvalInfo &Info,
SourceRange CallRange,
569 APValue *getTemporary(
const void *Key,
unsigned Version) {
570 MapKeyTy KV(Key, Version);
571 auto LB = Temporaries.lower_bound(KV);
572 if (LB != Temporaries.end() && LB->first == KV)
578 APValue *getCurrentTemporary(
const void *Key) {
579 auto UB = Temporaries.upper_bound(MapKeyTy(Key,
UINT_MAX));
580 if (UB != Temporaries.begin() && std::prev(UB)->first.first == Key)
581 return &std::prev(UB)->second;
586 unsigned getCurrentTemporaryVersion(
const void *Key)
const {
587 auto UB = Temporaries.upper_bound(MapKeyTy(Key,
UINT_MAX));
588 if (UB != Temporaries.begin() && std::prev(UB)->first.first == Key)
589 return std::prev(UB)->first.second;
597 template<
typename KeyT>
599 ScopeKind
Scope, LValue &LV);
604 void describe(llvm::raw_ostream &OS)
const override;
606 Frame *getCaller()
const override {
return Caller; }
607 SourceRange getCallRange()
const override {
return CallRange; }
610 bool isStdFunction()
const {
611 for (
const DeclContext *DC = Callee; DC; DC = DC->getParent())
612 if (DC->isStdNamespace())
619 bool CanEvalMSConstexpr =
false;
627 class ThisOverrideRAII {
629 ThisOverrideRAII(CallStackFrame &Frame,
const LValue *NewThis,
bool Enable)
630 : Frame(Frame), OldThis(Frame.This) {
632 Frame.This = NewThis;
634 ~ThisOverrideRAII() {
635 Frame.This = OldThis;
638 CallStackFrame &Frame;
639 const LValue *OldThis;
644 class ExprTimeTraceScope {
646 ExprTimeTraceScope(
const Expr *E,
const ASTContext &Ctx, StringRef Name)
647 : TimeScope(Name, [E, &Ctx] {
652 llvm::TimeTraceScope TimeScope;
657 struct MSConstexprContextRAII {
658 CallStackFrame &Frame;
660 explicit MSConstexprContextRAII(CallStackFrame &Frame,
bool Value)
661 : Frame(Frame), OldValue(Frame.CanEvalMSConstexpr) {
662 Frame.CanEvalMSConstexpr =
Value;
665 ~MSConstexprContextRAII() { Frame.CanEvalMSConstexpr = OldValue; }
678 llvm::PointerIntPair<APValue*, 2, ScopeKind> Value;
679 APValue::LValueBase Base;
683 Cleanup(
APValue *Val, APValue::LValueBase Base, QualType T,
685 : Value(Val, Scope), Base(Base), T(T) {}
689 bool isDestroyedAtEndOf(ScopeKind K)
const {
690 return (
int)Value.getInt() >= (
int)K;
692 bool endLifetime(EvalInfo &Info,
bool RunDestructors) {
693 if (RunDestructors) {
695 if (
const ValueDecl *VD = Base.dyn_cast<
const ValueDecl*>())
696 Loc = VD->getLocation();
697 else if (
const Expr *E = Base.dyn_cast<
const Expr*>())
698 Loc = E->getExprLoc();
701 *Value.getPointer() =
APValue();
705 bool hasSideEffect() {
706 return T.isDestructedType();
711 struct ObjectUnderConstruction {
712 APValue::LValueBase Base;
713 ArrayRef<APValue::LValuePathEntry> Path;
714 friend bool operator==(
const ObjectUnderConstruction &LHS,
715 const ObjectUnderConstruction &RHS) {
716 return LHS.Base == RHS.Base && LHS.Path == RHS.Path;
718 friend llvm::hash_code
hash_value(
const ObjectUnderConstruction &Obj) {
719 return llvm::hash_combine(Obj.Base, Obj.Path);
722 enum class ConstructionPhase {
733template<>
struct DenseMapInfo<ObjectUnderConstruction> {
734 using Base = DenseMapInfo<APValue::LValueBase>;
736 return {Base::getEmptyKey(), {}}; }
738 return {Base::getTombstoneKey(), {}};
743 static bool isEqual(
const ObjectUnderConstruction &LHS,
744 const ObjectUnderConstruction &RHS) {
758 const Expr *AllocExpr =
nullptr;
769 if (
auto *NE = dyn_cast<CXXNewExpr>(AllocExpr))
770 return NE->isArray() ? ArrayNew : New;
776 struct DynAllocOrder {
777 bool operator()(DynamicAllocLValue L, DynamicAllocLValue R)
const {
801 Expr::EvalStatus &EvalStatus;
804 CallStackFrame *CurrentCall;
807 unsigned CallStackDepth;
810 unsigned NextCallIndex;
819 bool EnableNewConstInterp;
823 CallStackFrame BottomFrame;
827 llvm::SmallVector<Cleanup, 16> CleanupStack;
831 APValue::LValueBase EvaluatingDecl;
833 enum class EvaluatingDeclKind {
840 EvaluatingDeclKind IsEvaluatingDecl = EvaluatingDeclKind::None;
849 SmallVector<const Stmt *> BreakContinueStack;
852 llvm::DenseMap<ObjectUnderConstruction, ConstructionPhase>
853 ObjectsUnderConstruction;
858 std::map<DynamicAllocLValue, DynAlloc, DynAllocOrder> HeapAllocs;
861 unsigned NumHeapAllocs = 0;
863 struct EvaluatingConstructorRAII {
865 ObjectUnderConstruction Object;
867 EvaluatingConstructorRAII(EvalInfo &EI, ObjectUnderConstruction Object,
869 : EI(EI), Object(Object) {
871 EI.ObjectsUnderConstruction
872 .insert({Object, HasBases ? ConstructionPhase::Bases
873 : ConstructionPhase::AfterBases})
876 void finishedConstructingBases() {
877 EI.ObjectsUnderConstruction[Object] = ConstructionPhase::AfterBases;
879 void finishedConstructingFields() {
880 EI.ObjectsUnderConstruction[Object] = ConstructionPhase::AfterFields;
882 ~EvaluatingConstructorRAII() {
883 if (DidInsert) EI.ObjectsUnderConstruction.erase(Object);
887 struct EvaluatingDestructorRAII {
889 ObjectUnderConstruction Object;
891 EvaluatingDestructorRAII(EvalInfo &EI, ObjectUnderConstruction Object)
892 : EI(EI), Object(Object) {
893 DidInsert = EI.ObjectsUnderConstruction
894 .insert({Object, ConstructionPhase::Destroying})
897 void startedDestroyingBases() {
898 EI.ObjectsUnderConstruction[Object] =
899 ConstructionPhase::DestroyingBases;
901 ~EvaluatingDestructorRAII() {
903 EI.ObjectsUnderConstruction.erase(Object);
908 isEvaluatingCtorDtor(APValue::LValueBase Base,
909 ArrayRef<APValue::LValuePathEntry> Path) {
910 return ObjectsUnderConstruction.lookup({
Base, Path});
915 unsigned SpeculativeEvaluationDepth = 0;
923 bool HasActiveDiagnostic;
927 bool HasFoldFailureDiagnostic;
929 EvalInfo(
const ASTContext &
C, Expr::EvalStatus &S,
EvaluationMode Mode)
930 : Ctx(const_cast<ASTContext &>(
C)), EvalStatus(S), CurrentCall(
nullptr),
931 CallStackDepth(0), NextCallIndex(1),
932 StepsLeft(
C.getLangOpts().ConstexprStepLimit),
933 EnableNewConstInterp(
C.getLangOpts().EnableNewConstInterp),
934 BottomFrame(*this, SourceLocation(),
nullptr,
937 EvaluatingDecl((const ValueDecl *)
nullptr),
938 EvaluatingDeclValue(
nullptr), HasActiveDiagnostic(
false),
939 HasFoldFailureDiagnostic(
false) {
947 ASTContext &getASTContext()
const override {
return Ctx; }
948 const LangOptions &getLangOpts()
const {
return Ctx.getLangOpts(); }
950 void setEvaluatingDecl(APValue::LValueBase Base,
APValue &
Value,
951 EvaluatingDeclKind EDK = EvaluatingDeclKind::Ctor) {
952 EvaluatingDecl =
Base;
953 IsEvaluatingDecl = EDK;
954 EvaluatingDeclValue = &
Value;
957 bool CheckCallLimit(SourceLocation Loc) {
960 if (checkingPotentialConstantExpression() && CallStackDepth > 1)
962 if (NextCallIndex == 0) {
964 FFDiag(Loc, diag::note_constexpr_call_limit_exceeded);
967 if (CallStackDepth <= getLangOpts().ConstexprCallDepth)
969 FFDiag(Loc, diag::note_constexpr_depth_limit_exceeded)
970 << getLangOpts().ConstexprCallDepth;
975 uint64_t ElemCount,
bool Diag) {
981 ElemCount >
uint64_t(std::numeric_limits<unsigned>::max())) {
983 FFDiag(Loc, diag::note_constexpr_new_too_large) << ElemCount;
992 uint64_t Limit = Ctx.getLangOpts().ConstexprStepLimit;
993 if (ElemCount > Limit) {
995 FFDiag(Loc, diag::note_constexpr_new_exceeds_limits)
996 << ElemCount << Limit;
1002 std::pair<CallStackFrame *, unsigned>
1003 getCallFrameAndDepth(
unsigned CallIndex) {
1004 assert(CallIndex &&
"no call index in getCallFrameAndDepth");
1007 unsigned Depth = CallStackDepth;
1008 CallStackFrame *Frame = CurrentCall;
1009 while (Frame->Index > CallIndex) {
1010 Frame = Frame->Caller;
1013 if (Frame->Index == CallIndex)
1014 return {Frame, Depth};
1015 return {
nullptr, 0};
1018 bool nextStep(
const Stmt *S) {
1020 FFDiag(S->
getBeginLoc(), diag::note_constexpr_step_limit_exceeded);
1027 APValue *createHeapAlloc(
const Expr *E, QualType
T, LValue &LV);
1029 std::optional<DynAlloc *> lookupDynamicAlloc(DynamicAllocLValue DA) {
1030 std::optional<DynAlloc *>
Result;
1031 auto It = HeapAllocs.find(DA);
1032 if (It != HeapAllocs.end())
1038 APValue *getParamSlot(CallRef
Call,
const ParmVarDecl *PVD) {
1039 CallStackFrame *Frame = getCallFrameAndDepth(
Call.CallIndex).first;
1040 return Frame ? Frame->getTemporary(
Call.getOrigParam(PVD),
Call.Version)
1045 struct StdAllocatorCaller {
1046 unsigned FrameIndex;
1049 explicit operator bool()
const {
return FrameIndex != 0; };
1052 StdAllocatorCaller getStdAllocatorCaller(StringRef FnName)
const {
1053 for (
const CallStackFrame *
Call = CurrentCall;
Call != &BottomFrame;
1055 const auto *MD = dyn_cast_or_null<CXXMethodDecl>(
Call->Callee);
1058 const IdentifierInfo *FnII = MD->getIdentifier();
1059 if (!FnII || !FnII->
isStr(FnName))
1063 dyn_cast<ClassTemplateSpecializationDecl>(MD->getParent());
1067 const IdentifierInfo *ClassII = CTSD->getIdentifier();
1068 const TemplateArgumentList &TAL = CTSD->getTemplateArgs();
1069 if (CTSD->isInStdNamespace() && ClassII &&
1070 ClassII->
isStr(
"allocator") && TAL.
size() >= 1 &&
1072 return {
Call->Index, TAL[0].getAsType(),
Call->CallExpr};
1078 void performLifetimeExtension() {
1080 llvm::erase_if(CleanupStack, [](Cleanup &
C) {
1081 return !
C.isDestroyedAtEndOf(ScopeKind::FullExpression);
1088 bool discardCleanups() {
1089 for (Cleanup &
C : CleanupStack) {
1090 if (
C.hasSideEffect() && !noteSideEffect()) {
1091 CleanupStack.clear();
1095 CleanupStack.clear();
1100 interp::Frame *getCurrentFrame()
override {
return CurrentCall; }
1101 const interp::Frame *getBottomFrame()
const override {
return &BottomFrame; }
1103 bool hasActiveDiagnostic()
override {
return HasActiveDiagnostic; }
1104 void setActiveDiagnostic(
bool Flag)
override { HasActiveDiagnostic = Flag; }
1106 void setFoldFailureDiagnostic(
bool Flag)
override {
1107 HasFoldFailureDiagnostic = Flag;
1110 Expr::EvalStatus &getEvalStatus()
const override {
return EvalStatus; }
1118 bool hasPriorDiagnostic()
override {
1119 if (!EvalStatus.Diag->empty()) {
1121 case EvaluationMode::ConstantFold:
1122 case EvaluationMode::IgnoreSideEffects:
1123 if (!HasFoldFailureDiagnostic)
1127 case EvaluationMode::ConstantExpression:
1128 case EvaluationMode::ConstantExpressionUnevaluated:
1129 setActiveDiagnostic(
false);
1136 unsigned getCallStackDepth()
override {
return CallStackDepth; }
1141 bool keepEvaluatingAfterSideEffect()
const override {
1143 case EvaluationMode::IgnoreSideEffects:
1146 case EvaluationMode::ConstantExpression:
1147 case EvaluationMode::ConstantExpressionUnevaluated:
1148 case EvaluationMode::ConstantFold:
1151 return checkingPotentialConstantExpression() ||
1152 checkingForUndefinedBehavior();
1154 llvm_unreachable(
"Missed EvalMode case");
1159 bool noteSideEffect()
override {
1160 EvalStatus.HasSideEffects =
true;
1161 return keepEvaluatingAfterSideEffect();
1165 bool keepEvaluatingAfterUndefinedBehavior() {
1167 case EvaluationMode::IgnoreSideEffects:
1168 case EvaluationMode::ConstantFold:
1171 case EvaluationMode::ConstantExpression:
1172 case EvaluationMode::ConstantExpressionUnevaluated:
1173 return checkingForUndefinedBehavior();
1175 llvm_unreachable(
"Missed EvalMode case");
1181 bool noteUndefinedBehavior()
override {
1182 EvalStatus.HasUndefinedBehavior =
true;
1183 return keepEvaluatingAfterUndefinedBehavior();
1188 bool keepEvaluatingAfterFailure()
const override {
1193 case EvaluationMode::ConstantExpression:
1194 case EvaluationMode::ConstantExpressionUnevaluated:
1195 case EvaluationMode::ConstantFold:
1196 case EvaluationMode::IgnoreSideEffects:
1197 return checkingPotentialConstantExpression() ||
1198 checkingForUndefinedBehavior();
1200 llvm_unreachable(
"Missed EvalMode case");
1213 [[nodiscard]]
bool noteFailure() {
1221 bool KeepGoing = keepEvaluatingAfterFailure();
1222 EvalStatus.HasSideEffects |= KeepGoing;
1226 class ArrayInitLoopIndex {
1231 ArrayInitLoopIndex(EvalInfo &Info)
1232 : Info(Info), OuterIndex(Info.ArrayInitIndex) {
1233 Info.ArrayInitIndex = 0;
1235 ~ArrayInitLoopIndex() { Info.ArrayInitIndex = OuterIndex; }
1237 operator uint64_t&() {
return Info.ArrayInitIndex; }
1242 struct FoldConstant {
1245 bool HadNoPriorDiags;
1248 explicit FoldConstant(EvalInfo &Info,
bool Enabled)
1251 HadNoPriorDiags(Info.EvalStatus.
Diag &&
1252 Info.EvalStatus.
Diag->empty() &&
1253 !Info.EvalStatus.HasSideEffects),
1254 OldMode(Info.EvalMode) {
1256 Info.EvalMode = EvaluationMode::ConstantFold;
1258 void keepDiagnostics() { Enabled =
false; }
1260 if (Enabled && HadNoPriorDiags && !Info.EvalStatus.Diag->empty() &&
1261 !Info.EvalStatus.HasSideEffects)
1262 Info.EvalStatus.Diag->clear();
1263 Info.EvalMode = OldMode;
1269 struct IgnoreSideEffectsRAII {
1272 explicit IgnoreSideEffectsRAII(EvalInfo &Info)
1273 : Info(Info), OldMode(Info.EvalMode) {
1274 Info.EvalMode = EvaluationMode::IgnoreSideEffects;
1277 ~IgnoreSideEffectsRAII() { Info.EvalMode = OldMode; }
1282 class SpeculativeEvaluationRAII {
1283 EvalInfo *Info =
nullptr;
1284 Expr::EvalStatus OldStatus;
1285 unsigned OldSpeculativeEvaluationDepth = 0;
1287 void moveFromAndCancel(SpeculativeEvaluationRAII &&
Other) {
1289 OldStatus =
Other.OldStatus;
1290 OldSpeculativeEvaluationDepth =
Other.OldSpeculativeEvaluationDepth;
1291 Other.Info =
nullptr;
1294 void maybeRestoreState() {
1298 Info->EvalStatus = OldStatus;
1299 Info->SpeculativeEvaluationDepth = OldSpeculativeEvaluationDepth;
1303 SpeculativeEvaluationRAII() =
default;
1305 SpeculativeEvaluationRAII(
1306 EvalInfo &Info, SmallVectorImpl<PartialDiagnosticAt> *NewDiag =
nullptr)
1307 : Info(&Info), OldStatus(Info.EvalStatus),
1308 OldSpeculativeEvaluationDepth(Info.SpeculativeEvaluationDepth) {
1309 Info.EvalStatus.Diag = NewDiag;
1310 Info.SpeculativeEvaluationDepth = Info.CallStackDepth + 1;
1313 SpeculativeEvaluationRAII(
const SpeculativeEvaluationRAII &
Other) =
delete;
1314 SpeculativeEvaluationRAII(SpeculativeEvaluationRAII &&
Other) {
1315 moveFromAndCancel(std::move(
Other));
1318 SpeculativeEvaluationRAII &operator=(SpeculativeEvaluationRAII &&
Other) {
1319 maybeRestoreState();
1320 moveFromAndCancel(std::move(
Other));
1324 ~SpeculativeEvaluationRAII() { maybeRestoreState(); }
1329 template<ScopeKind Kind>
1332 unsigned OldStackSize;
1334 ScopeRAII(EvalInfo &Info)
1335 : Info(Info), OldStackSize(Info.CleanupStack.size()) {
1338 Info.CurrentCall->pushTempVersion();
1340 bool destroy(
bool RunDestructors =
true) {
1341 bool OK =
cleanup(Info, RunDestructors, OldStackSize);
1342 OldStackSize = std::numeric_limits<unsigned>::max();
1346 if (OldStackSize != std::numeric_limits<unsigned>::max())
1350 Info.CurrentCall->popTempVersion();
1353 static bool cleanup(EvalInfo &Info,
bool RunDestructors,
1354 unsigned OldStackSize) {
1355 assert(OldStackSize <= Info.CleanupStack.size() &&
1356 "running cleanups out of order?");
1361 for (
unsigned I = Info.CleanupStack.size(); I > OldStackSize; --I) {
1362 if (Info.CleanupStack[I - 1].isDestroyedAtEndOf(Kind)) {
1363 if (!Info.CleanupStack[I - 1].endLifetime(Info, RunDestructors)) {
1371 auto NewEnd = Info.CleanupStack.begin() + OldStackSize;
1372 if (Kind != ScopeKind::Block)
1374 std::remove_if(NewEnd, Info.CleanupStack.end(), [](Cleanup &
C) {
1375 return C.isDestroyedAtEndOf(Kind);
1377 Info.CleanupStack.erase(NewEnd, Info.CleanupStack.end());
1381 typedef ScopeRAII<ScopeKind::Block> BlockScopeRAII;
1382 typedef ScopeRAII<ScopeKind::FullExpression> FullExpressionRAII;
1383 typedef ScopeRAII<ScopeKind::Call> CallScopeRAII;
1386bool SubobjectDesignator::checkSubobject(EvalInfo &Info,
const Expr *E,
1390 if (isOnePastTheEnd()) {
1391 Info.CCEDiag(E, diag::note_constexpr_past_end_subobject)
1402void SubobjectDesignator::diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info,
1404 Info.CCEDiag(E, diag::note_constexpr_unsized_array_indexed);
1409void SubobjectDesignator::diagnosePointerArithmetic(EvalInfo &Info,
1414 if (MostDerivedPathLength == Entries.size() && MostDerivedIsArrayElement)
1415 Info.CCEDiag(E, diag::note_constexpr_array_index)
1417 <<
static_cast<unsigned>(getMostDerivedArraySize());
1419 Info.CCEDiag(E, diag::note_constexpr_array_index)
1424CallStackFrame::CallStackFrame(EvalInfo &Info, SourceRange CallRange,
1425 const FunctionDecl *Callee,
const LValue *This,
1426 const Expr *CallExpr, CallRef Call)
1428 CallExpr(CallExpr),
Arguments(Call), CallRange(CallRange),
1429 Index(Info.NextCallIndex++) {
1430 Info.CurrentCall =
this;
1431 ++Info.CallStackDepth;
1434CallStackFrame::~CallStackFrame() {
1435 assert(Info.CurrentCall ==
this &&
"calls retired out of order");
1436 --Info.CallStackDepth;
1437 Info.CurrentCall = Caller;
1462 llvm_unreachable(
"unknown access kind");
1499 llvm_unreachable(
"unknown access kind");
1503 struct ComplexValue {
1511 ComplexValue() : FloatReal(
APFloat::Bogus()), FloatImag(
APFloat::Bogus()) {}
1513 void makeComplexFloat() { IsInt =
false; }
1514 bool isComplexFloat()
const {
return !IsInt; }
1515 APFloat &getComplexFloatReal() {
return FloatReal; }
1516 APFloat &getComplexFloatImag() {
return FloatImag; }
1518 void makeComplexInt() { IsInt =
true; }
1519 bool isComplexInt()
const {
return IsInt; }
1520 APSInt &getComplexIntReal() {
return IntReal; }
1521 APSInt &getComplexIntImag() {
return IntImag; }
1523 void moveInto(
APValue &v)
const {
1524 if (isComplexFloat())
1525 v =
APValue(FloatReal, FloatImag);
1527 v =
APValue(IntReal, IntImag);
1529 void setFrom(
const APValue &v) {
1544 APValue::LValueBase
Base;
1546 SubobjectDesignator Designator;
1548 bool InvalidBase : 1;
1550 bool AllowConstexprUnknown =
false;
1552 const APValue::LValueBase getLValueBase()
const {
return Base; }
1553 bool allowConstexprUnknown()
const {
return AllowConstexprUnknown; }
1554 CharUnits &getLValueOffset() {
return Offset; }
1555 const CharUnits &getLValueOffset()
const {
return Offset; }
1556 SubobjectDesignator &getLValueDesignator() {
return Designator; }
1557 const SubobjectDesignator &getLValueDesignator()
const {
return Designator;}
1558 bool isNullPointer()
const {
return IsNullPtr;}
1560 unsigned getLValueCallIndex()
const {
return Base.getCallIndex(); }
1561 unsigned getLValueVersion()
const {
return Base.getVersion(); }
1564 if (Designator.Invalid)
1565 V =
APValue(Base, Offset, APValue::NoLValuePath(), IsNullPtr);
1567 assert(!InvalidBase &&
"APValues can't handle invalid LValue bases");
1568 V =
APValue(Base, Offset, Designator.Entries,
1569 Designator.IsOnePastTheEnd, IsNullPtr);
1571 if (AllowConstexprUnknown)
1572 V.setConstexprUnknown();
1574 void setFrom(
const ASTContext &Ctx,
const APValue &
V) {
1575 assert(
V.isLValue() &&
"Setting LValue from a non-LValue?");
1576 Base =
V.getLValueBase();
1577 Offset =
V.getLValueOffset();
1578 InvalidBase =
false;
1579 Designator = SubobjectDesignator(Ctx,
V);
1580 IsNullPtr =
V.isNullPointer();
1581 AllowConstexprUnknown =
V.allowConstexprUnknown();
1584 void set(APValue::LValueBase B,
bool BInvalid =
false) {
1588 const auto *E = B.
get<
const Expr *>();
1590 "Unexpected type of invalid base");
1596 InvalidBase = BInvalid;
1597 Designator = SubobjectDesignator(
getType(B));
1599 AllowConstexprUnknown =
false;
1602 void setNull(ASTContext &Ctx, QualType PointerTy) {
1603 Base = (
const ValueDecl *)
nullptr;
1606 InvalidBase =
false;
1609 AllowConstexprUnknown =
false;
1612 void setInvalid(APValue::LValueBase B,
unsigned I = 0) {
1616 std::string
toString(ASTContext &Ctx, QualType
T)
const {
1618 moveInto(Printable);
1625 template <
typename GenDiagType>
1626 bool checkNullPointerDiagnosingWith(
const GenDiagType &GenDiag) {
1627 if (Designator.Invalid)
1631 Designator.setInvalid();
1638 bool checkNullPointer(EvalInfo &Info,
const Expr *E,
1640 return checkNullPointerDiagnosingWith([&Info, E, CSK] {
1641 Info.CCEDiag(E, diag::note_constexpr_null_subobject) << CSK;
1645 bool checkNullPointerForFoldAccess(EvalInfo &Info,
const Expr *E,
1647 return checkNullPointerDiagnosingWith([&Info, E, AK] {
1648 if (AK == AccessKinds::AK_Dereference)
1649 Info.FFDiag(E, diag::note_constexpr_dereferencing_null);
1651 Info.FFDiag(E, diag::note_constexpr_access_null) << AK;
1659 Designator.checkSubobject(Info, E, CSK);
1662 void addDecl(EvalInfo &Info,
const Expr *E,
1663 const Decl *D,
bool Virtual =
false) {
1665 Designator.addDeclUnchecked(D,
Virtual);
1667 void addUnsizedArray(EvalInfo &Info,
const Expr *E, QualType ElemTy) {
1668 if (!Designator.Entries.empty()) {
1669 Info.CCEDiag(E, diag::note_constexpr_unsupported_unsized_array);
1670 Designator.setInvalid();
1674 assert(
getType(Base).getNonReferenceType()->isPointerType() ||
1675 getType(Base).getNonReferenceType()->isArrayType());
1676 Designator.FirstEntryIsAnUnsizedArray =
true;
1677 Designator.addUnsizedArrayUnchecked(ElemTy);
1680 void addArray(EvalInfo &Info,
const Expr *E,
const ConstantArrayType *CAT) {
1682 Designator.addArrayUnchecked(CAT);
1684 void addComplex(EvalInfo &Info,
const Expr *E, QualType EltTy,
bool Imag) {
1686 Designator.addComplexUnchecked(EltTy, Imag);
1688 void addVectorElement(EvalInfo &Info,
const Expr *E, QualType EltTy,
1689 uint64_t Size, uint64_t Idx) {
1691 Designator.addVectorElementUnchecked(EltTy, Size, Idx);
1693 void clearIsNullPointer() {
1696 void adjustOffsetAndIndex(EvalInfo &Info,
const Expr *E,
1697 const APSInt &Index, CharUnits ElementSize) {
1708 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
1712 Designator.adjustIndex(Info, E, Index, *
this);
1713 clearIsNullPointer();
1715 void adjustOffset(CharUnits N) {
1718 clearIsNullPointer();
1724 explicit MemberPtr(
const ValueDecl *Decl)
1725 : DeclAndIsDerivedMember(
Decl,
false) {}
1729 const ValueDecl *getDecl()
const {
1730 return DeclAndIsDerivedMember.getPointer();
1733 bool isDerivedMember()
const {
1734 return DeclAndIsDerivedMember.getInt();
1737 const CXXRecordDecl *getContainingRecord()
const {
1739 DeclAndIsDerivedMember.getPointer()->getDeclContext());
1743 V =
APValue(getDecl(), isDerivedMember(), Path);
1746 assert(
V.isMemberPointer());
1747 DeclAndIsDerivedMember.setPointer(
V.getMemberPointerDecl());
1748 DeclAndIsDerivedMember.setInt(
V.isMemberPointerToDerivedMember());
1750 llvm::append_range(Path,
V.getMemberPointerPath());
1756 llvm::PointerIntPair<const ValueDecl*, 1, bool> DeclAndIsDerivedMember;
1759 SmallVector<const CXXRecordDecl*, 4> Path;
1763 bool castBack(
const CXXRecordDecl *
Class) {
1764 assert(!Path.empty());
1765 const CXXRecordDecl *Expected;
1766 if (Path.size() >= 2)
1767 Expected = Path[Path.size() - 2];
1769 Expected = getContainingRecord();
1783 bool castToDerived(
const CXXRecordDecl *Derived) {
1786 if (!isDerivedMember()) {
1787 Path.push_back(Derived);
1790 if (!castBack(Derived))
1793 DeclAndIsDerivedMember.setInt(
false);
1801 DeclAndIsDerivedMember.setInt(
true);
1802 if (isDerivedMember()) {
1803 Path.push_back(Base);
1806 return castBack(Base);
1811 static bool operator==(
const MemberPtr &LHS,
const MemberPtr &RHS) {
1812 if (!LHS.getDecl() || !RHS.getDecl())
1813 return !LHS.getDecl() && !RHS.getDecl();
1814 if (LHS.getDecl()->getCanonicalDecl() != RHS.getDecl()->getCanonicalDecl())
1816 return LHS.Path == RHS.Path;
1820void SubobjectDesignator::adjustIndex(EvalInfo &Info,
const Expr *E,
APSInt N,
1824 uint64_t TruncatedN = N.extOrTrunc(64).getZExtValue();
1825 if (isMostDerivedAnUnsizedArray()) {
1826 diagnoseUnsizedArrayPointerArithmetic(Info, E);
1831 PathEntry::ArrayIndex(Entries.back().getAsArrayIndex() + TruncatedN);
1839 MostDerivedPathLength == Entries.size() && MostDerivedIsArrayElement;
1841 IsArray ? Entries.back().getAsArrayIndex() : (
uint64_t)IsOnePastTheEnd;
1844 if (N < -(int64_t)ArrayIndex || N > ArraySize - ArrayIndex) {
1845 if (!Info.checkingPotentialConstantExpression() ||
1846 !LV.AllowConstexprUnknown) {
1849 N = N.extend(std::max<unsigned>(N.getBitWidth() + 1, 65));
1850 (llvm::APInt &)N += ArrayIndex;
1851 assert(N.ugt(ArraySize) &&
"bounds check failed for in-bounds index");
1852 diagnosePointerArithmetic(Info, E, N);
1858 ArrayIndex += TruncatedN;
1859 assert(ArrayIndex <= ArraySize &&
1860 "bounds check succeeded for out-of-bounds index");
1863 Entries.back() = PathEntry::ArrayIndex(ArrayIndex);
1865 IsOnePastTheEnd = (ArrayIndex != 0);
1870 const LValue &This,
const Expr *E,
1871 bool AllowNonLiteralTypes =
false);
1873 bool InvalidBaseOK =
false);
1875 bool InvalidBaseOK =
false);
1883static bool EvaluateComplex(
const Expr *E, ComplexValue &Res, EvalInfo &Info);
1889 std::string *StringResult =
nullptr);
1906 if (Int.isUnsigned() || Int.isMinSignedValue()) {
1907 Int = Int.extend(Int.getBitWidth() + 1);
1908 Int.setIsSigned(
true);
1913template<
typename KeyT>
1914APValue &CallStackFrame::createTemporary(
const KeyT *Key, QualType
T,
1915 ScopeKind Scope, LValue &LV) {
1916 unsigned Version = getTempVersion();
1917 APValue::LValueBase
Base(Key, Index, Version);
1919 return createLocal(Base, Key,
T, Scope);
1923APValue &CallStackFrame::createParam(CallRef Args,
const ParmVarDecl *PVD,
1925 assert(Args.CallIndex == Index &&
"creating parameter in wrong frame");
1926 APValue::LValueBase
Base(PVD, Index, Args.Version);
1931 return createLocal(Base, PVD, PVD->
getType(), ScopeKind::Call);
1934APValue &CallStackFrame::createLocal(APValue::LValueBase Base,
const void *Key,
1935 QualType
T, ScopeKind Scope) {
1936 assert(
Base.getCallIndex() == Index &&
"lvalue for wrong frame");
1937 unsigned Version =
Base.getVersion();
1939 assert(
Result.isAbsent() &&
"local created multiple times");
1945 if (Index <= Info.SpeculativeEvaluationDepth) {
1946 if (
T.isDestructedType())
1947 Info.noteSideEffect();
1949 Info.CleanupStack.push_back(Cleanup(&
Result, Base,
T, Scope));
1954APValue *EvalInfo::createHeapAlloc(
const Expr *E, QualType
T, LValue &LV) {
1956 FFDiag(E, diag::note_constexpr_heap_alloc_limit_exceeded);
1960 DynamicAllocLValue DA(NumHeapAllocs++);
1962 auto Result = HeapAllocs.emplace(std::piecewise_construct,
1963 std::forward_as_tuple(DA), std::tuple<>());
1964 assert(
Result.second &&
"reused a heap alloc index?");
1965 Result.first->second.AllocExpr = E;
1966 return &
Result.first->second.Value;
1970void CallStackFrame::describe(raw_ostream &Out)
const {
1971 unsigned ArgIndex = 0;
1980 if (This && IsMemberCall) {
1981 if (
const auto *MCE = dyn_cast_if_present<CXXMemberCallExpr>(CallExpr)) {
1982 const Expr *
Object = MCE->getImplicitObjectArgument();
1985 if (
Object->getType()->isPointerType())
1989 }
else if (
const auto *OCE =
1990 dyn_cast_if_present<CXXOperatorCallExpr>(CallExpr)) {
1991 OCE->getArg(0)->printPretty(Out,
nullptr,
1997 This->moveInto(Val);
2005 IsMemberCall =
false;
2011 E =
Callee->param_end(); I != E; ++I, ++ArgIndex) {
2012 if (ArgIndex > (
unsigned)IsMemberCall)
2015 const ParmVarDecl *Param = *I;
2016 APValue *
V = Info.getParamSlot(Arguments, Param);
2018 V->printPretty(Out, Info.Ctx, Param->
getType());
2022 if (ArgIndex == 0 && IsMemberCall)
2037 return Info.noteSideEffect();
2044 return (
Builtin == Builtin::BI__builtin___CFStringMakeConstantString ||
2045 Builtin == Builtin::BI__builtin___NSStringMakeConstantString ||
2046 Builtin == Builtin::BI__builtin_ptrauth_sign_constant ||
2047 Builtin == Builtin::BI__builtin_function_start);
2051 const auto *BaseExpr =
2052 llvm::dyn_cast_if_present<CallExpr>(LVal.Base.
dyn_cast<
const Expr *>());
2067 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
2068 return VD->hasGlobalStorage();
2084 case Expr::CompoundLiteralExprClass: {
2088 case Expr::MaterializeTemporaryExprClass:
2093 case Expr::StringLiteralClass:
2094 case Expr::PredefinedExprClass:
2095 case Expr::ObjCStringLiteralClass:
2096 case Expr::ObjCEncodeExprClass:
2098 case Expr::ObjCBoxedExprClass:
2100 case Expr::CallExprClass:
2103 case Expr::AddrLabelExprClass:
2107 case Expr::BlockExprClass:
2111 case Expr::SourceLocExprClass:
2113 case Expr::ImplicitValueInitExprClass:
2138 const auto *BaseExpr = LVal.Base.
dyn_cast<
const Expr *>();
2143 if (
const auto *EE = dyn_cast<ObjCEncodeExpr>(BaseExpr)) {
2152 const auto *Lit = dyn_cast<StringLiteral>(BaseExpr);
2153 if (
const auto *PE = dyn_cast<PredefinedExpr>(BaseExpr))
2154 Lit = PE->getFunctionName();
2159 AsString.
Bytes = Lit->getBytes();
2160 AsString.
CharWidth = Lit->getCharByteWidth();
2180 const LValue &RHS) {
2189 CharUnits Offset = RHS.Offset - LHS.Offset;
2190 if (Offset.isNegative()) {
2191 if (LHSString.
Bytes.size() < (
size_t)-Offset.getQuantity())
2193 LHSString.
Bytes = LHSString.
Bytes.drop_front(-Offset.getQuantity());
2195 if (RHSString.
Bytes.size() < (
size_t)Offset.getQuantity())
2197 RHSString.
Bytes = RHSString.
Bytes.drop_front(Offset.getQuantity());
2200 bool LHSIsLonger = LHSString.
Bytes.size() > RHSString.
Bytes.size();
2201 StringRef Longer = LHSIsLonger ? LHSString.
Bytes : RHSString.
Bytes;
2202 StringRef Shorter = LHSIsLonger ? RHSString.
Bytes : LHSString.
Bytes;
2203 int ShorterCharWidth = (LHSIsLonger ? RHSString : LHSString).CharWidth;
2208 for (
int NullByte : llvm::seq(ShorterCharWidth)) {
2209 if (Shorter.size() + NullByte >= Longer.size())
2211 if (Longer[Shorter.size() + NullByte])
2217 return Shorter == Longer.take_front(Shorter.size());
2227 if (isa_and_nonnull<VarDecl>(
Decl)) {
2237 if (!A.getLValueBase())
2238 return !B.getLValueBase();
2239 if (!B.getLValueBase())
2242 if (A.getLValueBase().getOpaqueValue() !=
2243 B.getLValueBase().getOpaqueValue())
2246 return A.getLValueCallIndex() == B.getLValueCallIndex() &&
2247 A.getLValueVersion() == B.getLValueVersion();
2251 assert(
Base &&
"no location for a null lvalue");
2257 if (
auto *PVD = dyn_cast_or_null<ParmVarDecl>(VD)) {
2259 for (CallStackFrame *F = Info.CurrentCall; F; F = F->Caller) {
2260 if (F->Arguments.CallIndex ==
Base.getCallIndex() &&
2261 F->Arguments.Version ==
Base.getVersion() && F->Callee &&
2262 Idx < F->Callee->getNumParams()) {
2263 VD = F->Callee->getParamDecl(Idx);
2270 Info.Note(VD->
getLocation(), diag::note_declared_at);
2272 Info.Note(E->
getExprLoc(), diag::note_constexpr_temporary_here);
2275 if (std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA))
2276 Info.Note((*Alloc)->AllocExpr->getExprLoc(),
2277 diag::note_constexpr_dynamic_alloc_here);
2310 const SubobjectDesignator &
Designator = LVal.getLValueDesignator();
2318 if (isTemplateArgument(Kind)) {
2319 int InvalidBaseKind = -1;
2322 InvalidBaseKind = 0;
2323 else if (isa_and_nonnull<StringLiteral>(BaseE))
2324 InvalidBaseKind = 1;
2325 else if (isa_and_nonnull<MaterializeTemporaryExpr>(BaseE) ||
2326 isa_and_nonnull<LifetimeExtendedTemporaryDecl>(BaseVD))
2327 InvalidBaseKind = 2;
2328 else if (
auto *PE = dyn_cast_or_null<PredefinedExpr>(BaseE)) {
2329 InvalidBaseKind = 3;
2330 Ident = PE->getIdentKindName();
2333 if (InvalidBaseKind != -1) {
2334 Info.FFDiag(Loc, diag::note_constexpr_invalid_template_arg)
2335 << IsReferenceType << !
Designator.Entries.empty() << InvalidBaseKind
2341 if (
auto *FD = dyn_cast_or_null<FunctionDecl>(BaseVD);
2342 FD && FD->isImmediateFunction()) {
2343 Info.FFDiag(Loc, diag::note_consteval_address_accessible)
2345 Info.Note(FD->getLocation(), diag::note_declared_at);
2353 if (Info.getLangOpts().CPlusPlus11) {
2354 Info.FFDiag(Loc, diag::note_constexpr_non_global, 1)
2355 << IsReferenceType << !
Designator.Entries.empty() << !!BaseVD
2357 auto *VarD = dyn_cast_or_null<VarDecl>(BaseVD);
2358 if (VarD && VarD->isConstexpr()) {
2364 Info.Note(VarD->getLocation(), diag::note_constexpr_not_static)
2376 assert((Info.checkingPotentialConstantExpression() ||
2377 LVal.getLValueCallIndex() == 0) &&
2378 "have call index for global lvalue");
2380 if (LVal.allowConstexprUnknown()) {
2382 Info.FFDiag(Loc, diag::note_constexpr_var_init_non_constant, 1) << BaseVD;
2391 Info.FFDiag(Loc, diag::note_constexpr_dynamic_alloc)
2392 << IsReferenceType << !
Designator.Entries.empty();
2398 if (
const VarDecl *Var = dyn_cast<const VarDecl>(BaseVD)) {
2400 if (Var->getTLSKind())
2406 if (!isForManglingOnly(Kind) && Var->hasAttr<DLLImportAttr>())
2412 if (Info.getASTContext().getLangOpts().CUDA &&
2413 Info.getASTContext().getLangOpts().CUDAIsDevice &&
2414 Info.getASTContext().CUDAConstantEvalCtx.NoWrongSidedVars) {
2415 if ((!Var->hasAttr<CUDADeviceAttr>() &&
2416 !Var->hasAttr<CUDAConstantAttr>() &&
2417 !Var->getType()->isCUDADeviceBuiltinSurfaceType() &&
2418 !Var->getType()->isCUDADeviceBuiltinTextureType()) ||
2419 Var->hasAttr<HIPManagedAttr>())
2423 if (
const auto *FD = dyn_cast<const FunctionDecl>(BaseVD)) {
2434 if (Info.getLangOpts().CPlusPlus && !isForManglingOnly(Kind) &&
2435 FD->hasAttr<DLLImportAttr>())
2439 }
else if (
const auto *MTE =
2440 dyn_cast_or_null<MaterializeTemporaryExpr>(BaseE)) {
2441 if (CheckedTemps.insert(MTE).second) {
2444 Info.FFDiag(MTE->getExprLoc(),
2445 diag::note_constexpr_unsupported_temporary_nontrivial_dtor)
2450 APValue *
V = MTE->getOrCreateValue(
false);
2451 assert(
V &&
"evasluation result refers to uninitialised temporary");
2453 Info, MTE->getExprLoc(), TempType, *
V, Kind,
2454 nullptr, CheckedTemps))
2461 if (!IsReferenceType)
2473 Info.FFDiag(Loc, diag::note_constexpr_past_end, 1)
2474 << !
Designator.Entries.empty() << !!BaseVD << BaseVD;
2489 const auto *FD = dyn_cast_or_null<CXXMethodDecl>(
Member);
2492 if (FD->isImmediateFunction()) {
2493 Info.FFDiag(Loc, diag::note_consteval_address_accessible) << 0;
2494 Info.Note(FD->getLocation(), diag::note_declared_at);
2497 return isForManglingOnly(Kind) || FD->isVirtual() ||
2498 !FD->hasAttr<DLLImportAttr>();
2504 const LValue *
This =
nullptr) {
2506 if (Info.getLangOpts().CPlusPlus23)
2525 if (
This && Info.EvaluatingDecl ==
This->getLValueBase())
2529 if (Info.getLangOpts().CPlusPlus11)
2530 Info.FFDiag(E, diag::note_constexpr_nonliteral)
2533 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
2544 if (SubobjectDecl) {
2545 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
2546 << 1 << SubobjectDecl;
2548 diag::note_constexpr_subobject_declared_here);
2550 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
2559 Type = AT->getValueType();
2564 if (
Value.isArray()) {
2566 for (
unsigned I = 0, N =
Value.getArrayInitializedElts(); I != N; ++I) {
2568 Value.getArrayInitializedElt(I), Kind,
2569 SubobjectDecl, CheckedTemps))
2572 if (!
Value.hasArrayFiller())
2575 Value.getArrayFiller(), Kind, SubobjectDecl,
2578 if (
Value.isUnion() &&
Value.getUnionField()) {
2581 Value.getUnionValue(), Kind,
Value.getUnionField(), CheckedTemps);
2583 if (
Value.isStruct()) {
2585 if (
const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {
2586 unsigned BaseIndex = 0;
2588 const APValue &BaseValue =
Value.getStructBase(BaseIndex);
2591 Info.FFDiag(TypeBeginLoc, diag::note_constexpr_uninitialized_base)
2592 << BS.getType() <<
SourceRange(TypeBeginLoc, BS.getEndLoc());
2602 for (
const auto *I : RD->fields()) {
2603 if (I->isUnnamedBitField())
2607 Value.getStructField(I->getFieldIndex()), Kind,
2613 if (
Value.isLValue() &&
2616 LVal.setFrom(Info.Ctx,
Value);
2621 if (
Value.isMemberPointer() &&
2642 nullptr, CheckedTemps);
2652 ConstantExprKind::Normal,
nullptr, CheckedTemps);
2658 if (!Info.HeapAllocs.empty()) {
2662 Info.CCEDiag(Info.HeapAllocs.begin()->second.AllocExpr,
2663 diag::note_constexpr_memory_leak)
2664 <<
unsigned(Info.HeapAllocs.size() - 1);
2672 if (!
Value.getLValueBase()) {
2674 Result = !
Value.getLValueOffset().isZero();
2692 Result = Val.
getInt().getBoolValue();
2724 llvm_unreachable(
"unknown APValue kind");
2730 assert(E->
isPRValue() &&
"missing lvalue-to-rvalue conv in bool condition");
2740 Info.CCEDiag(E, diag::note_constexpr_overflow)
2741 << SrcValue << DestType;
2742 return Info.noteUndefinedBehavior();
2748 unsigned DestWidth = Info.Ctx.
getIntWidth(DestType);
2752 Result =
APSInt(DestWidth, !DestSigned);
2754 if (
Value.convertToInteger(Result, llvm::APFloat::rmTowardZero, &ignored)
2755 & APFloat::opInvalidOp)
2766 llvm::RoundingMode RM =
2768 if (RM == llvm::RoundingMode::Dynamic)
2769 RM = llvm::RoundingMode::NearestTiesToEven;
2775 APFloat::opStatus St) {
2778 if (Info.InConstantContext)
2782 if ((St & APFloat::opInexact) &&
2786 Info.FFDiag(E, diag::note_constexpr_dynamic_rounding);
2790 if ((St != APFloat::opOK) &&
2793 FPO.getAllowFEnvAccess())) {
2794 Info.FFDiag(E, diag::note_constexpr_float_arithmetic_strict);
2798 if ((St & APFloat::opStatus::opInvalidOp) &&
2819 "HandleFloatToFloatCast has been checked with only CastExpr, "
2820 "CompoundAssignOperator and ConvertVectorExpr. Please either validate "
2821 "the new expression or address the root cause of this usage.");
2823 APFloat::opStatus St;
2824 APFloat
Value = Result;
2833 unsigned DestWidth = Info.Ctx.
getIntWidth(DestType);
2839 Result =
Value.getBoolValue();
2846 QualType DestType, APFloat &Result) {
2849 APFloat::opStatus St = Result.convertFromAPInt(
Value,
Value.isSigned(), RM);
2855 assert(FD->
isBitField() &&
"truncateBitfieldValue on non-bitfield");
2857 if (!
Value.isInt()) {
2861 assert(
Value.isLValue() &&
"integral value neither int nor lvalue?");
2867 unsigned OldBitWidth = Int.getBitWidth();
2869 if (NewBitWidth < OldBitWidth)
2870 Int = Int.trunc(NewBitWidth).extend(OldBitWidth);
2877template<
typename Operation>
2880 unsigned BitWidth, Operation Op,
2882 if (LHS.isUnsigned()) {
2883 Result = Op(LHS, RHS);
2887 APSInt Value(Op(LHS.extend(BitWidth), RHS.extend(BitWidth)),
false);
2888 Result =
Value.trunc(LHS.getBitWidth());
2889 if (Result.extend(BitWidth) !=
Value) {
2890 if (Info.checkingForUndefinedBehavior())
2892 diag::warn_integer_constant_overflow)
2893 <<
toString(Result, 10, Result.isSigned(),
false,
2905 bool HandleOverflowResult =
true;
2912 std::multiplies<APSInt>(), Result);
2915 std::plus<APSInt>(), Result);
2918 std::minus<APSInt>(), Result);
2919 case BO_And: Result = LHS & RHS;
return true;
2920 case BO_Xor: Result = LHS ^ RHS;
return true;
2921 case BO_Or: Result = LHS | RHS;
return true;
2925 Info.FFDiag(E, diag::note_expr_divide_by_zero)
2931 if (RHS.isNegative() && RHS.isAllOnes() && LHS.isSigned() &&
2932 LHS.isMinSignedValue())
2934 Info, E, -LHS.extend(LHS.getBitWidth() + 1), E->
getType());
2935 Result = (Opcode == BO_Rem ? LHS % RHS : LHS / RHS);
2936 return HandleOverflowResult;
2938 if (Info.getLangOpts().OpenCL)
2940 RHS &=
APSInt(llvm::APInt(RHS.getBitWidth(),
2941 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2943 else if (RHS.isSigned() && RHS.isNegative()) {
2946 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
2947 if (!Info.noteUndefinedBehavior())
2955 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
2957 Info.CCEDiag(E, diag::note_constexpr_large_shift)
2958 << RHS << E->
getType() << LHS.getBitWidth();
2959 if (!Info.noteUndefinedBehavior())
2961 }
else if (LHS.isSigned() && !Info.getLangOpts().CPlusPlus20) {
2966 if (LHS.isNegative()) {
2967 Info.CCEDiag(E, diag::note_constexpr_lshift_of_negative) << LHS;
2968 if (!Info.noteUndefinedBehavior())
2970 }
else if (LHS.countl_zero() < SA) {
2971 Info.CCEDiag(E, diag::note_constexpr_lshift_discards);
2972 if (!Info.noteUndefinedBehavior())
2980 if (Info.getLangOpts().OpenCL)
2982 RHS &=
APSInt(llvm::APInt(RHS.getBitWidth(),
2983 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2985 else if (RHS.isSigned() && RHS.isNegative()) {
2988 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
2989 if (!Info.noteUndefinedBehavior())
2997 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
2999 Info.CCEDiag(E, diag::note_constexpr_large_shift)
3000 << RHS << E->
getType() << LHS.getBitWidth();
3001 if (!Info.noteUndefinedBehavior())
3009 case BO_LT: Result = LHS < RHS;
return true;
3010 case BO_GT: Result = LHS > RHS;
return true;
3011 case BO_LE: Result = LHS <= RHS;
return true;
3012 case BO_GE: Result = LHS >= RHS;
return true;
3013 case BO_EQ: Result = LHS == RHS;
return true;
3014 case BO_NE: Result = LHS != RHS;
return true;
3016 llvm_unreachable(
"BO_Cmp should be handled elsewhere");
3023 const APFloat &RHS) {
3025 APFloat::opStatus St;
3031 St = LHS.multiply(RHS, RM);
3034 St = LHS.add(RHS, RM);
3037 St = LHS.subtract(RHS, RM);
3043 Info.CCEDiag(E, diag::note_expr_divide_by_zero);
3044 St = LHS.divide(RHS, RM);
3053 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << LHS.isNaN();
3054 return Info.noteUndefinedBehavior();
3062 const APInt &RHSValue, APInt &Result) {
3063 bool LHS = (LHSValue != 0);
3064 bool RHS = (RHSValue != 0);
3066 if (Opcode == BO_LAnd)
3067 Result = LHS && RHS;
3069 Result = LHS || RHS;
3074 const APFloat &RHSValue, APInt &Result) {
3075 bool LHS = !LHSValue.isZero();
3076 bool RHS = !RHSValue.isZero();
3078 if (Opcode == BO_LAnd)
3079 Result = LHS && RHS;
3081 Result = LHS || RHS;
3087 const APValue &RHSValue, APInt &Result) {
3091 RHSValue.
getInt(), Result);
3097template <
typename APTy>
3100 const APTy &RHSValue, APInt &Result) {
3103 llvm_unreachable(
"unsupported binary operator");
3105 Result = (LHSValue == RHSValue);
3108 Result = (LHSValue != RHSValue);
3111 Result = (LHSValue < RHSValue);
3114 Result = (LHSValue > RHSValue);
3117 Result = (LHSValue <= RHSValue);
3120 Result = (LHSValue >= RHSValue);
3134 const APValue &RHSValue, APInt &Result) {
3138 RHSValue.
getInt(), Result);
3149 assert(Opcode != BO_PtrMemD && Opcode != BO_PtrMemI &&
3150 "Operation not supported on vector types");
3154 QualType EltTy = VT->getElementType();
3161 "A vector result that isn't a vector OR uncalculated LValue");
3167 RHSValue.
getVectorLength() == NumElements &&
"Different vector sizes");
3171 for (
unsigned EltNum = 0; EltNum < NumElements; ++EltNum) {
3186 RHSElt.
getInt(), EltResult);
3192 ResultElements.emplace_back(EltResult);
3197 "Mismatched LHS/RHS/Result Type");
3198 APFloat LHSFloat = LHSElt.
getFloat();
3206 ResultElements.emplace_back(LHSFloat);
3210 LHSValue =
APValue(ResultElements.data(), ResultElements.size());
3218 unsigned TruncatedElements) {
3219 SubobjectDesignator &D = Result.Designator;
3222 if (TruncatedElements == D.Entries.size())
3224 assert(TruncatedElements >= D.MostDerivedPathLength &&
3225 "not casting to a derived class");
3231 for (
unsigned I = TruncatedElements, N = D.Entries.size(); I != N; ++I) {
3235 if (isVirtualBaseClass(D.Entries[I]))
3241 D.Entries.resize(TruncatedElements);
3254 Obj.addDecl(Info, E,
Base,
false);
3255 Obj.getLValueOffset() += RL->getBaseClassOffset(
Base);
3264 if (!
Base->isVirtual())
3267 SubobjectDesignator &D = Obj.Designator;
3283 Obj.addDecl(Info, E, BaseDecl,
true);
3292 PathI != PathE; ++PathI) {
3296 Type = (*PathI)->getType();
3308 llvm_unreachable(
"Class must be derived from the passed in base class!");
3327 LVal.addDecl(Info, E, FD);
3336 for (
const auto *
C : IFD->
chain())
3389 LVal.adjustOffsetAndIndex(Info, E, Adjustment, SizeOfPointee);
3395 int64_t Adjustment) {
3397 APSInt::get(Adjustment));
3412 LVal.Offset += SizeOfComponent;
3414 LVal.addComplex(Info, E, EltTy, Imag);
3420 uint64_t Size, uint64_t Idx) {
3425 LVal.Offset += SizeOfElement * Idx;
3427 LVal.addVectorElement(Info, E, EltTy, Size, Idx);
3441 const VarDecl *VD, CallStackFrame *Frame,
3442 unsigned Version,
APValue *&Result) {
3445 bool AllowConstexprUnknown =
3450 auto CheckUninitReference = [&](
bool IsLocalVariable) {
3462 if (!AllowConstexprUnknown || IsLocalVariable) {
3463 if (!Info.checkingPotentialConstantExpression())
3464 Info.FFDiag(E, diag::note_constexpr_use_uninit_reference);
3474 Result = Frame->getTemporary(VD, Version);
3476 return CheckUninitReference(
true);
3485 "missing value for local variable");
3486 if (Info.checkingPotentialConstantExpression())
3491 diag::note_unimplemented_constexpr_lambda_feature_ast)
3492 <<
"captures not currently allowed";
3499 if (Info.EvaluatingDecl ==
Base) {
3500 Result = Info.EvaluatingDeclValue;
3501 return CheckUninitReference(
false);
3509 if (AllowConstexprUnknown) {
3516 if (!Info.checkingPotentialConstantExpression() ||
3517 !Info.CurrentCall->Callee ||
3519 if (Info.getLangOpts().CPlusPlus11) {
3520 Info.FFDiag(E, diag::note_constexpr_function_param_value_unknown)
3541 if (!
Init && !AllowConstexprUnknown) {
3544 if (!Info.checkingPotentialConstantExpression()) {
3545 Info.FFDiag(E, diag::note_constexpr_var_init_unknown, 1)
3556 if (
Init &&
Init->isValueDependent()) {
3563 if (!Info.checkingPotentialConstantExpression()) {
3564 Info.FFDiag(E, Info.getLangOpts().CPlusPlus11
3565 ? diag::note_constexpr_ltor_non_constexpr
3566 : diag::note_constexpr_ltor_non_integral, 1)
3580 Info.FFDiag(E, diag::note_constexpr_var_init_non_constant, 1) << VD;
3596 !AllowConstexprUnknown) ||
3597 ((Info.getLangOpts().CPlusPlus || Info.getLangOpts().OpenCL) &&
3600 Info.CCEDiag(E, diag::note_constexpr_var_init_non_constant, 1) << VD;
3610 Info.FFDiag(E, diag::note_constexpr_var_init_weak) << VD;
3617 if (!Result && !AllowConstexprUnknown)
3620 return CheckUninitReference(
false);
3630 E = Derived->
bases_end(); I != E; ++I, ++Index) {
3631 if (I->getType()->getAsCXXRecordDecl()->getCanonicalDecl() ==
Base)
3635 llvm_unreachable(
"base class missing from derived class's bases list");
3642 "SourceLocExpr should have already been converted to a StringLiteral");
3645 if (
const auto *ObjCEnc = dyn_cast<ObjCEncodeExpr>(Lit)) {
3648 assert(Index <= Str.size() &&
"Index too large");
3649 return APSInt::getUnsigned(Str.c_str()[Index]);
3652 if (
auto PE = dyn_cast<PredefinedExpr>(Lit))
3653 Lit = PE->getFunctionName();
3657 assert(CAT &&
"string literal isn't an array");
3659 assert(CharType->
isIntegerType() &&
"unexpected character type");
3662 if (Index < S->getLength())
3675 AllocType.isNull() ? S->
getType() : AllocType);
3676 assert(CAT &&
"string literal isn't an array");
3678 assert(CharType->
isIntegerType() &&
"unexpected character type");
3685 if (Result.hasArrayFiller())
3687 for (
unsigned I = 0, N = Result.getArrayInitializedElts(); I != N; ++I) {
3695 unsigned Size = Array.getArraySize();
3696 assert(Index < Size);
3699 unsigned OldElts = Array.getArrayInitializedElts();
3700 unsigned NewElts = std::max(Index+1, OldElts * 2);
3701 NewElts = std::min(Size, std::max(NewElts, 8u));
3705 for (
unsigned I = 0; I != OldElts; ++I)
3707 for (
unsigned I = OldElts; I != NewElts; ++I)
3711 Array.
swap(NewValue);
3721 CXXRecordDecl *RD =
T->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
3732 for (
auto *Field : RD->
fields())
3733 if (!Field->isUnnamedBitField() &&
3737 for (
auto &BaseSpec : RD->
bases())
3748 CXXRecordDecl *RD =
T->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
3755 for (
auto *Field : RD->
fields()) {
3760 if (Field->isMutable() &&
3762 Info.FFDiag(E, diag::note_constexpr_access_mutable, 1) << AK << Field;
3763 Info.Note(Field->getLocation(), diag::note_declared_at);
3771 for (
auto &BaseSpec : RD->
bases())
3781 bool MutableSubobject =
false) {
3786 switch (Info.IsEvaluatingDecl) {
3787 case EvalInfo::EvaluatingDeclKind::None:
3790 case EvalInfo::EvaluatingDeclKind::Ctor:
3792 if (Info.EvaluatingDecl ==
Base)
3797 if (
auto *BaseE =
Base.dyn_cast<
const Expr *>())
3798 if (
auto *BaseMTE = dyn_cast<MaterializeTemporaryExpr>(BaseE))
3799 return Info.EvaluatingDecl == BaseMTE->getExtendingDecl();
3802 case EvalInfo::EvaluatingDeclKind::Dtor:
3807 if (MutableSubobject ||
Base != Info.EvaluatingDecl)
3813 return T.isConstQualified() ||
T->isReferenceType();
3816 llvm_unreachable(
"unknown evaluating decl kind");
3821 return Info.CheckArraySize(
3830struct CompleteObject {
3832 APValue::LValueBase
Base;
3842 bool mayAccessMutableMembers(EvalInfo &Info,
AccessKinds AK)
const {
3853 if (!Info.getLangOpts().CPlusPlus14 &&
3854 AK != AccessKinds::AK_IsWithinLifetime)
3859 explicit operator bool()
const {
return !
Type.isNull(); }
3864 bool IsMutable =
false) {
3878template <
typename Sub
objectHandler>
3879static typename SubobjectHandler::result_type
3881 const SubobjectDesignator &Sub, SubobjectHandler &handler) {
3884 return handler.failed();
3885 if (Sub.isOnePastTheEnd() || Sub.isMostDerivedAnUnsizedArray()) {
3886 if (Info.getLangOpts().CPlusPlus11)
3887 Info.FFDiag(E, Sub.isOnePastTheEnd()
3888 ? diag::note_constexpr_access_past_end
3889 : diag::note_constexpr_access_unsized_array)
3890 << handler.AccessKind;
3893 return handler.failed();
3899 const FieldDecl *VolatileField =
nullptr;
3902 for (
unsigned I = 0, N = Sub.Entries.size(); ; ++I) {
3913 if (!Info.checkingPotentialConstantExpression())
3914 Info.FFDiag(E, diag::note_constexpr_access_uninit)
3917 return handler.failed();
3925 Info.isEvaluatingCtorDtor(
3926 Obj.Base,
ArrayRef(Sub.Entries.begin(), Sub.Entries.begin() + I)) !=
3927 ConstructionPhase::None) {
3937 if (Info.getLangOpts().CPlusPlus) {
3941 if (VolatileField) {
3944 Decl = VolatileField;
3947 Loc = VD->getLocation();
3954 Info.FFDiag(E, diag::note_constexpr_access_volatile_obj, 1)
3955 << handler.AccessKind << DiagKind <<
Decl;
3956 Info.Note(Loc, diag::note_constexpr_volatile_here) << DiagKind;
3958 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
3960 return handler.failed();
3968 !Obj.mayAccessMutableMembers(Info, handler.AccessKind) &&
3970 return handler.failed();
3974 if (!handler.found(*O, ObjType))
3986 LastField =
nullptr;
3991 "vla in literal type?");
3992 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
3993 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT);
3994 CAT && CAT->
getSize().ule(Index)) {
3997 if (Info.getLangOpts().CPlusPlus11)
3998 Info.FFDiag(E, diag::note_constexpr_access_past_end)
3999 << handler.AccessKind;
4002 return handler.failed();
4009 else if (!
isRead(handler.AccessKind)) {
4010 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT);
4012 return handler.failed();
4020 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4022 if (Info.getLangOpts().CPlusPlus11)
4023 Info.FFDiag(E, diag::note_constexpr_access_past_end)
4024 << handler.AccessKind;
4027 return handler.failed();
4033 assert(I == N - 1 &&
"extracting subobject of scalar?");
4043 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4044 unsigned NumElements = VT->getNumElements();
4045 if (Index == NumElements) {
4046 if (Info.getLangOpts().CPlusPlus11)
4047 Info.FFDiag(E, diag::note_constexpr_access_past_end)
4048 << handler.AccessKind;
4051 return handler.failed();
4054 if (Index > NumElements) {
4055 Info.CCEDiag(E, diag::note_constexpr_array_index)
4056 << Index << 0 << NumElements;
4057 return handler.failed();
4060 ObjType = VT->getElementType();
4061 assert(I == N - 1 &&
"extracting subobject of scalar?");
4063 }
else if (
const FieldDecl *Field = getAsField(Sub.Entries[I])) {
4064 if (Field->isMutable() &&
4065 !Obj.mayAccessMutableMembers(Info, handler.AccessKind)) {
4066 Info.FFDiag(E, diag::note_constexpr_access_mutable, 1)
4067 << handler.AccessKind << Field;
4068 Info.Note(Field->getLocation(), diag::note_declared_at);
4069 return handler.failed();
4079 if (I == N - 1 && handler.AccessKind ==
AK_Construct) {
4090 Info.FFDiag(E, diag::note_constexpr_access_inactive_union_member)
4091 << handler.AccessKind << Field << !UnionField << UnionField;
4092 return handler.failed();
4101 if (Field->getType().isVolatileQualified())
4102 VolatileField = Field;
4115struct ExtractSubobjectHandler {
4121 typedef bool result_type;
4122 bool failed() {
return false; }
4123 bool found(
APValue &Subobj, QualType SubobjType) {
4133 bool found(APFloat &
Value, QualType SubobjType) {
4142 const CompleteObject &Obj,
4143 const SubobjectDesignator &Sub,
APValue &Result,
4146 ExtractSubobjectHandler Handler = {Info, E, Result, AK};
4151struct ModifySubobjectHandler {
4156 typedef bool result_type;
4159 bool checkConst(QualType QT) {
4162 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
4168 bool failed() {
return false; }
4169 bool found(
APValue &Subobj, QualType SubobjType) {
4170 if (!checkConst(SubobjType))
4173 Subobj.
swap(NewVal);
4177 if (!checkConst(SubobjType))
4179 if (!NewVal.
isInt()) {
4187 bool found(APFloat &
Value, QualType SubobjType) {
4188 if (!checkConst(SubobjType))
4196const AccessKinds ModifySubobjectHandler::AccessKind;
4200 const CompleteObject &Obj,
4201 const SubobjectDesignator &Sub,
4203 ModifySubobjectHandler Handler = { Info, NewVal, E };
4210 const SubobjectDesignator &A,
4211 const SubobjectDesignator &B,
4212 bool &WasArrayIndex) {
4213 unsigned I = 0, N = std::min(A.Entries.size(), B.Entries.size());
4214 for (; I != N; ++I) {
4218 if (A.Entries[I].getAsArrayIndex() != B.Entries[I].getAsArrayIndex()) {
4219 WasArrayIndex =
true;
4227 if (A.Entries[I].getAsBaseOrMember() !=
4228 B.Entries[I].getAsBaseOrMember()) {
4229 WasArrayIndex =
false;
4232 if (
const FieldDecl *FD = getAsField(A.Entries[I]))
4234 ObjType = FD->getType();
4240 WasArrayIndex =
false;
4247 const SubobjectDesignator &A,
4248 const SubobjectDesignator &B) {
4249 if (A.Entries.size() != B.Entries.size())
4252 bool IsArray = A.MostDerivedIsArrayElement;
4253 if (IsArray && A.MostDerivedPathLength != A.Entries.size())
4262 return CommonLength >= A.Entries.size() - IsArray;
4269 if (LVal.InvalidBase) {
4271 return CompleteObject();
4276 Info.FFDiag(E, diag::note_constexpr_dereferencing_null);
4278 Info.FFDiag(E, diag::note_constexpr_access_null) << AK;
4279 return CompleteObject();
4282 CallStackFrame *Frame =
nullptr;
4284 if (LVal.getLValueCallIndex()) {
4285 std::tie(Frame, Depth) =
4286 Info.getCallFrameAndDepth(LVal.getLValueCallIndex());
4288 Info.FFDiag(E, diag::note_constexpr_lifetime_ended, 1)
4291 return CompleteObject();
4302 if (Info.getLangOpts().CPlusPlus)
4303 Info.FFDiag(E, diag::note_constexpr_access_volatile_type)
4307 return CompleteObject();
4314 if (Info.getLangOpts().CPlusPlus14 && LVal.Base == Info.EvaluatingDecl &&
4318 BaseVal = Info.EvaluatingDeclValue;
4321 if (
auto *GD = dyn_cast<MSGuidDecl>(D)) {
4324 Info.FFDiag(E, diag::note_constexpr_modify_global);
4325 return CompleteObject();
4329 Info.FFDiag(E, diag::note_constexpr_unsupported_layout)
4331 return CompleteObject();
4333 return CompleteObject(LVal.Base, &
V, GD->getType());
4337 if (
auto *GCD = dyn_cast<UnnamedGlobalConstantDecl>(D)) {
4339 Info.FFDiag(E, diag::note_constexpr_modify_global);
4340 return CompleteObject();
4342 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&GCD->getValue()),
4347 if (
auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
4349 Info.FFDiag(E, diag::note_constexpr_modify_global);
4350 return CompleteObject();
4352 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&TPO->getValue()),
4363 const VarDecl *VD = dyn_cast<VarDecl>(D);
4370 return CompleteObject();
4373 bool IsConstant = BaseType.isConstant(Info.Ctx);
4374 bool ConstexprVar =
false;
4375 if (
const auto *VD = dyn_cast_if_present<VarDecl>(
4387 }
else if (Info.getLangOpts().CPlusPlus14 &&
4394 Info.FFDiag(E, diag::note_constexpr_modify_global);
4395 return CompleteObject();
4398 }
else if (Info.getLangOpts().C23 && ConstexprVar) {
4400 return CompleteObject();
4401 }
else if (BaseType->isIntegralOrEnumerationType()) {
4404 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4405 if (Info.getLangOpts().CPlusPlus) {
4406 Info.FFDiag(E, diag::note_constexpr_ltor_non_const_int, 1) << VD;
4407 Info.Note(VD->
getLocation(), diag::note_declared_at);
4411 return CompleteObject();
4413 }
else if (!IsAccess) {
4414 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4415 }
else if ((IsConstant || BaseType->isReferenceType()) &&
4416 Info.checkingPotentialConstantExpression() &&
4417 BaseType->isLiteralType(Info.Ctx) && !VD->
hasDefinition()) {
4419 }
else if (IsConstant) {
4423 if (Info.getLangOpts().CPlusPlus) {
4424 Info.CCEDiag(E, Info.getLangOpts().CPlusPlus11
4425 ? diag::note_constexpr_ltor_non_constexpr
4426 : diag::note_constexpr_ltor_non_integral, 1)
4428 Info.Note(VD->
getLocation(), diag::note_declared_at);
4434 if (Info.getLangOpts().CPlusPlus) {
4435 Info.FFDiag(E, Info.getLangOpts().CPlusPlus11
4436 ? diag::note_constexpr_ltor_non_constexpr
4437 : diag::note_constexpr_ltor_non_integral, 1)
4439 Info.Note(VD->
getLocation(), diag::note_declared_at);
4443 return CompleteObject();
4452 return CompleteObject();
4457 if (!Info.checkingPotentialConstantExpression()) {
4458 Info.FFDiag(E, diag::note_constexpr_access_unknown_variable, 1)
4460 Info.Note(VD->getLocation(), diag::note_declared_at);
4462 return CompleteObject();
4465 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
4467 Info.FFDiag(E, diag::note_constexpr_access_deleted_object) << AK;
4468 return CompleteObject();
4470 return CompleteObject(LVal.Base, &(*Alloc)->Value,
4480 dyn_cast_or_null<MaterializeTemporaryExpr>(
Base)) {
4481 assert(MTE->getStorageDuration() ==
SD_Static &&
4482 "should have a frame for a non-global materialized temporary");
4509 if (!MTE->isUsableInConstantExpressions(Info.Ctx) &&
4512 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4513 Info.FFDiag(E, diag::note_constexpr_access_static_temporary, 1) << AK;
4514 Info.Note(MTE->getExprLoc(), diag::note_constexpr_temporary_here);
4515 return CompleteObject();
4518 BaseVal = MTE->getOrCreateValue(
false);
4519 assert(BaseVal &&
"got reference to unevaluated temporary");
4521 dyn_cast_or_null<CompoundLiteralExpr>(
Base)) {
4537 !CLETy.isConstant(Info.Ctx)) {
4539 Info.Note(CLE->getExprLoc(), diag::note_declared_at);
4540 return CompleteObject();
4543 BaseVal = &CLE->getStaticValue();
4546 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4549 Info.FFDiag(E, diag::note_constexpr_access_unreadable_object)
4554 return CompleteObject();
4558 assert(BaseVal &&
"missing value for temporary");
4569 unsigned VisibleDepth = Depth;
4570 if (llvm::isa_and_nonnull<ParmVarDecl>(
4573 if ((Frame && Info.getLangOpts().CPlusPlus14 &&
4575 (
isModification(AK) && VisibleDepth < Info.SpeculativeEvaluationDepth))
4576 return CompleteObject();
4578 return CompleteObject(LVal.getLValueBase(), BaseVal, BaseType);
4597 const LValue &LVal,
APValue &RVal,
4598 bool WantObjectRepresentation =
false) {
4599 if (LVal.Designator.Invalid)
4608 if (
Base && !LVal.getLValueCallIndex() && !
Type.isVolatileQualified()) {
4612 assert(LVal.Designator.Entries.size() <= 1 &&
4613 "Can only read characters from string literals");
4614 if (LVal.Designator.Entries.empty()) {
4621 if (LVal.Designator.isOnePastTheEnd()) {
4622 if (Info.getLangOpts().CPlusPlus11)
4623 Info.FFDiag(Conv, diag::note_constexpr_access_past_end) << AK;
4628 uint64_t CharIndex = LVal.Designator.Entries[0].getAsArrayIndex();
4635 return Obj &&
extractSubobject(Info, Conv, Obj, LVal.Designator, RVal, AK);
4641 if (LVal.Designator.Invalid)
4644 if (!Info.getLangOpts().CPlusPlus14) {
4654struct CompoundAssignSubobjectHandler {
4656 const CompoundAssignOperator *E;
4657 QualType PromotedLHSType;
4663 typedef bool result_type;
4665 bool checkConst(QualType QT) {
4668 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
4674 bool failed() {
return false; }
4675 bool found(
APValue &Subobj, QualType SubobjType) {
4678 return found(Subobj.
getInt(), SubobjType);
4680 return found(Subobj.
getFloat(), SubobjType);
4687 return foundPointer(Subobj, SubobjType);
4689 return foundVector(Subobj, SubobjType);
4691 Info.FFDiag(E, diag::note_constexpr_access_uninit)
4702 bool foundVector(
APValue &
Value, QualType SubobjType) {
4703 if (!checkConst(SubobjType))
4714 if (!checkConst(SubobjType))
4736 PromotedLHSType, FValue) &&
4745 bool found(APFloat &
Value, QualType SubobjType) {
4746 return checkConst(SubobjType) &&
4752 bool foundPointer(
APValue &Subobj, QualType SubobjType) {
4753 if (!checkConst(SubobjType))
4756 QualType PointeeType;
4757 if (
const PointerType *PT = SubobjType->
getAs<PointerType>())
4761 (Opcode != BO_Add && Opcode != BO_Sub)) {
4767 if (Opcode == BO_Sub)
4771 LVal.setFrom(Info.Ctx, Subobj);
4774 LVal.moveInto(Subobj);
4780const AccessKinds CompoundAssignSubobjectHandler::AccessKind;
4785 const LValue &LVal,
QualType LValType,
4789 if (LVal.Designator.Invalid)
4792 if (!Info.getLangOpts().CPlusPlus14) {
4798 CompoundAssignSubobjectHandler Handler = { Info, E, PromotedLValType, Opcode,
4800 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
4804struct IncDecSubobjectHandler {
4806 const UnaryOperator *E;
4810 typedef bool result_type;
4812 bool checkConst(QualType QT) {
4815 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
4821 bool failed() {
return false; }
4822 bool found(
APValue &Subobj, QualType SubobjType) {
4832 return found(Subobj.
getInt(), SubobjType);
4834 return found(Subobj.
getFloat(), SubobjType);
4837 SubobjType->
castAs<ComplexType>()->getElementType()
4841 SubobjType->
castAs<ComplexType>()->getElementType()
4844 return foundPointer(Subobj, SubobjType);
4852 if (!checkConst(SubobjType))
4874 bool WasNegative =
Value.isNegative();
4886 unsigned BitWidth =
Value.getBitWidth();
4887 APSInt ActualValue(
Value.sext(BitWidth + 1),
false);
4888 ActualValue.setBit(BitWidth);
4894 bool found(APFloat &
Value, QualType SubobjType) {
4895 if (!checkConst(SubobjType))
4902 APFloat::opStatus St;
4904 St =
Value.add(One, RM);
4906 St =
Value.subtract(One, RM);
4909 bool foundPointer(
APValue &Subobj, QualType SubobjType) {
4910 if (!checkConst(SubobjType))
4913 QualType PointeeType;
4914 if (
const PointerType *PT = SubobjType->
getAs<PointerType>())
4922 LVal.setFrom(Info.Ctx, Subobj);
4926 LVal.moveInto(Subobj);
4935 if (LVal.Designator.Invalid)
4938 if (!Info.getLangOpts().CPlusPlus14) {
4946 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
4952 if (Object->getType()->isPointerType() && Object->isPRValue())
4955 if (Object->isGLValue())
4958 if (Object->getType()->isLiteralType(Info.Ctx))
4961 if (Object->getType()->isRecordType() && Object->isPRValue())
4964 Info.FFDiag(Object, diag::note_constexpr_nonliteral) << Object->getType();
4983 bool IncludeMember =
true) {
4990 if (!MemPtr.getDecl()) {
4996 if (MemPtr.isDerivedMember()) {
5003 if (LV.Designator.MostDerivedPathLength + MemPtr.Path.size() >
5004 LV.Designator.Entries.size()) {
5008 unsigned PathLengthToMember =
5009 LV.Designator.Entries.size() - MemPtr.Path.size();
5010 for (
unsigned I = 0, N = MemPtr.Path.size(); I != N; ++I) {
5012 LV.Designator.Entries[PathLengthToMember + I]);
5029 (PathLengthToMember > LV.Designator.MostDerivedPathLength)
5030 ? getAsBaseClass(LV.Designator.Entries[PathLengthToMember - 1])
5032 const CXXRecordDecl *LastMPDecl = MemPtr.getContainingRecord();
5040 PathLengthToMember))
5042 }
else if (!MemPtr.Path.empty()) {
5044 LV.Designator.Entries.reserve(LV.Designator.Entries.size() +
5045 MemPtr.Path.size() + IncludeMember);
5051 assert(RD &&
"member pointer access on non-class-type expression");
5053 for (
unsigned I = 1, N = MemPtr.Path.size(); I != N; ++I) {
5061 MemPtr.getContainingRecord()))
5066 if (IncludeMember) {
5067 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(MemPtr.getDecl())) {
5071 dyn_cast<IndirectFieldDecl>(MemPtr.getDecl())) {
5075 llvm_unreachable(
"can't construct reference to bound member function");
5079 return MemPtr.getDecl();
5085 bool IncludeMember =
true) {
5089 if (Info.noteFailure()) {
5097 BO->
getRHS(), IncludeMember);
5104 SubobjectDesignator &D = Result.Designator;
5105 if (D.Invalid || !Result.checkNullPointer(Info, E,
CSK_Derived))
5112 auto InvalidCast = [&]() {
5113 if (!Info.checkingPotentialConstantExpression() ||
5114 !Result.AllowConstexprUnknown) {
5115 Info.CCEDiag(E, diag::note_constexpr_invalid_downcast)
5116 << D.MostDerivedType << TargetQT;
5122 if (D.MostDerivedPathLength + E->
path_size() > D.Entries.size())
5123 return InvalidCast();
5127 unsigned NewEntriesSize = D.Entries.size() - E->
path_size();
5130 if (NewEntriesSize == D.MostDerivedPathLength)
5133 FinalType = getAsBaseClass(D.Entries[NewEntriesSize - 1]);
5135 return InvalidCast();
5147 if (!Result.isAbsent())
5150 if (
auto *RD =
T->getAsCXXRecordDecl()) {
5151 if (RD->isInvalidDecl()) {
5155 if (RD->isUnion()) {
5160 std::distance(RD->field_begin(), RD->field_end()));
5164 End = RD->bases_end();
5165 I != End; ++I, ++Index)
5169 for (
const auto *I : RD->fields()) {
5170 if (I->isUnnamedBitField())
5173 I->getType(), Result.getStructField(I->getFieldIndex()));
5179 dyn_cast_or_null<ConstantArrayType>(
T->getAsArrayTypeUnsafe())) {
5181 if (Result.hasArrayFiller())
5193enum EvalStmtResult {
5222 if (!Result.Designator.Invalid && Result.Designator.isOnePastTheEnd()) {
5228 Result.moveInto(Val);
5240 APValue &Val = Info.CurrentCall->createTemporary(VD, VD->
getType(),
5241 ScopeKind::Block, Result);
5246 return Info.noteSideEffect();
5267 const DecompositionDecl *DD);
5270 bool EvaluateConditionDecl =
false) {
5272 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
5276 EvaluateConditionDecl && DD)
5286 if (
auto *VD = BD->getHoldingVar())
5294 if (
auto *DD = dyn_cast_if_present<DecompositionDecl>(VD)) {
5303 if (Info.noteSideEffect())
5305 assert(E->
containsErrors() &&
"valid value-dependent expression should never "
5306 "reach invalid code path.");
5313 if (
Cond->isValueDependent())
5315 FullExpressionRAII
Scope(Info);
5322 return Scope.destroy();
5335struct TempVersionRAII {
5336 CallStackFrame &Frame;
5338 TempVersionRAII(CallStackFrame &Frame) : Frame(Frame) {
5339 Frame.pushTempVersion();
5342 ~TempVersionRAII() {
5343 Frame.popTempVersion();
5351 const SwitchCase *SC =
nullptr);
5357 const Stmt *LoopOrSwitch,
5359 EvalStmtResult &ESR) {
5363 if (!IsSwitch && ESR == ESR_Succeeded) {
5368 if (ESR != ESR_Break && ESR != ESR_Continue)
5372 bool CanBreakOrContinue = !IsSwitch || ESR == ESR_Break;
5373 const Stmt *StackTop = Info.BreakContinueStack.back();
5374 if (CanBreakOrContinue && (StackTop ==
nullptr || StackTop == LoopOrSwitch)) {
5375 Info.BreakContinueStack.pop_back();
5376 if (ESR == ESR_Break)
5377 ESR = ESR_Succeeded;
5382 for (BlockScopeRAII *S : Scopes) {
5383 if (!S->destroy()) {
5395 BlockScopeRAII
Scope(Info);
5397 EvalStmtResult ESR =
EvaluateStmt(Result, Info, Body, Case);
5398 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5407 BlockScopeRAII
Scope(Info);
5414 if (ESR != ESR_Succeeded) {
5415 if (ESR != ESR_Failed && !
Scope.destroy())
5421 FullExpressionRAII CondScope(Info);
5436 if (!CondScope.destroy())
5461 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5465 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5472 llvm_unreachable(
"Should have been converted to Succeeded");
5478 case ESR_CaseNotFound:
5481 Info.FFDiag(
Found->getBeginLoc(),
5482 diag::note_constexpr_stmt_expr_unsupported);
5485 llvm_unreachable(
"Invalid EvalStmtResult!");
5495 Info.CCEDiag(VD->
getLocation(), diag::note_constexpr_static_local)
5505 if (!Info.nextStep(S))
5512 case Stmt::CompoundStmtClass:
5516 case Stmt::LabelStmtClass:
5517 case Stmt::AttributedStmtClass:
5518 case Stmt::DoStmtClass:
5521 case Stmt::CaseStmtClass:
5522 case Stmt::DefaultStmtClass:
5527 case Stmt::IfStmtClass: {
5534 BlockScopeRAII
Scope(Info);
5540 if (ESR != ESR_CaseNotFound) {
5541 assert(ESR != ESR_Succeeded);
5552 if (ESR == ESR_Failed)
5554 if (ESR != ESR_CaseNotFound)
5555 return Scope.destroy() ? ESR : ESR_Failed;
5557 return ESR_CaseNotFound;
5560 if (ESR == ESR_Failed)
5562 if (ESR != ESR_CaseNotFound)
5563 return Scope.destroy() ? ESR : ESR_Failed;
5564 return ESR_CaseNotFound;
5567 case Stmt::WhileStmtClass: {
5568 EvalStmtResult ESR =
5572 if (ESR != ESR_Continue)
5577 case Stmt::ForStmtClass: {
5579 BlockScopeRAII
Scope(Info);
5585 if (ESR != ESR_CaseNotFound) {
5586 assert(ESR != ESR_Succeeded);
5591 EvalStmtResult ESR =
5595 if (ESR != ESR_Continue)
5597 if (
const auto *Inc = FS->
getInc()) {
5598 if (Inc->isValueDependent()) {
5602 FullExpressionRAII IncScope(Info);
5610 case Stmt::DeclStmtClass: {
5614 for (
const auto *D : DS->
decls()) {
5615 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
5618 if (VD->hasLocalStorage() && !VD->getInit())
5626 return ESR_CaseNotFound;
5630 return ESR_CaseNotFound;
5636 if (
const Expr *E = dyn_cast<Expr>(S)) {
5645 FullExpressionRAII
Scope(Info);
5649 return ESR_Succeeded;
5655 case Stmt::NullStmtClass:
5656 return ESR_Succeeded;
5658 case Stmt::DeclStmtClass: {
5660 for (
const auto *D : DS->
decls()) {
5661 const VarDecl *VD = dyn_cast_or_null<VarDecl>(D);
5665 FullExpressionRAII
Scope(Info);
5667 !Info.noteFailure())
5669 if (!
Scope.destroy())
5672 return ESR_Succeeded;
5675 case Stmt::ReturnStmtClass: {
5677 FullExpressionRAII
Scope(Info);
5686 :
Evaluate(Result.Value, Info, RetExpr)))
5688 return Scope.destroy() ? ESR_Returned : ESR_Failed;
5691 case Stmt::CompoundStmtClass: {
5692 BlockScopeRAII
Scope(Info);
5695 for (
const auto *BI : CS->
body()) {
5696 EvalStmtResult ESR =
EvaluateStmt(Result, Info, BI, Case);
5697 if (ESR == ESR_Succeeded)
5699 else if (ESR != ESR_CaseNotFound) {
5700 if (ESR != ESR_Failed && !
Scope.destroy())
5706 return ESR_CaseNotFound;
5707 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5710 case Stmt::IfStmtClass: {
5714 BlockScopeRAII
Scope(Info);
5717 if (ESR != ESR_Succeeded) {
5718 if (ESR != ESR_Failed && !
Scope.destroy())
5728 if (!Info.InConstantContext)
5735 EvalStmtResult ESR =
EvaluateStmt(Result, Info, SubStmt);
5736 if (ESR != ESR_Succeeded) {
5737 if (ESR != ESR_Failed && !
Scope.destroy())
5742 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5745 case Stmt::WhileStmtClass: {
5748 BlockScopeRAII
Scope(Info);
5760 if (ESR != ESR_Continue) {
5761 if (ESR != ESR_Failed && !
Scope.destroy())
5765 if (!
Scope.destroy())
5768 return ESR_Succeeded;
5771 case Stmt::DoStmtClass: {
5778 if (ESR != ESR_Continue)
5787 FullExpressionRAII CondScope(Info);
5789 !CondScope.destroy())
5792 return ESR_Succeeded;
5795 case Stmt::ForStmtClass: {
5797 BlockScopeRAII ForScope(Info);
5800 if (ESR != ESR_Succeeded) {
5801 if (ESR != ESR_Failed && !ForScope.destroy())
5807 BlockScopeRAII IterScope(Info);
5808 bool Continue =
true;
5814 if (!IterScope.destroy())
5822 if (ESR != ESR_Continue) {
5823 if (ESR != ESR_Failed && (!IterScope.destroy() || !ForScope.destroy()))
5828 if (
const auto *Inc = FS->
getInc()) {
5829 if (Inc->isValueDependent()) {
5833 FullExpressionRAII IncScope(Info);
5839 if (!IterScope.destroy())
5842 return ForScope.destroy() ? ESR_Succeeded : ESR_Failed;
5845 case Stmt::CXXForRangeStmtClass: {
5847 BlockScopeRAII
Scope(Info);
5852 if (ESR != ESR_Succeeded) {
5853 if (ESR != ESR_Failed && !
Scope.destroy())
5861 if (ESR != ESR_Succeeded) {
5862 if (ESR != ESR_Failed && !
Scope.destroy())
5874 if (ESR != ESR_Succeeded) {
5875 if (ESR != ESR_Failed && !
Scope.destroy())
5880 if (ESR != ESR_Succeeded) {
5881 if (ESR != ESR_Failed && !
Scope.destroy())
5894 bool Continue =
true;
5895 FullExpressionRAII CondExpr(Info);
5903 BlockScopeRAII InnerScope(Info);
5905 if (ESR != ESR_Succeeded) {
5906 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
5915 if (ESR != ESR_Continue) {
5916 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
5929 if (!InnerScope.destroy())
5933 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5936 case Stmt::SwitchStmtClass:
5939 case Stmt::ContinueStmtClass:
5940 case Stmt::BreakStmtClass: {
5942 Info.BreakContinueStack.push_back(B->getNamedLoopOrSwitch());
5946 case Stmt::LabelStmtClass:
5949 case Stmt::AttributedStmtClass: {
5951 const auto *SS = AS->getSubStmt();
5952 MSConstexprContextRAII ConstexprContext(
5956 auto LO = Info.getASTContext().getLangOpts();
5957 if (LO.CXXAssumptions && !LO.MSVCCompat) {
5958 for (
auto *
Attr : AS->getAttrs()) {
5959 auto *AA = dyn_cast<CXXAssumeAttr>(
Attr);
5963 auto *Assumption = AA->getAssumption();
5964 if (Assumption->isValueDependent())
5967 if (Assumption->HasSideEffects(Info.getASTContext()))
5974 Info.CCEDiag(Assumption->getExprLoc(),
5975 diag::note_constexpr_assumption_failed);
5984 case Stmt::CaseStmtClass:
5985 case Stmt::DefaultStmtClass:
5987 case Stmt::CXXTryStmtClass:
5999 bool IsValueInitialization) {
6006 if (!CD->
isConstexpr() && !IsValueInitialization) {
6007 if (Info.getLangOpts().CPlusPlus11) {
6010 Info.CCEDiag(Loc, diag::note_constexpr_invalid_function, 1)
6012 Info.Note(CD->
getLocation(), diag::note_declared_at);
6014 Info.CCEDiag(Loc, diag::note_invalid_subexpr_in_const_expr);
6028 if (Info.checkingPotentialConstantExpression() && !
Definition &&
6036 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6045 Info.CCEDiag(CallLoc, diag::note_constexpr_virtual_call);
6048 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6054 (
Definition->isConstexpr() || (Info.CurrentCall->CanEvalMSConstexpr &&
6064 StringRef Name = DiagDecl->
getName();
6066 Name ==
"__assert_rtn" || Name ==
"__assert_fail" || Name ==
"_wassert";
6068 Info.FFDiag(CallLoc, diag::note_constexpr_assert_failed);
6073 if (Info.getLangOpts().CPlusPlus11) {
6076 auto *CD = dyn_cast<CXXConstructorDecl>(DiagDecl);
6077 if (CD && CD->isInheritingConstructor()) {
6078 auto *Inherited = CD->getInheritedConstructor().getConstructor();
6079 if (!Inherited->isConstexpr())
6080 DiagDecl = CD = Inherited;
6086 if (CD && CD->isInheritingConstructor())
6087 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_inhctor, 1)
6088 << CD->getInheritedConstructor().getConstructor()->getParent();
6090 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_function, 1)
6092 Info.Note(DiagDecl->
getLocation(), diag::note_declared_at);
6094 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6100struct CheckDynamicTypeHandler {
6102 typedef bool result_type;
6103 bool failed() {
return false; }
6104 bool found(
APValue &Subobj, QualType SubobjType) {
return true; }
6105 bool found(
APSInt &
Value, QualType SubobjType) {
return true; }
6106 bool found(APFloat &
Value, QualType SubobjType) {
return true; }
6114 if (
This.Designator.Invalid)
6126 if (
This.Designator.isOnePastTheEnd() ||
6127 This.Designator.isMostDerivedAnUnsizedArray()) {
6128 Info.FFDiag(E,
This.Designator.isOnePastTheEnd()
6129 ? diag::note_constexpr_access_past_end
6130 : diag::note_constexpr_access_unsized_array)
6133 }
else if (Polymorphic) {
6136 if (!Info.checkingPotentialConstantExpression() ||
6137 !
This.AllowConstexprUnknown) {
6142 Info.FFDiag(E, diag::note_constexpr_polymorphic_unknown_dynamic_type)
6150 CheckDynamicTypeHandler Handler{AK};
6173 unsigned PathLength) {
6174 assert(PathLength >=
Designator.MostDerivedPathLength && PathLength <=
6175 Designator.Entries.size() &&
"invalid path length");
6176 return (PathLength ==
Designator.MostDerivedPathLength)
6177 ?
Designator.MostDerivedType->getAsCXXRecordDecl()
6178 : getAsBaseClass(
Designator.Entries[PathLength - 1]);
6191 return std::nullopt;
6193 if (
This.Designator.Invalid)
6194 return std::nullopt;
6203 This.Designator.MostDerivedType->getAsCXXRecordDecl();
6204 if (!Class || Class->getNumVBases()) {
6206 return std::nullopt;
6214 for (
unsigned PathLength =
This.Designator.MostDerivedPathLength;
6215 PathLength <= Path.size(); ++PathLength) {
6216 switch (Info.isEvaluatingCtorDtor(
This.getLValueBase(),
6217 Path.slice(0, PathLength))) {
6218 case ConstructionPhase::Bases:
6219 case ConstructionPhase::DestroyingBases:
6224 case ConstructionPhase::None:
6225 case ConstructionPhase::AfterBases:
6226 case ConstructionPhase::AfterFields:
6227 case ConstructionPhase::Destroying:
6239 return std::nullopt;
6257 unsigned PathLength = DynType->PathLength;
6258 for (; PathLength <=
This.Designator.Entries.size(); ++PathLength) {
6261 Found->getCorrespondingMethodDeclaredInClass(Class,
false);
6271 if (Callee->isPureVirtual()) {
6272 Info.FFDiag(E, diag::note_constexpr_pure_virtual_call, 1) << Callee;
6273 Info.Note(Callee->getLocation(), diag::note_declared_at);
6280 Found->getReturnType())) {
6281 CovariantAdjustmentPath.push_back(Callee->getReturnType());
6282 for (
unsigned CovariantPathLength = PathLength + 1;
6283 CovariantPathLength !=
This.Designator.Entries.size();
6284 ++CovariantPathLength) {
6288 Found->getCorrespondingMethodDeclaredInClass(NextClass,
false);
6290 Next->getReturnType(), CovariantAdjustmentPath.back()))
6291 CovariantAdjustmentPath.push_back(
Next->getReturnType());
6294 CovariantAdjustmentPath.back()))
6295 CovariantAdjustmentPath.push_back(
Found->getReturnType());
6311 assert(Result.isLValue() &&
6312 "unexpected kind of APValue for covariant return");
6313 if (Result.isNullPointer())
6317 LVal.setFrom(Info.Ctx, Result);
6319 const CXXRecordDecl *OldClass = Path[0]->getPointeeCXXRecordDecl();
6320 for (
unsigned I = 1; I != Path.size(); ++I) {
6321 const CXXRecordDecl *NewClass = Path[I]->getPointeeCXXRecordDecl();
6322 assert(OldClass && NewClass &&
"unexpected kind of covariant return");
6323 if (OldClass != NewClass &&
6326 OldClass = NewClass;
6329 LVal.moveInto(Result);
6338 auto *BaseClass = BaseSpec.getType()->getAsCXXRecordDecl();
6340 return BaseSpec.getAccessSpecifier() ==
AS_public;
6342 llvm_unreachable(
"Base is not a direct base of Derived");
6352 SubobjectDesignator &D = Ptr.Designator;
6358 if (Ptr.isNullPointer() && !E->
isGLValue())
6364 std::optional<DynamicType> DynType =
6376 assert(
C &&
"dynamic_cast target is not void pointer nor class");
6384 Ptr.setNull(Info.Ctx, E->
getType());
6391 DynType->Type->isDerivedFrom(
C)))
6393 else if (!Paths || Paths->begin() == Paths->end())
6395 else if (Paths->isAmbiguous(CQT))
6398 assert(Paths->front().Access !=
AS_public &&
"why did the cast fail?");
6401 Info.FFDiag(E, diag::note_constexpr_dynamic_cast_to_reference_failed)
6402 << DiagKind << Ptr.Designator.getType(Info.Ctx)
6411 for (
int PathLength = Ptr.Designator.Entries.size();
6412 PathLength >= (
int)DynType->PathLength; --PathLength) {
6417 if (PathLength > (
int)DynType->PathLength &&
6420 return RuntimeCheckFailed(
nullptr);
6427 if (DynType->Type->isDerivedFrom(
C, Paths) && !Paths.
isAmbiguous(CQT) &&
6440 return RuntimeCheckFailed(&Paths);
6444struct StartLifetimeOfUnionMemberHandler {
6446 const Expr *LHSExpr;
6447 const FieldDecl *
Field;
6449 bool Failed =
false;
6452 typedef bool result_type;
6453 bool failed() {
return Failed; }
6454 bool found(
APValue &Subobj, QualType SubobjType) {
6469 }
else if (DuringInit) {
6473 Info.FFDiag(LHSExpr,
6474 diag::note_constexpr_union_member_change_during_init);
6483 llvm_unreachable(
"wrong value kind for union object");
6485 bool found(APFloat &
Value, QualType SubobjType) {
6486 llvm_unreachable(
"wrong value kind for union object");
6491const AccessKinds StartLifetimeOfUnionMemberHandler::AccessKind;
6498 const Expr *LHSExpr,
6499 const LValue &LHS) {
6500 if (LHS.InvalidBase || LHS.Designator.Invalid)
6506 unsigned PathLength = LHS.Designator.Entries.size();
6507 for (
const Expr *E = LHSExpr; E !=
nullptr;) {
6509 if (
auto *ME = dyn_cast<MemberExpr>(E)) {
6510 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
6513 if (!FD || FD->getType()->isReferenceType())
6517 if (FD->getParent()->isUnion()) {
6522 FD->getType()->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
6523 if (!RD || RD->hasTrivialDefaultConstructor())
6524 UnionPathLengths.push_back({PathLength - 1, FD});
6530 LHS.Designator.Entries[PathLength]
6531 .getAsBaseOrMember().getPointer()));
6535 }
else if (
auto *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
6537 auto *
Base = ASE->getBase()->IgnoreImplicit();
6538 if (!
Base->getType()->isArrayType())
6544 }
else if (
auto *ICE = dyn_cast<ImplicitCastExpr>(E)) {
6547 if (ICE->getCastKind() == CK_NoOp)
6549 if (ICE->getCastKind() != CK_DerivedToBase &&
6550 ICE->getCastKind() != CK_UncheckedDerivedToBase)
6554 if (Elt->isVirtual()) {
6563 LHS.Designator.Entries[PathLength]
6564 .getAsBaseOrMember().getPointer()));
6574 if (UnionPathLengths.empty())
6579 CompleteObject Obj =
6583 for (std::pair<unsigned, const FieldDecl *> LengthAndField :
6584 llvm::reverse(UnionPathLengths)) {
6586 SubobjectDesignator D = LHS.Designator;
6587 D.truncate(Info.Ctx, LHS.Base, LengthAndField.first);
6589 bool DuringInit = Info.isEvaluatingCtorDtor(LHS.Base, D.Entries) ==
6590 ConstructionPhase::AfterBases;
6591 StartLifetimeOfUnionMemberHandler StartLifetime{
6592 Info, LHSExpr, LengthAndField.second, DuringInit};
6601 CallRef
Call, EvalInfo &Info,
bool NonNull =
false,
6602 APValue **EvaluatedArg =
nullptr) {
6609 APValue &
V = PVD ? Info.CurrentCall->createParam(
Call, PVD, LV)
6610 : Info.CurrentCall->createTemporary(Arg, Arg->
getType(),
6611 ScopeKind::Call, LV);
6617 if (
NonNull &&
V.isLValue() &&
V.isNullPointer()) {
6618 Info.CCEDiag(Arg, diag::note_non_null_attribute_failed);
6631 bool RightToLeft =
false,
6632 LValue *ObjectArg =
nullptr) {
6634 llvm::SmallBitVector ForbiddenNullArgs;
6635 if (Callee->hasAttr<NonNullAttr>()) {
6636 ForbiddenNullArgs.resize(Args.size());
6637 for (
const auto *
Attr : Callee->specific_attrs<NonNullAttr>()) {
6638 if (!
Attr->args_size()) {
6639 ForbiddenNullArgs.set();
6642 for (
auto Idx :
Attr->args()) {
6643 unsigned ASTIdx = Idx.getASTIndex();
6644 if (ASTIdx >= Args.size())
6646 ForbiddenNullArgs[ASTIdx] =
true;
6650 for (
unsigned I = 0; I < Args.size(); I++) {
6651 unsigned Idx = RightToLeft ? Args.size() - I - 1 : I;
6653 Idx < Callee->getNumParams() ? Callee->getParamDecl(Idx) :
nullptr;
6654 bool NonNull = !ForbiddenNullArgs.empty() && ForbiddenNullArgs[Idx];
6659 if (!Info.noteFailure())
6664 ObjectArg->setFrom(Info.Ctx, *That);
6673 bool CopyObjectRepresentation) {
6675 CallStackFrame *Frame = Info.CurrentCall;
6676 APValue *RefValue = Info.getParamSlot(Frame->Arguments, Param);
6684 RefLValue.setFrom(Info.Ctx, *RefValue);
6687 CopyObjectRepresentation);
6693 const LValue *ObjectArg,
const Expr *E,
6695 const Stmt *Body, EvalInfo &Info,
6696 APValue &Result,
const LValue *ResultSlot) {
6697 if (!Info.CheckCallLimit(CallLoc))
6726 ObjectArg->moveInto(Result);
6735 if (!Info.checkingPotentialConstantExpression())
6737 Frame.LambdaThisCaptureField);
6740 StmtResult Ret = {Result, ResultSlot};
6742 if (ESR == ESR_Succeeded) {
6743 if (Callee->getReturnType()->isVoidType())
6745 Info.FFDiag(Callee->getEndLoc(), diag::note_constexpr_no_return);
6747 return ESR == ESR_Returned;
6754 EvalInfo &Info,
APValue &Result) {
6756 if (!Info.CheckCallLimit(CallLoc))
6761 Info.FFDiag(CallLoc, diag::note_constexpr_virtual_base) << RD;
6765 EvalInfo::EvaluatingConstructorRAII EvalObj(
6767 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries},
6774 StmtResult Ret = {RetVal,
nullptr};
6779 if ((*I)->getInit()->isValueDependent()) {
6783 FullExpressionRAII InitScope(Info);
6785 !InitScope.destroy())
6808 if (!Result.hasValue()) {
6821 BlockScopeRAII LifetimeExtendedScope(Info);
6824 unsigned BasesSeen = 0;
6829 auto SkipToField = [&](
FieldDecl *FD,
bool Indirect) {
6834 assert(Indirect &&
"fields out of order?");
6840 assert(FieldIt != RD->
field_end() &&
"missing field?");
6841 if (!FieldIt->isUnnamedBitField())
6844 Result.getStructField(FieldIt->getFieldIndex()));
6849 LValue Subobject =
This;
6850 LValue SubobjectParent =
This;
6855 if (I->isBaseInitializer()) {
6856 QualType BaseType(I->getBaseClass(), 0);
6860 assert(!BaseIt->
isVirtual() &&
"virtual base for literal type");
6862 "base class initializers not in expected order");
6866 BaseType->getAsCXXRecordDecl(), &Layout))
6868 Value = &Result.getStructBase(BasesSeen++);
6869 }
else if ((FD = I->getMember())) {
6874 Value = &Result.getUnionValue();
6876 SkipToField(FD,
false);
6882 auto IndirectFieldChain = IFD->chain();
6883 for (
auto *
C : IndirectFieldChain) {
6892 (
Value->isUnion() &&
6905 if (
C == IndirectFieldChain.back())
6906 SubobjectParent = Subobject;
6912 if (
C == IndirectFieldChain.front() && !RD->
isUnion())
6913 SkipToField(FD,
true);
6918 llvm_unreachable(
"unknown base initializer kind");
6925 if (
Init->isValueDependent()) {
6929 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &SubobjectParent,
6931 FullExpressionRAII InitScope(Info);
6937 if (!Info.noteFailure())
6946 if (!Info.noteFailure())
6954 if (I->isBaseInitializer() && BasesSeen == RD->
getNumBases())
6955 EvalObj.finishedConstructingBases();
6960 for (; FieldIt != RD->
field_end(); ++FieldIt) {
6961 if (!FieldIt->isUnnamedBitField())
6964 Result.getStructField(FieldIt->getFieldIndex()));
6968 EvalObj.finishedConstructingFields();
6972 LifetimeExtendedScope.destroy();
6978 EvalInfo &Info,
APValue &Result) {
6979 CallScopeRAII CallScope(Info);
6985 CallScope.destroy();
6995 if (
Value.isAbsent() && !
T->isNullPtrType()) {
6997 This.moveInto(Printable);
6999 diag::note_constexpr_destroy_out_of_lifetime)
7016 LValue ElemLV =
This;
7017 ElemLV.addArray(Info, &LocE, CAT);
7024 if (Size && Size >
Value.getArrayInitializedElts())
7029 for (Size =
Value.getArraySize(); Size != 0; --Size) {
7030 APValue &Elem =
Value.getArrayInitializedElt(Size - 1);
7043 if (
T.isDestructedType()) {
7045 diag::note_constexpr_unsupported_destruction)
7055 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_virtual_base) << RD;
7080 if (!Info.CheckCallLimit(CallRange.
getBegin()))
7089 CallStackFrame Frame(Info, CallRange,
Definition, &
This,
nullptr,
7094 EvalInfo::EvaluatingDestructorRAII EvalObj(
7096 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries});
7097 if (!EvalObj.DidInsert) {
7104 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_double_destroy);
7111 StmtResult Ret = {RetVal,
nullptr};
7124 for (
const FieldDecl *FD : llvm::reverse(Fields)) {
7125 if (FD->isUnnamedBitField())
7128 LValue Subobject =
This;
7132 APValue *SubobjectValue = &
Value.getStructField(FD->getFieldIndex());
7139 EvalObj.startedDestroyingBases();
7146 LValue Subobject =
This;
7148 BaseType->getAsCXXRecordDecl(), &Layout))
7151 APValue *SubobjectValue = &
Value.getStructBase(BasesLeft);
7156 assert(BasesLeft == 0 &&
"NumBases was wrong?");
7164struct DestroyObjectHandler {
7170 typedef bool result_type;
7171 bool failed() {
return false; }
7172 bool found(
APValue &Subobj, QualType SubobjType) {
7177 Info.FFDiag(E, diag::note_constexpr_destroy_complex_elem);
7180 bool found(APFloat &
Value, QualType SubobjType) {
7181 Info.FFDiag(E, diag::note_constexpr_destroy_complex_elem);
7213 if (Info.checkingPotentialConstantExpression() ||
7214 Info.SpeculativeEvaluationDepth)
7218 auto Caller = Info.getStdAllocatorCaller(
"allocate");
7220 Info.FFDiag(E->
getExprLoc(), Info.getLangOpts().CPlusPlus20
7221 ? diag::note_constexpr_new_untyped
7222 : diag::note_constexpr_new);
7226 QualType ElemType = Caller.ElemType;
7229 diag::note_constexpr_new_not_complete_object_type)
7237 bool IsNothrow =
false;
7238 for (
unsigned I = 1, N = E->
getNumArgs(); I != N; ++I) {
7246 APInt Size, Remainder;
7247 APInt ElemSizeAP(ByteSize.getBitWidth(), ElemSize.
getQuantity());
7248 APInt::udivrem(ByteSize, ElemSizeAP, Size, Remainder);
7249 if (Remainder != 0) {
7251 Info.FFDiag(E->
getExprLoc(), diag::note_constexpr_operator_new_bad_size)
7252 << ByteSize <<
APSInt(ElemSizeAP,
true) << ElemType;
7256 if (!Info.CheckArraySize(E->
getBeginLoc(), ByteSize.getActiveBits(),
7257 Size.getZExtValue(), !IsNothrow)) {
7259 Result.setNull(Info.Ctx, E->
getType());
7267 APValue *Val = Info.createHeapAlloc(Caller.Call, AllocType, Result);
7276 return DD->isVirtual();
7283 return DD->isVirtual() ? DD->getOperatorDelete() :
nullptr;
7294 DynAlloc::Kind DeallocKind) {
7295 auto PointerAsString = [&] {
7301 Info.FFDiag(E, diag::note_constexpr_delete_not_heap_alloc)
7302 << PointerAsString();
7305 return std::nullopt;
7308 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
7310 Info.FFDiag(E, diag::note_constexpr_double_delete);
7311 return std::nullopt;
7314 if (DeallocKind != (*Alloc)->getKind()) {
7316 Info.FFDiag(E, diag::note_constexpr_new_delete_mismatch)
7317 << DeallocKind << (*Alloc)->getKind() << AllocType;
7319 return std::nullopt;
7322 bool Subobject =
false;
7323 if (DeallocKind == DynAlloc::New) {
7324 Subobject =
Pointer.Designator.MostDerivedPathLength != 0 ||
7325 Pointer.Designator.isOnePastTheEnd();
7327 Subobject =
Pointer.Designator.Entries.size() != 1 ||
7328 Pointer.Designator.Entries[0].getAsArrayIndex() != 0;
7331 Info.FFDiag(E, diag::note_constexpr_delete_subobject)
7332 << PointerAsString() <<
Pointer.Designator.isOnePastTheEnd();
7333 return std::nullopt;
7341 if (Info.checkingPotentialConstantExpression() ||
7342 Info.SpeculativeEvaluationDepth)
7346 if (!Info.getStdAllocatorCaller(
"deallocate")) {
7354 for (
unsigned I = 1, N = E->
getNumArgs(); I != N; ++I)
7357 if (
Pointer.Designator.Invalid)
7362 if (
Pointer.isNullPointer()) {
7363 Info.CCEDiag(E->
getExprLoc(), diag::note_constexpr_deallocate_null);
7379class BitCastBuffer {
7385 SmallVector<std::optional<unsigned char>, 32> Bytes;
7387 static_assert(std::numeric_limits<unsigned char>::digits >= 8,
7388 "Need at least 8 bit unsigned char");
7390 bool TargetIsLittleEndian;
7393 BitCastBuffer(CharUnits Width,
bool TargetIsLittleEndian)
7394 : Bytes(Width.getQuantity()),
7395 TargetIsLittleEndian(TargetIsLittleEndian) {}
7397 [[nodiscard]]
bool readObject(CharUnits Offset, CharUnits Width,
7398 SmallVectorImpl<unsigned char> &Output)
const {
7399 for (CharUnits I = Offset, E = Offset + Width; I != E; ++I) {
7402 if (!Bytes[I.getQuantity()])
7404 Output.push_back(*Bytes[I.getQuantity()]);
7406 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
7407 std::reverse(Output.begin(), Output.end());
7411 void writeObject(CharUnits Offset, SmallVectorImpl<unsigned char> &Input) {
7412 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
7413 std::reverse(Input.begin(), Input.end());
7416 for (
unsigned char Byte : Input) {
7417 assert(!Bytes[Offset.
getQuantity() + Index] &&
"overwriting a byte?");
7423 size_t size() {
return Bytes.size(); }
7428class APValueToBufferConverter {
7430 BitCastBuffer Buffer;
7433 APValueToBufferConverter(EvalInfo &Info, CharUnits ObjectWidth,
7436 Buffer(ObjectWidth, Info.Ctx.getTargetInfo().isLittleEndian()),
7439 bool visit(
const APValue &Val, QualType Ty) {
7444 bool visit(
const APValue &Val, QualType Ty, CharUnits Offset) {
7445 assert((
size_t)Offset.
getQuantity() <= Buffer.size());
7458 return visitInt(Val.
getInt(), Ty, Offset);
7460 return visitFloat(Val.
getFloat(), Ty, Offset);
7462 return visitArray(Val, Ty, Offset);
7464 return visitRecord(Val, Ty, Offset);
7466 return visitVector(Val, Ty, Offset);
7470 return visitComplex(Val, Ty, Offset);
7478 diag::note_constexpr_bit_cast_unsupported_type)
7484 llvm_unreachable(
"LValue subobject in bit_cast?");
7486 llvm_unreachable(
"Unhandled APValue::ValueKind");
7489 bool visitRecord(
const APValue &Val, QualType Ty, CharUnits Offset) {
7494 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
7495 for (
size_t I = 0, E = CXXRD->getNumBases(); I != E; ++I) {
7496 const CXXBaseSpecifier &BS = CXXRD->bases_begin()[I];
7501 if (!
Base.isStruct())
7504 if (!visitRecord(Base, BS.
getType(),
7511 unsigned FieldIdx = 0;
7512 for (FieldDecl *FD : RD->
fields()) {
7513 if (FD->isBitField()) {
7515 diag::note_constexpr_bit_cast_unsupported_bitfield);
7521 assert(FieldOffsetBits % Info.Ctx.
getCharWidth() == 0 &&
7522 "only bit-fields can have sub-char alignment");
7523 CharUnits FieldOffset =
7525 QualType FieldTy = FD->getType();
7534 bool visitArray(
const APValue &Val, QualType Ty, CharUnits Offset) {
7544 for (
unsigned I = 0; I != NumInitializedElts; ++I) {
7546 if (!visit(SubObj, CAT->
getElementType(), Offset + I * ElemWidth))
7553 for (
unsigned I = NumInitializedElts; I != ArraySize; ++I) {
7554 if (!visit(Filler, CAT->
getElementType(), Offset + I * ElemWidth))
7562 bool visitComplex(
const APValue &Val, QualType Ty, CharUnits Offset) {
7563 const ComplexType *ComplexTy = Ty->
castAs<ComplexType>();
7570 Offset + (0 * EltSizeChars)))
7573 Offset + (1 * EltSizeChars)))
7577 Offset + (0 * EltSizeChars)))
7580 Offset + (1 * EltSizeChars)))
7587 bool visitVector(
const APValue &Val, QualType Ty, CharUnits Offset) {
7588 const VectorType *VTy = Ty->
castAs<VectorType>();
7603 llvm::APInt Res = llvm::APInt::getZero(NElts);
7604 for (
unsigned I = 0; I < NElts; ++I) {
7606 assert(EltAsInt.isUnsigned() && EltAsInt.getBitWidth() == 1 &&
7607 "bool vector element must be 1-bit unsigned integer!");
7609 Res.insertBits(EltAsInt, BigEndian ? (NElts - I - 1) : I);
7612 SmallVector<uint8_t, 8> Bytes(NElts / 8);
7613 llvm::StoreIntToMemory(Res, &*Bytes.begin(), NElts / 8);
7614 Buffer.writeObject(Offset, Bytes);
7619 for (
unsigned I = 0; I < NElts; ++I) {
7620 if (!visit(Val.
getVectorElt(I), EltTy, Offset + I * EltSizeChars))
7628 bool visitInt(
const APSInt &Val, QualType Ty, CharUnits Offset) {
7629 APSInt AdjustedVal = Val;
7630 unsigned Width = AdjustedVal.getBitWidth();
7633 AdjustedVal = AdjustedVal.extend(Width);
7636 SmallVector<uint8_t, 8> Bytes(Width / 8);
7637 llvm::StoreIntToMemory(AdjustedVal, &*Bytes.begin(), Width / 8);
7638 Buffer.writeObject(Offset, Bytes);
7642 bool visitFloat(
const APFloat &Val, QualType Ty, CharUnits Offset) {
7643 APSInt AsInt(Val.bitcastToAPInt());
7644 return visitInt(AsInt, Ty, Offset);
7648 static std::optional<BitCastBuffer>
7651 APValueToBufferConverter Converter(Info, DstSize, BCE);
7653 return std::nullopt;
7654 return Converter.Buffer;
7659class BufferToAPValueConverter {
7661 const BitCastBuffer &Buffer;
7664 BufferToAPValueConverter(EvalInfo &Info,
const BitCastBuffer &Buffer,
7666 : Info(Info), Buffer(Buffer), BCE(BCE) {}
7671 std::nullopt_t unsupportedType(QualType Ty) {
7673 diag::note_constexpr_bit_cast_unsupported_type)
7675 return std::nullopt;
7678 std::nullopt_t unrepresentableValue(QualType Ty,
const APSInt &Val) {
7680 diag::note_constexpr_bit_cast_unrepresentable_value)
7682 return std::nullopt;
7685 std::optional<APValue> visit(
const BuiltinType *
T, CharUnits Offset,
7686 const EnumType *EnumSugar =
nullptr) {
7689 return APValue((Expr *)
nullptr,
7691 APValue::NoLValuePath{},
true);
7700 const llvm::fltSemantics &Semantics =
7702 unsigned NumBits = llvm::APFloatBase::getSizeInBits(Semantics);
7703 assert(NumBits % 8 == 0);
7709 SmallVector<uint8_t, 8> Bytes;
7710 if (!Buffer.readObject(Offset,
SizeOf, Bytes)) {
7713 bool IsStdByte = EnumSugar && EnumSugar->isStdByteType();
7717 if (!IsStdByte && !IsUChar) {
7718 QualType DisplayType(EnumSugar ? (
const Type *)EnumSugar :
T, 0);
7720 diag::note_constexpr_bit_cast_indet_dest)
7721 << DisplayType << Info.Ctx.
getLangOpts().CharIsSigned;
7722 return std::nullopt;
7729 llvm::LoadIntFromMemory(Val, &*Bytes.begin(), Bytes.size());
7734 unsigned IntWidth = Info.Ctx.
getIntWidth(QualType(
T, 0));
7735 if (IntWidth != Val.getBitWidth()) {
7736 APSInt Truncated = Val.trunc(IntWidth);
7737 if (Truncated.extend(Val.getBitWidth()) != Val)
7738 return unrepresentableValue(QualType(
T, 0), Val);
7746 const llvm::fltSemantics &Semantics =
7751 return unsupportedType(QualType(
T, 0));
7754 std::optional<APValue> visit(
const RecordType *RTy, CharUnits Offset) {
7755 const RecordDecl *RD = RTy->getAsRecordDecl();
7758 unsigned NumBases = 0;
7759 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
7760 NumBases = CXXRD->getNumBases();
7762 APValue ResultVal(APValue::UninitStruct(), NumBases,
7766 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
7767 for (
size_t I = 0, E = CXXRD->getNumBases(); I != E; ++I) {
7768 const CXXBaseSpecifier &BS = CXXRD->bases_begin()[I];
7771 std::optional<APValue> SubObj = visitType(
7774 return std::nullopt;
7775 ResultVal.getStructBase(I) = *SubObj;
7780 unsigned FieldIdx = 0;
7781 for (FieldDecl *FD : RD->
fields()) {
7784 if (FD->isBitField()) {
7786 diag::note_constexpr_bit_cast_unsupported_bitfield);
7787 return std::nullopt;
7791 assert(FieldOffsetBits % Info.Ctx.
getCharWidth() == 0);
7793 CharUnits FieldOffset =
7796 QualType FieldTy = FD->getType();
7797 std::optional<APValue> SubObj = visitType(FieldTy, FieldOffset);
7799 return std::nullopt;
7800 ResultVal.getStructField(FieldIdx) = *SubObj;
7807 std::optional<APValue> visit(
const EnumType *Ty, CharUnits Offset) {
7808 QualType RepresentationType =
7809 Ty->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType();
7810 assert(!RepresentationType.
isNull() &&
7811 "enum forward decl should be caught by Sema");
7812 const auto *AsBuiltin =
7816 return visit(AsBuiltin, Offset, Ty);
7819 std::optional<APValue> visit(
const ConstantArrayType *Ty, CharUnits Offset) {
7823 APValue ArrayValue(APValue::UninitArray(), Size, Size);
7824 for (
size_t I = 0; I !=
Size; ++I) {
7825 std::optional<APValue> ElementValue =
7828 return std::nullopt;
7829 ArrayValue.getArrayInitializedElt(I) = std::move(*ElementValue);
7835 std::optional<APValue> visit(
const ComplexType *Ty, CharUnits Offset) {
7840 std::optional<APValue> Values[2];
7841 for (
unsigned I = 0; I != 2; ++I) {
7842 Values[I] = visitType(Ty->
getElementType(), Offset + I * ElementWidth);
7844 return std::nullopt;
7848 return APValue(Values[0]->getInt(), Values[1]->getInt());
7849 return APValue(Values[0]->getFloat(), Values[1]->getFloat());
7852 std::optional<APValue> visit(
const VectorType *VTy, CharUnits Offset) {
7858 SmallVector<APValue, 4> Elts;
7859 Elts.reserve(NElts);
7871 SmallVector<uint8_t, 8> Bytes;
7872 Bytes.reserve(NElts / 8);
7874 return std::nullopt;
7876 APSInt SValInt(NElts,
true);
7877 llvm::LoadIntFromMemory(SValInt, &*Bytes.begin(), Bytes.size());
7879 for (
unsigned I = 0; I < NElts; ++I) {
7881 SValInt.extractBits(1, (BigEndian ? NElts - I - 1 : I) * EltSize);
7889 for (
unsigned I = 0; I < NElts; ++I) {
7890 std::optional<APValue> EltValue =
7891 visitType(EltTy, Offset + I * EltSizeChars);
7893 return std::nullopt;
7894 Elts.push_back(std::move(*EltValue));
7898 return APValue(Elts.data(), Elts.size());
7901 std::optional<APValue> visit(
const Type *Ty, CharUnits Offset) {
7902 return unsupportedType(QualType(Ty, 0));
7905 std::optional<APValue> visitType(QualType Ty, CharUnits Offset) {
7909#define TYPE(Class, Base) \
7911 return visit(cast<Class##Type>(Can.getTypePtr()), Offset);
7912#define ABSTRACT_TYPE(Class, Base)
7913#define NON_CANONICAL_TYPE(Class, Base) \
7915 llvm_unreachable("non-canonical type should be impossible!");
7916#define DEPENDENT_TYPE(Class, Base) \
7919 "dependent types aren't supported in the constant evaluator!");
7920#define NON_CANONICAL_UNLESS_DEPENDENT(Class, Base) \
7922 llvm_unreachable("either dependent or not canonical!");
7923#include "clang/AST/TypeNodes.inc"
7925 llvm_unreachable(
"Unhandled Type::TypeClass");
7930 static std::optional<APValue> convert(EvalInfo &Info, BitCastBuffer &Buffer,
7932 BufferToAPValueConverter Converter(Info, Buffer, BCE);
7937static bool checkBitCastConstexprEligibilityType(SourceLocation Loc,
7938 QualType Ty, EvalInfo *Info,
7939 const ASTContext &Ctx,
7940 bool CheckingDest) {
7943 auto diag = [&](
int Reason) {
7945 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_invalid_type)
7946 << CheckingDest << (Reason == 4) << Reason;
7949 auto note = [&](
int Construct, QualType NoteTy, SourceLocation NoteLoc) {
7951 Info->Note(NoteLoc, diag::note_constexpr_bit_cast_invalid_subtype)
7952 << NoteTy << Construct << Ty;
7966 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(
Record)) {
7967 for (CXXBaseSpecifier &BS : CXXRD->bases())
7968 if (!checkBitCastConstexprEligibilityType(Loc, BS.
getType(), Info, Ctx,
7972 for (FieldDecl *FD :
Record->fields()) {
7973 if (FD->getType()->isReferenceType())
7975 if (!checkBitCastConstexprEligibilityType(Loc, FD->getType(), Info, Ctx,
7977 return note(0, FD->getType(), FD->getBeginLoc());
7983 Info, Ctx, CheckingDest))
7986 if (
const auto *VTy = Ty->
getAs<VectorType>()) {
7998 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_invalid_vector)
7999 << QualType(VTy, 0) << EltSize << NElts << Ctx.
getCharWidth();
8009 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_unsupported_type)
8018static bool checkBitCastConstexprEligibility(EvalInfo *Info,
8019 const ASTContext &Ctx,
8021 bool DestOK = checkBitCastConstexprEligibilityType(
8023 bool SourceOK = DestOK && checkBitCastConstexprEligibilityType(
8029static bool handleRValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
8033 "no host or target supports non 8-bit chars");
8035 if (!checkBitCastConstexprEligibility(&Info, Info.Ctx, BCE))
8039 std::optional<BitCastBuffer> Buffer =
8040 APValueToBufferConverter::convert(Info, SourceRValue, BCE);
8045 std::optional<APValue> MaybeDestValue =
8046 BufferToAPValueConverter::convert(Info, *Buffer, BCE);
8047 if (!MaybeDestValue)
8050 DestValue = std::move(*MaybeDestValue);
8054static bool handleLValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
8058 "no host or target supports non 8-bit chars");
8060 "LValueToRValueBitcast requires an lvalue operand!");
8062 LValue SourceLValue;
8064 SourceLValue.setFrom(Info.Ctx, SourceValue);
8067 SourceRValue,
true))
8070 return handleRValueToRValueBitCast(Info, DestValue, SourceRValue, BCE);
8073template <
class Derived>
8074class ExprEvaluatorBase
8075 :
public ConstStmtVisitor<Derived, bool> {
8077 Derived &getDerived() {
return static_cast<Derived&
>(*this); }
8078 bool DerivedSuccess(
const APValue &
V,
const Expr *E) {
8079 return getDerived().Success(
V, E);
8081 bool DerivedZeroInitialization(
const Expr *E) {
8082 return getDerived().ZeroInitialization(E);
8088 template<
typename ConditionalOperator>
8089 void CheckPotentialConstantConditional(
const ConditionalOperator *E) {
8090 assert(Info.checkingPotentialConstantExpression());
8093 SmallVector<PartialDiagnosticAt, 8>
Diag;
8095 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
8102 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
8109 Error(E, diag::note_constexpr_conditional_never_const);
8113 template<
typename ConditionalOperator>
8114 bool HandleConditionalOperator(
const ConditionalOperator *E) {
8117 if (Info.checkingPotentialConstantExpression() && Info.noteFailure()) {
8118 CheckPotentialConstantConditional(E);
8121 if (Info.noteFailure()) {
8129 return StmtVisitorTy::Visit(EvalExpr);
8134 typedef ConstStmtVisitor<Derived, bool> StmtVisitorTy;
8135 typedef ExprEvaluatorBase ExprEvaluatorBaseTy;
8137 OptionalDiagnostic CCEDiag(
const Expr *E,
diag::kind D) {
8138 return Info.CCEDiag(E, D);
8141 bool ZeroInitialization(
const Expr *E) {
return Error(E); }
8143 bool IsConstantEvaluatedBuiltinCall(
const CallExpr *E) {
8145 return BuiltinOp != 0 &&
8150 ExprEvaluatorBase(EvalInfo &Info) : Info(Info) {}
8152 EvalInfo &getEvalInfo() {
return Info; }
8160 bool Error(
const Expr *E) {
8161 return Error(E, diag::note_invalid_subexpr_in_const_expr);
8164 bool VisitStmt(
const Stmt *) {
8165 llvm_unreachable(
"Expression evaluator should not be called on stmts");
8167 bool VisitExpr(
const Expr *E) {
8171 bool VisitEmbedExpr(
const EmbedExpr *E) {
8172 const auto It = E->
begin();
8173 return StmtVisitorTy::Visit(*It);
8176 bool VisitPredefinedExpr(
const PredefinedExpr *E) {
8179 bool VisitConstantExpr(
const ConstantExpr *E) {
8183 return StmtVisitorTy::Visit(E->
getSubExpr());
8186 bool VisitParenExpr(
const ParenExpr *E)
8187 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8188 bool VisitUnaryExtension(
const UnaryOperator *E)
8189 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8190 bool VisitUnaryPlus(
const UnaryOperator *E)
8191 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8192 bool VisitChooseExpr(
const ChooseExpr *E)
8194 bool VisitGenericSelectionExpr(
const GenericSelectionExpr *E)
8196 bool VisitSubstNonTypeTemplateParmExpr(
const SubstNonTypeTemplateParmExpr *E)
8198 bool VisitCXXDefaultArgExpr(
const CXXDefaultArgExpr *E) {
8199 TempVersionRAII RAII(*Info.CurrentCall);
8200 SourceLocExprScopeGuard Guard(E, Info.CurrentCall->CurSourceLocExprScope);
8201 return StmtVisitorTy::Visit(E->
getExpr());
8203 bool VisitCXXDefaultInitExpr(
const CXXDefaultInitExpr *E) {
8204 TempVersionRAII RAII(*Info.CurrentCall);
8208 SourceLocExprScopeGuard Guard(E, Info.CurrentCall->CurSourceLocExprScope);
8209 return StmtVisitorTy::Visit(E->
getExpr());
8212 bool VisitExprWithCleanups(
const ExprWithCleanups *E) {
8213 FullExpressionRAII Scope(Info);
8214 return StmtVisitorTy::Visit(E->
getSubExpr()) && Scope.destroy();
8219 bool VisitCXXBindTemporaryExpr(
const CXXBindTemporaryExpr *E) {
8220 return StmtVisitorTy::Visit(E->
getSubExpr());
8223 bool VisitCXXReinterpretCastExpr(
const CXXReinterpretCastExpr *E) {
8224 CCEDiag(E, diag::note_constexpr_invalid_cast)
8225 << diag::ConstexprInvalidCastKind::Reinterpret;
8226 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8228 bool VisitCXXDynamicCastExpr(
const CXXDynamicCastExpr *E) {
8230 CCEDiag(E, diag::note_constexpr_invalid_cast)
8231 << diag::ConstexprInvalidCastKind::Dynamic;
8232 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8234 bool VisitBuiltinBitCastExpr(
const BuiltinBitCastExpr *E) {
8235 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8238 bool VisitBinaryOperator(
const BinaryOperator *E) {
8244 VisitIgnoredValue(E->
getLHS());
8245 return StmtVisitorTy::Visit(E->
getRHS());
8255 return DerivedSuccess(
Result, E);
8260 bool VisitCXXRewrittenBinaryOperator(
const CXXRewrittenBinaryOperator *E) {
8264 bool VisitBinaryConditionalOperator(
const BinaryConditionalOperator *E) {
8268 if (!
Evaluate(Info.CurrentCall->createTemporary(
8271 ScopeKind::FullExpression, CommonLV),
8275 return HandleConditionalOperator(E);
8278 bool VisitConditionalOperator(
const ConditionalOperator *E) {
8279 bool IsBcpCall =
false;
8284 if (
const CallExpr *CallCE =
8286 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
8293 if (Info.checkingPotentialConstantExpression() && IsBcpCall)
8296 FoldConstant Fold(Info, IsBcpCall);
8297 if (!HandleConditionalOperator(E)) {
8298 Fold.keepDiagnostics();
8305 bool VisitOpaqueValueExpr(
const OpaqueValueExpr *E) {
8306 if (
APValue *
Value = Info.CurrentCall->getCurrentTemporary(E);
8308 return DerivedSuccess(*
Value, E);
8314 assert(0 &&
"OpaqueValueExpr recursively refers to itself");
8317 return StmtVisitorTy::Visit(Source);
8320 bool VisitPseudoObjectExpr(
const PseudoObjectExpr *E) {
8321 for (
const Expr *SemE : E->
semantics()) {
8322 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
8331 if (OVE->isUnique())
8335 if (!
Evaluate(Info.CurrentCall->createTemporary(
8336 OVE, getStorageType(Info.Ctx, OVE),
8337 ScopeKind::FullExpression, LV),
8338 Info, OVE->getSourceExpr()))
8341 if (!StmtVisitorTy::Visit(SemE))
8351 bool VisitCallExpr(
const CallExpr *E) {
8353 if (!handleCallExpr(E,
Result,
nullptr))
8355 return DerivedSuccess(
Result, E);
8359 const LValue *ResultSlot) {
8360 CallScopeRAII CallScope(Info);
8363 QualType CalleeType =
Callee->getType();
8365 const FunctionDecl *FD =
nullptr;
8366 LValue *
This =
nullptr, ObjectArg;
8368 bool HasQualifier =
false;
8374 const CXXMethodDecl *
Member =
nullptr;
8375 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(Callee)) {
8379 Member = dyn_cast<CXXMethodDecl>(ME->getMemberDecl());
8381 return Error(Callee);
8383 HasQualifier = ME->hasQualifier();
8384 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(Callee)) {
8386 const ValueDecl *D =
8390 Member = dyn_cast<CXXMethodDecl>(D);
8392 return Error(Callee);
8394 }
else if (
const auto *PDE = dyn_cast<CXXPseudoDestructorExpr>(Callee)) {
8395 if (!Info.getLangOpts().CPlusPlus20)
8396 Info.CCEDiag(PDE, diag::note_constexpr_pseudo_destructor);
8400 return Error(Callee);
8407 if (!CalleeLV.getLValueOffset().isZero())
8408 return Error(Callee);
8409 if (CalleeLV.isNullPointer()) {
8410 Info.FFDiag(Callee, diag::note_constexpr_null_callee)
8411 <<
const_cast<Expr *
>(
Callee);
8414 FD = dyn_cast_or_null<FunctionDecl>(
8415 CalleeLV.getLValueBase().dyn_cast<
const ValueDecl *>());
8417 return Error(Callee);
8427 auto *OCE = dyn_cast<CXXOperatorCallExpr>(E);
8428 if (OCE && OCE->isAssignmentOp()) {
8429 assert(Args.size() == 2 &&
"wrong number of arguments in assignment");
8430 Call = Info.CurrentCall->createCall(FD);
8431 bool HasThis =
false;
8432 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FD))
8433 HasThis = MD->isImplicitObjectMemberFunction();
8441 const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD);
8461 if (Info.getLangOpts().CPlusPlus20 && OCE &&
8462 OCE->getOperator() == OO_Equal && MD->
isTrivial() &&
8466 Args = Args.slice(1);
8472 const CXXRecordDecl *ClosureClass = MD->
getParent();
8474 ClosureClass->
captures().empty() &&
8475 "Number of captures must be zero for conversion to function-ptr");
8477 const CXXMethodDecl *LambdaCallOp =
8486 "A generic lambda's static-invoker function must be a "
8487 "template specialization");
8489 FunctionTemplateDecl *CallOpTemplate =
8491 void *InsertPos =
nullptr;
8492 FunctionDecl *CorrespondingCallOpSpecialization =
8494 assert(CorrespondingCallOpSpecialization &&
8495 "We must always have a function call operator specialization "
8496 "that corresponds to our static invoker specialization");
8498 FD = CorrespondingCallOpSpecialization;
8507 return CallScope.destroy();
8517 Call = Info.CurrentCall->createCall(FD);
8523 SmallVector<QualType, 4> CovariantAdjustmentPath;
8525 auto *NamedMember = dyn_cast<CXXMethodDecl>(FD);
8526 if (NamedMember && NamedMember->isVirtual() && !HasQualifier) {
8529 CovariantAdjustmentPath);
8532 }
else if (NamedMember && NamedMember->isImplicitObjectMemberFunction()) {
8542 if (
auto *DD = dyn_cast<CXXDestructorDecl>(FD)) {
8543 assert(This &&
"no 'this' pointer for destructor call");
8546 CallScope.destroy();
8563 if (!CovariantAdjustmentPath.empty() &&
8565 CovariantAdjustmentPath))
8568 return CallScope.destroy();
8571 bool VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E) {
8574 bool VisitInitListExpr(
const InitListExpr *E) {
8576 return DerivedZeroInitialization(E);
8578 return StmtVisitorTy::Visit(E->
getInit(0));
8581 bool VisitImplicitValueInitExpr(
const ImplicitValueInitExpr *E) {
8582 return DerivedZeroInitialization(E);
8584 bool VisitCXXScalarValueInitExpr(
const CXXScalarValueInitExpr *E) {
8585 return DerivedZeroInitialization(E);
8587 bool VisitCXXNullPtrLiteralExpr(
const CXXNullPtrLiteralExpr *E) {
8588 return DerivedZeroInitialization(E);
8592 bool VisitMemberExpr(
const MemberExpr *E) {
8594 "missing temporary materialization conversion");
8595 assert(!E->
isArrow() &&
"missing call to bound member function?");
8603 const FieldDecl *FD = dyn_cast<FieldDecl>(E->
getMemberDecl());
8604 if (!FD)
return Error(E);
8608 "record / field mismatch");
8613 CompleteObject Obj(APValue::LValueBase(), &Val, BaseTy);
8614 SubobjectDesignator Designator(BaseTy);
8615 Designator.addDeclUnchecked(FD);
8619 DerivedSuccess(
Result, E);
8622 bool VisitExtVectorElementExpr(
const ExtVectorElementExpr *E) {
8628 SmallVector<uint32_t, 4> Indices;
8630 if (Indices.size() == 1) {
8632 return DerivedSuccess(Val.
getVectorElt(Indices[0]), E);
8635 SmallVector<APValue, 4> Elts;
8636 for (
unsigned I = 0; I < Indices.size(); ++I) {
8639 APValue VecResult(Elts.data(), Indices.size());
8640 return DerivedSuccess(VecResult, E);
8647 bool VisitCastExpr(
const CastExpr *E) {
8652 case CK_AtomicToNonAtomic: {
8659 return DerivedSuccess(AtomicVal, E);
8663 case CK_UserDefinedConversion:
8664 return StmtVisitorTy::Visit(E->
getSubExpr());
8666 case CK_LValueToRValue: {
8675 return DerivedSuccess(RVal, E);
8677 case CK_LValueToRValueBitCast: {
8678 APValue DestValue, SourceValue;
8681 if (!handleLValueToRValueBitCast(Info, DestValue, SourceValue, E))
8683 return DerivedSuccess(DestValue, E);
8686 case CK_AddressSpaceConversion: {
8690 return DerivedSuccess(
Value, E);
8697 bool VisitUnaryPostInc(
const UnaryOperator *UO) {
8698 return VisitUnaryPostIncDec(UO);
8700 bool VisitUnaryPostDec(
const UnaryOperator *UO) {
8701 return VisitUnaryPostIncDec(UO);
8703 bool VisitUnaryPostIncDec(
const UnaryOperator *UO) {
8704 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
8714 return DerivedSuccess(RVal, UO);
8717 bool VisitStmtExpr(
const StmtExpr *E) {
8720 llvm::SaveAndRestore NotCheckingForUB(Info.CheckingForUndefinedBehavior,
8727 BlockScopeRAII Scope(Info);
8732 const Expr *FinalExpr = dyn_cast<Expr>(*BI);
8734 Info.FFDiag((*BI)->getBeginLoc(),
8735 diag::note_constexpr_stmt_expr_unsupported);
8738 return this->Visit(FinalExpr) && Scope.destroy();
8744 if (ESR != ESR_Succeeded) {
8748 if (ESR != ESR_Failed)
8749 Info.FFDiag((*BI)->getBeginLoc(),
8750 diag::note_constexpr_stmt_expr_unsupported);
8755 llvm_unreachable(
"Return from function from the loop above.");
8758 bool VisitPackIndexingExpr(
const PackIndexingExpr *E) {
8763 void VisitIgnoredValue(
const Expr *E) {
8768 void VisitIgnoredBaseExpression(
const Expr *E) {
8771 if (Info.getLangOpts().MSVCCompat && !E->
HasSideEffects(Info.Ctx))
8773 VisitIgnoredValue(E);
8783template<
class Derived>
8784class LValueExprEvaluatorBase
8785 :
public ExprEvaluatorBase<Derived> {
8789 typedef LValueExprEvaluatorBase LValueExprEvaluatorBaseTy;
8790 typedef ExprEvaluatorBase<Derived> ExprEvaluatorBaseTy;
8792 bool Success(APValue::LValueBase B) {
8797 bool evaluatePointer(
const Expr *E, LValue &
Result) {
8802 LValueExprEvaluatorBase(EvalInfo &Info, LValue &
Result,
bool InvalidBaseOK)
8804 InvalidBaseOK(InvalidBaseOK) {}
8807 Result.setFrom(this->Info.Ctx,
V);
8811 bool VisitMemberExpr(
const MemberExpr *E) {
8823 EvalOK = this->Visit(E->
getBase());
8834 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(E->
getMemberDecl())) {
8837 "record / field mismatch");
8841 }
else if (
const IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(MD)) {
8845 return this->
Error(E);
8857 bool VisitBinaryOperator(
const BinaryOperator *E) {
8860 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
8868 bool VisitCastExpr(
const CastExpr *E) {
8871 return ExprEvaluatorBaseTy::VisitCastExpr(E);
8873 case CK_DerivedToBase:
8874 case CK_UncheckedDerivedToBase:
8921class LValueExprEvaluator
8922 :
public LValueExprEvaluatorBase<LValueExprEvaluator> {
8924 LValueExprEvaluator(EvalInfo &Info, LValue &
Result,
bool InvalidBaseOK) :
8925 LValueExprEvaluatorBaseTy(Info,
Result, InvalidBaseOK) {}
8927 bool VisitVarDecl(
const Expr *E,
const VarDecl *VD);
8928 bool VisitUnaryPreIncDec(
const UnaryOperator *UO);
8930 bool VisitCallExpr(
const CallExpr *E);
8931 bool VisitDeclRefExpr(
const DeclRefExpr *E);
8932 bool VisitPredefinedExpr(
const PredefinedExpr *E) {
return Success(E); }
8933 bool VisitMaterializeTemporaryExpr(
const MaterializeTemporaryExpr *E);
8934 bool VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E);
8935 bool VisitMemberExpr(
const MemberExpr *E);
8936 bool VisitStringLiteral(
const StringLiteral *E) {
8937 return Success(APValue::LValueBase(
8938 E, 0, Info.getASTContext().getNextStringLiteralVersion()));
8940 bool VisitObjCEncodeExpr(
const ObjCEncodeExpr *E) {
return Success(E); }
8941 bool VisitCXXTypeidExpr(
const CXXTypeidExpr *E);
8942 bool VisitCXXUuidofExpr(
const CXXUuidofExpr *E);
8943 bool VisitArraySubscriptExpr(
const ArraySubscriptExpr *E);
8944 bool VisitExtVectorElementExpr(
const ExtVectorElementExpr *E);
8945 bool VisitUnaryDeref(
const UnaryOperator *E);
8946 bool VisitUnaryReal(
const UnaryOperator *E);
8947 bool VisitUnaryImag(
const UnaryOperator *E);
8948 bool VisitUnaryPreInc(
const UnaryOperator *UO) {
8949 return VisitUnaryPreIncDec(UO);
8951 bool VisitUnaryPreDec(
const UnaryOperator *UO) {
8952 return VisitUnaryPreIncDec(UO);
8954 bool VisitBinAssign(
const BinaryOperator *BO);
8955 bool VisitCompoundAssignOperator(
const CompoundAssignOperator *CAO);
8957 bool VisitCastExpr(
const CastExpr *E) {
8960 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
8962 case CK_LValueBitCast:
8963 this->CCEDiag(E, diag::note_constexpr_invalid_cast)
8964 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
8968 Result.Designator.setInvalid();
8971 case CK_BaseToDerived:
8988 bool LValueToRValueConversion) {
8992 assert(Info.CurrentCall->This ==
nullptr &&
8993 "This should not be set for a static call operator");
9001 if (
Self->getType()->isReferenceType()) {
9002 APValue *RefValue = Info.getParamSlot(Info.CurrentCall->Arguments,
Self);
9004 Result.setFrom(Info.Ctx, *RefValue);
9006 const ParmVarDecl *VD = Info.CurrentCall->Arguments.getOrigParam(
Self);
9007 CallStackFrame *Frame =
9008 Info.getCallFrameAndDepth(Info.CurrentCall->Arguments.CallIndex)
9010 unsigned Version = Info.CurrentCall->Arguments.Version;
9011 Result.set({VD, Frame->Index, Version});
9014 Result = *Info.CurrentCall->This;
9024 if (LValueToRValueConversion) {
9028 Result.setFrom(Info.Ctx, RVal);
9039 bool InvalidBaseOK) {
9043 return LValueExprEvaluator(Info, Result, InvalidBaseOK).Visit(E);
9046bool LValueExprEvaluator::VisitDeclRefExpr(
const DeclRefExpr *E) {
9047 const ValueDecl *D = E->
getDecl();
9059 if (Info.checkingPotentialConstantExpression())
9062 if (
auto *FD = Info.CurrentCall->LambdaCaptureFields.lookup(D)) {
9069 if (
isa<FunctionDecl, MSGuidDecl, TemplateParamObjectDecl,
9070 UnnamedGlobalConstantDecl>(D))
9072 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
9073 return VisitVarDecl(E, VD);
9074 if (
const BindingDecl *BD = dyn_cast<BindingDecl>(D))
9075 return Visit(BD->getBinding());
9079bool LValueExprEvaluator::VisitVarDecl(
const Expr *E,
const VarDecl *VD) {
9080 CallStackFrame *Frame =
nullptr;
9081 unsigned Version = 0;
9089 CallStackFrame *CurrFrame = Info.CurrentCall;
9094 if (
auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
9095 if (CurrFrame->Arguments) {
9096 VD = CurrFrame->Arguments.getOrigParam(PVD);
9098 Info.getCallFrameAndDepth(CurrFrame->Arguments.CallIndex).first;
9099 Version = CurrFrame->Arguments.Version;
9103 Version = CurrFrame->getCurrentTemporaryVersion(VD);
9110 Result.set({VD, Frame->Index, Version});
9116 if (!Info.getLangOpts().CPlusPlus11) {
9117 Info.CCEDiag(E, diag::note_constexpr_ltor_non_integral, 1)
9119 Info.Note(VD->
getLocation(), diag::note_declared_at);
9128 Result.AllowConstexprUnknown =
true;
9135bool LValueExprEvaluator::VisitCallExpr(
const CallExpr *E) {
9136 if (!IsConstantEvaluatedBuiltinCall(E))
9137 return ExprEvaluatorBaseTy::VisitCallExpr(E);
9142 case Builtin::BIas_const:
9143 case Builtin::BIforward:
9144 case Builtin::BIforward_like:
9145 case Builtin::BImove:
9146 case Builtin::BImove_if_noexcept:
9148 return Visit(E->
getArg(0));
9152 return ExprEvaluatorBaseTy::VisitCallExpr(E);
9155bool LValueExprEvaluator::VisitMaterializeTemporaryExpr(
9156 const MaterializeTemporaryExpr *E) {
9164 for (
const Expr *E : CommaLHSs)
9173 if (Info.EvalMode == EvaluationMode::ConstantFold)
9180 Value = &Info.CurrentCall->createTemporary(
9196 for (
unsigned I = Adjustments.size(); I != 0; ) {
9198 switch (Adjustments[I].Kind) {
9203 Type = Adjustments[I].DerivedToBase.BasePath->getType();
9209 Type = Adjustments[I].Field->getType();
9214 Adjustments[I].Ptr.RHS))
9216 Type = Adjustments[I].Ptr.MPT->getPointeeType();
9225LValueExprEvaluator::VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E) {
9226 assert((!Info.getLangOpts().CPlusPlus || E->
isFileScope()) &&
9227 "lvalue compound literal in c++?");
9239 assert(!Info.getLangOpts().CPlusPlus);
9241 ScopeKind::Block,
Result);
9253bool LValueExprEvaluator::VisitCXXTypeidExpr(
const CXXTypeidExpr *E) {
9254 TypeInfoLValue TypeInfo;
9263 Info.CCEDiag(E, diag::note_constexpr_typeid_polymorphic)
9271 std::optional<DynamicType> DynType =
9276 TypeInfo = TypeInfoLValue(
9283bool LValueExprEvaluator::VisitCXXUuidofExpr(
const CXXUuidofExpr *E) {
9287bool LValueExprEvaluator::VisitMemberExpr(
const MemberExpr *E) {
9289 if (
const VarDecl *VD = dyn_cast<VarDecl>(E->
getMemberDecl())) {
9290 VisitIgnoredBaseExpression(E->
getBase());
9291 return VisitVarDecl(E, VD);
9295 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(E->
getMemberDecl())) {
9296 if (MD->isStatic()) {
9297 VisitIgnoredBaseExpression(E->
getBase());
9303 return LValueExprEvaluatorBaseTy::VisitMemberExpr(E);
9306bool LValueExprEvaluator::VisitExtVectorElementExpr(
9307 const ExtVectorElementExpr *E) {
9312 if (!Info.noteFailure())
9320 if (Indices.size() > 1)
9324 Result.setFrom(Info.Ctx, Val);
9328 const auto *VT = BaseType->
castAs<VectorType>();
9330 VT->getNumElements(), Indices[0]);
9336bool LValueExprEvaluator::VisitArraySubscriptExpr(
const ArraySubscriptExpr *E) {
9346 if (!Info.noteFailure())
9352 if (!Info.noteFailure())
9358 Result.setFrom(Info.Ctx, Val);
9360 VT->getNumElements(), Index.getExtValue());
9368 for (
const Expr *SubExpr : {E->
getLHS(), E->
getRHS()}) {
9369 if (SubExpr == E->
getBase() ? !evaluatePointer(SubExpr,
Result)
9371 if (!Info.noteFailure())
9381bool LValueExprEvaluator::VisitUnaryDeref(
const UnaryOperator *E) {
9392 Info.noteUndefinedBehavior();
9395bool LValueExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
9404bool LValueExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
9406 "lvalue __imag__ on scalar?");
9413bool LValueExprEvaluator::VisitUnaryPreIncDec(
const UnaryOperator *UO) {
9414 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9425bool LValueExprEvaluator::VisitCompoundAssignOperator(
9426 const CompoundAssignOperator *CAO) {
9427 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9435 if (!Info.noteFailure())
9450bool LValueExprEvaluator::VisitBinAssign(
const BinaryOperator *E) {
9451 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9459 if (!Info.noteFailure())
9467 if (Info.getLangOpts().CPlusPlus20 &&
9483 llvm::APInt &Result) {
9484 assert(isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
9485 "Can't get the size of a non alloc_size function");
9486 const auto *
Base = LVal.getLValueBase().get<
const Expr *>();
9488 std::optional<llvm::APInt> Size =
9489 CE->evaluateBytesReturnedByAllocSizeCall(Ctx);
9493 Result = std::move(*Size);
9512 dyn_cast_or_null<VarDecl>(
Base.dyn_cast<
const ValueDecl *>());
9517 if (!
Init ||
Init->getType().isNull())
9520 const Expr *E =
Init->IgnoreParens();
9521 if (!tryUnwrapAllocSizeCall(E))
9526 Result.setInvalid(E);
9529 Result.addUnsizedArray(Info, E, Pointee);
9534class PointerExprEvaluator
9535 :
public ExprEvaluatorBase<PointerExprEvaluator> {
9544 bool evaluateLValue(
const Expr *E, LValue &
Result) {
9548 bool evaluatePointer(
const Expr *E, LValue &
Result) {
9552 bool visitNonBuiltinCallExpr(
const CallExpr *E);
9555 PointerExprEvaluator(EvalInfo &info, LValue &
Result,
bool InvalidBaseOK)
9557 InvalidBaseOK(InvalidBaseOK) {}
9563 bool ZeroInitialization(
const Expr *E) {
9568 bool VisitBinaryOperator(
const BinaryOperator *E);
9569 bool VisitCastExpr(
const CastExpr* E);
9570 bool VisitUnaryAddrOf(
const UnaryOperator *E);
9571 bool VisitObjCStringLiteral(
const ObjCStringLiteral *E)
9573 bool VisitObjCBoxedExpr(
const ObjCBoxedExpr *E) {
9576 if (Info.noteFailure())
9580 bool VisitAddrLabelExpr(
const AddrLabelExpr *E)
9582 bool VisitCallExpr(
const CallExpr *E);
9583 bool VisitBuiltinCallExpr(
const CallExpr *E,
unsigned BuiltinOp);
9584 bool VisitBlockExpr(
const BlockExpr *E) {
9589 bool VisitCXXThisExpr(
const CXXThisExpr *E) {
9590 auto DiagnoseInvalidUseOfThis = [&] {
9591 if (Info.getLangOpts().CPlusPlus11)
9592 Info.FFDiag(E, diag::note_constexpr_this) << E->
isImplicit();
9598 if (Info.checkingPotentialConstantExpression())
9601 bool IsExplicitLambda =
9603 if (!IsExplicitLambda) {
9604 if (!Info.CurrentCall->This) {
9605 DiagnoseInvalidUseOfThis();
9609 Result = *Info.CurrentCall->This;
9617 if (!Info.CurrentCall->LambdaThisCaptureField) {
9618 if (IsExplicitLambda && !Info.CurrentCall->This) {
9619 DiagnoseInvalidUseOfThis();
9628 Info, E,
Result, MD, Info.CurrentCall->LambdaThisCaptureField,
9634 bool VisitCXXNewExpr(
const CXXNewExpr *E);
9636 bool VisitSourceLocExpr(
const SourceLocExpr *E) {
9637 assert(!E->
isIntType() &&
"SourceLocExpr isn't a pointer type?");
9639 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.
getDefaultExpr());
9640 Result.setFrom(Info.Ctx, LValResult);
9644 bool VisitEmbedExpr(
const EmbedExpr *E) {
9645 llvm::report_fatal_error(
"Not yet implemented for ExprConstant.cpp");
9649 bool VisitSYCLUniqueStableNameExpr(
const SYCLUniqueStableNameExpr *E) {
9654 ResultStr.size() + 1);
9656 CharTy, Size,
nullptr, ArraySizeModifier::Normal, 0);
9659 StringLiteral::Create(Info.Ctx, ResultStr, StringLiteralKind::Ordinary,
9662 evaluateLValue(SL,
Result);
9672 bool InvalidBaseOK) {
9675 return PointerExprEvaluator(Info, Result, InvalidBaseOK).Visit(E);
9678bool PointerExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
9681 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
9683 const Expr *PExp = E->
getLHS();
9684 const Expr *IExp = E->
getRHS();
9686 std::swap(PExp, IExp);
9688 bool EvalPtrOK = evaluatePointer(PExp,
Result);
9689 if (!EvalPtrOK && !Info.noteFailure())
9692 llvm::APSInt Offset;
9703bool PointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
9712 if (!FnII || !FnII->
isStr(
"current"))
9715 const auto *RD = dyn_cast<RecordDecl>(FD->
getParent());
9723bool PointerExprEvaluator::VisitCastExpr(
const CastExpr *E) {
9730 case CK_CPointerToObjCPointerCast:
9731 case CK_BlockPointerToObjCPointerCast:
9732 case CK_AnyPointerToBlockPointerCast:
9733 case CK_AddressSpaceConversion:
9734 if (!Visit(SubExpr))
9740 CCEDiag(E, diag::note_constexpr_invalid_cast)
9741 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
9743 Result.Designator.setInvalid();
9751 bool HasValidResult = !
Result.InvalidBase && !
Result.Designator.Invalid &&
9753 bool VoidPtrCastMaybeOK =
9765 if (VoidPtrCastMaybeOK &&
9766 (Info.getStdAllocatorCaller(
"allocate") ||
9768 Info.getLangOpts().CPlusPlus26)) {
9772 Info.getLangOpts().CPlusPlus) {
9774 CCEDiag(E, diag::note_constexpr_invalid_void_star_cast)
9775 << SubExpr->
getType() << Info.getLangOpts().CPlusPlus26
9776 <<
Result.Designator.getType(Info.Ctx).getCanonicalType()
9779 CCEDiag(E, diag::note_constexpr_invalid_cast)
9780 << diag::ConstexprInvalidCastKind::CastFrom
9783 CCEDiag(E, diag::note_constexpr_invalid_cast)
9784 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
9786 Result.Designator.setInvalid();
9790 ZeroInitialization(E);
9793 case CK_DerivedToBase:
9794 case CK_UncheckedDerivedToBase:
9806 case CK_BaseToDerived:
9818 case CK_NullToPointer:
9820 return ZeroInitialization(E);
9822 case CK_IntegralToPointer: {
9823 CCEDiag(E, diag::note_constexpr_invalid_cast)
9824 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
9831 if (
Value.isInt()) {
9833 uint64_t N =
Value.getInt().extOrTrunc(Size).getZExtValue();
9837 Result.Base = (Expr *)
nullptr;
9838 Result.InvalidBase =
false;
9840 Result.Designator.setInvalid();
9841 Result.IsNullPtr =
false;
9849 if (!
Value.isLValue())
9858 case CK_ArrayToPointerDecay: {
9860 if (!evaluateLValue(SubExpr,
Result))
9864 SubExpr, SubExpr->
getType(), ScopeKind::FullExpression,
Result);
9870 if (
auto *CAT = dyn_cast<ConstantArrayType>(AT))
9871 Result.addArray(Info, E, CAT);
9873 Result.addUnsizedArray(Info, E, AT->getElementType());
9877 case CK_FunctionToPointerDecay:
9878 return evaluateLValue(SubExpr,
Result);
9880 case CK_LValueToRValue: {
9889 return InvalidBaseOK &&
9895 return ExprEvaluatorBaseTy::VisitCastExpr(E);
9903 T =
T.getNonReferenceType();
9905 if (
T.getQualifiers().hasUnaligned())
9908 const bool AlignOfReturnsPreferred =
9909 Ctx.
getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver7;
9914 if (ExprKind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
9917 else if (ExprKind == UETT_AlignOf)
9920 llvm_unreachable(
"GetAlignOfType on a non-alignment ExprKind");
9933 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
9937 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(E))
9947 if (
const auto *E =
Value.Base.dyn_cast<
const Expr *>())
9955 EvalInfo &Info,
APSInt &Alignment) {
9958 if (Alignment < 0 || !Alignment.isPowerOf2()) {
9959 Info.FFDiag(E, diag::note_constexpr_invalid_alignment) << Alignment;
9962 unsigned SrcWidth = Info.Ctx.
getIntWidth(ForType);
9963 APSInt MaxValue(APInt::getOneBitSet(SrcWidth, SrcWidth - 1));
9964 if (APSInt::compareValues(Alignment, MaxValue) > 0) {
9965 Info.FFDiag(E, diag::note_constexpr_alignment_too_big)
9966 << MaxValue << ForType << Alignment;
9972 APSInt(Alignment.zextOrTrunc(SrcWidth),
true);
9973 assert(APSInt::compareValues(Alignment, ExtAlignment) == 0 &&
9974 "Alignment should not be changed by ext/trunc");
9975 Alignment = ExtAlignment;
9976 assert(Alignment.getBitWidth() == SrcWidth);
9981bool PointerExprEvaluator::visitNonBuiltinCallExpr(
const CallExpr *E) {
9982 if (ExprEvaluatorBaseTy::VisitCallExpr(E))
9990 Result.addUnsizedArray(Info, E, PointeeTy);
9994bool PointerExprEvaluator::VisitCallExpr(
const CallExpr *E) {
9995 if (!IsConstantEvaluatedBuiltinCall(E))
9996 return visitNonBuiltinCallExpr(E);
10003 return T->isCharType() ||
T->isChar8Type();
10006bool PointerExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *E,
10007 unsigned BuiltinOp) {
10011 switch (BuiltinOp) {
10012 case Builtin::BIaddressof:
10013 case Builtin::BI__addressof:
10014 case Builtin::BI__builtin_addressof:
10016 case Builtin::BI__builtin_assume_aligned: {
10023 LValue OffsetResult(
Result);
10035 int64_t AdditionalOffset = -Offset.getZExtValue();
10040 if (OffsetResult.Base) {
10043 if (BaseAlignment < Align) {
10044 Result.Designator.setInvalid();
10045 CCEDiag(E->
getArg(0), diag::note_constexpr_baa_insufficient_alignment)
10052 if (OffsetResult.Offset.alignTo(Align) != OffsetResult.Offset) {
10053 Result.Designator.setInvalid();
10057 diag::note_constexpr_baa_insufficient_alignment)
10060 diag::note_constexpr_baa_value_insufficient_alignment))
10061 << OffsetResult.Offset.getQuantity() << Align.
getQuantity();
10067 case Builtin::BI__builtin_align_up:
10068 case Builtin::BI__builtin_align_down: {
10088 assert(Alignment.getBitWidth() <= 64 &&
10089 "Cannot handle > 64-bit address-space");
10090 uint64_t Alignment64 = Alignment.getZExtValue();
10092 BuiltinOp == Builtin::BI__builtin_align_down
10093 ? llvm::alignDown(
Result.Offset.getQuantity(), Alignment64)
10094 : llvm::alignTo(
Result.Offset.getQuantity(), Alignment64));
10100 Info.FFDiag(E->
getArg(0), diag::note_constexpr_alignment_adjust)
10104 case Builtin::BI__builtin_operator_new:
10106 case Builtin::BI__builtin_launder:
10108 case Builtin::BIstrchr:
10109 case Builtin::BIwcschr:
10110 case Builtin::BImemchr:
10111 case Builtin::BIwmemchr:
10112 if (Info.getLangOpts().CPlusPlus11)
10113 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
10117 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
10119 case Builtin::BI__builtin_strchr:
10120 case Builtin::BI__builtin_wcschr:
10121 case Builtin::BI__builtin_memchr:
10122 case Builtin::BI__builtin_char_memchr:
10123 case Builtin::BI__builtin_wmemchr: {
10124 if (!Visit(E->
getArg(0)))
10130 if (BuiltinOp != Builtin::BIstrchr &&
10131 BuiltinOp != Builtin::BIwcschr &&
10132 BuiltinOp != Builtin::BI__builtin_strchr &&
10133 BuiltinOp != Builtin::BI__builtin_wcschr) {
10137 MaxLength = N.getZExtValue();
10140 if (MaxLength == 0u)
10141 return ZeroInitialization(E);
10142 if (!
Result.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
10143 Result.Designator.Invalid)
10145 QualType CharTy =
Result.Designator.getType(Info.Ctx);
10146 bool IsRawByte = BuiltinOp == Builtin::BImemchr ||
10147 BuiltinOp == Builtin::BI__builtin_memchr;
10148 assert(IsRawByte ||
10153 Info.FFDiag(E, diag::note_constexpr_ltor_incomplete_type) << CharTy;
10159 Info.FFDiag(E, diag::note_constexpr_memchr_unsupported)
10166 bool StopAtNull =
false;
10167 switch (BuiltinOp) {
10168 case Builtin::BIstrchr:
10169 case Builtin::BI__builtin_strchr:
10176 return ZeroInitialization(E);
10179 case Builtin::BImemchr:
10180 case Builtin::BI__builtin_memchr:
10181 case Builtin::BI__builtin_char_memchr:
10185 DesiredVal = Desired.trunc(Info.Ctx.
getCharWidth()).getZExtValue();
10188 case Builtin::BIwcschr:
10189 case Builtin::BI__builtin_wcschr:
10192 case Builtin::BIwmemchr:
10193 case Builtin::BI__builtin_wmemchr:
10195 DesiredVal = Desired.getZExtValue();
10199 for (; MaxLength; --MaxLength) {
10204 if (Char.
getInt().getZExtValue() == DesiredVal)
10206 if (StopAtNull && !Char.
getInt())
10212 return ZeroInitialization(E);
10215 case Builtin::BImemcpy:
10216 case Builtin::BImemmove:
10217 case Builtin::BIwmemcpy:
10218 case Builtin::BIwmemmove:
10219 if (Info.getLangOpts().CPlusPlus11)
10220 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
10224 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
10226 case Builtin::BI__builtin_memcpy:
10227 case Builtin::BI__builtin_memmove:
10228 case Builtin::BI__builtin_wmemcpy:
10229 case Builtin::BI__builtin_wmemmove: {
10230 bool WChar = BuiltinOp == Builtin::BIwmemcpy ||
10231 BuiltinOp == Builtin::BIwmemmove ||
10232 BuiltinOp == Builtin::BI__builtin_wmemcpy ||
10233 BuiltinOp == Builtin::BI__builtin_wmemmove;
10234 bool Move = BuiltinOp == Builtin::BImemmove ||
10235 BuiltinOp == Builtin::BIwmemmove ||
10236 BuiltinOp == Builtin::BI__builtin_memmove ||
10237 BuiltinOp == Builtin::BI__builtin_wmemmove;
10240 if (!Visit(E->
getArg(0)))
10251 assert(!N.isSigned() &&
"memcpy and friends take an unsigned size");
10261 if (!Src.Base || !Dest.Base) {
10263 (!Src.Base ? Src : Dest).moveInto(Val);
10264 Info.FFDiag(E, diag::note_constexpr_memcpy_null)
10265 <<
Move << WChar << !!Src.Base
10269 if (Src.Designator.Invalid || Dest.Designator.Invalid)
10275 QualType
T = Dest.Designator.getType(Info.Ctx);
10276 QualType SrcT = Src.Designator.getType(Info.Ctx);
10279 Info.FFDiag(E, diag::note_constexpr_memcpy_type_pun) <<
Move << SrcT <<
T;
10283 Info.FFDiag(E, diag::note_constexpr_memcpy_incomplete_type) <<
Move <<
T;
10286 if (!
T.isTriviallyCopyableType(Info.Ctx)) {
10287 Info.FFDiag(E, diag::note_constexpr_memcpy_nontrivial) <<
Move <<
T;
10297 llvm::APInt OrigN = N;
10298 llvm::APInt::udivrem(OrigN, TSize, N, Remainder);
10300 Info.FFDiag(E, diag::note_constexpr_memcpy_unsupported)
10302 << (unsigned)TSize;
10310 uint64_t RemainingSrcSize = Src.Designator.validIndexAdjustments().second;
10311 uint64_t RemainingDestSize = Dest.Designator.validIndexAdjustments().second;
10312 if (N.ugt(RemainingSrcSize) || N.ugt(RemainingDestSize)) {
10313 Info.FFDiag(E, diag::note_constexpr_memcpy_unsupported)
10314 <<
Move << WChar << (N.ugt(RemainingSrcSize) ? 1 : 2) <<
T
10318 uint64_t NElems = N.getZExtValue();
10324 uint64_t SrcOffset = Src.getLValueOffset().getQuantity();
10325 uint64_t DestOffset = Dest.getLValueOffset().getQuantity();
10326 if (DestOffset >= SrcOffset && DestOffset - SrcOffset < NBytes) {
10329 Info.FFDiag(E, diag::note_constexpr_memcpy_overlap) << WChar;
10337 }
else if (!Move && SrcOffset >= DestOffset &&
10338 SrcOffset - DestOffset < NBytes) {
10340 Info.FFDiag(E, diag::note_constexpr_memcpy_overlap) << WChar;
10369 QualType AllocType);
10372 const CXXConstructExpr *CCE,
10373 QualType AllocType);
10375bool PointerExprEvaluator::VisitCXXNewExpr(
const CXXNewExpr *E) {
10376 if (!Info.getLangOpts().CPlusPlus20)
10377 Info.CCEDiag(E, diag::note_constexpr_new);
10380 if (Info.SpeculativeEvaluationDepth)
10385 QualType TargetType = AllocType;
10387 bool IsNothrow =
false;
10388 bool IsPlacement =
false;
10406 }
else if (OperatorNew->isReservedGlobalPlacementOperator()) {
10407 if (Info.CurrentCall->isStdFunction() || Info.getLangOpts().CPlusPlus26 ||
10408 (Info.CurrentCall->CanEvalMSConstexpr &&
10409 OperatorNew->hasAttr<MSConstexprAttr>())) {
10412 if (
Result.Designator.Invalid)
10415 IsPlacement =
true;
10417 Info.FFDiag(E, diag::note_constexpr_new_placement)
10422 Info.FFDiag(E, diag::note_constexpr_new_placement)
10425 }
else if (!OperatorNew
10426 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
10427 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
10433 const InitListExpr *ResizedArrayILE =
nullptr;
10434 const CXXConstructExpr *ResizedArrayCCE =
nullptr;
10435 bool ValueInit =
false;
10437 if (std::optional<const Expr *> ArraySize = E->
getArraySize()) {
10438 const Expr *Stripped = *ArraySize;
10439 for (;
auto *ICE = dyn_cast<ImplicitCastExpr>(Stripped);
10440 Stripped = ICE->getSubExpr())
10441 if (ICE->getCastKind() != CK_NoOp &&
10442 ICE->getCastKind() != CK_IntegralCast)
10455 return ZeroInitialization(E);
10457 Info.FFDiag(*ArraySize, diag::note_constexpr_new_negative)
10458 <<
ArrayBound << (*ArraySize)->getSourceRange();
10464 if (!Info.CheckArraySize(ArraySize.value()->getExprLoc(),
10469 return ZeroInitialization(E);
10481 }
else if (
auto *CCE = dyn_cast<CXXConstructExpr>(
Init)) {
10482 ResizedArrayCCE = CCE;
10485 assert(CAT &&
"unexpected type for array initializer");
10489 llvm::APInt InitBound = CAT->
getSize().zext(Bits);
10490 llvm::APInt AllocBound =
ArrayBound.zext(Bits);
10491 if (InitBound.ugt(AllocBound)) {
10493 return ZeroInitialization(E);
10495 Info.FFDiag(*ArraySize, diag::note_constexpr_new_too_small)
10496 <<
toString(AllocBound, 10,
false)
10498 << (*ArraySize)->getSourceRange();
10504 if (InitBound != AllocBound)
10509 ArraySizeModifier::Normal, 0);
10512 "array allocation with non-array new");
10518 struct FindObjectHandler {
10521 QualType AllocType;
10525 typedef bool result_type;
10526 bool failed() {
return false; }
10527 bool checkConst(QualType QT) {
10529 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
10534 bool found(
APValue &Subobj, QualType SubobjType) {
10535 if (!checkConst(SubobjType))
10539 unsigned SubobjectSize = 1;
10540 unsigned AllocSize = 1;
10541 if (
auto *CAT = dyn_cast<ConstantArrayType>(AllocType))
10543 if (
auto *CAT = dyn_cast<ConstantArrayType>(SubobjType))
10545 if (SubobjectSize < AllocSize ||
10548 Info.FFDiag(E, diag::note_constexpr_placement_new_wrong_type)
10549 << SubobjType << AllocType;
10556 Info.FFDiag(E, diag::note_constexpr_construct_complex_elem);
10559 bool found(APFloat &
Value, QualType SubobjType) {
10560 Info.FFDiag(E, diag::note_constexpr_construct_complex_elem);
10563 } Handler = {Info, E, AllocType, AK,
nullptr};
10569 Val = Handler.Value;
10578 Val = Info.createHeapAlloc(E, AllocType,
Result);
10584 ImplicitValueInitExpr VIE(AllocType);
10587 }
else if (ResizedArrayILE) {
10591 }
else if (ResizedArrayCCE) {
10614class MemberPointerExprEvaluator
10615 :
public ExprEvaluatorBase<MemberPointerExprEvaluator> {
10618 bool Success(
const ValueDecl *D) {
10624 MemberPointerExprEvaluator(EvalInfo &Info, MemberPtr &
Result)
10631 bool ZeroInitialization(
const Expr *E) {
10632 return Success((
const ValueDecl*)
nullptr);
10635 bool VisitCastExpr(
const CastExpr *E);
10636 bool VisitUnaryAddrOf(
const UnaryOperator *E);
10644 return MemberPointerExprEvaluator(Info, Result).Visit(E);
10647bool MemberPointerExprEvaluator::VisitCastExpr(
const CastExpr *E) {
10650 return ExprEvaluatorBaseTy::VisitCastExpr(E);
10652 case CK_NullToMemberPointer:
10654 return ZeroInitialization(E);
10656 case CK_BaseToDerivedMemberPointer: {
10664 typedef std::reverse_iterator<CastExpr::path_const_iterator> ReverseIter;
10666 PathI != PathE; ++PathI) {
10667 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
10668 const CXXRecordDecl *Derived = (*PathI)->getType()->getAsCXXRecordDecl();
10669 if (!
Result.castToDerived(Derived))
10673 ->
castAs<MemberPointerType>()
10674 ->getMostRecentCXXRecordDecl()))
10679 case CK_DerivedToBaseMemberPointer:
10683 PathE = E->
path_end(); PathI != PathE; ++PathI) {
10684 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
10685 const CXXRecordDecl *
Base = (*PathI)->getType()->getAsCXXRecordDecl();
10686 if (!
Result.castToBase(Base))
10693bool MemberPointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
10704 class RecordExprEvaluator
10705 :
public ExprEvaluatorBase<RecordExprEvaluator> {
10706 const LValue &
This;
10710 RecordExprEvaluator(EvalInfo &info,
const LValue &This,
APValue &
Result)
10717 bool ZeroInitialization(
const Expr *E) {
10718 return ZeroInitialization(E, E->
getType());
10720 bool ZeroInitialization(
const Expr *E, QualType
T);
10722 bool VisitCallExpr(
const CallExpr *E) {
10723 return handleCallExpr(E,
Result, &This);
10725 bool VisitCastExpr(
const CastExpr *E);
10726 bool VisitInitListExpr(
const InitListExpr *E);
10727 bool VisitCXXConstructExpr(
const CXXConstructExpr *E) {
10728 return VisitCXXConstructExpr(E, E->
getType());
10731 bool VisitCXXInheritedCtorInitExpr(
const CXXInheritedCtorInitExpr *E);
10732 bool VisitCXXConstructExpr(
const CXXConstructExpr *E, QualType
T);
10733 bool VisitCXXStdInitializerListExpr(
const CXXStdInitializerListExpr *E);
10734 bool VisitBinCmp(
const BinaryOperator *E);
10735 bool VisitCXXParenListInitExpr(
const CXXParenListInitExpr *E);
10736 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
10737 ArrayRef<Expr *> Args);
10751 assert(!RD->
isUnion() &&
"Expected non-union class type");
10760 unsigned Index = 0;
10762 End = CD->
bases_end(); I != End; ++I, ++Index) {
10764 LValue Subobject =
This;
10768 Result.getStructBase(Index)))
10773 for (
const auto *I : RD->
fields()) {
10775 if (I->isUnnamedBitField() || I->getType()->isReferenceType())
10778 LValue Subobject =
This;
10784 Result.getStructField(I->getFieldIndex()), Info, Subobject, &VIE))
10791bool RecordExprEvaluator::ZeroInitialization(
const Expr *E, QualType
T) {
10798 while (I != RD->
field_end() && (*I)->isUnnamedBitField())
10805 LValue Subobject =
This;
10809 ImplicitValueInitExpr VIE(I->getType());
10814 Info.FFDiag(E, diag::note_constexpr_virtual_base) << RD;
10821bool RecordExprEvaluator::VisitCastExpr(
const CastExpr *E) {
10824 return ExprEvaluatorBaseTy::VisitCastExpr(E);
10826 case CK_ConstructorConversion:
10829 case CK_DerivedToBase:
10830 case CK_UncheckedDerivedToBase: {
10841 PathE = E->
path_end(); PathI != PathE; ++PathI) {
10842 assert(!(*PathI)->isVirtual() &&
"record rvalue with virtual base");
10843 const CXXRecordDecl *
Base = (*PathI)->getType()->getAsCXXRecordDecl();
10853bool RecordExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
10856 return VisitCXXParenListOrInitListExpr(E, E->
inits());
10859bool RecordExprEvaluator::VisitCXXParenListOrInitListExpr(
10864 auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
10866 EvalInfo::EvaluatingConstructorRAII EvalObj(
10868 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries},
10869 CXXRD && CXXRD->getNumBases());
10872 const FieldDecl *
Field;
10873 if (
auto *ILE = dyn_cast<InitListExpr>(ExprToVisit)) {
10874 Field = ILE->getInitializedFieldInUnion();
10875 }
else if (
auto *PLIE = dyn_cast<CXXParenListInitExpr>(ExprToVisit)) {
10876 Field = PLIE->getInitializedFieldInUnion();
10879 "Expression is neither an init list nor a C++ paren list");
10891 ImplicitValueInitExpr VIE(
Field->getType());
10892 const Expr *InitExpr = Args.empty() ? &VIE : Args[0];
10894 LValue Subobject =
This;
10899 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
10903 if (
Field->isBitField())
10913 Result =
APValue(APValue::UninitStruct(), CXXRD ? CXXRD->getNumBases() : 0,
10915 unsigned ElementNo = 0;
10919 if (CXXRD && CXXRD->getNumBases()) {
10920 for (
const auto &Base : CXXRD->bases()) {
10921 assert(ElementNo < Args.size() &&
"missing init for base class");
10922 const Expr *
Init = Args[ElementNo];
10924 LValue Subobject =
This;
10930 if (!Info.noteFailure())
10937 EvalObj.finishedConstructingBases();
10941 for (
const auto *Field : RD->
fields()) {
10944 if (
Field->isUnnamedBitField())
10947 LValue Subobject =
This;
10949 bool HaveInit = ElementNo < Args.size();
10954 Subobject, Field, &Layout))
10959 ImplicitValueInitExpr VIE(HaveInit ? Info.Ctx.
IntTy :
Field->getType());
10960 const Expr *
Init = HaveInit ? Args[ElementNo++] : &VIE;
10962 if (
Field->getType()->isIncompleteArrayType()) {
10967 Info.FFDiag(
Init, diag::note_constexpr_unsupported_flexible_array);
10974 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
10978 if (
Field->getType()->isReferenceType()) {
10982 if (!Info.noteFailure())
10987 (
Field->isBitField() &&
10989 if (!Info.noteFailure())
10995 EvalObj.finishedConstructingFields();
11000bool RecordExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E,
11010 return ZeroInitialization(E,
T);
11028 const Expr *SrcObj = E->
getArg(0);
11031 if (
const MaterializeTemporaryExpr *ME =
11032 dyn_cast<MaterializeTemporaryExpr>(SrcObj))
11033 return Visit(ME->getSubExpr());
11036 if (ZeroInit && !ZeroInitialization(E,
T))
11045bool RecordExprEvaluator::VisitCXXInheritedCtorInitExpr(
11046 const CXXInheritedCtorInitExpr *E) {
11047 if (!Info.CurrentCall) {
11048 assert(Info.checkingPotentialConstantExpression());
11067bool RecordExprEvaluator::VisitCXXStdInitializerListExpr(
11068 const CXXStdInitializerListExpr *E) {
11069 const ConstantArrayType *ArrayType =
11076 assert(ArrayType &&
"unexpected type for array initializer");
11079 Array.addArray(Info, E, ArrayType);
11083 Array.moveInto(
Result.getStructField(0));
11087 assert(Field !=
Record->field_end() &&
11090 "Expected std::initializer_list first field to be const E *");
11092 assert(Field !=
Record->field_end() &&
11093 "Expected std::initializer_list to have two fields");
11102 "Expected std::initializer_list second field to be const E *");
11107 Array.moveInto(
Result.getStructField(1));
11110 assert(++Field ==
Record->field_end() &&
11111 "Expected std::initializer_list to only have two fields");
11116bool RecordExprEvaluator::VisitLambdaExpr(
const LambdaExpr *E) {
11121 const size_t NumFields =
11126 "The number of lambda capture initializers should equal the number of "
11127 "fields within the closure type");
11135 for (
const auto *Field : ClosureClass->
fields()) {
11138 Expr *
const CurFieldInit = *CaptureInitIt++;
11145 LValue Subobject =
This;
11152 if (!Info.keepEvaluatingAfterFailure())
11161 APValue &Result, EvalInfo &Info) {
11164 "can't evaluate expression as a record rvalue");
11165 return RecordExprEvaluator(Info,
This, Result).Visit(E);
11176class TemporaryExprEvaluator
11177 :
public LValueExprEvaluatorBase<TemporaryExprEvaluator> {
11179 TemporaryExprEvaluator(EvalInfo &Info, LValue &
Result) :
11180 LValueExprEvaluatorBaseTy(Info,
Result,
false) {}
11183 bool VisitConstructExpr(
const Expr *E) {
11189 bool VisitCastExpr(
const CastExpr *E) {
11192 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
11194 case CK_ConstructorConversion:
11198 bool VisitInitListExpr(
const InitListExpr *E) {
11199 return VisitConstructExpr(E);
11201 bool VisitCXXConstructExpr(
const CXXConstructExpr *E) {
11202 return VisitConstructExpr(E);
11204 bool VisitCallExpr(
const CallExpr *E) {
11205 return VisitConstructExpr(E);
11207 bool VisitCXXStdInitializerListExpr(
const CXXStdInitializerListExpr *E) {
11208 return VisitConstructExpr(E);
11211 return VisitConstructExpr(E);
11220 return TemporaryExprEvaluator(Info, Result).Visit(E);
11228 class VectorExprEvaluator
11229 :
public ExprEvaluatorBase<VectorExprEvaluator> {
11236 bool Success(ArrayRef<APValue>
V,
const Expr *E) {
11237 assert(
V.size() == E->
getType()->
castAs<VectorType>()->getNumElements());
11243 assert(
V.isVector());
11247 bool ZeroInitialization(
const Expr *E);
11249 bool VisitUnaryReal(
const UnaryOperator *E)
11251 bool VisitCastExpr(
const CastExpr* E);
11252 bool VisitInitListExpr(
const InitListExpr *E);
11253 bool VisitUnaryImag(
const UnaryOperator *E);
11254 bool VisitBinaryOperator(
const BinaryOperator *E);
11255 bool VisitUnaryOperator(
const UnaryOperator *E);
11256 bool VisitCallExpr(
const CallExpr *E);
11257 bool VisitConvertVectorExpr(
const ConvertVectorExpr *E);
11258 bool VisitShuffleVectorExpr(
const ShuffleVectorExpr *E);
11267 "not a vector prvalue");
11268 return VectorExprEvaluator(Info, Result).Visit(E);
11272 assert(Val.
isVector() &&
"expected vector APValue");
11276 llvm::APInt
Result(NumElts, 0);
11278 for (
unsigned I = 0; I < NumElts; ++I) {
11280 assert(Elt.
isInt() &&
"expected integer element in bool vector");
11282 if (Elt.
getInt().getBoolValue())
11289bool VectorExprEvaluator::VisitCastExpr(
const CastExpr *E) {
11290 const VectorType *VTy = E->
getType()->
castAs<VectorType>();
11294 QualType SETy = SE->
getType();
11297 case CK_VectorSplat: {
11303 Val =
APValue(std::move(IntResult));
11308 Val =
APValue(std::move(FloatResult));
11325 Info.FFDiag(E, diag::note_constexpr_invalid_cast)
11326 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
11331 if (!handleRValueToRValueBitCast(Info,
Result, SVal, E))
11336 case CK_HLSLVectorTruncation: {
11341 for (
unsigned I = 0; I < NElts; I++)
11346 return ExprEvaluatorBaseTy::VisitCastExpr(E);
11351VectorExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
11368 unsigned CountInits = 0, CountElts = 0;
11369 while (CountElts < NumElements) {
11371 if (CountInits < NumInits
11377 for (
unsigned j = 0; j < vlen; j++)
11381 llvm::APSInt sInt(32);
11382 if (CountInits < NumInits) {
11387 Elements.push_back(
APValue(sInt));
11390 llvm::APFloat f(0.0);
11391 if (CountInits < NumInits) {
11396 Elements.push_back(
APValue(f));
11405VectorExprEvaluator::ZeroInitialization(
const Expr *E) {
11409 if (EltTy->isIntegerType())
11419bool VectorExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
11421 return ZeroInitialization(E);
11424bool VectorExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
11426 assert(Op != BO_PtrMemD && Op != BO_PtrMemI && Op != BO_Cmp &&
11427 "Operation not supported on vector types");
11429 if (Op == BO_Comma)
11430 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
11432 Expr *LHS = E->
getLHS();
11433 Expr *RHS = E->
getRHS();
11436 "Must both be vector types");
11439 assert(LHS->
getType()->
castAs<VectorType>()->getNumElements() ==
11443 "All operands must be the same size.");
11447 bool LHSOK =
Evaluate(LHSValue, Info, LHS);
11448 if (!LHSOK && !Info.noteFailure())
11450 if (!
Evaluate(RHSValue, Info, RHS) || !LHSOK)
11472 "Vector can only be int or float type");
11480 "Vector operator ~ can only be int");
11481 Elt.
getInt().flipAllBits();
11491 "Vector can only be int or float type");
11497 EltResult.setAllBits();
11499 EltResult.clearAllBits();
11505 return std::nullopt;
11509bool VectorExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
11515 const QualType ResultEltTy = VD->getElementType();
11519 if (!
Evaluate(SubExprValue, Info, SubExpr))
11532 "Vector length doesn't match type?");
11535 for (
unsigned EltNum = 0; EltNum < VD->getNumElements(); ++EltNum) {
11537 Info.Ctx, ResultEltTy, Op, SubExprValue.
getVectorElt(EltNum));
11540 ResultElements.push_back(*Elt);
11542 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
11551 Result =
APValue(APFloat(0.0));
11553 DestTy, Result.getFloat());
11564 Result.getFloat());
11569 DestTy, Result.getInt());
11573 Info.FFDiag(E, diag::err_convertvector_constexpr_unsupported_vector_cast)
11574 << SourceTy << DestTy;
11579 llvm::function_ref<APInt(
const APSInt &)> PackFn) {
11588 assert(LHSVecLen != 0 && LHSVecLen == RHSVecLen &&
11589 "pack builtin LHSVecLen must equal to RHSVecLen");
11598 const unsigned SrcPerLane = 128 / SrcBits;
11599 const unsigned Lanes = LHSVecLen * SrcBits / 128;
11602 Out.reserve(LHSVecLen + RHSVecLen);
11604 for (
unsigned Lane = 0; Lane != Lanes; ++Lane) {
11605 unsigned base = Lane * SrcPerLane;
11606 for (
unsigned I = 0; I != SrcPerLane; ++I)
11609 for (
unsigned I = 0; I != SrcPerLane; ++I)
11614 Result =
APValue(Out.data(), Out.size());
11618bool VectorExprEvaluator::VisitCallExpr(
const CallExpr *E) {
11619 if (!IsConstantEvaluatedBuiltinCall(E))
11620 return ExprEvaluatorBaseTy::VisitCallExpr(E);
11622 auto EvaluateBinOpExpr =
11624 APValue SourceLHS, SourceRHS;
11630 QualType DestEltTy = DestTy->getElementType();
11631 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
11634 ResultElements.reserve(SourceLen);
11636 if (SourceRHS.
isInt()) {
11638 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11640 ResultElements.push_back(
11644 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11647 ResultElements.push_back(
11657 case Builtin::BI__builtin_elementwise_popcount:
11658 case Builtin::BI__builtin_elementwise_bitreverse: {
11663 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
11666 ResultElements.reserve(SourceLen);
11668 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11671 case Builtin::BI__builtin_elementwise_popcount:
11672 ResultElements.push_back(
APValue(
11676 case Builtin::BI__builtin_elementwise_bitreverse:
11677 ResultElements.push_back(
11684 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
11686 case Builtin::BI__builtin_elementwise_abs: {
11691 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
11694 ResultElements.reserve(SourceLen);
11696 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11701 CurrentEle.getInt().
abs(),
11702 DestEltTy->isUnsignedIntegerOrEnumerationType()));
11703 ResultElements.push_back(Val);
11706 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
11709 case Builtin::BI__builtin_elementwise_add_sat:
11710 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
11711 return LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS);
11714 case Builtin::BI__builtin_elementwise_sub_sat:
11715 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
11716 return LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
11719 case clang::X86::BI__builtin_ia32_pavgb128:
11720 case clang::X86::BI__builtin_ia32_pavgw128:
11721 case clang::X86::BI__builtin_ia32_pavgb256:
11722 case clang::X86::BI__builtin_ia32_pavgw256:
11723 case clang::X86::BI__builtin_ia32_pavgb512:
11724 case clang::X86::BI__builtin_ia32_pavgw512:
11725 return EvaluateBinOpExpr(llvm::APIntOps::avgCeilU);
11727 case clang::X86::BI__builtin_ia32_pmulhuw128:
11728 case clang::X86::BI__builtin_ia32_pmulhuw256:
11729 case clang::X86::BI__builtin_ia32_pmulhuw512:
11730 return EvaluateBinOpExpr(llvm::APIntOps::mulhu);
11732 case clang::X86::BI__builtin_ia32_pmulhw128:
11733 case clang::X86::BI__builtin_ia32_pmulhw256:
11734 case clang::X86::BI__builtin_ia32_pmulhw512:
11735 return EvaluateBinOpExpr(llvm::APIntOps::mulhs);
11737 case clang::X86::BI__builtin_ia32_psllv2di:
11738 case clang::X86::BI__builtin_ia32_psllv4di:
11739 case clang::X86::BI__builtin_ia32_psllv4si:
11740 case clang::X86::BI__builtin_ia32_psllv8di:
11741 case clang::X86::BI__builtin_ia32_psllv8hi:
11742 case clang::X86::BI__builtin_ia32_psllv8si:
11743 case clang::X86::BI__builtin_ia32_psllv16hi:
11744 case clang::X86::BI__builtin_ia32_psllv16si:
11745 case clang::X86::BI__builtin_ia32_psllv32hi:
11746 case clang::X86::BI__builtin_ia32_psllwi128:
11747 case clang::X86::BI__builtin_ia32_pslldi128:
11748 case clang::X86::BI__builtin_ia32_psllqi128:
11749 case clang::X86::BI__builtin_ia32_psllwi256:
11750 case clang::X86::BI__builtin_ia32_pslldi256:
11751 case clang::X86::BI__builtin_ia32_psllqi256:
11752 case clang::X86::BI__builtin_ia32_psllwi512:
11753 case clang::X86::BI__builtin_ia32_pslldi512:
11754 case clang::X86::BI__builtin_ia32_psllqi512:
11755 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
11756 if (RHS.uge(LHS.getBitWidth())) {
11757 return APInt::getZero(LHS.getBitWidth());
11759 return LHS.shl(RHS.getZExtValue());
11762 case clang::X86::BI__builtin_ia32_psrav4si:
11763 case clang::X86::BI__builtin_ia32_psrav8di:
11764 case clang::X86::BI__builtin_ia32_psrav8hi:
11765 case clang::X86::BI__builtin_ia32_psrav8si:
11766 case clang::X86::BI__builtin_ia32_psrav16hi:
11767 case clang::X86::BI__builtin_ia32_psrav16si:
11768 case clang::X86::BI__builtin_ia32_psrav32hi:
11769 case clang::X86::BI__builtin_ia32_psravq128:
11770 case clang::X86::BI__builtin_ia32_psravq256:
11771 case clang::X86::BI__builtin_ia32_psrawi128:
11772 case clang::X86::BI__builtin_ia32_psradi128:
11773 case clang::X86::BI__builtin_ia32_psraqi128:
11774 case clang::X86::BI__builtin_ia32_psrawi256:
11775 case clang::X86::BI__builtin_ia32_psradi256:
11776 case clang::X86::BI__builtin_ia32_psraqi256:
11777 case clang::X86::BI__builtin_ia32_psrawi512:
11778 case clang::X86::BI__builtin_ia32_psradi512:
11779 case clang::X86::BI__builtin_ia32_psraqi512:
11780 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
11781 if (RHS.uge(LHS.getBitWidth())) {
11782 return LHS.ashr(LHS.getBitWidth() - 1);
11784 return LHS.ashr(RHS.getZExtValue());
11787 case clang::X86::BI__builtin_ia32_psrlv2di:
11788 case clang::X86::BI__builtin_ia32_psrlv4di:
11789 case clang::X86::BI__builtin_ia32_psrlv4si:
11790 case clang::X86::BI__builtin_ia32_psrlv8di:
11791 case clang::X86::BI__builtin_ia32_psrlv8hi:
11792 case clang::X86::BI__builtin_ia32_psrlv8si:
11793 case clang::X86::BI__builtin_ia32_psrlv16hi:
11794 case clang::X86::BI__builtin_ia32_psrlv16si:
11795 case clang::X86::BI__builtin_ia32_psrlv32hi:
11796 case clang::X86::BI__builtin_ia32_psrlwi128:
11797 case clang::X86::BI__builtin_ia32_psrldi128:
11798 case clang::X86::BI__builtin_ia32_psrlqi128:
11799 case clang::X86::BI__builtin_ia32_psrlwi256:
11800 case clang::X86::BI__builtin_ia32_psrldi256:
11801 case clang::X86::BI__builtin_ia32_psrlqi256:
11802 case clang::X86::BI__builtin_ia32_psrlwi512:
11803 case clang::X86::BI__builtin_ia32_psrldi512:
11804 case clang::X86::BI__builtin_ia32_psrlqi512:
11805 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
11806 if (RHS.uge(LHS.getBitWidth())) {
11807 return APInt::getZero(LHS.getBitWidth());
11809 return LHS.lshr(RHS.getZExtValue());
11811 case X86::BI__builtin_ia32_packsswb128:
11812 case X86::BI__builtin_ia32_packsswb256:
11813 case X86::BI__builtin_ia32_packsswb512:
11814 case X86::BI__builtin_ia32_packssdw128:
11815 case X86::BI__builtin_ia32_packssdw256:
11816 case X86::BI__builtin_ia32_packssdw512:
11818 return APSInt(Src).truncSSat(Src.getBitWidth() / 2);
11820 case X86::BI__builtin_ia32_packusdw128:
11821 case X86::BI__builtin_ia32_packusdw256:
11822 case X86::BI__builtin_ia32_packusdw512:
11823 case X86::BI__builtin_ia32_packuswb128:
11824 case X86::BI__builtin_ia32_packuswb256:
11825 case X86::BI__builtin_ia32_packuswb512:
11827 unsigned DstBits = Src.getBitWidth() / 2;
11828 if (Src.isNegative())
11829 return APInt::getZero(DstBits);
11830 if (Src.isIntN(DstBits))
11832 return APInt::getAllOnes(DstBits);
11834 case clang::X86::BI__builtin_ia32_pmuldq128:
11835 case clang::X86::BI__builtin_ia32_pmuldq256:
11836 case clang::X86::BI__builtin_ia32_pmuldq512:
11837 case clang::X86::BI__builtin_ia32_pmuludq128:
11838 case clang::X86::BI__builtin_ia32_pmuludq256:
11839 case clang::X86::BI__builtin_ia32_pmuludq512: {
11840 APValue SourceLHS, SourceRHS;
11847 ResultElements.reserve(SourceLen / 2);
11849 for (
unsigned EltNum = 0; EltNum < SourceLen; EltNum += 2) {
11854 case clang::X86::BI__builtin_ia32_pmuludq128:
11855 case clang::X86::BI__builtin_ia32_pmuludq256:
11856 case clang::X86::BI__builtin_ia32_pmuludq512:
11857 ResultElements.push_back(
11858 APValue(
APSInt(llvm::APIntOps::muluExtended(LHS, RHS),
true)));
11860 case clang::X86::BI__builtin_ia32_pmuldq128:
11861 case clang::X86::BI__builtin_ia32_pmuldq256:
11862 case clang::X86::BI__builtin_ia32_pmuldq512:
11863 ResultElements.push_back(
11864 APValue(
APSInt(llvm::APIntOps::mulsExtended(LHS, RHS),
false)));
11869 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
11872 case clang::X86::BI__builtin_ia32_vprotbi:
11873 case clang::X86::BI__builtin_ia32_vprotdi:
11874 case clang::X86::BI__builtin_ia32_vprotqi:
11875 case clang::X86::BI__builtin_ia32_vprotwi:
11876 case clang::X86::BI__builtin_ia32_prold128:
11877 case clang::X86::BI__builtin_ia32_prold256:
11878 case clang::X86::BI__builtin_ia32_prold512:
11879 case clang::X86::BI__builtin_ia32_prolq128:
11880 case clang::X86::BI__builtin_ia32_prolq256:
11881 case clang::X86::BI__builtin_ia32_prolq512:
11882 return EvaluateBinOpExpr(
11883 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS.rotl(RHS); });
11885 case clang::X86::BI__builtin_ia32_prord128:
11886 case clang::X86::BI__builtin_ia32_prord256:
11887 case clang::X86::BI__builtin_ia32_prord512:
11888 case clang::X86::BI__builtin_ia32_prorq128:
11889 case clang::X86::BI__builtin_ia32_prorq256:
11890 case clang::X86::BI__builtin_ia32_prorq512:
11891 return EvaluateBinOpExpr(
11892 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS.rotr(RHS); });
11894 case Builtin::BI__builtin_elementwise_max:
11895 case Builtin::BI__builtin_elementwise_min: {
11896 APValue SourceLHS, SourceRHS;
11901 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
11908 ResultElements.reserve(SourceLen);
11910 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11914 case Builtin::BI__builtin_elementwise_max:
11915 ResultElements.push_back(
11919 case Builtin::BI__builtin_elementwise_min:
11920 ResultElements.push_back(
11927 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
11929 case X86::BI__builtin_ia32_vpshldd128:
11930 case X86::BI__builtin_ia32_vpshldd256:
11931 case X86::BI__builtin_ia32_vpshldd512:
11932 case X86::BI__builtin_ia32_vpshldq128:
11933 case X86::BI__builtin_ia32_vpshldq256:
11934 case X86::BI__builtin_ia32_vpshldq512:
11935 case X86::BI__builtin_ia32_vpshldw128:
11936 case X86::BI__builtin_ia32_vpshldw256:
11937 case X86::BI__builtin_ia32_vpshldw512: {
11938 APValue SourceHi, SourceLo, SourceAmt;
11944 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
11947 ResultElements.reserve(SourceLen);
11950 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11953 APInt R = llvm::APIntOps::fshl(Hi, Lo, Amt);
11954 ResultElements.push_back(
11958 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
11960 case X86::BI__builtin_ia32_vpshrdd128:
11961 case X86::BI__builtin_ia32_vpshrdd256:
11962 case X86::BI__builtin_ia32_vpshrdd512:
11963 case X86::BI__builtin_ia32_vpshrdq128:
11964 case X86::BI__builtin_ia32_vpshrdq256:
11965 case X86::BI__builtin_ia32_vpshrdq512:
11966 case X86::BI__builtin_ia32_vpshrdw128:
11967 case X86::BI__builtin_ia32_vpshrdw256:
11968 case X86::BI__builtin_ia32_vpshrdw512: {
11970 APValue SourceHi, SourceLo, SourceAmt;
11976 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
11979 ResultElements.reserve(SourceLen);
11982 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11985 APInt R = llvm::APIntOps::fshr(Hi, Lo, Amt);
11986 ResultElements.push_back(
11990 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
11992 case X86::BI__builtin_ia32_blendpd:
11993 case X86::BI__builtin_ia32_blendpd256:
11994 case X86::BI__builtin_ia32_blendps:
11995 case X86::BI__builtin_ia32_blendps256:
11996 case X86::BI__builtin_ia32_pblendw128:
11997 case X86::BI__builtin_ia32_pblendw256:
11998 case X86::BI__builtin_ia32_pblendd128:
11999 case X86::BI__builtin_ia32_pblendd256: {
12000 APValue SourceF, SourceT, SourceC;
12009 ResultElements.reserve(SourceLen);
12010 for (
unsigned EltNum = 0; EltNum != SourceLen; ++EltNum) {
12013 ResultElements.push_back(
C[EltNum % 8] ?
T : F);
12016 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12019 case X86::BI__builtin_ia32_blendvpd:
12020 case X86::BI__builtin_ia32_blendvpd256:
12021 case X86::BI__builtin_ia32_blendvps:
12022 case X86::BI__builtin_ia32_blendvps256:
12023 case X86::BI__builtin_ia32_pblendvb128:
12024 case X86::BI__builtin_ia32_pblendvb256: {
12026 APValue SourceF, SourceT, SourceC;
12034 ResultElements.reserve(SourceLen);
12036 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12040 APInt M =
C.isInt() ? (
APInt)
C.getInt() :
C.getFloat().bitcastToAPInt();
12041 ResultElements.push_back(M.isNegative() ?
T : F);
12044 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12046 case X86::BI__builtin_ia32_selectb_128:
12047 case X86::BI__builtin_ia32_selectb_256:
12048 case X86::BI__builtin_ia32_selectb_512:
12049 case X86::BI__builtin_ia32_selectw_128:
12050 case X86::BI__builtin_ia32_selectw_256:
12051 case X86::BI__builtin_ia32_selectw_512:
12052 case X86::BI__builtin_ia32_selectd_128:
12053 case X86::BI__builtin_ia32_selectd_256:
12054 case X86::BI__builtin_ia32_selectd_512:
12055 case X86::BI__builtin_ia32_selectq_128:
12056 case X86::BI__builtin_ia32_selectq_256:
12057 case X86::BI__builtin_ia32_selectq_512:
12058 case X86::BI__builtin_ia32_selectph_128:
12059 case X86::BI__builtin_ia32_selectph_256:
12060 case X86::BI__builtin_ia32_selectph_512:
12061 case X86::BI__builtin_ia32_selectpbf_128:
12062 case X86::BI__builtin_ia32_selectpbf_256:
12063 case X86::BI__builtin_ia32_selectpbf_512:
12064 case X86::BI__builtin_ia32_selectps_128:
12065 case X86::BI__builtin_ia32_selectps_256:
12066 case X86::BI__builtin_ia32_selectps_512:
12067 case X86::BI__builtin_ia32_selectpd_128:
12068 case X86::BI__builtin_ia32_selectpd_256:
12069 case X86::BI__builtin_ia32_selectpd_512: {
12071 APValue SourceMask, SourceLHS, SourceRHS;
12080 ResultElements.reserve(SourceLen);
12082 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12085 ResultElements.push_back(Mask[EltNum] ? LHS : RHS);
12088 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12090 case Builtin::BI__builtin_elementwise_clzg:
12091 case Builtin::BI__builtin_elementwise_ctzg: {
12093 std::optional<APValue> Fallback;
12100 Fallback = FallbackTmp;
12103 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12106 ResultElements.reserve(SourceLen);
12108 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12113 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
12115 Builtin::BI__builtin_elementwise_ctzg);
12118 ResultElements.push_back(Fallback->getVectorElt(EltNum));
12122 case Builtin::BI__builtin_elementwise_clzg:
12123 ResultElements.push_back(
APValue(
12127 case Builtin::BI__builtin_elementwise_ctzg:
12128 ResultElements.push_back(
APValue(
12135 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12138 case Builtin::BI__builtin_elementwise_fma: {
12139 APValue SourceX, SourceY, SourceZ;
12147 ResultElements.reserve(SourceLen);
12149 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12154 (void)
Result.fusedMultiplyAdd(Y, Z, RM);
12157 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12160 case Builtin::BI__builtin_elementwise_fshl:
12161 case Builtin::BI__builtin_elementwise_fshr: {
12162 APValue SourceHi, SourceLo, SourceShift;
12168 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12174 ResultElements.reserve(SourceLen);
12175 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12180 case Builtin::BI__builtin_elementwise_fshl:
12181 ResultElements.push_back(
APValue(
12182 APSInt(llvm::APIntOps::fshl(Hi, Lo, Shift), Hi.isUnsigned())));
12184 case Builtin::BI__builtin_elementwise_fshr:
12185 ResultElements.push_back(
APValue(
12186 APSInt(llvm::APIntOps::fshr(Hi, Lo, Shift), Hi.isUnsigned())));
12191 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12194 case X86::BI__builtin_ia32_insertf32x4_256:
12195 case X86::BI__builtin_ia32_inserti32x4_256:
12196 case X86::BI__builtin_ia32_insertf64x2_256:
12197 case X86::BI__builtin_ia32_inserti64x2_256:
12198 case X86::BI__builtin_ia32_insertf32x4:
12199 case X86::BI__builtin_ia32_inserti32x4:
12200 case X86::BI__builtin_ia32_insertf64x2_512:
12201 case X86::BI__builtin_ia32_inserti64x2_512:
12202 case X86::BI__builtin_ia32_insertf32x8:
12203 case X86::BI__builtin_ia32_inserti32x8:
12204 case X86::BI__builtin_ia32_insertf64x4:
12205 case X86::BI__builtin_ia32_inserti64x4:
12206 case X86::BI__builtin_ia32_vinsertf128_ps256:
12207 case X86::BI__builtin_ia32_vinsertf128_pd256:
12208 case X86::BI__builtin_ia32_vinsertf128_si256:
12209 case X86::BI__builtin_ia32_insert128i256: {
12210 APValue SourceDst, SourceSub;
12222 assert(SubLen != 0 && DstLen != 0 && (DstLen % SubLen) == 0);
12223 unsigned NumLanes = DstLen / SubLen;
12224 unsigned LaneIdx = (Imm.getZExtValue() % NumLanes) * SubLen;
12227 ResultElements.reserve(DstLen);
12229 for (
unsigned EltNum = 0; EltNum < DstLen; ++EltNum) {
12230 if (EltNum >= LaneIdx && EltNum < LaneIdx + SubLen)
12231 ResultElements.push_back(SourceSub.
getVectorElt(EltNum - LaneIdx));
12233 ResultElements.push_back(SourceDst.
getVectorElt(EltNum));
12236 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12241bool VectorExprEvaluator::VisitConvertVectorExpr(
const ConvertVectorExpr *E) {
12247 QualType DestTy = E->
getType()->
castAs<VectorType>()->getElementType();
12248 QualType SourceTy = SourceVecType->
castAs<VectorType>()->getElementType();
12254 ResultElements.reserve(SourceLen);
12255 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12260 ResultElements.push_back(std::move(Elt));
12263 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12268 APValue const &VecVal2,
unsigned EltNum,
12270 unsigned const TotalElementsInInputVector1 = VecVal1.
getVectorLength();
12271 unsigned const TotalElementsInInputVector2 = VecVal2.
getVectorLength();
12274 int64_t
index = IndexVal.getExtValue();
12281 E, diag::err_shufflevector_minus_one_is_undefined_behavior_constexpr)
12287 index >= TotalElementsInInputVector1 + TotalElementsInInputVector2)
12288 llvm_unreachable(
"Out of bounds shuffle index");
12290 if (
index >= TotalElementsInInputVector1)
12297bool VectorExprEvaluator::VisitShuffleVectorExpr(
const ShuffleVectorExpr *E) {
12302 const Expr *Vec1 = E->
getExpr(0);
12306 const Expr *Vec2 = E->
getExpr(1);
12310 VectorType
const *DestVecTy = E->
getType()->
castAs<VectorType>();
12316 ResultElements.reserve(TotalElementsInOutputVector);
12317 for (
unsigned EltNum = 0; EltNum < TotalElementsInOutputVector; ++EltNum) {
12321 ResultElements.push_back(std::move(Elt));
12324 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12332 class ArrayExprEvaluator
12333 :
public ExprEvaluatorBase<ArrayExprEvaluator> {
12334 const LValue &
This;
12338 ArrayExprEvaluator(EvalInfo &Info,
const LValue &This,
APValue &
Result)
12342 assert(
V.isArray() &&
"expected array");
12347 bool ZeroInitialization(
const Expr *E) {
12348 const ConstantArrayType *CAT =
12363 if (!
Result.hasArrayFiller())
12367 LValue Subobject =
This;
12368 Subobject.addArray(Info, E, CAT);
12373 bool VisitCallExpr(
const CallExpr *E) {
12374 return handleCallExpr(E,
Result, &This);
12376 bool VisitInitListExpr(
const InitListExpr *E,
12377 QualType AllocType = QualType());
12378 bool VisitArrayInitLoopExpr(
const ArrayInitLoopExpr *E);
12379 bool VisitCXXConstructExpr(
const CXXConstructExpr *E);
12380 bool VisitCXXConstructExpr(
const CXXConstructExpr *E,
12381 const LValue &Subobject,
12383 bool VisitStringLiteral(
const StringLiteral *E,
12384 QualType AllocType = QualType()) {
12388 bool VisitCXXParenListInitExpr(
const CXXParenListInitExpr *E);
12389 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
12390 ArrayRef<Expr *> Args,
12391 const Expr *ArrayFiller,
12392 QualType AllocType = QualType());
12397 APValue &Result, EvalInfo &Info) {
12400 "not an array prvalue");
12401 return ArrayExprEvaluator(Info,
This, Result).Visit(E);
12409 "not an array prvalue");
12410 return ArrayExprEvaluator(Info,
This, Result)
12411 .VisitInitListExpr(ILE, AllocType);
12420 "not an array prvalue");
12421 return ArrayExprEvaluator(Info,
This, Result)
12422 .VisitCXXConstructExpr(CCE,
This, &Result, AllocType);
12431 if (
const InitListExpr *ILE = dyn_cast<InitListExpr>(FillerExpr)) {
12432 for (
unsigned I = 0, E = ILE->
getNumInits(); I != E; ++I) {
12437 if (ILE->hasArrayFiller() &&
12446bool ArrayExprEvaluator::VisitInitListExpr(
const InitListExpr *E,
12447 QualType AllocType) {
12461 return VisitStringLiteral(SL, AllocType);
12466 "transparent array list initialization is not string literal init?");
12472bool ArrayExprEvaluator::VisitCXXParenListOrInitListExpr(
12474 QualType AllocType) {
12480 assert((!
Result.isArray() ||
Result.getArrayInitializedElts() == 0) &&
12481 "zero-initialized array shouldn't have any initialized elts");
12486 unsigned NumEltsToInit = Args.size();
12491 if (NumEltsToInit != NumElts &&
12493 NumEltsToInit = NumElts;
12495 for (
auto *
Init : Args) {
12496 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts()))
12497 NumEltsToInit += EmbedS->getDataElementCount() - 1;
12499 if (NumEltsToInit > NumElts)
12500 NumEltsToInit = NumElts;
12503 LLVM_DEBUG(llvm::dbgs() <<
"The number of elements to initialize: "
12504 << NumEltsToInit <<
".\n");
12506 Result =
APValue(APValue::UninitArray(), NumEltsToInit, NumElts);
12511 for (
unsigned I = 0, E =
Result.getArrayInitializedElts(); I != E; ++I)
12512 Result.getArrayInitializedElt(I) = Filler;
12513 if (
Result.hasArrayFiller())
12517 LValue Subobject =
This;
12518 Subobject.addArray(Info, ExprToVisit, CAT);
12519 auto Eval = [&](
const Expr *
Init,
unsigned ArrayIndex) {
12520 if (
Init->isValueDependent())
12524 Subobject,
Init) ||
12527 if (!Info.noteFailure())
12533 unsigned ArrayIndex = 0;
12536 for (
unsigned Index = 0; Index != NumEltsToInit; ++Index) {
12537 const Expr *
Init = Index < Args.size() ? Args[Index] : ArrayFiller;
12538 if (ArrayIndex >= NumEltsToInit)
12540 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
12541 StringLiteral *SL = EmbedS->getDataStringLiteral();
12542 for (
unsigned I = EmbedS->getStartingElementPos(),
12543 N = EmbedS->getDataElementCount();
12544 I != EmbedS->getStartingElementPos() + N; ++I) {
12550 const FPOptions FPO =
12556 Result.getArrayInitializedElt(ArrayIndex) =
APValue(FValue);
12561 if (!Eval(
Init, ArrayIndex))
12567 if (!
Result.hasArrayFiller())
12572 assert(ArrayFiller &&
"no array filler for incomplete init list");
12578bool ArrayExprEvaluator::VisitArrayInitLoopExpr(
const ArrayInitLoopExpr *E) {
12581 !
Evaluate(Info.CurrentCall->createTemporary(
12584 ScopeKind::FullExpression, CommonLV),
12591 Result =
APValue(APValue::UninitArray(), Elements, Elements);
12593 LValue Subobject =
This;
12594 Subobject.addArray(Info, E, CAT);
12597 for (EvalInfo::ArrayInitLoopIndex Index(Info); Index != Elements; ++Index) {
12606 FullExpressionRAII Scope(Info);
12612 if (!Info.noteFailure())
12624bool ArrayExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E) {
12625 return VisitCXXConstructExpr(E, This, &
Result, E->
getType());
12628bool ArrayExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E,
12629 const LValue &Subobject,
12632 bool HadZeroInit =
Value->hasValue();
12639 HadZeroInit &&
Value->hasArrayFiller() ?
Value->getArrayFiller()
12642 *
Value =
APValue(APValue::UninitArray(), 0, FinalSize);
12643 if (FinalSize == 0)
12649 LValue ArrayElt = Subobject;
12650 ArrayElt.addArray(Info, E, CAT);
12656 for (
const unsigned N : {1u, FinalSize}) {
12657 unsigned OldElts =
Value->getArrayInitializedElts();
12662 APValue NewValue(APValue::UninitArray(), N, FinalSize);
12663 for (
unsigned I = 0; I < OldElts; ++I)
12664 NewValue.getArrayInitializedElt(I).swap(
12665 Value->getArrayInitializedElt(I));
12666 Value->swap(NewValue);
12669 for (
unsigned I = OldElts; I < N; ++I)
12670 Value->getArrayInitializedElt(I) = Filler;
12672 if (HasTrivialConstructor && N == FinalSize && FinalSize != 1) {
12675 APValue &FirstResult =
Value->getArrayInitializedElt(0);
12676 for (
unsigned I = OldElts; I < FinalSize; ++I)
12677 Value->getArrayInitializedElt(I) = FirstResult;
12679 for (
unsigned I = OldElts; I < N; ++I) {
12680 if (!VisitCXXConstructExpr(E, ArrayElt,
12681 &
Value->getArrayInitializedElt(I),
12688 if (Info.EvalStatus.
Diag && !Info.EvalStatus.
Diag->empty() &&
12689 !Info.keepEvaluatingAfterFailure())
12698 if (!
Type->isRecordType())
12701 return RecordExprEvaluator(Info, Subobject, *
Value)
12702 .VisitCXXConstructExpr(E,
Type);
12705bool ArrayExprEvaluator::VisitCXXParenListInitExpr(
12706 const CXXParenListInitExpr *E) {
12708 "Expression result is not a constant array type");
12710 return VisitCXXParenListOrInitListExpr(E, E->
getInitExprs(),
12723class IntExprEvaluator
12724 :
public ExprEvaluatorBase<IntExprEvaluator> {
12727 IntExprEvaluator(EvalInfo &info,
APValue &result)
12728 : ExprEvaluatorBaseTy(info),
Result(result) {}
12732 "Invalid evaluation result.");
12734 "Invalid evaluation result.");
12736 "Invalid evaluation result.");
12740 bool Success(
const llvm::APSInt &SI,
const Expr *E) {
12746 "Invalid evaluation result.");
12748 "Invalid evaluation result.");
12750 Result.getInt().setIsUnsigned(
12754 bool Success(
const llvm::APInt &I,
const Expr *E) {
12760 "Invalid evaluation result.");
12768 bool Success(CharUnits Size,
const Expr *E) {
12775 if (
V.isLValue() ||
V.isAddrLabelDiff() ||
V.isIndeterminate() ||
12776 V.allowConstexprUnknown()) {
12783 bool ZeroInitialization(
const Expr *E) {
return Success(0, E); }
12785 friend std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &,
12792 bool VisitIntegerLiteral(
const IntegerLiteral *E) {
12795 bool VisitCharacterLiteral(
const CharacterLiteral *E) {
12799 bool CheckReferencedDecl(
const Expr *E,
const Decl *D);
12800 bool VisitDeclRefExpr(
const DeclRefExpr *E) {
12801 if (CheckReferencedDecl(E, E->
getDecl()))
12804 return ExprEvaluatorBaseTy::VisitDeclRefExpr(E);
12806 bool VisitMemberExpr(
const MemberExpr *E) {
12808 VisitIgnoredBaseExpression(E->
getBase());
12812 return ExprEvaluatorBaseTy::VisitMemberExpr(E);
12815 bool VisitCallExpr(
const CallExpr *E);
12816 bool VisitBuiltinCallExpr(
const CallExpr *E,
unsigned BuiltinOp);
12817 bool VisitBinaryOperator(
const BinaryOperator *E);
12818 bool VisitOffsetOfExpr(
const OffsetOfExpr *E);
12819 bool VisitUnaryOperator(
const UnaryOperator *E);
12821 bool VisitCastExpr(
const CastExpr* E);
12822 bool VisitUnaryExprOrTypeTraitExpr(
const UnaryExprOrTypeTraitExpr *E);
12824 bool VisitCXXBoolLiteralExpr(
const CXXBoolLiteralExpr *E) {
12828 bool VisitObjCBoolLiteralExpr(
const ObjCBoolLiteralExpr *E) {
12832 bool VisitArrayInitIndexExpr(
const ArrayInitIndexExpr *E) {
12833 if (Info.ArrayInitIndex ==
uint64_t(-1)) {
12839 return Success(Info.ArrayInitIndex, E);
12843 bool VisitGNUNullExpr(
const GNUNullExpr *E) {
12844 return ZeroInitialization(E);
12847 bool VisitTypeTraitExpr(
const TypeTraitExpr *E) {
12856 bool VisitArrayTypeTraitExpr(
const ArrayTypeTraitExpr *E) {
12860 bool VisitExpressionTraitExpr(
const ExpressionTraitExpr *E) {
12864 bool VisitOpenACCAsteriskSizeExpr(
const OpenACCAsteriskSizeExpr *E) {
12871 bool VisitUnaryReal(
const UnaryOperator *E);
12872 bool VisitUnaryImag(
const UnaryOperator *E);
12874 bool VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E);
12875 bool VisitSizeOfPackExpr(
const SizeOfPackExpr *E);
12876 bool VisitSourceLocExpr(
const SourceLocExpr *E);
12877 bool VisitConceptSpecializationExpr(
const ConceptSpecializationExpr *E);
12882class FixedPointExprEvaluator
12883 :
public ExprEvaluatorBase<FixedPointExprEvaluator> {
12887 FixedPointExprEvaluator(EvalInfo &info,
APValue &result)
12888 : ExprEvaluatorBaseTy(info),
Result(result) {}
12890 bool Success(
const llvm::APInt &I,
const Expr *E) {
12901 return Success(
V.getFixedPoint(), E);
12904 bool Success(
const APFixedPoint &
V,
const Expr *E) {
12907 "Invalid evaluation result.");
12912 bool ZeroInitialization(
const Expr *E) {
12920 bool VisitFixedPointLiteral(
const FixedPointLiteral *E) {
12924 bool VisitCastExpr(
const CastExpr *E);
12925 bool VisitUnaryOperator(
const UnaryOperator *E);
12926 bool VisitBinaryOperator(
const BinaryOperator *E);
12942 return IntExprEvaluator(Info, Result).Visit(E);
12950 if (!Val.
isInt()) {
12953 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
12960bool IntExprEvaluator::VisitSourceLocExpr(
const SourceLocExpr *E) {
12962 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.
getDefaultExpr());
12971 if (!FixedPointExprEvaluator(Info, Val).Visit(E))
12990 Result = APFixedPoint(Val, FXSema);
13001bool IntExprEvaluator::CheckReferencedDecl(
const Expr* E,
const Decl* D) {
13003 if (
const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(D)) {
13005 bool SameSign = (ECD->getInitVal().isSigned()
13007 bool SameWidth = (ECD->getInitVal().getBitWidth()
13009 if (SameSign && SameWidth)
13010 return Success(ECD->getInitVal(), E);
13014 llvm::APSInt Val = ECD->getInitVal();
13016 Val.setIsSigned(!ECD->getInitVal().isSigned());
13029 assert(!
T->isDependentType() &&
"unexpected dependent type");
13034#define TYPE(ID, BASE)
13035#define DEPENDENT_TYPE(ID, BASE) case Type::ID:
13036#define NON_CANONICAL_TYPE(ID, BASE) case Type::ID:
13037#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(ID, BASE) case Type::ID:
13038#include "clang/AST/TypeNodes.inc"
13040 case Type::DeducedTemplateSpecialization:
13041 llvm_unreachable(
"unexpected non-canonical or dependent type");
13043 case Type::Builtin:
13045#define BUILTIN_TYPE(ID, SINGLETON_ID)
13046#define SIGNED_TYPE(ID, SINGLETON_ID) \
13047 case BuiltinType::ID: return GCCTypeClass::Integer;
13048#define FLOATING_TYPE(ID, SINGLETON_ID) \
13049 case BuiltinType::ID: return GCCTypeClass::RealFloat;
13050#define PLACEHOLDER_TYPE(ID, SINGLETON_ID) \
13051 case BuiltinType::ID: break;
13052#include "clang/AST/BuiltinTypes.def"
13053 case BuiltinType::Void:
13056 case BuiltinType::Bool:
13059 case BuiltinType::Char_U:
13060 case BuiltinType::UChar:
13061 case BuiltinType::WChar_U:
13062 case BuiltinType::Char8:
13063 case BuiltinType::Char16:
13064 case BuiltinType::Char32:
13065 case BuiltinType::UShort:
13066 case BuiltinType::UInt:
13067 case BuiltinType::ULong:
13068 case BuiltinType::ULongLong:
13069 case BuiltinType::UInt128:
13072 case BuiltinType::UShortAccum:
13073 case BuiltinType::UAccum:
13074 case BuiltinType::ULongAccum:
13075 case BuiltinType::UShortFract:
13076 case BuiltinType::UFract:
13077 case BuiltinType::ULongFract:
13078 case BuiltinType::SatUShortAccum:
13079 case BuiltinType::SatUAccum:
13080 case BuiltinType::SatULongAccum:
13081 case BuiltinType::SatUShortFract:
13082 case BuiltinType::SatUFract:
13083 case BuiltinType::SatULongFract:
13086 case BuiltinType::NullPtr:
13088 case BuiltinType::ObjCId:
13089 case BuiltinType::ObjCClass:
13090 case BuiltinType::ObjCSel:
13091#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
13092 case BuiltinType::Id:
13093#include "clang/Basic/OpenCLImageTypes.def"
13094#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
13095 case BuiltinType::Id:
13096#include "clang/Basic/OpenCLExtensionTypes.def"
13097 case BuiltinType::OCLSampler:
13098 case BuiltinType::OCLEvent:
13099 case BuiltinType::OCLClkEvent:
13100 case BuiltinType::OCLQueue:
13101 case BuiltinType::OCLReserveID:
13102#define SVE_TYPE(Name, Id, SingletonId) \
13103 case BuiltinType::Id:
13104#include "clang/Basic/AArch64ACLETypes.def"
13105#define PPC_VECTOR_TYPE(Name, Id, Size) \
13106 case BuiltinType::Id:
13107#include "clang/Basic/PPCTypes.def"
13108#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
13109#include "clang/Basic/RISCVVTypes.def"
13110#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
13111#include "clang/Basic/WebAssemblyReferenceTypes.def"
13112#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
13113#include "clang/Basic/AMDGPUTypes.def"
13114#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
13115#include "clang/Basic/HLSLIntangibleTypes.def"
13118 case BuiltinType::Dependent:
13119 llvm_unreachable(
"unexpected dependent type");
13121 llvm_unreachable(
"unexpected placeholder type");
13126 case Type::Pointer:
13127 case Type::ConstantArray:
13128 case Type::VariableArray:
13129 case Type::IncompleteArray:
13130 case Type::FunctionNoProto:
13131 case Type::FunctionProto:
13132 case Type::ArrayParameter:
13135 case Type::MemberPointer:
13140 case Type::Complex:
13153 case Type::ExtVector:
13156 case Type::BlockPointer:
13157 case Type::ConstantMatrix:
13158 case Type::ObjCObject:
13159 case Type::ObjCInterface:
13160 case Type::ObjCObjectPointer:
13162 case Type::HLSLAttributedResource:
13163 case Type::HLSLInlineSpirv:
13171 case Type::LValueReference:
13172 case Type::RValueReference:
13173 llvm_unreachable(
"invalid type for expression");
13176 llvm_unreachable(
"unexpected type class");
13201 if (
Base.isNull()) {
13204 }
else if (
const Expr *E =
Base.dyn_cast<
const Expr *>()) {
13223 SpeculativeEvaluationRAII SpeculativeEval(Info);
13228 FoldConstant Fold(Info,
true);
13246 if (ArgType->isIntegralOrEnumerationType() || ArgType->isFloatingType() ||
13247 ArgType->isAnyComplexType() || ArgType->isPointerType() ||
13248 ArgType->isNullPtrType()) {
13251 Fold.keepDiagnostics();
13260 return V.hasValue();
13271 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
13295 const auto *Cast = dyn_cast<CastExpr>(NoParens);
13296 if (Cast ==
nullptr)
13301 auto CastKind = Cast->getCastKind();
13303 CastKind != CK_AddressSpaceConversion)
13306 const auto *SubExpr = Cast->getSubExpr();
13328 assert(!LVal.Designator.Invalid);
13330 auto IsLastOrInvalidFieldDecl = [&Ctx](
const FieldDecl *FD) {
13338 auto &
Base = LVal.getLValueBase();
13339 if (
auto *ME = dyn_cast_or_null<MemberExpr>(
Base.dyn_cast<
const Expr *>())) {
13340 if (
auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
13341 if (!IsLastOrInvalidFieldDecl(FD))
13343 }
else if (
auto *IFD = dyn_cast<IndirectFieldDecl>(ME->getMemberDecl())) {
13344 for (
auto *FD : IFD->chain()) {
13353 if (LVal.Designator.FirstEntryIsAnUnsizedArray) {
13357 if (BaseType->isIncompleteArrayType())
13363 for (
unsigned E = LVal.Designator.Entries.size(); I != E; ++I) {
13364 const auto &Entry = LVal.Designator.Entries[I];
13365 if (BaseType->isArrayType()) {
13371 uint64_t Index = Entry.getAsArrayIndex();
13375 }
else if (BaseType->isAnyComplexType()) {
13376 const auto *CT = BaseType->castAs<
ComplexType>();
13377 uint64_t Index = Entry.getAsArrayIndex();
13381 }
else if (
auto *FD = getAsField(Entry)) {
13382 if (!IsLastOrInvalidFieldDecl(FD))
13386 assert(getAsBaseClass(Entry) &&
"Expecting cast to a base class");
13398 if (LVal.Designator.Invalid)
13401 if (!LVal.Designator.Entries.empty())
13402 return LVal.Designator.isMostDerivedAnUnsizedArray();
13404 if (!LVal.InvalidBase)
13416 const SubobjectDesignator &
Designator = LVal.Designator;
13428 auto isFlexibleArrayMember = [&] {
13430 FAMKind StrictFlexArraysLevel =
13433 if (
Designator.isMostDerivedAnUnsizedArray())
13436 if (StrictFlexArraysLevel == FAMKind::Default)
13439 if (
Designator.getMostDerivedArraySize() == 0 &&
13440 StrictFlexArraysLevel != FAMKind::IncompleteOnly)
13443 if (
Designator.getMostDerivedArraySize() == 1 &&
13444 StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete)
13450 return LVal.InvalidBase &&
13452 Designator.MostDerivedIsArrayElement && isFlexibleArrayMember() &&
13460 auto CharUnitsMax = std::numeric_limits<CharUnits::QuantityType>::max();
13461 if (Int.ugt(CharUnitsMax))
13471 if (!
T.isNull() &&
T->isStructureType() &&
13472 T->castAsRecordDecl()->hasFlexibleArrayMember())
13473 if (
const auto *
V = LV.getLValueBase().dyn_cast<
const ValueDecl *>())
13474 if (
const auto *VD = dyn_cast<VarDecl>(
V))
13486 unsigned Type,
const LValue &LVal,
13505 if (!(
Type & 1) || LVal.Designator.Invalid || DetermineForCompleteObject) {
13507 if (
Type == 3 && !DetermineForCompleteObject)
13510 llvm::APInt APEndOffset;
13511 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
13515 if (LVal.InvalidBase)
13519 const bool Ret = CheckedHandleSizeof(BaseTy, EndOffset);
13525 const SubobjectDesignator &
Designator = LVal.Designator;
13537 llvm::APInt APEndOffset;
13538 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
13550 if (!CheckedHandleSizeof(
Designator.MostDerivedType, BytesPerElem))
13556 int64_t ElemsRemaining;
13559 uint64_t ArraySize =
Designator.getMostDerivedArraySize();
13560 uint64_t ArrayIndex =
Designator.Entries.back().getAsArrayIndex();
13561 ElemsRemaining = ArraySize <= ArrayIndex ? 0 : ArraySize - ArrayIndex;
13563 ElemsRemaining =
Designator.isOnePastTheEnd() ? 0 : 1;
13566 EndOffset = LVal.getLValueOffset() + BytesPerElem * ElemsRemaining;
13576 EvalInfo &Info, uint64_t &Size) {
13583 SpeculativeEvaluationRAII SpeculativeEval(Info);
13584 IgnoreSideEffectsRAII Fold(Info);
13592 LVal.setFrom(Info.Ctx, RVal);
13600 if (LVal.getLValueOffset().isNegative()) {
13611 if (EndOffset <= LVal.getLValueOffset())
13614 Size = (EndOffset - LVal.getLValueOffset()).getQuantity();
13618bool IntExprEvaluator::VisitCallExpr(
const CallExpr *E) {
13619 if (!IsConstantEvaluatedBuiltinCall(E))
13620 return ExprEvaluatorBaseTy::VisitCallExpr(E);
13637 Info.FFDiag(E->
getArg(0));
13643 assert(SrcInt.getBitWidth() >= Alignment.getBitWidth() &&
13644 "Bit widths must be the same");
13651bool IntExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *E,
13652 unsigned BuiltinOp) {
13654 auto HandleMaskBinOp =
13667 switch (BuiltinOp) {
13671 case Builtin::BI__builtin_dynamic_object_size:
13672 case Builtin::BI__builtin_object_size: {
13676 assert(
Type <= 3 &&
"unexpected type");
13687 switch (Info.EvalMode) {
13688 case EvaluationMode::ConstantExpression:
13689 case EvaluationMode::ConstantFold:
13690 case EvaluationMode::IgnoreSideEffects:
13693 case EvaluationMode::ConstantExpressionUnevaluated:
13698 llvm_unreachable(
"unexpected EvalMode");
13701 case Builtin::BI__builtin_os_log_format_buffer_size: {
13702 analyze_os_log::OSLogBufferLayout Layout;
13707 case Builtin::BI__builtin_is_aligned: {
13715 Ptr.setFrom(Info.Ctx, Src);
13721 assert(Alignment.isPowerOf2());
13734 Info.FFDiag(E->
getArg(0), diag::note_constexpr_alignment_compute)
13738 assert(Src.
isInt());
13739 return Success((Src.
getInt() & (Alignment - 1)) == 0 ? 1 : 0, E);
13741 case Builtin::BI__builtin_align_up: {
13749 APSInt((Src.
getInt() + (Alignment - 1)) & ~(Alignment - 1),
13750 Src.
getInt().isUnsigned());
13751 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
13752 return Success(AlignedVal, E);
13754 case Builtin::BI__builtin_align_down: {
13763 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
13764 return Success(AlignedVal, E);
13767 case Builtin::BI__builtin_bitreverse8:
13768 case Builtin::BI__builtin_bitreverse16:
13769 case Builtin::BI__builtin_bitreverse32:
13770 case Builtin::BI__builtin_bitreverse64:
13771 case Builtin::BI__builtin_elementwise_bitreverse: {
13776 return Success(Val.reverseBits(), E);
13779 case Builtin::BI__builtin_bswap16:
13780 case Builtin::BI__builtin_bswap32:
13781 case Builtin::BI__builtin_bswap64: {
13786 return Success(Val.byteSwap(), E);
13789 case Builtin::BI__builtin_classify_type:
13792 case Builtin::BI__builtin_clrsb:
13793 case Builtin::BI__builtin_clrsbl:
13794 case Builtin::BI__builtin_clrsbll: {
13799 return Success(Val.getBitWidth() - Val.getSignificantBits(), E);
13802 case Builtin::BI__builtin_clz:
13803 case Builtin::BI__builtin_clzl:
13804 case Builtin::BI__builtin_clzll:
13805 case Builtin::BI__builtin_clzs:
13806 case Builtin::BI__builtin_clzg:
13807 case Builtin::BI__builtin_elementwise_clzg:
13808 case Builtin::BI__lzcnt16:
13809 case Builtin::BI__lzcnt:
13810 case Builtin::BI__lzcnt64: {
13821 std::optional<APSInt> Fallback;
13822 if ((BuiltinOp == Builtin::BI__builtin_clzg ||
13823 BuiltinOp == Builtin::BI__builtin_elementwise_clzg) &&
13828 Fallback = FallbackTemp;
13833 return Success(*Fallback, E);
13838 bool ZeroIsUndefined = BuiltinOp != Builtin::BI__lzcnt16 &&
13839 BuiltinOp != Builtin::BI__lzcnt &&
13840 BuiltinOp != Builtin::BI__lzcnt64;
13842 if (BuiltinOp == Builtin::BI__builtin_elementwise_clzg) {
13843 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
13847 if (ZeroIsUndefined)
13851 return Success(Val.countl_zero(), E);
13854 case Builtin::BI__builtin_constant_p: {
13855 const Expr *Arg = E->
getArg(0);
13864 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
13868 case Builtin::BI__noop:
13872 case Builtin::BI__builtin_is_constant_evaluated: {
13873 const auto *
Callee = Info.CurrentCall->getCallee();
13874 if (Info.InConstantContext && !Info.CheckingPotentialConstantExpression &&
13875 (Info.CallStackDepth == 1 ||
13876 (Info.CallStackDepth == 2 &&
Callee->isInStdNamespace() &&
13877 Callee->getIdentifier() &&
13878 Callee->getIdentifier()->isStr(
"is_constant_evaluated")))) {
13880 if (Info.EvalStatus.
Diag)
13881 Info.report((Info.CallStackDepth == 1)
13883 : Info.CurrentCall->getCallRange().getBegin(),
13884 diag::warn_is_constant_evaluated_always_true_constexpr)
13885 << (Info.CallStackDepth == 1 ?
"__builtin_is_constant_evaluated"
13886 :
"std::is_constant_evaluated");
13889 return Success(Info.InConstantContext, E);
13892 case Builtin::BI__builtin_is_within_lifetime:
13893 if (
auto result = EvaluateBuiltinIsWithinLifetime(*
this, E))
13897 case Builtin::BI__builtin_ctz:
13898 case Builtin::BI__builtin_ctzl:
13899 case Builtin::BI__builtin_ctzll:
13900 case Builtin::BI__builtin_ctzs:
13901 case Builtin::BI__builtin_ctzg:
13902 case Builtin::BI__builtin_elementwise_ctzg: {
13913 std::optional<APSInt> Fallback;
13914 if ((BuiltinOp == Builtin::BI__builtin_ctzg ||
13915 BuiltinOp == Builtin::BI__builtin_elementwise_ctzg) &&
13920 Fallback = FallbackTemp;
13925 return Success(*Fallback, E);
13927 if (BuiltinOp == Builtin::BI__builtin_elementwise_ctzg) {
13928 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
13934 return Success(Val.countr_zero(), E);
13937 case Builtin::BI__builtin_eh_return_data_regno: {
13943 case Builtin::BI__builtin_elementwise_abs: {
13948 return Success(Val.abs(), E);
13951 case Builtin::BI__builtin_expect:
13952 case Builtin::BI__builtin_expect_with_probability:
13953 return Visit(E->
getArg(0));
13955 case Builtin::BI__builtin_ptrauth_string_discriminator: {
13962 case Builtin::BI__builtin_ffs:
13963 case Builtin::BI__builtin_ffsl:
13964 case Builtin::BI__builtin_ffsll: {
13969 unsigned N = Val.countr_zero();
13970 return Success(N == Val.getBitWidth() ? 0 : N + 1, E);
13973 case Builtin::BI__builtin_fpclassify: {
13978 switch (Val.getCategory()) {
13979 case APFloat::fcNaN: Arg = 0;
break;
13980 case APFloat::fcInfinity: Arg = 1;
break;
13981 case APFloat::fcNormal: Arg = Val.isDenormal() ? 3 : 2;
break;
13982 case APFloat::fcZero: Arg = 4;
break;
13984 return Visit(E->
getArg(Arg));
13987 case Builtin::BI__builtin_isinf_sign: {
13990 Success(Val.isInfinity() ? (Val.isNegative() ? -1 : 1) : 0, E);
13993 case Builtin::BI__builtin_isinf: {
13996 Success(Val.isInfinity() ? 1 : 0, E);
13999 case Builtin::BI__builtin_isfinite: {
14002 Success(Val.isFinite() ? 1 : 0, E);
14005 case Builtin::BI__builtin_isnan: {
14008 Success(Val.isNaN() ? 1 : 0, E);
14011 case Builtin::BI__builtin_isnormal: {
14014 Success(Val.isNormal() ? 1 : 0, E);
14017 case Builtin::BI__builtin_issubnormal: {
14020 Success(Val.isDenormal() ? 1 : 0, E);
14023 case Builtin::BI__builtin_iszero: {
14026 Success(Val.isZero() ? 1 : 0, E);
14029 case Builtin::BI__builtin_signbit:
14030 case Builtin::BI__builtin_signbitf:
14031 case Builtin::BI__builtin_signbitl: {
14034 Success(Val.isNegative() ? 1 : 0, E);
14037 case Builtin::BI__builtin_isgreater:
14038 case Builtin::BI__builtin_isgreaterequal:
14039 case Builtin::BI__builtin_isless:
14040 case Builtin::BI__builtin_islessequal:
14041 case Builtin::BI__builtin_islessgreater:
14042 case Builtin::BI__builtin_isunordered: {
14051 switch (BuiltinOp) {
14052 case Builtin::BI__builtin_isgreater:
14054 case Builtin::BI__builtin_isgreaterequal:
14056 case Builtin::BI__builtin_isless:
14058 case Builtin::BI__builtin_islessequal:
14060 case Builtin::BI__builtin_islessgreater: {
14061 APFloat::cmpResult cmp = LHS.compare(RHS);
14062 return cmp == APFloat::cmpResult::cmpLessThan ||
14063 cmp == APFloat::cmpResult::cmpGreaterThan;
14065 case Builtin::BI__builtin_isunordered:
14066 return LHS.compare(RHS) == APFloat::cmpResult::cmpUnordered;
14068 llvm_unreachable(
"Unexpected builtin ID: Should be a floating "
14069 "point comparison function");
14077 case Builtin::BI__builtin_issignaling: {
14080 Success(Val.isSignaling() ? 1 : 0, E);
14083 case Builtin::BI__builtin_isfpclass: {
14087 unsigned Test =
static_cast<llvm::FPClassTest
>(MaskVal.getZExtValue());
14090 Success((Val.classify() & Test) ? 1 : 0, E);
14093 case Builtin::BI__builtin_parity:
14094 case Builtin::BI__builtin_parityl:
14095 case Builtin::BI__builtin_parityll: {
14100 return Success(Val.popcount() % 2, E);
14103 case Builtin::BI__builtin_abs:
14104 case Builtin::BI__builtin_labs:
14105 case Builtin::BI__builtin_llabs: {
14109 if (Val ==
APSInt(APInt::getSignedMinValue(Val.getBitWidth()),
14112 if (Val.isNegative())
14117 case Builtin::BI__builtin_popcount:
14118 case Builtin::BI__builtin_popcountl:
14119 case Builtin::BI__builtin_popcountll:
14120 case Builtin::BI__builtin_popcountg:
14121 case Builtin::BI__builtin_elementwise_popcount:
14122 case Builtin::BI__popcnt16:
14123 case Builtin::BI__popcnt:
14124 case Builtin::BI__popcnt64: {
14135 return Success(Val.popcount(), E);
14138 case Builtin::BI__builtin_rotateleft8:
14139 case Builtin::BI__builtin_rotateleft16:
14140 case Builtin::BI__builtin_rotateleft32:
14141 case Builtin::BI__builtin_rotateleft64:
14142 case Builtin::BI_rotl8:
14143 case Builtin::BI_rotl16:
14144 case Builtin::BI_rotl:
14145 case Builtin::BI_lrotl:
14146 case Builtin::BI_rotl64: {
14152 return Success(Val.rotl(Amt.urem(Val.getBitWidth())), E);
14155 case Builtin::BI__builtin_rotateright8:
14156 case Builtin::BI__builtin_rotateright16:
14157 case Builtin::BI__builtin_rotateright32:
14158 case Builtin::BI__builtin_rotateright64:
14159 case Builtin::BI_rotr8:
14160 case Builtin::BI_rotr16:
14161 case Builtin::BI_rotr:
14162 case Builtin::BI_lrotr:
14163 case Builtin::BI_rotr64: {
14169 return Success(Val.rotr(Amt.urem(Val.getBitWidth())), E);
14172 case Builtin::BI__builtin_elementwise_add_sat: {
14178 APInt Result = LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS);
14181 case Builtin::BI__builtin_elementwise_sub_sat: {
14187 APInt Result = LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
14190 case Builtin::BI__builtin_elementwise_max: {
14199 case Builtin::BI__builtin_elementwise_min: {
14208 case Builtin::BI__builtin_elementwise_fshl:
14209 case Builtin::BI__builtin_elementwise_fshr: {
14216 switch (BuiltinOp) {
14217 case Builtin::BI__builtin_elementwise_fshl: {
14218 APSInt Result(llvm::APIntOps::fshl(Hi, Lo, Shift), Hi.isUnsigned());
14221 case Builtin::BI__builtin_elementwise_fshr: {
14222 APSInt Result(llvm::APIntOps::fshr(Hi, Lo, Shift), Hi.isUnsigned());
14226 llvm_unreachable(
"Fully covered switch above");
14228 case Builtin::BIstrlen:
14229 case Builtin::BIwcslen:
14231 if (Info.getLangOpts().CPlusPlus11)
14232 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
14236 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
14238 case Builtin::BI__builtin_strlen:
14239 case Builtin::BI__builtin_wcslen: {
14248 case Builtin::BIstrcmp:
14249 case Builtin::BIwcscmp:
14250 case Builtin::BIstrncmp:
14251 case Builtin::BIwcsncmp:
14252 case Builtin::BImemcmp:
14253 case Builtin::BIbcmp:
14254 case Builtin::BIwmemcmp:
14256 if (Info.getLangOpts().CPlusPlus11)
14257 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
14261 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
14263 case Builtin::BI__builtin_strcmp:
14264 case Builtin::BI__builtin_wcscmp:
14265 case Builtin::BI__builtin_strncmp:
14266 case Builtin::BI__builtin_wcsncmp:
14267 case Builtin::BI__builtin_memcmp:
14268 case Builtin::BI__builtin_bcmp:
14269 case Builtin::BI__builtin_wmemcmp: {
14270 LValue String1, String2;
14276 if (BuiltinOp != Builtin::BIstrcmp &&
14277 BuiltinOp != Builtin::BIwcscmp &&
14278 BuiltinOp != Builtin::BI__builtin_strcmp &&
14279 BuiltinOp != Builtin::BI__builtin_wcscmp) {
14283 MaxLength = N.getZExtValue();
14287 if (MaxLength == 0u)
14290 if (!String1.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
14291 !String2.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
14292 String1.Designator.Invalid || String2.Designator.Invalid)
14295 QualType CharTy1 = String1.Designator.getType(Info.Ctx);
14296 QualType CharTy2 = String2.Designator.getType(Info.Ctx);
14298 bool IsRawByte = BuiltinOp == Builtin::BImemcmp ||
14299 BuiltinOp == Builtin::BIbcmp ||
14300 BuiltinOp == Builtin::BI__builtin_memcmp ||
14301 BuiltinOp == Builtin::BI__builtin_bcmp;
14303 assert(IsRawByte ||
14313 Info.FFDiag(E, diag::note_constexpr_memcmp_unsupported)
14319 const auto &ReadCurElems = [&](
APValue &Char1,
APValue &Char2) {
14322 Char1.
isInt() && Char2.isInt();
14324 const auto &AdvanceElems = [&] {
14330 (BuiltinOp != Builtin::BImemcmp && BuiltinOp != Builtin::BIbcmp &&
14331 BuiltinOp != Builtin::BIwmemcmp &&
14332 BuiltinOp != Builtin::BI__builtin_memcmp &&
14333 BuiltinOp != Builtin::BI__builtin_bcmp &&
14334 BuiltinOp != Builtin::BI__builtin_wmemcmp);
14335 bool IsWide = BuiltinOp == Builtin::BIwcscmp ||
14336 BuiltinOp == Builtin::BIwcsncmp ||
14337 BuiltinOp == Builtin::BIwmemcmp ||
14338 BuiltinOp == Builtin::BI__builtin_wcscmp ||
14339 BuiltinOp == Builtin::BI__builtin_wcsncmp ||
14340 BuiltinOp == Builtin::BI__builtin_wmemcmp;
14342 for (; MaxLength; --MaxLength) {
14344 if (!ReadCurElems(Char1, Char2))
14352 if (StopAtNull && !Char1.
getInt())
14354 assert(!(StopAtNull && !Char2.
getInt()));
14355 if (!AdvanceElems())
14362 case Builtin::BI__atomic_always_lock_free:
14363 case Builtin::BI__atomic_is_lock_free:
14364 case Builtin::BI__c11_atomic_is_lock_free: {
14380 if (
Size.isPowerOfTwo()) {
14382 unsigned InlineWidthBits =
14385 if (BuiltinOp == Builtin::BI__c11_atomic_is_lock_free ||
14391 const Expr *PtrArg = E->
getArg(1);
14397 IntResult.isAligned(
Size.getAsAlign()))
14401 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(PtrArg)) {
14404 if (ICE->getCastKind() == CK_BitCast)
14405 PtrArg = ICE->getSubExpr();
14408 if (
auto PtrTy = PtrArg->
getType()->
getAs<PointerType>()) {
14419 return BuiltinOp == Builtin::BI__atomic_always_lock_free ?
14422 case Builtin::BI__builtin_addcb:
14423 case Builtin::BI__builtin_addcs:
14424 case Builtin::BI__builtin_addc:
14425 case Builtin::BI__builtin_addcl:
14426 case Builtin::BI__builtin_addcll:
14427 case Builtin::BI__builtin_subcb:
14428 case Builtin::BI__builtin_subcs:
14429 case Builtin::BI__builtin_subc:
14430 case Builtin::BI__builtin_subcl:
14431 case Builtin::BI__builtin_subcll: {
14432 LValue CarryOutLValue;
14444 bool FirstOverflowed =
false;
14445 bool SecondOverflowed =
false;
14446 switch (BuiltinOp) {
14448 llvm_unreachable(
"Invalid value for BuiltinOp");
14449 case Builtin::BI__builtin_addcb:
14450 case Builtin::BI__builtin_addcs:
14451 case Builtin::BI__builtin_addc:
14452 case Builtin::BI__builtin_addcl:
14453 case Builtin::BI__builtin_addcll:
14455 LHS.uadd_ov(RHS, FirstOverflowed).uadd_ov(CarryIn, SecondOverflowed);
14457 case Builtin::BI__builtin_subcb:
14458 case Builtin::BI__builtin_subcs:
14459 case Builtin::BI__builtin_subc:
14460 case Builtin::BI__builtin_subcl:
14461 case Builtin::BI__builtin_subcll:
14463 LHS.usub_ov(RHS, FirstOverflowed).usub_ov(CarryIn, SecondOverflowed);
14469 CarryOut = (
uint64_t)(FirstOverflowed | SecondOverflowed);
14475 case Builtin::BI__builtin_add_overflow:
14476 case Builtin::BI__builtin_sub_overflow:
14477 case Builtin::BI__builtin_mul_overflow:
14478 case Builtin::BI__builtin_sadd_overflow:
14479 case Builtin::BI__builtin_uadd_overflow:
14480 case Builtin::BI__builtin_uaddl_overflow:
14481 case Builtin::BI__builtin_uaddll_overflow:
14482 case Builtin::BI__builtin_usub_overflow:
14483 case Builtin::BI__builtin_usubl_overflow:
14484 case Builtin::BI__builtin_usubll_overflow:
14485 case Builtin::BI__builtin_umul_overflow:
14486 case Builtin::BI__builtin_umull_overflow:
14487 case Builtin::BI__builtin_umulll_overflow:
14488 case Builtin::BI__builtin_saddl_overflow:
14489 case Builtin::BI__builtin_saddll_overflow:
14490 case Builtin::BI__builtin_ssub_overflow:
14491 case Builtin::BI__builtin_ssubl_overflow:
14492 case Builtin::BI__builtin_ssubll_overflow:
14493 case Builtin::BI__builtin_smul_overflow:
14494 case Builtin::BI__builtin_smull_overflow:
14495 case Builtin::BI__builtin_smulll_overflow: {
14496 LValue ResultLValue;
14506 bool DidOverflow =
false;
14509 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
14510 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
14511 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
14512 bool IsSigned = LHS.isSigned() || RHS.isSigned() ||
14514 bool AllSigned = LHS.isSigned() && RHS.isSigned() &&
14516 uint64_t LHSSize = LHS.getBitWidth();
14517 uint64_t RHSSize = RHS.getBitWidth();
14519 uint64_t MaxBits = std::max(std::max(LHSSize, RHSSize), ResultSize);
14525 if (IsSigned && !AllSigned)
14528 LHS =
APSInt(LHS.extOrTrunc(MaxBits), !IsSigned);
14529 RHS =
APSInt(RHS.extOrTrunc(MaxBits), !IsSigned);
14534 switch (BuiltinOp) {
14536 llvm_unreachable(
"Invalid value for BuiltinOp");
14537 case Builtin::BI__builtin_add_overflow:
14538 case Builtin::BI__builtin_sadd_overflow:
14539 case Builtin::BI__builtin_saddl_overflow:
14540 case Builtin::BI__builtin_saddll_overflow:
14541 case Builtin::BI__builtin_uadd_overflow:
14542 case Builtin::BI__builtin_uaddl_overflow:
14543 case Builtin::BI__builtin_uaddll_overflow:
14544 Result = LHS.isSigned() ? LHS.sadd_ov(RHS, DidOverflow)
14545 : LHS.uadd_ov(RHS, DidOverflow);
14547 case Builtin::BI__builtin_sub_overflow:
14548 case Builtin::BI__builtin_ssub_overflow:
14549 case Builtin::BI__builtin_ssubl_overflow:
14550 case Builtin::BI__builtin_ssubll_overflow:
14551 case Builtin::BI__builtin_usub_overflow:
14552 case Builtin::BI__builtin_usubl_overflow:
14553 case Builtin::BI__builtin_usubll_overflow:
14554 Result = LHS.isSigned() ? LHS.ssub_ov(RHS, DidOverflow)
14555 : LHS.usub_ov(RHS, DidOverflow);
14557 case Builtin::BI__builtin_mul_overflow:
14558 case Builtin::BI__builtin_smul_overflow:
14559 case Builtin::BI__builtin_smull_overflow:
14560 case Builtin::BI__builtin_smulll_overflow:
14561 case Builtin::BI__builtin_umul_overflow:
14562 case Builtin::BI__builtin_umull_overflow:
14563 case Builtin::BI__builtin_umulll_overflow:
14564 Result = LHS.isSigned() ? LHS.smul_ov(RHS, DidOverflow)
14565 : LHS.umul_ov(RHS, DidOverflow);
14571 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
14572 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
14573 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
14582 if (!APSInt::isSameValue(Temp,
Result))
14583 DidOverflow =
true;
14590 return Success(DidOverflow, E);
14593 case Builtin::BI__builtin_reduce_add:
14594 case Builtin::BI__builtin_reduce_mul:
14595 case Builtin::BI__builtin_reduce_and:
14596 case Builtin::BI__builtin_reduce_or:
14597 case Builtin::BI__builtin_reduce_xor:
14598 case Builtin::BI__builtin_reduce_min:
14599 case Builtin::BI__builtin_reduce_max: {
14606 for (
unsigned EltNum = 1; EltNum < SourceLen; ++EltNum) {
14607 switch (BuiltinOp) {
14610 case Builtin::BI__builtin_reduce_add: {
14613 Reduced.getBitWidth() + 1, std::plus<APSInt>(), Reduced))
14617 case Builtin::BI__builtin_reduce_mul: {
14620 Reduced.getBitWidth() * 2, std::multiplies<APSInt>(), Reduced))
14624 case Builtin::BI__builtin_reduce_and: {
14628 case Builtin::BI__builtin_reduce_or: {
14632 case Builtin::BI__builtin_reduce_xor: {
14636 case Builtin::BI__builtin_reduce_min: {
14640 case Builtin::BI__builtin_reduce_max: {
14650 case clang::X86::BI__builtin_ia32_addcarryx_u32:
14651 case clang::X86::BI__builtin_ia32_addcarryx_u64:
14652 case clang::X86::BI__builtin_ia32_subborrow_u32:
14653 case clang::X86::BI__builtin_ia32_subborrow_u64: {
14654 LValue ResultLValue;
14655 APSInt CarryIn, LHS, RHS;
14663 bool IsAdd = BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u32 ||
14664 BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u64;
14666 unsigned BitWidth = LHS.getBitWidth();
14667 unsigned CarryInBit = CarryIn.ugt(0) ? 1 : 0;
14670 ? (LHS.zext(BitWidth + 1) + (RHS.zext(BitWidth + 1) + CarryInBit))
14671 : (LHS.zext(BitWidth + 1) - (RHS.zext(BitWidth + 1) + CarryInBit));
14673 APInt Result = ExResult.extractBits(BitWidth, 0);
14674 uint64_t CarryOut = ExResult.extractBitsAsZExtValue(1, BitWidth);
14682 case clang::X86::BI__builtin_ia32_bextr_u32:
14683 case clang::X86::BI__builtin_ia32_bextr_u64:
14684 case clang::X86::BI__builtin_ia32_bextri_u32:
14685 case clang::X86::BI__builtin_ia32_bextri_u64: {
14691 unsigned BitWidth = Val.getBitWidth();
14693 uint64_t Length = Idx.extractBitsAsZExtValue(8, 8);
14694 Length = Length > BitWidth ? BitWidth : Length;
14697 if (Length == 0 || Shift >= BitWidth)
14701 Result &= llvm::maskTrailingOnes<uint64_t>(Length);
14705 case clang::X86::BI__builtin_ia32_bzhi_si:
14706 case clang::X86::BI__builtin_ia32_bzhi_di: {
14712 unsigned BitWidth = Val.getBitWidth();
14713 unsigned Index = Idx.extractBitsAsZExtValue(8, 0);
14714 if (Index < BitWidth)
14715 Val.clearHighBits(BitWidth - Index);
14719 case clang::X86::BI__builtin_ia32_lzcnt_u16:
14720 case clang::X86::BI__builtin_ia32_lzcnt_u32:
14721 case clang::X86::BI__builtin_ia32_lzcnt_u64: {
14725 return Success(Val.countLeadingZeros(), E);
14728 case clang::X86::BI__builtin_ia32_tzcnt_u16:
14729 case clang::X86::BI__builtin_ia32_tzcnt_u32:
14730 case clang::X86::BI__builtin_ia32_tzcnt_u64: {
14734 return Success(Val.countTrailingZeros(), E);
14737 case clang::X86::BI__builtin_ia32_pdep_si:
14738 case clang::X86::BI__builtin_ia32_pdep_di: {
14744 unsigned BitWidth = Val.getBitWidth();
14746 for (
unsigned I = 0, P = 0; I != BitWidth; ++I)
14748 Result.setBitVal(I, Val[P++]);
14752 case clang::X86::BI__builtin_ia32_pext_si:
14753 case clang::X86::BI__builtin_ia32_pext_di: {
14759 unsigned BitWidth = Val.getBitWidth();
14761 for (
unsigned I = 0, P = 0; I != BitWidth; ++I)
14763 Result.setBitVal(P++, Val[I]);
14767 case X86::BI__builtin_ia32_kandqi:
14768 case X86::BI__builtin_ia32_kandhi:
14769 case X86::BI__builtin_ia32_kandsi:
14770 case X86::BI__builtin_ia32_kanddi: {
14771 return HandleMaskBinOp(
14772 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS & RHS; });
14775 case X86::BI__builtin_ia32_kandnqi:
14776 case X86::BI__builtin_ia32_kandnhi:
14777 case X86::BI__builtin_ia32_kandnsi:
14778 case X86::BI__builtin_ia32_kandndi: {
14779 return HandleMaskBinOp(
14780 [](
const APSInt &LHS,
const APSInt &RHS) {
return ~LHS & RHS; });
14783 case X86::BI__builtin_ia32_korqi:
14784 case X86::BI__builtin_ia32_korhi:
14785 case X86::BI__builtin_ia32_korsi:
14786 case X86::BI__builtin_ia32_kordi: {
14787 return HandleMaskBinOp(
14788 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS | RHS; });
14791 case X86::BI__builtin_ia32_kxnorqi:
14792 case X86::BI__builtin_ia32_kxnorhi:
14793 case X86::BI__builtin_ia32_kxnorsi:
14794 case X86::BI__builtin_ia32_kxnordi: {
14795 return HandleMaskBinOp(
14796 [](
const APSInt &LHS,
const APSInt &RHS) {
return ~(LHS ^ RHS); });
14799 case X86::BI__builtin_ia32_kxorqi:
14800 case X86::BI__builtin_ia32_kxorhi:
14801 case X86::BI__builtin_ia32_kxorsi:
14802 case X86::BI__builtin_ia32_kxordi: {
14803 return HandleMaskBinOp(
14804 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS ^ RHS; });
14807 case X86::BI__builtin_ia32_knotqi:
14808 case X86::BI__builtin_ia32_knothi:
14809 case X86::BI__builtin_ia32_knotsi:
14810 case X86::BI__builtin_ia32_knotdi: {
14818 case X86::BI__builtin_ia32_kaddqi:
14819 case X86::BI__builtin_ia32_kaddhi:
14820 case X86::BI__builtin_ia32_kaddsi:
14821 case X86::BI__builtin_ia32_kadddi: {
14822 return HandleMaskBinOp(
14823 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS + RHS; });
14831 const LValue &LV) {
14834 if (!LV.getLValueBase())
14839 if (!LV.getLValueDesignator().Invalid &&
14840 !LV.getLValueDesignator().isOnePastTheEnd())
14850 if (LV.getLValueDesignator().Invalid)
14856 return LV.getLValueOffset() == Size;
14866class DataRecursiveIntBinOpEvaluator {
14867 struct EvalResult {
14869 bool Failed =
false;
14871 EvalResult() =
default;
14873 void swap(EvalResult &RHS) {
14875 Failed = RHS.Failed;
14876 RHS.Failed =
false;
14882 EvalResult LHSResult;
14883 enum { AnyExprKind, BinOpKind, BinOpVisitedLHSKind }
Kind;
14886 Job(Job &&) =
default;
14888 void startSpeculativeEval(EvalInfo &Info) {
14889 SpecEvalRAII = SpeculativeEvaluationRAII(Info);
14893 SpeculativeEvaluationRAII SpecEvalRAII;
14896 SmallVector<Job, 16> Queue;
14898 IntExprEvaluator &IntEval;
14903 DataRecursiveIntBinOpEvaluator(IntExprEvaluator &IntEval,
APValue &
Result)
14904 : IntEval(IntEval), Info(IntEval.getEvalInfo()), FinalResult(
Result) { }
14910 static bool shouldEnqueue(
const BinaryOperator *E) {
14917 bool Traverse(
const BinaryOperator *E) {
14919 EvalResult PrevResult;
14920 while (!Queue.empty())
14921 process(PrevResult);
14923 if (PrevResult.Failed)
return false;
14925 FinalResult.
swap(PrevResult.Val);
14936 bool Error(
const Expr *E) {
14937 return IntEval.Error(E);
14940 return IntEval.Error(E, D);
14943 OptionalDiagnostic CCEDiag(
const Expr *E,
diag::kind D) {
14944 return Info.CCEDiag(E, D);
14948 bool VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
14949 bool &SuppressRHSDiags);
14951 bool VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
14954 void EvaluateExpr(
const Expr *E, EvalResult &
Result) {
14960 void process(EvalResult &
Result);
14962 void enqueue(
const Expr *E) {
14964 Queue.resize(Queue.size()+1);
14965 Queue.back().E = E;
14966 Queue.back().Kind = Job::AnyExprKind;
14972bool DataRecursiveIntBinOpEvaluator::
14973 VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
14974 bool &SuppressRHSDiags) {
14977 if (LHSResult.Failed)
14978 return Info.noteSideEffect();
14987 if (LHSAsBool == (E->
getOpcode() == BO_LOr)) {
14988 Success(LHSAsBool, E, LHSResult.Val);
14992 LHSResult.Failed =
true;
14996 if (!Info.noteSideEffect())
15002 SuppressRHSDiags =
true;
15011 if (LHSResult.Failed && !Info.noteFailure())
15022 assert(!LVal.
hasLValuePath() &&
"have designator for integer lvalue");
15024 uint64_t Offset64 = Offset.getQuantity();
15025 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
15027 : Offset64 + Index64);
15030bool DataRecursiveIntBinOpEvaluator::
15031 VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
15034 if (RHSResult.Failed)
15041 bool lhsResult, rhsResult;
15056 if (rhsResult == (E->
getOpcode() == BO_LOr))
15067 if (LHSResult.Failed || RHSResult.Failed)
15070 const APValue &LHSVal = LHSResult.Val;
15071 const APValue &RHSVal = RHSResult.Val;
15095 if (!LHSExpr || !RHSExpr)
15097 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
15098 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
15099 if (!LHSAddrExpr || !RHSAddrExpr)
15124void DataRecursiveIntBinOpEvaluator::process(EvalResult &
Result) {
15125 Job &job = Queue.back();
15127 switch (job.Kind) {
15128 case Job::AnyExprKind: {
15129 if (
const BinaryOperator *Bop = dyn_cast<BinaryOperator>(job.E)) {
15130 if (shouldEnqueue(Bop)) {
15131 job.Kind = Job::BinOpKind;
15132 enqueue(Bop->getLHS());
15137 EvaluateExpr(job.E,
Result);
15142 case Job::BinOpKind: {
15144 bool SuppressRHSDiags =
false;
15145 if (!VisitBinOpLHSOnly(
Result, Bop, SuppressRHSDiags)) {
15149 if (SuppressRHSDiags)
15150 job.startSpeculativeEval(Info);
15151 job.LHSResult.swap(
Result);
15152 job.Kind = Job::BinOpVisitedLHSKind;
15157 case Job::BinOpVisitedLHSKind: {
15161 Result.Failed = !VisitBinOp(job.LHSResult, RHS, Bop,
Result.Val);
15167 llvm_unreachable(
"Invalid Job::Kind!");
15171enum class CmpResult {
15180template <
class SuccessCB,
class AfterCB>
15183 SuccessCB &&
Success, AfterCB &&DoAfter) {
15188 "unsupported binary expression evaluation");
15190 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
15204 if (!LHSOK && !Info.noteFailure())
15209 return Success(CmpResult::Less, E);
15211 return Success(CmpResult::Greater, E);
15212 return Success(CmpResult::Equal, E);
15220 if (!LHSOK && !Info.noteFailure())
15225 return Success(CmpResult::Less, E);
15227 return Success(CmpResult::Greater, E);
15228 return Success(CmpResult::Equal, E);
15232 ComplexValue LHS, RHS;
15241 LHS.makeComplexFloat();
15242 LHS.FloatImag = APFloat(LHS.FloatReal.getSemantics());
15247 if (!LHSOK && !Info.noteFailure())
15253 RHS.makeComplexFloat();
15254 RHS.FloatImag = APFloat(RHS.FloatReal.getSemantics());
15258 if (LHS.isComplexFloat()) {
15259 APFloat::cmpResult CR_r =
15260 LHS.getComplexFloatReal().compare(RHS.getComplexFloatReal());
15261 APFloat::cmpResult CR_i =
15262 LHS.getComplexFloatImag().compare(RHS.getComplexFloatImag());
15263 bool IsEqual = CR_r == APFloat::cmpEqual && CR_i == APFloat::cmpEqual;
15264 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal, E);
15266 assert(IsEquality &&
"invalid complex comparison");
15267 bool IsEqual = LHS.getComplexIntReal() == RHS.getComplexIntReal() &&
15268 LHS.getComplexIntImag() == RHS.getComplexIntImag();
15269 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal, E);
15275 APFloat RHS(0.0), LHS(0.0);
15278 if (!LHSOK && !Info.noteFailure())
15285 llvm::APFloatBase::cmpResult APFloatCmpResult = LHS.compare(RHS);
15286 if (!Info.InConstantContext &&
15287 APFloatCmpResult == APFloat::cmpUnordered &&
15290 Info.FFDiag(E, diag::note_constexpr_float_arithmetic_strict);
15293 auto GetCmpRes = [&]() {
15294 switch (APFloatCmpResult) {
15295 case APFloat::cmpEqual:
15296 return CmpResult::Equal;
15297 case APFloat::cmpLessThan:
15298 return CmpResult::Less;
15299 case APFloat::cmpGreaterThan:
15300 return CmpResult::Greater;
15301 case APFloat::cmpUnordered:
15302 return CmpResult::Unordered;
15304 llvm_unreachable(
"Unrecognised APFloat::cmpResult enum");
15306 return Success(GetCmpRes(), E);
15310 LValue LHSValue, RHSValue;
15313 if (!LHSOK && !Info.noteFailure())
15324 if (Info.checkingPotentialConstantExpression() &&
15325 (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown))
15327 auto DiagComparison = [&] (
unsigned DiagID,
bool Reversed =
false) {
15328 std::string LHS = LHSValue.toString(Info.Ctx, E->
getLHS()->
getType());
15329 std::string RHS = RHSValue.toString(Info.Ctx, E->
getRHS()->
getType());
15330 Info.FFDiag(E, DiagID)
15337 return DiagComparison(
15338 diag::note_constexpr_pointer_comparison_unspecified);
15344 if ((!LHSValue.Base && !LHSValue.Offset.
isZero()) ||
15345 (!RHSValue.Base && !RHSValue.Offset.
isZero()))
15346 return DiagComparison(diag::note_constexpr_pointer_constant_comparison,
15360 return DiagComparison(diag::note_constexpr_literal_comparison);
15362 return DiagComparison(diag::note_constexpr_opaque_call_comparison,
15367 return DiagComparison(diag::note_constexpr_pointer_weak_comparison,
15371 if (LHSValue.Base && LHSValue.Offset.
isZero() &&
15373 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
15375 if (RHSValue.Base && RHSValue.Offset.
isZero() &&
15377 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
15383 return DiagComparison(
15384 diag::note_constexpr_pointer_comparison_zero_sized);
15385 if (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown)
15386 return DiagComparison(
15387 diag::note_constexpr_pointer_comparison_unspecified);
15389 return Success(CmpResult::Unequal, E);
15392 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
15393 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
15395 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
15396 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
15406 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid && IsRelational) {
15407 bool WasArrayIndex;
15410 :
getType(LHSValue.Base).getNonReferenceType(),
15411 LHSDesignator, RHSDesignator, WasArrayIndex);
15418 if (!WasArrayIndex && Mismatch < LHSDesignator.Entries.size() &&
15419 Mismatch < RHSDesignator.Entries.size()) {
15420 const FieldDecl *LF = getAsField(LHSDesignator.Entries[Mismatch]);
15421 const FieldDecl *RF = getAsField(RHSDesignator.Entries[Mismatch]);
15423 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_classes);
15425 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
15426 << getAsBaseClass(LHSDesignator.Entries[Mismatch])
15429 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
15430 << getAsBaseClass(RHSDesignator.Entries[Mismatch])
15435 diag::note_constexpr_pointer_comparison_differing_access)
15446 assert(PtrSize <= 64 &&
"Unexpected pointer width");
15447 uint64_t Mask = ~0ULL >> (64 - PtrSize);
15448 CompareLHS &= Mask;
15449 CompareRHS &= Mask;
15454 if (!LHSValue.Base.
isNull() && IsRelational) {
15459 uint64_t OffsetLimit = Size.getQuantity();
15460 if (CompareLHS > OffsetLimit || CompareRHS > OffsetLimit)
15464 if (CompareLHS < CompareRHS)
15465 return Success(CmpResult::Less, E);
15466 if (CompareLHS > CompareRHS)
15467 return Success(CmpResult::Greater, E);
15468 return Success(CmpResult::Equal, E);
15472 assert(IsEquality &&
"unexpected member pointer operation");
15475 MemberPtr LHSValue, RHSValue;
15478 if (!LHSOK && !Info.noteFailure())
15486 if (LHSValue.getDecl() && LHSValue.getDecl()->isWeak()) {
15487 Info.FFDiag(E, diag::note_constexpr_mem_pointer_weak_comparison)
15488 << LHSValue.getDecl();
15491 if (RHSValue.getDecl() && RHSValue.getDecl()->isWeak()) {
15492 Info.FFDiag(E, diag::note_constexpr_mem_pointer_weak_comparison)
15493 << RHSValue.getDecl();
15500 if (!LHSValue.getDecl() || !RHSValue.getDecl()) {
15501 bool Equal = !LHSValue.getDecl() && !RHSValue.getDecl();
15502 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal, E);
15507 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(LHSValue.getDecl()))
15508 if (MD->isVirtual())
15509 Info.CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
15510 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(RHSValue.getDecl()))
15511 if (MD->isVirtual())
15512 Info.CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
15518 bool Equal = LHSValue == RHSValue;
15519 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal, E);
15524 assert(RHSTy->
isNullPtrType() &&
"missing pointer conversion");
15532 return Success(CmpResult::Equal, E);
15538bool RecordExprEvaluator::VisitBinCmp(
const BinaryOperator *E) {
15542 auto OnSuccess = [&](CmpResult CR,
const BinaryOperator *E) {
15545 case CmpResult::Unequal:
15546 llvm_unreachable(
"should never produce Unequal for three-way comparison");
15547 case CmpResult::Less:
15548 CCR = ComparisonCategoryResult::Less;
15550 case CmpResult::Equal:
15551 CCR = ComparisonCategoryResult::Equal;
15553 case CmpResult::Greater:
15554 CCR = ComparisonCategoryResult::Greater;
15556 case CmpResult::Unordered:
15557 CCR = ComparisonCategoryResult::Unordered;
15562 const ComparisonCategoryInfo &CmpInfo =
15571 ConstantExprKind::Normal);
15574 return ExprEvaluatorBaseTy::VisitBinCmp(E);
15578bool RecordExprEvaluator::VisitCXXParenListInitExpr(
15579 const CXXParenListInitExpr *E) {
15580 return VisitCXXParenListOrInitListExpr(E, E->
getInitExprs());
15583bool IntExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
15588 if (!Info.noteFailure())
15592 if (DataRecursiveIntBinOpEvaluator::shouldEnqueue(E))
15593 return DataRecursiveIntBinOpEvaluator(*
this,
Result).Traverse(E);
15597 "DataRecursiveIntBinOpEvaluator should have handled integral types");
15602 auto OnSuccess = [&](CmpResult CR,
const BinaryOperator *E) {
15603 assert((CR != CmpResult::Unequal || E->
isEqualityOp()) &&
15604 "should only produce Unequal for equality comparisons");
15605 bool IsEqual = CR == CmpResult::Equal,
15606 IsLess = CR == CmpResult::Less,
15607 IsGreater = CR == CmpResult::Greater;
15611 llvm_unreachable(
"unsupported binary operator");
15614 return Success(IsEqual == (Op == BO_EQ), E);
15618 return Success(IsGreater, E);
15620 return Success(IsEqual || IsLess, E);
15622 return Success(IsEqual || IsGreater, E);
15626 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
15635 LValue LHSValue, RHSValue;
15638 if (!LHSOK && !Info.noteFailure())
15647 if (Info.checkingPotentialConstantExpression() &&
15648 (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown))
15651 const Expr *LHSExpr = LHSValue.Base.
dyn_cast<
const Expr *>();
15652 const Expr *RHSExpr = RHSValue.Base.
dyn_cast<
const Expr *>();
15654 auto DiagArith = [&](
unsigned DiagID) {
15655 std::string LHS = LHSValue.toString(Info.Ctx, E->
getLHS()->
getType());
15656 std::string RHS = RHSValue.toString(Info.Ctx, E->
getRHS()->
getType());
15657 Info.FFDiag(E, DiagID) << LHS << RHS;
15658 if (LHSExpr && LHSExpr == RHSExpr)
15660 diag::note_constexpr_repeated_literal_eval)
15665 if (!LHSExpr || !RHSExpr)
15666 return DiagArith(diag::note_constexpr_pointer_arith_unspecified);
15669 return DiagArith(diag::note_constexpr_literal_arith);
15671 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
15672 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
15673 if (!LHSAddrExpr || !RHSAddrExpr)
15681 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
15682 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
15684 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
15685 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
15691 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid &&
15694 Info.CCEDiag(E, diag::note_constexpr_pointer_subtraction_not_same_array);
15699 CharUnits ElementSize;
15706 if (ElementSize.
isZero()) {
15707 Info.FFDiag(E, diag::note_constexpr_pointer_subtraction_zero_size)
15724 APSInt TrueResult = (LHS - RHS) / ElemSize;
15727 if (
Result.extend(65) != TrueResult &&
15733 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
15738bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr(
15739 const UnaryExprOrTypeTraitExpr *E) {
15741 case UETT_PreferredAlignOf:
15742 case UETT_AlignOf: {
15751 case UETT_PtrAuthTypeDiscriminator: {
15757 case UETT_VecStep: {
15761 unsigned n = Ty->
castAs<VectorType>()->getNumElements();
15773 case UETT_DataSizeOf:
15774 case UETT_SizeOf: {
15778 if (
const ReferenceType *Ref = SrcTy->
getAs<ReferenceType>())
15789 case UETT_OpenMPRequiredSimdAlign:
15796 case UETT_VectorElements: {
15800 if (
const auto *VT = Ty->
getAs<VectorType>())
15804 if (Info.InConstantContext)
15805 Info.CCEDiag(E, diag::note_constexpr_non_const_vectorelements)
15810 case UETT_CountOf: {
15816 if (
const auto *CAT =
15828 if (VAT->getElementType()->isArrayType()) {
15831 if (!VAT->getSizeExpr()) {
15836 std::optional<APSInt> Res =
15837 VAT->getSizeExpr()->getIntegerConstantExpr(Info.Ctx);
15843 Res->getZExtValue()};
15855 llvm_unreachable(
"unknown expr/type trait");
15858bool IntExprEvaluator::VisitOffsetOfExpr(
const OffsetOfExpr *OOE) {
15864 for (
unsigned i = 0; i != n; ++i) {
15877 Result += IdxResult.getSExtValue() * ElementSize;
15882 FieldDecl *MemberDecl = ON.
getField();
15889 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
15896 llvm_unreachable(
"dependent __builtin_offsetof");
15899 CXXBaseSpecifier *BaseSpec = ON.
getBase();
15911 CurrentType = BaseSpec->
getType();
15925bool IntExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
15944 if (Info.checkingForUndefinedBehavior())
15946 diag::warn_integer_constant_overflow)
15974bool IntExprEvaluator::VisitCastExpr(
const CastExpr *E) {
15976 QualType DestType = E->
getType();
15977 QualType SrcType = SubExpr->
getType();
15980 case CK_BaseToDerived:
15981 case CK_DerivedToBase:
15982 case CK_UncheckedDerivedToBase:
15985 case CK_ArrayToPointerDecay:
15986 case CK_FunctionToPointerDecay:
15987 case CK_NullToPointer:
15988 case CK_NullToMemberPointer:
15989 case CK_BaseToDerivedMemberPointer:
15990 case CK_DerivedToBaseMemberPointer:
15991 case CK_ReinterpretMemberPointer:
15992 case CK_ConstructorConversion:
15993 case CK_IntegralToPointer:
15995 case CK_VectorSplat:
15996 case CK_IntegralToFloating:
15997 case CK_FloatingCast:
15998 case CK_CPointerToObjCPointerCast:
15999 case CK_BlockPointerToObjCPointerCast:
16000 case CK_AnyPointerToBlockPointerCast:
16001 case CK_ObjCObjectLValueCast:
16002 case CK_FloatingRealToComplex:
16003 case CK_FloatingComplexToReal:
16004 case CK_FloatingComplexCast:
16005 case CK_FloatingComplexToIntegralComplex:
16006 case CK_IntegralRealToComplex:
16007 case CK_IntegralComplexCast:
16008 case CK_IntegralComplexToFloatingComplex:
16009 case CK_BuiltinFnToFnPtr:
16010 case CK_ZeroToOCLOpaqueType:
16011 case CK_NonAtomicToAtomic:
16012 case CK_AddressSpaceConversion:
16013 case CK_IntToOCLSampler:
16014 case CK_FloatingToFixedPoint:
16015 case CK_FixedPointToFloating:
16016 case CK_FixedPointCast:
16017 case CK_IntegralToFixedPoint:
16018 case CK_MatrixCast:
16019 case CK_HLSLAggregateSplatCast:
16020 llvm_unreachable(
"invalid cast kind for integral value");
16024 case CK_LValueBitCast:
16025 case CK_ARCProduceObject:
16026 case CK_ARCConsumeObject:
16027 case CK_ARCReclaimReturnedObject:
16028 case CK_ARCExtendBlockObject:
16029 case CK_CopyAndAutoreleaseBlockObject:
16032 case CK_UserDefinedConversion:
16033 case CK_LValueToRValue:
16034 case CK_AtomicToNonAtomic:
16036 case CK_LValueToRValueBitCast:
16037 case CK_HLSLArrayRValue:
16038 case CK_HLSLElementwiseCast:
16039 return ExprEvaluatorBaseTy::VisitCastExpr(E);
16041 case CK_MemberPointerToBoolean:
16042 case CK_PointerToBoolean:
16043 case CK_IntegralToBoolean:
16044 case CK_FloatingToBoolean:
16045 case CK_BooleanToSignedIntegral:
16046 case CK_FloatingComplexToBoolean:
16047 case CK_IntegralComplexToBoolean: {
16052 if (BoolResult && E->
getCastKind() == CK_BooleanToSignedIntegral)
16054 return Success(IntResult, E);
16057 case CK_FixedPointToIntegral: {
16062 llvm::APSInt
Result = Src.convertToInt(
16070 case CK_FixedPointToBoolean: {
16073 if (!
Evaluate(Val, Info, SubExpr))
16078 case CK_IntegralCast: {
16079 if (!Visit(SubExpr))
16088 if (
Result.isAddrLabelDiff())
16106 if (!ED->isFixed()) {
16110 ED->getValueRange(
Max,
Min);
16113 if (ED->getNumNegativeBits() &&
16114 (
Max.slt(
Result.getInt().getSExtValue()) ||
16115 Min.sgt(
Result.getInt().getSExtValue())))
16116 Info.CCEDiag(E, diag::note_constexpr_unscoped_enum_out_of_range)
16117 << llvm::toString(
Result.getInt(), 10) <<
Min.getSExtValue()
16118 <<
Max.getSExtValue() << ED;
16119 else if (!ED->getNumNegativeBits() &&
16120 Max.ult(
Result.getInt().getZExtValue()))
16121 Info.CCEDiag(E, diag::note_constexpr_unscoped_enum_out_of_range)
16122 << llvm::toString(
Result.getInt(), 10) <<
Min.getZExtValue()
16123 <<
Max.getZExtValue() << ED;
16131 case CK_PointerToIntegral: {
16132 CCEDiag(E, diag::note_constexpr_invalid_cast)
16133 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
16140 if (LV.getLValueBase()) {
16148 LV.Designator.setInvalid();
16156 if (!
V.toIntegralConstant(AsInt, SrcType, Info.Ctx))
16157 llvm_unreachable(
"Can't cast this!");
16162 case CK_IntegralComplexToReal: {
16166 return Success(
C.getComplexIntReal(), E);
16169 case CK_FloatingToIntegral: {
16179 case CK_HLSLVectorTruncation: {
16187 llvm_unreachable(
"unknown cast resulting in integral value");
16190bool IntExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
16195 if (!LV.isComplexInt())
16197 return Success(LV.getComplexIntReal(), E);
16203bool IntExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
16208 if (!LV.isComplexInt())
16210 return Success(LV.getComplexIntImag(), E);
16217bool IntExprEvaluator::VisitSizeOfPackExpr(
const SizeOfPackExpr *E) {
16221bool IntExprEvaluator::VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E) {
16225bool IntExprEvaluator::VisitConceptSpecializationExpr(
16226 const ConceptSpecializationExpr *E) {
16230bool IntExprEvaluator::VisitRequiresExpr(
const RequiresExpr *E) {
16234bool FixedPointExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
16244 if (!
Result.isFixedPoint())
16247 APFixedPoint Negated =
Result.getFixedPoint().negate(&Overflowed);
16261bool FixedPointExprEvaluator::VisitCastExpr(
const CastExpr *E) {
16263 QualType DestType = E->
getType();
16265 "Expected destination type to be a fixed point type");
16269 case CK_FixedPointCast: {
16274 APFixedPoint
Result = Src.convert(DestFXSema, &Overflowed);
16276 if (Info.checkingForUndefinedBehavior())
16278 diag::warn_fixedpoint_constant_overflow)
16285 case CK_IntegralToFixedPoint: {
16291 APFixedPoint IntResult = APFixedPoint::getFromIntValue(
16295 if (Info.checkingForUndefinedBehavior())
16297 diag::warn_fixedpoint_constant_overflow)
16298 << IntResult.toString() << E->
getType();
16303 return Success(IntResult, E);
16305 case CK_FloatingToFixedPoint: {
16311 APFixedPoint
Result = APFixedPoint::getFromFloatValue(
16315 if (Info.checkingForUndefinedBehavior())
16317 diag::warn_fixedpoint_constant_overflow)
16326 case CK_LValueToRValue:
16327 return ExprEvaluatorBaseTy::VisitCastExpr(E);
16333bool FixedPointExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
16335 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
16337 const Expr *LHS = E->
getLHS();
16338 const Expr *RHS = E->
getRHS();
16349 bool OpOverflow =
false, ConversionOverflow =
false;
16350 APFixedPoint
Result(LHSFX.getSemantics());
16353 Result = LHSFX.add(RHSFX, &OpOverflow)
16354 .convert(ResultFXSema, &ConversionOverflow);
16358 Result = LHSFX.sub(RHSFX, &OpOverflow)
16359 .convert(ResultFXSema, &ConversionOverflow);
16363 Result = LHSFX.mul(RHSFX, &OpOverflow)
16364 .convert(ResultFXSema, &ConversionOverflow);
16368 if (RHSFX.getValue() == 0) {
16369 Info.FFDiag(E, diag::note_expr_divide_by_zero);
16372 Result = LHSFX.div(RHSFX, &OpOverflow)
16373 .convert(ResultFXSema, &ConversionOverflow);
16379 llvm::APSInt RHSVal = RHSFX.getValue();
16382 LHSSema.getWidth() - (unsigned)LHSSema.hasUnsignedPadding();
16383 unsigned Amt = RHSVal.getLimitedValue(ShiftBW - 1);
16387 if (RHSVal.isNegative())
16388 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHSVal;
16389 else if (Amt != RHSVal)
16390 Info.CCEDiag(E, diag::note_constexpr_large_shift)
16391 << RHSVal << E->
getType() << ShiftBW;
16394 Result = LHSFX.shl(Amt, &OpOverflow);
16396 Result = LHSFX.shr(Amt, &OpOverflow);
16402 if (OpOverflow || ConversionOverflow) {
16403 if (Info.checkingForUndefinedBehavior())
16405 diag::warn_fixedpoint_constant_overflow)
16418class FloatExprEvaluator
16419 :
public ExprEvaluatorBase<FloatExprEvaluator> {
16422 FloatExprEvaluator(EvalInfo &info, APFloat &result)
16423 : ExprEvaluatorBaseTy(info),
Result(result) {}
16430 bool ZeroInitialization(
const Expr *E) {
16435 bool VisitCallExpr(
const CallExpr *E);
16437 bool VisitUnaryOperator(
const UnaryOperator *E);
16438 bool VisitBinaryOperator(
const BinaryOperator *E);
16439 bool VisitFloatingLiteral(
const FloatingLiteral *E);
16440 bool VisitCastExpr(
const CastExpr *E);
16442 bool VisitUnaryReal(
const UnaryOperator *E);
16443 bool VisitUnaryImag(
const UnaryOperator *E);
16452 return FloatExprEvaluator(Info, Result).Visit(E);
16459 llvm::APFloat &Result) {
16461 if (!S)
return false;
16463 const llvm::fltSemantics &Sem = Context.getFloatTypeSemantics(ResultTy);
16469 fill = llvm::APInt(32, 0);
16470 else if (S->
getString().getAsInteger(0, fill))
16473 if (Context.getTargetInfo().isNan2008()) {
16475 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
16477 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
16485 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
16487 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
16493bool FloatExprEvaluator::VisitCallExpr(
const CallExpr *E) {
16494 if (!IsConstantEvaluatedBuiltinCall(E))
16495 return ExprEvaluatorBaseTy::VisitCallExpr(E);
16501 case Builtin::BI__builtin_huge_val:
16502 case Builtin::BI__builtin_huge_valf:
16503 case Builtin::BI__builtin_huge_vall:
16504 case Builtin::BI__builtin_huge_valf16:
16505 case Builtin::BI__builtin_huge_valf128:
16506 case Builtin::BI__builtin_inf:
16507 case Builtin::BI__builtin_inff:
16508 case Builtin::BI__builtin_infl:
16509 case Builtin::BI__builtin_inff16:
16510 case Builtin::BI__builtin_inff128: {
16511 const llvm::fltSemantics &Sem =
16513 Result = llvm::APFloat::getInf(Sem);
16517 case Builtin::BI__builtin_nans:
16518 case Builtin::BI__builtin_nansf:
16519 case Builtin::BI__builtin_nansl:
16520 case Builtin::BI__builtin_nansf16:
16521 case Builtin::BI__builtin_nansf128:
16527 case Builtin::BI__builtin_nan:
16528 case Builtin::BI__builtin_nanf:
16529 case Builtin::BI__builtin_nanl:
16530 case Builtin::BI__builtin_nanf16:
16531 case Builtin::BI__builtin_nanf128:
16539 case Builtin::BI__builtin_elementwise_abs:
16540 case Builtin::BI__builtin_fabs:
16541 case Builtin::BI__builtin_fabsf:
16542 case Builtin::BI__builtin_fabsl:
16543 case Builtin::BI__builtin_fabsf128:
16552 if (
Result.isNegative())
16556 case Builtin::BI__arithmetic_fence:
16563 case Builtin::BI__builtin_copysign:
16564 case Builtin::BI__builtin_copysignf:
16565 case Builtin::BI__builtin_copysignl:
16566 case Builtin::BI__builtin_copysignf128: {
16575 case Builtin::BI__builtin_fmax:
16576 case Builtin::BI__builtin_fmaxf:
16577 case Builtin::BI__builtin_fmaxl:
16578 case Builtin::BI__builtin_fmaxf16:
16579 case Builtin::BI__builtin_fmaxf128: {
16588 case Builtin::BI__builtin_fmin:
16589 case Builtin::BI__builtin_fminf:
16590 case Builtin::BI__builtin_fminl:
16591 case Builtin::BI__builtin_fminf16:
16592 case Builtin::BI__builtin_fminf128: {
16601 case Builtin::BI__builtin_fmaximum_num:
16602 case Builtin::BI__builtin_fmaximum_numf:
16603 case Builtin::BI__builtin_fmaximum_numl:
16604 case Builtin::BI__builtin_fmaximum_numf16:
16605 case Builtin::BI__builtin_fmaximum_numf128: {
16614 case Builtin::BI__builtin_fminimum_num:
16615 case Builtin::BI__builtin_fminimum_numf:
16616 case Builtin::BI__builtin_fminimum_numl:
16617 case Builtin::BI__builtin_fminimum_numf16:
16618 case Builtin::BI__builtin_fminimum_numf128: {
16627 case Builtin::BI__builtin_elementwise_fma: {
16632 APFloat SourceY(0.), SourceZ(0.);
16638 (void)
Result.fusedMultiplyAdd(SourceY, SourceZ, RM);
16644bool FloatExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
16656bool FloatExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
16667 Result = llvm::APFloat::getZero(Sem);
16671bool FloatExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
16673 default:
return Error(E);
16687bool FloatExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
16689 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
16693 if (!LHSOK && !Info.noteFailure())
16699bool FloatExprEvaluator::VisitFloatingLiteral(
const FloatingLiteral *E) {
16704bool FloatExprEvaluator::VisitCastExpr(
const CastExpr *E) {
16709 return ExprEvaluatorBaseTy::VisitCastExpr(E);
16711 case CK_IntegralToFloating: {
16720 case CK_FixedPointToFloating: {
16729 case CK_FloatingCast: {
16730 if (!Visit(SubExpr))
16736 case CK_FloatingComplexToReal: {
16740 Result =
V.getComplexFloatReal();
16743 case CK_HLSLVectorTruncation: {
16757class ComplexExprEvaluator
16758 :
public ExprEvaluatorBase<ComplexExprEvaluator> {
16762 ComplexExprEvaluator(EvalInfo &info, ComplexValue &
Result)
16770 bool ZeroInitialization(
const Expr *E);
16776 bool VisitImaginaryLiteral(
const ImaginaryLiteral *E);
16777 bool VisitCastExpr(
const CastExpr *E);
16778 bool VisitBinaryOperator(
const BinaryOperator *E);
16779 bool VisitUnaryOperator(
const UnaryOperator *E);
16780 bool VisitInitListExpr(
const InitListExpr *E);
16781 bool VisitCallExpr(
const CallExpr *E);
16789 return ComplexExprEvaluator(Info, Result).Visit(E);
16792bool ComplexExprEvaluator::ZeroInitialization(
const Expr *E) {
16793 QualType ElemTy = E->
getType()->
castAs<ComplexType>()->getElementType();
16795 Result.makeComplexFloat();
16800 Result.makeComplexInt();
16808bool ComplexExprEvaluator::VisitImaginaryLiteral(
const ImaginaryLiteral *E) {
16812 Result.makeComplexFloat();
16821 "Unexpected imaginary literal.");
16823 Result.makeComplexInt();
16828 Result.IntReal =
APSInt(Imag.getBitWidth(), !Imag.isSigned());
16833bool ComplexExprEvaluator::VisitCastExpr(
const CastExpr *E) {
16837 case CK_BaseToDerived:
16838 case CK_DerivedToBase:
16839 case CK_UncheckedDerivedToBase:
16842 case CK_ArrayToPointerDecay:
16843 case CK_FunctionToPointerDecay:
16844 case CK_NullToPointer:
16845 case CK_NullToMemberPointer:
16846 case CK_BaseToDerivedMemberPointer:
16847 case CK_DerivedToBaseMemberPointer:
16848 case CK_MemberPointerToBoolean:
16849 case CK_ReinterpretMemberPointer:
16850 case CK_ConstructorConversion:
16851 case CK_IntegralToPointer:
16852 case CK_PointerToIntegral:
16853 case CK_PointerToBoolean:
16855 case CK_VectorSplat:
16856 case CK_IntegralCast:
16857 case CK_BooleanToSignedIntegral:
16858 case CK_IntegralToBoolean:
16859 case CK_IntegralToFloating:
16860 case CK_FloatingToIntegral:
16861 case CK_FloatingToBoolean:
16862 case CK_FloatingCast:
16863 case CK_CPointerToObjCPointerCast:
16864 case CK_BlockPointerToObjCPointerCast:
16865 case CK_AnyPointerToBlockPointerCast:
16866 case CK_ObjCObjectLValueCast:
16867 case CK_FloatingComplexToReal:
16868 case CK_FloatingComplexToBoolean:
16869 case CK_IntegralComplexToReal:
16870 case CK_IntegralComplexToBoolean:
16871 case CK_ARCProduceObject:
16872 case CK_ARCConsumeObject:
16873 case CK_ARCReclaimReturnedObject:
16874 case CK_ARCExtendBlockObject:
16875 case CK_CopyAndAutoreleaseBlockObject:
16876 case CK_BuiltinFnToFnPtr:
16877 case CK_ZeroToOCLOpaqueType:
16878 case CK_NonAtomicToAtomic:
16879 case CK_AddressSpaceConversion:
16880 case CK_IntToOCLSampler:
16881 case CK_FloatingToFixedPoint:
16882 case CK_FixedPointToFloating:
16883 case CK_FixedPointCast:
16884 case CK_FixedPointToBoolean:
16885 case CK_FixedPointToIntegral:
16886 case CK_IntegralToFixedPoint:
16887 case CK_MatrixCast:
16888 case CK_HLSLVectorTruncation:
16889 case CK_HLSLElementwiseCast:
16890 case CK_HLSLAggregateSplatCast:
16891 llvm_unreachable(
"invalid cast kind for complex value");
16893 case CK_LValueToRValue:
16894 case CK_AtomicToNonAtomic:
16896 case CK_LValueToRValueBitCast:
16897 case CK_HLSLArrayRValue:
16898 return ExprEvaluatorBaseTy::VisitCastExpr(E);
16901 case CK_LValueBitCast:
16902 case CK_UserDefinedConversion:
16905 case CK_FloatingRealToComplex: {
16910 Result.makeComplexFloat();
16915 case CK_FloatingComplexCast: {
16919 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
16927 case CK_FloatingComplexToIntegralComplex: {
16931 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
16934 Result.makeComplexInt();
16941 case CK_IntegralRealToComplex: {
16946 Result.makeComplexInt();
16947 Result.IntImag =
APSInt(Real.getBitWidth(), !Real.isSigned());
16951 case CK_IntegralComplexCast: {
16955 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
16964 case CK_IntegralComplexToFloatingComplex: {
16970 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
16973 Result.makeComplexFloat();
16975 To,
Result.FloatReal) &&
16981 llvm_unreachable(
"unknown cast resulting in complex value");
16985 APFloat &ResR, APFloat &ResI) {
16991 APFloat AC = A *
C;
16992 APFloat BD = B * D;
16993 APFloat AD = A * D;
16994 APFloat BC = B *
C;
16997 if (ResR.isNaN() && ResI.isNaN()) {
16998 bool Recalc =
false;
16999 if (A.isInfinity() || B.isInfinity()) {
17000 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
17002 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
17005 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
17007 D = APFloat::copySign(APFloat(D.getSemantics()), D);
17010 if (
C.isInfinity() || D.isInfinity()) {
17011 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
17013 D = APFloat::copySign(APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0),
17016 A = APFloat::copySign(APFloat(A.getSemantics()), A);
17018 B = APFloat::copySign(APFloat(B.getSemantics()), B);
17021 if (!Recalc && (AC.isInfinity() || BD.isInfinity() || AD.isInfinity() ||
17022 BC.isInfinity())) {
17024 A = APFloat::copySign(APFloat(A.getSemantics()), A);
17026 B = APFloat::copySign(APFloat(B.getSemantics()), B);
17028 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
17030 D = APFloat::copySign(APFloat(D.getSemantics()), D);
17034 ResR = APFloat::getInf(A.getSemantics()) * (A *
C - B * D);
17035 ResI = APFloat::getInf(A.getSemantics()) * (A * D + B *
C);
17041 APFloat &ResR, APFloat &ResI) {
17048 APFloat MaxCD = maxnum(
abs(
C),
abs(D));
17049 if (MaxCD.isFinite()) {
17050 DenomLogB =
ilogb(MaxCD);
17051 C =
scalbn(
C, -DenomLogB, APFloat::rmNearestTiesToEven);
17052 D =
scalbn(D, -DenomLogB, APFloat::rmNearestTiesToEven);
17054 APFloat Denom =
C *
C + D * D;
17056 scalbn((A *
C + B * D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
17058 scalbn((B *
C - A * D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
17059 if (ResR.isNaN() && ResI.isNaN()) {
17060 if (Denom.isPosZero() && (!A.isNaN() || !B.isNaN())) {
17061 ResR = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * A;
17062 ResI = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * B;
17063 }
else if ((A.isInfinity() || B.isInfinity()) &&
C.isFinite() &&
17065 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
17067 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
17069 ResR = APFloat::getInf(ResR.getSemantics()) * (A *
C + B * D);
17070 ResI = APFloat::getInf(ResI.getSemantics()) * (B *
C - A * D);
17071 }
else if (MaxCD.isInfinity() && A.isFinite() && B.isFinite()) {
17072 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
17074 D = APFloat::copySign(APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0),
17076 ResR = APFloat::getZero(ResR.getSemantics()) * (A *
C + B * D);
17077 ResI = APFloat::getZero(ResI.getSemantics()) * (B *
C - A * D);
17082bool ComplexExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
17084 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
17088 bool LHSReal =
false, RHSReal =
false;
17096 Result.makeComplexFloat();
17100 LHSOK = Visit(E->
getLHS());
17102 if (!LHSOK && !Info.noteFailure())
17108 APFloat &Real = RHS.FloatReal;
17111 RHS.makeComplexFloat();
17112 RHS.FloatImag =
APFloat(Real.getSemantics());
17116 assert(!(LHSReal && RHSReal) &&
17117 "Cannot have both operands of a complex operation be real.");
17119 default:
return Error(E);
17121 if (
Result.isComplexFloat()) {
17122 Result.getComplexFloatReal().add(RHS.getComplexFloatReal(),
17123 APFloat::rmNearestTiesToEven);
17125 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
17127 Result.getComplexFloatImag().add(RHS.getComplexFloatImag(),
17128 APFloat::rmNearestTiesToEven);
17130 Result.getComplexIntReal() += RHS.getComplexIntReal();
17131 Result.getComplexIntImag() += RHS.getComplexIntImag();
17135 if (
Result.isComplexFloat()) {
17136 Result.getComplexFloatReal().subtract(RHS.getComplexFloatReal(),
17137 APFloat::rmNearestTiesToEven);
17139 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
17140 Result.getComplexFloatImag().changeSign();
17141 }
else if (!RHSReal) {
17142 Result.getComplexFloatImag().subtract(RHS.getComplexFloatImag(),
17143 APFloat::rmNearestTiesToEven);
17146 Result.getComplexIntReal() -= RHS.getComplexIntReal();
17147 Result.getComplexIntImag() -= RHS.getComplexIntImag();
17151 if (
Result.isComplexFloat()) {
17156 ComplexValue LHS =
Result;
17157 APFloat &A = LHS.getComplexFloatReal();
17158 APFloat &B = LHS.getComplexFloatImag();
17159 APFloat &
C = RHS.getComplexFloatReal();
17160 APFloat &D = RHS.getComplexFloatImag();
17164 assert(!RHSReal &&
"Cannot have two real operands for a complex op!");
17172 }
else if (RHSReal) {
17184 ComplexValue LHS =
Result;
17185 Result.getComplexIntReal() =
17186 (LHS.getComplexIntReal() * RHS.getComplexIntReal() -
17187 LHS.getComplexIntImag() * RHS.getComplexIntImag());
17188 Result.getComplexIntImag() =
17189 (LHS.getComplexIntReal() * RHS.getComplexIntImag() +
17190 LHS.getComplexIntImag() * RHS.getComplexIntReal());
17194 if (
Result.isComplexFloat()) {
17199 ComplexValue LHS =
Result;
17200 APFloat &A = LHS.getComplexFloatReal();
17201 APFloat &B = LHS.getComplexFloatImag();
17202 APFloat &
C = RHS.getComplexFloatReal();
17203 APFloat &D = RHS.getComplexFloatImag();
17217 B = APFloat::getZero(A.getSemantics());
17222 ComplexValue LHS =
Result;
17223 APSInt Den = RHS.getComplexIntReal() * RHS.getComplexIntReal() +
17224 RHS.getComplexIntImag() * RHS.getComplexIntImag();
17226 return Error(E, diag::note_expr_divide_by_zero);
17228 Result.getComplexIntReal() =
17229 (LHS.getComplexIntReal() * RHS.getComplexIntReal() +
17230 LHS.getComplexIntImag() * RHS.getComplexIntImag()) / Den;
17231 Result.getComplexIntImag() =
17232 (LHS.getComplexIntImag() * RHS.getComplexIntReal() -
17233 LHS.getComplexIntReal() * RHS.getComplexIntImag()) / Den;
17241bool ComplexExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
17255 if (
Result.isComplexFloat()) {
17256 Result.getComplexFloatReal().changeSign();
17257 Result.getComplexFloatImag().changeSign();
17260 Result.getComplexIntReal() = -
Result.getComplexIntReal();
17261 Result.getComplexIntImag() = -
Result.getComplexIntImag();
17265 if (
Result.isComplexFloat())
17266 Result.getComplexFloatImag().changeSign();
17268 Result.getComplexIntImag() = -
Result.getComplexIntImag();
17273bool ComplexExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
17276 Result.makeComplexFloat();
17282 Result.makeComplexInt();
17290 return ExprEvaluatorBaseTy::VisitInitListExpr(E);
17293bool ComplexExprEvaluator::VisitCallExpr(
const CallExpr *E) {
17294 if (!IsConstantEvaluatedBuiltinCall(E))
17295 return ExprEvaluatorBaseTy::VisitCallExpr(E);
17298 case Builtin::BI__builtin_complex:
17299 Result.makeComplexFloat();
17317class AtomicExprEvaluator :
17318 public ExprEvaluatorBase<AtomicExprEvaluator> {
17319 const LValue *
This;
17322 AtomicExprEvaluator(EvalInfo &Info,
const LValue *This,
APValue &
Result)
17330 bool ZeroInitialization(
const Expr *E) {
17331 ImplicitValueInitExpr VIE(
17339 bool VisitCastExpr(
const CastExpr *E) {
17342 return ExprEvaluatorBaseTy::VisitCastExpr(E);
17343 case CK_NullToPointer:
17345 return ZeroInitialization(E);
17346 case CK_NonAtomicToAtomic:
17358 return AtomicExprEvaluator(Info,
This, Result).Visit(E);
17367class VoidExprEvaluator
17368 :
public ExprEvaluatorBase<VoidExprEvaluator> {
17370 VoidExprEvaluator(EvalInfo &Info) : ExprEvaluatorBaseTy(Info) {}
17374 bool ZeroInitialization(
const Expr *E) {
return true; }
17376 bool VisitCastExpr(
const CastExpr *E) {
17379 return ExprEvaluatorBaseTy::VisitCastExpr(E);
17386 bool VisitCallExpr(
const CallExpr *E) {
17387 if (!IsConstantEvaluatedBuiltinCall(E))
17388 return ExprEvaluatorBaseTy::VisitCallExpr(E);
17391 case Builtin::BI__assume:
17392 case Builtin::BI__builtin_assume:
17396 case Builtin::BI__builtin_operator_delete:
17404 bool VisitCXXDeleteExpr(
const CXXDeleteExpr *E);
17408bool VoidExprEvaluator::VisitCXXDeleteExpr(
const CXXDeleteExpr *E) {
17410 if (Info.SpeculativeEvaluationDepth)
17414 if (!OperatorDelete
17415 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
17416 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
17426 if (
Pointer.Designator.Invalid)
17430 if (
Pointer.isNullPointer()) {
17434 if (!Info.getLangOpts().CPlusPlus20)
17435 Info.CCEDiag(E, diag::note_constexpr_new);
17443 QualType AllocType =
Pointer.Base.getDynamicAllocType();
17449 Info.FFDiag(E, diag::note_constexpr_delete_base_nonvirt_dtor)
17458 if (VirtualDelete &&
17460 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
17461 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
17468 (*Alloc)->Value, AllocType))
17471 if (!Info.HeapAllocs.erase(
Pointer.Base.dyn_cast<DynamicAllocLValue>())) {
17476 Info.FFDiag(E, diag::note_constexpr_double_delete);
17486 return VoidExprEvaluator(Info).Visit(E);
17498 if (E->
isGLValue() ||
T->isFunctionType()) {
17502 LV.moveInto(Result);
17503 }
else if (
T->isVectorType()) {
17506 }
else if (
T->isIntegralOrEnumerationType()) {
17507 if (!IntExprEvaluator(Info, Result).Visit(E))
17509 }
else if (
T->hasPointerRepresentation()) {
17513 LV.moveInto(Result);
17514 }
else if (
T->isRealFloatingType()) {
17515 llvm::APFloat F(0.0);
17519 }
else if (
T->isAnyComplexType()) {
17523 C.moveInto(Result);
17524 }
else if (
T->isFixedPointType()) {
17525 if (!FixedPointExprEvaluator(Info, Result).Visit(E))
return false;
17526 }
else if (
T->isMemberPointerType()) {
17530 P.moveInto(Result);
17532 }
else if (
T->isArrayType()) {
17535 Info.CurrentCall->createTemporary(E,
T, ScopeKind::FullExpression, LV);
17539 }
else if (
T->isRecordType()) {
17542 Info.CurrentCall->createTemporary(E,
T, ScopeKind::FullExpression, LV);
17546 }
else if (
T->isVoidType()) {
17547 if (!Info.getLangOpts().CPlusPlus11)
17548 Info.CCEDiag(E, diag::note_constexpr_nonliteral)
17552 }
else if (
T->isAtomicType()) {
17553 QualType Unqual =
T.getAtomicUnqualifiedType();
17557 E, Unqual, ScopeKind::FullExpression, LV);
17565 }
else if (Info.getLangOpts().CPlusPlus11) {
17566 Info.FFDiag(E, diag::note_constexpr_nonliteral) << E->
getType();
17569 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
17580 const Expr *E,
bool AllowNonLiteralTypes) {
17596 if (
T->isArrayType())
17598 else if (
T->isRecordType())
17600 else if (
T->isAtomicType()) {
17601 QualType Unqual =
T.getAtomicUnqualifiedType();
17622 if (Info.EnableNewConstInterp) {
17626 ConstantExprKind::Normal);
17635 LV.setFrom(Info.Ctx, Result);
17642 ConstantExprKind::Normal) &&
17650 if (
const auto *L = dyn_cast<IntegerLiteral>(Exp)) {
17652 APValue(
APSInt(L->getValue(), L->getType()->isUnsignedIntegerType()));
17657 if (
const auto *L = dyn_cast<CXXBoolLiteralExpr>(Exp)) {
17663 if (
const auto *FL = dyn_cast<FloatingLiteral>(Exp)) {
17664 Result =
APValue(FL->getValue());
17669 if (
const auto *L = dyn_cast<CharacterLiteral>(Exp)) {
17675 if (
const auto *CE = dyn_cast<ConstantExpr>(Exp)) {
17676 if (CE->hasAPValueResult()) {
17677 APValue APV = CE->getAPValueResult();
17679 Result = std::move(APV);
17755 bool InConstantContext)
const {
17757 "Expression evaluator can't be called on a dependent expression.");
17758 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsRValue");
17760 Info.InConstantContext = InConstantContext;
17761 return ::EvaluateAsRValue(
this,
Result, Ctx, Info);
17765 bool InConstantContext)
const {
17767 "Expression evaluator can't be called on a dependent expression.");
17768 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsBooleanCondition");
17776 bool InConstantContext)
const {
17778 "Expression evaluator can't be called on a dependent expression.");
17779 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsInt");
17781 Info.InConstantContext = InConstantContext;
17782 return ::EvaluateAsInt(
this,
Result, Ctx, AllowSideEffects, Info);
17787 bool InConstantContext)
const {
17789 "Expression evaluator can't be called on a dependent expression.");
17790 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFixedPoint");
17792 Info.InConstantContext = InConstantContext;
17793 return ::EvaluateAsFixedPoint(
this,
Result, Ctx, AllowSideEffects, Info);
17798 bool InConstantContext)
const {
17800 "Expression evaluator can't be called on a dependent expression.");
17802 if (!
getType()->isRealFloatingType())
17805 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFloat");
17817 bool InConstantContext)
const {
17819 "Expression evaluator can't be called on a dependent expression.");
17821 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsLValue");
17823 Info.InConstantContext = InConstantContext;
17827 if (Info.EnableNewConstInterp) {
17829 ConstantExprKind::Normal))
17832 LV.setFrom(Ctx,
Result.Val);
17835 ConstantExprKind::Normal, CheckedTemps);
17838 if (!
EvaluateLValue(
this, LV, Info) || !Info.discardCleanups() ||
17839 Result.HasSideEffects ||
17842 ConstantExprKind::Normal, CheckedTemps))
17845 LV.moveInto(
Result.Val);
17852 bool IsConstantDestruction) {
17853 EvalInfo Info(Ctx, EStatus,
17856 Info.setEvaluatingDecl(
Base, DestroyedValue,
17857 EvalInfo::EvaluatingDeclKind::Dtor);
17858 Info.InConstantContext = IsConstantDestruction;
17867 if (!Info.discardCleanups())
17868 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
17876 "Expression evaluator can't be called on a dependent expression.");
17882 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsConstantExpr");
17884 EvalInfo Info(Ctx,
Result, EM);
17885 Info.InConstantContext =
true;
17887 if (Info.EnableNewConstInterp) {
17891 getStorageType(Ctx,
this),
Result.Val, Kind);
17896 if (Kind == ConstantExprKind::ClassTemplateArgument)
17912 FullExpressionRAII
Scope(Info);
17917 if (!Info.discardCleanups())
17918 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
17928 if (Kind == ConstantExprKind::ClassTemplateArgument &&
17931 Result.HasSideEffects)) {
17943 bool IsConstantInitialization)
const {
17945 "Expression evaluator can't be called on a dependent expression.");
17946 assert(VD &&
"Need a valid VarDecl");
17948 llvm::TimeTraceScope TimeScope(
"EvaluateAsInitializer", [&] {
17950 llvm::raw_string_ostream OS(Name);
17956 EStatus.
Diag = &Notes;
17958 EvalInfo Info(Ctx, EStatus,
17959 (IsConstantInitialization &&
17963 Info.setEvaluatingDecl(VD,
Value);
17964 Info.InConstantContext = IsConstantInitialization;
17969 if (Info.EnableNewConstInterp) {
17970 auto &InterpCtx =
const_cast<ASTContext &
>(Ctx).getInterpContext();
17971 if (!InterpCtx.evaluateAsInitializer(Info, VD,
this,
Value))
17975 ConstantExprKind::Normal);
17990 FullExpressionRAII
Scope(Info);
17993 EStatus.HasSideEffects)
17999 Info.performLifetimeExtension();
18001 if (!Info.discardCleanups())
18002 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
18006 ConstantExprKind::Normal) &&
18013 EStatus.
Diag = &Notes;
18030 IsConstantDestruction) ||
18042 "Expression evaluator can't be called on a dependent expression.");
18051 "Expression evaluator can't be called on a dependent expression.");
18053 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstInt");
18056 Info.InConstantContext =
true;
18060 assert(
Result &&
"Could not evaluate expression");
18061 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
18063 return EVResult.Val.getInt();
18069 "Expression evaluator can't be called on a dependent expression.");
18071 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstIntCheckOverflow");
18073 EVResult.Diag =
Diag;
18075 Info.InConstantContext =
true;
18076 Info.CheckingForUndefinedBehavior =
true;
18080 assert(
Result &&
"Could not evaluate expression");
18081 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
18083 return EVResult.Val.getInt();
18088 "Expression evaluator can't be called on a dependent expression.");
18090 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateForOverflow");
18095 Info.CheckingForUndefinedBehavior =
true;
18101 assert(
Val.isLValue());
18127 IK_ICEIfUnevaluated,
18143static ICEDiag
Worst(ICEDiag A, ICEDiag B) {
return A.Kind >= B.Kind ? A : B; }
18150 Info.InConstantContext =
true;
18159 assert(!E->
isValueDependent() &&
"Should not see value dependent exprs!");
18164#define ABSTRACT_STMT(Node)
18165#define STMT(Node, Base) case Expr::Node##Class:
18166#define EXPR(Node, Base)
18167#include "clang/AST/StmtNodes.inc"
18168 case Expr::PredefinedExprClass:
18169 case Expr::FloatingLiteralClass:
18170 case Expr::ImaginaryLiteralClass:
18171 case Expr::StringLiteralClass:
18172 case Expr::ArraySubscriptExprClass:
18173 case Expr::MatrixSubscriptExprClass:
18174 case Expr::ArraySectionExprClass:
18175 case Expr::OMPArrayShapingExprClass:
18176 case Expr::OMPIteratorExprClass:
18177 case Expr::MemberExprClass:
18178 case Expr::CompoundAssignOperatorClass:
18179 case Expr::CompoundLiteralExprClass:
18180 case Expr::ExtVectorElementExprClass:
18181 case Expr::DesignatedInitExprClass:
18182 case Expr::ArrayInitLoopExprClass:
18183 case Expr::ArrayInitIndexExprClass:
18184 case Expr::NoInitExprClass:
18185 case Expr::DesignatedInitUpdateExprClass:
18186 case Expr::ImplicitValueInitExprClass:
18187 case Expr::ParenListExprClass:
18188 case Expr::VAArgExprClass:
18189 case Expr::AddrLabelExprClass:
18190 case Expr::StmtExprClass:
18191 case Expr::CXXMemberCallExprClass:
18192 case Expr::CUDAKernelCallExprClass:
18193 case Expr::CXXAddrspaceCastExprClass:
18194 case Expr::CXXDynamicCastExprClass:
18195 case Expr::CXXTypeidExprClass:
18196 case Expr::CXXUuidofExprClass:
18197 case Expr::MSPropertyRefExprClass:
18198 case Expr::MSPropertySubscriptExprClass:
18199 case Expr::CXXNullPtrLiteralExprClass:
18200 case Expr::UserDefinedLiteralClass:
18201 case Expr::CXXThisExprClass:
18202 case Expr::CXXThrowExprClass:
18203 case Expr::CXXNewExprClass:
18204 case Expr::CXXDeleteExprClass:
18205 case Expr::CXXPseudoDestructorExprClass:
18206 case Expr::UnresolvedLookupExprClass:
18207 case Expr::RecoveryExprClass:
18208 case Expr::DependentScopeDeclRefExprClass:
18209 case Expr::CXXConstructExprClass:
18210 case Expr::CXXInheritedCtorInitExprClass:
18211 case Expr::CXXStdInitializerListExprClass:
18212 case Expr::CXXBindTemporaryExprClass:
18213 case Expr::ExprWithCleanupsClass:
18214 case Expr::CXXTemporaryObjectExprClass:
18215 case Expr::CXXUnresolvedConstructExprClass:
18216 case Expr::CXXDependentScopeMemberExprClass:
18217 case Expr::UnresolvedMemberExprClass:
18218 case Expr::ObjCStringLiteralClass:
18219 case Expr::ObjCBoxedExprClass:
18220 case Expr::ObjCArrayLiteralClass:
18221 case Expr::ObjCDictionaryLiteralClass:
18222 case Expr::ObjCEncodeExprClass:
18223 case Expr::ObjCMessageExprClass:
18224 case Expr::ObjCSelectorExprClass:
18225 case Expr::ObjCProtocolExprClass:
18226 case Expr::ObjCIvarRefExprClass:
18227 case Expr::ObjCPropertyRefExprClass:
18228 case Expr::ObjCSubscriptRefExprClass:
18229 case Expr::ObjCIsaExprClass:
18230 case Expr::ObjCAvailabilityCheckExprClass:
18231 case Expr::ShuffleVectorExprClass:
18232 case Expr::ConvertVectorExprClass:
18233 case Expr::BlockExprClass:
18235 case Expr::OpaqueValueExprClass:
18236 case Expr::PackExpansionExprClass:
18237 case Expr::SubstNonTypeTemplateParmPackExprClass:
18238 case Expr::FunctionParmPackExprClass:
18239 case Expr::AsTypeExprClass:
18240 case Expr::ObjCIndirectCopyRestoreExprClass:
18241 case Expr::MaterializeTemporaryExprClass:
18242 case Expr::PseudoObjectExprClass:
18243 case Expr::AtomicExprClass:
18244 case Expr::LambdaExprClass:
18245 case Expr::CXXFoldExprClass:
18246 case Expr::CoawaitExprClass:
18247 case Expr::DependentCoawaitExprClass:
18248 case Expr::CoyieldExprClass:
18249 case Expr::SYCLUniqueStableNameExprClass:
18250 case Expr::CXXParenListInitExprClass:
18251 case Expr::HLSLOutArgExprClass:
18254 case Expr::InitListExprClass: {
18265 case Expr::SizeOfPackExprClass:
18266 case Expr::GNUNullExprClass:
18267 case Expr::SourceLocExprClass:
18268 case Expr::EmbedExprClass:
18269 case Expr::OpenACCAsteriskSizeExprClass:
18272 case Expr::PackIndexingExprClass:
18275 case Expr::SubstNonTypeTemplateParmExprClass:
18279 case Expr::ConstantExprClass:
18282 case Expr::ParenExprClass:
18284 case Expr::GenericSelectionExprClass:
18286 case Expr::IntegerLiteralClass:
18287 case Expr::FixedPointLiteralClass:
18288 case Expr::CharacterLiteralClass:
18289 case Expr::ObjCBoolLiteralExprClass:
18290 case Expr::CXXBoolLiteralExprClass:
18291 case Expr::CXXScalarValueInitExprClass:
18292 case Expr::TypeTraitExprClass:
18293 case Expr::ConceptSpecializationExprClass:
18294 case Expr::RequiresExprClass:
18295 case Expr::ArrayTypeTraitExprClass:
18296 case Expr::ExpressionTraitExprClass:
18297 case Expr::CXXNoexceptExprClass:
18299 case Expr::CallExprClass:
18300 case Expr::CXXOperatorCallExprClass: {
18309 case Expr::CXXRewrittenBinaryOperatorClass:
18312 case Expr::DeclRefExprClass: {
18326 const VarDecl *VD = dyn_cast<VarDecl>(D);
18333 case Expr::UnaryOperatorClass: {
18356 llvm_unreachable(
"invalid unary operator class");
18358 case Expr::OffsetOfExprClass: {
18367 case Expr::UnaryExprOrTypeTraitExprClass: {
18369 if ((Exp->
getKind() == UETT_SizeOf) &&
18372 if (Exp->
getKind() == UETT_CountOf) {
18379 if (VAT->getElementType()->isArrayType())
18391 case Expr::BinaryOperatorClass: {
18436 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE) {
18439 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
18440 if (REval.isSigned() && REval.isAllOnes()) {
18442 if (LEval.isMinSignedValue())
18443 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
18451 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE)
18452 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
18458 return Worst(LHSResult, RHSResult);
18464 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICEIfUnevaluated) {
18474 return Worst(LHSResult, RHSResult);
18477 llvm_unreachable(
"invalid binary operator kind");
18479 case Expr::ImplicitCastExprClass:
18480 case Expr::CStyleCastExprClass:
18481 case Expr::CXXFunctionalCastExprClass:
18482 case Expr::CXXStaticCastExprClass:
18483 case Expr::CXXReinterpretCastExprClass:
18484 case Expr::CXXConstCastExprClass:
18485 case Expr::ObjCBridgedCastExprClass: {
18492 APSInt IgnoredVal(DestWidth, !DestSigned);
18497 if (FL->getValue().convertToInteger(IgnoredVal,
18498 llvm::APFloat::rmTowardZero,
18499 &Ignored) & APFloat::opInvalidOp)
18505 case CK_LValueToRValue:
18506 case CK_AtomicToNonAtomic:
18507 case CK_NonAtomicToAtomic:
18509 case CK_IntegralToBoolean:
18510 case CK_IntegralCast:
18516 case Expr::BinaryConditionalOperatorClass: {
18519 if (CommonResult.Kind == IK_NotICE)
return CommonResult;
18521 if (FalseResult.Kind == IK_NotICE)
return FalseResult;
18522 if (CommonResult.Kind == IK_ICEIfUnevaluated)
return CommonResult;
18523 if (FalseResult.Kind == IK_ICEIfUnevaluated &&
18525 return FalseResult;
18527 case Expr::ConditionalOperatorClass: {
18535 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
18538 if (CondResult.Kind == IK_NotICE)
18544 if (TrueResult.Kind == IK_NotICE)
18546 if (FalseResult.Kind == IK_NotICE)
18547 return FalseResult;
18548 if (CondResult.Kind == IK_ICEIfUnevaluated)
18550 if (TrueResult.Kind == IK_ICE && FalseResult.Kind == IK_ICE)
18556 return FalseResult;
18559 case Expr::CXXDefaultArgExprClass:
18561 case Expr::CXXDefaultInitExprClass:
18563 case Expr::ChooseExprClass: {
18566 case Expr::BuiltinBitCastExprClass: {
18567 if (!checkBitCastConstexprEligibility(
nullptr, Ctx,
cast<CastExpr>(E)))
18573 llvm_unreachable(
"Invalid StmtClass!");
18579 llvm::APSInt *
Value) {
18587 if (!Result.isInt())
18596 "Expression evaluator can't be called on a dependent expression.");
18598 ExprTimeTraceScope TimeScope(
this, Ctx,
"isIntegerConstantExpr");
18604 if (D.Kind != IK_ICE)
18609std::optional<llvm::APSInt>
18613 return std::nullopt;
18620 return std::nullopt;
18624 return std::nullopt;
18633 Info.InConstantContext =
true;
18636 llvm_unreachable(
"ICE cannot be evaluated!");
18643 "Expression evaluator can't be called on a dependent expression.");
18645 return CheckICE(
this, Ctx).Kind == IK_ICE;
18650 "Expression evaluator can't be called on a dependent expression.");
18667 Status.Diag = &Diags;
18674 Info.discardCleanups() && !Status.HasSideEffects;
18676 return IsConstExpr && Diags.empty();
18684 "Expression evaluator can't be called on a dependent expression.");
18686 llvm::TimeTraceScope TimeScope(
"EvaluateWithSubstitution", [&] {
18688 llvm::raw_string_ostream OS(Name);
18696 Info.InConstantContext =
true;
18699 const LValue *ThisPtr =
nullptr;
18702 auto *MD = dyn_cast<CXXMethodDecl>(Callee);
18703 assert(MD &&
"Don't provide `this` for non-methods.");
18704 assert(MD->isImplicitObjectMemberFunction() &&
18705 "Don't provide `this` for methods without an implicit object.");
18707 if (!
This->isValueDependent() &&
18710 ThisPtr = &ThisVal;
18717 CallRef
Call = Info.CurrentCall->createCall(Callee);
18720 unsigned Idx = I - Args.begin();
18721 if (Idx >= Callee->getNumParams())
18723 const ParmVarDecl *PVD = Callee->getParamDecl(Idx);
18724 if ((*I)->isValueDependent() ||
18728 if (
APValue *Slot = Info.getParamSlot(
Call, PVD))
18739 Info.discardCleanups();
18743 CallStackFrame Frame(Info, Callee->getLocation(), Callee, ThisPtr,
This,
18746 FullExpressionRAII
Scope(Info);
18760 llvm::TimeTraceScope TimeScope(
"isPotentialConstantExpr", [&] {
18762 llvm::raw_string_ostream OS(Name);
18769 Status.
Diag = &Diags;
18773 Info.InConstantContext =
true;
18774 Info.CheckingPotentialConstantExpression =
true;
18777 if (Info.EnableNewConstInterp) {
18779 return Diags.empty();
18790 This.set({&VIE, Info.CurrentCall->Index});
18798 Info.setEvaluatingDecl(
This.getLValueBase(), Scratch);
18804 &VIE, Args, CallRef(), FD->
getBody(), Info, Scratch,
18808 return Diags.empty();
18816 "Expression evaluator can't be called on a dependent expression.");
18819 Status.
Diag = &Diags;
18823 Info.InConstantContext =
true;
18824 Info.CheckingPotentialConstantExpression =
true;
18826 if (Info.EnableNewConstInterp) {
18828 return Diags.empty();
18833 nullptr, CallRef());
18837 return Diags.empty();
18841 unsigned Type)
const {
18842 if (!
getType()->isPointerType())
18851 EvalInfo &Info, std::string *StringResult) {
18863 if (
const StringLiteral *S = dyn_cast_or_null<StringLiteral>(
18864 String.getLValueBase().dyn_cast<
const Expr *>())) {
18867 if (Off >= 0 && (uint64_t)Off <= (uint64_t)Str.size() &&
18871 Str = Str.substr(Off);
18873 StringRef::size_type Pos = Str.find(0);
18874 if (Pos != StringRef::npos)
18875 Str = Str.substr(0, Pos);
18877 Result = Str.size();
18879 *StringResult = Str;
18887 for (uint64_t Strlen = 0; ; ++Strlen) {
18895 }
else if (StringResult)
18896 StringResult->push_back(Char.
getInt().getExtValue());
18906 std::string StringResult;
18909 return StringResult;
18913template <
typename T>
18915 const Expr *SizeExpression,
18916 const Expr *PtrExpression,
18920 Info.InConstantContext =
true;
18922 if (Info.EnableNewConstInterp)
18924 PtrExpression, Result);
18927 FullExpressionRAII
Scope(Info);
18932 uint64_t Size = SizeValue.getZExtValue();
18935 if constexpr (std::is_same_v<APValue, T>)
18938 if (Size < Result.max_size())
18939 Result.reserve(Size);
18945 for (uint64_t I = 0; I < Size; ++I) {
18951 if constexpr (std::is_same_v<APValue, T>) {
18952 Result.getArrayInitializedElt(I) = std::move(Char);
18956 assert(
C.getBitWidth() <= 8 &&
18957 "string element not representable in char");
18959 Result.push_back(
static_cast<char>(
C.getExtValue()));
18970 const Expr *SizeExpression,
18974 PtrExpression, Ctx, Status);
18978 const Expr *SizeExpression,
18982 PtrExpression, Ctx, Status);
18989 if (Info.EnableNewConstInterp)
18996struct IsWithinLifetimeHandler {
18999 using result_type = std::optional<bool>;
19000 std::optional<bool> failed() {
return std::nullopt; }
19001 template <
typename T>
19002 std::optional<bool> found(
T &Subobj,
QualType SubobjType) {
19007std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &IEE,
19008 const CallExpr *E) {
19009 EvalInfo &Info = IEE.Info;
19014 if (!Info.InConstantContext)
19015 return std::nullopt;
19017 const Expr *Arg = E->
getArg(0);
19019 return std::nullopt;
19022 return std::nullopt;
19024 if (Val.allowConstexprUnknown())
19028 bool CalledFromStd =
false;
19029 const auto *
Callee = Info.CurrentCall->getCallee();
19030 if (Callee &&
Callee->isInStdNamespace()) {
19031 const IdentifierInfo *Identifier =
Callee->getIdentifier();
19032 CalledFromStd = Identifier && Identifier->
isStr(
"is_within_lifetime");
19034 Info.CCEDiag(CalledFromStd ? Info.CurrentCall->getCallRange().getBegin()
19036 diag::err_invalid_is_within_lifetime)
19037 << (CalledFromStd ?
"std::is_within_lifetime"
19038 :
"__builtin_is_within_lifetime")
19040 return std::nullopt;
19050 if (Val.isNullPointer() || Val.getLValueBase().isNull())
19052 QualType
T = Val.getLValueBase().getType();
19054 "Pointers to functions should have been typed as function pointers "
19055 "which would have been rejected earlier");
19058 if (Val.getLValueDesignator().isOnePastTheEnd())
19060 assert(Val.getLValueDesignator().isValidSubobject() &&
19061 "Unchecked case for valid subobject");
19065 CompleteObject CO =
19069 if (Info.EvaluatingDeclValue && CO.Value == Info.EvaluatingDeclValue)
19074 IsWithinLifetimeHandler handler{Info};
19075 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 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 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 EvaluateDecl(EvalInfo &Info, const Decl *D, bool EvaluateConditionDecl=false)
static void expandArray(APValue &Array, unsigned Index)
static bool handleLogicalOpForVector(const APInt &LHSValue, BinaryOperatorKind Opcode, const APInt &RHSValue, APInt &Result)
static unsigned FindDesignatorMismatch(QualType ObjType, const SubobjectDesignator &A, const SubobjectDesignator &B, bool &WasArrayIndex)
Find the position where two subobject designators diverge, or equivalently the length of the common i...
static bool isOnePastTheEndOfCompleteObject(const ASTContext &Ctx, const LValue &LV)
Determine whether this is a pointer past the end of the complete object referred to by the lvalue.
static unsigned getBaseIndex(const CXXRecordDecl *Derived, const CXXRecordDecl *Base)
Get the base index of the given base class within an APValue representing the given derived class.
static bool EvaluateFixedPoint(const Expr *E, APFixedPoint &Result, EvalInfo &Info)
Evaluate only a fixed point expression into an APResult.
void HandleComplexComplexMul(APFloat A, APFloat B, APFloat C, APFloat D, APFloat &ResR, APFloat &ResI)
static bool tryEvaluateBuiltinObjectSize(const Expr *E, unsigned Type, EvalInfo &Info, uint64_t &Size)
Tries to evaluate the __builtin_object_size for E. If successful, returns true and stores the result ...
static bool EvalPointerValueAsBool(const APValue &Value, bool &Result)
static bool handleVectorVectorBinOp(EvalInfo &Info, const BinaryOperator *E, BinaryOperatorKind Opcode, APValue &LHSValue, const APValue &RHSValue)
static const FunctionDecl * getVirtualOperatorDelete(QualType T)
static bool isDesignatorAtObjectEnd(const ASTContext &Ctx, const LValue &LVal)
Checks to see if the given LValue's Designator is at the end of the LValue's record layout....
static bool CheckArraySize(EvalInfo &Info, const ConstantArrayType *CAT, SourceLocation CallLoc={})
static bool EvaluateInPlace(APValue &Result, EvalInfo &Info, const LValue &This, const Expr *E, bool AllowNonLiteralTypes=false)
EvaluateInPlace - Evaluate an expression in-place in an APValue. In some cases, the in-place evaluati...
static bool handleFloatFloatBinOp(EvalInfo &Info, const BinaryOperator *E, APFloat &LHS, BinaryOperatorKind Opcode, const APFloat &RHS)
Perform the given binary floating-point operation, in-place, on LHS.
static std::optional< DynAlloc * > CheckDeleteKind(EvalInfo &Info, const Expr *E, const LValue &Pointer, DynAlloc::Kind DeallocKind)
Check that the given object is a suitable pointer to a heap allocation that still exists and is of th...
static bool EvaluateLValue(const Expr *E, LValue &Result, EvalInfo &Info, bool InvalidBaseOK=false)
Evaluate an expression as an lvalue. This can be legitimately called on expressions which are not glv...
static bool FastEvaluateAsRValue(const Expr *Exp, APValue &Result, const ASTContext &Ctx, bool &IsConst)
static bool HandleCovariantReturnAdjustment(EvalInfo &Info, const Expr *E, APValue &Result, ArrayRef< QualType > Path)
Perform the adjustment from a value returned by a virtual function to a value of the statically expec...
static EvalStmtResult EvaluateSwitch(StmtResult &Result, EvalInfo &Info, const SwitchStmt *SS)
Evaluate a switch statement.
static void expandStringLiteral(EvalInfo &Info, const StringLiteral *S, APValue &Result, QualType AllocType=QualType())
static bool EvaluateArgs(ArrayRef< const Expr * > Args, CallRef Call, EvalInfo &Info, const FunctionDecl *Callee, bool RightToLeft=false, LValue *ObjectArg=nullptr)
Evaluate the arguments to a function call.
static bool EvaluateAtomic(const Expr *E, const LValue *This, APValue &Result, EvalInfo &Info)
static bool getBytesReturnedByAllocSizeCall(const ASTContext &Ctx, const LValue &LVal, llvm::APInt &Result)
Convenience function. LVal's base must be a call to an alloc_size function.
static bool handleIntIntBinOp(EvalInfo &Info, const BinaryOperator *E, const APSInt &LHS, BinaryOperatorKind Opcode, APSInt RHS, APSInt &Result)
Perform the given binary integer operation.
static bool EvaluateInitForDeclOfReferenceType(EvalInfo &Info, const ValueDecl *D, const Expr *Init, LValue &Result, APValue &Val)
Evaluates the initializer of a reference.
static bool checkDynamicType(EvalInfo &Info, const Expr *E, const LValue &This, AccessKinds AK, bool Polymorphic)
Check that we can access the notional vptr of an object / determine its dynamic type.
static bool HandleFloatToIntCast(EvalInfo &Info, const Expr *E, QualType SrcType, const APFloat &Value, QualType DestType, APSInt &Result)
static bool getAlignmentArgument(const Expr *E, QualType ForType, EvalInfo &Info, APSInt &Alignment)
Evaluate the value of the alignment argument to __builtin_align_{up,down}, __builtin_is_aligned and _...
static bool CheckFullyInitialized(EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value)
Check that this evaluated value is fully-initialized and can be loaded by an lvalue-to-rvalue convers...
static SubobjectHandler::result_type findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, const SubobjectDesignator &Sub, SubobjectHandler &handler)
Find the designated sub-object of an rvalue.
static bool determineEndOffset(EvalInfo &Info, SourceLocation ExprLoc, unsigned Type, const LValue &LVal, CharUnits &EndOffset)
Helper for tryEvaluateBuiltinObjectSize – Given an LValue, this will determine how many bytes exist f...
static bool convertUnsignedAPIntToCharUnits(const llvm::APInt &Int, CharUnits &Result)
Converts the given APInt to CharUnits, assuming the APInt is unsigned. Fails if the conversion would ...
static bool EvaluateCallArg(const ParmVarDecl *PVD, const Expr *Arg, CallRef Call, EvalInfo &Info, bool NonNull=false, APValue **EvaluatedArg=nullptr)
llvm::SmallPtrSet< const MaterializeTemporaryExpr *, 8 > CheckedTemporaries
Materialized temporaries that we've already checked to determine if they're initializsed by a constan...
GCCTypeClass EvaluateBuiltinClassifyType(QualType T, const LangOptions &LangOpts)
EvaluateBuiltinClassifyType - Evaluate __builtin_classify_type the same way as GCC.
static bool EvaluateDependentExpr(const Expr *E, EvalInfo &Info)
static bool MaybeEvaluateDeferredVarDeclInit(EvalInfo &Info, const VarDecl *VD)
static APSInt HandleIntToIntCast(EvalInfo &Info, const Expr *E, QualType DestType, QualType SrcType, const APSInt &Value)
static std::optional< APValue > handleVectorUnaryOperator(ASTContext &Ctx, QualType ResultTy, UnaryOperatorKind Op, APValue Elt)
static bool lifetimeStartedInEvaluation(EvalInfo &Info, APValue::LValueBase Base, bool MutableSubobject=false)
static bool isOneByteCharacterType(QualType T)
static bool HandleLambdaCapture(EvalInfo &Info, const Expr *E, LValue &Result, const CXXMethodDecl *MD, const FieldDecl *FD, bool LValueToRValueConversion)
Get an lvalue to a field of a lambda's closure type.
static bool EvaluateCond(EvalInfo &Info, const VarDecl *CondDecl, const Expr *Cond, bool &Result)
Evaluate a condition (either a variable declaration or an expression).
static bool EvaluateAsFixedPoint(const Expr *E, Expr::EvalResult &ExprResult, const ASTContext &Ctx, Expr::SideEffectsKind AllowSideEffects, EvalInfo &Info)
static bool EvaluateAsRValue(EvalInfo &Info, const Expr *E, APValue &Result)
EvaluateAsRValue - Try to evaluate this expression, performing an implicit lvalue-to-rvalue cast if i...
static bool diagnoseMutableFields(EvalInfo &Info, const Expr *E, AccessKinds AK, QualType T)
Diagnose an attempt to read from any unreadable field within the specified type, which might be a cla...
static ICEDiag CheckICE(const Expr *E, const ASTContext &Ctx)
static bool CheckConstexprFunction(EvalInfo &Info, SourceLocation CallLoc, const FunctionDecl *Declaration, const FunctionDecl *Definition, const Stmt *Body)
CheckConstexprFunction - Check that a function can be called in a constant expression.
static bool EvaluateDestruction(const ASTContext &Ctx, APValue::LValueBase Base, APValue DestroyedValue, QualType Type, SourceLocation Loc, Expr::EvalStatus &EStatus, bool IsConstantDestruction)
static EvalStmtResult EvaluateStmt(StmtResult &Result, EvalInfo &Info, const Stmt *S, const SwitchCase *SC=nullptr)
static bool EvaluateArrayNewInitList(EvalInfo &Info, LValue &This, APValue &Result, const InitListExpr *ILE, QualType AllocType)
static bool HasSameBase(const LValue &A, const LValue &B)
static bool CheckLocalVariableDeclaration(EvalInfo &Info, const VarDecl *VD)
static bool HandleLValueDirectBase(EvalInfo &Info, const Expr *E, LValue &Obj, const CXXRecordDecl *Derived, const CXXRecordDecl *Base, const ASTRecordLayout *RL=nullptr)
static bool IsGlobalLValue(APValue::LValueBase B)
static llvm::RoundingMode getActiveRoundingMode(EvalInfo &Info, const Expr *E)
Get rounding mode to use in evaluation of the specified expression.
static QualType getObjectType(APValue::LValueBase B)
Retrieves the "underlying object type" of the given expression, as used by __builtin_object_size.
static bool handleCompareOpForVectorHelper(const APTy &LHSValue, BinaryOperatorKind Opcode, const APTy &RHSValue, APInt &Result)
static bool Evaluate(APValue &Result, EvalInfo &Info, const Expr *E)
static bool isReadByLvalueToRvalueConversion(const CXXRecordDecl *RD)
Determine whether a type would actually be read by an lvalue-to-rvalue conversion.
static void negateAsSigned(APSInt &Int)
Negate an APSInt in place, converting it to a signed form if necessary, and preserving its value (by ...
static bool HandleFunctionCall(SourceLocation CallLoc, const FunctionDecl *Callee, const LValue *ObjectArg, const Expr *E, ArrayRef< const Expr * > Args, CallRef Call, const Stmt *Body, EvalInfo &Info, APValue &Result, const LValue *ResultSlot)
Evaluate a function call.
static bool isUserWritingOffTheEnd(const ASTContext &Ctx, const LValue &LVal)
Attempts to detect a user writing into a piece of memory that's impossible to figure out the size of ...
static bool GetLValueBaseAsString(const EvalInfo &Info, const LValue &LVal, LValueBaseString &AsString)
static bool HandleOperatorDeleteCall(EvalInfo &Info, const CallExpr *E)
static bool EvaluateIntegerOrLValue(const Expr *E, APValue &Result, EvalInfo &Info)
EvaluateIntegerOrLValue - Evaluate an rvalue integral-typed expression, and produce either the intege...
static bool HandleDynamicCast(EvalInfo &Info, const ExplicitCastExpr *E, LValue &Ptr)
Apply the given dynamic cast operation on the provided lvalue.
static bool HandleOperatorNewCall(EvalInfo &Info, const CallExpr *E, LValue &Result)
Perform a call to 'operator new' or to ‘__builtin_operator_new’.
static bool HandleFloatToFloatCast(EvalInfo &Info, const Expr *E, QualType SrcType, QualType DestType, APFloat &Result)
static bool MaybeHandleUnionActiveMemberChange(EvalInfo &Info, const Expr *LHSExpr, const LValue &LHS)
Handle a builtin simple-assignment or a call to a trivial assignment operator whose left-hand side mi...
static bool isFormalAccess(AccessKinds AK)
Is this an access per the C++ definition?
static bool handleCompoundAssignment(EvalInfo &Info, const CompoundAssignOperator *E, const LValue &LVal, QualType LValType, QualType PromotedLValType, BinaryOperatorKind Opcode, const APValue &RVal)
Perform a compound assignment of LVal <op>= RVal.
static bool handleIncDec(EvalInfo &Info, const Expr *E, const LValue &LVal, QualType LValType, bool IsIncrement, APValue *Old)
Perform an increment or decrement on LVal.
static bool EvaluateVoid(const Expr *E, EvalInfo &Info)
static bool HandleDestruction(EvalInfo &Info, const Expr *E, const LValue &This, QualType ThisType)
Perform a destructor or pseudo-destructor call on the given object, which might in general not be a c...
static bool HandleDestructionImpl(EvalInfo &Info, SourceRange CallRange, const LValue &This, APValue &Value, QualType T)
static bool ArePotentiallyOverlappingStringLiterals(const EvalInfo &Info, const LValue &LHS, const LValue &RHS)
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
llvm::MachO::Record Record
Implements a partial diagnostic which may not be emitted.
llvm::DenseMap< Stmt *, Stmt * > MapTy
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
Expr * getExpr()
Get 'expr' part of the associated expression/statement.
static QualType getPointeeType(const MemRegion *R)
Enumerates target-specific builtins in their own namespaces within namespace clang.
Defines the clang::TypeLoc interface and its subclasses.
C Language Family Type Representation.
__DEVICE__ long long abs(long long __n)
a trap message and trap category.
llvm::APInt getValue() const
unsigned getVersion() const
QualType getDynamicAllocType() const
QualType getTypeInfoType() const
static LValueBase getTypeInfo(TypeInfoLValue LV, QualType TypeInfo)
static LValueBase getDynamicAlloc(DynamicAllocLValue LV, QualType Type)
A non-discriminated union of a base, field, or array index.
BaseOrMemberType getAsBaseOrMember() const
static LValuePathEntry ArrayIndex(uint64_t Index)
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
bool hasArrayFiller() const
const LValueBase getLValueBase() const
APValue & getArrayInitializedElt(unsigned I)
void swap(APValue &RHS)
Swaps the contents of this and the given APValue.
APValue & getStructField(unsigned i)
const FieldDecl * getUnionField() const
APSInt & getComplexIntImag()
bool isComplexInt() const
llvm::PointerIntPair< const Decl *, 1, bool > BaseOrMemberType
A FieldDecl or CXXRecordDecl, along with a flag indicating whether we mean a virtual or non-virtual b...
ValueKind getKind() const
unsigned getArrayInitializedElts() const
static APValue IndeterminateValue()
APFixedPoint & getFixedPoint()
bool hasLValuePath() const
const ValueDecl * getMemberPointerDecl() const
APValue & getUnionValue()
CharUnits & getLValueOffset()
void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const
bool isComplexFloat() const
APValue & getVectorElt(unsigned I)
APValue & getArrayFiller()
unsigned getVectorLength() const
void setUnion(const FieldDecl *Field, const APValue &Value)
bool isIndeterminate() const
unsigned getArraySize() const
bool allowConstexprUnknown() const
std::string getAsString(const ASTContext &Ctx, QualType Ty) const
bool isFixedPoint() const
@ Indeterminate
This object has an indeterminate value (C++ [basic.indet]).
@ None
There is no such object (it's outside its lifetime).
APSInt & getComplexIntReal()
APFloat & getComplexFloatImag()
APFloat & getComplexFloatReal()
APValue & getStructBase(unsigned i)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
SourceManager & getSourceManager()
const ConstantArrayType * getAsConstantArrayType(QualType T) const
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
unsigned getIntWidth(QualType T) const
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
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,...
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
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
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
llvm::APSInt MakeIntValue(uint64_t Value, QualType Type) const
Make an APSInt of the appropriate width and signedness for the given Value and integer Type.
const VariableArrayType * getAsVariableArrayType(QualType T) const
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
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 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 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.
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)