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;
11578bool VectorExprEvaluator::VisitCallExpr(
const CallExpr *E) {
11579 if (!IsConstantEvaluatedBuiltinCall(E))
11580 return ExprEvaluatorBaseTy::VisitCallExpr(E);
11582 auto EvaluateBinOpExpr =
11584 APValue SourceLHS, SourceRHS;
11590 QualType DestEltTy = DestTy->getElementType();
11591 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
11594 ResultElements.reserve(SourceLen);
11596 if (SourceRHS.
isInt()) {
11598 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11600 ResultElements.push_back(
11604 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11607 ResultElements.push_back(
11617 case Builtin::BI__builtin_elementwise_popcount:
11618 case Builtin::BI__builtin_elementwise_bitreverse: {
11623 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
11626 ResultElements.reserve(SourceLen);
11628 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11631 case Builtin::BI__builtin_elementwise_popcount:
11632 ResultElements.push_back(
APValue(
11636 case Builtin::BI__builtin_elementwise_bitreverse:
11637 ResultElements.push_back(
11644 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
11646 case Builtin::BI__builtin_elementwise_abs: {
11651 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
11654 ResultElements.reserve(SourceLen);
11656 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11661 CurrentEle.getInt().
abs(),
11662 DestEltTy->isUnsignedIntegerOrEnumerationType()));
11663 ResultElements.push_back(Val);
11666 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
11669 case Builtin::BI__builtin_elementwise_add_sat:
11670 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
11671 return LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS);
11674 case Builtin::BI__builtin_elementwise_sub_sat:
11675 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
11676 return LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
11679 case clang::X86::BI__builtin_ia32_pavgb128:
11680 case clang::X86::BI__builtin_ia32_pavgw128:
11681 case clang::X86::BI__builtin_ia32_pavgb256:
11682 case clang::X86::BI__builtin_ia32_pavgw256:
11683 case clang::X86::BI__builtin_ia32_pavgb512:
11684 case clang::X86::BI__builtin_ia32_pavgw512:
11685 return EvaluateBinOpExpr(llvm::APIntOps::avgCeilU);
11687 case clang::X86::BI__builtin_ia32_pmulhuw128:
11688 case clang::X86::BI__builtin_ia32_pmulhuw256:
11689 case clang::X86::BI__builtin_ia32_pmulhuw512:
11690 return EvaluateBinOpExpr(llvm::APIntOps::mulhu);
11692 case clang::X86::BI__builtin_ia32_pmulhw128:
11693 case clang::X86::BI__builtin_ia32_pmulhw256:
11694 case clang::X86::BI__builtin_ia32_pmulhw512:
11695 return EvaluateBinOpExpr(llvm::APIntOps::mulhs);
11697 case clang::X86::BI__builtin_ia32_psllv2di:
11698 case clang::X86::BI__builtin_ia32_psllv4di:
11699 case clang::X86::BI__builtin_ia32_psllv4si:
11700 case clang::X86::BI__builtin_ia32_psllv8di:
11701 case clang::X86::BI__builtin_ia32_psllv8hi:
11702 case clang::X86::BI__builtin_ia32_psllv8si:
11703 case clang::X86::BI__builtin_ia32_psllv16hi:
11704 case clang::X86::BI__builtin_ia32_psllv16si:
11705 case clang::X86::BI__builtin_ia32_psllv32hi:
11706 case clang::X86::BI__builtin_ia32_psllwi128:
11707 case clang::X86::BI__builtin_ia32_pslldi128:
11708 case clang::X86::BI__builtin_ia32_psllqi128:
11709 case clang::X86::BI__builtin_ia32_psllwi256:
11710 case clang::X86::BI__builtin_ia32_pslldi256:
11711 case clang::X86::BI__builtin_ia32_psllqi256:
11712 case clang::X86::BI__builtin_ia32_psllwi512:
11713 case clang::X86::BI__builtin_ia32_pslldi512:
11714 case clang::X86::BI__builtin_ia32_psllqi512:
11715 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
11716 if (RHS.uge(LHS.getBitWidth())) {
11717 return APInt::getZero(LHS.getBitWidth());
11719 return LHS.shl(RHS.getZExtValue());
11722 case clang::X86::BI__builtin_ia32_psrav4si:
11723 case clang::X86::BI__builtin_ia32_psrav8di:
11724 case clang::X86::BI__builtin_ia32_psrav8hi:
11725 case clang::X86::BI__builtin_ia32_psrav8si:
11726 case clang::X86::BI__builtin_ia32_psrav16hi:
11727 case clang::X86::BI__builtin_ia32_psrav16si:
11728 case clang::X86::BI__builtin_ia32_psrav32hi:
11729 case clang::X86::BI__builtin_ia32_psravq128:
11730 case clang::X86::BI__builtin_ia32_psravq256:
11731 case clang::X86::BI__builtin_ia32_psrawi128:
11732 case clang::X86::BI__builtin_ia32_psradi128:
11733 case clang::X86::BI__builtin_ia32_psraqi128:
11734 case clang::X86::BI__builtin_ia32_psrawi256:
11735 case clang::X86::BI__builtin_ia32_psradi256:
11736 case clang::X86::BI__builtin_ia32_psraqi256:
11737 case clang::X86::BI__builtin_ia32_psrawi512:
11738 case clang::X86::BI__builtin_ia32_psradi512:
11739 case clang::X86::BI__builtin_ia32_psraqi512:
11740 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
11741 if (RHS.uge(LHS.getBitWidth())) {
11742 return LHS.ashr(LHS.getBitWidth() - 1);
11744 return LHS.ashr(RHS.getZExtValue());
11747 case clang::X86::BI__builtin_ia32_psrlv2di:
11748 case clang::X86::BI__builtin_ia32_psrlv4di:
11749 case clang::X86::BI__builtin_ia32_psrlv4si:
11750 case clang::X86::BI__builtin_ia32_psrlv8di:
11751 case clang::X86::BI__builtin_ia32_psrlv8hi:
11752 case clang::X86::BI__builtin_ia32_psrlv8si:
11753 case clang::X86::BI__builtin_ia32_psrlv16hi:
11754 case clang::X86::BI__builtin_ia32_psrlv16si:
11755 case clang::X86::BI__builtin_ia32_psrlv32hi:
11756 case clang::X86::BI__builtin_ia32_psrlwi128:
11757 case clang::X86::BI__builtin_ia32_psrldi128:
11758 case clang::X86::BI__builtin_ia32_psrlqi128:
11759 case clang::X86::BI__builtin_ia32_psrlwi256:
11760 case clang::X86::BI__builtin_ia32_psrldi256:
11761 case clang::X86::BI__builtin_ia32_psrlqi256:
11762 case clang::X86::BI__builtin_ia32_psrlwi512:
11763 case clang::X86::BI__builtin_ia32_psrldi512:
11764 case clang::X86::BI__builtin_ia32_psrlqi512:
11765 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
11766 if (RHS.uge(LHS.getBitWidth())) {
11767 return APInt::getZero(LHS.getBitWidth());
11769 return LHS.lshr(RHS.getZExtValue());
11772 case clang::X86::BI__builtin_ia32_pmuldq128:
11773 case clang::X86::BI__builtin_ia32_pmuldq256:
11774 case clang::X86::BI__builtin_ia32_pmuldq512:
11775 case clang::X86::BI__builtin_ia32_pmuludq128:
11776 case clang::X86::BI__builtin_ia32_pmuludq256:
11777 case clang::X86::BI__builtin_ia32_pmuludq512: {
11778 APValue SourceLHS, SourceRHS;
11785 ResultElements.reserve(SourceLen / 2);
11787 for (
unsigned EltNum = 0; EltNum < SourceLen; EltNum += 2) {
11792 case clang::X86::BI__builtin_ia32_pmuludq128:
11793 case clang::X86::BI__builtin_ia32_pmuludq256:
11794 case clang::X86::BI__builtin_ia32_pmuludq512:
11795 ResultElements.push_back(
11796 APValue(
APSInt(llvm::APIntOps::muluExtended(LHS, RHS),
true)));
11798 case clang::X86::BI__builtin_ia32_pmuldq128:
11799 case clang::X86::BI__builtin_ia32_pmuldq256:
11800 case clang::X86::BI__builtin_ia32_pmuldq512:
11801 ResultElements.push_back(
11802 APValue(
APSInt(llvm::APIntOps::mulsExtended(LHS, RHS),
false)));
11807 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
11810 case clang::X86::BI__builtin_ia32_vprotbi:
11811 case clang::X86::BI__builtin_ia32_vprotdi:
11812 case clang::X86::BI__builtin_ia32_vprotqi:
11813 case clang::X86::BI__builtin_ia32_vprotwi:
11814 case clang::X86::BI__builtin_ia32_prold128:
11815 case clang::X86::BI__builtin_ia32_prold256:
11816 case clang::X86::BI__builtin_ia32_prold512:
11817 case clang::X86::BI__builtin_ia32_prolq128:
11818 case clang::X86::BI__builtin_ia32_prolq256:
11819 case clang::X86::BI__builtin_ia32_prolq512:
11820 return EvaluateBinOpExpr(
11821 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS.rotl(RHS); });
11823 case clang::X86::BI__builtin_ia32_prord128:
11824 case clang::X86::BI__builtin_ia32_prord256:
11825 case clang::X86::BI__builtin_ia32_prord512:
11826 case clang::X86::BI__builtin_ia32_prorq128:
11827 case clang::X86::BI__builtin_ia32_prorq256:
11828 case clang::X86::BI__builtin_ia32_prorq512:
11829 return EvaluateBinOpExpr(
11830 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS.rotr(RHS); });
11832 case Builtin::BI__builtin_elementwise_max:
11833 case Builtin::BI__builtin_elementwise_min: {
11834 APValue SourceLHS, SourceRHS;
11839 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
11846 ResultElements.reserve(SourceLen);
11848 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11852 case Builtin::BI__builtin_elementwise_max:
11853 ResultElements.push_back(
11857 case Builtin::BI__builtin_elementwise_min:
11858 ResultElements.push_back(
11865 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
11867 case X86::BI__builtin_ia32_vpshldd128:
11868 case X86::BI__builtin_ia32_vpshldd256:
11869 case X86::BI__builtin_ia32_vpshldd512:
11870 case X86::BI__builtin_ia32_vpshldq128:
11871 case X86::BI__builtin_ia32_vpshldq256:
11872 case X86::BI__builtin_ia32_vpshldq512:
11873 case X86::BI__builtin_ia32_vpshldw128:
11874 case X86::BI__builtin_ia32_vpshldw256:
11875 case X86::BI__builtin_ia32_vpshldw512: {
11876 APValue SourceHi, SourceLo, SourceAmt;
11882 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
11885 ResultElements.reserve(SourceLen);
11888 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11891 APInt R = llvm::APIntOps::fshl(Hi, Lo, Amt);
11892 ResultElements.push_back(
11896 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
11898 case X86::BI__builtin_ia32_vpshrdd128:
11899 case X86::BI__builtin_ia32_vpshrdd256:
11900 case X86::BI__builtin_ia32_vpshrdd512:
11901 case X86::BI__builtin_ia32_vpshrdq128:
11902 case X86::BI__builtin_ia32_vpshrdq256:
11903 case X86::BI__builtin_ia32_vpshrdq512:
11904 case X86::BI__builtin_ia32_vpshrdw128:
11905 case X86::BI__builtin_ia32_vpshrdw256:
11906 case X86::BI__builtin_ia32_vpshrdw512: {
11908 APValue SourceHi, SourceLo, SourceAmt;
11914 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
11917 ResultElements.reserve(SourceLen);
11920 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11923 APInt R = llvm::APIntOps::fshr(Hi, Lo, Amt);
11924 ResultElements.push_back(
11928 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
11930 case X86::BI__builtin_ia32_blendpd:
11931 case X86::BI__builtin_ia32_blendpd256:
11932 case X86::BI__builtin_ia32_blendps:
11933 case X86::BI__builtin_ia32_blendps256:
11934 case X86::BI__builtin_ia32_pblendw128:
11935 case X86::BI__builtin_ia32_pblendw256:
11936 case X86::BI__builtin_ia32_pblendd128:
11937 case X86::BI__builtin_ia32_pblendd256: {
11938 APValue SourceF, SourceT, SourceC;
11947 ResultElements.reserve(SourceLen);
11948 for (
unsigned EltNum = 0; EltNum != SourceLen; ++EltNum) {
11951 ResultElements.push_back(
C[EltNum % 8] ?
T : F);
11954 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
11957 case X86::BI__builtin_ia32_blendvpd:
11958 case X86::BI__builtin_ia32_blendvpd256:
11959 case X86::BI__builtin_ia32_blendvps:
11960 case X86::BI__builtin_ia32_blendvps256:
11961 case X86::BI__builtin_ia32_pblendvb128:
11962 case X86::BI__builtin_ia32_pblendvb256: {
11964 APValue SourceF, SourceT, SourceC;
11972 ResultElements.reserve(SourceLen);
11974 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11978 APInt M =
C.isInt() ? (
APInt)
C.getInt() :
C.getFloat().bitcastToAPInt();
11979 ResultElements.push_back(M.isNegative() ?
T : F);
11982 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
11984 case X86::BI__builtin_ia32_selectb_128:
11985 case X86::BI__builtin_ia32_selectb_256:
11986 case X86::BI__builtin_ia32_selectb_512:
11987 case X86::BI__builtin_ia32_selectw_128:
11988 case X86::BI__builtin_ia32_selectw_256:
11989 case X86::BI__builtin_ia32_selectw_512:
11990 case X86::BI__builtin_ia32_selectd_128:
11991 case X86::BI__builtin_ia32_selectd_256:
11992 case X86::BI__builtin_ia32_selectd_512:
11993 case X86::BI__builtin_ia32_selectq_128:
11994 case X86::BI__builtin_ia32_selectq_256:
11995 case X86::BI__builtin_ia32_selectq_512:
11996 case X86::BI__builtin_ia32_selectph_128:
11997 case X86::BI__builtin_ia32_selectph_256:
11998 case X86::BI__builtin_ia32_selectph_512:
11999 case X86::BI__builtin_ia32_selectpbf_128:
12000 case X86::BI__builtin_ia32_selectpbf_256:
12001 case X86::BI__builtin_ia32_selectpbf_512:
12002 case X86::BI__builtin_ia32_selectps_128:
12003 case X86::BI__builtin_ia32_selectps_256:
12004 case X86::BI__builtin_ia32_selectps_512:
12005 case X86::BI__builtin_ia32_selectpd_128:
12006 case X86::BI__builtin_ia32_selectpd_256:
12007 case X86::BI__builtin_ia32_selectpd_512: {
12009 APValue SourceMask, SourceLHS, SourceRHS;
12018 ResultElements.reserve(SourceLen);
12020 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12023 ResultElements.push_back(Mask[EltNum] ? LHS : RHS);
12026 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12028 case Builtin::BI__builtin_elementwise_clzg:
12029 case Builtin::BI__builtin_elementwise_ctzg: {
12031 std::optional<APValue> Fallback;
12038 Fallback = FallbackTmp;
12041 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12044 ResultElements.reserve(SourceLen);
12046 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12051 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
12053 Builtin::BI__builtin_elementwise_ctzg);
12056 ResultElements.push_back(Fallback->getVectorElt(EltNum));
12060 case Builtin::BI__builtin_elementwise_clzg:
12061 ResultElements.push_back(
APValue(
12065 case Builtin::BI__builtin_elementwise_ctzg:
12066 ResultElements.push_back(
APValue(
12073 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12076 case Builtin::BI__builtin_elementwise_fma: {
12077 APValue SourceX, SourceY, SourceZ;
12085 ResultElements.reserve(SourceLen);
12087 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12092 (void)
Result.fusedMultiplyAdd(Y, Z, RM);
12095 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12098 case Builtin::BI__builtin_elementwise_fshl:
12099 case Builtin::BI__builtin_elementwise_fshr: {
12100 APValue SourceHi, SourceLo, SourceShift;
12106 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12112 ResultElements.reserve(SourceLen);
12113 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12118 case Builtin::BI__builtin_elementwise_fshl:
12119 ResultElements.push_back(
APValue(
12120 APSInt(llvm::APIntOps::fshl(Hi, Lo, Shift), Hi.isUnsigned())));
12122 case Builtin::BI__builtin_elementwise_fshr:
12123 ResultElements.push_back(
APValue(
12124 APSInt(llvm::APIntOps::fshr(Hi, Lo, Shift), Hi.isUnsigned())));
12129 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12132 case X86::BI__builtin_ia32_insertf32x4_256:
12133 case X86::BI__builtin_ia32_inserti32x4_256:
12134 case X86::BI__builtin_ia32_insertf64x2_256:
12135 case X86::BI__builtin_ia32_inserti64x2_256:
12136 case X86::BI__builtin_ia32_insertf32x4:
12137 case X86::BI__builtin_ia32_inserti32x4:
12138 case X86::BI__builtin_ia32_insertf64x2_512:
12139 case X86::BI__builtin_ia32_inserti64x2_512:
12140 case X86::BI__builtin_ia32_insertf32x8:
12141 case X86::BI__builtin_ia32_inserti32x8:
12142 case X86::BI__builtin_ia32_insertf64x4:
12143 case X86::BI__builtin_ia32_inserti64x4:
12144 case X86::BI__builtin_ia32_vinsertf128_ps256:
12145 case X86::BI__builtin_ia32_vinsertf128_pd256:
12146 case X86::BI__builtin_ia32_vinsertf128_si256:
12147 case X86::BI__builtin_ia32_insert128i256: {
12148 APValue SourceDst, SourceSub;
12160 assert(SubLen != 0 && DstLen != 0 && (DstLen % SubLen) == 0);
12161 unsigned NumLanes = DstLen / SubLen;
12162 unsigned LaneIdx = (Imm.getZExtValue() % NumLanes) * SubLen;
12165 ResultElements.reserve(DstLen);
12167 for (
unsigned EltNum = 0; EltNum < DstLen; ++EltNum) {
12168 if (EltNum >= LaneIdx && EltNum < LaneIdx + SubLen)
12169 ResultElements.push_back(SourceSub.
getVectorElt(EltNum - LaneIdx));
12171 ResultElements.push_back(SourceDst.
getVectorElt(EltNum));
12174 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12179bool VectorExprEvaluator::VisitConvertVectorExpr(
const ConvertVectorExpr *E) {
12185 QualType DestTy = E->
getType()->
castAs<VectorType>()->getElementType();
12186 QualType SourceTy = SourceVecType->
castAs<VectorType>()->getElementType();
12192 ResultElements.reserve(SourceLen);
12193 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12198 ResultElements.push_back(std::move(Elt));
12201 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12206 APValue const &VecVal2,
unsigned EltNum,
12208 unsigned const TotalElementsInInputVector1 = VecVal1.
getVectorLength();
12209 unsigned const TotalElementsInInputVector2 = VecVal2.
getVectorLength();
12212 int64_t
index = IndexVal.getExtValue();
12219 E, diag::err_shufflevector_minus_one_is_undefined_behavior_constexpr)
12225 index >= TotalElementsInInputVector1 + TotalElementsInInputVector2)
12226 llvm_unreachable(
"Out of bounds shuffle index");
12228 if (
index >= TotalElementsInInputVector1)
12235bool VectorExprEvaluator::VisitShuffleVectorExpr(
const ShuffleVectorExpr *E) {
12240 const Expr *Vec1 = E->
getExpr(0);
12244 const Expr *Vec2 = E->
getExpr(1);
12248 VectorType
const *DestVecTy = E->
getType()->
castAs<VectorType>();
12254 ResultElements.reserve(TotalElementsInOutputVector);
12255 for (
unsigned EltNum = 0; EltNum < TotalElementsInOutputVector; ++EltNum) {
12259 ResultElements.push_back(std::move(Elt));
12262 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12270 class ArrayExprEvaluator
12271 :
public ExprEvaluatorBase<ArrayExprEvaluator> {
12272 const LValue &
This;
12276 ArrayExprEvaluator(EvalInfo &Info,
const LValue &This,
APValue &
Result)
12280 assert(
V.isArray() &&
"expected array");
12285 bool ZeroInitialization(
const Expr *E) {
12286 const ConstantArrayType *CAT =
12301 if (!
Result.hasArrayFiller())
12305 LValue Subobject =
This;
12306 Subobject.addArray(Info, E, CAT);
12311 bool VisitCallExpr(
const CallExpr *E) {
12312 return handleCallExpr(E,
Result, &This);
12314 bool VisitInitListExpr(
const InitListExpr *E,
12315 QualType AllocType = QualType());
12316 bool VisitArrayInitLoopExpr(
const ArrayInitLoopExpr *E);
12317 bool VisitCXXConstructExpr(
const CXXConstructExpr *E);
12318 bool VisitCXXConstructExpr(
const CXXConstructExpr *E,
12319 const LValue &Subobject,
12321 bool VisitStringLiteral(
const StringLiteral *E,
12322 QualType AllocType = QualType()) {
12326 bool VisitCXXParenListInitExpr(
const CXXParenListInitExpr *E);
12327 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
12328 ArrayRef<Expr *> Args,
12329 const Expr *ArrayFiller,
12330 QualType AllocType = QualType());
12335 APValue &Result, EvalInfo &Info) {
12338 "not an array prvalue");
12339 return ArrayExprEvaluator(Info,
This, Result).Visit(E);
12347 "not an array prvalue");
12348 return ArrayExprEvaluator(Info,
This, Result)
12349 .VisitInitListExpr(ILE, AllocType);
12358 "not an array prvalue");
12359 return ArrayExprEvaluator(Info,
This, Result)
12360 .VisitCXXConstructExpr(CCE,
This, &Result, AllocType);
12369 if (
const InitListExpr *ILE = dyn_cast<InitListExpr>(FillerExpr)) {
12370 for (
unsigned I = 0, E = ILE->
getNumInits(); I != E; ++I) {
12375 if (ILE->hasArrayFiller() &&
12384bool ArrayExprEvaluator::VisitInitListExpr(
const InitListExpr *E,
12385 QualType AllocType) {
12399 return VisitStringLiteral(SL, AllocType);
12404 "transparent array list initialization is not string literal init?");
12410bool ArrayExprEvaluator::VisitCXXParenListOrInitListExpr(
12412 QualType AllocType) {
12418 assert((!
Result.isArray() ||
Result.getArrayInitializedElts() == 0) &&
12419 "zero-initialized array shouldn't have any initialized elts");
12424 unsigned NumEltsToInit = Args.size();
12429 if (NumEltsToInit != NumElts &&
12431 NumEltsToInit = NumElts;
12433 for (
auto *
Init : Args) {
12434 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts()))
12435 NumEltsToInit += EmbedS->getDataElementCount() - 1;
12437 if (NumEltsToInit > NumElts)
12438 NumEltsToInit = NumElts;
12441 LLVM_DEBUG(llvm::dbgs() <<
"The number of elements to initialize: "
12442 << NumEltsToInit <<
".\n");
12444 Result =
APValue(APValue::UninitArray(), NumEltsToInit, NumElts);
12449 for (
unsigned I = 0, E =
Result.getArrayInitializedElts(); I != E; ++I)
12450 Result.getArrayInitializedElt(I) = Filler;
12451 if (
Result.hasArrayFiller())
12455 LValue Subobject =
This;
12456 Subobject.addArray(Info, ExprToVisit, CAT);
12457 auto Eval = [&](
const Expr *
Init,
unsigned ArrayIndex) {
12458 if (
Init->isValueDependent())
12462 Subobject,
Init) ||
12465 if (!Info.noteFailure())
12471 unsigned ArrayIndex = 0;
12474 for (
unsigned Index = 0; Index != NumEltsToInit; ++Index) {
12475 const Expr *
Init = Index < Args.size() ? Args[Index] : ArrayFiller;
12476 if (ArrayIndex >= NumEltsToInit)
12478 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
12479 StringLiteral *SL = EmbedS->getDataStringLiteral();
12480 for (
unsigned I = EmbedS->getStartingElementPos(),
12481 N = EmbedS->getDataElementCount();
12482 I != EmbedS->getStartingElementPos() + N; ++I) {
12488 const FPOptions FPO =
12494 Result.getArrayInitializedElt(ArrayIndex) =
APValue(FValue);
12499 if (!Eval(
Init, ArrayIndex))
12505 if (!
Result.hasArrayFiller())
12510 assert(ArrayFiller &&
"no array filler for incomplete init list");
12516bool ArrayExprEvaluator::VisitArrayInitLoopExpr(
const ArrayInitLoopExpr *E) {
12519 !
Evaluate(Info.CurrentCall->createTemporary(
12522 ScopeKind::FullExpression, CommonLV),
12529 Result =
APValue(APValue::UninitArray(), Elements, Elements);
12531 LValue Subobject =
This;
12532 Subobject.addArray(Info, E, CAT);
12535 for (EvalInfo::ArrayInitLoopIndex Index(Info); Index != Elements; ++Index) {
12544 FullExpressionRAII Scope(Info);
12550 if (!Info.noteFailure())
12562bool ArrayExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E) {
12563 return VisitCXXConstructExpr(E, This, &
Result, E->
getType());
12566bool ArrayExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E,
12567 const LValue &Subobject,
12570 bool HadZeroInit =
Value->hasValue();
12577 HadZeroInit &&
Value->hasArrayFiller() ?
Value->getArrayFiller()
12580 *
Value =
APValue(APValue::UninitArray(), 0, FinalSize);
12581 if (FinalSize == 0)
12587 LValue ArrayElt = Subobject;
12588 ArrayElt.addArray(Info, E, CAT);
12594 for (
const unsigned N : {1u, FinalSize}) {
12595 unsigned OldElts =
Value->getArrayInitializedElts();
12600 APValue NewValue(APValue::UninitArray(), N, FinalSize);
12601 for (
unsigned I = 0; I < OldElts; ++I)
12602 NewValue.getArrayInitializedElt(I).swap(
12603 Value->getArrayInitializedElt(I));
12604 Value->swap(NewValue);
12607 for (
unsigned I = OldElts; I < N; ++I)
12608 Value->getArrayInitializedElt(I) = Filler;
12610 if (HasTrivialConstructor && N == FinalSize && FinalSize != 1) {
12613 APValue &FirstResult =
Value->getArrayInitializedElt(0);
12614 for (
unsigned I = OldElts; I < FinalSize; ++I)
12615 Value->getArrayInitializedElt(I) = FirstResult;
12617 for (
unsigned I = OldElts; I < N; ++I) {
12618 if (!VisitCXXConstructExpr(E, ArrayElt,
12619 &
Value->getArrayInitializedElt(I),
12626 if (Info.EvalStatus.
Diag && !Info.EvalStatus.
Diag->empty() &&
12627 !Info.keepEvaluatingAfterFailure())
12636 if (!
Type->isRecordType())
12639 return RecordExprEvaluator(Info, Subobject, *
Value)
12640 .VisitCXXConstructExpr(E,
Type);
12643bool ArrayExprEvaluator::VisitCXXParenListInitExpr(
12644 const CXXParenListInitExpr *E) {
12646 "Expression result is not a constant array type");
12648 return VisitCXXParenListOrInitListExpr(E, E->
getInitExprs(),
12661class IntExprEvaluator
12662 :
public ExprEvaluatorBase<IntExprEvaluator> {
12665 IntExprEvaluator(EvalInfo &info,
APValue &result)
12666 : ExprEvaluatorBaseTy(info),
Result(result) {}
12670 "Invalid evaluation result.");
12672 "Invalid evaluation result.");
12674 "Invalid evaluation result.");
12678 bool Success(
const llvm::APSInt &SI,
const Expr *E) {
12684 "Invalid evaluation result.");
12686 "Invalid evaluation result.");
12688 Result.getInt().setIsUnsigned(
12692 bool Success(
const llvm::APInt &I,
const Expr *E) {
12698 "Invalid evaluation result.");
12706 bool Success(CharUnits Size,
const Expr *E) {
12713 if (
V.isLValue() ||
V.isAddrLabelDiff() ||
V.isIndeterminate() ||
12714 V.allowConstexprUnknown()) {
12721 bool ZeroInitialization(
const Expr *E) {
return Success(0, E); }
12723 friend std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &,
12730 bool VisitIntegerLiteral(
const IntegerLiteral *E) {
12733 bool VisitCharacterLiteral(
const CharacterLiteral *E) {
12737 bool CheckReferencedDecl(
const Expr *E,
const Decl *D);
12738 bool VisitDeclRefExpr(
const DeclRefExpr *E) {
12739 if (CheckReferencedDecl(E, E->
getDecl()))
12742 return ExprEvaluatorBaseTy::VisitDeclRefExpr(E);
12744 bool VisitMemberExpr(
const MemberExpr *E) {
12746 VisitIgnoredBaseExpression(E->
getBase());
12750 return ExprEvaluatorBaseTy::VisitMemberExpr(E);
12753 bool VisitCallExpr(
const CallExpr *E);
12754 bool VisitBuiltinCallExpr(
const CallExpr *E,
unsigned BuiltinOp);
12755 bool VisitBinaryOperator(
const BinaryOperator *E);
12756 bool VisitOffsetOfExpr(
const OffsetOfExpr *E);
12757 bool VisitUnaryOperator(
const UnaryOperator *E);
12759 bool VisitCastExpr(
const CastExpr* E);
12760 bool VisitUnaryExprOrTypeTraitExpr(
const UnaryExprOrTypeTraitExpr *E);
12762 bool VisitCXXBoolLiteralExpr(
const CXXBoolLiteralExpr *E) {
12766 bool VisitObjCBoolLiteralExpr(
const ObjCBoolLiteralExpr *E) {
12770 bool VisitArrayInitIndexExpr(
const ArrayInitIndexExpr *E) {
12771 if (Info.ArrayInitIndex ==
uint64_t(-1)) {
12777 return Success(Info.ArrayInitIndex, E);
12781 bool VisitGNUNullExpr(
const GNUNullExpr *E) {
12782 return ZeroInitialization(E);
12785 bool VisitTypeTraitExpr(
const TypeTraitExpr *E) {
12794 bool VisitArrayTypeTraitExpr(
const ArrayTypeTraitExpr *E) {
12798 bool VisitExpressionTraitExpr(
const ExpressionTraitExpr *E) {
12802 bool VisitOpenACCAsteriskSizeExpr(
const OpenACCAsteriskSizeExpr *E) {
12809 bool VisitUnaryReal(
const UnaryOperator *E);
12810 bool VisitUnaryImag(
const UnaryOperator *E);
12812 bool VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E);
12813 bool VisitSizeOfPackExpr(
const SizeOfPackExpr *E);
12814 bool VisitSourceLocExpr(
const SourceLocExpr *E);
12815 bool VisitConceptSpecializationExpr(
const ConceptSpecializationExpr *E);
12820class FixedPointExprEvaluator
12821 :
public ExprEvaluatorBase<FixedPointExprEvaluator> {
12825 FixedPointExprEvaluator(EvalInfo &info,
APValue &result)
12826 : ExprEvaluatorBaseTy(info),
Result(result) {}
12828 bool Success(
const llvm::APInt &I,
const Expr *E) {
12839 return Success(
V.getFixedPoint(), E);
12842 bool Success(
const APFixedPoint &
V,
const Expr *E) {
12845 "Invalid evaluation result.");
12850 bool ZeroInitialization(
const Expr *E) {
12858 bool VisitFixedPointLiteral(
const FixedPointLiteral *E) {
12862 bool VisitCastExpr(
const CastExpr *E);
12863 bool VisitUnaryOperator(
const UnaryOperator *E);
12864 bool VisitBinaryOperator(
const BinaryOperator *E);
12880 return IntExprEvaluator(Info, Result).Visit(E);
12888 if (!Val.
isInt()) {
12891 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
12898bool IntExprEvaluator::VisitSourceLocExpr(
const SourceLocExpr *E) {
12900 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.
getDefaultExpr());
12909 if (!FixedPointExprEvaluator(Info, Val).Visit(E))
12928 Result = APFixedPoint(Val, FXSema);
12939bool IntExprEvaluator::CheckReferencedDecl(
const Expr* E,
const Decl* D) {
12941 if (
const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(D)) {
12943 bool SameSign = (ECD->getInitVal().isSigned()
12945 bool SameWidth = (ECD->getInitVal().getBitWidth()
12947 if (SameSign && SameWidth)
12948 return Success(ECD->getInitVal(), E);
12952 llvm::APSInt Val = ECD->getInitVal();
12954 Val.setIsSigned(!ECD->getInitVal().isSigned());
12967 assert(!
T->isDependentType() &&
"unexpected dependent type");
12972#define TYPE(ID, BASE)
12973#define DEPENDENT_TYPE(ID, BASE) case Type::ID:
12974#define NON_CANONICAL_TYPE(ID, BASE) case Type::ID:
12975#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(ID, BASE) case Type::ID:
12976#include "clang/AST/TypeNodes.inc"
12978 case Type::DeducedTemplateSpecialization:
12979 llvm_unreachable(
"unexpected non-canonical or dependent type");
12981 case Type::Builtin:
12983#define BUILTIN_TYPE(ID, SINGLETON_ID)
12984#define SIGNED_TYPE(ID, SINGLETON_ID) \
12985 case BuiltinType::ID: return GCCTypeClass::Integer;
12986#define FLOATING_TYPE(ID, SINGLETON_ID) \
12987 case BuiltinType::ID: return GCCTypeClass::RealFloat;
12988#define PLACEHOLDER_TYPE(ID, SINGLETON_ID) \
12989 case BuiltinType::ID: break;
12990#include "clang/AST/BuiltinTypes.def"
12991 case BuiltinType::Void:
12994 case BuiltinType::Bool:
12997 case BuiltinType::Char_U:
12998 case BuiltinType::UChar:
12999 case BuiltinType::WChar_U:
13000 case BuiltinType::Char8:
13001 case BuiltinType::Char16:
13002 case BuiltinType::Char32:
13003 case BuiltinType::UShort:
13004 case BuiltinType::UInt:
13005 case BuiltinType::ULong:
13006 case BuiltinType::ULongLong:
13007 case BuiltinType::UInt128:
13010 case BuiltinType::UShortAccum:
13011 case BuiltinType::UAccum:
13012 case BuiltinType::ULongAccum:
13013 case BuiltinType::UShortFract:
13014 case BuiltinType::UFract:
13015 case BuiltinType::ULongFract:
13016 case BuiltinType::SatUShortAccum:
13017 case BuiltinType::SatUAccum:
13018 case BuiltinType::SatULongAccum:
13019 case BuiltinType::SatUShortFract:
13020 case BuiltinType::SatUFract:
13021 case BuiltinType::SatULongFract:
13024 case BuiltinType::NullPtr:
13026 case BuiltinType::ObjCId:
13027 case BuiltinType::ObjCClass:
13028 case BuiltinType::ObjCSel:
13029#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
13030 case BuiltinType::Id:
13031#include "clang/Basic/OpenCLImageTypes.def"
13032#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
13033 case BuiltinType::Id:
13034#include "clang/Basic/OpenCLExtensionTypes.def"
13035 case BuiltinType::OCLSampler:
13036 case BuiltinType::OCLEvent:
13037 case BuiltinType::OCLClkEvent:
13038 case BuiltinType::OCLQueue:
13039 case BuiltinType::OCLReserveID:
13040#define SVE_TYPE(Name, Id, SingletonId) \
13041 case BuiltinType::Id:
13042#include "clang/Basic/AArch64ACLETypes.def"
13043#define PPC_VECTOR_TYPE(Name, Id, Size) \
13044 case BuiltinType::Id:
13045#include "clang/Basic/PPCTypes.def"
13046#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
13047#include "clang/Basic/RISCVVTypes.def"
13048#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
13049#include "clang/Basic/WebAssemblyReferenceTypes.def"
13050#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
13051#include "clang/Basic/AMDGPUTypes.def"
13052#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
13053#include "clang/Basic/HLSLIntangibleTypes.def"
13056 case BuiltinType::Dependent:
13057 llvm_unreachable(
"unexpected dependent type");
13059 llvm_unreachable(
"unexpected placeholder type");
13064 case Type::Pointer:
13065 case Type::ConstantArray:
13066 case Type::VariableArray:
13067 case Type::IncompleteArray:
13068 case Type::FunctionNoProto:
13069 case Type::FunctionProto:
13070 case Type::ArrayParameter:
13073 case Type::MemberPointer:
13078 case Type::Complex:
13091 case Type::ExtVector:
13094 case Type::BlockPointer:
13095 case Type::ConstantMatrix:
13096 case Type::ObjCObject:
13097 case Type::ObjCInterface:
13098 case Type::ObjCObjectPointer:
13100 case Type::HLSLAttributedResource:
13101 case Type::HLSLInlineSpirv:
13109 case Type::LValueReference:
13110 case Type::RValueReference:
13111 llvm_unreachable(
"invalid type for expression");
13114 llvm_unreachable(
"unexpected type class");
13139 if (
Base.isNull()) {
13142 }
else if (
const Expr *E =
Base.dyn_cast<
const Expr *>()) {
13161 SpeculativeEvaluationRAII SpeculativeEval(Info);
13166 FoldConstant Fold(Info,
true);
13184 if (ArgType->isIntegralOrEnumerationType() || ArgType->isFloatingType() ||
13185 ArgType->isAnyComplexType() || ArgType->isPointerType() ||
13186 ArgType->isNullPtrType()) {
13189 Fold.keepDiagnostics();
13198 return V.hasValue();
13209 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
13233 const auto *Cast = dyn_cast<CastExpr>(NoParens);
13234 if (Cast ==
nullptr)
13239 auto CastKind = Cast->getCastKind();
13241 CastKind != CK_AddressSpaceConversion)
13244 const auto *SubExpr = Cast->getSubExpr();
13266 assert(!LVal.Designator.Invalid);
13268 auto IsLastOrInvalidFieldDecl = [&Ctx](
const FieldDecl *FD) {
13276 auto &
Base = LVal.getLValueBase();
13277 if (
auto *ME = dyn_cast_or_null<MemberExpr>(
Base.dyn_cast<
const Expr *>())) {
13278 if (
auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
13279 if (!IsLastOrInvalidFieldDecl(FD))
13281 }
else if (
auto *IFD = dyn_cast<IndirectFieldDecl>(ME->getMemberDecl())) {
13282 for (
auto *FD : IFD->chain()) {
13291 if (LVal.Designator.FirstEntryIsAnUnsizedArray) {
13295 if (BaseType->isIncompleteArrayType())
13301 for (
unsigned E = LVal.Designator.Entries.size(); I != E; ++I) {
13302 const auto &Entry = LVal.Designator.Entries[I];
13303 if (BaseType->isArrayType()) {
13309 uint64_t Index = Entry.getAsArrayIndex();
13313 }
else if (BaseType->isAnyComplexType()) {
13314 const auto *CT = BaseType->castAs<
ComplexType>();
13315 uint64_t Index = Entry.getAsArrayIndex();
13319 }
else if (
auto *FD = getAsField(Entry)) {
13320 if (!IsLastOrInvalidFieldDecl(FD))
13324 assert(getAsBaseClass(Entry) &&
"Expecting cast to a base class");
13336 if (LVal.Designator.Invalid)
13339 if (!LVal.Designator.Entries.empty())
13340 return LVal.Designator.isMostDerivedAnUnsizedArray();
13342 if (!LVal.InvalidBase)
13354 const SubobjectDesignator &
Designator = LVal.Designator;
13366 auto isFlexibleArrayMember = [&] {
13368 FAMKind StrictFlexArraysLevel =
13371 if (
Designator.isMostDerivedAnUnsizedArray())
13374 if (StrictFlexArraysLevel == FAMKind::Default)
13377 if (
Designator.getMostDerivedArraySize() == 0 &&
13378 StrictFlexArraysLevel != FAMKind::IncompleteOnly)
13381 if (
Designator.getMostDerivedArraySize() == 1 &&
13382 StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete)
13388 return LVal.InvalidBase &&
13390 Designator.MostDerivedIsArrayElement && isFlexibleArrayMember() &&
13398 auto CharUnitsMax = std::numeric_limits<CharUnits::QuantityType>::max();
13399 if (Int.ugt(CharUnitsMax))
13409 if (!
T.isNull() &&
T->isStructureType() &&
13410 T->castAsRecordDecl()->hasFlexibleArrayMember())
13411 if (
const auto *
V = LV.getLValueBase().dyn_cast<
const ValueDecl *>())
13412 if (
const auto *VD = dyn_cast<VarDecl>(
V))
13424 unsigned Type,
const LValue &LVal,
13443 if (!(
Type & 1) || LVal.Designator.Invalid || DetermineForCompleteObject) {
13445 if (
Type == 3 && !DetermineForCompleteObject)
13448 llvm::APInt APEndOffset;
13449 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
13453 if (LVal.InvalidBase)
13457 const bool Ret = CheckedHandleSizeof(BaseTy, EndOffset);
13463 const SubobjectDesignator &
Designator = LVal.Designator;
13475 llvm::APInt APEndOffset;
13476 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
13488 if (!CheckedHandleSizeof(
Designator.MostDerivedType, BytesPerElem))
13494 int64_t ElemsRemaining;
13497 uint64_t ArraySize =
Designator.getMostDerivedArraySize();
13498 uint64_t ArrayIndex =
Designator.Entries.back().getAsArrayIndex();
13499 ElemsRemaining = ArraySize <= ArrayIndex ? 0 : ArraySize - ArrayIndex;
13501 ElemsRemaining =
Designator.isOnePastTheEnd() ? 0 : 1;
13504 EndOffset = LVal.getLValueOffset() + BytesPerElem * ElemsRemaining;
13514 EvalInfo &Info, uint64_t &Size) {
13521 SpeculativeEvaluationRAII SpeculativeEval(Info);
13522 IgnoreSideEffectsRAII Fold(Info);
13530 LVal.setFrom(Info.Ctx, RVal);
13538 if (LVal.getLValueOffset().isNegative()) {
13549 if (EndOffset <= LVal.getLValueOffset())
13552 Size = (EndOffset - LVal.getLValueOffset()).getQuantity();
13556bool IntExprEvaluator::VisitCallExpr(
const CallExpr *E) {
13557 if (!IsConstantEvaluatedBuiltinCall(E))
13558 return ExprEvaluatorBaseTy::VisitCallExpr(E);
13575 Info.FFDiag(E->
getArg(0));
13581 assert(SrcInt.getBitWidth() >= Alignment.getBitWidth() &&
13582 "Bit widths must be the same");
13589bool IntExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *E,
13590 unsigned BuiltinOp) {
13591 switch (BuiltinOp) {
13595 case Builtin::BI__builtin_dynamic_object_size:
13596 case Builtin::BI__builtin_object_size: {
13600 assert(
Type <= 3 &&
"unexpected type");
13611 switch (Info.EvalMode) {
13612 case EvaluationMode::ConstantExpression:
13613 case EvaluationMode::ConstantFold:
13614 case EvaluationMode::IgnoreSideEffects:
13617 case EvaluationMode::ConstantExpressionUnevaluated:
13622 llvm_unreachable(
"unexpected EvalMode");
13625 case Builtin::BI__builtin_os_log_format_buffer_size: {
13626 analyze_os_log::OSLogBufferLayout Layout;
13631 case Builtin::BI__builtin_is_aligned: {
13639 Ptr.setFrom(Info.Ctx, Src);
13645 assert(Alignment.isPowerOf2());
13658 Info.FFDiag(E->
getArg(0), diag::note_constexpr_alignment_compute)
13662 assert(Src.
isInt());
13663 return Success((Src.
getInt() & (Alignment - 1)) == 0 ? 1 : 0, E);
13665 case Builtin::BI__builtin_align_up: {
13673 APSInt((Src.
getInt() + (Alignment - 1)) & ~(Alignment - 1),
13674 Src.
getInt().isUnsigned());
13675 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
13676 return Success(AlignedVal, E);
13678 case Builtin::BI__builtin_align_down: {
13687 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
13688 return Success(AlignedVal, E);
13691 case Builtin::BI__builtin_bitreverse8:
13692 case Builtin::BI__builtin_bitreverse16:
13693 case Builtin::BI__builtin_bitreverse32:
13694 case Builtin::BI__builtin_bitreverse64:
13695 case Builtin::BI__builtin_elementwise_bitreverse: {
13700 return Success(Val.reverseBits(), E);
13703 case Builtin::BI__builtin_bswap16:
13704 case Builtin::BI__builtin_bswap32:
13705 case Builtin::BI__builtin_bswap64: {
13710 return Success(Val.byteSwap(), E);
13713 case Builtin::BI__builtin_classify_type:
13716 case Builtin::BI__builtin_clrsb:
13717 case Builtin::BI__builtin_clrsbl:
13718 case Builtin::BI__builtin_clrsbll: {
13723 return Success(Val.getBitWidth() - Val.getSignificantBits(), E);
13726 case Builtin::BI__builtin_clz:
13727 case Builtin::BI__builtin_clzl:
13728 case Builtin::BI__builtin_clzll:
13729 case Builtin::BI__builtin_clzs:
13730 case Builtin::BI__builtin_clzg:
13731 case Builtin::BI__builtin_elementwise_clzg:
13732 case Builtin::BI__lzcnt16:
13733 case Builtin::BI__lzcnt:
13734 case Builtin::BI__lzcnt64: {
13745 std::optional<APSInt> Fallback;
13746 if ((BuiltinOp == Builtin::BI__builtin_clzg ||
13747 BuiltinOp == Builtin::BI__builtin_elementwise_clzg) &&
13752 Fallback = FallbackTemp;
13757 return Success(*Fallback, E);
13762 bool ZeroIsUndefined = BuiltinOp != Builtin::BI__lzcnt16 &&
13763 BuiltinOp != Builtin::BI__lzcnt &&
13764 BuiltinOp != Builtin::BI__lzcnt64;
13766 if (BuiltinOp == Builtin::BI__builtin_elementwise_clzg) {
13767 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
13771 if (ZeroIsUndefined)
13775 return Success(Val.countl_zero(), E);
13778 case Builtin::BI__builtin_constant_p: {
13779 const Expr *Arg = E->
getArg(0);
13788 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
13792 case Builtin::BI__noop:
13796 case Builtin::BI__builtin_is_constant_evaluated: {
13797 const auto *
Callee = Info.CurrentCall->getCallee();
13798 if (Info.InConstantContext && !Info.CheckingPotentialConstantExpression &&
13799 (Info.CallStackDepth == 1 ||
13800 (Info.CallStackDepth == 2 &&
Callee->isInStdNamespace() &&
13801 Callee->getIdentifier() &&
13802 Callee->getIdentifier()->isStr(
"is_constant_evaluated")))) {
13804 if (Info.EvalStatus.
Diag)
13805 Info.report((Info.CallStackDepth == 1)
13807 : Info.CurrentCall->getCallRange().getBegin(),
13808 diag::warn_is_constant_evaluated_always_true_constexpr)
13809 << (Info.CallStackDepth == 1 ?
"__builtin_is_constant_evaluated"
13810 :
"std::is_constant_evaluated");
13813 return Success(Info.InConstantContext, E);
13816 case Builtin::BI__builtin_is_within_lifetime:
13817 if (
auto result = EvaluateBuiltinIsWithinLifetime(*
this, E))
13821 case Builtin::BI__builtin_ctz:
13822 case Builtin::BI__builtin_ctzl:
13823 case Builtin::BI__builtin_ctzll:
13824 case Builtin::BI__builtin_ctzs:
13825 case Builtin::BI__builtin_ctzg:
13826 case Builtin::BI__builtin_elementwise_ctzg: {
13837 std::optional<APSInt> Fallback;
13838 if ((BuiltinOp == Builtin::BI__builtin_ctzg ||
13839 BuiltinOp == Builtin::BI__builtin_elementwise_ctzg) &&
13844 Fallback = FallbackTemp;
13849 return Success(*Fallback, E);
13851 if (BuiltinOp == Builtin::BI__builtin_elementwise_ctzg) {
13852 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
13858 return Success(Val.countr_zero(), E);
13861 case Builtin::BI__builtin_eh_return_data_regno: {
13867 case Builtin::BI__builtin_elementwise_abs: {
13872 return Success(Val.abs(), E);
13875 case Builtin::BI__builtin_expect:
13876 case Builtin::BI__builtin_expect_with_probability:
13877 return Visit(E->
getArg(0));
13879 case Builtin::BI__builtin_ptrauth_string_discriminator: {
13886 case Builtin::BI__builtin_ffs:
13887 case Builtin::BI__builtin_ffsl:
13888 case Builtin::BI__builtin_ffsll: {
13893 unsigned N = Val.countr_zero();
13894 return Success(N == Val.getBitWidth() ? 0 : N + 1, E);
13897 case Builtin::BI__builtin_fpclassify: {
13902 switch (Val.getCategory()) {
13903 case APFloat::fcNaN: Arg = 0;
break;
13904 case APFloat::fcInfinity: Arg = 1;
break;
13905 case APFloat::fcNormal: Arg = Val.isDenormal() ? 3 : 2;
break;
13906 case APFloat::fcZero: Arg = 4;
break;
13908 return Visit(E->
getArg(Arg));
13911 case Builtin::BI__builtin_isinf_sign: {
13914 Success(Val.isInfinity() ? (Val.isNegative() ? -1 : 1) : 0, E);
13917 case Builtin::BI__builtin_isinf: {
13920 Success(Val.isInfinity() ? 1 : 0, E);
13923 case Builtin::BI__builtin_isfinite: {
13926 Success(Val.isFinite() ? 1 : 0, E);
13929 case Builtin::BI__builtin_isnan: {
13932 Success(Val.isNaN() ? 1 : 0, E);
13935 case Builtin::BI__builtin_isnormal: {
13938 Success(Val.isNormal() ? 1 : 0, E);
13941 case Builtin::BI__builtin_issubnormal: {
13944 Success(Val.isDenormal() ? 1 : 0, E);
13947 case Builtin::BI__builtin_iszero: {
13950 Success(Val.isZero() ? 1 : 0, E);
13953 case Builtin::BI__builtin_signbit:
13954 case Builtin::BI__builtin_signbitf:
13955 case Builtin::BI__builtin_signbitl: {
13958 Success(Val.isNegative() ? 1 : 0, E);
13961 case Builtin::BI__builtin_isgreater:
13962 case Builtin::BI__builtin_isgreaterequal:
13963 case Builtin::BI__builtin_isless:
13964 case Builtin::BI__builtin_islessequal:
13965 case Builtin::BI__builtin_islessgreater:
13966 case Builtin::BI__builtin_isunordered: {
13975 switch (BuiltinOp) {
13976 case Builtin::BI__builtin_isgreater:
13978 case Builtin::BI__builtin_isgreaterequal:
13980 case Builtin::BI__builtin_isless:
13982 case Builtin::BI__builtin_islessequal:
13984 case Builtin::BI__builtin_islessgreater: {
13985 APFloat::cmpResult cmp = LHS.compare(RHS);
13986 return cmp == APFloat::cmpResult::cmpLessThan ||
13987 cmp == APFloat::cmpResult::cmpGreaterThan;
13989 case Builtin::BI__builtin_isunordered:
13990 return LHS.compare(RHS) == APFloat::cmpResult::cmpUnordered;
13992 llvm_unreachable(
"Unexpected builtin ID: Should be a floating "
13993 "point comparison function");
14001 case Builtin::BI__builtin_issignaling: {
14004 Success(Val.isSignaling() ? 1 : 0, E);
14007 case Builtin::BI__builtin_isfpclass: {
14011 unsigned Test =
static_cast<llvm::FPClassTest
>(MaskVal.getZExtValue());
14014 Success((Val.classify() & Test) ? 1 : 0, E);
14017 case Builtin::BI__builtin_parity:
14018 case Builtin::BI__builtin_parityl:
14019 case Builtin::BI__builtin_parityll: {
14024 return Success(Val.popcount() % 2, E);
14027 case Builtin::BI__builtin_abs:
14028 case Builtin::BI__builtin_labs:
14029 case Builtin::BI__builtin_llabs: {
14033 if (Val ==
APSInt(APInt::getSignedMinValue(Val.getBitWidth()),
14036 if (Val.isNegative())
14041 case Builtin::BI__builtin_popcount:
14042 case Builtin::BI__builtin_popcountl:
14043 case Builtin::BI__builtin_popcountll:
14044 case Builtin::BI__builtin_popcountg:
14045 case Builtin::BI__builtin_elementwise_popcount:
14046 case Builtin::BI__popcnt16:
14047 case Builtin::BI__popcnt:
14048 case Builtin::BI__popcnt64: {
14059 return Success(Val.popcount(), E);
14062 case Builtin::BI__builtin_rotateleft8:
14063 case Builtin::BI__builtin_rotateleft16:
14064 case Builtin::BI__builtin_rotateleft32:
14065 case Builtin::BI__builtin_rotateleft64:
14066 case Builtin::BI_rotl8:
14067 case Builtin::BI_rotl16:
14068 case Builtin::BI_rotl:
14069 case Builtin::BI_lrotl:
14070 case Builtin::BI_rotl64: {
14076 return Success(Val.rotl(Amt.urem(Val.getBitWidth())), E);
14079 case Builtin::BI__builtin_rotateright8:
14080 case Builtin::BI__builtin_rotateright16:
14081 case Builtin::BI__builtin_rotateright32:
14082 case Builtin::BI__builtin_rotateright64:
14083 case Builtin::BI_rotr8:
14084 case Builtin::BI_rotr16:
14085 case Builtin::BI_rotr:
14086 case Builtin::BI_lrotr:
14087 case Builtin::BI_rotr64: {
14093 return Success(Val.rotr(Amt.urem(Val.getBitWidth())), E);
14096 case Builtin::BI__builtin_elementwise_add_sat: {
14102 APInt Result = LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS);
14105 case Builtin::BI__builtin_elementwise_sub_sat: {
14111 APInt Result = LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
14114 case Builtin::BI__builtin_elementwise_max: {
14123 case Builtin::BI__builtin_elementwise_min: {
14132 case Builtin::BI__builtin_elementwise_fshl:
14133 case Builtin::BI__builtin_elementwise_fshr: {
14140 switch (BuiltinOp) {
14141 case Builtin::BI__builtin_elementwise_fshl: {
14142 APSInt Result(llvm::APIntOps::fshl(Hi, Lo, Shift), Hi.isUnsigned());
14145 case Builtin::BI__builtin_elementwise_fshr: {
14146 APSInt Result(llvm::APIntOps::fshr(Hi, Lo, Shift), Hi.isUnsigned());
14150 llvm_unreachable(
"Fully covered switch above");
14152 case Builtin::BIstrlen:
14153 case Builtin::BIwcslen:
14155 if (Info.getLangOpts().CPlusPlus11)
14156 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
14160 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
14162 case Builtin::BI__builtin_strlen:
14163 case Builtin::BI__builtin_wcslen: {
14172 case Builtin::BIstrcmp:
14173 case Builtin::BIwcscmp:
14174 case Builtin::BIstrncmp:
14175 case Builtin::BIwcsncmp:
14176 case Builtin::BImemcmp:
14177 case Builtin::BIbcmp:
14178 case Builtin::BIwmemcmp:
14180 if (Info.getLangOpts().CPlusPlus11)
14181 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
14185 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
14187 case Builtin::BI__builtin_strcmp:
14188 case Builtin::BI__builtin_wcscmp:
14189 case Builtin::BI__builtin_strncmp:
14190 case Builtin::BI__builtin_wcsncmp:
14191 case Builtin::BI__builtin_memcmp:
14192 case Builtin::BI__builtin_bcmp:
14193 case Builtin::BI__builtin_wmemcmp: {
14194 LValue String1, String2;
14200 if (BuiltinOp != Builtin::BIstrcmp &&
14201 BuiltinOp != Builtin::BIwcscmp &&
14202 BuiltinOp != Builtin::BI__builtin_strcmp &&
14203 BuiltinOp != Builtin::BI__builtin_wcscmp) {
14207 MaxLength = N.getZExtValue();
14211 if (MaxLength == 0u)
14214 if (!String1.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
14215 !String2.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
14216 String1.Designator.Invalid || String2.Designator.Invalid)
14219 QualType CharTy1 = String1.Designator.getType(Info.Ctx);
14220 QualType CharTy2 = String2.Designator.getType(Info.Ctx);
14222 bool IsRawByte = BuiltinOp == Builtin::BImemcmp ||
14223 BuiltinOp == Builtin::BIbcmp ||
14224 BuiltinOp == Builtin::BI__builtin_memcmp ||
14225 BuiltinOp == Builtin::BI__builtin_bcmp;
14227 assert(IsRawByte ||
14237 Info.FFDiag(E, diag::note_constexpr_memcmp_unsupported)
14243 const auto &ReadCurElems = [&](
APValue &Char1,
APValue &Char2) {
14246 Char1.
isInt() && Char2.isInt();
14248 const auto &AdvanceElems = [&] {
14254 (BuiltinOp != Builtin::BImemcmp && BuiltinOp != Builtin::BIbcmp &&
14255 BuiltinOp != Builtin::BIwmemcmp &&
14256 BuiltinOp != Builtin::BI__builtin_memcmp &&
14257 BuiltinOp != Builtin::BI__builtin_bcmp &&
14258 BuiltinOp != Builtin::BI__builtin_wmemcmp);
14259 bool IsWide = BuiltinOp == Builtin::BIwcscmp ||
14260 BuiltinOp == Builtin::BIwcsncmp ||
14261 BuiltinOp == Builtin::BIwmemcmp ||
14262 BuiltinOp == Builtin::BI__builtin_wcscmp ||
14263 BuiltinOp == Builtin::BI__builtin_wcsncmp ||
14264 BuiltinOp == Builtin::BI__builtin_wmemcmp;
14266 for (; MaxLength; --MaxLength) {
14268 if (!ReadCurElems(Char1, Char2))
14276 if (StopAtNull && !Char1.
getInt())
14278 assert(!(StopAtNull && !Char2.
getInt()));
14279 if (!AdvanceElems())
14286 case Builtin::BI__atomic_always_lock_free:
14287 case Builtin::BI__atomic_is_lock_free:
14288 case Builtin::BI__c11_atomic_is_lock_free: {
14304 if (
Size.isPowerOfTwo()) {
14306 unsigned InlineWidthBits =
14309 if (BuiltinOp == Builtin::BI__c11_atomic_is_lock_free ||
14315 const Expr *PtrArg = E->
getArg(1);
14321 IntResult.isAligned(
Size.getAsAlign()))
14325 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(PtrArg)) {
14328 if (ICE->getCastKind() == CK_BitCast)
14329 PtrArg = ICE->getSubExpr();
14332 if (
auto PtrTy = PtrArg->
getType()->
getAs<PointerType>()) {
14343 return BuiltinOp == Builtin::BI__atomic_always_lock_free ?
14346 case Builtin::BI__builtin_addcb:
14347 case Builtin::BI__builtin_addcs:
14348 case Builtin::BI__builtin_addc:
14349 case Builtin::BI__builtin_addcl:
14350 case Builtin::BI__builtin_addcll:
14351 case Builtin::BI__builtin_subcb:
14352 case Builtin::BI__builtin_subcs:
14353 case Builtin::BI__builtin_subc:
14354 case Builtin::BI__builtin_subcl:
14355 case Builtin::BI__builtin_subcll: {
14356 LValue CarryOutLValue;
14368 bool FirstOverflowed =
false;
14369 bool SecondOverflowed =
false;
14370 switch (BuiltinOp) {
14372 llvm_unreachable(
"Invalid value for BuiltinOp");
14373 case Builtin::BI__builtin_addcb:
14374 case Builtin::BI__builtin_addcs:
14375 case Builtin::BI__builtin_addc:
14376 case Builtin::BI__builtin_addcl:
14377 case Builtin::BI__builtin_addcll:
14379 LHS.uadd_ov(RHS, FirstOverflowed).uadd_ov(CarryIn, SecondOverflowed);
14381 case Builtin::BI__builtin_subcb:
14382 case Builtin::BI__builtin_subcs:
14383 case Builtin::BI__builtin_subc:
14384 case Builtin::BI__builtin_subcl:
14385 case Builtin::BI__builtin_subcll:
14387 LHS.usub_ov(RHS, FirstOverflowed).usub_ov(CarryIn, SecondOverflowed);
14393 CarryOut = (
uint64_t)(FirstOverflowed | SecondOverflowed);
14399 case Builtin::BI__builtin_add_overflow:
14400 case Builtin::BI__builtin_sub_overflow:
14401 case Builtin::BI__builtin_mul_overflow:
14402 case Builtin::BI__builtin_sadd_overflow:
14403 case Builtin::BI__builtin_uadd_overflow:
14404 case Builtin::BI__builtin_uaddl_overflow:
14405 case Builtin::BI__builtin_uaddll_overflow:
14406 case Builtin::BI__builtin_usub_overflow:
14407 case Builtin::BI__builtin_usubl_overflow:
14408 case Builtin::BI__builtin_usubll_overflow:
14409 case Builtin::BI__builtin_umul_overflow:
14410 case Builtin::BI__builtin_umull_overflow:
14411 case Builtin::BI__builtin_umulll_overflow:
14412 case Builtin::BI__builtin_saddl_overflow:
14413 case Builtin::BI__builtin_saddll_overflow:
14414 case Builtin::BI__builtin_ssub_overflow:
14415 case Builtin::BI__builtin_ssubl_overflow:
14416 case Builtin::BI__builtin_ssubll_overflow:
14417 case Builtin::BI__builtin_smul_overflow:
14418 case Builtin::BI__builtin_smull_overflow:
14419 case Builtin::BI__builtin_smulll_overflow: {
14420 LValue ResultLValue;
14430 bool DidOverflow =
false;
14433 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
14434 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
14435 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
14436 bool IsSigned = LHS.isSigned() || RHS.isSigned() ||
14438 bool AllSigned = LHS.isSigned() && RHS.isSigned() &&
14440 uint64_t LHSSize = LHS.getBitWidth();
14441 uint64_t RHSSize = RHS.getBitWidth();
14443 uint64_t MaxBits = std::max(std::max(LHSSize, RHSSize), ResultSize);
14449 if (IsSigned && !AllSigned)
14452 LHS =
APSInt(LHS.extOrTrunc(MaxBits), !IsSigned);
14453 RHS =
APSInt(RHS.extOrTrunc(MaxBits), !IsSigned);
14458 switch (BuiltinOp) {
14460 llvm_unreachable(
"Invalid value for BuiltinOp");
14461 case Builtin::BI__builtin_add_overflow:
14462 case Builtin::BI__builtin_sadd_overflow:
14463 case Builtin::BI__builtin_saddl_overflow:
14464 case Builtin::BI__builtin_saddll_overflow:
14465 case Builtin::BI__builtin_uadd_overflow:
14466 case Builtin::BI__builtin_uaddl_overflow:
14467 case Builtin::BI__builtin_uaddll_overflow:
14468 Result = LHS.isSigned() ? LHS.sadd_ov(RHS, DidOverflow)
14469 : LHS.uadd_ov(RHS, DidOverflow);
14471 case Builtin::BI__builtin_sub_overflow:
14472 case Builtin::BI__builtin_ssub_overflow:
14473 case Builtin::BI__builtin_ssubl_overflow:
14474 case Builtin::BI__builtin_ssubll_overflow:
14475 case Builtin::BI__builtin_usub_overflow:
14476 case Builtin::BI__builtin_usubl_overflow:
14477 case Builtin::BI__builtin_usubll_overflow:
14478 Result = LHS.isSigned() ? LHS.ssub_ov(RHS, DidOverflow)
14479 : LHS.usub_ov(RHS, DidOverflow);
14481 case Builtin::BI__builtin_mul_overflow:
14482 case Builtin::BI__builtin_smul_overflow:
14483 case Builtin::BI__builtin_smull_overflow:
14484 case Builtin::BI__builtin_smulll_overflow:
14485 case Builtin::BI__builtin_umul_overflow:
14486 case Builtin::BI__builtin_umull_overflow:
14487 case Builtin::BI__builtin_umulll_overflow:
14488 Result = LHS.isSigned() ? LHS.smul_ov(RHS, DidOverflow)
14489 : LHS.umul_ov(RHS, DidOverflow);
14495 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
14496 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
14497 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
14506 if (!APSInt::isSameValue(Temp,
Result))
14507 DidOverflow =
true;
14514 return Success(DidOverflow, E);
14517 case Builtin::BI__builtin_reduce_add:
14518 case Builtin::BI__builtin_reduce_mul:
14519 case Builtin::BI__builtin_reduce_and:
14520 case Builtin::BI__builtin_reduce_or:
14521 case Builtin::BI__builtin_reduce_xor:
14522 case Builtin::BI__builtin_reduce_min:
14523 case Builtin::BI__builtin_reduce_max: {
14530 for (
unsigned EltNum = 1; EltNum < SourceLen; ++EltNum) {
14531 switch (BuiltinOp) {
14534 case Builtin::BI__builtin_reduce_add: {
14537 Reduced.getBitWidth() + 1, std::plus<APSInt>(), Reduced))
14541 case Builtin::BI__builtin_reduce_mul: {
14544 Reduced.getBitWidth() * 2, std::multiplies<APSInt>(), Reduced))
14548 case Builtin::BI__builtin_reduce_and: {
14552 case Builtin::BI__builtin_reduce_or: {
14556 case Builtin::BI__builtin_reduce_xor: {
14560 case Builtin::BI__builtin_reduce_min: {
14564 case Builtin::BI__builtin_reduce_max: {
14574 case clang::X86::BI__builtin_ia32_addcarryx_u32:
14575 case clang::X86::BI__builtin_ia32_addcarryx_u64:
14576 case clang::X86::BI__builtin_ia32_subborrow_u32:
14577 case clang::X86::BI__builtin_ia32_subborrow_u64: {
14578 LValue ResultLValue;
14579 APSInt CarryIn, LHS, RHS;
14587 bool IsAdd = BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u32 ||
14588 BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u64;
14590 unsigned BitWidth = LHS.getBitWidth();
14591 unsigned CarryInBit = CarryIn.ugt(0) ? 1 : 0;
14594 ? (LHS.zext(BitWidth + 1) + (RHS.zext(BitWidth + 1) + CarryInBit))
14595 : (LHS.zext(BitWidth + 1) - (RHS.zext(BitWidth + 1) + CarryInBit));
14597 APInt Result = ExResult.extractBits(BitWidth, 0);
14598 uint64_t CarryOut = ExResult.extractBitsAsZExtValue(1, BitWidth);
14606 case clang::X86::BI__builtin_ia32_bextr_u32:
14607 case clang::X86::BI__builtin_ia32_bextr_u64:
14608 case clang::X86::BI__builtin_ia32_bextri_u32:
14609 case clang::X86::BI__builtin_ia32_bextri_u64: {
14615 unsigned BitWidth = Val.getBitWidth();
14617 uint64_t Length = Idx.extractBitsAsZExtValue(8, 8);
14618 Length = Length > BitWidth ? BitWidth : Length;
14621 if (Length == 0 || Shift >= BitWidth)
14625 Result &= llvm::maskTrailingOnes<uint64_t>(Length);
14629 case clang::X86::BI__builtin_ia32_bzhi_si:
14630 case clang::X86::BI__builtin_ia32_bzhi_di: {
14636 unsigned BitWidth = Val.getBitWidth();
14637 unsigned Index = Idx.extractBitsAsZExtValue(8, 0);
14638 if (Index < BitWidth)
14639 Val.clearHighBits(BitWidth - Index);
14643 case clang::X86::BI__builtin_ia32_lzcnt_u16:
14644 case clang::X86::BI__builtin_ia32_lzcnt_u32:
14645 case clang::X86::BI__builtin_ia32_lzcnt_u64: {
14649 return Success(Val.countLeadingZeros(), E);
14652 case clang::X86::BI__builtin_ia32_tzcnt_u16:
14653 case clang::X86::BI__builtin_ia32_tzcnt_u32:
14654 case clang::X86::BI__builtin_ia32_tzcnt_u64: {
14658 return Success(Val.countTrailingZeros(), E);
14661 case clang::X86::BI__builtin_ia32_pdep_si:
14662 case clang::X86::BI__builtin_ia32_pdep_di: {
14668 unsigned BitWidth = Val.getBitWidth();
14670 for (
unsigned I = 0, P = 0; I != BitWidth; ++I)
14672 Result.setBitVal(I, Val[P++]);
14676 case clang::X86::BI__builtin_ia32_pext_si:
14677 case clang::X86::BI__builtin_ia32_pext_di: {
14683 unsigned BitWidth = Val.getBitWidth();
14685 for (
unsigned I = 0, P = 0; I != BitWidth; ++I)
14687 Result.setBitVal(P++, Val[I]);
14696 const LValue &LV) {
14699 if (!LV.getLValueBase())
14704 if (!LV.getLValueDesignator().Invalid &&
14705 !LV.getLValueDesignator().isOnePastTheEnd())
14715 if (LV.getLValueDesignator().Invalid)
14721 return LV.getLValueOffset() == Size;
14731class DataRecursiveIntBinOpEvaluator {
14732 struct EvalResult {
14734 bool Failed =
false;
14736 EvalResult() =
default;
14738 void swap(EvalResult &RHS) {
14740 Failed = RHS.Failed;
14741 RHS.Failed =
false;
14747 EvalResult LHSResult;
14748 enum { AnyExprKind, BinOpKind, BinOpVisitedLHSKind }
Kind;
14751 Job(Job &&) =
default;
14753 void startSpeculativeEval(EvalInfo &Info) {
14754 SpecEvalRAII = SpeculativeEvaluationRAII(Info);
14758 SpeculativeEvaluationRAII SpecEvalRAII;
14761 SmallVector<Job, 16> Queue;
14763 IntExprEvaluator &IntEval;
14768 DataRecursiveIntBinOpEvaluator(IntExprEvaluator &IntEval,
APValue &
Result)
14769 : IntEval(IntEval), Info(IntEval.getEvalInfo()), FinalResult(
Result) { }
14775 static bool shouldEnqueue(
const BinaryOperator *E) {
14782 bool Traverse(
const BinaryOperator *E) {
14784 EvalResult PrevResult;
14785 while (!Queue.empty())
14786 process(PrevResult);
14788 if (PrevResult.Failed)
return false;
14790 FinalResult.
swap(PrevResult.Val);
14801 bool Error(
const Expr *E) {
14802 return IntEval.Error(E);
14805 return IntEval.Error(E, D);
14808 OptionalDiagnostic CCEDiag(
const Expr *E,
diag::kind D) {
14809 return Info.CCEDiag(E, D);
14813 bool VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
14814 bool &SuppressRHSDiags);
14816 bool VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
14819 void EvaluateExpr(
const Expr *E, EvalResult &
Result) {
14825 void process(EvalResult &
Result);
14827 void enqueue(
const Expr *E) {
14829 Queue.resize(Queue.size()+1);
14830 Queue.back().E = E;
14831 Queue.back().Kind = Job::AnyExprKind;
14837bool DataRecursiveIntBinOpEvaluator::
14838 VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
14839 bool &SuppressRHSDiags) {
14842 if (LHSResult.Failed)
14843 return Info.noteSideEffect();
14852 if (LHSAsBool == (E->
getOpcode() == BO_LOr)) {
14853 Success(LHSAsBool, E, LHSResult.Val);
14857 LHSResult.Failed =
true;
14861 if (!Info.noteSideEffect())
14867 SuppressRHSDiags =
true;
14876 if (LHSResult.Failed && !Info.noteFailure())
14887 assert(!LVal.
hasLValuePath() &&
"have designator for integer lvalue");
14889 uint64_t Offset64 = Offset.getQuantity();
14890 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
14892 : Offset64 + Index64);
14895bool DataRecursiveIntBinOpEvaluator::
14896 VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
14899 if (RHSResult.Failed)
14906 bool lhsResult, rhsResult;
14921 if (rhsResult == (E->
getOpcode() == BO_LOr))
14932 if (LHSResult.Failed || RHSResult.Failed)
14935 const APValue &LHSVal = LHSResult.Val;
14936 const APValue &RHSVal = RHSResult.Val;
14960 if (!LHSExpr || !RHSExpr)
14962 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
14963 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
14964 if (!LHSAddrExpr || !RHSAddrExpr)
14989void DataRecursiveIntBinOpEvaluator::process(EvalResult &
Result) {
14990 Job &job = Queue.back();
14992 switch (job.Kind) {
14993 case Job::AnyExprKind: {
14994 if (
const BinaryOperator *Bop = dyn_cast<BinaryOperator>(job.E)) {
14995 if (shouldEnqueue(Bop)) {
14996 job.Kind = Job::BinOpKind;
14997 enqueue(Bop->getLHS());
15002 EvaluateExpr(job.E,
Result);
15007 case Job::BinOpKind: {
15009 bool SuppressRHSDiags =
false;
15010 if (!VisitBinOpLHSOnly(
Result, Bop, SuppressRHSDiags)) {
15014 if (SuppressRHSDiags)
15015 job.startSpeculativeEval(Info);
15016 job.LHSResult.swap(
Result);
15017 job.Kind = Job::BinOpVisitedLHSKind;
15022 case Job::BinOpVisitedLHSKind: {
15026 Result.Failed = !VisitBinOp(job.LHSResult, RHS, Bop,
Result.Val);
15032 llvm_unreachable(
"Invalid Job::Kind!");
15036enum class CmpResult {
15045template <
class SuccessCB,
class AfterCB>
15048 SuccessCB &&
Success, AfterCB &&DoAfter) {
15053 "unsupported binary expression evaluation");
15055 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
15069 if (!LHSOK && !Info.noteFailure())
15074 return Success(CmpResult::Less, E);
15076 return Success(CmpResult::Greater, E);
15077 return Success(CmpResult::Equal, E);
15085 if (!LHSOK && !Info.noteFailure())
15090 return Success(CmpResult::Less, E);
15092 return Success(CmpResult::Greater, E);
15093 return Success(CmpResult::Equal, E);
15097 ComplexValue LHS, RHS;
15106 LHS.makeComplexFloat();
15107 LHS.FloatImag = APFloat(LHS.FloatReal.getSemantics());
15112 if (!LHSOK && !Info.noteFailure())
15118 RHS.makeComplexFloat();
15119 RHS.FloatImag = APFloat(RHS.FloatReal.getSemantics());
15123 if (LHS.isComplexFloat()) {
15124 APFloat::cmpResult CR_r =
15125 LHS.getComplexFloatReal().compare(RHS.getComplexFloatReal());
15126 APFloat::cmpResult CR_i =
15127 LHS.getComplexFloatImag().compare(RHS.getComplexFloatImag());
15128 bool IsEqual = CR_r == APFloat::cmpEqual && CR_i == APFloat::cmpEqual;
15129 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal, E);
15131 assert(IsEquality &&
"invalid complex comparison");
15132 bool IsEqual = LHS.getComplexIntReal() == RHS.getComplexIntReal() &&
15133 LHS.getComplexIntImag() == RHS.getComplexIntImag();
15134 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal, E);
15140 APFloat RHS(0.0), LHS(0.0);
15143 if (!LHSOK && !Info.noteFailure())
15150 llvm::APFloatBase::cmpResult APFloatCmpResult = LHS.compare(RHS);
15151 if (!Info.InConstantContext &&
15152 APFloatCmpResult == APFloat::cmpUnordered &&
15155 Info.FFDiag(E, diag::note_constexpr_float_arithmetic_strict);
15158 auto GetCmpRes = [&]() {
15159 switch (APFloatCmpResult) {
15160 case APFloat::cmpEqual:
15161 return CmpResult::Equal;
15162 case APFloat::cmpLessThan:
15163 return CmpResult::Less;
15164 case APFloat::cmpGreaterThan:
15165 return CmpResult::Greater;
15166 case APFloat::cmpUnordered:
15167 return CmpResult::Unordered;
15169 llvm_unreachable(
"Unrecognised APFloat::cmpResult enum");
15171 return Success(GetCmpRes(), E);
15175 LValue LHSValue, RHSValue;
15178 if (!LHSOK && !Info.noteFailure())
15189 if (Info.checkingPotentialConstantExpression() &&
15190 (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown))
15192 auto DiagComparison = [&] (
unsigned DiagID,
bool Reversed =
false) {
15193 std::string LHS = LHSValue.toString(Info.Ctx, E->
getLHS()->
getType());
15194 std::string RHS = RHSValue.toString(Info.Ctx, E->
getRHS()->
getType());
15195 Info.FFDiag(E, DiagID)
15202 return DiagComparison(
15203 diag::note_constexpr_pointer_comparison_unspecified);
15209 if ((!LHSValue.Base && !LHSValue.Offset.
isZero()) ||
15210 (!RHSValue.Base && !RHSValue.Offset.
isZero()))
15211 return DiagComparison(diag::note_constexpr_pointer_constant_comparison,
15225 return DiagComparison(diag::note_constexpr_literal_comparison);
15227 return DiagComparison(diag::note_constexpr_opaque_call_comparison,
15232 return DiagComparison(diag::note_constexpr_pointer_weak_comparison,
15236 if (LHSValue.Base && LHSValue.Offset.
isZero() &&
15238 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
15240 if (RHSValue.Base && RHSValue.Offset.
isZero() &&
15242 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
15248 return DiagComparison(
15249 diag::note_constexpr_pointer_comparison_zero_sized);
15250 if (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown)
15251 return DiagComparison(
15252 diag::note_constexpr_pointer_comparison_unspecified);
15254 return Success(CmpResult::Unequal, E);
15257 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
15258 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
15260 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
15261 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
15271 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid && IsRelational) {
15272 bool WasArrayIndex;
15275 :
getType(LHSValue.Base).getNonReferenceType(),
15276 LHSDesignator, RHSDesignator, WasArrayIndex);
15283 if (!WasArrayIndex && Mismatch < LHSDesignator.Entries.size() &&
15284 Mismatch < RHSDesignator.Entries.size()) {
15285 const FieldDecl *LF = getAsField(LHSDesignator.Entries[Mismatch]);
15286 const FieldDecl *RF = getAsField(RHSDesignator.Entries[Mismatch]);
15288 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_classes);
15290 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
15291 << getAsBaseClass(LHSDesignator.Entries[Mismatch])
15294 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
15295 << getAsBaseClass(RHSDesignator.Entries[Mismatch])
15300 diag::note_constexpr_pointer_comparison_differing_access)
15311 assert(PtrSize <= 64 &&
"Unexpected pointer width");
15312 uint64_t Mask = ~0ULL >> (64 - PtrSize);
15313 CompareLHS &= Mask;
15314 CompareRHS &= Mask;
15319 if (!LHSValue.Base.
isNull() && IsRelational) {
15324 uint64_t OffsetLimit = Size.getQuantity();
15325 if (CompareLHS > OffsetLimit || CompareRHS > OffsetLimit)
15329 if (CompareLHS < CompareRHS)
15330 return Success(CmpResult::Less, E);
15331 if (CompareLHS > CompareRHS)
15332 return Success(CmpResult::Greater, E);
15333 return Success(CmpResult::Equal, E);
15337 assert(IsEquality &&
"unexpected member pointer operation");
15340 MemberPtr LHSValue, RHSValue;
15343 if (!LHSOK && !Info.noteFailure())
15351 if (LHSValue.getDecl() && LHSValue.getDecl()->isWeak()) {
15352 Info.FFDiag(E, diag::note_constexpr_mem_pointer_weak_comparison)
15353 << LHSValue.getDecl();
15356 if (RHSValue.getDecl() && RHSValue.getDecl()->isWeak()) {
15357 Info.FFDiag(E, diag::note_constexpr_mem_pointer_weak_comparison)
15358 << RHSValue.getDecl();
15365 if (!LHSValue.getDecl() || !RHSValue.getDecl()) {
15366 bool Equal = !LHSValue.getDecl() && !RHSValue.getDecl();
15367 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal, E);
15372 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(LHSValue.getDecl()))
15373 if (MD->isVirtual())
15374 Info.CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
15375 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(RHSValue.getDecl()))
15376 if (MD->isVirtual())
15377 Info.CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
15383 bool Equal = LHSValue == RHSValue;
15384 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal, E);
15389 assert(RHSTy->
isNullPtrType() &&
"missing pointer conversion");
15397 return Success(CmpResult::Equal, E);
15403bool RecordExprEvaluator::VisitBinCmp(
const BinaryOperator *E) {
15407 auto OnSuccess = [&](CmpResult CR,
const BinaryOperator *E) {
15410 case CmpResult::Unequal:
15411 llvm_unreachable(
"should never produce Unequal for three-way comparison");
15412 case CmpResult::Less:
15413 CCR = ComparisonCategoryResult::Less;
15415 case CmpResult::Equal:
15416 CCR = ComparisonCategoryResult::Equal;
15418 case CmpResult::Greater:
15419 CCR = ComparisonCategoryResult::Greater;
15421 case CmpResult::Unordered:
15422 CCR = ComparisonCategoryResult::Unordered;
15427 const ComparisonCategoryInfo &CmpInfo =
15436 ConstantExprKind::Normal);
15439 return ExprEvaluatorBaseTy::VisitBinCmp(E);
15443bool RecordExprEvaluator::VisitCXXParenListInitExpr(
15444 const CXXParenListInitExpr *E) {
15445 return VisitCXXParenListOrInitListExpr(E, E->
getInitExprs());
15448bool IntExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
15453 if (!Info.noteFailure())
15457 if (DataRecursiveIntBinOpEvaluator::shouldEnqueue(E))
15458 return DataRecursiveIntBinOpEvaluator(*
this,
Result).Traverse(E);
15462 "DataRecursiveIntBinOpEvaluator should have handled integral types");
15467 auto OnSuccess = [&](CmpResult CR,
const BinaryOperator *E) {
15468 assert((CR != CmpResult::Unequal || E->
isEqualityOp()) &&
15469 "should only produce Unequal for equality comparisons");
15470 bool IsEqual = CR == CmpResult::Equal,
15471 IsLess = CR == CmpResult::Less,
15472 IsGreater = CR == CmpResult::Greater;
15476 llvm_unreachable(
"unsupported binary operator");
15479 return Success(IsEqual == (Op == BO_EQ), E);
15483 return Success(IsGreater, E);
15485 return Success(IsEqual || IsLess, E);
15487 return Success(IsEqual || IsGreater, E);
15491 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
15500 LValue LHSValue, RHSValue;
15503 if (!LHSOK && !Info.noteFailure())
15512 if (Info.checkingPotentialConstantExpression() &&
15513 (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown))
15516 const Expr *LHSExpr = LHSValue.Base.
dyn_cast<
const Expr *>();
15517 const Expr *RHSExpr = RHSValue.Base.
dyn_cast<
const Expr *>();
15519 auto DiagArith = [&](
unsigned DiagID) {
15520 std::string LHS = LHSValue.toString(Info.Ctx, E->
getLHS()->
getType());
15521 std::string RHS = RHSValue.toString(Info.Ctx, E->
getRHS()->
getType());
15522 Info.FFDiag(E, DiagID) << LHS << RHS;
15523 if (LHSExpr && LHSExpr == RHSExpr)
15525 diag::note_constexpr_repeated_literal_eval)
15530 if (!LHSExpr || !RHSExpr)
15531 return DiagArith(diag::note_constexpr_pointer_arith_unspecified);
15534 return DiagArith(diag::note_constexpr_literal_arith);
15536 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
15537 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
15538 if (!LHSAddrExpr || !RHSAddrExpr)
15546 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
15547 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
15549 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
15550 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
15556 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid &&
15559 Info.CCEDiag(E, diag::note_constexpr_pointer_subtraction_not_same_array);
15564 CharUnits ElementSize;
15571 if (ElementSize.
isZero()) {
15572 Info.FFDiag(E, diag::note_constexpr_pointer_subtraction_zero_size)
15589 APSInt TrueResult = (LHS - RHS) / ElemSize;
15592 if (
Result.extend(65) != TrueResult &&
15598 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
15603bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr(
15604 const UnaryExprOrTypeTraitExpr *E) {
15606 case UETT_PreferredAlignOf:
15607 case UETT_AlignOf: {
15616 case UETT_PtrAuthTypeDiscriminator: {
15622 case UETT_VecStep: {
15626 unsigned n = Ty->
castAs<VectorType>()->getNumElements();
15638 case UETT_DataSizeOf:
15639 case UETT_SizeOf: {
15643 if (
const ReferenceType *Ref = SrcTy->
getAs<ReferenceType>())
15654 case UETT_OpenMPRequiredSimdAlign:
15661 case UETT_VectorElements: {
15665 if (
const auto *VT = Ty->
getAs<VectorType>())
15669 if (Info.InConstantContext)
15670 Info.CCEDiag(E, diag::note_constexpr_non_const_vectorelements)
15675 case UETT_CountOf: {
15681 if (
const auto *CAT =
15693 if (VAT->getElementType()->isArrayType()) {
15696 if (!VAT->getSizeExpr()) {
15701 std::optional<APSInt> Res =
15702 VAT->getSizeExpr()->getIntegerConstantExpr(Info.Ctx);
15708 Res->getZExtValue()};
15720 llvm_unreachable(
"unknown expr/type trait");
15723bool IntExprEvaluator::VisitOffsetOfExpr(
const OffsetOfExpr *OOE) {
15729 for (
unsigned i = 0; i != n; ++i) {
15742 Result += IdxResult.getSExtValue() * ElementSize;
15747 FieldDecl *MemberDecl = ON.
getField();
15754 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
15761 llvm_unreachable(
"dependent __builtin_offsetof");
15764 CXXBaseSpecifier *BaseSpec = ON.
getBase();
15776 CurrentType = BaseSpec->
getType();
15790bool IntExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
15809 if (Info.checkingForUndefinedBehavior())
15811 diag::warn_integer_constant_overflow)
15839bool IntExprEvaluator::VisitCastExpr(
const CastExpr *E) {
15841 QualType DestType = E->
getType();
15842 QualType SrcType = SubExpr->
getType();
15845 case CK_BaseToDerived:
15846 case CK_DerivedToBase:
15847 case CK_UncheckedDerivedToBase:
15850 case CK_ArrayToPointerDecay:
15851 case CK_FunctionToPointerDecay:
15852 case CK_NullToPointer:
15853 case CK_NullToMemberPointer:
15854 case CK_BaseToDerivedMemberPointer:
15855 case CK_DerivedToBaseMemberPointer:
15856 case CK_ReinterpretMemberPointer:
15857 case CK_ConstructorConversion:
15858 case CK_IntegralToPointer:
15860 case CK_VectorSplat:
15861 case CK_IntegralToFloating:
15862 case CK_FloatingCast:
15863 case CK_CPointerToObjCPointerCast:
15864 case CK_BlockPointerToObjCPointerCast:
15865 case CK_AnyPointerToBlockPointerCast:
15866 case CK_ObjCObjectLValueCast:
15867 case CK_FloatingRealToComplex:
15868 case CK_FloatingComplexToReal:
15869 case CK_FloatingComplexCast:
15870 case CK_FloatingComplexToIntegralComplex:
15871 case CK_IntegralRealToComplex:
15872 case CK_IntegralComplexCast:
15873 case CK_IntegralComplexToFloatingComplex:
15874 case CK_BuiltinFnToFnPtr:
15875 case CK_ZeroToOCLOpaqueType:
15876 case CK_NonAtomicToAtomic:
15877 case CK_AddressSpaceConversion:
15878 case CK_IntToOCLSampler:
15879 case CK_FloatingToFixedPoint:
15880 case CK_FixedPointToFloating:
15881 case CK_FixedPointCast:
15882 case CK_IntegralToFixedPoint:
15883 case CK_MatrixCast:
15884 case CK_HLSLAggregateSplatCast:
15885 llvm_unreachable(
"invalid cast kind for integral value");
15889 case CK_LValueBitCast:
15890 case CK_ARCProduceObject:
15891 case CK_ARCConsumeObject:
15892 case CK_ARCReclaimReturnedObject:
15893 case CK_ARCExtendBlockObject:
15894 case CK_CopyAndAutoreleaseBlockObject:
15897 case CK_UserDefinedConversion:
15898 case CK_LValueToRValue:
15899 case CK_AtomicToNonAtomic:
15901 case CK_LValueToRValueBitCast:
15902 case CK_HLSLArrayRValue:
15903 case CK_HLSLElementwiseCast:
15904 return ExprEvaluatorBaseTy::VisitCastExpr(E);
15906 case CK_MemberPointerToBoolean:
15907 case CK_PointerToBoolean:
15908 case CK_IntegralToBoolean:
15909 case CK_FloatingToBoolean:
15910 case CK_BooleanToSignedIntegral:
15911 case CK_FloatingComplexToBoolean:
15912 case CK_IntegralComplexToBoolean: {
15917 if (BoolResult && E->
getCastKind() == CK_BooleanToSignedIntegral)
15919 return Success(IntResult, E);
15922 case CK_FixedPointToIntegral: {
15927 llvm::APSInt
Result = Src.convertToInt(
15935 case CK_FixedPointToBoolean: {
15938 if (!
Evaluate(Val, Info, SubExpr))
15943 case CK_IntegralCast: {
15944 if (!Visit(SubExpr))
15953 if (
Result.isAddrLabelDiff())
15971 if (!ED->isFixed()) {
15975 ED->getValueRange(
Max,
Min);
15978 if (ED->getNumNegativeBits() &&
15979 (
Max.slt(
Result.getInt().getSExtValue()) ||
15980 Min.sgt(
Result.getInt().getSExtValue())))
15981 Info.CCEDiag(E, diag::note_constexpr_unscoped_enum_out_of_range)
15982 << llvm::toString(
Result.getInt(), 10) <<
Min.getSExtValue()
15983 <<
Max.getSExtValue() << ED;
15984 else if (!ED->getNumNegativeBits() &&
15985 Max.ult(
Result.getInt().getZExtValue()))
15986 Info.CCEDiag(E, diag::note_constexpr_unscoped_enum_out_of_range)
15987 << llvm::toString(
Result.getInt(), 10) <<
Min.getZExtValue()
15988 <<
Max.getZExtValue() << ED;
15996 case CK_PointerToIntegral: {
15997 CCEDiag(E, diag::note_constexpr_invalid_cast)
15998 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
16005 if (LV.getLValueBase()) {
16013 LV.Designator.setInvalid();
16021 if (!
V.toIntegralConstant(AsInt, SrcType, Info.Ctx))
16022 llvm_unreachable(
"Can't cast this!");
16027 case CK_IntegralComplexToReal: {
16031 return Success(
C.getComplexIntReal(), E);
16034 case CK_FloatingToIntegral: {
16044 case CK_HLSLVectorTruncation: {
16052 llvm_unreachable(
"unknown cast resulting in integral value");
16055bool IntExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
16060 if (!LV.isComplexInt())
16062 return Success(LV.getComplexIntReal(), E);
16068bool IntExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
16073 if (!LV.isComplexInt())
16075 return Success(LV.getComplexIntImag(), E);
16082bool IntExprEvaluator::VisitSizeOfPackExpr(
const SizeOfPackExpr *E) {
16086bool IntExprEvaluator::VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E) {
16090bool IntExprEvaluator::VisitConceptSpecializationExpr(
16091 const ConceptSpecializationExpr *E) {
16095bool IntExprEvaluator::VisitRequiresExpr(
const RequiresExpr *E) {
16099bool FixedPointExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
16109 if (!
Result.isFixedPoint())
16112 APFixedPoint Negated =
Result.getFixedPoint().negate(&Overflowed);
16126bool FixedPointExprEvaluator::VisitCastExpr(
const CastExpr *E) {
16128 QualType DestType = E->
getType();
16130 "Expected destination type to be a fixed point type");
16134 case CK_FixedPointCast: {
16139 APFixedPoint
Result = Src.convert(DestFXSema, &Overflowed);
16141 if (Info.checkingForUndefinedBehavior())
16143 diag::warn_fixedpoint_constant_overflow)
16150 case CK_IntegralToFixedPoint: {
16156 APFixedPoint IntResult = APFixedPoint::getFromIntValue(
16160 if (Info.checkingForUndefinedBehavior())
16162 diag::warn_fixedpoint_constant_overflow)
16163 << IntResult.toString() << E->
getType();
16168 return Success(IntResult, E);
16170 case CK_FloatingToFixedPoint: {
16176 APFixedPoint
Result = APFixedPoint::getFromFloatValue(
16180 if (Info.checkingForUndefinedBehavior())
16182 diag::warn_fixedpoint_constant_overflow)
16191 case CK_LValueToRValue:
16192 return ExprEvaluatorBaseTy::VisitCastExpr(E);
16198bool FixedPointExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
16200 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
16202 const Expr *LHS = E->
getLHS();
16203 const Expr *RHS = E->
getRHS();
16214 bool OpOverflow =
false, ConversionOverflow =
false;
16215 APFixedPoint
Result(LHSFX.getSemantics());
16218 Result = LHSFX.add(RHSFX, &OpOverflow)
16219 .convert(ResultFXSema, &ConversionOverflow);
16223 Result = LHSFX.sub(RHSFX, &OpOverflow)
16224 .convert(ResultFXSema, &ConversionOverflow);
16228 Result = LHSFX.mul(RHSFX, &OpOverflow)
16229 .convert(ResultFXSema, &ConversionOverflow);
16233 if (RHSFX.getValue() == 0) {
16234 Info.FFDiag(E, diag::note_expr_divide_by_zero);
16237 Result = LHSFX.div(RHSFX, &OpOverflow)
16238 .convert(ResultFXSema, &ConversionOverflow);
16244 llvm::APSInt RHSVal = RHSFX.getValue();
16247 LHSSema.getWidth() - (unsigned)LHSSema.hasUnsignedPadding();
16248 unsigned Amt = RHSVal.getLimitedValue(ShiftBW - 1);
16252 if (RHSVal.isNegative())
16253 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHSVal;
16254 else if (Amt != RHSVal)
16255 Info.CCEDiag(E, diag::note_constexpr_large_shift)
16256 << RHSVal << E->
getType() << ShiftBW;
16259 Result = LHSFX.shl(Amt, &OpOverflow);
16261 Result = LHSFX.shr(Amt, &OpOverflow);
16267 if (OpOverflow || ConversionOverflow) {
16268 if (Info.checkingForUndefinedBehavior())
16270 diag::warn_fixedpoint_constant_overflow)
16283class FloatExprEvaluator
16284 :
public ExprEvaluatorBase<FloatExprEvaluator> {
16287 FloatExprEvaluator(EvalInfo &info, APFloat &result)
16288 : ExprEvaluatorBaseTy(info),
Result(result) {}
16295 bool ZeroInitialization(
const Expr *E) {
16300 bool VisitCallExpr(
const CallExpr *E);
16302 bool VisitUnaryOperator(
const UnaryOperator *E);
16303 bool VisitBinaryOperator(
const BinaryOperator *E);
16304 bool VisitFloatingLiteral(
const FloatingLiteral *E);
16305 bool VisitCastExpr(
const CastExpr *E);
16307 bool VisitUnaryReal(
const UnaryOperator *E);
16308 bool VisitUnaryImag(
const UnaryOperator *E);
16317 return FloatExprEvaluator(Info, Result).Visit(E);
16324 llvm::APFloat &Result) {
16326 if (!S)
return false;
16328 const llvm::fltSemantics &Sem = Context.getFloatTypeSemantics(ResultTy);
16334 fill = llvm::APInt(32, 0);
16335 else if (S->
getString().getAsInteger(0, fill))
16338 if (Context.getTargetInfo().isNan2008()) {
16340 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
16342 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
16350 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
16352 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
16358bool FloatExprEvaluator::VisitCallExpr(
const CallExpr *E) {
16359 if (!IsConstantEvaluatedBuiltinCall(E))
16360 return ExprEvaluatorBaseTy::VisitCallExpr(E);
16366 case Builtin::BI__builtin_huge_val:
16367 case Builtin::BI__builtin_huge_valf:
16368 case Builtin::BI__builtin_huge_vall:
16369 case Builtin::BI__builtin_huge_valf16:
16370 case Builtin::BI__builtin_huge_valf128:
16371 case Builtin::BI__builtin_inf:
16372 case Builtin::BI__builtin_inff:
16373 case Builtin::BI__builtin_infl:
16374 case Builtin::BI__builtin_inff16:
16375 case Builtin::BI__builtin_inff128: {
16376 const llvm::fltSemantics &Sem =
16378 Result = llvm::APFloat::getInf(Sem);
16382 case Builtin::BI__builtin_nans:
16383 case Builtin::BI__builtin_nansf:
16384 case Builtin::BI__builtin_nansl:
16385 case Builtin::BI__builtin_nansf16:
16386 case Builtin::BI__builtin_nansf128:
16392 case Builtin::BI__builtin_nan:
16393 case Builtin::BI__builtin_nanf:
16394 case Builtin::BI__builtin_nanl:
16395 case Builtin::BI__builtin_nanf16:
16396 case Builtin::BI__builtin_nanf128:
16404 case Builtin::BI__builtin_elementwise_abs:
16405 case Builtin::BI__builtin_fabs:
16406 case Builtin::BI__builtin_fabsf:
16407 case Builtin::BI__builtin_fabsl:
16408 case Builtin::BI__builtin_fabsf128:
16417 if (
Result.isNegative())
16421 case Builtin::BI__arithmetic_fence:
16428 case Builtin::BI__builtin_copysign:
16429 case Builtin::BI__builtin_copysignf:
16430 case Builtin::BI__builtin_copysignl:
16431 case Builtin::BI__builtin_copysignf128: {
16440 case Builtin::BI__builtin_fmax:
16441 case Builtin::BI__builtin_fmaxf:
16442 case Builtin::BI__builtin_fmaxl:
16443 case Builtin::BI__builtin_fmaxf16:
16444 case Builtin::BI__builtin_fmaxf128: {
16453 case Builtin::BI__builtin_fmin:
16454 case Builtin::BI__builtin_fminf:
16455 case Builtin::BI__builtin_fminl:
16456 case Builtin::BI__builtin_fminf16:
16457 case Builtin::BI__builtin_fminf128: {
16466 case Builtin::BI__builtin_fmaximum_num:
16467 case Builtin::BI__builtin_fmaximum_numf:
16468 case Builtin::BI__builtin_fmaximum_numl:
16469 case Builtin::BI__builtin_fmaximum_numf16:
16470 case Builtin::BI__builtin_fmaximum_numf128: {
16479 case Builtin::BI__builtin_fminimum_num:
16480 case Builtin::BI__builtin_fminimum_numf:
16481 case Builtin::BI__builtin_fminimum_numl:
16482 case Builtin::BI__builtin_fminimum_numf16:
16483 case Builtin::BI__builtin_fminimum_numf128: {
16492 case Builtin::BI__builtin_elementwise_fma: {
16497 APFloat SourceY(0.), SourceZ(0.);
16503 (void)
Result.fusedMultiplyAdd(SourceY, SourceZ, RM);
16509bool FloatExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
16521bool FloatExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
16532 Result = llvm::APFloat::getZero(Sem);
16536bool FloatExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
16538 default:
return Error(E);
16552bool FloatExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
16554 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
16558 if (!LHSOK && !Info.noteFailure())
16564bool FloatExprEvaluator::VisitFloatingLiteral(
const FloatingLiteral *E) {
16569bool FloatExprEvaluator::VisitCastExpr(
const CastExpr *E) {
16574 return ExprEvaluatorBaseTy::VisitCastExpr(E);
16576 case CK_IntegralToFloating: {
16585 case CK_FixedPointToFloating: {
16594 case CK_FloatingCast: {
16595 if (!Visit(SubExpr))
16601 case CK_FloatingComplexToReal: {
16605 Result =
V.getComplexFloatReal();
16608 case CK_HLSLVectorTruncation: {
16622class ComplexExprEvaluator
16623 :
public ExprEvaluatorBase<ComplexExprEvaluator> {
16627 ComplexExprEvaluator(EvalInfo &info, ComplexValue &
Result)
16635 bool ZeroInitialization(
const Expr *E);
16641 bool VisitImaginaryLiteral(
const ImaginaryLiteral *E);
16642 bool VisitCastExpr(
const CastExpr *E);
16643 bool VisitBinaryOperator(
const BinaryOperator *E);
16644 bool VisitUnaryOperator(
const UnaryOperator *E);
16645 bool VisitInitListExpr(
const InitListExpr *E);
16646 bool VisitCallExpr(
const CallExpr *E);
16654 return ComplexExprEvaluator(Info, Result).Visit(E);
16657bool ComplexExprEvaluator::ZeroInitialization(
const Expr *E) {
16658 QualType ElemTy = E->
getType()->
castAs<ComplexType>()->getElementType();
16660 Result.makeComplexFloat();
16665 Result.makeComplexInt();
16673bool ComplexExprEvaluator::VisitImaginaryLiteral(
const ImaginaryLiteral *E) {
16677 Result.makeComplexFloat();
16686 "Unexpected imaginary literal.");
16688 Result.makeComplexInt();
16693 Result.IntReal =
APSInt(Imag.getBitWidth(), !Imag.isSigned());
16698bool ComplexExprEvaluator::VisitCastExpr(
const CastExpr *E) {
16702 case CK_BaseToDerived:
16703 case CK_DerivedToBase:
16704 case CK_UncheckedDerivedToBase:
16707 case CK_ArrayToPointerDecay:
16708 case CK_FunctionToPointerDecay:
16709 case CK_NullToPointer:
16710 case CK_NullToMemberPointer:
16711 case CK_BaseToDerivedMemberPointer:
16712 case CK_DerivedToBaseMemberPointer:
16713 case CK_MemberPointerToBoolean:
16714 case CK_ReinterpretMemberPointer:
16715 case CK_ConstructorConversion:
16716 case CK_IntegralToPointer:
16717 case CK_PointerToIntegral:
16718 case CK_PointerToBoolean:
16720 case CK_VectorSplat:
16721 case CK_IntegralCast:
16722 case CK_BooleanToSignedIntegral:
16723 case CK_IntegralToBoolean:
16724 case CK_IntegralToFloating:
16725 case CK_FloatingToIntegral:
16726 case CK_FloatingToBoolean:
16727 case CK_FloatingCast:
16728 case CK_CPointerToObjCPointerCast:
16729 case CK_BlockPointerToObjCPointerCast:
16730 case CK_AnyPointerToBlockPointerCast:
16731 case CK_ObjCObjectLValueCast:
16732 case CK_FloatingComplexToReal:
16733 case CK_FloatingComplexToBoolean:
16734 case CK_IntegralComplexToReal:
16735 case CK_IntegralComplexToBoolean:
16736 case CK_ARCProduceObject:
16737 case CK_ARCConsumeObject:
16738 case CK_ARCReclaimReturnedObject:
16739 case CK_ARCExtendBlockObject:
16740 case CK_CopyAndAutoreleaseBlockObject:
16741 case CK_BuiltinFnToFnPtr:
16742 case CK_ZeroToOCLOpaqueType:
16743 case CK_NonAtomicToAtomic:
16744 case CK_AddressSpaceConversion:
16745 case CK_IntToOCLSampler:
16746 case CK_FloatingToFixedPoint:
16747 case CK_FixedPointToFloating:
16748 case CK_FixedPointCast:
16749 case CK_FixedPointToBoolean:
16750 case CK_FixedPointToIntegral:
16751 case CK_IntegralToFixedPoint:
16752 case CK_MatrixCast:
16753 case CK_HLSLVectorTruncation:
16754 case CK_HLSLElementwiseCast:
16755 case CK_HLSLAggregateSplatCast:
16756 llvm_unreachable(
"invalid cast kind for complex value");
16758 case CK_LValueToRValue:
16759 case CK_AtomicToNonAtomic:
16761 case CK_LValueToRValueBitCast:
16762 case CK_HLSLArrayRValue:
16763 return ExprEvaluatorBaseTy::VisitCastExpr(E);
16766 case CK_LValueBitCast:
16767 case CK_UserDefinedConversion:
16770 case CK_FloatingRealToComplex: {
16775 Result.makeComplexFloat();
16780 case CK_FloatingComplexCast: {
16784 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
16792 case CK_FloatingComplexToIntegralComplex: {
16796 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
16799 Result.makeComplexInt();
16806 case CK_IntegralRealToComplex: {
16811 Result.makeComplexInt();
16812 Result.IntImag =
APSInt(Real.getBitWidth(), !Real.isSigned());
16816 case CK_IntegralComplexCast: {
16820 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
16829 case CK_IntegralComplexToFloatingComplex: {
16835 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
16838 Result.makeComplexFloat();
16840 To,
Result.FloatReal) &&
16846 llvm_unreachable(
"unknown cast resulting in complex value");
16850 APFloat &ResR, APFloat &ResI) {
16856 APFloat AC = A *
C;
16857 APFloat BD = B * D;
16858 APFloat AD = A * D;
16859 APFloat BC = B *
C;
16862 if (ResR.isNaN() && ResI.isNaN()) {
16863 bool Recalc =
false;
16864 if (A.isInfinity() || B.isInfinity()) {
16865 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
16867 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
16870 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
16872 D = APFloat::copySign(APFloat(D.getSemantics()), D);
16875 if (
C.isInfinity() || D.isInfinity()) {
16876 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
16878 D = APFloat::copySign(APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0),
16881 A = APFloat::copySign(APFloat(A.getSemantics()), A);
16883 B = APFloat::copySign(APFloat(B.getSemantics()), B);
16886 if (!Recalc && (AC.isInfinity() || BD.isInfinity() || AD.isInfinity() ||
16887 BC.isInfinity())) {
16889 A = APFloat::copySign(APFloat(A.getSemantics()), A);
16891 B = APFloat::copySign(APFloat(B.getSemantics()), B);
16893 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
16895 D = APFloat::copySign(APFloat(D.getSemantics()), D);
16899 ResR = APFloat::getInf(A.getSemantics()) * (A *
C - B * D);
16900 ResI = APFloat::getInf(A.getSemantics()) * (A * D + B *
C);
16906 APFloat &ResR, APFloat &ResI) {
16913 APFloat MaxCD = maxnum(
abs(
C),
abs(D));
16914 if (MaxCD.isFinite()) {
16915 DenomLogB =
ilogb(MaxCD);
16916 C =
scalbn(
C, -DenomLogB, APFloat::rmNearestTiesToEven);
16917 D =
scalbn(D, -DenomLogB, APFloat::rmNearestTiesToEven);
16919 APFloat Denom =
C *
C + D * D;
16921 scalbn((A *
C + B * D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
16923 scalbn((B *
C - A * D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
16924 if (ResR.isNaN() && ResI.isNaN()) {
16925 if (Denom.isPosZero() && (!A.isNaN() || !B.isNaN())) {
16926 ResR = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * A;
16927 ResI = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * B;
16928 }
else if ((A.isInfinity() || B.isInfinity()) &&
C.isFinite() &&
16930 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
16932 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
16934 ResR = APFloat::getInf(ResR.getSemantics()) * (A *
C + B * D);
16935 ResI = APFloat::getInf(ResI.getSemantics()) * (B *
C - A * D);
16936 }
else if (MaxCD.isInfinity() && A.isFinite() && B.isFinite()) {
16937 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
16939 D = APFloat::copySign(APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0),
16941 ResR = APFloat::getZero(ResR.getSemantics()) * (A *
C + B * D);
16942 ResI = APFloat::getZero(ResI.getSemantics()) * (B *
C - A * D);
16947bool ComplexExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
16949 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
16953 bool LHSReal =
false, RHSReal =
false;
16961 Result.makeComplexFloat();
16965 LHSOK = Visit(E->
getLHS());
16967 if (!LHSOK && !Info.noteFailure())
16973 APFloat &Real = RHS.FloatReal;
16976 RHS.makeComplexFloat();
16977 RHS.FloatImag =
APFloat(Real.getSemantics());
16981 assert(!(LHSReal && RHSReal) &&
16982 "Cannot have both operands of a complex operation be real.");
16984 default:
return Error(E);
16986 if (
Result.isComplexFloat()) {
16987 Result.getComplexFloatReal().add(RHS.getComplexFloatReal(),
16988 APFloat::rmNearestTiesToEven);
16990 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
16992 Result.getComplexFloatImag().add(RHS.getComplexFloatImag(),
16993 APFloat::rmNearestTiesToEven);
16995 Result.getComplexIntReal() += RHS.getComplexIntReal();
16996 Result.getComplexIntImag() += RHS.getComplexIntImag();
17000 if (
Result.isComplexFloat()) {
17001 Result.getComplexFloatReal().subtract(RHS.getComplexFloatReal(),
17002 APFloat::rmNearestTiesToEven);
17004 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
17005 Result.getComplexFloatImag().changeSign();
17006 }
else if (!RHSReal) {
17007 Result.getComplexFloatImag().subtract(RHS.getComplexFloatImag(),
17008 APFloat::rmNearestTiesToEven);
17011 Result.getComplexIntReal() -= RHS.getComplexIntReal();
17012 Result.getComplexIntImag() -= RHS.getComplexIntImag();
17016 if (
Result.isComplexFloat()) {
17021 ComplexValue LHS =
Result;
17022 APFloat &A = LHS.getComplexFloatReal();
17023 APFloat &B = LHS.getComplexFloatImag();
17024 APFloat &
C = RHS.getComplexFloatReal();
17025 APFloat &D = RHS.getComplexFloatImag();
17029 assert(!RHSReal &&
"Cannot have two real operands for a complex op!");
17037 }
else if (RHSReal) {
17049 ComplexValue LHS =
Result;
17050 Result.getComplexIntReal() =
17051 (LHS.getComplexIntReal() * RHS.getComplexIntReal() -
17052 LHS.getComplexIntImag() * RHS.getComplexIntImag());
17053 Result.getComplexIntImag() =
17054 (LHS.getComplexIntReal() * RHS.getComplexIntImag() +
17055 LHS.getComplexIntImag() * RHS.getComplexIntReal());
17059 if (
Result.isComplexFloat()) {
17064 ComplexValue LHS =
Result;
17065 APFloat &A = LHS.getComplexFloatReal();
17066 APFloat &B = LHS.getComplexFloatImag();
17067 APFloat &
C = RHS.getComplexFloatReal();
17068 APFloat &D = RHS.getComplexFloatImag();
17082 B = APFloat::getZero(A.getSemantics());
17087 ComplexValue LHS =
Result;
17088 APSInt Den = RHS.getComplexIntReal() * RHS.getComplexIntReal() +
17089 RHS.getComplexIntImag() * RHS.getComplexIntImag();
17091 return Error(E, diag::note_expr_divide_by_zero);
17093 Result.getComplexIntReal() =
17094 (LHS.getComplexIntReal() * RHS.getComplexIntReal() +
17095 LHS.getComplexIntImag() * RHS.getComplexIntImag()) / Den;
17096 Result.getComplexIntImag() =
17097 (LHS.getComplexIntImag() * RHS.getComplexIntReal() -
17098 LHS.getComplexIntReal() * RHS.getComplexIntImag()) / Den;
17106bool ComplexExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
17120 if (
Result.isComplexFloat()) {
17121 Result.getComplexFloatReal().changeSign();
17122 Result.getComplexFloatImag().changeSign();
17125 Result.getComplexIntReal() = -
Result.getComplexIntReal();
17126 Result.getComplexIntImag() = -
Result.getComplexIntImag();
17130 if (
Result.isComplexFloat())
17131 Result.getComplexFloatImag().changeSign();
17133 Result.getComplexIntImag() = -
Result.getComplexIntImag();
17138bool ComplexExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
17141 Result.makeComplexFloat();
17147 Result.makeComplexInt();
17155 return ExprEvaluatorBaseTy::VisitInitListExpr(E);
17158bool ComplexExprEvaluator::VisitCallExpr(
const CallExpr *E) {
17159 if (!IsConstantEvaluatedBuiltinCall(E))
17160 return ExprEvaluatorBaseTy::VisitCallExpr(E);
17163 case Builtin::BI__builtin_complex:
17164 Result.makeComplexFloat();
17182class AtomicExprEvaluator :
17183 public ExprEvaluatorBase<AtomicExprEvaluator> {
17184 const LValue *
This;
17187 AtomicExprEvaluator(EvalInfo &Info,
const LValue *This,
APValue &
Result)
17195 bool ZeroInitialization(
const Expr *E) {
17196 ImplicitValueInitExpr VIE(
17204 bool VisitCastExpr(
const CastExpr *E) {
17207 return ExprEvaluatorBaseTy::VisitCastExpr(E);
17208 case CK_NullToPointer:
17210 return ZeroInitialization(E);
17211 case CK_NonAtomicToAtomic:
17223 return AtomicExprEvaluator(Info,
This, Result).Visit(E);
17232class VoidExprEvaluator
17233 :
public ExprEvaluatorBase<VoidExprEvaluator> {
17235 VoidExprEvaluator(EvalInfo &Info) : ExprEvaluatorBaseTy(Info) {}
17239 bool ZeroInitialization(
const Expr *E) {
return true; }
17241 bool VisitCastExpr(
const CastExpr *E) {
17244 return ExprEvaluatorBaseTy::VisitCastExpr(E);
17251 bool VisitCallExpr(
const CallExpr *E) {
17252 if (!IsConstantEvaluatedBuiltinCall(E))
17253 return ExprEvaluatorBaseTy::VisitCallExpr(E);
17256 case Builtin::BI__assume:
17257 case Builtin::BI__builtin_assume:
17261 case Builtin::BI__builtin_operator_delete:
17269 bool VisitCXXDeleteExpr(
const CXXDeleteExpr *E);
17273bool VoidExprEvaluator::VisitCXXDeleteExpr(
const CXXDeleteExpr *E) {
17275 if (Info.SpeculativeEvaluationDepth)
17279 if (!OperatorDelete
17280 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
17281 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
17291 if (
Pointer.Designator.Invalid)
17295 if (
Pointer.isNullPointer()) {
17299 if (!Info.getLangOpts().CPlusPlus20)
17300 Info.CCEDiag(E, diag::note_constexpr_new);
17308 QualType AllocType =
Pointer.Base.getDynamicAllocType();
17314 Info.FFDiag(E, diag::note_constexpr_delete_base_nonvirt_dtor)
17323 if (VirtualDelete &&
17325 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
17326 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
17333 (*Alloc)->Value, AllocType))
17336 if (!Info.HeapAllocs.erase(
Pointer.Base.dyn_cast<DynamicAllocLValue>())) {
17341 Info.FFDiag(E, diag::note_constexpr_double_delete);
17351 return VoidExprEvaluator(Info).Visit(E);
17363 if (E->
isGLValue() ||
T->isFunctionType()) {
17367 LV.moveInto(Result);
17368 }
else if (
T->isVectorType()) {
17371 }
else if (
T->isIntegralOrEnumerationType()) {
17372 if (!IntExprEvaluator(Info, Result).Visit(E))
17374 }
else if (
T->hasPointerRepresentation()) {
17378 LV.moveInto(Result);
17379 }
else if (
T->isRealFloatingType()) {
17380 llvm::APFloat F(0.0);
17384 }
else if (
T->isAnyComplexType()) {
17388 C.moveInto(Result);
17389 }
else if (
T->isFixedPointType()) {
17390 if (!FixedPointExprEvaluator(Info, Result).Visit(E))
return false;
17391 }
else if (
T->isMemberPointerType()) {
17395 P.moveInto(Result);
17397 }
else if (
T->isArrayType()) {
17400 Info.CurrentCall->createTemporary(E,
T, ScopeKind::FullExpression, LV);
17404 }
else if (
T->isRecordType()) {
17407 Info.CurrentCall->createTemporary(E,
T, ScopeKind::FullExpression, LV);
17411 }
else if (
T->isVoidType()) {
17412 if (!Info.getLangOpts().CPlusPlus11)
17413 Info.CCEDiag(E, diag::note_constexpr_nonliteral)
17417 }
else if (
T->isAtomicType()) {
17418 QualType Unqual =
T.getAtomicUnqualifiedType();
17422 E, Unqual, ScopeKind::FullExpression, LV);
17430 }
else if (Info.getLangOpts().CPlusPlus11) {
17431 Info.FFDiag(E, diag::note_constexpr_nonliteral) << E->
getType();
17434 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
17445 const Expr *E,
bool AllowNonLiteralTypes) {
17461 if (
T->isArrayType())
17463 else if (
T->isRecordType())
17465 else if (
T->isAtomicType()) {
17466 QualType Unqual =
T.getAtomicUnqualifiedType();
17487 if (Info.EnableNewConstInterp) {
17491 ConstantExprKind::Normal);
17500 LV.setFrom(Info.Ctx, Result);
17507 ConstantExprKind::Normal) &&
17515 if (
const auto *L = dyn_cast<IntegerLiteral>(Exp)) {
17517 APValue(
APSInt(L->getValue(), L->getType()->isUnsignedIntegerType()));
17522 if (
const auto *L = dyn_cast<CXXBoolLiteralExpr>(Exp)) {
17528 if (
const auto *FL = dyn_cast<FloatingLiteral>(Exp)) {
17529 Result =
APValue(FL->getValue());
17534 if (
const auto *L = dyn_cast<CharacterLiteral>(Exp)) {
17540 if (
const auto *CE = dyn_cast<ConstantExpr>(Exp)) {
17541 if (CE->hasAPValueResult()) {
17542 APValue APV = CE->getAPValueResult();
17544 Result = std::move(APV);
17620 bool InConstantContext)
const {
17622 "Expression evaluator can't be called on a dependent expression.");
17623 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsRValue");
17625 Info.InConstantContext = InConstantContext;
17626 return ::EvaluateAsRValue(
this,
Result, Ctx, Info);
17630 bool InConstantContext)
const {
17632 "Expression evaluator can't be called on a dependent expression.");
17633 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsBooleanCondition");
17641 bool InConstantContext)
const {
17643 "Expression evaluator can't be called on a dependent expression.");
17644 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsInt");
17646 Info.InConstantContext = InConstantContext;
17647 return ::EvaluateAsInt(
this,
Result, Ctx, AllowSideEffects, Info);
17652 bool InConstantContext)
const {
17654 "Expression evaluator can't be called on a dependent expression.");
17655 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFixedPoint");
17657 Info.InConstantContext = InConstantContext;
17658 return ::EvaluateAsFixedPoint(
this,
Result, Ctx, AllowSideEffects, Info);
17663 bool InConstantContext)
const {
17665 "Expression evaluator can't be called on a dependent expression.");
17667 if (!
getType()->isRealFloatingType())
17670 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFloat");
17682 bool InConstantContext)
const {
17684 "Expression evaluator can't be called on a dependent expression.");
17686 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsLValue");
17688 Info.InConstantContext = InConstantContext;
17692 if (Info.EnableNewConstInterp) {
17694 ConstantExprKind::Normal))
17697 LV.setFrom(Ctx,
Result.Val);
17700 ConstantExprKind::Normal, CheckedTemps);
17703 if (!
EvaluateLValue(
this, LV, Info) || !Info.discardCleanups() ||
17704 Result.HasSideEffects ||
17707 ConstantExprKind::Normal, CheckedTemps))
17710 LV.moveInto(
Result.Val);
17717 bool IsConstantDestruction) {
17718 EvalInfo Info(Ctx, EStatus,
17721 Info.setEvaluatingDecl(
Base, DestroyedValue,
17722 EvalInfo::EvaluatingDeclKind::Dtor);
17723 Info.InConstantContext = IsConstantDestruction;
17732 if (!Info.discardCleanups())
17733 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
17741 "Expression evaluator can't be called on a dependent expression.");
17747 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsConstantExpr");
17749 EvalInfo Info(Ctx,
Result, EM);
17750 Info.InConstantContext =
true;
17752 if (Info.EnableNewConstInterp) {
17756 getStorageType(Ctx,
this),
Result.Val, Kind);
17761 if (Kind == ConstantExprKind::ClassTemplateArgument)
17777 FullExpressionRAII
Scope(Info);
17782 if (!Info.discardCleanups())
17783 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
17793 if (Kind == ConstantExprKind::ClassTemplateArgument &&
17796 Result.HasSideEffects)) {
17808 bool IsConstantInitialization)
const {
17810 "Expression evaluator can't be called on a dependent expression.");
17811 assert(VD &&
"Need a valid VarDecl");
17813 llvm::TimeTraceScope TimeScope(
"EvaluateAsInitializer", [&] {
17815 llvm::raw_string_ostream OS(Name);
17821 EStatus.
Diag = &Notes;
17823 EvalInfo Info(Ctx, EStatus,
17824 (IsConstantInitialization &&
17828 Info.setEvaluatingDecl(VD,
Value);
17829 Info.InConstantContext = IsConstantInitialization;
17834 if (Info.EnableNewConstInterp) {
17835 auto &InterpCtx =
const_cast<ASTContext &
>(Ctx).getInterpContext();
17836 if (!InterpCtx.evaluateAsInitializer(Info, VD,
this,
Value))
17840 ConstantExprKind::Normal);
17855 FullExpressionRAII
Scope(Info);
17858 EStatus.HasSideEffects)
17864 Info.performLifetimeExtension();
17866 if (!Info.discardCleanups())
17867 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
17871 ConstantExprKind::Normal) &&
17878 EStatus.
Diag = &Notes;
17895 IsConstantDestruction) ||
17907 "Expression evaluator can't be called on a dependent expression.");
17916 "Expression evaluator can't be called on a dependent expression.");
17918 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstInt");
17921 Info.InConstantContext =
true;
17925 assert(
Result &&
"Could not evaluate expression");
17926 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
17928 return EVResult.Val.getInt();
17934 "Expression evaluator can't be called on a dependent expression.");
17936 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstIntCheckOverflow");
17938 EVResult.Diag =
Diag;
17940 Info.InConstantContext =
true;
17941 Info.CheckingForUndefinedBehavior =
true;
17945 assert(
Result &&
"Could not evaluate expression");
17946 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
17948 return EVResult.Val.getInt();
17953 "Expression evaluator can't be called on a dependent expression.");
17955 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateForOverflow");
17960 Info.CheckingForUndefinedBehavior =
true;
17966 assert(
Val.isLValue());
17992 IK_ICEIfUnevaluated,
18008static ICEDiag
Worst(ICEDiag A, ICEDiag B) {
return A.Kind >= B.Kind ? A : B; }
18015 Info.InConstantContext =
true;
18024 assert(!E->
isValueDependent() &&
"Should not see value dependent exprs!");
18029#define ABSTRACT_STMT(Node)
18030#define STMT(Node, Base) case Expr::Node##Class:
18031#define EXPR(Node, Base)
18032#include "clang/AST/StmtNodes.inc"
18033 case Expr::PredefinedExprClass:
18034 case Expr::FloatingLiteralClass:
18035 case Expr::ImaginaryLiteralClass:
18036 case Expr::StringLiteralClass:
18037 case Expr::ArraySubscriptExprClass:
18038 case Expr::MatrixSubscriptExprClass:
18039 case Expr::ArraySectionExprClass:
18040 case Expr::OMPArrayShapingExprClass:
18041 case Expr::OMPIteratorExprClass:
18042 case Expr::MemberExprClass:
18043 case Expr::CompoundAssignOperatorClass:
18044 case Expr::CompoundLiteralExprClass:
18045 case Expr::ExtVectorElementExprClass:
18046 case Expr::DesignatedInitExprClass:
18047 case Expr::ArrayInitLoopExprClass:
18048 case Expr::ArrayInitIndexExprClass:
18049 case Expr::NoInitExprClass:
18050 case Expr::DesignatedInitUpdateExprClass:
18051 case Expr::ImplicitValueInitExprClass:
18052 case Expr::ParenListExprClass:
18053 case Expr::VAArgExprClass:
18054 case Expr::AddrLabelExprClass:
18055 case Expr::StmtExprClass:
18056 case Expr::CXXMemberCallExprClass:
18057 case Expr::CUDAKernelCallExprClass:
18058 case Expr::CXXAddrspaceCastExprClass:
18059 case Expr::CXXDynamicCastExprClass:
18060 case Expr::CXXTypeidExprClass:
18061 case Expr::CXXUuidofExprClass:
18062 case Expr::MSPropertyRefExprClass:
18063 case Expr::MSPropertySubscriptExprClass:
18064 case Expr::CXXNullPtrLiteralExprClass:
18065 case Expr::UserDefinedLiteralClass:
18066 case Expr::CXXThisExprClass:
18067 case Expr::CXXThrowExprClass:
18068 case Expr::CXXNewExprClass:
18069 case Expr::CXXDeleteExprClass:
18070 case Expr::CXXPseudoDestructorExprClass:
18071 case Expr::UnresolvedLookupExprClass:
18072 case Expr::RecoveryExprClass:
18073 case Expr::DependentScopeDeclRefExprClass:
18074 case Expr::CXXConstructExprClass:
18075 case Expr::CXXInheritedCtorInitExprClass:
18076 case Expr::CXXStdInitializerListExprClass:
18077 case Expr::CXXBindTemporaryExprClass:
18078 case Expr::ExprWithCleanupsClass:
18079 case Expr::CXXTemporaryObjectExprClass:
18080 case Expr::CXXUnresolvedConstructExprClass:
18081 case Expr::CXXDependentScopeMemberExprClass:
18082 case Expr::UnresolvedMemberExprClass:
18083 case Expr::ObjCStringLiteralClass:
18084 case Expr::ObjCBoxedExprClass:
18085 case Expr::ObjCArrayLiteralClass:
18086 case Expr::ObjCDictionaryLiteralClass:
18087 case Expr::ObjCEncodeExprClass:
18088 case Expr::ObjCMessageExprClass:
18089 case Expr::ObjCSelectorExprClass:
18090 case Expr::ObjCProtocolExprClass:
18091 case Expr::ObjCIvarRefExprClass:
18092 case Expr::ObjCPropertyRefExprClass:
18093 case Expr::ObjCSubscriptRefExprClass:
18094 case Expr::ObjCIsaExprClass:
18095 case Expr::ObjCAvailabilityCheckExprClass:
18096 case Expr::ShuffleVectorExprClass:
18097 case Expr::ConvertVectorExprClass:
18098 case Expr::BlockExprClass:
18100 case Expr::OpaqueValueExprClass:
18101 case Expr::PackExpansionExprClass:
18102 case Expr::SubstNonTypeTemplateParmPackExprClass:
18103 case Expr::FunctionParmPackExprClass:
18104 case Expr::AsTypeExprClass:
18105 case Expr::ObjCIndirectCopyRestoreExprClass:
18106 case Expr::MaterializeTemporaryExprClass:
18107 case Expr::PseudoObjectExprClass:
18108 case Expr::AtomicExprClass:
18109 case Expr::LambdaExprClass:
18110 case Expr::CXXFoldExprClass:
18111 case Expr::CoawaitExprClass:
18112 case Expr::DependentCoawaitExprClass:
18113 case Expr::CoyieldExprClass:
18114 case Expr::SYCLUniqueStableNameExprClass:
18115 case Expr::CXXParenListInitExprClass:
18116 case Expr::HLSLOutArgExprClass:
18119 case Expr::InitListExprClass: {
18130 case Expr::SizeOfPackExprClass:
18131 case Expr::GNUNullExprClass:
18132 case Expr::SourceLocExprClass:
18133 case Expr::EmbedExprClass:
18134 case Expr::OpenACCAsteriskSizeExprClass:
18137 case Expr::PackIndexingExprClass:
18140 case Expr::SubstNonTypeTemplateParmExprClass:
18144 case Expr::ConstantExprClass:
18147 case Expr::ParenExprClass:
18149 case Expr::GenericSelectionExprClass:
18151 case Expr::IntegerLiteralClass:
18152 case Expr::FixedPointLiteralClass:
18153 case Expr::CharacterLiteralClass:
18154 case Expr::ObjCBoolLiteralExprClass:
18155 case Expr::CXXBoolLiteralExprClass:
18156 case Expr::CXXScalarValueInitExprClass:
18157 case Expr::TypeTraitExprClass:
18158 case Expr::ConceptSpecializationExprClass:
18159 case Expr::RequiresExprClass:
18160 case Expr::ArrayTypeTraitExprClass:
18161 case Expr::ExpressionTraitExprClass:
18162 case Expr::CXXNoexceptExprClass:
18164 case Expr::CallExprClass:
18165 case Expr::CXXOperatorCallExprClass: {
18174 case Expr::CXXRewrittenBinaryOperatorClass:
18177 case Expr::DeclRefExprClass: {
18191 const VarDecl *VD = dyn_cast<VarDecl>(D);
18198 case Expr::UnaryOperatorClass: {
18221 llvm_unreachable(
"invalid unary operator class");
18223 case Expr::OffsetOfExprClass: {
18232 case Expr::UnaryExprOrTypeTraitExprClass: {
18234 if ((Exp->
getKind() == UETT_SizeOf) &&
18237 if (Exp->
getKind() == UETT_CountOf) {
18244 if (VAT->getElementType()->isArrayType())
18256 case Expr::BinaryOperatorClass: {
18301 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE) {
18304 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
18305 if (REval.isSigned() && REval.isAllOnes()) {
18307 if (LEval.isMinSignedValue())
18308 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
18316 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE)
18317 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
18323 return Worst(LHSResult, RHSResult);
18329 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICEIfUnevaluated) {
18339 return Worst(LHSResult, RHSResult);
18342 llvm_unreachable(
"invalid binary operator kind");
18344 case Expr::ImplicitCastExprClass:
18345 case Expr::CStyleCastExprClass:
18346 case Expr::CXXFunctionalCastExprClass:
18347 case Expr::CXXStaticCastExprClass:
18348 case Expr::CXXReinterpretCastExprClass:
18349 case Expr::CXXConstCastExprClass:
18350 case Expr::ObjCBridgedCastExprClass: {
18357 APSInt IgnoredVal(DestWidth, !DestSigned);
18362 if (FL->getValue().convertToInteger(IgnoredVal,
18363 llvm::APFloat::rmTowardZero,
18364 &Ignored) & APFloat::opInvalidOp)
18370 case CK_LValueToRValue:
18371 case CK_AtomicToNonAtomic:
18372 case CK_NonAtomicToAtomic:
18374 case CK_IntegralToBoolean:
18375 case CK_IntegralCast:
18381 case Expr::BinaryConditionalOperatorClass: {
18384 if (CommonResult.Kind == IK_NotICE)
return CommonResult;
18386 if (FalseResult.Kind == IK_NotICE)
return FalseResult;
18387 if (CommonResult.Kind == IK_ICEIfUnevaluated)
return CommonResult;
18388 if (FalseResult.Kind == IK_ICEIfUnevaluated &&
18390 return FalseResult;
18392 case Expr::ConditionalOperatorClass: {
18400 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
18403 if (CondResult.Kind == IK_NotICE)
18409 if (TrueResult.Kind == IK_NotICE)
18411 if (FalseResult.Kind == IK_NotICE)
18412 return FalseResult;
18413 if (CondResult.Kind == IK_ICEIfUnevaluated)
18415 if (TrueResult.Kind == IK_ICE && FalseResult.Kind == IK_ICE)
18421 return FalseResult;
18424 case Expr::CXXDefaultArgExprClass:
18426 case Expr::CXXDefaultInitExprClass:
18428 case Expr::ChooseExprClass: {
18431 case Expr::BuiltinBitCastExprClass: {
18432 if (!checkBitCastConstexprEligibility(
nullptr, Ctx,
cast<CastExpr>(E)))
18438 llvm_unreachable(
"Invalid StmtClass!");
18444 llvm::APSInt *
Value) {
18452 if (!Result.isInt())
18461 "Expression evaluator can't be called on a dependent expression.");
18463 ExprTimeTraceScope TimeScope(
this, Ctx,
"isIntegerConstantExpr");
18469 if (D.Kind != IK_ICE)
18474std::optional<llvm::APSInt>
18478 return std::nullopt;
18485 return std::nullopt;
18489 return std::nullopt;
18498 Info.InConstantContext =
true;
18501 llvm_unreachable(
"ICE cannot be evaluated!");
18508 "Expression evaluator can't be called on a dependent expression.");
18510 return CheckICE(
this, Ctx).Kind == IK_ICE;
18515 "Expression evaluator can't be called on a dependent expression.");
18532 Status.Diag = &Diags;
18539 Info.discardCleanups() && !Status.HasSideEffects;
18541 return IsConstExpr && Diags.empty();
18549 "Expression evaluator can't be called on a dependent expression.");
18551 llvm::TimeTraceScope TimeScope(
"EvaluateWithSubstitution", [&] {
18553 llvm::raw_string_ostream OS(Name);
18561 Info.InConstantContext =
true;
18564 const LValue *ThisPtr =
nullptr;
18567 auto *MD = dyn_cast<CXXMethodDecl>(Callee);
18568 assert(MD &&
"Don't provide `this` for non-methods.");
18569 assert(MD->isImplicitObjectMemberFunction() &&
18570 "Don't provide `this` for methods without an implicit object.");
18572 if (!
This->isValueDependent() &&
18575 ThisPtr = &ThisVal;
18582 CallRef
Call = Info.CurrentCall->createCall(Callee);
18585 unsigned Idx = I - Args.begin();
18586 if (Idx >= Callee->getNumParams())
18588 const ParmVarDecl *PVD = Callee->getParamDecl(Idx);
18589 if ((*I)->isValueDependent() ||
18593 if (
APValue *Slot = Info.getParamSlot(
Call, PVD))
18604 Info.discardCleanups();
18608 CallStackFrame Frame(Info, Callee->getLocation(), Callee, ThisPtr,
This,
18611 FullExpressionRAII
Scope(Info);
18625 llvm::TimeTraceScope TimeScope(
"isPotentialConstantExpr", [&] {
18627 llvm::raw_string_ostream OS(Name);
18634 Status.
Diag = &Diags;
18638 Info.InConstantContext =
true;
18639 Info.CheckingPotentialConstantExpression =
true;
18642 if (Info.EnableNewConstInterp) {
18644 return Diags.empty();
18655 This.set({&VIE, Info.CurrentCall->Index});
18663 Info.setEvaluatingDecl(
This.getLValueBase(), Scratch);
18669 &VIE, Args, CallRef(), FD->
getBody(), Info, Scratch,
18673 return Diags.empty();
18681 "Expression evaluator can't be called on a dependent expression.");
18684 Status.
Diag = &Diags;
18688 Info.InConstantContext =
true;
18689 Info.CheckingPotentialConstantExpression =
true;
18691 if (Info.EnableNewConstInterp) {
18693 return Diags.empty();
18698 nullptr, CallRef());
18702 return Diags.empty();
18706 unsigned Type)
const {
18707 if (!
getType()->isPointerType())
18716 EvalInfo &Info, std::string *StringResult) {
18728 if (
const StringLiteral *S = dyn_cast_or_null<StringLiteral>(
18729 String.getLValueBase().dyn_cast<
const Expr *>())) {
18732 if (Off >= 0 && (uint64_t)Off <= (uint64_t)Str.size() &&
18736 Str = Str.substr(Off);
18738 StringRef::size_type Pos = Str.find(0);
18739 if (Pos != StringRef::npos)
18740 Str = Str.substr(0, Pos);
18742 Result = Str.size();
18744 *StringResult = Str;
18752 for (uint64_t Strlen = 0; ; ++Strlen) {
18760 }
else if (StringResult)
18761 StringResult->push_back(Char.
getInt().getExtValue());
18771 std::string StringResult;
18774 return StringResult;
18778template <
typename T>
18780 const Expr *SizeExpression,
18781 const Expr *PtrExpression,
18785 Info.InConstantContext =
true;
18787 if (Info.EnableNewConstInterp)
18789 PtrExpression, Result);
18792 FullExpressionRAII
Scope(Info);
18797 uint64_t Size = SizeValue.getZExtValue();
18800 if constexpr (std::is_same_v<APValue, T>)
18803 if (Size < Result.max_size())
18804 Result.reserve(Size);
18810 for (uint64_t I = 0; I < Size; ++I) {
18816 if constexpr (std::is_same_v<APValue, T>) {
18817 Result.getArrayInitializedElt(I) = std::move(Char);
18821 assert(
C.getBitWidth() <= 8 &&
18822 "string element not representable in char");
18824 Result.push_back(
static_cast<char>(
C.getExtValue()));
18835 const Expr *SizeExpression,
18839 PtrExpression, Ctx, Status);
18843 const Expr *SizeExpression,
18847 PtrExpression, Ctx, Status);
18854 if (Info.EnableNewConstInterp)
18861struct IsWithinLifetimeHandler {
18864 using result_type = std::optional<bool>;
18865 std::optional<bool> failed() {
return std::nullopt; }
18866 template <
typename T>
18867 std::optional<bool> found(
T &Subobj,
QualType SubobjType) {
18872std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &IEE,
18873 const CallExpr *E) {
18874 EvalInfo &Info = IEE.Info;
18879 if (!Info.InConstantContext)
18880 return std::nullopt;
18882 const Expr *Arg = E->
getArg(0);
18884 return std::nullopt;
18887 return std::nullopt;
18889 if (Val.allowConstexprUnknown())
18893 bool CalledFromStd =
false;
18894 const auto *
Callee = Info.CurrentCall->getCallee();
18895 if (Callee &&
Callee->isInStdNamespace()) {
18896 const IdentifierInfo *Identifier =
Callee->getIdentifier();
18897 CalledFromStd = Identifier && Identifier->
isStr(
"is_within_lifetime");
18899 Info.CCEDiag(CalledFromStd ? Info.CurrentCall->getCallRange().getBegin()
18901 diag::err_invalid_is_within_lifetime)
18902 << (CalledFromStd ?
"std::is_within_lifetime"
18903 :
"__builtin_is_within_lifetime")
18905 return std::nullopt;
18915 if (Val.isNullPointer() || Val.getLValueBase().isNull())
18917 QualType
T = Val.getLValueBase().getType();
18919 "Pointers to functions should have been typed as function pointers "
18920 "which would have been rejected earlier");
18923 if (Val.getLValueDesignator().isOnePastTheEnd())
18925 assert(Val.getLValueDesignator().isValidSubobject() &&
18926 "Unchecked case for valid subobject");
18930 CompleteObject CO =
18934 if (Info.EvaluatingDeclValue && CO.Value == Info.EvaluatingDeclValue)
18939 IsWithinLifetimeHandler handler{Info};
18940 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 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)