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) {
743 static bool isEqual(
const ObjectUnderConstruction &LHS, {
…}
733template<>
struct DenseMapInfo<ObjectUnderConstruction> {
…};
758 const Expr *AllocExpr =
nullptr;
769 if (
auto *NE = dyn_cast<CXXNewExpr>(AllocExpr))
770 return NE->isArray() ? ArrayNew : New;
776 struct DynAllocOrder {
777 bool operator()(DynamicAllocLValue L, DynamicAllocLValue R)
const {
801 Expr::EvalStatus &EvalStatus;
804 CallStackFrame *CurrentCall;
807 unsigned CallStackDepth;
810 unsigned NextCallIndex;
819 bool EnableNewConstInterp;
823 CallStackFrame BottomFrame;
827 llvm::SmallVector<Cleanup, 16> CleanupStack;
831 APValue::LValueBase EvaluatingDecl;
833 enum class EvaluatingDeclKind {
840 EvaluatingDeclKind IsEvaluatingDecl = EvaluatingDeclKind::None;
849 SmallVector<const Stmt *> BreakContinueStack;
852 llvm::DenseMap<ObjectUnderConstruction, ConstructionPhase>
853 ObjectsUnderConstruction;
858 std::map<DynamicAllocLValue, DynAlloc, DynAllocOrder> HeapAllocs;
861 unsigned NumHeapAllocs = 0;
863 struct EvaluatingConstructorRAII {
865 ObjectUnderConstruction Object;
867 EvaluatingConstructorRAII(EvalInfo &EI, ObjectUnderConstruction Object,
869 : EI(EI), Object(Object) {
871 EI.ObjectsUnderConstruction
872 .insert({Object, HasBases ? ConstructionPhase::Bases
873 : ConstructionPhase::AfterBases})
876 void finishedConstructingBases() {
877 EI.ObjectsUnderConstruction[Object] = ConstructionPhase::AfterBases;
879 void finishedConstructingFields() {
880 EI.ObjectsUnderConstruction[Object] = ConstructionPhase::AfterFields;
882 ~EvaluatingConstructorRAII() {
883 if (DidInsert) EI.ObjectsUnderConstruction.erase(Object);
887 struct EvaluatingDestructorRAII {
889 ObjectUnderConstruction Object;
891 EvaluatingDestructorRAII(EvalInfo &EI, ObjectUnderConstruction Object)
892 : EI(EI), Object(Object) {
893 DidInsert = EI.ObjectsUnderConstruction
894 .insert({Object, ConstructionPhase::Destroying})
897 void startedDestroyingBases() {
898 EI.ObjectsUnderConstruction[Object] =
899 ConstructionPhase::DestroyingBases;
901 ~EvaluatingDestructorRAII() {
903 EI.ObjectsUnderConstruction.erase(Object);
908 isEvaluatingCtorDtor(APValue::LValueBase Base,
909 ArrayRef<APValue::LValuePathEntry> Path) {
910 return ObjectsUnderConstruction.lookup({
Base, Path});
915 unsigned SpeculativeEvaluationDepth = 0;
923 bool HasActiveDiagnostic;
927 bool HasFoldFailureDiagnostic;
929 EvalInfo(
const ASTContext &
C, Expr::EvalStatus &S,
EvaluationMode Mode)
930 : Ctx(const_cast<ASTContext &>(
C)), EvalStatus(S), CurrentCall(
nullptr),
931 CallStackDepth(0), NextCallIndex(1),
932 StepsLeft(
C.getLangOpts().ConstexprStepLimit),
933 EnableNewConstInterp(
C.getLangOpts().EnableNewConstInterp),
934 BottomFrame(*this, SourceLocation(),
nullptr,
937 EvaluatingDecl((const ValueDecl *)
nullptr),
938 EvaluatingDeclValue(
nullptr), HasActiveDiagnostic(
false),
939 HasFoldFailureDiagnostic(
false) {
947 ASTContext &getASTContext()
const override {
return Ctx; }
948 const LangOptions &getLangOpts()
const {
return Ctx.getLangOpts(); }
950 void setEvaluatingDecl(APValue::LValueBase Base,
APValue &
Value,
951 EvaluatingDeclKind EDK = EvaluatingDeclKind::Ctor) {
952 EvaluatingDecl =
Base;
953 IsEvaluatingDecl = EDK;
954 EvaluatingDeclValue = &
Value;
957 bool CheckCallLimit(SourceLocation Loc) {
960 if (checkingPotentialConstantExpression() && CallStackDepth > 1)
962 if (NextCallIndex == 0) {
964 FFDiag(Loc, diag::note_constexpr_call_limit_exceeded);
967 if (CallStackDepth <= getLangOpts().ConstexprCallDepth)
969 FFDiag(Loc, diag::note_constexpr_depth_limit_exceeded)
970 << getLangOpts().ConstexprCallDepth;
975 uint64_t ElemCount,
bool Diag) {
981 ElemCount >
uint64_t(std::numeric_limits<unsigned>::max())) {
983 FFDiag(Loc, diag::note_constexpr_new_too_large) << ElemCount;
992 uint64_t Limit = Ctx.getLangOpts().ConstexprStepLimit;
993 if (ElemCount > Limit) {
995 FFDiag(Loc, diag::note_constexpr_new_exceeds_limits)
996 << ElemCount << Limit;
1002 std::pair<CallStackFrame *, unsigned>
1003 getCallFrameAndDepth(
unsigned CallIndex) {
1004 assert(CallIndex &&
"no call index in getCallFrameAndDepth");
1007 unsigned Depth = CallStackDepth;
1008 CallStackFrame *Frame = CurrentCall;
1009 while (Frame->Index > CallIndex) {
1010 Frame = Frame->Caller;
1013 if (Frame->Index == CallIndex)
1014 return {Frame, Depth};
1015 return {
nullptr, 0};
1018 bool nextStep(
const Stmt *S) {
1020 FFDiag(S->
getBeginLoc(), diag::note_constexpr_step_limit_exceeded);
1027 APValue *createHeapAlloc(
const Expr *E, QualType
T, LValue &LV);
1029 std::optional<DynAlloc *> lookupDynamicAlloc(DynamicAllocLValue DA) {
1030 std::optional<DynAlloc *>
Result;
1031 auto It = HeapAllocs.find(DA);
1032 if (It != HeapAllocs.end())
1038 APValue *getParamSlot(CallRef
Call,
const ParmVarDecl *PVD) {
1039 CallStackFrame *Frame = getCallFrameAndDepth(
Call.CallIndex).first;
1040 return Frame ? Frame->getTemporary(
Call.getOrigParam(PVD),
Call.Version)
1045 struct StdAllocatorCaller {
1046 unsigned FrameIndex;
1049 explicit operator bool()
const {
return FrameIndex != 0; };
1052 StdAllocatorCaller getStdAllocatorCaller(StringRef FnName)
const {
1053 for (
const CallStackFrame *
Call = CurrentCall;
Call != &BottomFrame;
1055 const auto *MD = dyn_cast_or_null<CXXMethodDecl>(
Call->Callee);
1058 const IdentifierInfo *FnII = MD->getIdentifier();
1059 if (!FnII || !FnII->
isStr(FnName))
1063 dyn_cast<ClassTemplateSpecializationDecl>(MD->getParent());
1067 const IdentifierInfo *ClassII = CTSD->getIdentifier();
1068 const TemplateArgumentList &TAL = CTSD->getTemplateArgs();
1069 if (CTSD->isInStdNamespace() && ClassII &&
1070 ClassII->
isStr(
"allocator") && TAL.
size() >= 1 &&
1072 return {
Call->Index, TAL[0].getAsType(),
Call->CallExpr};
1078 void performLifetimeExtension() {
1080 llvm::erase_if(CleanupStack, [](Cleanup &
C) {
1081 return !
C.isDestroyedAtEndOf(ScopeKind::FullExpression);
1088 bool discardCleanups() {
1089 for (Cleanup &
C : CleanupStack) {
1090 if (
C.hasSideEffect() && !noteSideEffect()) {
1091 CleanupStack.clear();
1095 CleanupStack.clear();
1100 interp::Frame *getCurrentFrame()
override {
return CurrentCall; }
1101 const interp::Frame *getBottomFrame()
const override {
return &BottomFrame; }
1103 bool hasActiveDiagnostic()
override {
return HasActiveDiagnostic; }
1104 void setActiveDiagnostic(
bool Flag)
override { HasActiveDiagnostic = Flag; }
1106 void setFoldFailureDiagnostic(
bool Flag)
override {
1107 HasFoldFailureDiagnostic = Flag;
1110 Expr::EvalStatus &getEvalStatus()
const override {
return EvalStatus; }
1118 bool hasPriorDiagnostic()
override {
1119 if (!EvalStatus.Diag->empty()) {
1121 case EvaluationMode::ConstantFold:
1122 case EvaluationMode::IgnoreSideEffects:
1123 if (!HasFoldFailureDiagnostic)
1127 case EvaluationMode::ConstantExpression:
1128 case EvaluationMode::ConstantExpressionUnevaluated:
1129 setActiveDiagnostic(
false);
1136 unsigned getCallStackDepth()
override {
return CallStackDepth; }
1141 bool keepEvaluatingAfterSideEffect()
const override {
1143 case EvaluationMode::IgnoreSideEffects:
1146 case EvaluationMode::ConstantExpression:
1147 case EvaluationMode::ConstantExpressionUnevaluated:
1148 case EvaluationMode::ConstantFold:
1151 return checkingPotentialConstantExpression() ||
1152 checkingForUndefinedBehavior();
1154 llvm_unreachable(
"Missed EvalMode case");
1159 bool noteSideEffect()
override {
1160 EvalStatus.HasSideEffects =
true;
1161 return keepEvaluatingAfterSideEffect();
1165 bool keepEvaluatingAfterUndefinedBehavior() {
1167 case EvaluationMode::IgnoreSideEffects:
1168 case EvaluationMode::ConstantFold:
1171 case EvaluationMode::ConstantExpression:
1172 case EvaluationMode::ConstantExpressionUnevaluated:
1173 return checkingForUndefinedBehavior();
1175 llvm_unreachable(
"Missed EvalMode case");
1181 bool noteUndefinedBehavior()
override {
1182 EvalStatus.HasUndefinedBehavior =
true;
1183 return keepEvaluatingAfterUndefinedBehavior();
1188 bool keepEvaluatingAfterFailure()
const override {
1193 case EvaluationMode::ConstantExpression:
1194 case EvaluationMode::ConstantExpressionUnevaluated:
1195 case EvaluationMode::ConstantFold:
1196 case EvaluationMode::IgnoreSideEffects:
1197 return checkingPotentialConstantExpression() ||
1198 checkingForUndefinedBehavior();
1200 llvm_unreachable(
"Missed EvalMode case");
1213 [[nodiscard]]
bool noteFailure() {
1221 bool KeepGoing = keepEvaluatingAfterFailure();
1222 EvalStatus.HasSideEffects |= KeepGoing;
1226 class ArrayInitLoopIndex {
1231 ArrayInitLoopIndex(EvalInfo &Info)
1232 : Info(Info), OuterIndex(Info.ArrayInitIndex) {
1233 Info.ArrayInitIndex = 0;
1235 ~ArrayInitLoopIndex() { Info.ArrayInitIndex = OuterIndex; }
1237 operator uint64_t&() {
return Info.ArrayInitIndex; }
1242 struct FoldConstant {
1245 bool HadNoPriorDiags;
1248 explicit FoldConstant(EvalInfo &Info,
bool Enabled)
1251 HadNoPriorDiags(Info.EvalStatus.
Diag &&
1252 Info.EvalStatus.
Diag->empty() &&
1253 !Info.EvalStatus.HasSideEffects),
1254 OldMode(Info.EvalMode) {
1256 Info.EvalMode = EvaluationMode::ConstantFold;
1258 void keepDiagnostics() { Enabled =
false; }
1260 if (Enabled && HadNoPriorDiags && !Info.EvalStatus.Diag->empty() &&
1261 !Info.EvalStatus.HasSideEffects)
1262 Info.EvalStatus.Diag->clear();
1263 Info.EvalMode = OldMode;
1269 struct IgnoreSideEffectsRAII {
1272 explicit IgnoreSideEffectsRAII(EvalInfo &Info)
1273 : Info(Info), OldMode(Info.EvalMode) {
1274 Info.EvalMode = EvaluationMode::IgnoreSideEffects;
1277 ~IgnoreSideEffectsRAII() { Info.EvalMode = OldMode; }
1282 class SpeculativeEvaluationRAII {
1283 EvalInfo *Info =
nullptr;
1284 Expr::EvalStatus OldStatus;
1285 unsigned OldSpeculativeEvaluationDepth = 0;
1287 void moveFromAndCancel(SpeculativeEvaluationRAII &&
Other) {
1289 OldStatus =
Other.OldStatus;
1290 OldSpeculativeEvaluationDepth =
Other.OldSpeculativeEvaluationDepth;
1291 Other.Info =
nullptr;
1294 void maybeRestoreState() {
1298 Info->EvalStatus = OldStatus;
1299 Info->SpeculativeEvaluationDepth = OldSpeculativeEvaluationDepth;
1303 SpeculativeEvaluationRAII() =
default;
1305 SpeculativeEvaluationRAII(
1306 EvalInfo &Info, SmallVectorImpl<PartialDiagnosticAt> *NewDiag =
nullptr)
1307 : Info(&Info), OldStatus(Info.EvalStatus),
1308 OldSpeculativeEvaluationDepth(Info.SpeculativeEvaluationDepth) {
1309 Info.EvalStatus.Diag = NewDiag;
1310 Info.SpeculativeEvaluationDepth = Info.CallStackDepth + 1;
1313 SpeculativeEvaluationRAII(
const SpeculativeEvaluationRAII &
Other) =
delete;
1314 SpeculativeEvaluationRAII(SpeculativeEvaluationRAII &&
Other) {
1315 moveFromAndCancel(std::move(
Other));
1318 SpeculativeEvaluationRAII &operator=(SpeculativeEvaluationRAII &&
Other) {
1319 maybeRestoreState();
1320 moveFromAndCancel(std::move(
Other));
1324 ~SpeculativeEvaluationRAII() { maybeRestoreState(); }
1329 template<ScopeKind Kind>
1332 unsigned OldStackSize;
1334 ScopeRAII(EvalInfo &Info)
1335 : Info(Info), OldStackSize(Info.CleanupStack.size()) {
1338 Info.CurrentCall->pushTempVersion();
1340 bool destroy(
bool RunDestructors =
true) {
1341 bool OK =
cleanup(Info, RunDestructors, OldStackSize);
1342 OldStackSize = std::numeric_limits<unsigned>::max();
1346 if (OldStackSize != std::numeric_limits<unsigned>::max())
1350 Info.CurrentCall->popTempVersion();
1353 static bool cleanup(EvalInfo &Info,
bool RunDestructors,
1354 unsigned OldStackSize) {
1355 assert(OldStackSize <= Info.CleanupStack.size() &&
1356 "running cleanups out of order?");
1361 for (
unsigned I = Info.CleanupStack.size(); I > OldStackSize; --I) {
1362 if (Info.CleanupStack[I - 1].isDestroyedAtEndOf(Kind)) {
1363 if (!Info.CleanupStack[I - 1].endLifetime(Info, RunDestructors)) {
1371 auto NewEnd = Info.CleanupStack.begin() + OldStackSize;
1372 if (Kind != ScopeKind::Block)
1374 std::remove_if(NewEnd, Info.CleanupStack.end(), [](Cleanup &
C) {
1375 return C.isDestroyedAtEndOf(Kind);
1377 Info.CleanupStack.erase(NewEnd, Info.CleanupStack.end());
1381 typedef ScopeRAII<ScopeKind::Block> BlockScopeRAII;
1382 typedef ScopeRAII<ScopeKind::FullExpression> FullExpressionRAII;
1383 typedef ScopeRAII<ScopeKind::Call> CallScopeRAII;
1386bool SubobjectDesignator::checkSubobject(EvalInfo &Info,
const Expr *E,
1390 if (isOnePastTheEnd()) {
1391 Info.CCEDiag(E, diag::note_constexpr_past_end_subobject)
1402void SubobjectDesignator::diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info,
1404 Info.CCEDiag(E, diag::note_constexpr_unsized_array_indexed);
1409void SubobjectDesignator::diagnosePointerArithmetic(EvalInfo &Info,
1414 if (MostDerivedPathLength == Entries.size() && MostDerivedIsArrayElement)
1415 Info.CCEDiag(E, diag::note_constexpr_array_index)
1417 <<
static_cast<unsigned>(getMostDerivedArraySize());
1419 Info.CCEDiag(E, diag::note_constexpr_array_index)
1424CallStackFrame::CallStackFrame(EvalInfo &Info, SourceRange CallRange,
1425 const FunctionDecl *Callee,
const LValue *This,
1426 const Expr *CallExpr, CallRef Call)
1428 CallExpr(CallExpr),
Arguments(Call), CallRange(CallRange),
1429 Index(Info.NextCallIndex++) {
1430 Info.CurrentCall =
this;
1431 ++Info.CallStackDepth;
1434CallStackFrame::~CallStackFrame() {
1435 assert(Info.CurrentCall ==
this &&
"calls retired out of order");
1436 --Info.CallStackDepth;
1437 Info.CurrentCall = Caller;
1462 llvm_unreachable(
"unknown access kind");
1499 llvm_unreachable(
"unknown access kind");
1503 struct ComplexValue {
1511 ComplexValue() : FloatReal(
APFloat::Bogus()), FloatImag(
APFloat::Bogus()) {}
1513 void makeComplexFloat() { IsInt =
false; }
1514 bool isComplexFloat()
const {
return !IsInt; }
1515 APFloat &getComplexFloatReal() {
return FloatReal; }
1516 APFloat &getComplexFloatImag() {
return FloatImag; }
1518 void makeComplexInt() { IsInt =
true; }
1519 bool isComplexInt()
const {
return IsInt; }
1520 APSInt &getComplexIntReal() {
return IntReal; }
1521 APSInt &getComplexIntImag() {
return IntImag; }
1523 void moveInto(
APValue &v)
const {
1524 if (isComplexFloat())
1525 v =
APValue(FloatReal, FloatImag);
1527 v =
APValue(IntReal, IntImag);
1529 void setFrom(
const APValue &v) {
1544 APValue::LValueBase
Base;
1546 SubobjectDesignator Designator;
1548 bool InvalidBase : 1;
1550 bool AllowConstexprUnknown =
false;
1552 const APValue::LValueBase getLValueBase()
const {
return Base; }
1553 bool allowConstexprUnknown()
const {
return AllowConstexprUnknown; }
1554 CharUnits &getLValueOffset() {
return Offset; }
1555 const CharUnits &getLValueOffset()
const {
return Offset; }
1556 SubobjectDesignator &getLValueDesignator() {
return Designator; }
1557 const SubobjectDesignator &getLValueDesignator()
const {
return Designator;}
1558 bool isNullPointer()
const {
return IsNullPtr;}
1560 unsigned getLValueCallIndex()
const {
return Base.getCallIndex(); }
1561 unsigned getLValueVersion()
const {
return Base.getVersion(); }
1564 if (Designator.Invalid)
1565 V =
APValue(Base, Offset, APValue::NoLValuePath(), IsNullPtr);
1567 assert(!InvalidBase &&
"APValues can't handle invalid LValue bases");
1568 V =
APValue(Base, Offset, Designator.Entries,
1569 Designator.IsOnePastTheEnd, IsNullPtr);
1571 if (AllowConstexprUnknown)
1572 V.setConstexprUnknown();
1574 void setFrom(
const ASTContext &Ctx,
const APValue &
V) {
1575 assert(
V.isLValue() &&
"Setting LValue from a non-LValue?");
1576 Base =
V.getLValueBase();
1577 Offset =
V.getLValueOffset();
1578 InvalidBase =
false;
1579 Designator = SubobjectDesignator(Ctx,
V);
1580 IsNullPtr =
V.isNullPointer();
1581 AllowConstexprUnknown =
V.allowConstexprUnknown();
1584 void set(APValue::LValueBase B,
bool BInvalid =
false) {
1588 const auto *E = B.
get<
const Expr *>();
1590 "Unexpected type of invalid base");
1596 InvalidBase = BInvalid;
1597 Designator = SubobjectDesignator(
getType(B));
1599 AllowConstexprUnknown =
false;
1602 void setNull(ASTContext &Ctx, QualType PointerTy) {
1603 Base = (
const ValueDecl *)
nullptr;
1606 InvalidBase =
false;
1609 AllowConstexprUnknown =
false;
1612 void setInvalid(APValue::LValueBase B,
unsigned I = 0) {
1616 std::string
toString(ASTContext &Ctx, QualType
T)
const {
1618 moveInto(Printable);
1625 template <
typename GenDiagType>
1626 bool checkNullPointerDiagnosingWith(
const GenDiagType &GenDiag) {
1627 if (Designator.Invalid)
1631 Designator.setInvalid();
1638 bool checkNullPointer(EvalInfo &Info,
const Expr *E,
1640 return checkNullPointerDiagnosingWith([&Info, E, CSK] {
1641 Info.CCEDiag(E, diag::note_constexpr_null_subobject) << CSK;
1645 bool checkNullPointerForFoldAccess(EvalInfo &Info,
const Expr *E,
1647 return checkNullPointerDiagnosingWith([&Info, E, AK] {
1648 if (AK == AccessKinds::AK_Dereference)
1649 Info.FFDiag(E, diag::note_constexpr_dereferencing_null);
1651 Info.FFDiag(E, diag::note_constexpr_access_null) << AK;
1659 Designator.checkSubobject(Info, E, CSK);
1662 void addDecl(EvalInfo &Info,
const Expr *E,
1663 const Decl *D,
bool Virtual =
false) {
1665 Designator.addDeclUnchecked(D,
Virtual);
1667 void addUnsizedArray(EvalInfo &Info,
const Expr *E, QualType ElemTy) {
1668 if (!Designator.Entries.empty()) {
1669 Info.CCEDiag(E, diag::note_constexpr_unsupported_unsized_array);
1670 Designator.setInvalid();
1674 assert(
getType(Base).getNonReferenceType()->isPointerType() ||
1675 getType(Base).getNonReferenceType()->isArrayType());
1676 Designator.FirstEntryIsAnUnsizedArray =
true;
1677 Designator.addUnsizedArrayUnchecked(ElemTy);
1680 void addArray(EvalInfo &Info,
const Expr *E,
const ConstantArrayType *CAT) {
1682 Designator.addArrayUnchecked(CAT);
1684 void addComplex(EvalInfo &Info,
const Expr *E, QualType EltTy,
bool Imag) {
1686 Designator.addComplexUnchecked(EltTy, Imag);
1688 void addVectorElement(EvalInfo &Info,
const Expr *E, QualType EltTy,
1689 uint64_t Size, uint64_t Idx) {
1691 Designator.addVectorElementUnchecked(EltTy, Size, Idx);
1693 void clearIsNullPointer() {
1696 void adjustOffsetAndIndex(EvalInfo &Info,
const Expr *E,
1697 const APSInt &Index, CharUnits ElementSize) {
1708 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
1712 Designator.adjustIndex(Info, E, Index, *
this);
1713 clearIsNullPointer();
1715 void adjustOffset(CharUnits N) {
1718 clearIsNullPointer();
1724 explicit MemberPtr(
const ValueDecl *Decl)
1725 : DeclAndIsDerivedMember(
Decl,
false) {}
1729 const ValueDecl *getDecl()
const {
1730 return DeclAndIsDerivedMember.getPointer();
1733 bool isDerivedMember()
const {
1734 return DeclAndIsDerivedMember.getInt();
1737 const CXXRecordDecl *getContainingRecord()
const {
1739 DeclAndIsDerivedMember.getPointer()->getDeclContext());
1743 V =
APValue(getDecl(), isDerivedMember(), Path);
1746 assert(
V.isMemberPointer());
1747 DeclAndIsDerivedMember.setPointer(
V.getMemberPointerDecl());
1748 DeclAndIsDerivedMember.setInt(
V.isMemberPointerToDerivedMember());
1750 llvm::append_range(Path,
V.getMemberPointerPath());
1756 llvm::PointerIntPair<const ValueDecl*, 1, bool> DeclAndIsDerivedMember;
1759 SmallVector<const CXXRecordDecl*, 4> Path;
1763 bool castBack(
const CXXRecordDecl *
Class) {
1764 assert(!Path.empty());
1765 const CXXRecordDecl *Expected;
1766 if (Path.size() >= 2)
1767 Expected = Path[Path.size() - 2];
1769 Expected = getContainingRecord();
1783 bool castToDerived(
const CXXRecordDecl *Derived) {
1786 if (!isDerivedMember()) {
1787 Path.push_back(Derived);
1790 if (!castBack(Derived))
1793 DeclAndIsDerivedMember.setInt(
false);
1801 DeclAndIsDerivedMember.setInt(
true);
1802 if (isDerivedMember()) {
1803 Path.push_back(Base);
1806 return castBack(Base);
1811 static bool operator==(
const MemberPtr &LHS,
const MemberPtr &RHS) {
1812 if (!LHS.getDecl() || !RHS.getDecl())
1813 return !LHS.getDecl() && !RHS.getDecl();
1814 if (LHS.getDecl()->getCanonicalDecl() != RHS.getDecl()->getCanonicalDecl())
1816 return LHS.Path == RHS.Path;
1820void SubobjectDesignator::adjustIndex(EvalInfo &Info,
const Expr *E,
APSInt N,
1824 uint64_t TruncatedN = N.extOrTrunc(64).getZExtValue();
1825 if (isMostDerivedAnUnsizedArray()) {
1826 diagnoseUnsizedArrayPointerArithmetic(Info, E);
1831 PathEntry::ArrayIndex(Entries.back().getAsArrayIndex() + TruncatedN);
1839 MostDerivedPathLength == Entries.size() && MostDerivedIsArrayElement;
1841 IsArray ? Entries.back().getAsArrayIndex() : (
uint64_t)IsOnePastTheEnd;
1844 if (N < -(int64_t)ArrayIndex || N > ArraySize - ArrayIndex) {
1845 if (!Info.checkingPotentialConstantExpression() ||
1846 !LV.AllowConstexprUnknown) {
1849 N = N.extend(std::max<unsigned>(N.getBitWidth() + 1, 65));
1850 (llvm::APInt &)N += ArrayIndex;
1851 assert(N.ugt(ArraySize) &&
"bounds check failed for in-bounds index");
1852 diagnosePointerArithmetic(Info, E, N);
1858 ArrayIndex += TruncatedN;
1859 assert(ArrayIndex <= ArraySize &&
1860 "bounds check succeeded for out-of-bounds index");
1863 Entries.back() = PathEntry::ArrayIndex(ArrayIndex);
1865 IsOnePastTheEnd = (ArrayIndex != 0);
1870 const LValue &This,
const Expr *E,
1871 bool AllowNonLiteralTypes =
false);
1873 bool InvalidBaseOK =
false);
1875 bool InvalidBaseOK =
false);
1883static bool EvaluateComplex(
const Expr *E, ComplexValue &Res, EvalInfo &Info);
1889 std::string *StringResult =
nullptr);
1906 if (Int.isUnsigned() || Int.isMinSignedValue()) {
1907 Int = Int.extend(Int.getBitWidth() + 1);
1908 Int.setIsSigned(
true);
1913template<
typename KeyT>
1914APValue &CallStackFrame::createTemporary(
const KeyT *Key, QualType
T,
1915 ScopeKind Scope, LValue &LV) {
1916 unsigned Version = getTempVersion();
1917 APValue::LValueBase
Base(Key, Index, Version);
1919 return createLocal(Base, Key,
T, Scope);
1923APValue &CallStackFrame::createParam(CallRef Args,
const ParmVarDecl *PVD,
1925 assert(Args.CallIndex == Index &&
"creating parameter in wrong frame");
1926 APValue::LValueBase
Base(PVD, Index, Args.Version);
1931 return createLocal(Base, PVD, PVD->
getType(), ScopeKind::Call);
1934APValue &CallStackFrame::createLocal(APValue::LValueBase Base,
const void *Key,
1935 QualType
T, ScopeKind Scope) {
1936 assert(
Base.getCallIndex() == Index &&
"lvalue for wrong frame");
1937 unsigned Version =
Base.getVersion();
1939 assert(
Result.isAbsent() &&
"local created multiple times");
1945 if (Index <= Info.SpeculativeEvaluationDepth) {
1946 if (
T.isDestructedType())
1947 Info.noteSideEffect();
1949 Info.CleanupStack.push_back(Cleanup(&
Result, Base,
T, Scope));
1954APValue *EvalInfo::createHeapAlloc(
const Expr *E, QualType
T, LValue &LV) {
1956 FFDiag(E, diag::note_constexpr_heap_alloc_limit_exceeded);
1960 DynamicAllocLValue DA(NumHeapAllocs++);
1962 auto Result = HeapAllocs.emplace(std::piecewise_construct,
1963 std::forward_as_tuple(DA), std::tuple<>());
1964 assert(
Result.second &&
"reused a heap alloc index?");
1965 Result.first->second.AllocExpr = E;
1966 return &
Result.first->second.Value;
1970void CallStackFrame::describe(raw_ostream &Out)
const {
1971 unsigned ArgIndex = 0;
1980 if (This && IsMemberCall) {
1981 if (
const auto *MCE = dyn_cast_if_present<CXXMemberCallExpr>(CallExpr)) {
1982 const Expr *
Object = MCE->getImplicitObjectArgument();
1985 if (
Object->getType()->isPointerType())
1989 }
else if (
const auto *OCE =
1990 dyn_cast_if_present<CXXOperatorCallExpr>(CallExpr)) {
1991 OCE->getArg(0)->printPretty(Out,
nullptr,
1997 This->moveInto(Val);
2005 IsMemberCall =
false;
2011 E =
Callee->param_end(); I != E; ++I, ++ArgIndex) {
2012 if (ArgIndex > (
unsigned)IsMemberCall)
2015 const ParmVarDecl *Param = *I;
2016 APValue *
V = Info.getParamSlot(Arguments, Param);
2018 V->printPretty(Out, Info.Ctx, Param->
getType());
2022 if (ArgIndex == 0 && IsMemberCall)
2037 return Info.noteSideEffect();
2044 return (
Builtin == Builtin::BI__builtin___CFStringMakeConstantString ||
2045 Builtin == Builtin::BI__builtin___NSStringMakeConstantString ||
2046 Builtin == Builtin::BI__builtin_ptrauth_sign_constant ||
2047 Builtin == Builtin::BI__builtin_function_start);
2051 const auto *BaseExpr =
2052 llvm::dyn_cast_if_present<CallExpr>(LVal.Base.
dyn_cast<
const Expr *>());
2067 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
2068 return VD->hasGlobalStorage();
2084 case Expr::CompoundLiteralExprClass: {
2088 case Expr::MaterializeTemporaryExprClass:
2093 case Expr::StringLiteralClass:
2094 case Expr::PredefinedExprClass:
2095 case Expr::ObjCStringLiteralClass:
2096 case Expr::ObjCEncodeExprClass:
2098 case Expr::ObjCBoxedExprClass:
2100 case Expr::CallExprClass:
2103 case Expr::AddrLabelExprClass:
2107 case Expr::BlockExprClass:
2111 case Expr::SourceLocExprClass:
2113 case Expr::ImplicitValueInitExprClass:
2138 const auto *BaseExpr = LVal.Base.
dyn_cast<
const Expr *>();
2143 if (
const auto *EE = dyn_cast<ObjCEncodeExpr>(BaseExpr)) {
2152 const auto *Lit = dyn_cast<StringLiteral>(BaseExpr);
2153 if (
const auto *PE = dyn_cast<PredefinedExpr>(BaseExpr))
2154 Lit = PE->getFunctionName();
2159 AsString.
Bytes = Lit->getBytes();
2160 AsString.
CharWidth = Lit->getCharByteWidth();
2180 const LValue &RHS) {
2189 CharUnits Offset = RHS.Offset - LHS.Offset;
2190 if (Offset.isNegative()) {
2191 if (LHSString.
Bytes.size() < (
size_t)-Offset.getQuantity())
2193 LHSString.
Bytes = LHSString.
Bytes.drop_front(-Offset.getQuantity());
2195 if (RHSString.
Bytes.size() < (
size_t)Offset.getQuantity())
2197 RHSString.
Bytes = RHSString.
Bytes.drop_front(Offset.getQuantity());
2200 bool LHSIsLonger = LHSString.
Bytes.size() > RHSString.
Bytes.size();
2201 StringRef Longer = LHSIsLonger ? LHSString.
Bytes : RHSString.
Bytes;
2202 StringRef Shorter = LHSIsLonger ? RHSString.
Bytes : LHSString.
Bytes;
2203 int ShorterCharWidth = (LHSIsLonger ? RHSString : LHSString).CharWidth;
2208 for (
int NullByte : llvm::seq(ShorterCharWidth)) {
2209 if (Shorter.size() + NullByte >= Longer.size())
2211 if (Longer[Shorter.size() + NullByte])
2217 return Shorter == Longer.take_front(Shorter.size());
2227 if (isa_and_nonnull<VarDecl>(
Decl)) {
2237 if (!A.getLValueBase())
2238 return !B.getLValueBase();
2239 if (!B.getLValueBase())
2242 if (A.getLValueBase().getOpaqueValue() !=
2243 B.getLValueBase().getOpaqueValue())
2246 return A.getLValueCallIndex() == B.getLValueCallIndex() &&
2247 A.getLValueVersion() == B.getLValueVersion();
2251 assert(
Base &&
"no location for a null lvalue");
2257 if (
auto *PVD = dyn_cast_or_null<ParmVarDecl>(VD)) {
2259 for (CallStackFrame *F = Info.CurrentCall; F; F = F->Caller) {
2260 if (F->Arguments.CallIndex ==
Base.getCallIndex() &&
2261 F->Arguments.Version ==
Base.getVersion() && F->Callee &&
2262 Idx < F->Callee->getNumParams()) {
2263 VD = F->Callee->getParamDecl(Idx);
2270 Info.Note(VD->
getLocation(), diag::note_declared_at);
2272 Info.Note(E->
getExprLoc(), diag::note_constexpr_temporary_here);
2275 if (std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA))
2276 Info.Note((*Alloc)->AllocExpr->getExprLoc(),
2277 diag::note_constexpr_dynamic_alloc_here);
2310 const SubobjectDesignator &
Designator = LVal.getLValueDesignator();
2318 if (isTemplateArgument(Kind)) {
2319 int InvalidBaseKind = -1;
2322 InvalidBaseKind = 0;
2323 else if (isa_and_nonnull<StringLiteral>(BaseE))
2324 InvalidBaseKind = 1;
2325 else if (isa_and_nonnull<MaterializeTemporaryExpr>(BaseE) ||
2326 isa_and_nonnull<LifetimeExtendedTemporaryDecl>(BaseVD))
2327 InvalidBaseKind = 2;
2328 else if (
auto *PE = dyn_cast_or_null<PredefinedExpr>(BaseE)) {
2329 InvalidBaseKind = 3;
2330 Ident = PE->getIdentKindName();
2333 if (InvalidBaseKind != -1) {
2334 Info.FFDiag(Loc, diag::note_constexpr_invalid_template_arg)
2335 << IsReferenceType << !
Designator.Entries.empty() << InvalidBaseKind
2341 if (
auto *FD = dyn_cast_or_null<FunctionDecl>(BaseVD);
2342 FD && FD->isImmediateFunction()) {
2343 Info.FFDiag(Loc, diag::note_consteval_address_accessible)
2345 Info.Note(FD->getLocation(), diag::note_declared_at);
2353 if (Info.getLangOpts().CPlusPlus11) {
2354 Info.FFDiag(Loc, diag::note_constexpr_non_global, 1)
2355 << IsReferenceType << !
Designator.Entries.empty() << !!BaseVD
2357 auto *VarD = dyn_cast_or_null<VarDecl>(BaseVD);
2358 if (VarD && VarD->isConstexpr()) {
2364 Info.Note(VarD->getLocation(), diag::note_constexpr_not_static)
2376 assert((Info.checkingPotentialConstantExpression() ||
2377 LVal.getLValueCallIndex() == 0) &&
2378 "have call index for global lvalue");
2380 if (LVal.allowConstexprUnknown()) {
2382 Info.FFDiag(Loc, diag::note_constexpr_var_init_non_constant, 1) << BaseVD;
2391 Info.FFDiag(Loc, diag::note_constexpr_dynamic_alloc)
2392 << IsReferenceType << !
Designator.Entries.empty();
2398 if (
const VarDecl *Var = dyn_cast<const VarDecl>(BaseVD)) {
2400 if (Var->getTLSKind())
2406 if (!isForManglingOnly(Kind) && Var->hasAttr<DLLImportAttr>())
2412 if (Info.getASTContext().getLangOpts().CUDA &&
2413 Info.getASTContext().getLangOpts().CUDAIsDevice &&
2414 Info.getASTContext().CUDAConstantEvalCtx.NoWrongSidedVars) {
2415 if ((!Var->hasAttr<CUDADeviceAttr>() &&
2416 !Var->hasAttr<CUDAConstantAttr>() &&
2417 !Var->getType()->isCUDADeviceBuiltinSurfaceType() &&
2418 !Var->getType()->isCUDADeviceBuiltinTextureType()) ||
2419 Var->hasAttr<HIPManagedAttr>())
2423 if (
const auto *FD = dyn_cast<const FunctionDecl>(BaseVD)) {
2434 if (Info.getLangOpts().CPlusPlus && !isForManglingOnly(Kind) &&
2435 FD->hasAttr<DLLImportAttr>())
2439 }
else if (
const auto *MTE =
2440 dyn_cast_or_null<MaterializeTemporaryExpr>(BaseE)) {
2441 if (CheckedTemps.insert(MTE).second) {
2444 Info.FFDiag(MTE->getExprLoc(),
2445 diag::note_constexpr_unsupported_temporary_nontrivial_dtor)
2450 APValue *
V = MTE->getOrCreateValue(
false);
2451 assert(
V &&
"evasluation result refers to uninitialised temporary");
2453 Info, MTE->getExprLoc(), TempType, *
V, Kind,
2454 nullptr, CheckedTemps))
2461 if (!IsReferenceType)
2473 Info.FFDiag(Loc, diag::note_constexpr_past_end, 1)
2474 << !
Designator.Entries.empty() << !!BaseVD << BaseVD;
2489 const auto *FD = dyn_cast_or_null<CXXMethodDecl>(
Member);
2492 if (FD->isImmediateFunction()) {
2493 Info.FFDiag(Loc, diag::note_consteval_address_accessible) << 0;
2494 Info.Note(FD->getLocation(), diag::note_declared_at);
2497 return isForManglingOnly(Kind) || FD->isVirtual() ||
2498 !FD->hasAttr<DLLImportAttr>();
2504 const LValue *
This =
nullptr) {
2506 if (Info.getLangOpts().CPlusPlus23)
2525 if (
This && Info.EvaluatingDecl ==
This->getLValueBase())
2529 if (Info.getLangOpts().CPlusPlus11)
2530 Info.FFDiag(E, diag::note_constexpr_nonliteral)
2533 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
2544 if (SubobjectDecl) {
2545 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
2546 << 1 << SubobjectDecl;
2548 diag::note_constexpr_subobject_declared_here);
2550 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
2559 Type = AT->getValueType();
2564 if (
Value.isArray()) {
2566 for (
unsigned I = 0, N =
Value.getArrayInitializedElts(); I != N; ++I) {
2568 Value.getArrayInitializedElt(I), Kind,
2569 SubobjectDecl, CheckedTemps))
2572 if (!
Value.hasArrayFiller())
2575 Value.getArrayFiller(), Kind, SubobjectDecl,
2578 if (
Value.isUnion() &&
Value.getUnionField()) {
2581 Value.getUnionValue(), Kind,
Value.getUnionField(), CheckedTemps);
2583 if (
Value.isStruct()) {
2585 if (
const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {
2586 unsigned BaseIndex = 0;
2588 const APValue &BaseValue =
Value.getStructBase(BaseIndex);
2591 Info.FFDiag(TypeBeginLoc, diag::note_constexpr_uninitialized_base)
2592 << BS.getType() <<
SourceRange(TypeBeginLoc, BS.getEndLoc());
2602 for (
const auto *I : RD->fields()) {
2603 if (I->isUnnamedBitField())
2607 Value.getStructField(I->getFieldIndex()), Kind,
2613 if (
Value.isLValue() &&
2616 LVal.setFrom(Info.Ctx,
Value);
2621 if (
Value.isMemberPointer() &&
2642 nullptr, CheckedTemps);
2652 ConstantExprKind::Normal,
nullptr, CheckedTemps);
2658 if (!Info.HeapAllocs.empty()) {
2662 Info.CCEDiag(Info.HeapAllocs.begin()->second.AllocExpr,
2663 diag::note_constexpr_memory_leak)
2664 <<
unsigned(Info.HeapAllocs.size() - 1);
2672 if (!
Value.getLValueBase()) {
2674 Result = !
Value.getLValueOffset().isZero();
2692 Result = Val.
getInt().getBoolValue();
2724 llvm_unreachable(
"unknown APValue kind");
2730 assert(E->
isPRValue() &&
"missing lvalue-to-rvalue conv in bool condition");
2740 Info.CCEDiag(E, diag::note_constexpr_overflow)
2741 << SrcValue << DestType;
2742 return Info.noteUndefinedBehavior();
2748 unsigned DestWidth = Info.Ctx.
getIntWidth(DestType);
2752 Result =
APSInt(DestWidth, !DestSigned);
2754 if (
Value.convertToInteger(Result, llvm::APFloat::rmTowardZero, &ignored)
2755 & APFloat::opInvalidOp)
2766 llvm::RoundingMode RM =
2768 if (RM == llvm::RoundingMode::Dynamic)
2769 RM = llvm::RoundingMode::NearestTiesToEven;
2775 APFloat::opStatus St) {
2778 if (Info.InConstantContext)
2782 if ((St & APFloat::opInexact) &&
2786 Info.FFDiag(E, diag::note_constexpr_dynamic_rounding);
2790 if ((St != APFloat::opOK) &&
2793 FPO.getAllowFEnvAccess())) {
2794 Info.FFDiag(E, diag::note_constexpr_float_arithmetic_strict);
2798 if ((St & APFloat::opStatus::opInvalidOp) &&
2819 "HandleFloatToFloatCast has been checked with only CastExpr, "
2820 "CompoundAssignOperator and ConvertVectorExpr. Please either validate "
2821 "the new expression or address the root cause of this usage.");
2823 APFloat::opStatus St;
2824 APFloat
Value = Result;
2833 unsigned DestWidth = Info.Ctx.
getIntWidth(DestType);
2839 Result =
Value.getBoolValue();
2846 QualType DestType, APFloat &Result) {
2849 APFloat::opStatus St = Result.convertFromAPInt(
Value,
Value.isSigned(), RM);
2855 assert(FD->
isBitField() &&
"truncateBitfieldValue on non-bitfield");
2857 if (!
Value.isInt()) {
2861 assert(
Value.isLValue() &&
"integral value neither int nor lvalue?");
2867 unsigned OldBitWidth = Int.getBitWidth();
2869 if (NewBitWidth < OldBitWidth)
2870 Int = Int.trunc(NewBitWidth).extend(OldBitWidth);
2877template<
typename Operation>
2880 unsigned BitWidth, Operation Op,
2882 if (LHS.isUnsigned()) {
2883 Result = Op(LHS, RHS);
2887 APSInt Value(Op(LHS.extend(BitWidth), RHS.extend(BitWidth)),
false);
2888 Result =
Value.trunc(LHS.getBitWidth());
2889 if (Result.extend(BitWidth) !=
Value) {
2890 if (Info.checkingForUndefinedBehavior())
2892 diag::warn_integer_constant_overflow)
2893 <<
toString(Result, 10, Result.isSigned(),
false,
2905 bool HandleOverflowResult =
true;
2912 std::multiplies<APSInt>(), Result);
2915 std::plus<APSInt>(), Result);
2918 std::minus<APSInt>(), Result);
2919 case BO_And: Result = LHS & RHS;
return true;
2920 case BO_Xor: Result = LHS ^ RHS;
return true;
2921 case BO_Or: Result = LHS | RHS;
return true;
2925 Info.FFDiag(E, diag::note_expr_divide_by_zero)
2931 if (RHS.isNegative() && RHS.isAllOnes() && LHS.isSigned() &&
2932 LHS.isMinSignedValue())
2934 Info, E, -LHS.extend(LHS.getBitWidth() + 1), E->
getType());
2935 Result = (Opcode == BO_Rem ? LHS % RHS : LHS / RHS);
2936 return HandleOverflowResult;
2938 if (Info.getLangOpts().OpenCL)
2940 RHS &=
APSInt(llvm::APInt(RHS.getBitWidth(),
2941 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2943 else if (RHS.isSigned() && RHS.isNegative()) {
2946 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
2947 if (!Info.noteUndefinedBehavior())
2955 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
2957 Info.CCEDiag(E, diag::note_constexpr_large_shift)
2958 << RHS << E->
getType() << LHS.getBitWidth();
2959 if (!Info.noteUndefinedBehavior())
2961 }
else if (LHS.isSigned() && !Info.getLangOpts().CPlusPlus20) {
2966 if (LHS.isNegative()) {
2967 Info.CCEDiag(E, diag::note_constexpr_lshift_of_negative) << LHS;
2968 if (!Info.noteUndefinedBehavior())
2970 }
else if (LHS.countl_zero() < SA) {
2971 Info.CCEDiag(E, diag::note_constexpr_lshift_discards);
2972 if (!Info.noteUndefinedBehavior())
2980 if (Info.getLangOpts().OpenCL)
2982 RHS &=
APSInt(llvm::APInt(RHS.getBitWidth(),
2983 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2985 else if (RHS.isSigned() && RHS.isNegative()) {
2988 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
2989 if (!Info.noteUndefinedBehavior())
2997 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
2999 Info.CCEDiag(E, diag::note_constexpr_large_shift)
3000 << RHS << E->
getType() << LHS.getBitWidth();
3001 if (!Info.noteUndefinedBehavior())
3009 case BO_LT: Result = LHS < RHS;
return true;
3010 case BO_GT: Result = LHS > RHS;
return true;
3011 case BO_LE: Result = LHS <= RHS;
return true;
3012 case BO_GE: Result = LHS >= RHS;
return true;
3013 case BO_EQ: Result = LHS == RHS;
return true;
3014 case BO_NE: Result = LHS != RHS;
return true;
3016 llvm_unreachable(
"BO_Cmp should be handled elsewhere");
3023 const APFloat &RHS) {
3025 APFloat::opStatus St;
3031 St = LHS.multiply(RHS, RM);
3034 St = LHS.add(RHS, RM);
3037 St = LHS.subtract(RHS, RM);
3043 Info.CCEDiag(E, diag::note_expr_divide_by_zero);
3044 St = LHS.divide(RHS, RM);
3053 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << LHS.isNaN();
3054 return Info.noteUndefinedBehavior();
3062 const APInt &RHSValue, APInt &Result) {
3063 bool LHS = (LHSValue != 0);
3064 bool RHS = (RHSValue != 0);
3066 if (Opcode == BO_LAnd)
3067 Result = LHS && RHS;
3069 Result = LHS || RHS;
3074 const APFloat &RHSValue, APInt &Result) {
3075 bool LHS = !LHSValue.isZero();
3076 bool RHS = !RHSValue.isZero();
3078 if (Opcode == BO_LAnd)
3079 Result = LHS && RHS;
3081 Result = LHS || RHS;
3087 const APValue &RHSValue, APInt &Result) {
3091 RHSValue.
getInt(), Result);
3097template <
typename APTy>
3100 const APTy &RHSValue, APInt &Result) {
3103 llvm_unreachable(
"unsupported binary operator");
3105 Result = (LHSValue == RHSValue);
3108 Result = (LHSValue != RHSValue);
3111 Result = (LHSValue < RHSValue);
3114 Result = (LHSValue > RHSValue);
3117 Result = (LHSValue <= RHSValue);
3120 Result = (LHSValue >= RHSValue);
3134 const APValue &RHSValue, APInt &Result) {
3138 RHSValue.
getInt(), Result);
3149 assert(Opcode != BO_PtrMemD && Opcode != BO_PtrMemI &&
3150 "Operation not supported on vector types");
3154 QualType EltTy = VT->getElementType();
3161 "A vector result that isn't a vector OR uncalculated LValue");
3167 RHSValue.
getVectorLength() == NumElements &&
"Different vector sizes");
3171 for (
unsigned EltNum = 0; EltNum < NumElements; ++EltNum) {
3186 RHSElt.
getInt(), EltResult);
3192 ResultElements.emplace_back(EltResult);
3197 "Mismatched LHS/RHS/Result Type");
3198 APFloat LHSFloat = LHSElt.
getFloat();
3206 ResultElements.emplace_back(LHSFloat);
3210 LHSValue =
APValue(ResultElements.data(), ResultElements.size());
3218 unsigned TruncatedElements) {
3219 SubobjectDesignator &D = Result.Designator;
3222 if (TruncatedElements == D.Entries.size())
3224 assert(TruncatedElements >= D.MostDerivedPathLength &&
3225 "not casting to a derived class");
3231 for (
unsigned I = TruncatedElements, N = D.Entries.size(); I != N; ++I) {
3235 if (isVirtualBaseClass(D.Entries[I]))
3241 D.Entries.resize(TruncatedElements);
3254 Obj.addDecl(Info, E,
Base,
false);
3255 Obj.getLValueOffset() += RL->getBaseClassOffset(
Base);
3264 if (!
Base->isVirtual())
3267 SubobjectDesignator &D = Obj.Designator;
3283 Obj.addDecl(Info, E, BaseDecl,
true);
3292 PathI != PathE; ++PathI) {
3296 Type = (*PathI)->getType();
3308 llvm_unreachable(
"Class must be derived from the passed in base class!");
3327 LVal.addDecl(Info, E, FD);
3336 for (
const auto *
C : IFD->
chain())
3389 LVal.adjustOffsetAndIndex(Info, E, Adjustment, SizeOfPointee);
3395 int64_t Adjustment) {
3397 APSInt::get(Adjustment));
3412 LVal.Offset += SizeOfComponent;
3414 LVal.addComplex(Info, E, EltTy, Imag);
3420 uint64_t Size, uint64_t Idx) {
3425 LVal.Offset += SizeOfElement * Idx;
3427 LVal.addVectorElement(Info, E, EltTy, Size, Idx);
3441 const VarDecl *VD, CallStackFrame *Frame,
3442 unsigned Version,
APValue *&Result) {
3445 bool AllowConstexprUnknown =
3450 auto CheckUninitReference = [&](
bool IsLocalVariable) {
3462 if (!AllowConstexprUnknown || IsLocalVariable) {
3463 if (!Info.checkingPotentialConstantExpression())
3464 Info.FFDiag(E, diag::note_constexpr_use_uninit_reference);
3474 Result = Frame->getTemporary(VD, Version);
3476 return CheckUninitReference(
true);
3485 "missing value for local variable");
3486 if (Info.checkingPotentialConstantExpression())
3491 diag::note_unimplemented_constexpr_lambda_feature_ast)
3492 <<
"captures not currently allowed";
3499 if (Info.EvaluatingDecl ==
Base) {
3500 Result = Info.EvaluatingDeclValue;
3501 return CheckUninitReference(
false);
3509 if (AllowConstexprUnknown) {
3516 if (!Info.checkingPotentialConstantExpression() ||
3517 !Info.CurrentCall->Callee ||
3519 if (Info.getLangOpts().CPlusPlus11) {
3520 Info.FFDiag(E, diag::note_constexpr_function_param_value_unknown)
3541 if (!
Init && !AllowConstexprUnknown) {
3544 if (!Info.checkingPotentialConstantExpression()) {
3545 Info.FFDiag(E, diag::note_constexpr_var_init_unknown, 1)
3556 if (
Init &&
Init->isValueDependent()) {
3563 if (!Info.checkingPotentialConstantExpression()) {
3564 Info.FFDiag(E, Info.getLangOpts().CPlusPlus11
3565 ? diag::note_constexpr_ltor_non_constexpr
3566 : diag::note_constexpr_ltor_non_integral, 1)
3580 Info.FFDiag(E, diag::note_constexpr_var_init_non_constant, 1) << VD;
3596 !AllowConstexprUnknown) ||
3597 ((Info.getLangOpts().CPlusPlus || Info.getLangOpts().OpenCL) &&
3600 Info.CCEDiag(E, diag::note_constexpr_var_init_non_constant, 1) << VD;
3610 Info.FFDiag(E, diag::note_constexpr_var_init_weak) << VD;
3617 if (!Result && !AllowConstexprUnknown)
3620 return CheckUninitReference(
false);
3630 E = Derived->
bases_end(); I != E; ++I, ++Index) {
3631 if (I->getType()->getAsCXXRecordDecl()->getCanonicalDecl() ==
Base)
3635 llvm_unreachable(
"base class missing from derived class's bases list");
3642 "SourceLocExpr should have already been converted to a StringLiteral");
3645 if (
const auto *ObjCEnc = dyn_cast<ObjCEncodeExpr>(Lit)) {
3648 assert(Index <= Str.size() &&
"Index too large");
3649 return APSInt::getUnsigned(Str.c_str()[Index]);
3652 if (
auto PE = dyn_cast<PredefinedExpr>(Lit))
3653 Lit = PE->getFunctionName();
3657 assert(CAT &&
"string literal isn't an array");
3659 assert(CharType->
isIntegerType() &&
"unexpected character type");
3662 if (Index < S->getLength())
3675 AllocType.isNull() ? S->
getType() : AllocType);
3676 assert(CAT &&
"string literal isn't an array");
3678 assert(CharType->
isIntegerType() &&
"unexpected character type");
3685 if (Result.hasArrayFiller())
3687 for (
unsigned I = 0, N = Result.getArrayInitializedElts(); I != N; ++I) {
3695 unsigned Size = Array.getArraySize();
3696 assert(Index < Size);
3699 unsigned OldElts = Array.getArrayInitializedElts();
3700 unsigned NewElts = std::max(Index+1, OldElts * 2);
3701 NewElts = std::min(Size, std::max(NewElts, 8u));
3705 for (
unsigned I = 0; I != OldElts; ++I)
3707 for (
unsigned I = OldElts; I != NewElts; ++I)
3711 Array.
swap(NewValue);
3721 CXXRecordDecl *RD =
T->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
3732 for (
auto *Field : RD->
fields())
3733 if (!Field->isUnnamedBitField() &&
3737 for (
auto &BaseSpec : RD->
bases())
3748 CXXRecordDecl *RD =
T->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
3755 for (
auto *Field : RD->
fields()) {
3760 if (Field->isMutable() &&
3762 Info.FFDiag(E, diag::note_constexpr_access_mutable, 1) << AK << Field;
3763 Info.Note(Field->getLocation(), diag::note_declared_at);
3771 for (
auto &BaseSpec : RD->
bases())
3781 bool MutableSubobject =
false) {
3786 switch (Info.IsEvaluatingDecl) {
3787 case EvalInfo::EvaluatingDeclKind::None:
3790 case EvalInfo::EvaluatingDeclKind::Ctor:
3792 if (Info.EvaluatingDecl ==
Base)
3797 if (
auto *BaseE =
Base.dyn_cast<
const Expr *>())
3798 if (
auto *BaseMTE = dyn_cast<MaterializeTemporaryExpr>(BaseE))
3799 return Info.EvaluatingDecl == BaseMTE->getExtendingDecl();
3802 case EvalInfo::EvaluatingDeclKind::Dtor:
3807 if (MutableSubobject ||
Base != Info.EvaluatingDecl)
3813 return T.isConstQualified() ||
T->isReferenceType();
3816 llvm_unreachable(
"unknown evaluating decl kind");
3821 return Info.CheckArraySize(
3830struct CompleteObject {
3832 APValue::LValueBase
Base;
3842 bool mayAccessMutableMembers(EvalInfo &Info,
AccessKinds AK)
const {
3853 if (!Info.getLangOpts().CPlusPlus14 &&
3854 AK != AccessKinds::AK_IsWithinLifetime)
3859 explicit operator bool()
const {
return !
Type.isNull(); }
3864 bool IsMutable =
false) {
3878template <
typename Sub
objectHandler>
3879static typename SubobjectHandler::result_type
3881 const SubobjectDesignator &Sub, SubobjectHandler &handler) {
3884 return handler.failed();
3885 if (Sub.isOnePastTheEnd() || Sub.isMostDerivedAnUnsizedArray()) {
3886 if (Info.getLangOpts().CPlusPlus11)
3887 Info.FFDiag(E, Sub.isOnePastTheEnd()
3888 ? diag::note_constexpr_access_past_end
3889 : diag::note_constexpr_access_unsized_array)
3890 << handler.AccessKind;
3893 return handler.failed();
3899 const FieldDecl *VolatileField =
nullptr;
3902 for (
unsigned I = 0, N = Sub.Entries.size(); ; ++I) {
3913 if (!Info.checkingPotentialConstantExpression())
3914 Info.FFDiag(E, diag::note_constexpr_access_uninit)
3917 return handler.failed();
3925 Info.isEvaluatingCtorDtor(
3926 Obj.Base,
ArrayRef(Sub.Entries.begin(), Sub.Entries.begin() + I)) !=
3927 ConstructionPhase::None) {
3937 if (Info.getLangOpts().CPlusPlus) {
3941 if (VolatileField) {
3944 Decl = VolatileField;
3947 Loc = VD->getLocation();
3954 Info.FFDiag(E, diag::note_constexpr_access_volatile_obj, 1)
3955 << handler.AccessKind << DiagKind <<
Decl;
3956 Info.Note(Loc, diag::note_constexpr_volatile_here) << DiagKind;
3958 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
3960 return handler.failed();
3968 !Obj.mayAccessMutableMembers(Info, handler.AccessKind) &&
3970 return handler.failed();
3974 if (!handler.found(*O, ObjType))
3986 LastField =
nullptr;
3991 "vla in literal type?");
3992 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
3993 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT);
3994 CAT && CAT->
getSize().ule(Index)) {
3997 if (Info.getLangOpts().CPlusPlus11)
3998 Info.FFDiag(E, diag::note_constexpr_access_past_end)
3999 << handler.AccessKind;
4002 return handler.failed();
4009 else if (!
isRead(handler.AccessKind)) {
4010 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT);
4012 return handler.failed();
4020 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4022 if (Info.getLangOpts().CPlusPlus11)
4023 Info.FFDiag(E, diag::note_constexpr_access_past_end)
4024 << handler.AccessKind;
4027 return handler.failed();
4033 assert(I == N - 1 &&
"extracting subobject of scalar?");
4043 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4044 unsigned NumElements = VT->getNumElements();
4045 if (Index == NumElements) {
4046 if (Info.getLangOpts().CPlusPlus11)
4047 Info.FFDiag(E, diag::note_constexpr_access_past_end)
4048 << handler.AccessKind;
4051 return handler.failed();
4054 if (Index > NumElements) {
4055 Info.CCEDiag(E, diag::note_constexpr_array_index)
4056 << Index << 0 << NumElements;
4057 return handler.failed();
4060 ObjType = VT->getElementType();
4061 assert(I == N - 1 &&
"extracting subobject of scalar?");
4063 }
else if (
const FieldDecl *Field = getAsField(Sub.Entries[I])) {
4064 if (Field->isMutable() &&
4065 !Obj.mayAccessMutableMembers(Info, handler.AccessKind)) {
4066 Info.FFDiag(E, diag::note_constexpr_access_mutable, 1)
4067 << handler.AccessKind << Field;
4068 Info.Note(Field->getLocation(), diag::note_declared_at);
4069 return handler.failed();
4079 if (I == N - 1 && handler.AccessKind ==
AK_Construct) {
4090 Info.FFDiag(E, diag::note_constexpr_access_inactive_union_member)
4091 << handler.AccessKind << Field << !UnionField << UnionField;
4092 return handler.failed();
4101 if (Field->getType().isVolatileQualified())
4102 VolatileField = Field;
4115struct ExtractSubobjectHandler {
4121 typedef bool result_type;
4122 bool failed() {
return false; }
4123 bool found(
APValue &Subobj, QualType SubobjType) {
4133 bool found(APFloat &
Value, QualType SubobjType) {
4142 const CompleteObject &Obj,
4143 const SubobjectDesignator &Sub,
APValue &Result,
4146 ExtractSubobjectHandler Handler = {Info, E, Result, AK};
4151struct ModifySubobjectHandler {
4156 typedef bool result_type;
4159 bool checkConst(QualType QT) {
4162 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
4168 bool failed() {
return false; }
4169 bool found(
APValue &Subobj, QualType SubobjType) {
4170 if (!checkConst(SubobjType))
4173 Subobj.
swap(NewVal);
4177 if (!checkConst(SubobjType))
4179 if (!NewVal.
isInt()) {
4187 bool found(APFloat &
Value, QualType SubobjType) {
4188 if (!checkConst(SubobjType))
4196const AccessKinds ModifySubobjectHandler::AccessKind;
4200 const CompleteObject &Obj,
4201 const SubobjectDesignator &Sub,
4203 ModifySubobjectHandler Handler = { Info, NewVal, E };
4210 const SubobjectDesignator &A,
4211 const SubobjectDesignator &B,
4212 bool &WasArrayIndex) {
4213 unsigned I = 0, N = std::min(A.Entries.size(), B.Entries.size());
4214 for (; I != N; ++I) {
4218 if (A.Entries[I].getAsArrayIndex() != B.Entries[I].getAsArrayIndex()) {
4219 WasArrayIndex =
true;
4227 if (A.Entries[I].getAsBaseOrMember() !=
4228 B.Entries[I].getAsBaseOrMember()) {
4229 WasArrayIndex =
false;
4232 if (
const FieldDecl *FD = getAsField(A.Entries[I]))
4234 ObjType = FD->getType();
4240 WasArrayIndex =
false;
4247 const SubobjectDesignator &A,
4248 const SubobjectDesignator &B) {
4249 if (A.Entries.size() != B.Entries.size())
4252 bool IsArray = A.MostDerivedIsArrayElement;
4253 if (IsArray && A.MostDerivedPathLength != A.Entries.size())
4262 return CommonLength >= A.Entries.size() - IsArray;
4269 if (LVal.InvalidBase) {
4271 return CompleteObject();
4276 Info.FFDiag(E, diag::note_constexpr_dereferencing_null);
4278 Info.FFDiag(E, diag::note_constexpr_access_null) << AK;
4279 return CompleteObject();
4282 CallStackFrame *Frame =
nullptr;
4284 if (LVal.getLValueCallIndex()) {
4285 std::tie(Frame, Depth) =
4286 Info.getCallFrameAndDepth(LVal.getLValueCallIndex());
4288 Info.FFDiag(E, diag::note_constexpr_lifetime_ended, 1)
4291 return CompleteObject();
4302 if (Info.getLangOpts().CPlusPlus)
4303 Info.FFDiag(E, diag::note_constexpr_access_volatile_type)
4307 return CompleteObject();
4314 if (Info.getLangOpts().CPlusPlus14 && LVal.Base == Info.EvaluatingDecl &&
4318 BaseVal = Info.EvaluatingDeclValue;
4321 if (
auto *GD = dyn_cast<MSGuidDecl>(D)) {
4324 Info.FFDiag(E, diag::note_constexpr_modify_global);
4325 return CompleteObject();
4329 Info.FFDiag(E, diag::note_constexpr_unsupported_layout)
4331 return CompleteObject();
4333 return CompleteObject(LVal.Base, &
V, GD->getType());
4337 if (
auto *GCD = dyn_cast<UnnamedGlobalConstantDecl>(D)) {
4339 Info.FFDiag(E, diag::note_constexpr_modify_global);
4340 return CompleteObject();
4342 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&GCD->getValue()),
4347 if (
auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
4349 Info.FFDiag(E, diag::note_constexpr_modify_global);
4350 return CompleteObject();
4352 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&TPO->getValue()),
4363 const VarDecl *VD = dyn_cast<VarDecl>(D);
4370 return CompleteObject();
4373 bool IsConstant = BaseType.isConstant(Info.Ctx);
4374 bool ConstexprVar =
false;
4375 if (
const auto *VD = dyn_cast_if_present<VarDecl>(
4387 }
else if (Info.getLangOpts().CPlusPlus14 &&
4394 Info.FFDiag(E, diag::note_constexpr_modify_global);
4395 return CompleteObject();
4398 }
else if (Info.getLangOpts().C23 && ConstexprVar) {
4400 return CompleteObject();
4401 }
else if (BaseType->isIntegralOrEnumerationType()) {
4404 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4405 if (Info.getLangOpts().CPlusPlus) {
4406 Info.FFDiag(E, diag::note_constexpr_ltor_non_const_int, 1) << VD;
4407 Info.Note(VD->
getLocation(), diag::note_declared_at);
4411 return CompleteObject();
4413 }
else if (!IsAccess) {
4414 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4415 }
else if ((IsConstant || BaseType->isReferenceType()) &&
4416 Info.checkingPotentialConstantExpression() &&
4417 BaseType->isLiteralType(Info.Ctx) && !VD->
hasDefinition()) {
4419 }
else if (IsConstant) {
4423 if (Info.getLangOpts().CPlusPlus) {
4424 Info.CCEDiag(E, Info.getLangOpts().CPlusPlus11
4425 ? diag::note_constexpr_ltor_non_constexpr
4426 : diag::note_constexpr_ltor_non_integral, 1)
4428 Info.Note(VD->
getLocation(), diag::note_declared_at);
4434 if (Info.getLangOpts().CPlusPlus) {
4435 Info.FFDiag(E, Info.getLangOpts().CPlusPlus11
4436 ? diag::note_constexpr_ltor_non_constexpr
4437 : diag::note_constexpr_ltor_non_integral, 1)
4439 Info.Note(VD->
getLocation(), diag::note_declared_at);
4443 return CompleteObject();
4452 return CompleteObject();
4457 if (!Info.checkingPotentialConstantExpression()) {
4458 Info.FFDiag(E, diag::note_constexpr_access_unknown_variable, 1)
4460 Info.Note(VD->getLocation(), diag::note_declared_at);
4462 return CompleteObject();
4465 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
4467 Info.FFDiag(E, diag::note_constexpr_access_deleted_object) << AK;
4468 return CompleteObject();
4470 return CompleteObject(LVal.Base, &(*Alloc)->Value,
4480 dyn_cast_or_null<MaterializeTemporaryExpr>(
Base)) {
4481 assert(MTE->getStorageDuration() ==
SD_Static &&
4482 "should have a frame for a non-global materialized temporary");
4509 if (!MTE->isUsableInConstantExpressions(Info.Ctx) &&
4512 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4513 Info.FFDiag(E, diag::note_constexpr_access_static_temporary, 1) << AK;
4514 Info.Note(MTE->getExprLoc(), diag::note_constexpr_temporary_here);
4515 return CompleteObject();
4518 BaseVal = MTE->getOrCreateValue(
false);
4519 assert(BaseVal &&
"got reference to unevaluated temporary");
4521 dyn_cast_or_null<CompoundLiteralExpr>(
Base)) {
4537 !CLETy.isConstant(Info.Ctx)) {
4539 Info.Note(CLE->getExprLoc(), diag::note_declared_at);
4540 return CompleteObject();
4543 BaseVal = &CLE->getStaticValue();
4546 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4549 Info.FFDiag(E, diag::note_constexpr_access_unreadable_object)
4554 return CompleteObject();
4558 assert(BaseVal &&
"missing value for temporary");
4569 unsigned VisibleDepth = Depth;
4570 if (llvm::isa_and_nonnull<ParmVarDecl>(
4573 if ((Frame && Info.getLangOpts().CPlusPlus14 &&
4575 (
isModification(AK) && VisibleDepth < Info.SpeculativeEvaluationDepth))
4576 return CompleteObject();
4578 return CompleteObject(LVal.getLValueBase(), BaseVal, BaseType);
4597 const LValue &LVal,
APValue &RVal,
4598 bool WantObjectRepresentation =
false) {
4599 if (LVal.Designator.Invalid)
4608 if (
Base && !LVal.getLValueCallIndex() && !
Type.isVolatileQualified()) {
4612 assert(LVal.Designator.Entries.size() <= 1 &&
4613 "Can only read characters from string literals");
4614 if (LVal.Designator.Entries.empty()) {
4621 if (LVal.Designator.isOnePastTheEnd()) {
4622 if (Info.getLangOpts().CPlusPlus11)
4623 Info.FFDiag(Conv, diag::note_constexpr_access_past_end) << AK;
4628 uint64_t CharIndex = LVal.Designator.Entries[0].getAsArrayIndex();
4635 return Obj &&
extractSubobject(Info, Conv, Obj, LVal.Designator, RVal, AK);
4641 if (LVal.Designator.Invalid)
4644 if (!Info.getLangOpts().CPlusPlus14) {
4654struct CompoundAssignSubobjectHandler {
4656 const CompoundAssignOperator *E;
4657 QualType PromotedLHSType;
4663 typedef bool result_type;
4665 bool checkConst(QualType QT) {
4668 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
4674 bool failed() {
return false; }
4675 bool found(
APValue &Subobj, QualType SubobjType) {
4678 return found(Subobj.
getInt(), SubobjType);
4680 return found(Subobj.
getFloat(), SubobjType);
4687 return foundPointer(Subobj, SubobjType);
4689 return foundVector(Subobj, SubobjType);
4691 Info.FFDiag(E, diag::note_constexpr_access_uninit)
4702 bool foundVector(
APValue &
Value, QualType SubobjType) {
4703 if (!checkConst(SubobjType))
4714 if (!checkConst(SubobjType))
4736 PromotedLHSType, FValue) &&
4745 bool found(APFloat &
Value, QualType SubobjType) {
4746 return checkConst(SubobjType) &&
4752 bool foundPointer(
APValue &Subobj, QualType SubobjType) {
4753 if (!checkConst(SubobjType))
4756 QualType PointeeType;
4757 if (
const PointerType *PT = SubobjType->
getAs<PointerType>())
4761 (Opcode != BO_Add && Opcode != BO_Sub)) {
4767 if (Opcode == BO_Sub)
4771 LVal.setFrom(Info.Ctx, Subobj);
4774 LVal.moveInto(Subobj);
4780const AccessKinds CompoundAssignSubobjectHandler::AccessKind;
4785 const LValue &LVal,
QualType LValType,
4789 if (LVal.Designator.Invalid)
4792 if (!Info.getLangOpts().CPlusPlus14) {
4798 CompoundAssignSubobjectHandler Handler = { Info, E, PromotedLValType, Opcode,
4800 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
4804struct IncDecSubobjectHandler {
4806 const UnaryOperator *E;
4810 typedef bool result_type;
4812 bool checkConst(QualType QT) {
4815 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
4821 bool failed() {
return false; }
4822 bool found(
APValue &Subobj, QualType SubobjType) {
4832 return found(Subobj.
getInt(), SubobjType);
4834 return found(Subobj.
getFloat(), SubobjType);
4837 SubobjType->
castAs<ComplexType>()->getElementType()
4841 SubobjType->
castAs<ComplexType>()->getElementType()
4844 return foundPointer(Subobj, SubobjType);
4852 if (!checkConst(SubobjType))
4874 bool WasNegative =
Value.isNegative();
4886 unsigned BitWidth =
Value.getBitWidth();
4887 APSInt ActualValue(
Value.sext(BitWidth + 1),
false);
4888 ActualValue.setBit(BitWidth);
4894 bool found(APFloat &
Value, QualType SubobjType) {
4895 if (!checkConst(SubobjType))
4902 APFloat::opStatus St;
4904 St =
Value.add(One, RM);
4906 St =
Value.subtract(One, RM);
4909 bool foundPointer(
APValue &Subobj, QualType SubobjType) {
4910 if (!checkConst(SubobjType))
4913 QualType PointeeType;
4914 if (
const PointerType *PT = SubobjType->
getAs<PointerType>())
4922 LVal.setFrom(Info.Ctx, Subobj);
4926 LVal.moveInto(Subobj);
4935 if (LVal.Designator.Invalid)
4938 if (!Info.getLangOpts().CPlusPlus14) {
4946 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
4952 if (Object->getType()->isPointerType() && Object->isPRValue())
4955 if (Object->isGLValue())
4958 if (Object->getType()->isLiteralType(Info.Ctx))
4961 if (Object->getType()->isRecordType() && Object->isPRValue())
4964 Info.FFDiag(Object, diag::note_constexpr_nonliteral) << Object->getType();
4983 bool IncludeMember =
true) {
4990 if (!MemPtr.getDecl()) {
4996 if (MemPtr.isDerivedMember()) {
5003 if (LV.Designator.MostDerivedPathLength + MemPtr.Path.size() >
5004 LV.Designator.Entries.size()) {
5008 unsigned PathLengthToMember =
5009 LV.Designator.Entries.size() - MemPtr.Path.size();
5010 for (
unsigned I = 0, N = MemPtr.Path.size(); I != N; ++I) {
5012 LV.Designator.Entries[PathLengthToMember + I]);
5029 (PathLengthToMember > LV.Designator.MostDerivedPathLength)
5030 ? getAsBaseClass(LV.Designator.Entries[PathLengthToMember - 1])
5032 const CXXRecordDecl *LastMPDecl = MemPtr.getContainingRecord();
5040 PathLengthToMember))
5042 }
else if (!MemPtr.Path.empty()) {
5044 LV.Designator.Entries.reserve(LV.Designator.Entries.size() +
5045 MemPtr.Path.size() + IncludeMember);
5051 assert(RD &&
"member pointer access on non-class-type expression");
5053 for (
unsigned I = 1, N = MemPtr.Path.size(); I != N; ++I) {
5061 MemPtr.getContainingRecord()))
5066 if (IncludeMember) {
5067 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(MemPtr.getDecl())) {
5071 dyn_cast<IndirectFieldDecl>(MemPtr.getDecl())) {
5075 llvm_unreachable(
"can't construct reference to bound member function");
5079 return MemPtr.getDecl();
5085 bool IncludeMember =
true) {
5089 if (Info.noteFailure()) {
5097 BO->
getRHS(), IncludeMember);
5104 SubobjectDesignator &D = Result.Designator;
5105 if (D.Invalid || !Result.checkNullPointer(Info, E,
CSK_Derived))
5112 auto InvalidCast = [&]() {
5113 if (!Info.checkingPotentialConstantExpression() ||
5114 !Result.AllowConstexprUnknown) {
5115 Info.CCEDiag(E, diag::note_constexpr_invalid_downcast)
5116 << D.MostDerivedType << TargetQT;
5122 if (D.MostDerivedPathLength + E->
path_size() > D.Entries.size())
5123 return InvalidCast();
5127 unsigned NewEntriesSize = D.Entries.size() - E->
path_size();
5130 if (NewEntriesSize == D.MostDerivedPathLength)
5133 FinalType = getAsBaseClass(D.Entries[NewEntriesSize - 1]);
5135 return InvalidCast();
5147 if (!Result.isAbsent())
5150 if (
auto *RD =
T->getAsCXXRecordDecl()) {
5151 if (RD->isInvalidDecl()) {
5155 if (RD->isUnion()) {
5160 std::distance(RD->field_begin(), RD->field_end()));
5164 End = RD->bases_end();
5165 I != End; ++I, ++Index)
5169 for (
const auto *I : RD->fields()) {
5170 if (I->isUnnamedBitField())
5173 I->getType(), Result.getStructField(I->getFieldIndex()));
5179 dyn_cast_or_null<ConstantArrayType>(
T->getAsArrayTypeUnsafe())) {
5181 if (Result.hasArrayFiller())
5193enum EvalStmtResult {
5222 if (!Result.Designator.Invalid && Result.Designator.isOnePastTheEnd()) {
5228 Result.moveInto(Val);
5240 APValue &Val = Info.CurrentCall->createTemporary(VD, VD->
getType(),
5241 ScopeKind::Block, Result);
5246 return Info.noteSideEffect();
5267 const DecompositionDecl *DD);
5270 bool EvaluateConditionDecl =
false) {
5272 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
5276 EvaluateConditionDecl && DD)
5286 if (
auto *VD = BD->getHoldingVar())
5294 if (
auto *DD = dyn_cast_if_present<DecompositionDecl>(VD)) {
5303 if (Info.noteSideEffect())
5305 assert(E->
containsErrors() &&
"valid value-dependent expression should never "
5306 "reach invalid code path.");
5313 if (
Cond->isValueDependent())
5315 FullExpressionRAII
Scope(Info);
5322 return Scope.destroy();
5335struct TempVersionRAII {
5336 CallStackFrame &Frame;
5338 TempVersionRAII(CallStackFrame &Frame) : Frame(Frame) {
5339 Frame.pushTempVersion();
5342 ~TempVersionRAII() {
5343 Frame.popTempVersion();
5351 const SwitchCase *SC =
nullptr);
5357 const Stmt *LoopOrSwitch,
5359 EvalStmtResult &ESR) {
5363 if (!IsSwitch && ESR == ESR_Succeeded) {
5368 if (ESR != ESR_Break && ESR != ESR_Continue)
5372 bool CanBreakOrContinue = !IsSwitch || ESR == ESR_Break;
5373 const Stmt *StackTop = Info.BreakContinueStack.back();
5374 if (CanBreakOrContinue && (StackTop ==
nullptr || StackTop == LoopOrSwitch)) {
5375 Info.BreakContinueStack.pop_back();
5376 if (ESR == ESR_Break)
5377 ESR = ESR_Succeeded;
5382 for (BlockScopeRAII *S : Scopes) {
5383 if (!S->destroy()) {
5395 BlockScopeRAII
Scope(Info);
5397 EvalStmtResult ESR =
EvaluateStmt(Result, Info, Body, Case);
5398 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5407 BlockScopeRAII
Scope(Info);
5414 if (ESR != ESR_Succeeded) {
5415 if (ESR != ESR_Failed && !
Scope.destroy())
5421 FullExpressionRAII CondScope(Info);
5436 if (!CondScope.destroy())
5461 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5465 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5472 llvm_unreachable(
"Should have been converted to Succeeded");
5478 case ESR_CaseNotFound:
5481 Info.FFDiag(
Found->getBeginLoc(),
5482 diag::note_constexpr_stmt_expr_unsupported);
5485 llvm_unreachable(
"Invalid EvalStmtResult!");
5495 Info.CCEDiag(VD->
getLocation(), diag::note_constexpr_static_local)
5505 if (!Info.nextStep(S))
5512 case Stmt::CompoundStmtClass:
5516 case Stmt::LabelStmtClass:
5517 case Stmt::AttributedStmtClass:
5518 case Stmt::DoStmtClass:
5521 case Stmt::CaseStmtClass:
5522 case Stmt::DefaultStmtClass:
5527 case Stmt::IfStmtClass: {
5534 BlockScopeRAII
Scope(Info);
5540 if (ESR != ESR_CaseNotFound) {
5541 assert(ESR != ESR_Succeeded);
5552 if (ESR == ESR_Failed)
5554 if (ESR != ESR_CaseNotFound)
5555 return Scope.destroy() ? ESR : ESR_Failed;
5557 return ESR_CaseNotFound;
5560 if (ESR == ESR_Failed)
5562 if (ESR != ESR_CaseNotFound)
5563 return Scope.destroy() ? ESR : ESR_Failed;
5564 return ESR_CaseNotFound;
5567 case Stmt::WhileStmtClass: {
5568 EvalStmtResult ESR =
5572 if (ESR != ESR_Continue)
5577 case Stmt::ForStmtClass: {
5579 BlockScopeRAII
Scope(Info);
5585 if (ESR != ESR_CaseNotFound) {
5586 assert(ESR != ESR_Succeeded);
5591 EvalStmtResult ESR =
5595 if (ESR != ESR_Continue)
5597 if (
const auto *Inc = FS->
getInc()) {
5598 if (Inc->isValueDependent()) {
5602 FullExpressionRAII IncScope(Info);
5610 case Stmt::DeclStmtClass: {
5614 for (
const auto *D : DS->
decls()) {
5615 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
5618 if (VD->hasLocalStorage() && !VD->getInit())
5626 return ESR_CaseNotFound;
5630 return ESR_CaseNotFound;
5636 if (
const Expr *E = dyn_cast<Expr>(S)) {
5645 FullExpressionRAII
Scope(Info);
5649 return ESR_Succeeded;
5655 case Stmt::NullStmtClass:
5656 return ESR_Succeeded;
5658 case Stmt::DeclStmtClass: {
5660 for (
const auto *D : DS->
decls()) {
5661 const VarDecl *VD = dyn_cast_or_null<VarDecl>(D);
5665 FullExpressionRAII
Scope(Info);
5667 !Info.noteFailure())
5669 if (!
Scope.destroy())
5672 return ESR_Succeeded;
5675 case Stmt::ReturnStmtClass: {
5677 FullExpressionRAII
Scope(Info);
5686 :
Evaluate(Result.Value, Info, RetExpr)))
5688 return Scope.destroy() ? ESR_Returned : ESR_Failed;
5691 case Stmt::CompoundStmtClass: {
5692 BlockScopeRAII
Scope(Info);
5695 for (
const auto *BI : CS->
body()) {
5696 EvalStmtResult ESR =
EvaluateStmt(Result, Info, BI, Case);
5697 if (ESR == ESR_Succeeded)
5699 else if (ESR != ESR_CaseNotFound) {
5700 if (ESR != ESR_Failed && !
Scope.destroy())
5706 return ESR_CaseNotFound;
5707 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5710 case Stmt::IfStmtClass: {
5714 BlockScopeRAII
Scope(Info);
5717 if (ESR != ESR_Succeeded) {
5718 if (ESR != ESR_Failed && !
Scope.destroy())
5728 if (!Info.InConstantContext)
5735 EvalStmtResult ESR =
EvaluateStmt(Result, Info, SubStmt);
5736 if (ESR != ESR_Succeeded) {
5737 if (ESR != ESR_Failed && !
Scope.destroy())
5742 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5745 case Stmt::WhileStmtClass: {
5748 BlockScopeRAII
Scope(Info);
5760 if (ESR != ESR_Continue) {
5761 if (ESR != ESR_Failed && !
Scope.destroy())
5765 if (!
Scope.destroy())
5768 return ESR_Succeeded;
5771 case Stmt::DoStmtClass: {
5778 if (ESR != ESR_Continue)
5787 FullExpressionRAII CondScope(Info);
5789 !CondScope.destroy())
5792 return ESR_Succeeded;
5795 case Stmt::ForStmtClass: {
5797 BlockScopeRAII ForScope(Info);
5800 if (ESR != ESR_Succeeded) {
5801 if (ESR != ESR_Failed && !ForScope.destroy())
5807 BlockScopeRAII IterScope(Info);
5808 bool Continue =
true;
5814 if (!IterScope.destroy())
5822 if (ESR != ESR_Continue) {
5823 if (ESR != ESR_Failed && (!IterScope.destroy() || !ForScope.destroy()))
5828 if (
const auto *Inc = FS->
getInc()) {
5829 if (Inc->isValueDependent()) {
5833 FullExpressionRAII IncScope(Info);
5839 if (!IterScope.destroy())
5842 return ForScope.destroy() ? ESR_Succeeded : ESR_Failed;
5845 case Stmt::CXXForRangeStmtClass: {
5847 BlockScopeRAII
Scope(Info);
5852 if (ESR != ESR_Succeeded) {
5853 if (ESR != ESR_Failed && !
Scope.destroy())
5861 if (ESR != ESR_Succeeded) {
5862 if (ESR != ESR_Failed && !
Scope.destroy())
5874 if (ESR != ESR_Succeeded) {
5875 if (ESR != ESR_Failed && !
Scope.destroy())
5880 if (ESR != ESR_Succeeded) {
5881 if (ESR != ESR_Failed && !
Scope.destroy())
5894 bool Continue =
true;
5895 FullExpressionRAII CondExpr(Info);
5903 BlockScopeRAII InnerScope(Info);
5905 if (ESR != ESR_Succeeded) {
5906 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
5915 if (ESR != ESR_Continue) {
5916 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
5929 if (!InnerScope.destroy())
5933 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5936 case Stmt::SwitchStmtClass:
5939 case Stmt::ContinueStmtClass:
5940 case Stmt::BreakStmtClass: {
5942 Info.BreakContinueStack.push_back(B->getNamedLoopOrSwitch());
5946 case Stmt::LabelStmtClass:
5949 case Stmt::AttributedStmtClass: {
5951 const auto *SS = AS->getSubStmt();
5952 MSConstexprContextRAII ConstexprContext(
5956 auto LO = Info.getASTContext().getLangOpts();
5957 if (LO.CXXAssumptions && !LO.MSVCCompat) {
5958 for (
auto *
Attr : AS->getAttrs()) {
5959 auto *AA = dyn_cast<CXXAssumeAttr>(
Attr);
5963 auto *Assumption = AA->getAssumption();
5964 if (Assumption->isValueDependent())
5967 if (Assumption->HasSideEffects(Info.getASTContext()))
5974 Info.CCEDiag(Assumption->getExprLoc(),
5975 diag::note_constexpr_assumption_failed);
5984 case Stmt::CaseStmtClass:
5985 case Stmt::DefaultStmtClass:
5987 case Stmt::CXXTryStmtClass:
5999 bool IsValueInitialization) {
6006 if (!CD->
isConstexpr() && !IsValueInitialization) {
6007 if (Info.getLangOpts().CPlusPlus11) {
6010 Info.CCEDiag(Loc, diag::note_constexpr_invalid_function, 1)
6012 Info.Note(CD->
getLocation(), diag::note_declared_at);
6014 Info.CCEDiag(Loc, diag::note_invalid_subexpr_in_const_expr);
6028 if (Info.checkingPotentialConstantExpression() && !
Definition &&
6036 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6045 Info.CCEDiag(CallLoc, diag::note_constexpr_virtual_call);
6048 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6054 (
Definition->isConstexpr() || (Info.CurrentCall->CanEvalMSConstexpr &&
6064 StringRef Name = DiagDecl->
getName();
6066 Name ==
"__assert_rtn" || Name ==
"__assert_fail" || Name ==
"_wassert";
6068 Info.FFDiag(CallLoc, diag::note_constexpr_assert_failed);
6073 if (Info.getLangOpts().CPlusPlus11) {
6076 auto *CD = dyn_cast<CXXConstructorDecl>(DiagDecl);
6077 if (CD && CD->isInheritingConstructor()) {
6078 auto *Inherited = CD->getInheritedConstructor().getConstructor();
6079 if (!Inherited->isConstexpr())
6080 DiagDecl = CD = Inherited;
6086 if (CD && CD->isInheritingConstructor())
6087 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_inhctor, 1)
6088 << CD->getInheritedConstructor().getConstructor()->getParent();
6090 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_function, 1)
6092 Info.Note(DiagDecl->
getLocation(), diag::note_declared_at);
6094 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6100struct CheckDynamicTypeHandler {
6102 typedef bool result_type;
6103 bool failed() {
return false; }
6104 bool found(
APValue &Subobj, QualType SubobjType) {
return true; }
6105 bool found(
APSInt &
Value, QualType SubobjType) {
return true; }
6106 bool found(APFloat &
Value, QualType SubobjType) {
return true; }
6114 if (
This.Designator.Invalid)
6126 if (
This.Designator.isOnePastTheEnd() ||
6127 This.Designator.isMostDerivedAnUnsizedArray()) {
6128 Info.FFDiag(E,
This.Designator.isOnePastTheEnd()
6129 ? diag::note_constexpr_access_past_end
6130 : diag::note_constexpr_access_unsized_array)
6133 }
else if (Polymorphic) {
6136 if (!Info.checkingPotentialConstantExpression() ||
6137 !
This.AllowConstexprUnknown) {
6142 Info.FFDiag(E, diag::note_constexpr_polymorphic_unknown_dynamic_type)
6150 CheckDynamicTypeHandler Handler{AK};
6173 unsigned PathLength) {
6174 assert(PathLength >=
Designator.MostDerivedPathLength && PathLength <=
6175 Designator.Entries.size() &&
"invalid path length");
6176 return (PathLength ==
Designator.MostDerivedPathLength)
6177 ?
Designator.MostDerivedType->getAsCXXRecordDecl()
6178 : getAsBaseClass(
Designator.Entries[PathLength - 1]);
6191 return std::nullopt;
6193 if (
This.Designator.Invalid)
6194 return std::nullopt;
6203 This.Designator.MostDerivedType->getAsCXXRecordDecl();
6204 if (!Class || Class->getNumVBases()) {
6206 return std::nullopt;
6214 for (
unsigned PathLength =
This.Designator.MostDerivedPathLength;
6215 PathLength <= Path.size(); ++PathLength) {
6216 switch (Info.isEvaluatingCtorDtor(
This.getLValueBase(),
6217 Path.slice(0, PathLength))) {
6218 case ConstructionPhase::Bases:
6219 case ConstructionPhase::DestroyingBases:
6224 case ConstructionPhase::None:
6225 case ConstructionPhase::AfterBases:
6226 case ConstructionPhase::AfterFields:
6227 case ConstructionPhase::Destroying:
6239 return std::nullopt;
6257 unsigned PathLength = DynType->PathLength;
6258 for (; PathLength <=
This.Designator.Entries.size(); ++PathLength) {
6261 Found->getCorrespondingMethodDeclaredInClass(Class,
false);
6271 if (Callee->isPureVirtual()) {
6272 Info.FFDiag(E, diag::note_constexpr_pure_virtual_call, 1) << Callee;
6273 Info.Note(Callee->getLocation(), diag::note_declared_at);
6280 Found->getReturnType())) {
6281 CovariantAdjustmentPath.push_back(Callee->getReturnType());
6282 for (
unsigned CovariantPathLength = PathLength + 1;
6283 CovariantPathLength !=
This.Designator.Entries.size();
6284 ++CovariantPathLength) {
6288 Found->getCorrespondingMethodDeclaredInClass(NextClass,
false);
6290 Next->getReturnType(), CovariantAdjustmentPath.back()))
6291 CovariantAdjustmentPath.push_back(
Next->getReturnType());
6294 CovariantAdjustmentPath.back()))
6295 CovariantAdjustmentPath.push_back(
Found->getReturnType());
6311 assert(Result.isLValue() &&
6312 "unexpected kind of APValue for covariant return");
6313 if (Result.isNullPointer())
6317 LVal.setFrom(Info.Ctx, Result);
6319 const CXXRecordDecl *OldClass = Path[0]->getPointeeCXXRecordDecl();
6320 for (
unsigned I = 1; I != Path.size(); ++I) {
6321 const CXXRecordDecl *NewClass = Path[I]->getPointeeCXXRecordDecl();
6322 assert(OldClass && NewClass &&
"unexpected kind of covariant return");
6323 if (OldClass != NewClass &&
6326 OldClass = NewClass;
6329 LVal.moveInto(Result);
6338 auto *BaseClass = BaseSpec.getType()->getAsCXXRecordDecl();
6340 return BaseSpec.getAccessSpecifier() ==
AS_public;
6342 llvm_unreachable(
"Base is not a direct base of Derived");
6352 SubobjectDesignator &D = Ptr.Designator;
6358 if (Ptr.isNullPointer() && !E->
isGLValue())
6364 std::optional<DynamicType> DynType =
6376 assert(
C &&
"dynamic_cast target is not void pointer nor class");
6384 Ptr.setNull(Info.Ctx, E->
getType());
6391 DynType->Type->isDerivedFrom(
C)))
6393 else if (!Paths || Paths->begin() == Paths->end())
6395 else if (Paths->isAmbiguous(CQT))
6398 assert(Paths->front().Access !=
AS_public &&
"why did the cast fail?");
6401 Info.FFDiag(E, diag::note_constexpr_dynamic_cast_to_reference_failed)
6402 << DiagKind << Ptr.Designator.getType(Info.Ctx)
6411 for (
int PathLength = Ptr.Designator.Entries.size();
6412 PathLength >= (
int)DynType->PathLength; --PathLength) {
6417 if (PathLength > (
int)DynType->PathLength &&
6420 return RuntimeCheckFailed(
nullptr);
6427 if (DynType->Type->isDerivedFrom(
C, Paths) && !Paths.
isAmbiguous(CQT) &&
6440 return RuntimeCheckFailed(&Paths);
6444struct StartLifetimeOfUnionMemberHandler {
6446 const Expr *LHSExpr;
6447 const FieldDecl *
Field;
6449 bool Failed =
false;
6452 typedef bool result_type;
6453 bool failed() {
return Failed; }
6454 bool found(
APValue &Subobj, QualType SubobjType) {
6469 }
else if (DuringInit) {
6473 Info.FFDiag(LHSExpr,
6474 diag::note_constexpr_union_member_change_during_init);
6483 llvm_unreachable(
"wrong value kind for union object");
6485 bool found(APFloat &
Value, QualType SubobjType) {
6486 llvm_unreachable(
"wrong value kind for union object");
6491const AccessKinds StartLifetimeOfUnionMemberHandler::AccessKind;
6498 const Expr *LHSExpr,
6499 const LValue &LHS) {
6500 if (LHS.InvalidBase || LHS.Designator.Invalid)
6506 unsigned PathLength = LHS.Designator.Entries.size();
6507 for (
const Expr *E = LHSExpr; E !=
nullptr;) {
6509 if (
auto *ME = dyn_cast<MemberExpr>(E)) {
6510 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
6513 if (!FD || FD->getType()->isReferenceType())
6517 if (FD->getParent()->isUnion()) {
6522 FD->getType()->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
6523 if (!RD || RD->hasTrivialDefaultConstructor())
6524 UnionPathLengths.push_back({PathLength - 1, FD});
6530 LHS.Designator.Entries[PathLength]
6531 .getAsBaseOrMember().getPointer()));
6535 }
else if (
auto *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
6537 auto *
Base = ASE->getBase()->IgnoreImplicit();
6538 if (!
Base->getType()->isArrayType())
6544 }
else if (
auto *ICE = dyn_cast<ImplicitCastExpr>(E)) {
6547 if (ICE->getCastKind() == CK_NoOp)
6549 if (ICE->getCastKind() != CK_DerivedToBase &&
6550 ICE->getCastKind() != CK_UncheckedDerivedToBase)
6554 if (Elt->isVirtual()) {
6563 LHS.Designator.Entries[PathLength]
6564 .getAsBaseOrMember().getPointer()));
6574 if (UnionPathLengths.empty())
6579 CompleteObject Obj =
6583 for (std::pair<unsigned, const FieldDecl *> LengthAndField :
6584 llvm::reverse(UnionPathLengths)) {
6586 SubobjectDesignator D = LHS.Designator;
6587 D.truncate(Info.Ctx, LHS.Base, LengthAndField.first);
6589 bool DuringInit = Info.isEvaluatingCtorDtor(LHS.Base, D.Entries) ==
6590 ConstructionPhase::AfterBases;
6591 StartLifetimeOfUnionMemberHandler StartLifetime{
6592 Info, LHSExpr, LengthAndField.second, DuringInit};
6601 CallRef
Call, EvalInfo &Info,
bool NonNull =
false,
6602 APValue **EvaluatedArg =
nullptr) {
6609 APValue &
V = PVD ? Info.CurrentCall->createParam(
Call, PVD, LV)
6610 : Info.CurrentCall->createTemporary(Arg, Arg->
getType(),
6611 ScopeKind::Call, LV);
6617 if (
NonNull &&
V.isLValue() &&
V.isNullPointer()) {
6618 Info.CCEDiag(Arg, diag::note_non_null_attribute_failed);
6631 bool RightToLeft =
false,
6632 LValue *ObjectArg =
nullptr) {
6634 llvm::SmallBitVector ForbiddenNullArgs;
6635 if (Callee->hasAttr<NonNullAttr>()) {
6636 ForbiddenNullArgs.resize(Args.size());
6637 for (
const auto *
Attr : Callee->specific_attrs<NonNullAttr>()) {
6638 if (!
Attr->args_size()) {
6639 ForbiddenNullArgs.set();
6642 for (
auto Idx :
Attr->args()) {
6643 unsigned ASTIdx = Idx.getASTIndex();
6644 if (ASTIdx >= Args.size())
6646 ForbiddenNullArgs[ASTIdx] =
true;
6650 for (
unsigned I = 0; I < Args.size(); I++) {
6651 unsigned Idx = RightToLeft ? Args.size() - I - 1 : I;
6653 Idx < Callee->getNumParams() ? Callee->getParamDecl(Idx) :
nullptr;
6654 bool NonNull = !ForbiddenNullArgs.empty() && ForbiddenNullArgs[Idx];
6659 if (!Info.noteFailure())
6664 ObjectArg->setFrom(Info.Ctx, *That);
6673 bool CopyObjectRepresentation) {
6675 CallStackFrame *Frame = Info.CurrentCall;
6676 APValue *RefValue = Info.getParamSlot(Frame->Arguments, Param);
6684 RefLValue.setFrom(Info.Ctx, *RefValue);
6687 CopyObjectRepresentation);
6693 const LValue *ObjectArg,
const Expr *E,
6695 const Stmt *Body, EvalInfo &Info,
6696 APValue &Result,
const LValue *ResultSlot) {
6697 if (!Info.CheckCallLimit(CallLoc))
6726 ObjectArg->moveInto(Result);
6735 if (!Info.checkingPotentialConstantExpression())
6737 Frame.LambdaThisCaptureField);
6740 StmtResult Ret = {Result, ResultSlot};
6742 if (ESR == ESR_Succeeded) {
6743 if (Callee->getReturnType()->isVoidType())
6745 Info.FFDiag(Callee->getEndLoc(), diag::note_constexpr_no_return);
6747 return ESR == ESR_Returned;
6754 EvalInfo &Info,
APValue &Result) {
6756 if (!Info.CheckCallLimit(CallLoc))
6761 Info.FFDiag(CallLoc, diag::note_constexpr_virtual_base) << RD;
6765 EvalInfo::EvaluatingConstructorRAII EvalObj(
6767 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries},
6774 StmtResult Ret = {RetVal,
nullptr};
6779 if ((*I)->getInit()->isValueDependent()) {
6783 FullExpressionRAII InitScope(Info);
6785 !InitScope.destroy())
6808 if (!Result.hasValue()) {
6821 BlockScopeRAII LifetimeExtendedScope(Info);
6824 unsigned BasesSeen = 0;
6829 auto SkipToField = [&](
FieldDecl *FD,
bool Indirect) {
6834 assert(Indirect &&
"fields out of order?");
6840 assert(FieldIt != RD->
field_end() &&
"missing field?");
6841 if (!FieldIt->isUnnamedBitField())
6844 Result.getStructField(FieldIt->getFieldIndex()));
6849 LValue Subobject =
This;
6850 LValue SubobjectParent =
This;
6855 if (I->isBaseInitializer()) {
6856 QualType BaseType(I->getBaseClass(), 0);
6860 assert(!BaseIt->
isVirtual() &&
"virtual base for literal type");
6862 "base class initializers not in expected order");
6866 BaseType->getAsCXXRecordDecl(), &Layout))
6868 Value = &Result.getStructBase(BasesSeen++);
6869 }
else if ((FD = I->getMember())) {
6874 Value = &Result.getUnionValue();
6876 SkipToField(FD,
false);
6882 auto IndirectFieldChain = IFD->chain();
6883 for (
auto *
C : IndirectFieldChain) {
6892 (
Value->isUnion() &&
6905 if (
C == IndirectFieldChain.back())
6906 SubobjectParent = Subobject;
6912 if (
C == IndirectFieldChain.front() && !RD->
isUnion())
6913 SkipToField(FD,
true);
6918 llvm_unreachable(
"unknown base initializer kind");
6925 if (
Init->isValueDependent()) {
6929 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &SubobjectParent,
6931 FullExpressionRAII InitScope(Info);
6937 if (!Info.noteFailure())
6946 if (!Info.noteFailure())
6954 if (I->isBaseInitializer() && BasesSeen == RD->
getNumBases())
6955 EvalObj.finishedConstructingBases();
6960 for (; FieldIt != RD->
field_end(); ++FieldIt) {
6961 if (!FieldIt->isUnnamedBitField())
6964 Result.getStructField(FieldIt->getFieldIndex()));
6968 EvalObj.finishedConstructingFields();
6972 LifetimeExtendedScope.destroy();
6978 EvalInfo &Info,
APValue &Result) {
6979 CallScopeRAII CallScope(Info);
6985 CallScope.destroy();
6995 if (
Value.isAbsent() && !
T->isNullPtrType()) {
6997 This.moveInto(Printable);
6999 diag::note_constexpr_destroy_out_of_lifetime)
7016 LValue ElemLV =
This;
7017 ElemLV.addArray(Info, &LocE, CAT);
7024 if (Size && Size >
Value.getArrayInitializedElts())
7029 for (Size =
Value.getArraySize(); Size != 0; --Size) {
7030 APValue &Elem =
Value.getArrayInitializedElt(Size - 1);
7043 if (
T.isDestructedType()) {
7045 diag::note_constexpr_unsupported_destruction)
7055 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_virtual_base) << RD;
7080 if (!Info.CheckCallLimit(CallRange.
getBegin()))
7089 CallStackFrame Frame(Info, CallRange,
Definition, &
This,
nullptr,
7094 EvalInfo::EvaluatingDestructorRAII EvalObj(
7096 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries});
7097 if (!EvalObj.DidInsert) {
7104 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_double_destroy);
7111 StmtResult Ret = {RetVal,
nullptr};
7124 for (
const FieldDecl *FD : llvm::reverse(Fields)) {
7125 if (FD->isUnnamedBitField())
7128 LValue Subobject =
This;
7132 APValue *SubobjectValue = &
Value.getStructField(FD->getFieldIndex());
7139 EvalObj.startedDestroyingBases();
7146 LValue Subobject =
This;
7148 BaseType->getAsCXXRecordDecl(), &Layout))
7151 APValue *SubobjectValue = &
Value.getStructBase(BasesLeft);
7156 assert(BasesLeft == 0 &&
"NumBases was wrong?");
7164struct DestroyObjectHandler {
7170 typedef bool result_type;
7171 bool failed() {
return false; }
7172 bool found(
APValue &Subobj, QualType SubobjType) {
7177 Info.FFDiag(E, diag::note_constexpr_destroy_complex_elem);
7180 bool found(APFloat &
Value, QualType SubobjType) {
7181 Info.FFDiag(E, diag::note_constexpr_destroy_complex_elem);
7213 if (Info.checkingPotentialConstantExpression() ||
7214 Info.SpeculativeEvaluationDepth)
7218 auto Caller = Info.getStdAllocatorCaller(
"allocate");
7220 Info.FFDiag(E->
getExprLoc(), Info.getLangOpts().CPlusPlus20
7221 ? diag::note_constexpr_new_untyped
7222 : diag::note_constexpr_new);
7226 QualType ElemType = Caller.ElemType;
7229 diag::note_constexpr_new_not_complete_object_type)
7237 bool IsNothrow =
false;
7238 for (
unsigned I = 1, N = E->
getNumArgs(); I != N; ++I) {
7246 APInt Size, Remainder;
7247 APInt ElemSizeAP(ByteSize.getBitWidth(), ElemSize.
getQuantity());
7248 APInt::udivrem(ByteSize, ElemSizeAP, Size, Remainder);
7249 if (Remainder != 0) {
7251 Info.FFDiag(E->
getExprLoc(), diag::note_constexpr_operator_new_bad_size)
7252 << ByteSize <<
APSInt(ElemSizeAP,
true) << ElemType;
7256 if (!Info.CheckArraySize(E->
getBeginLoc(), ByteSize.getActiveBits(),
7257 Size.getZExtValue(), !IsNothrow)) {
7259 Result.setNull(Info.Ctx, E->
getType());
7267 APValue *Val = Info.createHeapAlloc(Caller.Call, AllocType, Result);
7276 return DD->isVirtual();
7283 return DD->isVirtual() ? DD->getOperatorDelete() :
nullptr;
7294 DynAlloc::Kind DeallocKind) {
7295 auto PointerAsString = [&] {
7301 Info.FFDiag(E, diag::note_constexpr_delete_not_heap_alloc)
7302 << PointerAsString();
7305 return std::nullopt;
7308 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
7310 Info.FFDiag(E, diag::note_constexpr_double_delete);
7311 return std::nullopt;
7314 if (DeallocKind != (*Alloc)->getKind()) {
7316 Info.FFDiag(E, diag::note_constexpr_new_delete_mismatch)
7317 << DeallocKind << (*Alloc)->getKind() << AllocType;
7319 return std::nullopt;
7322 bool Subobject =
false;
7323 if (DeallocKind == DynAlloc::New) {
7324 Subobject =
Pointer.Designator.MostDerivedPathLength != 0 ||
7325 Pointer.Designator.isOnePastTheEnd();
7327 Subobject =
Pointer.Designator.Entries.size() != 1 ||
7328 Pointer.Designator.Entries[0].getAsArrayIndex() != 0;
7331 Info.FFDiag(E, diag::note_constexpr_delete_subobject)
7332 << PointerAsString() <<
Pointer.Designator.isOnePastTheEnd();
7333 return std::nullopt;
7341 if (Info.checkingPotentialConstantExpression() ||
7342 Info.SpeculativeEvaluationDepth)
7346 if (!Info.getStdAllocatorCaller(
"deallocate")) {
7354 for (
unsigned I = 1, N = E->
getNumArgs(); I != N; ++I)
7357 if (
Pointer.Designator.Invalid)
7362 if (
Pointer.isNullPointer()) {
7363 Info.CCEDiag(E->
getExprLoc(), diag::note_constexpr_deallocate_null);
7379class BitCastBuffer {
7385 SmallVector<std::optional<unsigned char>, 32> Bytes;
7387 static_assert(std::numeric_limits<unsigned char>::digits >= 8,
7388 "Need at least 8 bit unsigned char");
7390 bool TargetIsLittleEndian;
7393 BitCastBuffer(CharUnits Width,
bool TargetIsLittleEndian)
7394 : Bytes(Width.getQuantity()),
7395 TargetIsLittleEndian(TargetIsLittleEndian) {}
7397 [[nodiscard]]
bool readObject(CharUnits Offset, CharUnits Width,
7398 SmallVectorImpl<unsigned char> &Output)
const {
7399 for (CharUnits I = Offset, E = Offset + Width; I != E; ++I) {
7402 if (!Bytes[I.getQuantity()])
7404 Output.push_back(*Bytes[I.getQuantity()]);
7406 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
7407 std::reverse(Output.begin(), Output.end());
7411 void writeObject(CharUnits Offset, SmallVectorImpl<unsigned char> &Input) {
7412 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
7413 std::reverse(Input.begin(), Input.end());
7416 for (
unsigned char Byte : Input) {
7417 assert(!Bytes[Offset.
getQuantity() + Index] &&
"overwriting a byte?");
7423 size_t size() {
return Bytes.size(); }
7428class APValueToBufferConverter {
7430 BitCastBuffer Buffer;
7433 APValueToBufferConverter(EvalInfo &Info, CharUnits ObjectWidth,
7436 Buffer(ObjectWidth, Info.Ctx.getTargetInfo().isLittleEndian()),
7439 bool visit(
const APValue &Val, QualType Ty) {
7444 bool visit(
const APValue &Val, QualType Ty, CharUnits Offset) {
7445 assert((
size_t)Offset.
getQuantity() <= Buffer.size());
7458 return visitInt(Val.
getInt(), Ty, Offset);
7460 return visitFloat(Val.
getFloat(), Ty, Offset);
7462 return visitArray(Val, Ty, Offset);
7464 return visitRecord(Val, Ty, Offset);
7466 return visitVector(Val, Ty, Offset);
7470 return visitComplex(Val, Ty, Offset);
7478 diag::note_constexpr_bit_cast_unsupported_type)
7484 llvm_unreachable(
"LValue subobject in bit_cast?");
7486 llvm_unreachable(
"Unhandled APValue::ValueKind");
7489 bool visitRecord(
const APValue &Val, QualType Ty, CharUnits Offset) {
7494 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
7495 for (
size_t I = 0, E = CXXRD->getNumBases(); I != E; ++I) {
7496 const CXXBaseSpecifier &BS = CXXRD->bases_begin()[I];
7501 if (!
Base.isStruct())
7504 if (!visitRecord(Base, BS.
getType(),
7511 unsigned FieldIdx = 0;
7512 for (FieldDecl *FD : RD->
fields()) {
7513 if (FD->isBitField()) {
7515 diag::note_constexpr_bit_cast_unsupported_bitfield);
7521 assert(FieldOffsetBits % Info.Ctx.
getCharWidth() == 0 &&
7522 "only bit-fields can have sub-char alignment");
7523 CharUnits FieldOffset =
7525 QualType FieldTy = FD->getType();
7534 bool visitArray(
const APValue &Val, QualType Ty, CharUnits Offset) {
7544 for (
unsigned I = 0; I != NumInitializedElts; ++I) {
7546 if (!visit(SubObj, CAT->
getElementType(), Offset + I * ElemWidth))
7553 for (
unsigned I = NumInitializedElts; I != ArraySize; ++I) {
7554 if (!visit(Filler, CAT->
getElementType(), Offset + I * ElemWidth))
7562 bool visitComplex(
const APValue &Val, QualType Ty, CharUnits Offset) {
7563 const ComplexType *ComplexTy = Ty->
castAs<ComplexType>();
7570 Offset + (0 * EltSizeChars)))
7573 Offset + (1 * EltSizeChars)))
7577 Offset + (0 * EltSizeChars)))
7580 Offset + (1 * EltSizeChars)))
7587 bool visitVector(
const APValue &Val, QualType Ty, CharUnits Offset) {
7588 const VectorType *VTy = Ty->
castAs<VectorType>();
7603 llvm::APInt Res = llvm::APInt::getZero(NElts);
7604 for (
unsigned I = 0; I < NElts; ++I) {
7606 assert(EltAsInt.isUnsigned() && EltAsInt.getBitWidth() == 1 &&
7607 "bool vector element must be 1-bit unsigned integer!");
7609 Res.insertBits(EltAsInt, BigEndian ? (NElts - I - 1) : I);
7612 SmallVector<uint8_t, 8> Bytes(NElts / 8);
7613 llvm::StoreIntToMemory(Res, &*Bytes.begin(), NElts / 8);
7614 Buffer.writeObject(Offset, Bytes);
7619 for (
unsigned I = 0; I < NElts; ++I) {
7620 if (!visit(Val.
getVectorElt(I), EltTy, Offset + I * EltSizeChars))
7628 bool visitInt(
const APSInt &Val, QualType Ty, CharUnits Offset) {
7629 APSInt AdjustedVal = Val;
7630 unsigned Width = AdjustedVal.getBitWidth();
7633 AdjustedVal = AdjustedVal.extend(Width);
7636 SmallVector<uint8_t, 8> Bytes(Width / 8);
7637 llvm::StoreIntToMemory(AdjustedVal, &*Bytes.begin(), Width / 8);
7638 Buffer.writeObject(Offset, Bytes);
7642 bool visitFloat(
const APFloat &Val, QualType Ty, CharUnits Offset) {
7643 APSInt AsInt(Val.bitcastToAPInt());
7644 return visitInt(AsInt, Ty, Offset);
7648 static std::optional<BitCastBuffer>
7651 APValueToBufferConverter Converter(Info, DstSize, BCE);
7653 return std::nullopt;
7654 return Converter.Buffer;
7659class BufferToAPValueConverter {
7661 const BitCastBuffer &Buffer;
7664 BufferToAPValueConverter(EvalInfo &Info,
const BitCastBuffer &Buffer,
7666 : Info(Info), Buffer(Buffer), BCE(BCE) {}
7671 std::nullopt_t unsupportedType(QualType Ty) {
7673 diag::note_constexpr_bit_cast_unsupported_type)
7675 return std::nullopt;
7678 std::nullopt_t unrepresentableValue(QualType Ty,
const APSInt &Val) {
7680 diag::note_constexpr_bit_cast_unrepresentable_value)
7682 return std::nullopt;
7685 std::optional<APValue> visit(
const BuiltinType *
T, CharUnits Offset,
7686 const EnumType *EnumSugar =
nullptr) {
7689 return APValue((Expr *)
nullptr,
7691 APValue::NoLValuePath{},
true);
7700 const llvm::fltSemantics &Semantics =
7702 unsigned NumBits = llvm::APFloatBase::getSizeInBits(Semantics);
7703 assert(NumBits % 8 == 0);
7709 SmallVector<uint8_t, 8> Bytes;
7710 if (!Buffer.readObject(Offset,
SizeOf, Bytes)) {
7713 bool IsStdByte = EnumSugar && EnumSugar->isStdByteType();
7717 if (!IsStdByte && !IsUChar) {
7718 QualType DisplayType(EnumSugar ? (
const Type *)EnumSugar :
T, 0);
7720 diag::note_constexpr_bit_cast_indet_dest)
7721 << DisplayType << Info.Ctx.
getLangOpts().CharIsSigned;
7722 return std::nullopt;
7729 llvm::LoadIntFromMemory(Val, &*Bytes.begin(), Bytes.size());
7734 unsigned IntWidth = Info.Ctx.
getIntWidth(QualType(
T, 0));
7735 if (IntWidth != Val.getBitWidth()) {
7736 APSInt Truncated = Val.trunc(IntWidth);
7737 if (Truncated.extend(Val.getBitWidth()) != Val)
7738 return unrepresentableValue(QualType(
T, 0), Val);
7746 const llvm::fltSemantics &Semantics =
7751 return unsupportedType(QualType(
T, 0));
7754 std::optional<APValue> visit(
const RecordType *RTy, CharUnits Offset) {
7755 const RecordDecl *RD = RTy->getAsRecordDecl();
7758 unsigned NumBases = 0;
7759 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
7760 NumBases = CXXRD->getNumBases();
7762 APValue ResultVal(APValue::UninitStruct(), NumBases,
7766 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
7767 for (
size_t I = 0, E = CXXRD->getNumBases(); I != E; ++I) {
7768 const CXXBaseSpecifier &BS = CXXRD->bases_begin()[I];
7771 std::optional<APValue> SubObj = visitType(
7774 return std::nullopt;
7775 ResultVal.getStructBase(I) = *SubObj;
7780 unsigned FieldIdx = 0;
7781 for (FieldDecl *FD : RD->
fields()) {
7784 if (FD->isBitField()) {
7786 diag::note_constexpr_bit_cast_unsupported_bitfield);
7787 return std::nullopt;
7791 assert(FieldOffsetBits % Info.Ctx.
getCharWidth() == 0);
7793 CharUnits FieldOffset =
7796 QualType FieldTy = FD->getType();
7797 std::optional<APValue> SubObj = visitType(FieldTy, FieldOffset);
7799 return std::nullopt;
7800 ResultVal.getStructField(FieldIdx) = *SubObj;
7807 std::optional<APValue> visit(
const EnumType *Ty, CharUnits Offset) {
7808 QualType RepresentationType =
7809 Ty->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType();
7810 assert(!RepresentationType.
isNull() &&
7811 "enum forward decl should be caught by Sema");
7812 const auto *AsBuiltin =
7816 return visit(AsBuiltin, Offset, Ty);
7819 std::optional<APValue> visit(
const ConstantArrayType *Ty, CharUnits Offset) {
7823 APValue ArrayValue(APValue::UninitArray(), Size, Size);
7824 for (
size_t I = 0; I !=
Size; ++I) {
7825 std::optional<APValue> ElementValue =
7828 return std::nullopt;
7829 ArrayValue.getArrayInitializedElt(I) = std::move(*ElementValue);
7835 std::optional<APValue> visit(
const ComplexType *Ty, CharUnits Offset) {
7840 std::optional<APValue> Values[2];
7841 for (
unsigned I = 0; I != 2; ++I) {
7842 Values[I] = visitType(Ty->
getElementType(), Offset + I * ElementWidth);
7844 return std::nullopt;
7848 return APValue(Values[0]->getInt(), Values[1]->getInt());
7849 return APValue(Values[0]->getFloat(), Values[1]->getFloat());
7852 std::optional<APValue> visit(
const VectorType *VTy, CharUnits Offset) {
7858 SmallVector<APValue, 4> Elts;
7859 Elts.reserve(NElts);
7871 SmallVector<uint8_t, 8> Bytes;
7872 Bytes.reserve(NElts / 8);
7874 return std::nullopt;
7876 APSInt SValInt(NElts,
true);
7877 llvm::LoadIntFromMemory(SValInt, &*Bytes.begin(), Bytes.size());
7879 for (
unsigned I = 0; I < NElts; ++I) {
7881 SValInt.extractBits(1, (BigEndian ? NElts - I - 1 : I) * EltSize);
7889 for (
unsigned I = 0; I < NElts; ++I) {
7890 std::optional<APValue> EltValue =
7891 visitType(EltTy, Offset + I * EltSizeChars);
7893 return std::nullopt;
7894 Elts.push_back(std::move(*EltValue));
7898 return APValue(Elts.data(), Elts.size());
7901 std::optional<APValue> visit(
const Type *Ty, CharUnits Offset) {
7902 return unsupportedType(QualType(Ty, 0));
7905 std::optional<APValue> visitType(QualType Ty, CharUnits Offset) {
7909#define TYPE(Class, Base) \
7911 return visit(cast<Class##Type>(Can.getTypePtr()), Offset);
7912#define ABSTRACT_TYPE(Class, Base)
7913#define NON_CANONICAL_TYPE(Class, Base) \
7915 llvm_unreachable("non-canonical type should be impossible!");
7916#define DEPENDENT_TYPE(Class, Base) \
7919 "dependent types aren't supported in the constant evaluator!");
7920#define NON_CANONICAL_UNLESS_DEPENDENT(Class, Base) \
7922 llvm_unreachable("either dependent or not canonical!");
7923#include "clang/AST/TypeNodes.inc"
7925 llvm_unreachable(
"Unhandled Type::TypeClass");
7930 static std::optional<APValue> convert(EvalInfo &Info, BitCastBuffer &Buffer,
7932 BufferToAPValueConverter Converter(Info, Buffer, BCE);
7937static bool checkBitCastConstexprEligibilityType(SourceLocation Loc,
7938 QualType Ty, EvalInfo *Info,
7939 const ASTContext &Ctx,
7940 bool CheckingDest) {
7943 auto diag = [&](
int Reason) {
7945 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_invalid_type)
7946 << CheckingDest << (Reason == 4) << Reason;
7949 auto note = [&](
int Construct, QualType NoteTy, SourceLocation NoteLoc) {
7951 Info->Note(NoteLoc, diag::note_constexpr_bit_cast_invalid_subtype)
7952 << NoteTy << Construct << Ty;
7966 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(
Record)) {
7967 for (CXXBaseSpecifier &BS : CXXRD->bases())
7968 if (!checkBitCastConstexprEligibilityType(Loc, BS.
getType(), Info, Ctx,
7972 for (FieldDecl *FD :
Record->fields()) {
7973 if (FD->getType()->isReferenceType())
7975 if (!checkBitCastConstexprEligibilityType(Loc, FD->getType(), Info, Ctx,
7977 return note(0, FD->getType(), FD->getBeginLoc());
7983 Info, Ctx, CheckingDest))
7986 if (
const auto *VTy = Ty->
getAs<VectorType>()) {
7998 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_invalid_vector)
7999 << QualType(VTy, 0) << EltSize << NElts << Ctx.
getCharWidth();
8009 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_unsupported_type)
8018static bool checkBitCastConstexprEligibility(EvalInfo *Info,
8019 const ASTContext &Ctx,
8021 bool DestOK = checkBitCastConstexprEligibilityType(
8023 bool SourceOK = DestOK && checkBitCastConstexprEligibilityType(
8029static bool handleRValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
8033 "no host or target supports non 8-bit chars");
8035 if (!checkBitCastConstexprEligibility(&Info, Info.Ctx, BCE))
8039 std::optional<BitCastBuffer> Buffer =
8040 APValueToBufferConverter::convert(Info, SourceRValue, BCE);
8045 std::optional<APValue> MaybeDestValue =
8046 BufferToAPValueConverter::convert(Info, *Buffer, BCE);
8047 if (!MaybeDestValue)
8050 DestValue = std::move(*MaybeDestValue);
8054static bool handleLValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
8058 "no host or target supports non 8-bit chars");
8060 "LValueToRValueBitcast requires an lvalue operand!");
8062 LValue SourceLValue;
8064 SourceLValue.setFrom(Info.Ctx, SourceValue);
8067 SourceRValue,
true))
8070 return handleRValueToRValueBitCast(Info, DestValue, SourceRValue, BCE);
8073template <
class Derived>
8074class ExprEvaluatorBase
8075 :
public ConstStmtVisitor<Derived, bool> {
8077 Derived &getDerived() {
return static_cast<Derived&
>(*this); }
8078 bool DerivedSuccess(
const APValue &
V,
const Expr *E) {
8079 return getDerived().Success(
V, E);
8081 bool DerivedZeroInitialization(
const Expr *E) {
8082 return getDerived().ZeroInitialization(E);
8088 template<
typename ConditionalOperator>
8089 void CheckPotentialConstantConditional(
const ConditionalOperator *E) {
8090 assert(Info.checkingPotentialConstantExpression());
8093 SmallVector<PartialDiagnosticAt, 8>
Diag;
8095 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
8102 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
8109 Error(E, diag::note_constexpr_conditional_never_const);
8113 template<
typename ConditionalOperator>
8114 bool HandleConditionalOperator(
const ConditionalOperator *E) {
8117 if (Info.checkingPotentialConstantExpression() && Info.noteFailure()) {
8118 CheckPotentialConstantConditional(E);
8121 if (Info.noteFailure()) {
8129 return StmtVisitorTy::Visit(EvalExpr);
8134 typedef ConstStmtVisitor<Derived, bool> StmtVisitorTy;
8135 typedef ExprEvaluatorBase ExprEvaluatorBaseTy;
8137 OptionalDiagnostic CCEDiag(
const Expr *E,
diag::kind D) {
8138 return Info.CCEDiag(E, D);
8141 bool ZeroInitialization(
const Expr *E) {
return Error(E); }
8143 bool IsConstantEvaluatedBuiltinCall(
const CallExpr *E) {
8145 return BuiltinOp != 0 &&
8150 ExprEvaluatorBase(EvalInfo &Info) : Info(Info) {}
8152 EvalInfo &getEvalInfo() {
return Info; }
8160 bool Error(
const Expr *E) {
8161 return Error(E, diag::note_invalid_subexpr_in_const_expr);
8164 bool VisitStmt(
const Stmt *) {
8165 llvm_unreachable(
"Expression evaluator should not be called on stmts");
8167 bool VisitExpr(
const Expr *E) {
8171 bool VisitEmbedExpr(
const EmbedExpr *E) {
8172 const auto It = E->
begin();
8173 return StmtVisitorTy::Visit(*It);
8176 bool VisitPredefinedExpr(
const PredefinedExpr *E) {
8179 bool VisitConstantExpr(
const ConstantExpr *E) {
8183 return StmtVisitorTy::Visit(E->
getSubExpr());
8186 bool VisitParenExpr(
const ParenExpr *E)
8187 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8188 bool VisitUnaryExtension(
const UnaryOperator *E)
8189 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8190 bool VisitUnaryPlus(
const UnaryOperator *E)
8191 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8192 bool VisitChooseExpr(
const ChooseExpr *E)
8194 bool VisitGenericSelectionExpr(
const GenericSelectionExpr *E)
8196 bool VisitSubstNonTypeTemplateParmExpr(
const SubstNonTypeTemplateParmExpr *E)
8198 bool VisitCXXDefaultArgExpr(
const CXXDefaultArgExpr *E) {
8199 TempVersionRAII RAII(*Info.CurrentCall);
8200 SourceLocExprScopeGuard Guard(E, Info.CurrentCall->CurSourceLocExprScope);
8201 return StmtVisitorTy::Visit(E->
getExpr());
8203 bool VisitCXXDefaultInitExpr(
const CXXDefaultInitExpr *E) {
8204 TempVersionRAII RAII(*Info.CurrentCall);
8208 SourceLocExprScopeGuard Guard(E, Info.CurrentCall->CurSourceLocExprScope);
8209 return StmtVisitorTy::Visit(E->
getExpr());
8212 bool VisitExprWithCleanups(
const ExprWithCleanups *E) {
8213 FullExpressionRAII Scope(Info);
8214 return StmtVisitorTy::Visit(E->
getSubExpr()) && Scope.destroy();
8219 bool VisitCXXBindTemporaryExpr(
const CXXBindTemporaryExpr *E) {
8220 return StmtVisitorTy::Visit(E->
getSubExpr());
8223 bool VisitCXXReinterpretCastExpr(
const CXXReinterpretCastExpr *E) {
8224 CCEDiag(E, diag::note_constexpr_invalid_cast)
8225 << diag::ConstexprInvalidCastKind::Reinterpret;
8226 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8228 bool VisitCXXDynamicCastExpr(
const CXXDynamicCastExpr *E) {
8230 CCEDiag(E, diag::note_constexpr_invalid_cast)
8231 << diag::ConstexprInvalidCastKind::Dynamic;
8232 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8234 bool VisitBuiltinBitCastExpr(
const BuiltinBitCastExpr *E) {
8235 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8238 bool VisitBinaryOperator(
const BinaryOperator *E) {
8244 VisitIgnoredValue(E->
getLHS());
8245 return StmtVisitorTy::Visit(E->
getRHS());
8255 return DerivedSuccess(
Result, E);
8260 bool VisitCXXRewrittenBinaryOperator(
const CXXRewrittenBinaryOperator *E) {
8264 bool VisitBinaryConditionalOperator(
const BinaryConditionalOperator *E) {
8268 if (!
Evaluate(Info.CurrentCall->createTemporary(
8271 ScopeKind::FullExpression, CommonLV),
8275 return HandleConditionalOperator(E);
8278 bool VisitConditionalOperator(
const ConditionalOperator *E) {
8279 bool IsBcpCall =
false;
8284 if (
const CallExpr *CallCE =
8286 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
8293 if (Info.checkingPotentialConstantExpression() && IsBcpCall)
8296 FoldConstant Fold(Info, IsBcpCall);
8297 if (!HandleConditionalOperator(E)) {
8298 Fold.keepDiagnostics();
8305 bool VisitOpaqueValueExpr(
const OpaqueValueExpr *E) {
8306 if (
APValue *
Value = Info.CurrentCall->getCurrentTemporary(E);
8308 return DerivedSuccess(*
Value, E);
8314 assert(0 &&
"OpaqueValueExpr recursively refers to itself");
8317 return StmtVisitorTy::Visit(Source);
8320 bool VisitPseudoObjectExpr(
const PseudoObjectExpr *E) {
8321 for (
const Expr *SemE : E->
semantics()) {
8322 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
8331 if (OVE->isUnique())
8335 if (!
Evaluate(Info.CurrentCall->createTemporary(
8336 OVE, getStorageType(Info.Ctx, OVE),
8337 ScopeKind::FullExpression, LV),
8338 Info, OVE->getSourceExpr()))
8341 if (!StmtVisitorTy::Visit(SemE))
8351 bool VisitCallExpr(
const CallExpr *E) {
8353 if (!handleCallExpr(E,
Result,
nullptr))
8355 return DerivedSuccess(
Result, E);
8359 const LValue *ResultSlot) {
8360 CallScopeRAII CallScope(Info);
8363 QualType CalleeType =
Callee->getType();
8365 const FunctionDecl *FD =
nullptr;
8366 LValue *
This =
nullptr, ObjectArg;
8368 bool HasQualifier =
false;
8374 const CXXMethodDecl *
Member =
nullptr;
8375 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(Callee)) {
8379 Member = dyn_cast<CXXMethodDecl>(ME->getMemberDecl());
8381 return Error(Callee);
8383 HasQualifier = ME->hasQualifier();
8384 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(Callee)) {
8386 const ValueDecl *D =
8390 Member = dyn_cast<CXXMethodDecl>(D);
8392 return Error(Callee);
8394 }
else if (
const auto *PDE = dyn_cast<CXXPseudoDestructorExpr>(Callee)) {
8395 if (!Info.getLangOpts().CPlusPlus20)
8396 Info.CCEDiag(PDE, diag::note_constexpr_pseudo_destructor);
8400 return Error(Callee);
8407 if (!CalleeLV.getLValueOffset().isZero())
8408 return Error(Callee);
8409 if (CalleeLV.isNullPointer()) {
8410 Info.FFDiag(Callee, diag::note_constexpr_null_callee)
8411 <<
const_cast<Expr *
>(
Callee);
8414 FD = dyn_cast_or_null<FunctionDecl>(
8415 CalleeLV.getLValueBase().dyn_cast<
const ValueDecl *>());
8417 return Error(Callee);
8427 auto *OCE = dyn_cast<CXXOperatorCallExpr>(E);
8428 if (OCE && OCE->isAssignmentOp()) {
8429 assert(Args.size() == 2 &&
"wrong number of arguments in assignment");
8430 Call = Info.CurrentCall->createCall(FD);
8431 bool HasThis =
false;
8432 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FD))
8433 HasThis = MD->isImplicitObjectMemberFunction();
8441 const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD);
8461 if (Info.getLangOpts().CPlusPlus20 && OCE &&
8462 OCE->getOperator() == OO_Equal && MD->
isTrivial() &&
8466 Args = Args.slice(1);
8472 const CXXRecordDecl *ClosureClass = MD->
getParent();
8474 ClosureClass->
captures().empty() &&
8475 "Number of captures must be zero for conversion to function-ptr");
8477 const CXXMethodDecl *LambdaCallOp =
8486 "A generic lambda's static-invoker function must be a "
8487 "template specialization");
8489 FunctionTemplateDecl *CallOpTemplate =
8491 void *InsertPos =
nullptr;
8492 FunctionDecl *CorrespondingCallOpSpecialization =
8494 assert(CorrespondingCallOpSpecialization &&
8495 "We must always have a function call operator specialization "
8496 "that corresponds to our static invoker specialization");
8498 FD = CorrespondingCallOpSpecialization;
8507 return CallScope.destroy();
8517 Call = Info.CurrentCall->createCall(FD);
8523 SmallVector<QualType, 4> CovariantAdjustmentPath;
8525 auto *NamedMember = dyn_cast<CXXMethodDecl>(FD);
8526 if (NamedMember && NamedMember->isVirtual() && !HasQualifier) {
8529 CovariantAdjustmentPath);
8532 }
else if (NamedMember && NamedMember->isImplicitObjectMemberFunction()) {
8542 if (
auto *DD = dyn_cast<CXXDestructorDecl>(FD)) {
8543 assert(This &&
"no 'this' pointer for destructor call");
8546 CallScope.destroy();
8563 if (!CovariantAdjustmentPath.empty() &&
8565 CovariantAdjustmentPath))
8568 return CallScope.destroy();
8571 bool VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E) {
8574 bool VisitInitListExpr(
const InitListExpr *E) {
8576 return DerivedZeroInitialization(E);
8578 return StmtVisitorTy::Visit(E->
getInit(0));
8581 bool VisitImplicitValueInitExpr(
const ImplicitValueInitExpr *E) {
8582 return DerivedZeroInitialization(E);
8584 bool VisitCXXScalarValueInitExpr(
const CXXScalarValueInitExpr *E) {
8585 return DerivedZeroInitialization(E);
8587 bool VisitCXXNullPtrLiteralExpr(
const CXXNullPtrLiteralExpr *E) {
8588 return DerivedZeroInitialization(E);
8592 bool VisitMemberExpr(
const MemberExpr *E) {
8594 "missing temporary materialization conversion");
8595 assert(!E->
isArrow() &&
"missing call to bound member function?");
8603 const FieldDecl *FD = dyn_cast<FieldDecl>(E->
getMemberDecl());
8604 if (!FD)
return Error(E);
8608 "record / field mismatch");
8613 CompleteObject Obj(APValue::LValueBase(), &Val, BaseTy);
8614 SubobjectDesignator Designator(BaseTy);
8615 Designator.addDeclUnchecked(FD);
8619 DerivedSuccess(
Result, E);
8622 bool VisitExtVectorElementExpr(
const ExtVectorElementExpr *E) {
8628 SmallVector<uint32_t, 4> Indices;
8630 if (Indices.size() == 1) {
8632 return DerivedSuccess(Val.
getVectorElt(Indices[0]), E);
8635 SmallVector<APValue, 4> Elts;
8636 for (
unsigned I = 0; I < Indices.size(); ++I) {
8639 APValue VecResult(Elts.data(), Indices.size());
8640 return DerivedSuccess(VecResult, E);
8647 bool VisitCastExpr(
const CastExpr *E) {
8652 case CK_AtomicToNonAtomic: {
8659 return DerivedSuccess(AtomicVal, E);
8663 case CK_UserDefinedConversion:
8664 return StmtVisitorTy::Visit(E->
getSubExpr());
8666 case CK_LValueToRValue: {
8675 return DerivedSuccess(RVal, E);
8677 case CK_LValueToRValueBitCast: {
8678 APValue DestValue, SourceValue;
8681 if (!handleLValueToRValueBitCast(Info, DestValue, SourceValue, E))
8683 return DerivedSuccess(DestValue, E);
8686 case CK_AddressSpaceConversion: {
8690 return DerivedSuccess(
Value, E);
8697 bool VisitUnaryPostInc(
const UnaryOperator *UO) {
8698 return VisitUnaryPostIncDec(UO);
8700 bool VisitUnaryPostDec(
const UnaryOperator *UO) {
8701 return VisitUnaryPostIncDec(UO);
8703 bool VisitUnaryPostIncDec(
const UnaryOperator *UO) {
8704 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
8714 return DerivedSuccess(RVal, UO);
8717 bool VisitStmtExpr(
const StmtExpr *E) {
8720 llvm::SaveAndRestore NotCheckingForUB(Info.CheckingForUndefinedBehavior,
8727 BlockScopeRAII Scope(Info);
8732 const Expr *FinalExpr = dyn_cast<Expr>(*BI);
8734 Info.FFDiag((*BI)->getBeginLoc(),
8735 diag::note_constexpr_stmt_expr_unsupported);
8738 return this->Visit(FinalExpr) && Scope.destroy();
8744 if (ESR != ESR_Succeeded) {
8748 if (ESR != ESR_Failed)
8749 Info.FFDiag((*BI)->getBeginLoc(),
8750 diag::note_constexpr_stmt_expr_unsupported);
8755 llvm_unreachable(
"Return from function from the loop above.");
8758 bool VisitPackIndexingExpr(
const PackIndexingExpr *E) {
8763 void VisitIgnoredValue(
const Expr *E) {
8768 void VisitIgnoredBaseExpression(
const Expr *E) {
8771 if (Info.getLangOpts().MSVCCompat && !E->
HasSideEffects(Info.Ctx))
8773 VisitIgnoredValue(E);
8783template<
class Derived>
8784class LValueExprEvaluatorBase
8785 :
public ExprEvaluatorBase<Derived> {
8789 typedef LValueExprEvaluatorBase LValueExprEvaluatorBaseTy;
8790 typedef ExprEvaluatorBase<Derived> ExprEvaluatorBaseTy;
8792 bool Success(APValue::LValueBase B) {
8797 bool evaluatePointer(
const Expr *E, LValue &
Result) {
8802 LValueExprEvaluatorBase(EvalInfo &Info, LValue &
Result,
bool InvalidBaseOK)
8804 InvalidBaseOK(InvalidBaseOK) {}
8807 Result.setFrom(this->Info.Ctx,
V);
8811 bool VisitMemberExpr(
const MemberExpr *E) {
8823 EvalOK = this->Visit(E->
getBase());
8834 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(E->
getMemberDecl())) {
8837 "record / field mismatch");
8841 }
else if (
const IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(MD)) {
8845 return this->
Error(E);
8857 bool VisitBinaryOperator(
const BinaryOperator *E) {
8860 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
8868 bool VisitCastExpr(
const CastExpr *E) {
8871 return ExprEvaluatorBaseTy::VisitCastExpr(E);
8873 case CK_DerivedToBase:
8874 case CK_UncheckedDerivedToBase:
8921class LValueExprEvaluator
8922 :
public LValueExprEvaluatorBase<LValueExprEvaluator> {
8924 LValueExprEvaluator(EvalInfo &Info, LValue &
Result,
bool InvalidBaseOK) :
8925 LValueExprEvaluatorBaseTy(Info,
Result, InvalidBaseOK) {}
8927 bool VisitVarDecl(
const Expr *E,
const VarDecl *VD);
8928 bool VisitUnaryPreIncDec(
const UnaryOperator *UO);
8930 bool VisitCallExpr(
const CallExpr *E);
8931 bool VisitDeclRefExpr(
const DeclRefExpr *E);
8932 bool VisitPredefinedExpr(
const PredefinedExpr *E) {
return Success(E); }
8933 bool VisitMaterializeTemporaryExpr(
const MaterializeTemporaryExpr *E);
8934 bool VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E);
8935 bool VisitMemberExpr(
const MemberExpr *E);
8936 bool VisitStringLiteral(
const StringLiteral *E) {
8937 return Success(APValue::LValueBase(
8938 E, 0, Info.getASTContext().getNextStringLiteralVersion()));
8940 bool VisitObjCEncodeExpr(
const ObjCEncodeExpr *E) {
return Success(E); }
8941 bool VisitCXXTypeidExpr(
const CXXTypeidExpr *E);
8942 bool VisitCXXUuidofExpr(
const CXXUuidofExpr *E);
8943 bool VisitArraySubscriptExpr(
const ArraySubscriptExpr *E);
8944 bool VisitExtVectorElementExpr(
const ExtVectorElementExpr *E);
8945 bool VisitUnaryDeref(
const UnaryOperator *E);
8946 bool VisitUnaryReal(
const UnaryOperator *E);
8947 bool VisitUnaryImag(
const UnaryOperator *E);
8948 bool VisitUnaryPreInc(
const UnaryOperator *UO) {
8949 return VisitUnaryPreIncDec(UO);
8951 bool VisitUnaryPreDec(
const UnaryOperator *UO) {
8952 return VisitUnaryPreIncDec(UO);
8954 bool VisitBinAssign(
const BinaryOperator *BO);
8955 bool VisitCompoundAssignOperator(
const CompoundAssignOperator *CAO);
8957 bool VisitCastExpr(
const CastExpr *E) {
8960 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
8962 case CK_LValueBitCast:
8963 this->CCEDiag(E, diag::note_constexpr_invalid_cast)
8964 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
8968 Result.Designator.setInvalid();
8971 case CK_BaseToDerived:
8988 bool LValueToRValueConversion) {
8992 assert(Info.CurrentCall->This ==
nullptr &&
8993 "This should not be set for a static call operator");
9001 if (
Self->getType()->isReferenceType()) {
9002 APValue *RefValue = Info.getParamSlot(Info.CurrentCall->Arguments,
Self);
9004 Result.setFrom(Info.Ctx, *RefValue);
9006 const ParmVarDecl *VD = Info.CurrentCall->Arguments.getOrigParam(
Self);
9007 CallStackFrame *Frame =
9008 Info.getCallFrameAndDepth(Info.CurrentCall->Arguments.CallIndex)
9010 unsigned Version = Info.CurrentCall->Arguments.Version;
9011 Result.set({VD, Frame->Index, Version});
9014 Result = *Info.CurrentCall->This;
9024 if (LValueToRValueConversion) {
9028 Result.setFrom(Info.Ctx, RVal);
9039 bool InvalidBaseOK) {
9043 return LValueExprEvaluator(Info, Result, InvalidBaseOK).Visit(E);
9046bool LValueExprEvaluator::VisitDeclRefExpr(
const DeclRefExpr *E) {
9047 const ValueDecl *D = E->
getDecl();
9059 if (Info.checkingPotentialConstantExpression())
9062 if (
auto *FD = Info.CurrentCall->LambdaCaptureFields.lookup(D)) {
9069 if (
isa<FunctionDecl, MSGuidDecl, TemplateParamObjectDecl,
9070 UnnamedGlobalConstantDecl>(D))
9072 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
9073 return VisitVarDecl(E, VD);
9074 if (
const BindingDecl *BD = dyn_cast<BindingDecl>(D))
9075 return Visit(BD->getBinding());
9079bool LValueExprEvaluator::VisitVarDecl(
const Expr *E,
const VarDecl *VD) {
9080 CallStackFrame *Frame =
nullptr;
9081 unsigned Version = 0;
9089 CallStackFrame *CurrFrame = Info.CurrentCall;
9094 if (
auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
9095 if (CurrFrame->Arguments) {
9096 VD = CurrFrame->Arguments.getOrigParam(PVD);
9098 Info.getCallFrameAndDepth(CurrFrame->Arguments.CallIndex).first;
9099 Version = CurrFrame->Arguments.Version;
9103 Version = CurrFrame->getCurrentTemporaryVersion(VD);
9110 Result.set({VD, Frame->Index, Version});
9116 if (!Info.getLangOpts().CPlusPlus11) {
9117 Info.CCEDiag(E, diag::note_constexpr_ltor_non_integral, 1)
9119 Info.Note(VD->
getLocation(), diag::note_declared_at);
9128 Result.AllowConstexprUnknown =
true;
9135bool LValueExprEvaluator::VisitCallExpr(
const CallExpr *E) {
9136 if (!IsConstantEvaluatedBuiltinCall(E))
9137 return ExprEvaluatorBaseTy::VisitCallExpr(E);
9142 case Builtin::BIas_const:
9143 case Builtin::BIforward:
9144 case Builtin::BIforward_like:
9145 case Builtin::BImove:
9146 case Builtin::BImove_if_noexcept:
9148 return Visit(E->
getArg(0));
9152 return ExprEvaluatorBaseTy::VisitCallExpr(E);
9155bool LValueExprEvaluator::VisitMaterializeTemporaryExpr(
9156 const MaterializeTemporaryExpr *E) {
9164 for (
const Expr *E : CommaLHSs)
9173 if (Info.EvalMode == EvaluationMode::ConstantFold)
9180 Value = &Info.CurrentCall->createTemporary(
9196 for (
unsigned I = Adjustments.size(); I != 0; ) {
9198 switch (Adjustments[I].Kind) {
9203 Type = Adjustments[I].DerivedToBase.BasePath->getType();
9209 Type = Adjustments[I].Field->getType();
9214 Adjustments[I].Ptr.RHS))
9216 Type = Adjustments[I].Ptr.MPT->getPointeeType();
9225LValueExprEvaluator::VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E) {
9226 assert((!Info.getLangOpts().CPlusPlus || E->
isFileScope()) &&
9227 "lvalue compound literal in c++?");
9239 assert(!Info.getLangOpts().CPlusPlus);
9241 ScopeKind::Block,
Result);
9253bool LValueExprEvaluator::VisitCXXTypeidExpr(
const CXXTypeidExpr *E) {
9254 TypeInfoLValue TypeInfo;
9263 Info.CCEDiag(E, diag::note_constexpr_typeid_polymorphic)
9271 std::optional<DynamicType> DynType =
9276 TypeInfo = TypeInfoLValue(
9283bool LValueExprEvaluator::VisitCXXUuidofExpr(
const CXXUuidofExpr *E) {
9287bool LValueExprEvaluator::VisitMemberExpr(
const MemberExpr *E) {
9289 if (
const VarDecl *VD = dyn_cast<VarDecl>(E->
getMemberDecl())) {
9290 VisitIgnoredBaseExpression(E->
getBase());
9291 return VisitVarDecl(E, VD);
9295 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(E->
getMemberDecl())) {
9296 if (MD->isStatic()) {
9297 VisitIgnoredBaseExpression(E->
getBase());
9303 return LValueExprEvaluatorBaseTy::VisitMemberExpr(E);
9306bool LValueExprEvaluator::VisitExtVectorElementExpr(
9307 const ExtVectorElementExpr *E) {
9312 if (!Info.noteFailure())
9320 if (Indices.size() > 1)
9324 Result.setFrom(Info.Ctx, Val);
9328 const auto *VT = BaseType->
castAs<VectorType>();
9330 VT->getNumElements(), Indices[0]);
9336bool LValueExprEvaluator::VisitArraySubscriptExpr(
const ArraySubscriptExpr *E) {
9346 if (!Info.noteFailure())
9352 if (!Info.noteFailure())
9358 Result.setFrom(Info.Ctx, Val);
9360 VT->getNumElements(), Index.getExtValue());
9368 for (
const Expr *SubExpr : {E->
getLHS(), E->
getRHS()}) {
9369 if (SubExpr == E->
getBase() ? !evaluatePointer(SubExpr,
Result)
9371 if (!Info.noteFailure())
9381bool LValueExprEvaluator::VisitUnaryDeref(
const UnaryOperator *E) {
9392 Info.noteUndefinedBehavior();
9395bool LValueExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
9404bool LValueExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
9406 "lvalue __imag__ on scalar?");
9413bool LValueExprEvaluator::VisitUnaryPreIncDec(
const UnaryOperator *UO) {
9414 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9425bool LValueExprEvaluator::VisitCompoundAssignOperator(
9426 const CompoundAssignOperator *CAO) {
9427 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9435 if (!Info.noteFailure())
9450bool LValueExprEvaluator::VisitBinAssign(
const BinaryOperator *E) {
9451 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9459 if (!Info.noteFailure())
9467 if (Info.getLangOpts().CPlusPlus20 &&
9483 llvm::APInt &Result) {
9484 assert(isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
9485 "Can't get the size of a non alloc_size function");
9486 const auto *
Base = LVal.getLValueBase().get<
const Expr *>();
9488 std::optional<llvm::APInt> Size =
9489 CE->evaluateBytesReturnedByAllocSizeCall(Ctx);
9493 Result = std::move(*Size);
9512 dyn_cast_or_null<VarDecl>(
Base.dyn_cast<
const ValueDecl *>());
9517 if (!
Init ||
Init->getType().isNull())
9520 const Expr *E =
Init->IgnoreParens();
9521 if (!tryUnwrapAllocSizeCall(E))
9526 Result.setInvalid(E);
9529 Result.addUnsizedArray(Info, E, Pointee);
9534class PointerExprEvaluator
9535 :
public ExprEvaluatorBase<PointerExprEvaluator> {
9544 bool evaluateLValue(
const Expr *E, LValue &
Result) {
9548 bool evaluatePointer(
const Expr *E, LValue &
Result) {
9552 bool visitNonBuiltinCallExpr(
const CallExpr *E);
9555 PointerExprEvaluator(EvalInfo &info, LValue &
Result,
bool InvalidBaseOK)
9557 InvalidBaseOK(InvalidBaseOK) {}
9563 bool ZeroInitialization(
const Expr *E) {
9568 bool VisitBinaryOperator(
const BinaryOperator *E);
9569 bool VisitCastExpr(
const CastExpr* E);
9570 bool VisitUnaryAddrOf(
const UnaryOperator *E);
9571 bool VisitObjCStringLiteral(
const ObjCStringLiteral *E)
9573 bool VisitObjCBoxedExpr(
const ObjCBoxedExpr *E) {
9576 if (Info.noteFailure())
9580 bool VisitAddrLabelExpr(
const AddrLabelExpr *E)
9582 bool VisitCallExpr(
const CallExpr *E);
9583 bool VisitBuiltinCallExpr(
const CallExpr *E,
unsigned BuiltinOp);
9584 bool VisitBlockExpr(
const BlockExpr *E) {
9589 bool VisitCXXThisExpr(
const CXXThisExpr *E) {
9590 auto DiagnoseInvalidUseOfThis = [&] {
9591 if (Info.getLangOpts().CPlusPlus11)
9592 Info.FFDiag(E, diag::note_constexpr_this) << E->
isImplicit();
9598 if (Info.checkingPotentialConstantExpression())
9601 bool IsExplicitLambda =
9603 if (!IsExplicitLambda) {
9604 if (!Info.CurrentCall->This) {
9605 DiagnoseInvalidUseOfThis();
9609 Result = *Info.CurrentCall->This;
9617 if (!Info.CurrentCall->LambdaThisCaptureField) {
9618 if (IsExplicitLambda && !Info.CurrentCall->This) {
9619 DiagnoseInvalidUseOfThis();
9628 Info, E,
Result, MD, Info.CurrentCall->LambdaThisCaptureField,
9634 bool VisitCXXNewExpr(
const CXXNewExpr *E);
9636 bool VisitSourceLocExpr(
const SourceLocExpr *E) {
9637 assert(!E->
isIntType() &&
"SourceLocExpr isn't a pointer type?");
9639 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.
getDefaultExpr());
9640 Result.setFrom(Info.Ctx, LValResult);
9644 bool VisitEmbedExpr(
const EmbedExpr *E) {
9645 llvm::report_fatal_error(
"Not yet implemented for ExprConstant.cpp");
9649 bool VisitSYCLUniqueStableNameExpr(
const SYCLUniqueStableNameExpr *E) {
9654 ResultStr.size() + 1);
9656 CharTy, Size,
nullptr, ArraySizeModifier::Normal, 0);
9659 StringLiteral::Create(Info.Ctx, ResultStr, StringLiteralKind::Ordinary,
9662 evaluateLValue(SL,
Result);
9672 bool InvalidBaseOK) {
9675 return PointerExprEvaluator(Info, Result, InvalidBaseOK).Visit(E);
9678bool PointerExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
9681 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
9683 const Expr *PExp = E->
getLHS();
9684 const Expr *IExp = E->
getRHS();
9686 std::swap(PExp, IExp);
9688 bool EvalPtrOK = evaluatePointer(PExp,
Result);
9689 if (!EvalPtrOK && !Info.noteFailure())
9692 llvm::APSInt Offset;
9703bool PointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
9712 if (!FnII || !FnII->
isStr(
"current"))
9715 const auto *RD = dyn_cast<RecordDecl>(FD->
getParent());
9723bool PointerExprEvaluator::VisitCastExpr(
const CastExpr *E) {
9730 case CK_CPointerToObjCPointerCast:
9731 case CK_BlockPointerToObjCPointerCast:
9732 case CK_AnyPointerToBlockPointerCast:
9733 case CK_AddressSpaceConversion:
9734 if (!Visit(SubExpr))
9740 CCEDiag(E, diag::note_constexpr_invalid_cast)
9741 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
9743 Result.Designator.setInvalid();
9751 bool HasValidResult = !
Result.InvalidBase && !
Result.Designator.Invalid &&
9753 bool VoidPtrCastMaybeOK =
9765 if (VoidPtrCastMaybeOK &&
9766 (Info.getStdAllocatorCaller(
"allocate") ||
9768 Info.getLangOpts().CPlusPlus26)) {
9772 Info.getLangOpts().CPlusPlus) {
9774 CCEDiag(E, diag::note_constexpr_invalid_void_star_cast)
9775 << SubExpr->
getType() << Info.getLangOpts().CPlusPlus26
9776 <<
Result.Designator.getType(Info.Ctx).getCanonicalType()
9779 CCEDiag(E, diag::note_constexpr_invalid_cast)
9780 << diag::ConstexprInvalidCastKind::CastFrom
9783 CCEDiag(E, diag::note_constexpr_invalid_cast)
9784 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
9786 Result.Designator.setInvalid();
9790 ZeroInitialization(E);
9793 case CK_DerivedToBase:
9794 case CK_UncheckedDerivedToBase:
9806 case CK_BaseToDerived:
9818 case CK_NullToPointer:
9820 return ZeroInitialization(E);
9822 case CK_IntegralToPointer: {
9823 CCEDiag(E, diag::note_constexpr_invalid_cast)
9824 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
9831 if (
Value.isInt()) {
9833 uint64_t N =
Value.getInt().extOrTrunc(Size).getZExtValue();
9837 Result.Base = (Expr *)
nullptr;
9838 Result.InvalidBase =
false;
9840 Result.Designator.setInvalid();
9841 Result.IsNullPtr =
false;
9849 if (!
Value.isLValue())
9858 case CK_ArrayToPointerDecay: {
9860 if (!evaluateLValue(SubExpr,
Result))
9864 SubExpr, SubExpr->
getType(), ScopeKind::FullExpression,
Result);
9870 if (
auto *CAT = dyn_cast<ConstantArrayType>(AT))
9871 Result.addArray(Info, E, CAT);
9873 Result.addUnsizedArray(Info, E, AT->getElementType());
9877 case CK_FunctionToPointerDecay:
9878 return evaluateLValue(SubExpr,
Result);
9880 case CK_LValueToRValue: {
9889 return InvalidBaseOK &&
9895 return ExprEvaluatorBaseTy::VisitCastExpr(E);
9903 T =
T.getNonReferenceType();
9905 if (
T.getQualifiers().hasUnaligned())
9908 const bool AlignOfReturnsPreferred =
9909 Ctx.
getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver7;
9914 if (ExprKind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
9917 else if (ExprKind == UETT_AlignOf)
9920 llvm_unreachable(
"GetAlignOfType on a non-alignment ExprKind");
9933 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
9937 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(E))
9947 if (
const auto *E =
Value.Base.dyn_cast<
const Expr *>())
9955 EvalInfo &Info,
APSInt &Alignment) {
9958 if (Alignment < 0 || !Alignment.isPowerOf2()) {
9959 Info.FFDiag(E, diag::note_constexpr_invalid_alignment) << Alignment;
9962 unsigned SrcWidth = Info.Ctx.
getIntWidth(ForType);
9963 APSInt MaxValue(APInt::getOneBitSet(SrcWidth, SrcWidth - 1));
9964 if (APSInt::compareValues(Alignment, MaxValue) > 0) {
9965 Info.FFDiag(E, diag::note_constexpr_alignment_too_big)
9966 << MaxValue << ForType << Alignment;
9972 APSInt(Alignment.zextOrTrunc(SrcWidth),
true);
9973 assert(APSInt::compareValues(Alignment, ExtAlignment) == 0 &&
9974 "Alignment should not be changed by ext/trunc");
9975 Alignment = ExtAlignment;
9976 assert(Alignment.getBitWidth() == SrcWidth);
9981bool PointerExprEvaluator::visitNonBuiltinCallExpr(
const CallExpr *E) {
9982 if (ExprEvaluatorBaseTy::VisitCallExpr(E))
9990 Result.addUnsizedArray(Info, E, PointeeTy);
9994bool PointerExprEvaluator::VisitCallExpr(
const CallExpr *E) {
9995 if (!IsConstantEvaluatedBuiltinCall(E))
9996 return visitNonBuiltinCallExpr(E);
10003 return T->isCharType() ||
T->isChar8Type();
10006bool PointerExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *E,
10007 unsigned BuiltinOp) {
10011 switch (BuiltinOp) {
10012 case Builtin::BIaddressof:
10013 case Builtin::BI__addressof:
10014 case Builtin::BI__builtin_addressof:
10016 case Builtin::BI__builtin_assume_aligned: {
10023 LValue OffsetResult(
Result);
10035 int64_t AdditionalOffset = -Offset.getZExtValue();
10040 if (OffsetResult.Base) {
10043 if (BaseAlignment < Align) {
10044 Result.Designator.setInvalid();
10045 CCEDiag(E->
getArg(0), diag::note_constexpr_baa_insufficient_alignment)
10052 if (OffsetResult.Offset.alignTo(Align) != OffsetResult.Offset) {
10053 Result.Designator.setInvalid();
10057 diag::note_constexpr_baa_insufficient_alignment)
10060 diag::note_constexpr_baa_value_insufficient_alignment))
10061 << OffsetResult.Offset.getQuantity() << Align.
getQuantity();
10067 case Builtin::BI__builtin_align_up:
10068 case Builtin::BI__builtin_align_down: {
10088 assert(Alignment.getBitWidth() <= 64 &&
10089 "Cannot handle > 64-bit address-space");
10090 uint64_t Alignment64 = Alignment.getZExtValue();
10092 BuiltinOp == Builtin::BI__builtin_align_down
10093 ? llvm::alignDown(
Result.Offset.getQuantity(), Alignment64)
10094 : llvm::alignTo(
Result.Offset.getQuantity(), Alignment64));
10100 Info.FFDiag(E->
getArg(0), diag::note_constexpr_alignment_adjust)
10104 case Builtin::BI__builtin_operator_new:
10106 case Builtin::BI__builtin_launder:
10108 case Builtin::BIstrchr:
10109 case Builtin::BIwcschr:
10110 case Builtin::BImemchr:
10111 case Builtin::BIwmemchr:
10112 if (Info.getLangOpts().CPlusPlus11)
10113 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
10117 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
10119 case Builtin::BI__builtin_strchr:
10120 case Builtin::BI__builtin_wcschr:
10121 case Builtin::BI__builtin_memchr:
10122 case Builtin::BI__builtin_char_memchr:
10123 case Builtin::BI__builtin_wmemchr: {
10124 if (!Visit(E->
getArg(0)))
10130 if (BuiltinOp != Builtin::BIstrchr &&
10131 BuiltinOp != Builtin::BIwcschr &&
10132 BuiltinOp != Builtin::BI__builtin_strchr &&
10133 BuiltinOp != Builtin::BI__builtin_wcschr) {
10137 MaxLength = N.getZExtValue();
10140 if (MaxLength == 0u)
10141 return ZeroInitialization(E);
10142 if (!
Result.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
10143 Result.Designator.Invalid)
10145 QualType CharTy =
Result.Designator.getType(Info.Ctx);
10146 bool IsRawByte = BuiltinOp == Builtin::BImemchr ||
10147 BuiltinOp == Builtin::BI__builtin_memchr;
10148 assert(IsRawByte ||
10153 Info.FFDiag(E, diag::note_constexpr_ltor_incomplete_type) << CharTy;
10159 Info.FFDiag(E, diag::note_constexpr_memchr_unsupported)
10166 bool StopAtNull =
false;
10167 switch (BuiltinOp) {
10168 case Builtin::BIstrchr:
10169 case Builtin::BI__builtin_strchr:
10176 return ZeroInitialization(E);
10179 case Builtin::BImemchr:
10180 case Builtin::BI__builtin_memchr:
10181 case Builtin::BI__builtin_char_memchr:
10185 DesiredVal = Desired.trunc(Info.Ctx.
getCharWidth()).getZExtValue();
10188 case Builtin::BIwcschr:
10189 case Builtin::BI__builtin_wcschr:
10192 case Builtin::BIwmemchr:
10193 case Builtin::BI__builtin_wmemchr:
10195 DesiredVal = Desired.getZExtValue();
10199 for (; MaxLength; --MaxLength) {
10204 if (Char.
getInt().getZExtValue() == DesiredVal)
10206 if (StopAtNull && !Char.
getInt())
10212 return ZeroInitialization(E);
10215 case Builtin::BImemcpy:
10216 case Builtin::BImemmove:
10217 case Builtin::BIwmemcpy:
10218 case Builtin::BIwmemmove:
10219 if (Info.getLangOpts().CPlusPlus11)
10220 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
10224 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
10226 case Builtin::BI__builtin_memcpy:
10227 case Builtin::BI__builtin_memmove:
10228 case Builtin::BI__builtin_wmemcpy:
10229 case Builtin::BI__builtin_wmemmove: {
10230 bool WChar = BuiltinOp == Builtin::BIwmemcpy ||
10231 BuiltinOp == Builtin::BIwmemmove ||
10232 BuiltinOp == Builtin::BI__builtin_wmemcpy ||
10233 BuiltinOp == Builtin::BI__builtin_wmemmove;
10234 bool Move = BuiltinOp == Builtin::BImemmove ||
10235 BuiltinOp == Builtin::BIwmemmove ||
10236 BuiltinOp == Builtin::BI__builtin_memmove ||
10237 BuiltinOp == Builtin::BI__builtin_wmemmove;
10240 if (!Visit(E->
getArg(0)))
10251 assert(!N.isSigned() &&
"memcpy and friends take an unsigned size");
10261 if (!Src.Base || !Dest.Base) {
10263 (!Src.Base ? Src : Dest).moveInto(Val);
10264 Info.FFDiag(E, diag::note_constexpr_memcpy_null)
10265 <<
Move << WChar << !!Src.Base
10269 if (Src.Designator.Invalid || Dest.Designator.Invalid)
10275 QualType
T = Dest.Designator.getType(Info.Ctx);
10276 QualType SrcT = Src.Designator.getType(Info.Ctx);
10279 Info.FFDiag(E, diag::note_constexpr_memcpy_type_pun) <<
Move << SrcT <<
T;
10283 Info.FFDiag(E, diag::note_constexpr_memcpy_incomplete_type) <<
Move <<
T;
10286 if (!
T.isTriviallyCopyableType(Info.Ctx)) {
10287 Info.FFDiag(E, diag::note_constexpr_memcpy_nontrivial) <<
Move <<
T;
10297 llvm::APInt OrigN = N;
10298 llvm::APInt::udivrem(OrigN, TSize, N, Remainder);
10300 Info.FFDiag(E, diag::note_constexpr_memcpy_unsupported)
10302 << (unsigned)TSize;
10310 uint64_t RemainingSrcSize = Src.Designator.validIndexAdjustments().second;
10311 uint64_t RemainingDestSize = Dest.Designator.validIndexAdjustments().second;
10312 if (N.ugt(RemainingSrcSize) || N.ugt(RemainingDestSize)) {
10313 Info.FFDiag(E, diag::note_constexpr_memcpy_unsupported)
10314 <<
Move << WChar << (N.ugt(RemainingSrcSize) ? 1 : 2) <<
T
10318 uint64_t NElems = N.getZExtValue();
10324 uint64_t SrcOffset = Src.getLValueOffset().getQuantity();
10325 uint64_t DestOffset = Dest.getLValueOffset().getQuantity();
10326 if (DestOffset >= SrcOffset && DestOffset - SrcOffset < NBytes) {
10329 Info.FFDiag(E, diag::note_constexpr_memcpy_overlap) << WChar;
10337 }
else if (!Move && SrcOffset >= DestOffset &&
10338 SrcOffset - DestOffset < NBytes) {
10340 Info.FFDiag(E, diag::note_constexpr_memcpy_overlap) << WChar;
10369 QualType AllocType);
10372 const CXXConstructExpr *CCE,
10373 QualType AllocType);
10375bool PointerExprEvaluator::VisitCXXNewExpr(
const CXXNewExpr *E) {
10376 if (!Info.getLangOpts().CPlusPlus20)
10377 Info.CCEDiag(E, diag::note_constexpr_new);
10380 if (Info.SpeculativeEvaluationDepth)
10385 QualType TargetType = AllocType;
10387 bool IsNothrow =
false;
10388 bool IsPlacement =
false;
10406 }
else if (OperatorNew->isReservedGlobalPlacementOperator()) {
10407 if (Info.CurrentCall->isStdFunction() || Info.getLangOpts().CPlusPlus26 ||
10408 (Info.CurrentCall->CanEvalMSConstexpr &&
10409 OperatorNew->hasAttr<MSConstexprAttr>())) {
10412 if (
Result.Designator.Invalid)
10415 IsPlacement =
true;
10417 Info.FFDiag(E, diag::note_constexpr_new_placement)
10422 Info.FFDiag(E, diag::note_constexpr_new_placement)
10425 }
else if (!OperatorNew
10426 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
10427 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
10433 const InitListExpr *ResizedArrayILE =
nullptr;
10434 const CXXConstructExpr *ResizedArrayCCE =
nullptr;
10435 bool ValueInit =
false;
10437 if (std::optional<const Expr *> ArraySize = E->
getArraySize()) {
10438 const Expr *Stripped = *ArraySize;
10439 for (;
auto *ICE = dyn_cast<ImplicitCastExpr>(Stripped);
10440 Stripped = ICE->getSubExpr())
10441 if (ICE->getCastKind() != CK_NoOp &&
10442 ICE->getCastKind() != CK_IntegralCast)
10455 return ZeroInitialization(E);
10457 Info.FFDiag(*ArraySize, diag::note_constexpr_new_negative)
10458 <<
ArrayBound << (*ArraySize)->getSourceRange();
10464 if (!Info.CheckArraySize(ArraySize.value()->getExprLoc(),
10469 return ZeroInitialization(E);
10481 }
else if (
auto *CCE = dyn_cast<CXXConstructExpr>(
Init)) {
10482 ResizedArrayCCE = CCE;
10485 assert(CAT &&
"unexpected type for array initializer");
10489 llvm::APInt InitBound = CAT->
getSize().zext(Bits);
10490 llvm::APInt AllocBound =
ArrayBound.zext(Bits);
10491 if (InitBound.ugt(AllocBound)) {
10493 return ZeroInitialization(E);
10495 Info.FFDiag(*ArraySize, diag::note_constexpr_new_too_small)
10496 <<
toString(AllocBound, 10,
false)
10498 << (*ArraySize)->getSourceRange();
10504 if (InitBound != AllocBound)
10509 ArraySizeModifier::Normal, 0);
10512 "array allocation with non-array new");
10518 struct FindObjectHandler {
10521 QualType AllocType;
10525 typedef bool result_type;
10526 bool failed() {
return false; }
10527 bool checkConst(QualType QT) {
10529 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
10534 bool found(
APValue &Subobj, QualType SubobjType) {
10535 if (!checkConst(SubobjType))
10539 unsigned SubobjectSize = 1;
10540 unsigned AllocSize = 1;
10541 if (
auto *CAT = dyn_cast<ConstantArrayType>(AllocType))
10543 if (
auto *CAT = dyn_cast<ConstantArrayType>(SubobjType))
10545 if (SubobjectSize < AllocSize ||
10548 Info.FFDiag(E, diag::note_constexpr_placement_new_wrong_type)
10549 << SubobjType << AllocType;
10556 Info.FFDiag(E, diag::note_constexpr_construct_complex_elem);
10559 bool found(APFloat &
Value, QualType SubobjType) {
10560 Info.FFDiag(E, diag::note_constexpr_construct_complex_elem);
10563 } Handler = {Info, E, AllocType, AK,
nullptr};
10569 Val = Handler.Value;
10578 Val = Info.createHeapAlloc(E, AllocType,
Result);
10584 ImplicitValueInitExpr VIE(AllocType);
10587 }
else if (ResizedArrayILE) {
10591 }
else if (ResizedArrayCCE) {
10614class MemberPointerExprEvaluator
10615 :
public ExprEvaluatorBase<MemberPointerExprEvaluator> {
10618 bool Success(
const ValueDecl *D) {
10624 MemberPointerExprEvaluator(EvalInfo &Info, MemberPtr &
Result)
10631 bool ZeroInitialization(
const Expr *E) {
10632 return Success((
const ValueDecl*)
nullptr);
10635 bool VisitCastExpr(
const CastExpr *E);
10636 bool VisitUnaryAddrOf(
const UnaryOperator *E);
10644 return MemberPointerExprEvaluator(Info, Result).Visit(E);
10647bool MemberPointerExprEvaluator::VisitCastExpr(
const CastExpr *E) {
10650 return ExprEvaluatorBaseTy::VisitCastExpr(E);
10652 case CK_NullToMemberPointer:
10654 return ZeroInitialization(E);
10656 case CK_BaseToDerivedMemberPointer: {
10664 typedef std::reverse_iterator<CastExpr::path_const_iterator> ReverseIter;
10666 PathI != PathE; ++PathI) {
10667 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
10668 const CXXRecordDecl *Derived = (*PathI)->getType()->getAsCXXRecordDecl();
10669 if (!
Result.castToDerived(Derived))
10673 ->
castAs<MemberPointerType>()
10674 ->getMostRecentCXXRecordDecl()))
10679 case CK_DerivedToBaseMemberPointer:
10683 PathE = E->
path_end(); PathI != PathE; ++PathI) {
10684 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
10685 const CXXRecordDecl *
Base = (*PathI)->getType()->getAsCXXRecordDecl();
10686 if (!
Result.castToBase(Base))
10693bool MemberPointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
10704 class RecordExprEvaluator
10705 :
public ExprEvaluatorBase<RecordExprEvaluator> {
10706 const LValue &
This;
10710 RecordExprEvaluator(EvalInfo &info,
const LValue &This,
APValue &
Result)
10717 bool ZeroInitialization(
const Expr *E) {
10718 return ZeroInitialization(E, E->
getType());
10720 bool ZeroInitialization(
const Expr *E, QualType
T);
10722 bool VisitCallExpr(
const CallExpr *E) {
10723 return handleCallExpr(E,
Result, &This);
10725 bool VisitCastExpr(
const CastExpr *E);
10726 bool VisitInitListExpr(
const InitListExpr *E);
10727 bool VisitCXXConstructExpr(
const CXXConstructExpr *E) {
10728 return VisitCXXConstructExpr(E, E->
getType());
10731 bool VisitCXXInheritedCtorInitExpr(
const CXXInheritedCtorInitExpr *E);
10732 bool VisitCXXConstructExpr(
const CXXConstructExpr *E, QualType
T);
10733 bool VisitCXXStdInitializerListExpr(
const CXXStdInitializerListExpr *E);
10734 bool VisitBinCmp(
const BinaryOperator *E);
10735 bool VisitCXXParenListInitExpr(
const CXXParenListInitExpr *E);
10736 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
10737 ArrayRef<Expr *> Args);
10751 assert(!RD->
isUnion() &&
"Expected non-union class type");
10760 unsigned Index = 0;
10762 End = CD->
bases_end(); I != End; ++I, ++Index) {
10764 LValue Subobject =
This;
10768 Result.getStructBase(Index)))
10773 for (
const auto *I : RD->
fields()) {
10775 if (I->isUnnamedBitField() || I->getType()->isReferenceType())
10778 LValue Subobject =
This;
10784 Result.getStructField(I->getFieldIndex()), Info, Subobject, &VIE))
10791bool RecordExprEvaluator::ZeroInitialization(
const Expr *E, QualType
T) {
10798 while (I != RD->
field_end() && (*I)->isUnnamedBitField())
10805 LValue Subobject =
This;
10809 ImplicitValueInitExpr VIE(I->getType());
10814 Info.FFDiag(E, diag::note_constexpr_virtual_base) << RD;
10821bool RecordExprEvaluator::VisitCastExpr(
const CastExpr *E) {
10824 return ExprEvaluatorBaseTy::VisitCastExpr(E);
10826 case CK_ConstructorConversion:
10829 case CK_DerivedToBase:
10830 case CK_UncheckedDerivedToBase: {
10841 PathE = E->
path_end(); PathI != PathE; ++PathI) {
10842 assert(!(*PathI)->isVirtual() &&
"record rvalue with virtual base");
10843 const CXXRecordDecl *
Base = (*PathI)->getType()->getAsCXXRecordDecl();
10853bool RecordExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
10856 return VisitCXXParenListOrInitListExpr(E, E->
inits());
10859bool RecordExprEvaluator::VisitCXXParenListOrInitListExpr(
10864 auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
10866 EvalInfo::EvaluatingConstructorRAII EvalObj(
10868 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries},
10869 CXXRD && CXXRD->getNumBases());
10872 const FieldDecl *
Field;
10873 if (
auto *ILE = dyn_cast<InitListExpr>(ExprToVisit)) {
10874 Field = ILE->getInitializedFieldInUnion();
10875 }
else if (
auto *PLIE = dyn_cast<CXXParenListInitExpr>(ExprToVisit)) {
10876 Field = PLIE->getInitializedFieldInUnion();
10879 "Expression is neither an init list nor a C++ paren list");
10891 ImplicitValueInitExpr VIE(
Field->getType());
10892 const Expr *InitExpr = Args.empty() ? &VIE : Args[0];
10894 LValue Subobject =
This;
10899 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
10903 if (
Field->isBitField())
10913 Result =
APValue(APValue::UninitStruct(), CXXRD ? CXXRD->getNumBases() : 0,
10915 unsigned ElementNo = 0;
10919 if (CXXRD && CXXRD->getNumBases()) {
10920 for (
const auto &Base : CXXRD->bases()) {
10921 assert(ElementNo < Args.size() &&
"missing init for base class");
10922 const Expr *
Init = Args[ElementNo];
10924 LValue Subobject =
This;
10930 if (!Info.noteFailure())
10937 EvalObj.finishedConstructingBases();
10941 for (
const auto *Field : RD->
fields()) {
10944 if (
Field->isUnnamedBitField())
10947 LValue Subobject =
This;
10949 bool HaveInit = ElementNo < Args.size();
10954 Subobject, Field, &Layout))
10959 ImplicitValueInitExpr VIE(HaveInit ? Info.Ctx.
IntTy :
Field->getType());
10960 const Expr *
Init = HaveInit ? Args[ElementNo++] : &VIE;
10962 if (
Field->getType()->isIncompleteArrayType()) {
10967 Info.FFDiag(
Init, diag::note_constexpr_unsupported_flexible_array);
10974 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
10978 if (
Field->getType()->isReferenceType()) {
10982 if (!Info.noteFailure())
10987 (
Field->isBitField() &&
10989 if (!Info.noteFailure())
10995 EvalObj.finishedConstructingFields();
11000bool RecordExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E,
11010 return ZeroInitialization(E,
T);
11028 const Expr *SrcObj = E->
getArg(0);
11031 if (
const MaterializeTemporaryExpr *ME =
11032 dyn_cast<MaterializeTemporaryExpr>(SrcObj))
11033 return Visit(ME->getSubExpr());
11036 if (ZeroInit && !ZeroInitialization(E,
T))
11045bool RecordExprEvaluator::VisitCXXInheritedCtorInitExpr(
11046 const CXXInheritedCtorInitExpr *E) {
11047 if (!Info.CurrentCall) {
11048 assert(Info.checkingPotentialConstantExpression());
11067bool RecordExprEvaluator::VisitCXXStdInitializerListExpr(
11068 const CXXStdInitializerListExpr *E) {
11069 const ConstantArrayType *ArrayType =
11076 assert(ArrayType &&
"unexpected type for array initializer");
11079 Array.addArray(Info, E, ArrayType);
11083 Array.moveInto(
Result.getStructField(0));
11087 assert(Field !=
Record->field_end() &&
11090 "Expected std::initializer_list first field to be const E *");
11092 assert(Field !=
Record->field_end() &&
11093 "Expected std::initializer_list to have two fields");
11102 "Expected std::initializer_list second field to be const E *");
11107 Array.moveInto(
Result.getStructField(1));
11110 assert(++Field ==
Record->field_end() &&
11111 "Expected std::initializer_list to only have two fields");
11116bool RecordExprEvaluator::VisitLambdaExpr(
const LambdaExpr *E) {
11121 const size_t NumFields =
11126 "The number of lambda capture initializers should equal the number of "
11127 "fields within the closure type");
11135 for (
const auto *Field : ClosureClass->
fields()) {
11138 Expr *
const CurFieldInit = *CaptureInitIt++;
11145 LValue Subobject =
This;
11152 if (!Info.keepEvaluatingAfterFailure())
11161 APValue &Result, EvalInfo &Info) {
11164 "can't evaluate expression as a record rvalue");
11165 return RecordExprEvaluator(Info,
This, Result).Visit(E);
11176class TemporaryExprEvaluator
11177 :
public LValueExprEvaluatorBase<TemporaryExprEvaluator> {
11179 TemporaryExprEvaluator(EvalInfo &Info, LValue &
Result) :
11180 LValueExprEvaluatorBaseTy(Info,
Result,
false) {}
11183 bool VisitConstructExpr(
const Expr *E) {
11189 bool VisitCastExpr(
const CastExpr *E) {
11192 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
11194 case CK_ConstructorConversion:
11198 bool VisitInitListExpr(
const InitListExpr *E) {
11199 return VisitConstructExpr(E);
11201 bool VisitCXXConstructExpr(
const CXXConstructExpr *E) {
11202 return VisitConstructExpr(E);
11204 bool VisitCallExpr(
const CallExpr *E) {
11205 return VisitConstructExpr(E);
11207 bool VisitCXXStdInitializerListExpr(
const CXXStdInitializerListExpr *E) {
11208 return VisitConstructExpr(E);
11211 return VisitConstructExpr(E);
11220 return TemporaryExprEvaluator(Info, Result).Visit(E);
11228 class VectorExprEvaluator
11229 :
public ExprEvaluatorBase<VectorExprEvaluator> {
11236 bool Success(ArrayRef<APValue>
V,
const Expr *E) {
11237 assert(
V.size() == E->
getType()->
castAs<VectorType>()->getNumElements());
11243 assert(
V.isVector());
11247 bool ZeroInitialization(
const Expr *E);
11249 bool VisitUnaryReal(
const UnaryOperator *E)
11251 bool VisitCastExpr(
const CastExpr* E);
11252 bool VisitInitListExpr(
const InitListExpr *E);
11253 bool VisitUnaryImag(
const UnaryOperator *E);
11254 bool VisitBinaryOperator(
const BinaryOperator *E);
11255 bool VisitUnaryOperator(
const UnaryOperator *E);
11256 bool VisitCallExpr(
const CallExpr *E);
11257 bool VisitConvertVectorExpr(
const ConvertVectorExpr *E);
11258 bool VisitShuffleVectorExpr(
const ShuffleVectorExpr *E);
11267 "not a vector prvalue");
11268 return VectorExprEvaluator(Info, Result).Visit(E);
11272 assert(Val.
isVector() &&
"expected vector APValue");
11276 llvm::APInt
Result(NumElts, 0);
11278 for (
unsigned I = 0; I < NumElts; ++I) {
11280 assert(Elt.
isInt() &&
"expected integer element in bool vector");
11282 if (Elt.
getInt().getBoolValue())
11289bool VectorExprEvaluator::VisitCastExpr(
const CastExpr *E) {
11290 const VectorType *VTy = E->
getType()->
castAs<VectorType>();
11294 QualType SETy = SE->
getType();
11297 case CK_VectorSplat: {
11303 Val =
APValue(std::move(IntResult));
11308 Val =
APValue(std::move(FloatResult));
11325 Info.FFDiag(E, diag::note_constexpr_invalid_cast)
11326 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
11331 if (!handleRValueToRValueBitCast(Info,
Result, SVal, E))
11336 case CK_HLSLVectorTruncation: {
11341 for (
unsigned I = 0; I < NElts; I++)
11346 return ExprEvaluatorBaseTy::VisitCastExpr(E);
11351VectorExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
11368 unsigned CountInits = 0, CountElts = 0;
11369 while (CountElts < NumElements) {
11371 if (CountInits < NumInits
11377 for (
unsigned j = 0; j < vlen; j++)
11381 llvm::APSInt sInt(32);
11382 if (CountInits < NumInits) {
11387 Elements.push_back(
APValue(sInt));
11390 llvm::APFloat f(0.0);
11391 if (CountInits < NumInits) {
11396 Elements.push_back(
APValue(f));
11405VectorExprEvaluator::ZeroInitialization(
const Expr *E) {
11409 if (EltTy->isIntegerType())
11419bool VectorExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
11421 return ZeroInitialization(E);
11424bool VectorExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
11426 assert(Op != BO_PtrMemD && Op != BO_PtrMemI && Op != BO_Cmp &&
11427 "Operation not supported on vector types");
11429 if (Op == BO_Comma)
11430 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
11432 Expr *LHS = E->
getLHS();
11433 Expr *RHS = E->
getRHS();
11436 "Must both be vector types");
11439 assert(LHS->
getType()->
castAs<VectorType>()->getNumElements() ==
11443 "All operands must be the same size.");
11447 bool LHSOK =
Evaluate(LHSValue, Info, LHS);
11448 if (!LHSOK && !Info.noteFailure())
11450 if (!
Evaluate(RHSValue, Info, RHS) || !LHSOK)
11472 "Vector can only be int or float type");
11480 "Vector operator ~ can only be int");
11481 Elt.
getInt().flipAllBits();
11491 "Vector can only be int or float type");
11497 EltResult.setAllBits();
11499 EltResult.clearAllBits();
11505 return std::nullopt;
11509bool VectorExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
11515 const QualType ResultEltTy = VD->getElementType();
11519 if (!
Evaluate(SubExprValue, Info, SubExpr))
11532 "Vector length doesn't match type?");
11535 for (
unsigned EltNum = 0; EltNum < VD->getNumElements(); ++EltNum) {
11537 Info.Ctx, ResultEltTy, Op, SubExprValue.
getVectorElt(EltNum));
11540 ResultElements.push_back(*Elt);
11542 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
11551 Result =
APValue(APFloat(0.0));
11553 DestTy, Result.getFloat());
11564 Result.getFloat());
11569 DestTy, Result.getInt());
11573 Info.FFDiag(E, diag::err_convertvector_constexpr_unsupported_vector_cast)
11574 << SourceTy << DestTy;
11579 llvm::function_ref<APInt(
const APSInt &)> PackFn) {
11588 assert(LHSVecLen != 0 && LHSVecLen == RHSVecLen &&
11589 "pack builtin LHSVecLen must equal to RHSVecLen");
11598 const unsigned SrcPerLane = 128 / SrcBits;
11599 const unsigned Lanes = LHSVecLen * SrcBits / 128;
11602 Out.reserve(LHSVecLen + RHSVecLen);
11604 for (
unsigned Lane = 0; Lane != Lanes; ++Lane) {
11605 unsigned base = Lane * SrcPerLane;
11606 for (
unsigned I = 0; I != SrcPerLane; ++I)
11609 for (
unsigned I = 0; I != SrcPerLane; ++I)
11614 Result =
APValue(Out.data(), Out.size());
11619 bool IsShufHW,
APValue &Out) {
11635 unsigned LaneBits = 128u;
11636 unsigned LaneElts = LaneBits / ElemBits;
11637 if (!LaneElts || (NumElts % LaneElts) != 0)
11640 uint8_t Ctl =
static_cast<uint8_t
>(Imm.getZExtValue());
11643 ResultElements.reserve(NumElts);
11645 for (
unsigned Idx = 0; Idx != NumElts; Idx++) {
11646 unsigned LaneBase = (Idx / LaneElts) * LaneElts;
11647 unsigned LaneIdx = Idx % LaneElts;
11648 unsigned SrcIdx = Idx;
11649 unsigned Sel = (Ctl >> (2 * LaneIdx)) & 0x3;
11651 if (ElemBits == 32) {
11652 SrcIdx = LaneBase + Sel;
11654 constexpr unsigned HalfSize = 4;
11655 bool InHigh = LaneIdx >= HalfSize;
11656 if (!IsShufHW && !InHigh) {
11657 SrcIdx = LaneBase + Sel;
11658 }
else if (IsShufHW && InHigh) {
11659 unsigned Rel = LaneIdx - HalfSize;
11660 Sel = (Ctl >> (2 * Rel)) & 0x3;
11661 SrcIdx = LaneBase + HalfSize + Sel;
11668 Out =
APValue(ResultElements.data(), ResultElements.size());
11672bool VectorExprEvaluator::VisitCallExpr(
const CallExpr *E) {
11673 if (!IsConstantEvaluatedBuiltinCall(E))
11674 return ExprEvaluatorBaseTy::VisitCallExpr(E);
11676 auto EvaluateBinOpExpr =
11678 APValue SourceLHS, SourceRHS;
11684 QualType DestEltTy = DestTy->getElementType();
11685 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
11688 ResultElements.reserve(SourceLen);
11690 if (SourceRHS.
isInt()) {
11692 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11694 ResultElements.push_back(
11698 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11701 ResultElements.push_back(
11711 case Builtin::BI__builtin_elementwise_popcount:
11712 case Builtin::BI__builtin_elementwise_bitreverse: {
11717 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
11720 ResultElements.reserve(SourceLen);
11722 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11725 case Builtin::BI__builtin_elementwise_popcount:
11726 ResultElements.push_back(
APValue(
11730 case Builtin::BI__builtin_elementwise_bitreverse:
11731 ResultElements.push_back(
11738 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
11740 case Builtin::BI__builtin_elementwise_abs: {
11745 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
11748 ResultElements.reserve(SourceLen);
11750 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11755 CurrentEle.getInt().
abs(),
11756 DestEltTy->isUnsignedIntegerOrEnumerationType()));
11757 ResultElements.push_back(Val);
11760 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
11763 case Builtin::BI__builtin_elementwise_add_sat:
11764 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
11765 return LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS);
11768 case Builtin::BI__builtin_elementwise_sub_sat:
11769 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
11770 return LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
11773 case clang::X86::BI__builtin_ia32_pavgb128:
11774 case clang::X86::BI__builtin_ia32_pavgw128:
11775 case clang::X86::BI__builtin_ia32_pavgb256:
11776 case clang::X86::BI__builtin_ia32_pavgw256:
11777 case clang::X86::BI__builtin_ia32_pavgb512:
11778 case clang::X86::BI__builtin_ia32_pavgw512:
11779 return EvaluateBinOpExpr(llvm::APIntOps::avgCeilU);
11781 case clang::X86::BI__builtin_ia32_pmaddubsw128:
11782 case clang::X86::BI__builtin_ia32_pmaddubsw256:
11783 case clang::X86::BI__builtin_ia32_pmaddubsw512:
11784 case clang::X86::BI__builtin_ia32_pmaddwd128:
11785 case clang::X86::BI__builtin_ia32_pmaddwd256:
11786 case clang::X86::BI__builtin_ia32_pmaddwd512: {
11787 APValue SourceLHS, SourceRHS;
11793 QualType DestEltTy = DestTy->getElementType();
11795 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
11797 ResultElements.reserve(SourceLen / 2);
11799 for (
unsigned EltNum = 0; EltNum < SourceLen; EltNum += 2) {
11804 unsigned BitWidth = 2 * LoLHS.getBitWidth();
11807 case clang::X86::BI__builtin_ia32_pmaddubsw128:
11808 case clang::X86::BI__builtin_ia32_pmaddubsw256:
11809 case clang::X86::BI__builtin_ia32_pmaddubsw512:
11810 ResultElements.push_back(
APValue(
11811 APSInt((LoLHS.zext(BitWidth) * LoRHS.sext(BitWidth))
11812 .sadd_sat((HiLHS.zext(BitWidth) * HiRHS.sext(BitWidth))),
11815 case clang::X86::BI__builtin_ia32_pmaddwd128:
11816 case clang::X86::BI__builtin_ia32_pmaddwd256:
11817 case clang::X86::BI__builtin_ia32_pmaddwd512:
11818 ResultElements.push_back(
11819 APValue(
APSInt((LoLHS.sext(BitWidth) * LoRHS.sext(BitWidth)) +
11820 (HiLHS.sext(BitWidth) * HiRHS.sext(BitWidth)),
11826 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
11829 case clang::X86::BI__builtin_ia32_pmulhuw128:
11830 case clang::X86::BI__builtin_ia32_pmulhuw256:
11831 case clang::X86::BI__builtin_ia32_pmulhuw512:
11832 return EvaluateBinOpExpr(llvm::APIntOps::mulhu);
11834 case clang::X86::BI__builtin_ia32_pmulhw128:
11835 case clang::X86::BI__builtin_ia32_pmulhw256:
11836 case clang::X86::BI__builtin_ia32_pmulhw512:
11837 return EvaluateBinOpExpr(llvm::APIntOps::mulhs);
11839 case clang::X86::BI__builtin_ia32_psllv2di:
11840 case clang::X86::BI__builtin_ia32_psllv4di:
11841 case clang::X86::BI__builtin_ia32_psllv4si:
11842 case clang::X86::BI__builtin_ia32_psllv8di:
11843 case clang::X86::BI__builtin_ia32_psllv8hi:
11844 case clang::X86::BI__builtin_ia32_psllv8si:
11845 case clang::X86::BI__builtin_ia32_psllv16hi:
11846 case clang::X86::BI__builtin_ia32_psllv16si:
11847 case clang::X86::BI__builtin_ia32_psllv32hi:
11848 case clang::X86::BI__builtin_ia32_psllwi128:
11849 case clang::X86::BI__builtin_ia32_pslldi128:
11850 case clang::X86::BI__builtin_ia32_psllqi128:
11851 case clang::X86::BI__builtin_ia32_psllwi256:
11852 case clang::X86::BI__builtin_ia32_pslldi256:
11853 case clang::X86::BI__builtin_ia32_psllqi256:
11854 case clang::X86::BI__builtin_ia32_psllwi512:
11855 case clang::X86::BI__builtin_ia32_pslldi512:
11856 case clang::X86::BI__builtin_ia32_psllqi512:
11857 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
11858 if (RHS.uge(LHS.getBitWidth())) {
11859 return APInt::getZero(LHS.getBitWidth());
11861 return LHS.shl(RHS.getZExtValue());
11864 case clang::X86::BI__builtin_ia32_psrav4si:
11865 case clang::X86::BI__builtin_ia32_psrav8di:
11866 case clang::X86::BI__builtin_ia32_psrav8hi:
11867 case clang::X86::BI__builtin_ia32_psrav8si:
11868 case clang::X86::BI__builtin_ia32_psrav16hi:
11869 case clang::X86::BI__builtin_ia32_psrav16si:
11870 case clang::X86::BI__builtin_ia32_psrav32hi:
11871 case clang::X86::BI__builtin_ia32_psravq128:
11872 case clang::X86::BI__builtin_ia32_psravq256:
11873 case clang::X86::BI__builtin_ia32_psrawi128:
11874 case clang::X86::BI__builtin_ia32_psradi128:
11875 case clang::X86::BI__builtin_ia32_psraqi128:
11876 case clang::X86::BI__builtin_ia32_psrawi256:
11877 case clang::X86::BI__builtin_ia32_psradi256:
11878 case clang::X86::BI__builtin_ia32_psraqi256:
11879 case clang::X86::BI__builtin_ia32_psrawi512:
11880 case clang::X86::BI__builtin_ia32_psradi512:
11881 case clang::X86::BI__builtin_ia32_psraqi512:
11882 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
11883 if (RHS.uge(LHS.getBitWidth())) {
11884 return LHS.ashr(LHS.getBitWidth() - 1);
11886 return LHS.ashr(RHS.getZExtValue());
11889 case clang::X86::BI__builtin_ia32_psrlv2di:
11890 case clang::X86::BI__builtin_ia32_psrlv4di:
11891 case clang::X86::BI__builtin_ia32_psrlv4si:
11892 case clang::X86::BI__builtin_ia32_psrlv8di:
11893 case clang::X86::BI__builtin_ia32_psrlv8hi:
11894 case clang::X86::BI__builtin_ia32_psrlv8si:
11895 case clang::X86::BI__builtin_ia32_psrlv16hi:
11896 case clang::X86::BI__builtin_ia32_psrlv16si:
11897 case clang::X86::BI__builtin_ia32_psrlv32hi:
11898 case clang::X86::BI__builtin_ia32_psrlwi128:
11899 case clang::X86::BI__builtin_ia32_psrldi128:
11900 case clang::X86::BI__builtin_ia32_psrlqi128:
11901 case clang::X86::BI__builtin_ia32_psrlwi256:
11902 case clang::X86::BI__builtin_ia32_psrldi256:
11903 case clang::X86::BI__builtin_ia32_psrlqi256:
11904 case clang::X86::BI__builtin_ia32_psrlwi512:
11905 case clang::X86::BI__builtin_ia32_psrldi512:
11906 case clang::X86::BI__builtin_ia32_psrlqi512:
11907 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
11908 if (RHS.uge(LHS.getBitWidth())) {
11909 return APInt::getZero(LHS.getBitWidth());
11911 return LHS.lshr(RHS.getZExtValue());
11913 case X86::BI__builtin_ia32_packsswb128:
11914 case X86::BI__builtin_ia32_packsswb256:
11915 case X86::BI__builtin_ia32_packsswb512:
11916 case X86::BI__builtin_ia32_packssdw128:
11917 case X86::BI__builtin_ia32_packssdw256:
11918 case X86::BI__builtin_ia32_packssdw512:
11920 return APSInt(Src).truncSSat(Src.getBitWidth() / 2);
11922 case X86::BI__builtin_ia32_packusdw128:
11923 case X86::BI__builtin_ia32_packusdw256:
11924 case X86::BI__builtin_ia32_packusdw512:
11925 case X86::BI__builtin_ia32_packuswb128:
11926 case X86::BI__builtin_ia32_packuswb256:
11927 case X86::BI__builtin_ia32_packuswb512:
11929 unsigned DstBits = Src.getBitWidth() / 2;
11930 if (Src.isNegative())
11931 return APInt::getZero(DstBits);
11932 if (Src.isIntN(DstBits))
11934 return APInt::getAllOnes(DstBits);
11936 case clang::X86::BI__builtin_ia32_pmuldq128:
11937 case clang::X86::BI__builtin_ia32_pmuldq256:
11938 case clang::X86::BI__builtin_ia32_pmuldq512:
11939 case clang::X86::BI__builtin_ia32_pmuludq128:
11940 case clang::X86::BI__builtin_ia32_pmuludq256:
11941 case clang::X86::BI__builtin_ia32_pmuludq512: {
11942 APValue SourceLHS, SourceRHS;
11949 ResultElements.reserve(SourceLen / 2);
11951 for (
unsigned EltNum = 0; EltNum < SourceLen; EltNum += 2) {
11956 case clang::X86::BI__builtin_ia32_pmuludq128:
11957 case clang::X86::BI__builtin_ia32_pmuludq256:
11958 case clang::X86::BI__builtin_ia32_pmuludq512:
11959 ResultElements.push_back(
11960 APValue(
APSInt(llvm::APIntOps::muluExtended(LHS, RHS),
true)));
11962 case clang::X86::BI__builtin_ia32_pmuldq128:
11963 case clang::X86::BI__builtin_ia32_pmuldq256:
11964 case clang::X86::BI__builtin_ia32_pmuldq512:
11965 ResultElements.push_back(
11966 APValue(
APSInt(llvm::APIntOps::mulsExtended(LHS, RHS),
false)));
11971 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
11973 case clang::X86::BI__builtin_ia32_vprotbi:
11974 case clang::X86::BI__builtin_ia32_vprotdi:
11975 case clang::X86::BI__builtin_ia32_vprotqi:
11976 case clang::X86::BI__builtin_ia32_vprotwi:
11977 case clang::X86::BI__builtin_ia32_prold128:
11978 case clang::X86::BI__builtin_ia32_prold256:
11979 case clang::X86::BI__builtin_ia32_prold512:
11980 case clang::X86::BI__builtin_ia32_prolq128:
11981 case clang::X86::BI__builtin_ia32_prolq256:
11982 case clang::X86::BI__builtin_ia32_prolq512:
11983 return EvaluateBinOpExpr(
11984 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS.rotl(RHS); });
11986 case clang::X86::BI__builtin_ia32_prord128:
11987 case clang::X86::BI__builtin_ia32_prord256:
11988 case clang::X86::BI__builtin_ia32_prord512:
11989 case clang::X86::BI__builtin_ia32_prorq128:
11990 case clang::X86::BI__builtin_ia32_prorq256:
11991 case clang::X86::BI__builtin_ia32_prorq512:
11992 return EvaluateBinOpExpr(
11993 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS.rotr(RHS); });
11995 case Builtin::BI__builtin_elementwise_max:
11996 case Builtin::BI__builtin_elementwise_min: {
11997 APValue SourceLHS, SourceRHS;
12002 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12009 ResultElements.reserve(SourceLen);
12011 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12015 case Builtin::BI__builtin_elementwise_max:
12016 ResultElements.push_back(
12020 case Builtin::BI__builtin_elementwise_min:
12021 ResultElements.push_back(
12028 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12030 case X86::BI__builtin_ia32_vpshldd128:
12031 case X86::BI__builtin_ia32_vpshldd256:
12032 case X86::BI__builtin_ia32_vpshldd512:
12033 case X86::BI__builtin_ia32_vpshldq128:
12034 case X86::BI__builtin_ia32_vpshldq256:
12035 case X86::BI__builtin_ia32_vpshldq512:
12036 case X86::BI__builtin_ia32_vpshldw128:
12037 case X86::BI__builtin_ia32_vpshldw256:
12038 case X86::BI__builtin_ia32_vpshldw512: {
12039 APValue SourceHi, SourceLo, SourceAmt;
12045 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12048 ResultElements.reserve(SourceLen);
12051 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12054 APInt R = llvm::APIntOps::fshl(Hi, Lo, Amt);
12055 ResultElements.push_back(
12059 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12061 case X86::BI__builtin_ia32_vpshrdd128:
12062 case X86::BI__builtin_ia32_vpshrdd256:
12063 case X86::BI__builtin_ia32_vpshrdd512:
12064 case X86::BI__builtin_ia32_vpshrdq128:
12065 case X86::BI__builtin_ia32_vpshrdq256:
12066 case X86::BI__builtin_ia32_vpshrdq512:
12067 case X86::BI__builtin_ia32_vpshrdw128:
12068 case X86::BI__builtin_ia32_vpshrdw256:
12069 case X86::BI__builtin_ia32_vpshrdw512: {
12071 APValue SourceHi, SourceLo, SourceAmt;
12077 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12080 ResultElements.reserve(SourceLen);
12083 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12086 APInt R = llvm::APIntOps::fshr(Hi, Lo, Amt);
12087 ResultElements.push_back(
12091 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12093 case X86::BI__builtin_ia32_blendpd:
12094 case X86::BI__builtin_ia32_blendpd256:
12095 case X86::BI__builtin_ia32_blendps:
12096 case X86::BI__builtin_ia32_blendps256:
12097 case X86::BI__builtin_ia32_pblendw128:
12098 case X86::BI__builtin_ia32_pblendw256:
12099 case X86::BI__builtin_ia32_pblendd128:
12100 case X86::BI__builtin_ia32_pblendd256: {
12101 APValue SourceF, SourceT, SourceC;
12110 ResultElements.reserve(SourceLen);
12111 for (
unsigned EltNum = 0; EltNum != SourceLen; ++EltNum) {
12114 ResultElements.push_back(
C[EltNum % 8] ?
T : F);
12117 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12120 case X86::BI__builtin_ia32_blendvpd:
12121 case X86::BI__builtin_ia32_blendvpd256:
12122 case X86::BI__builtin_ia32_blendvps:
12123 case X86::BI__builtin_ia32_blendvps256:
12124 case X86::BI__builtin_ia32_pblendvb128:
12125 case X86::BI__builtin_ia32_pblendvb256: {
12127 APValue SourceF, SourceT, SourceC;
12135 ResultElements.reserve(SourceLen);
12137 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12141 APInt M =
C.isInt() ? (
APInt)
C.getInt() :
C.getFloat().bitcastToAPInt();
12142 ResultElements.push_back(M.isNegative() ?
T : F);
12145 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12147 case X86::BI__builtin_ia32_selectb_128:
12148 case X86::BI__builtin_ia32_selectb_256:
12149 case X86::BI__builtin_ia32_selectb_512:
12150 case X86::BI__builtin_ia32_selectw_128:
12151 case X86::BI__builtin_ia32_selectw_256:
12152 case X86::BI__builtin_ia32_selectw_512:
12153 case X86::BI__builtin_ia32_selectd_128:
12154 case X86::BI__builtin_ia32_selectd_256:
12155 case X86::BI__builtin_ia32_selectd_512:
12156 case X86::BI__builtin_ia32_selectq_128:
12157 case X86::BI__builtin_ia32_selectq_256:
12158 case X86::BI__builtin_ia32_selectq_512:
12159 case X86::BI__builtin_ia32_selectph_128:
12160 case X86::BI__builtin_ia32_selectph_256:
12161 case X86::BI__builtin_ia32_selectph_512:
12162 case X86::BI__builtin_ia32_selectpbf_128:
12163 case X86::BI__builtin_ia32_selectpbf_256:
12164 case X86::BI__builtin_ia32_selectpbf_512:
12165 case X86::BI__builtin_ia32_selectps_128:
12166 case X86::BI__builtin_ia32_selectps_256:
12167 case X86::BI__builtin_ia32_selectps_512:
12168 case X86::BI__builtin_ia32_selectpd_128:
12169 case X86::BI__builtin_ia32_selectpd_256:
12170 case X86::BI__builtin_ia32_selectpd_512: {
12172 APValue SourceMask, SourceLHS, SourceRHS;
12181 ResultElements.reserve(SourceLen);
12183 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12186 ResultElements.push_back(Mask[EltNum] ? LHS : RHS);
12189 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12192 case X86::BI__builtin_ia32_pshuflw:
12193 case X86::BI__builtin_ia32_pshuflw256:
12194 case X86::BI__builtin_ia32_pshuflw512: {
12201 case X86::BI__builtin_ia32_pshufhw:
12202 case X86::BI__builtin_ia32_pshufhw256:
12203 case X86::BI__builtin_ia32_pshufhw512: {
12210 case X86::BI__builtin_ia32_pshufd:
12211 case X86::BI__builtin_ia32_pshufd256:
12212 case X86::BI__builtin_ia32_pshufd512: {
12219 case X86::BI__builtin_ia32_pternlogd128_mask:
12220 case X86::BI__builtin_ia32_pternlogd256_mask:
12221 case X86::BI__builtin_ia32_pternlogd512_mask:
12222 case X86::BI__builtin_ia32_pternlogq128_mask:
12223 case X86::BI__builtin_ia32_pternlogq256_mask:
12224 case X86::BI__builtin_ia32_pternlogq512_mask: {
12225 APValue AValue, BValue, CValue, ImmValue, UValue;
12233 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12239 ResultElements.reserve(ResultLen);
12241 for (
unsigned EltNum = 0; EltNum < ResultLen; ++EltNum) {
12247 unsigned BitWidth = ALane.getBitWidth();
12248 APInt ResLane(BitWidth, 0);
12250 for (
unsigned Bit = 0; Bit < BitWidth; ++Bit) {
12251 unsigned ABit = ALane[Bit];
12252 unsigned BBit = BLane[Bit];
12253 unsigned CBit = CLane[Bit];
12255 unsigned Idx = (ABit << 2) | (BBit << 1) | CBit;
12256 ResLane.setBitVal(Bit, Imm[Idx]);
12258 ResultElements.push_back(
APValue(
APSInt(ResLane, DestUnsigned)));
12260 ResultElements.push_back(
APValue(
APSInt(ALane, DestUnsigned)));
12263 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12265 case X86::BI__builtin_ia32_pternlogd128_maskz:
12266 case X86::BI__builtin_ia32_pternlogd256_maskz:
12267 case X86::BI__builtin_ia32_pternlogd512_maskz:
12268 case X86::BI__builtin_ia32_pternlogq128_maskz:
12269 case X86::BI__builtin_ia32_pternlogq256_maskz:
12270 case X86::BI__builtin_ia32_pternlogq512_maskz: {
12271 APValue AValue, BValue, CValue, ImmValue, UValue;
12279 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12285 ResultElements.reserve(ResultLen);
12287 for (
unsigned EltNum = 0; EltNum < ResultLen; ++EltNum) {
12292 unsigned BitWidth = ALane.getBitWidth();
12293 APInt ResLane(BitWidth, 0);
12296 for (
unsigned Bit = 0; Bit < BitWidth; ++Bit) {
12297 unsigned ABit = ALane[Bit];
12298 unsigned BBit = BLane[Bit];
12299 unsigned CBit = CLane[Bit];
12301 unsigned Idx = (ABit << 2) | (BBit << 1) | CBit;
12302 ResLane.setBitVal(Bit, Imm[Idx]);
12305 ResultElements.push_back(
APValue(
APSInt(ResLane, DestUnsigned)));
12307 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12310 case Builtin::BI__builtin_elementwise_clzg:
12311 case Builtin::BI__builtin_elementwise_ctzg: {
12313 std::optional<APValue> Fallback;
12320 Fallback = FallbackTmp;
12323 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12326 ResultElements.reserve(SourceLen);
12328 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12333 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
12335 Builtin::BI__builtin_elementwise_ctzg);
12338 ResultElements.push_back(Fallback->getVectorElt(EltNum));
12342 case Builtin::BI__builtin_elementwise_clzg:
12343 ResultElements.push_back(
APValue(
12347 case Builtin::BI__builtin_elementwise_ctzg:
12348 ResultElements.push_back(
APValue(
12355 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12358 case Builtin::BI__builtin_elementwise_fma: {
12359 APValue SourceX, SourceY, SourceZ;
12367 ResultElements.reserve(SourceLen);
12369 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12374 (void)
Result.fusedMultiplyAdd(Y, Z, RM);
12377 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12380 case Builtin::BI__builtin_elementwise_fshl:
12381 case Builtin::BI__builtin_elementwise_fshr: {
12382 APValue SourceHi, SourceLo, SourceShift;
12388 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12394 ResultElements.reserve(SourceLen);
12395 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12400 case Builtin::BI__builtin_elementwise_fshl:
12401 ResultElements.push_back(
APValue(
12402 APSInt(llvm::APIntOps::fshl(Hi, Lo, Shift), Hi.isUnsigned())));
12404 case Builtin::BI__builtin_elementwise_fshr:
12405 ResultElements.push_back(
APValue(
12406 APSInt(llvm::APIntOps::fshr(Hi, Lo, Shift), Hi.isUnsigned())));
12411 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12414 case X86::BI__builtin_ia32_insertf32x4_256:
12415 case X86::BI__builtin_ia32_inserti32x4_256:
12416 case X86::BI__builtin_ia32_insertf64x2_256:
12417 case X86::BI__builtin_ia32_inserti64x2_256:
12418 case X86::BI__builtin_ia32_insertf32x4:
12419 case X86::BI__builtin_ia32_inserti32x4:
12420 case X86::BI__builtin_ia32_insertf64x2_512:
12421 case X86::BI__builtin_ia32_inserti64x2_512:
12422 case X86::BI__builtin_ia32_insertf32x8:
12423 case X86::BI__builtin_ia32_inserti32x8:
12424 case X86::BI__builtin_ia32_insertf64x4:
12425 case X86::BI__builtin_ia32_inserti64x4:
12426 case X86::BI__builtin_ia32_vinsertf128_ps256:
12427 case X86::BI__builtin_ia32_vinsertf128_pd256:
12428 case X86::BI__builtin_ia32_vinsertf128_si256:
12429 case X86::BI__builtin_ia32_insert128i256: {
12430 APValue SourceDst, SourceSub;
12442 assert(SubLen != 0 && DstLen != 0 && (DstLen % SubLen) == 0);
12443 unsigned NumLanes = DstLen / SubLen;
12444 unsigned LaneIdx = (Imm.getZExtValue() % NumLanes) * SubLen;
12447 ResultElements.reserve(DstLen);
12449 for (
unsigned EltNum = 0; EltNum < DstLen; ++EltNum) {
12450 if (EltNum >= LaneIdx && EltNum < LaneIdx + SubLen)
12451 ResultElements.push_back(SourceSub.
getVectorElt(EltNum - LaneIdx));
12453 ResultElements.push_back(SourceDst.
getVectorElt(EltNum));
12456 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12459 case clang::X86::BI__builtin_ia32_vec_set_v4hi:
12460 case clang::X86::BI__builtin_ia32_vec_set_v16qi:
12461 case clang::X86::BI__builtin_ia32_vec_set_v8hi:
12462 case clang::X86::BI__builtin_ia32_vec_set_v4si:
12463 case clang::X86::BI__builtin_ia32_vec_set_v2di:
12464 case clang::X86::BI__builtin_ia32_vec_set_v32qi:
12465 case clang::X86::BI__builtin_ia32_vec_set_v16hi:
12466 case clang::X86::BI__builtin_ia32_vec_set_v8si:
12467 case clang::X86::BI__builtin_ia32_vec_set_v4di: {
12475 QualType ElemTy = E->
getType()->
castAs<VectorType>()->getElementType();
12476 unsigned ElemWidth = Info.Ctx.
getIntWidth(ElemTy);
12478 Scalar.setIsUnsigned(ElemUnsigned);
12484 static_cast<unsigned>(IndexAPS.getZExtValue() & (NumElems - 1));
12487 Elems.reserve(NumElems);
12488 for (
unsigned ElemNum = 0; ElemNum != NumElems; ++ElemNum)
12489 Elems.push_back(ElemNum == Index ? ElemAV : VecVal.
getVectorElt(ElemNum));
12496bool VectorExprEvaluator::VisitConvertVectorExpr(
const ConvertVectorExpr *E) {
12502 QualType DestTy = E->
getType()->
castAs<VectorType>()->getElementType();
12503 QualType SourceTy = SourceVecType->
castAs<VectorType>()->getElementType();
12509 ResultElements.reserve(SourceLen);
12510 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12515 ResultElements.push_back(std::move(Elt));
12518 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12523 APValue const &VecVal2,
unsigned EltNum,
12525 unsigned const TotalElementsInInputVector1 = VecVal1.
getVectorLength();
12526 unsigned const TotalElementsInInputVector2 = VecVal2.
getVectorLength();
12529 int64_t
index = IndexVal.getExtValue();
12536 E, diag::err_shufflevector_minus_one_is_undefined_behavior_constexpr)
12542 index >= TotalElementsInInputVector1 + TotalElementsInInputVector2)
12543 llvm_unreachable(
"Out of bounds shuffle index");
12545 if (
index >= TotalElementsInInputVector1)
12552bool VectorExprEvaluator::VisitShuffleVectorExpr(
const ShuffleVectorExpr *E) {
12557 const Expr *Vec1 = E->
getExpr(0);
12561 const Expr *Vec2 = E->
getExpr(1);
12565 VectorType
const *DestVecTy = E->
getType()->
castAs<VectorType>();
12571 ResultElements.reserve(TotalElementsInOutputVector);
12572 for (
unsigned EltNum = 0; EltNum < TotalElementsInOutputVector; ++EltNum) {
12576 ResultElements.push_back(std::move(Elt));
12579 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12587 class ArrayExprEvaluator
12588 :
public ExprEvaluatorBase<ArrayExprEvaluator> {
12589 const LValue &
This;
12593 ArrayExprEvaluator(EvalInfo &Info,
const LValue &This,
APValue &
Result)
12597 assert(
V.isArray() &&
"expected array");
12602 bool ZeroInitialization(
const Expr *E) {
12603 const ConstantArrayType *CAT =
12618 if (!
Result.hasArrayFiller())
12622 LValue Subobject =
This;
12623 Subobject.addArray(Info, E, CAT);
12628 bool VisitCallExpr(
const CallExpr *E) {
12629 return handleCallExpr(E,
Result, &This);
12631 bool VisitInitListExpr(
const InitListExpr *E,
12632 QualType AllocType = QualType());
12633 bool VisitArrayInitLoopExpr(
const ArrayInitLoopExpr *E);
12634 bool VisitCXXConstructExpr(
const CXXConstructExpr *E);
12635 bool VisitCXXConstructExpr(
const CXXConstructExpr *E,
12636 const LValue &Subobject,
12638 bool VisitStringLiteral(
const StringLiteral *E,
12639 QualType AllocType = QualType()) {
12643 bool VisitCXXParenListInitExpr(
const CXXParenListInitExpr *E);
12644 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
12645 ArrayRef<Expr *> Args,
12646 const Expr *ArrayFiller,
12647 QualType AllocType = QualType());
12652 APValue &Result, EvalInfo &Info) {
12655 "not an array prvalue");
12656 return ArrayExprEvaluator(Info,
This, Result).Visit(E);
12664 "not an array prvalue");
12665 return ArrayExprEvaluator(Info,
This, Result)
12666 .VisitInitListExpr(ILE, AllocType);
12675 "not an array prvalue");
12676 return ArrayExprEvaluator(Info,
This, Result)
12677 .VisitCXXConstructExpr(CCE,
This, &Result, AllocType);
12686 if (
const InitListExpr *ILE = dyn_cast<InitListExpr>(FillerExpr)) {
12687 for (
unsigned I = 0, E = ILE->
getNumInits(); I != E; ++I) {
12692 if (ILE->hasArrayFiller() &&
12701bool ArrayExprEvaluator::VisitInitListExpr(
const InitListExpr *E,
12702 QualType AllocType) {
12716 return VisitStringLiteral(SL, AllocType);
12721 "transparent array list initialization is not string literal init?");
12727bool ArrayExprEvaluator::VisitCXXParenListOrInitListExpr(
12729 QualType AllocType) {
12735 assert((!
Result.isArray() ||
Result.getArrayInitializedElts() == 0) &&
12736 "zero-initialized array shouldn't have any initialized elts");
12741 unsigned NumEltsToInit = Args.size();
12746 if (NumEltsToInit != NumElts &&
12748 NumEltsToInit = NumElts;
12750 for (
auto *
Init : Args) {
12751 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts()))
12752 NumEltsToInit += EmbedS->getDataElementCount() - 1;
12754 if (NumEltsToInit > NumElts)
12755 NumEltsToInit = NumElts;
12758 LLVM_DEBUG(llvm::dbgs() <<
"The number of elements to initialize: "
12759 << NumEltsToInit <<
".\n");
12761 Result =
APValue(APValue::UninitArray(), NumEltsToInit, NumElts);
12766 for (
unsigned I = 0, E =
Result.getArrayInitializedElts(); I != E; ++I)
12767 Result.getArrayInitializedElt(I) = Filler;
12768 if (
Result.hasArrayFiller())
12772 LValue Subobject =
This;
12773 Subobject.addArray(Info, ExprToVisit, CAT);
12774 auto Eval = [&](
const Expr *
Init,
unsigned ArrayIndex) {
12775 if (
Init->isValueDependent())
12779 Subobject,
Init) ||
12782 if (!Info.noteFailure())
12788 unsigned ArrayIndex = 0;
12791 for (
unsigned Index = 0; Index != NumEltsToInit; ++Index) {
12792 const Expr *
Init = Index < Args.size() ? Args[Index] : ArrayFiller;
12793 if (ArrayIndex >= NumEltsToInit)
12795 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
12796 StringLiteral *SL = EmbedS->getDataStringLiteral();
12797 for (
unsigned I = EmbedS->getStartingElementPos(),
12798 N = EmbedS->getDataElementCount();
12799 I != EmbedS->getStartingElementPos() + N; ++I) {
12805 const FPOptions FPO =
12811 Result.getArrayInitializedElt(ArrayIndex) =
APValue(FValue);
12816 if (!Eval(
Init, ArrayIndex))
12822 if (!
Result.hasArrayFiller())
12827 assert(ArrayFiller &&
"no array filler for incomplete init list");
12833bool ArrayExprEvaluator::VisitArrayInitLoopExpr(
const ArrayInitLoopExpr *E) {
12836 !
Evaluate(Info.CurrentCall->createTemporary(
12839 ScopeKind::FullExpression, CommonLV),
12846 Result =
APValue(APValue::UninitArray(), Elements, Elements);
12848 LValue Subobject =
This;
12849 Subobject.addArray(Info, E, CAT);
12852 for (EvalInfo::ArrayInitLoopIndex Index(Info); Index != Elements; ++Index) {
12861 FullExpressionRAII Scope(Info);
12867 if (!Info.noteFailure())
12879bool ArrayExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E) {
12880 return VisitCXXConstructExpr(E, This, &
Result, E->
getType());
12883bool ArrayExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E,
12884 const LValue &Subobject,
12887 bool HadZeroInit =
Value->hasValue();
12894 HadZeroInit &&
Value->hasArrayFiller() ?
Value->getArrayFiller()
12897 *
Value =
APValue(APValue::UninitArray(), 0, FinalSize);
12898 if (FinalSize == 0)
12904 LValue ArrayElt = Subobject;
12905 ArrayElt.addArray(Info, E, CAT);
12911 for (
const unsigned N : {1u, FinalSize}) {
12912 unsigned OldElts =
Value->getArrayInitializedElts();
12917 APValue NewValue(APValue::UninitArray(), N, FinalSize);
12918 for (
unsigned I = 0; I < OldElts; ++I)
12919 NewValue.getArrayInitializedElt(I).swap(
12920 Value->getArrayInitializedElt(I));
12921 Value->swap(NewValue);
12924 for (
unsigned I = OldElts; I < N; ++I)
12925 Value->getArrayInitializedElt(I) = Filler;
12927 if (HasTrivialConstructor && N == FinalSize && FinalSize != 1) {
12930 APValue &FirstResult =
Value->getArrayInitializedElt(0);
12931 for (
unsigned I = OldElts; I < FinalSize; ++I)
12932 Value->getArrayInitializedElt(I) = FirstResult;
12934 for (
unsigned I = OldElts; I < N; ++I) {
12935 if (!VisitCXXConstructExpr(E, ArrayElt,
12936 &
Value->getArrayInitializedElt(I),
12943 if (Info.EvalStatus.
Diag && !Info.EvalStatus.
Diag->empty() &&
12944 !Info.keepEvaluatingAfterFailure())
12953 if (!
Type->isRecordType())
12956 return RecordExprEvaluator(Info, Subobject, *
Value)
12957 .VisitCXXConstructExpr(E,
Type);
12960bool ArrayExprEvaluator::VisitCXXParenListInitExpr(
12961 const CXXParenListInitExpr *E) {
12963 "Expression result is not a constant array type");
12965 return VisitCXXParenListOrInitListExpr(E, E->
getInitExprs(),
12978class IntExprEvaluator
12979 :
public ExprEvaluatorBase<IntExprEvaluator> {
12982 IntExprEvaluator(EvalInfo &info,
APValue &result)
12983 : ExprEvaluatorBaseTy(info),
Result(result) {}
12987 "Invalid evaluation result.");
12989 "Invalid evaluation result.");
12991 "Invalid evaluation result.");
12995 bool Success(
const llvm::APSInt &SI,
const Expr *E) {
13001 "Invalid evaluation result.");
13003 "Invalid evaluation result.");
13005 Result.getInt().setIsUnsigned(
13009 bool Success(
const llvm::APInt &I,
const Expr *E) {
13015 "Invalid evaluation result.");
13023 bool Success(CharUnits Size,
const Expr *E) {
13030 if (
V.isLValue() ||
V.isAddrLabelDiff() ||
V.isIndeterminate() ||
13031 V.allowConstexprUnknown()) {
13038 bool ZeroInitialization(
const Expr *E) {
return Success(0, E); }
13040 friend std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &,
13047 bool VisitIntegerLiteral(
const IntegerLiteral *E) {
13050 bool VisitCharacterLiteral(
const CharacterLiteral *E) {
13054 bool CheckReferencedDecl(
const Expr *E,
const Decl *D);
13055 bool VisitDeclRefExpr(
const DeclRefExpr *E) {
13056 if (CheckReferencedDecl(E, E->
getDecl()))
13059 return ExprEvaluatorBaseTy::VisitDeclRefExpr(E);
13061 bool VisitMemberExpr(
const MemberExpr *E) {
13063 VisitIgnoredBaseExpression(E->
getBase());
13067 return ExprEvaluatorBaseTy::VisitMemberExpr(E);
13070 bool VisitCallExpr(
const CallExpr *E);
13071 bool VisitBuiltinCallExpr(
const CallExpr *E,
unsigned BuiltinOp);
13072 bool VisitBinaryOperator(
const BinaryOperator *E);
13073 bool VisitOffsetOfExpr(
const OffsetOfExpr *E);
13074 bool VisitUnaryOperator(
const UnaryOperator *E);
13076 bool VisitCastExpr(
const CastExpr* E);
13077 bool VisitUnaryExprOrTypeTraitExpr(
const UnaryExprOrTypeTraitExpr *E);
13079 bool VisitCXXBoolLiteralExpr(
const CXXBoolLiteralExpr *E) {
13083 bool VisitObjCBoolLiteralExpr(
const ObjCBoolLiteralExpr *E) {
13087 bool VisitArrayInitIndexExpr(
const ArrayInitIndexExpr *E) {
13088 if (Info.ArrayInitIndex ==
uint64_t(-1)) {
13094 return Success(Info.ArrayInitIndex, E);
13098 bool VisitGNUNullExpr(
const GNUNullExpr *E) {
13099 return ZeroInitialization(E);
13102 bool VisitTypeTraitExpr(
const TypeTraitExpr *E) {
13111 bool VisitArrayTypeTraitExpr(
const ArrayTypeTraitExpr *E) {
13115 bool VisitExpressionTraitExpr(
const ExpressionTraitExpr *E) {
13119 bool VisitOpenACCAsteriskSizeExpr(
const OpenACCAsteriskSizeExpr *E) {
13126 bool VisitUnaryReal(
const UnaryOperator *E);
13127 bool VisitUnaryImag(
const UnaryOperator *E);
13129 bool VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E);
13130 bool VisitSizeOfPackExpr(
const SizeOfPackExpr *E);
13131 bool VisitSourceLocExpr(
const SourceLocExpr *E);
13132 bool VisitConceptSpecializationExpr(
const ConceptSpecializationExpr *E);
13137class FixedPointExprEvaluator
13138 :
public ExprEvaluatorBase<FixedPointExprEvaluator> {
13142 FixedPointExprEvaluator(EvalInfo &info,
APValue &result)
13143 : ExprEvaluatorBaseTy(info),
Result(result) {}
13145 bool Success(
const llvm::APInt &I,
const Expr *E) {
13156 return Success(
V.getFixedPoint(), E);
13159 bool Success(
const APFixedPoint &
V,
const Expr *E) {
13162 "Invalid evaluation result.");
13167 bool ZeroInitialization(
const Expr *E) {
13175 bool VisitFixedPointLiteral(
const FixedPointLiteral *E) {
13179 bool VisitCastExpr(
const CastExpr *E);
13180 bool VisitUnaryOperator(
const UnaryOperator *E);
13181 bool VisitBinaryOperator(
const BinaryOperator *E);
13197 return IntExprEvaluator(Info, Result).Visit(E);
13205 if (!Val.
isInt()) {
13208 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
13215bool IntExprEvaluator::VisitSourceLocExpr(
const SourceLocExpr *E) {
13217 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.
getDefaultExpr());
13226 if (!FixedPointExprEvaluator(Info, Val).Visit(E))
13245 Result = APFixedPoint(Val, FXSema);
13256bool IntExprEvaluator::CheckReferencedDecl(
const Expr* E,
const Decl* D) {
13258 if (
const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(D)) {
13260 bool SameSign = (ECD->getInitVal().isSigned()
13262 bool SameWidth = (ECD->getInitVal().getBitWidth()
13264 if (SameSign && SameWidth)
13265 return Success(ECD->getInitVal(), E);
13269 llvm::APSInt Val = ECD->getInitVal();
13271 Val.setIsSigned(!ECD->getInitVal().isSigned());
13284 assert(!
T->isDependentType() &&
"unexpected dependent type");
13289#define TYPE(ID, BASE)
13290#define DEPENDENT_TYPE(ID, BASE) case Type::ID:
13291#define NON_CANONICAL_TYPE(ID, BASE) case Type::ID:
13292#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(ID, BASE) case Type::ID:
13293#include "clang/AST/TypeNodes.inc"
13295 case Type::DeducedTemplateSpecialization:
13296 llvm_unreachable(
"unexpected non-canonical or dependent type");
13298 case Type::Builtin:
13300#define BUILTIN_TYPE(ID, SINGLETON_ID)
13301#define SIGNED_TYPE(ID, SINGLETON_ID) \
13302 case BuiltinType::ID: return GCCTypeClass::Integer;
13303#define FLOATING_TYPE(ID, SINGLETON_ID) \
13304 case BuiltinType::ID: return GCCTypeClass::RealFloat;
13305#define PLACEHOLDER_TYPE(ID, SINGLETON_ID) \
13306 case BuiltinType::ID: break;
13307#include "clang/AST/BuiltinTypes.def"
13308 case BuiltinType::Void:
13311 case BuiltinType::Bool:
13314 case BuiltinType::Char_U:
13315 case BuiltinType::UChar:
13316 case BuiltinType::WChar_U:
13317 case BuiltinType::Char8:
13318 case BuiltinType::Char16:
13319 case BuiltinType::Char32:
13320 case BuiltinType::UShort:
13321 case BuiltinType::UInt:
13322 case BuiltinType::ULong:
13323 case BuiltinType::ULongLong:
13324 case BuiltinType::UInt128:
13327 case BuiltinType::UShortAccum:
13328 case BuiltinType::UAccum:
13329 case BuiltinType::ULongAccum:
13330 case BuiltinType::UShortFract:
13331 case BuiltinType::UFract:
13332 case BuiltinType::ULongFract:
13333 case BuiltinType::SatUShortAccum:
13334 case BuiltinType::SatUAccum:
13335 case BuiltinType::SatULongAccum:
13336 case BuiltinType::SatUShortFract:
13337 case BuiltinType::SatUFract:
13338 case BuiltinType::SatULongFract:
13341 case BuiltinType::NullPtr:
13343 case BuiltinType::ObjCId:
13344 case BuiltinType::ObjCClass:
13345 case BuiltinType::ObjCSel:
13346#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
13347 case BuiltinType::Id:
13348#include "clang/Basic/OpenCLImageTypes.def"
13349#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
13350 case BuiltinType::Id:
13351#include "clang/Basic/OpenCLExtensionTypes.def"
13352 case BuiltinType::OCLSampler:
13353 case BuiltinType::OCLEvent:
13354 case BuiltinType::OCLClkEvent:
13355 case BuiltinType::OCLQueue:
13356 case BuiltinType::OCLReserveID:
13357#define SVE_TYPE(Name, Id, SingletonId) \
13358 case BuiltinType::Id:
13359#include "clang/Basic/AArch64ACLETypes.def"
13360#define PPC_VECTOR_TYPE(Name, Id, Size) \
13361 case BuiltinType::Id:
13362#include "clang/Basic/PPCTypes.def"
13363#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
13364#include "clang/Basic/RISCVVTypes.def"
13365#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
13366#include "clang/Basic/WebAssemblyReferenceTypes.def"
13367#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
13368#include "clang/Basic/AMDGPUTypes.def"
13369#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
13370#include "clang/Basic/HLSLIntangibleTypes.def"
13373 case BuiltinType::Dependent:
13374 llvm_unreachable(
"unexpected dependent type");
13376 llvm_unreachable(
"unexpected placeholder type");
13381 case Type::Pointer:
13382 case Type::ConstantArray:
13383 case Type::VariableArray:
13384 case Type::IncompleteArray:
13385 case Type::FunctionNoProto:
13386 case Type::FunctionProto:
13387 case Type::ArrayParameter:
13390 case Type::MemberPointer:
13395 case Type::Complex:
13408 case Type::ExtVector:
13411 case Type::BlockPointer:
13412 case Type::ConstantMatrix:
13413 case Type::ObjCObject:
13414 case Type::ObjCInterface:
13415 case Type::ObjCObjectPointer:
13417 case Type::HLSLAttributedResource:
13418 case Type::HLSLInlineSpirv:
13426 case Type::LValueReference:
13427 case Type::RValueReference:
13428 llvm_unreachable(
"invalid type for expression");
13431 llvm_unreachable(
"unexpected type class");
13456 if (
Base.isNull()) {
13459 }
else if (
const Expr *E =
Base.dyn_cast<
const Expr *>()) {
13478 SpeculativeEvaluationRAII SpeculativeEval(Info);
13483 FoldConstant Fold(Info,
true);
13501 if (ArgType->isIntegralOrEnumerationType() || ArgType->isFloatingType() ||
13502 ArgType->isAnyComplexType() || ArgType->isPointerType() ||
13503 ArgType->isNullPtrType()) {
13506 Fold.keepDiagnostics();
13515 return V.hasValue();
13526 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
13550 const auto *Cast = dyn_cast<CastExpr>(NoParens);
13551 if (Cast ==
nullptr)
13556 auto CastKind = Cast->getCastKind();
13558 CastKind != CK_AddressSpaceConversion)
13561 const auto *SubExpr = Cast->getSubExpr();
13583 assert(!LVal.Designator.Invalid);
13585 auto IsLastOrInvalidFieldDecl = [&Ctx](
const FieldDecl *FD) {
13593 auto &
Base = LVal.getLValueBase();
13594 if (
auto *ME = dyn_cast_or_null<MemberExpr>(
Base.dyn_cast<
const Expr *>())) {
13595 if (
auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
13596 if (!IsLastOrInvalidFieldDecl(FD))
13598 }
else if (
auto *IFD = dyn_cast<IndirectFieldDecl>(ME->getMemberDecl())) {
13599 for (
auto *FD : IFD->chain()) {
13608 if (LVal.Designator.FirstEntryIsAnUnsizedArray) {
13612 if (BaseType->isIncompleteArrayType())
13618 for (
unsigned E = LVal.Designator.Entries.size(); I != E; ++I) {
13619 const auto &Entry = LVal.Designator.Entries[I];
13620 if (BaseType->isArrayType()) {
13626 uint64_t Index = Entry.getAsArrayIndex();
13630 }
else if (BaseType->isAnyComplexType()) {
13631 const auto *CT = BaseType->castAs<
ComplexType>();
13632 uint64_t Index = Entry.getAsArrayIndex();
13635 BaseType = CT->getElementType();
13636 }
else if (
auto *FD = getAsField(Entry)) {
13637 if (!IsLastOrInvalidFieldDecl(FD))
13641 assert(getAsBaseClass(Entry) &&
"Expecting cast to a base class");
13653 if (LVal.Designator.Invalid)
13656 if (!LVal.Designator.Entries.empty())
13657 return LVal.Designator.isMostDerivedAnUnsizedArray();
13659 if (!LVal.InvalidBase)
13671 const SubobjectDesignator &
Designator = LVal.Designator;
13683 auto isFlexibleArrayMember = [&] {
13685 FAMKind StrictFlexArraysLevel =
13688 if (
Designator.isMostDerivedAnUnsizedArray())
13691 if (StrictFlexArraysLevel == FAMKind::Default)
13694 if (
Designator.getMostDerivedArraySize() == 0 &&
13695 StrictFlexArraysLevel != FAMKind::IncompleteOnly)
13698 if (
Designator.getMostDerivedArraySize() == 1 &&
13699 StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete)
13705 return LVal.InvalidBase &&
13707 Designator.MostDerivedIsArrayElement && isFlexibleArrayMember() &&
13715 auto CharUnitsMax = std::numeric_limits<CharUnits::QuantityType>::max();
13716 if (Int.ugt(CharUnitsMax))
13726 if (!
T.isNull() &&
T->isStructureType() &&
13727 T->castAsRecordDecl()->hasFlexibleArrayMember())
13728 if (
const auto *
V = LV.getLValueBase().dyn_cast<
const ValueDecl *>())
13729 if (
const auto *VD = dyn_cast<VarDecl>(
V))
13741 unsigned Type,
const LValue &LVal,
13760 if (!(
Type & 1) || LVal.Designator.Invalid || DetermineForCompleteObject) {
13762 if (
Type == 3 && !DetermineForCompleteObject)
13765 llvm::APInt APEndOffset;
13766 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
13770 if (LVal.InvalidBase)
13774 const bool Ret = CheckedHandleSizeof(BaseTy, EndOffset);
13780 const SubobjectDesignator &
Designator = LVal.Designator;
13792 llvm::APInt APEndOffset;
13793 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
13805 if (!CheckedHandleSizeof(
Designator.MostDerivedType, BytesPerElem))
13811 int64_t ElemsRemaining;
13814 uint64_t ArraySize =
Designator.getMostDerivedArraySize();
13815 uint64_t ArrayIndex =
Designator.Entries.back().getAsArrayIndex();
13816 ElemsRemaining = ArraySize <= ArrayIndex ? 0 : ArraySize - ArrayIndex;
13818 ElemsRemaining =
Designator.isOnePastTheEnd() ? 0 : 1;
13821 EndOffset = LVal.getLValueOffset() + BytesPerElem * ElemsRemaining;
13831 EvalInfo &Info, uint64_t &Size) {
13838 SpeculativeEvaluationRAII SpeculativeEval(Info);
13839 IgnoreSideEffectsRAII Fold(Info);
13847 LVal.setFrom(Info.Ctx, RVal);
13855 if (LVal.getLValueOffset().isNegative()) {
13866 if (EndOffset <= LVal.getLValueOffset())
13869 Size = (EndOffset - LVal.getLValueOffset()).getQuantity();
13873bool IntExprEvaluator::VisitCallExpr(
const CallExpr *E) {
13874 if (!IsConstantEvaluatedBuiltinCall(E))
13875 return ExprEvaluatorBaseTy::VisitCallExpr(E);
13892 Info.FFDiag(E->
getArg(0));
13898 assert(SrcInt.getBitWidth() >= Alignment.getBitWidth() &&
13899 "Bit widths must be the same");
13906bool IntExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *E,
13907 unsigned BuiltinOp) {
13909 auto HandleMaskBinOp =
13922 switch (BuiltinOp) {
13926 case Builtin::BI__builtin_dynamic_object_size:
13927 case Builtin::BI__builtin_object_size: {
13931 assert(
Type <= 3 &&
"unexpected type");
13942 switch (Info.EvalMode) {
13943 case EvaluationMode::ConstantExpression:
13944 case EvaluationMode::ConstantFold:
13945 case EvaluationMode::IgnoreSideEffects:
13948 case EvaluationMode::ConstantExpressionUnevaluated:
13953 llvm_unreachable(
"unexpected EvalMode");
13956 case Builtin::BI__builtin_os_log_format_buffer_size: {
13957 analyze_os_log::OSLogBufferLayout Layout;
13962 case Builtin::BI__builtin_is_aligned: {
13970 Ptr.setFrom(Info.Ctx, Src);
13976 assert(Alignment.isPowerOf2());
13989 Info.FFDiag(E->
getArg(0), diag::note_constexpr_alignment_compute)
13993 assert(Src.
isInt());
13994 return Success((Src.
getInt() & (Alignment - 1)) == 0 ? 1 : 0, E);
13996 case Builtin::BI__builtin_align_up: {
14004 APSInt((Src.
getInt() + (Alignment - 1)) & ~(Alignment - 1),
14005 Src.
getInt().isUnsigned());
14006 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
14007 return Success(AlignedVal, E);
14009 case Builtin::BI__builtin_align_down: {
14018 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
14019 return Success(AlignedVal, E);
14022 case Builtin::BI__builtin_bitreverse8:
14023 case Builtin::BI__builtin_bitreverse16:
14024 case Builtin::BI__builtin_bitreverse32:
14025 case Builtin::BI__builtin_bitreverse64:
14026 case Builtin::BI__builtin_elementwise_bitreverse: {
14031 return Success(Val.reverseBits(), E);
14034 case Builtin::BI__builtin_bswap16:
14035 case Builtin::BI__builtin_bswap32:
14036 case Builtin::BI__builtin_bswap64: {
14041 return Success(Val.byteSwap(), E);
14044 case Builtin::BI__builtin_classify_type:
14047 case Builtin::BI__builtin_clrsb:
14048 case Builtin::BI__builtin_clrsbl:
14049 case Builtin::BI__builtin_clrsbll: {
14054 return Success(Val.getBitWidth() - Val.getSignificantBits(), E);
14057 case Builtin::BI__builtin_clz:
14058 case Builtin::BI__builtin_clzl:
14059 case Builtin::BI__builtin_clzll:
14060 case Builtin::BI__builtin_clzs:
14061 case Builtin::BI__builtin_clzg:
14062 case Builtin::BI__builtin_elementwise_clzg:
14063 case Builtin::BI__lzcnt16:
14064 case Builtin::BI__lzcnt:
14065 case Builtin::BI__lzcnt64: {
14076 std::optional<APSInt> Fallback;
14077 if ((BuiltinOp == Builtin::BI__builtin_clzg ||
14078 BuiltinOp == Builtin::BI__builtin_elementwise_clzg) &&
14083 Fallback = FallbackTemp;
14088 return Success(*Fallback, E);
14093 bool ZeroIsUndefined = BuiltinOp != Builtin::BI__lzcnt16 &&
14094 BuiltinOp != Builtin::BI__lzcnt &&
14095 BuiltinOp != Builtin::BI__lzcnt64;
14097 if (BuiltinOp == Builtin::BI__builtin_elementwise_clzg) {
14098 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
14102 if (ZeroIsUndefined)
14106 return Success(Val.countl_zero(), E);
14109 case Builtin::BI__builtin_constant_p: {
14110 const Expr *Arg = E->
getArg(0);
14119 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
14123 case Builtin::BI__noop:
14127 case Builtin::BI__builtin_is_constant_evaluated: {
14128 const auto *
Callee = Info.CurrentCall->getCallee();
14129 if (Info.InConstantContext && !Info.CheckingPotentialConstantExpression &&
14130 (Info.CallStackDepth == 1 ||
14131 (Info.CallStackDepth == 2 &&
Callee->isInStdNamespace() &&
14132 Callee->getIdentifier() &&
14133 Callee->getIdentifier()->isStr(
"is_constant_evaluated")))) {
14135 if (Info.EvalStatus.
Diag)
14136 Info.report((Info.CallStackDepth == 1)
14138 : Info.CurrentCall->getCallRange().getBegin(),
14139 diag::warn_is_constant_evaluated_always_true_constexpr)
14140 << (Info.CallStackDepth == 1 ?
"__builtin_is_constant_evaluated"
14141 :
"std::is_constant_evaluated");
14144 return Success(Info.InConstantContext, E);
14147 case Builtin::BI__builtin_is_within_lifetime:
14148 if (
auto result = EvaluateBuiltinIsWithinLifetime(*
this, E))
14152 case Builtin::BI__builtin_ctz:
14153 case Builtin::BI__builtin_ctzl:
14154 case Builtin::BI__builtin_ctzll:
14155 case Builtin::BI__builtin_ctzs:
14156 case Builtin::BI__builtin_ctzg:
14157 case Builtin::BI__builtin_elementwise_ctzg: {
14168 std::optional<APSInt> Fallback;
14169 if ((BuiltinOp == Builtin::BI__builtin_ctzg ||
14170 BuiltinOp == Builtin::BI__builtin_elementwise_ctzg) &&
14175 Fallback = FallbackTemp;
14180 return Success(*Fallback, E);
14182 if (BuiltinOp == Builtin::BI__builtin_elementwise_ctzg) {
14183 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
14189 return Success(Val.countr_zero(), E);
14192 case Builtin::BI__builtin_eh_return_data_regno: {
14198 case Builtin::BI__builtin_elementwise_abs: {
14203 return Success(Val.abs(), E);
14206 case Builtin::BI__builtin_expect:
14207 case Builtin::BI__builtin_expect_with_probability:
14208 return Visit(E->
getArg(0));
14210 case Builtin::BI__builtin_ptrauth_string_discriminator: {
14217 case Builtin::BI__builtin_ffs:
14218 case Builtin::BI__builtin_ffsl:
14219 case Builtin::BI__builtin_ffsll: {
14224 unsigned N = Val.countr_zero();
14225 return Success(N == Val.getBitWidth() ? 0 : N + 1, E);
14228 case Builtin::BI__builtin_fpclassify: {
14233 switch (Val.getCategory()) {
14234 case APFloat::fcNaN: Arg = 0;
break;
14235 case APFloat::fcInfinity: Arg = 1;
break;
14236 case APFloat::fcNormal: Arg = Val.isDenormal() ? 3 : 2;
break;
14237 case APFloat::fcZero: Arg = 4;
break;
14239 return Visit(E->
getArg(Arg));
14242 case Builtin::BI__builtin_isinf_sign: {
14245 Success(Val.isInfinity() ? (Val.isNegative() ? -1 : 1) : 0, E);
14248 case Builtin::BI__builtin_isinf: {
14251 Success(Val.isInfinity() ? 1 : 0, E);
14254 case Builtin::BI__builtin_isfinite: {
14257 Success(Val.isFinite() ? 1 : 0, E);
14260 case Builtin::BI__builtin_isnan: {
14263 Success(Val.isNaN() ? 1 : 0, E);
14266 case Builtin::BI__builtin_isnormal: {
14269 Success(Val.isNormal() ? 1 : 0, E);
14272 case Builtin::BI__builtin_issubnormal: {
14275 Success(Val.isDenormal() ? 1 : 0, E);
14278 case Builtin::BI__builtin_iszero: {
14281 Success(Val.isZero() ? 1 : 0, E);
14284 case Builtin::BI__builtin_signbit:
14285 case Builtin::BI__builtin_signbitf:
14286 case Builtin::BI__builtin_signbitl: {
14289 Success(Val.isNegative() ? 1 : 0, E);
14292 case Builtin::BI__builtin_isgreater:
14293 case Builtin::BI__builtin_isgreaterequal:
14294 case Builtin::BI__builtin_isless:
14295 case Builtin::BI__builtin_islessequal:
14296 case Builtin::BI__builtin_islessgreater:
14297 case Builtin::BI__builtin_isunordered: {
14306 switch (BuiltinOp) {
14307 case Builtin::BI__builtin_isgreater:
14309 case Builtin::BI__builtin_isgreaterequal:
14311 case Builtin::BI__builtin_isless:
14313 case Builtin::BI__builtin_islessequal:
14315 case Builtin::BI__builtin_islessgreater: {
14316 APFloat::cmpResult cmp = LHS.compare(RHS);
14317 return cmp == APFloat::cmpResult::cmpLessThan ||
14318 cmp == APFloat::cmpResult::cmpGreaterThan;
14320 case Builtin::BI__builtin_isunordered:
14321 return LHS.compare(RHS) == APFloat::cmpResult::cmpUnordered;
14323 llvm_unreachable(
"Unexpected builtin ID: Should be a floating "
14324 "point comparison function");
14332 case Builtin::BI__builtin_issignaling: {
14335 Success(Val.isSignaling() ? 1 : 0, E);
14338 case Builtin::BI__builtin_isfpclass: {
14342 unsigned Test =
static_cast<llvm::FPClassTest
>(MaskVal.getZExtValue());
14345 Success((Val.classify() & Test) ? 1 : 0, E);
14348 case Builtin::BI__builtin_parity:
14349 case Builtin::BI__builtin_parityl:
14350 case Builtin::BI__builtin_parityll: {
14355 return Success(Val.popcount() % 2, E);
14358 case Builtin::BI__builtin_abs:
14359 case Builtin::BI__builtin_labs:
14360 case Builtin::BI__builtin_llabs: {
14364 if (Val ==
APSInt(APInt::getSignedMinValue(Val.getBitWidth()),
14367 if (Val.isNegative())
14372 case Builtin::BI__builtin_popcount:
14373 case Builtin::BI__builtin_popcountl:
14374 case Builtin::BI__builtin_popcountll:
14375 case Builtin::BI__builtin_popcountg:
14376 case Builtin::BI__builtin_elementwise_popcount:
14377 case Builtin::BI__popcnt16:
14378 case Builtin::BI__popcnt:
14379 case Builtin::BI__popcnt64: {
14390 return Success(Val.popcount(), E);
14393 case Builtin::BI__builtin_rotateleft8:
14394 case Builtin::BI__builtin_rotateleft16:
14395 case Builtin::BI__builtin_rotateleft32:
14396 case Builtin::BI__builtin_rotateleft64:
14397 case Builtin::BI_rotl8:
14398 case Builtin::BI_rotl16:
14399 case Builtin::BI_rotl:
14400 case Builtin::BI_lrotl:
14401 case Builtin::BI_rotl64: {
14407 return Success(Val.rotl(Amt), E);
14410 case Builtin::BI__builtin_rotateright8:
14411 case Builtin::BI__builtin_rotateright16:
14412 case Builtin::BI__builtin_rotateright32:
14413 case Builtin::BI__builtin_rotateright64:
14414 case Builtin::BI_rotr8:
14415 case Builtin::BI_rotr16:
14416 case Builtin::BI_rotr:
14417 case Builtin::BI_lrotr:
14418 case Builtin::BI_rotr64: {
14424 return Success(Val.rotr(Amt), E);
14427 case Builtin::BI__builtin_elementwise_add_sat: {
14433 APInt Result = LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS);
14436 case Builtin::BI__builtin_elementwise_sub_sat: {
14442 APInt Result = LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
14445 case Builtin::BI__builtin_elementwise_max: {
14454 case Builtin::BI__builtin_elementwise_min: {
14463 case Builtin::BI__builtin_elementwise_fshl:
14464 case Builtin::BI__builtin_elementwise_fshr: {
14471 switch (BuiltinOp) {
14472 case Builtin::BI__builtin_elementwise_fshl: {
14473 APSInt Result(llvm::APIntOps::fshl(Hi, Lo, Shift), Hi.isUnsigned());
14476 case Builtin::BI__builtin_elementwise_fshr: {
14477 APSInt Result(llvm::APIntOps::fshr(Hi, Lo, Shift), Hi.isUnsigned());
14481 llvm_unreachable(
"Fully covered switch above");
14483 case Builtin::BIstrlen:
14484 case Builtin::BIwcslen:
14486 if (Info.getLangOpts().CPlusPlus11)
14487 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
14491 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
14493 case Builtin::BI__builtin_strlen:
14494 case Builtin::BI__builtin_wcslen: {
14503 case Builtin::BIstrcmp:
14504 case Builtin::BIwcscmp:
14505 case Builtin::BIstrncmp:
14506 case Builtin::BIwcsncmp:
14507 case Builtin::BImemcmp:
14508 case Builtin::BIbcmp:
14509 case Builtin::BIwmemcmp:
14511 if (Info.getLangOpts().CPlusPlus11)
14512 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
14516 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
14518 case Builtin::BI__builtin_strcmp:
14519 case Builtin::BI__builtin_wcscmp:
14520 case Builtin::BI__builtin_strncmp:
14521 case Builtin::BI__builtin_wcsncmp:
14522 case Builtin::BI__builtin_memcmp:
14523 case Builtin::BI__builtin_bcmp:
14524 case Builtin::BI__builtin_wmemcmp: {
14525 LValue String1, String2;
14531 if (BuiltinOp != Builtin::BIstrcmp &&
14532 BuiltinOp != Builtin::BIwcscmp &&
14533 BuiltinOp != Builtin::BI__builtin_strcmp &&
14534 BuiltinOp != Builtin::BI__builtin_wcscmp) {
14538 MaxLength = N.getZExtValue();
14542 if (MaxLength == 0u)
14545 if (!String1.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
14546 !String2.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
14547 String1.Designator.Invalid || String2.Designator.Invalid)
14550 QualType CharTy1 = String1.Designator.getType(Info.Ctx);
14551 QualType CharTy2 = String2.Designator.getType(Info.Ctx);
14553 bool IsRawByte = BuiltinOp == Builtin::BImemcmp ||
14554 BuiltinOp == Builtin::BIbcmp ||
14555 BuiltinOp == Builtin::BI__builtin_memcmp ||
14556 BuiltinOp == Builtin::BI__builtin_bcmp;
14558 assert(IsRawByte ||
14568 Info.FFDiag(E, diag::note_constexpr_memcmp_unsupported)
14574 const auto &ReadCurElems = [&](
APValue &Char1,
APValue &Char2) {
14577 Char1.
isInt() && Char2.isInt();
14579 const auto &AdvanceElems = [&] {
14585 (BuiltinOp != Builtin::BImemcmp && BuiltinOp != Builtin::BIbcmp &&
14586 BuiltinOp != Builtin::BIwmemcmp &&
14587 BuiltinOp != Builtin::BI__builtin_memcmp &&
14588 BuiltinOp != Builtin::BI__builtin_bcmp &&
14589 BuiltinOp != Builtin::BI__builtin_wmemcmp);
14590 bool IsWide = BuiltinOp == Builtin::BIwcscmp ||
14591 BuiltinOp == Builtin::BIwcsncmp ||
14592 BuiltinOp == Builtin::BIwmemcmp ||
14593 BuiltinOp == Builtin::BI__builtin_wcscmp ||
14594 BuiltinOp == Builtin::BI__builtin_wcsncmp ||
14595 BuiltinOp == Builtin::BI__builtin_wmemcmp;
14597 for (; MaxLength; --MaxLength) {
14599 if (!ReadCurElems(Char1, Char2))
14607 if (StopAtNull && !Char1.
getInt())
14609 assert(!(StopAtNull && !Char2.
getInt()));
14610 if (!AdvanceElems())
14617 case Builtin::BI__atomic_always_lock_free:
14618 case Builtin::BI__atomic_is_lock_free:
14619 case Builtin::BI__c11_atomic_is_lock_free: {
14635 if (
Size.isPowerOfTwo()) {
14637 unsigned InlineWidthBits =
14640 if (BuiltinOp == Builtin::BI__c11_atomic_is_lock_free ||
14646 const Expr *PtrArg = E->
getArg(1);
14652 IntResult.isAligned(
Size.getAsAlign()))
14656 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(PtrArg)) {
14659 if (ICE->getCastKind() == CK_BitCast)
14660 PtrArg = ICE->getSubExpr();
14663 if (
auto PtrTy = PtrArg->
getType()->
getAs<PointerType>()) {
14674 return BuiltinOp == Builtin::BI__atomic_always_lock_free ?
14677 case Builtin::BI__builtin_addcb:
14678 case Builtin::BI__builtin_addcs:
14679 case Builtin::BI__builtin_addc:
14680 case Builtin::BI__builtin_addcl:
14681 case Builtin::BI__builtin_addcll:
14682 case Builtin::BI__builtin_subcb:
14683 case Builtin::BI__builtin_subcs:
14684 case Builtin::BI__builtin_subc:
14685 case Builtin::BI__builtin_subcl:
14686 case Builtin::BI__builtin_subcll: {
14687 LValue CarryOutLValue;
14699 bool FirstOverflowed =
false;
14700 bool SecondOverflowed =
false;
14701 switch (BuiltinOp) {
14703 llvm_unreachable(
"Invalid value for BuiltinOp");
14704 case Builtin::BI__builtin_addcb:
14705 case Builtin::BI__builtin_addcs:
14706 case Builtin::BI__builtin_addc:
14707 case Builtin::BI__builtin_addcl:
14708 case Builtin::BI__builtin_addcll:
14710 LHS.uadd_ov(RHS, FirstOverflowed).uadd_ov(CarryIn, SecondOverflowed);
14712 case Builtin::BI__builtin_subcb:
14713 case Builtin::BI__builtin_subcs:
14714 case Builtin::BI__builtin_subc:
14715 case Builtin::BI__builtin_subcl:
14716 case Builtin::BI__builtin_subcll:
14718 LHS.usub_ov(RHS, FirstOverflowed).usub_ov(CarryIn, SecondOverflowed);
14724 CarryOut = (
uint64_t)(FirstOverflowed | SecondOverflowed);
14730 case Builtin::BI__builtin_add_overflow:
14731 case Builtin::BI__builtin_sub_overflow:
14732 case Builtin::BI__builtin_mul_overflow:
14733 case Builtin::BI__builtin_sadd_overflow:
14734 case Builtin::BI__builtin_uadd_overflow:
14735 case Builtin::BI__builtin_uaddl_overflow:
14736 case Builtin::BI__builtin_uaddll_overflow:
14737 case Builtin::BI__builtin_usub_overflow:
14738 case Builtin::BI__builtin_usubl_overflow:
14739 case Builtin::BI__builtin_usubll_overflow:
14740 case Builtin::BI__builtin_umul_overflow:
14741 case Builtin::BI__builtin_umull_overflow:
14742 case Builtin::BI__builtin_umulll_overflow:
14743 case Builtin::BI__builtin_saddl_overflow:
14744 case Builtin::BI__builtin_saddll_overflow:
14745 case Builtin::BI__builtin_ssub_overflow:
14746 case Builtin::BI__builtin_ssubl_overflow:
14747 case Builtin::BI__builtin_ssubll_overflow:
14748 case Builtin::BI__builtin_smul_overflow:
14749 case Builtin::BI__builtin_smull_overflow:
14750 case Builtin::BI__builtin_smulll_overflow: {
14751 LValue ResultLValue;
14761 bool DidOverflow =
false;
14764 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
14765 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
14766 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
14767 bool IsSigned = LHS.isSigned() || RHS.isSigned() ||
14769 bool AllSigned = LHS.isSigned() && RHS.isSigned() &&
14771 uint64_t LHSSize = LHS.getBitWidth();
14772 uint64_t RHSSize = RHS.getBitWidth();
14774 uint64_t MaxBits = std::max(std::max(LHSSize, RHSSize), ResultSize);
14780 if (IsSigned && !AllSigned)
14783 LHS =
APSInt(LHS.extOrTrunc(MaxBits), !IsSigned);
14784 RHS =
APSInt(RHS.extOrTrunc(MaxBits), !IsSigned);
14789 switch (BuiltinOp) {
14791 llvm_unreachable(
"Invalid value for BuiltinOp");
14792 case Builtin::BI__builtin_add_overflow:
14793 case Builtin::BI__builtin_sadd_overflow:
14794 case Builtin::BI__builtin_saddl_overflow:
14795 case Builtin::BI__builtin_saddll_overflow:
14796 case Builtin::BI__builtin_uadd_overflow:
14797 case Builtin::BI__builtin_uaddl_overflow:
14798 case Builtin::BI__builtin_uaddll_overflow:
14799 Result = LHS.isSigned() ? LHS.sadd_ov(RHS, DidOverflow)
14800 : LHS.uadd_ov(RHS, DidOverflow);
14802 case Builtin::BI__builtin_sub_overflow:
14803 case Builtin::BI__builtin_ssub_overflow:
14804 case Builtin::BI__builtin_ssubl_overflow:
14805 case Builtin::BI__builtin_ssubll_overflow:
14806 case Builtin::BI__builtin_usub_overflow:
14807 case Builtin::BI__builtin_usubl_overflow:
14808 case Builtin::BI__builtin_usubll_overflow:
14809 Result = LHS.isSigned() ? LHS.ssub_ov(RHS, DidOverflow)
14810 : LHS.usub_ov(RHS, DidOverflow);
14812 case Builtin::BI__builtin_mul_overflow:
14813 case Builtin::BI__builtin_smul_overflow:
14814 case Builtin::BI__builtin_smull_overflow:
14815 case Builtin::BI__builtin_smulll_overflow:
14816 case Builtin::BI__builtin_umul_overflow:
14817 case Builtin::BI__builtin_umull_overflow:
14818 case Builtin::BI__builtin_umulll_overflow:
14819 Result = LHS.isSigned() ? LHS.smul_ov(RHS, DidOverflow)
14820 : LHS.umul_ov(RHS, DidOverflow);
14826 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
14827 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
14828 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
14837 if (!APSInt::isSameValue(Temp,
Result))
14838 DidOverflow =
true;
14845 return Success(DidOverflow, E);
14848 case Builtin::BI__builtin_reduce_add:
14849 case Builtin::BI__builtin_reduce_mul:
14850 case Builtin::BI__builtin_reduce_and:
14851 case Builtin::BI__builtin_reduce_or:
14852 case Builtin::BI__builtin_reduce_xor:
14853 case Builtin::BI__builtin_reduce_min:
14854 case Builtin::BI__builtin_reduce_max: {
14861 for (
unsigned EltNum = 1; EltNum < SourceLen; ++EltNum) {
14862 switch (BuiltinOp) {
14865 case Builtin::BI__builtin_reduce_add: {
14868 Reduced.getBitWidth() + 1, std::plus<APSInt>(), Reduced))
14872 case Builtin::BI__builtin_reduce_mul: {
14875 Reduced.getBitWidth() * 2, std::multiplies<APSInt>(), Reduced))
14879 case Builtin::BI__builtin_reduce_and: {
14883 case Builtin::BI__builtin_reduce_or: {
14887 case Builtin::BI__builtin_reduce_xor: {
14891 case Builtin::BI__builtin_reduce_min: {
14895 case Builtin::BI__builtin_reduce_max: {
14905 case clang::X86::BI__builtin_ia32_addcarryx_u32:
14906 case clang::X86::BI__builtin_ia32_addcarryx_u64:
14907 case clang::X86::BI__builtin_ia32_subborrow_u32:
14908 case clang::X86::BI__builtin_ia32_subborrow_u64: {
14909 LValue ResultLValue;
14910 APSInt CarryIn, LHS, RHS;
14918 bool IsAdd = BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u32 ||
14919 BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u64;
14921 unsigned BitWidth = LHS.getBitWidth();
14922 unsigned CarryInBit = CarryIn.ugt(0) ? 1 : 0;
14925 ? (LHS.zext(BitWidth + 1) + (RHS.zext(BitWidth + 1) + CarryInBit))
14926 : (LHS.zext(BitWidth + 1) - (RHS.zext(BitWidth + 1) + CarryInBit));
14928 APInt Result = ExResult.extractBits(BitWidth, 0);
14929 uint64_t CarryOut = ExResult.extractBitsAsZExtValue(1, BitWidth);
14937 case clang::X86::BI__builtin_ia32_bextr_u32:
14938 case clang::X86::BI__builtin_ia32_bextr_u64:
14939 case clang::X86::BI__builtin_ia32_bextri_u32:
14940 case clang::X86::BI__builtin_ia32_bextri_u64: {
14946 unsigned BitWidth = Val.getBitWidth();
14948 uint64_t Length = Idx.extractBitsAsZExtValue(8, 8);
14949 Length = Length > BitWidth ? BitWidth : Length;
14952 if (Length == 0 || Shift >= BitWidth)
14956 Result &= llvm::maskTrailingOnes<uint64_t>(Length);
14960 case clang::X86::BI__builtin_ia32_bzhi_si:
14961 case clang::X86::BI__builtin_ia32_bzhi_di: {
14967 unsigned BitWidth = Val.getBitWidth();
14968 unsigned Index = Idx.extractBitsAsZExtValue(8, 0);
14969 if (Index < BitWidth)
14970 Val.clearHighBits(BitWidth - Index);
14974 case clang::X86::BI__builtin_ia32_lzcnt_u16:
14975 case clang::X86::BI__builtin_ia32_lzcnt_u32:
14976 case clang::X86::BI__builtin_ia32_lzcnt_u64: {
14980 return Success(Val.countLeadingZeros(), E);
14983 case clang::X86::BI__builtin_ia32_tzcnt_u16:
14984 case clang::X86::BI__builtin_ia32_tzcnt_u32:
14985 case clang::X86::BI__builtin_ia32_tzcnt_u64: {
14989 return Success(Val.countTrailingZeros(), E);
14992 case clang::X86::BI__builtin_ia32_pdep_si:
14993 case clang::X86::BI__builtin_ia32_pdep_di: {
14999 unsigned BitWidth = Val.getBitWidth();
15001 for (
unsigned I = 0, P = 0; I != BitWidth; ++I)
15003 Result.setBitVal(I, Val[P++]);
15007 case clang::X86::BI__builtin_ia32_pext_si:
15008 case clang::X86::BI__builtin_ia32_pext_di: {
15014 unsigned BitWidth = Val.getBitWidth();
15016 for (
unsigned I = 0, P = 0; I != BitWidth; ++I)
15018 Result.setBitVal(P++, Val[I]);
15022 case X86::BI__builtin_ia32_kandqi:
15023 case X86::BI__builtin_ia32_kandhi:
15024 case X86::BI__builtin_ia32_kandsi:
15025 case X86::BI__builtin_ia32_kanddi: {
15026 return HandleMaskBinOp(
15027 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS & RHS; });
15030 case X86::BI__builtin_ia32_kandnqi:
15031 case X86::BI__builtin_ia32_kandnhi:
15032 case X86::BI__builtin_ia32_kandnsi:
15033 case X86::BI__builtin_ia32_kandndi: {
15034 return HandleMaskBinOp(
15035 [](
const APSInt &LHS,
const APSInt &RHS) {
return ~LHS & RHS; });
15038 case X86::BI__builtin_ia32_korqi:
15039 case X86::BI__builtin_ia32_korhi:
15040 case X86::BI__builtin_ia32_korsi:
15041 case X86::BI__builtin_ia32_kordi: {
15042 return HandleMaskBinOp(
15043 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS | RHS; });
15046 case X86::BI__builtin_ia32_kxnorqi:
15047 case X86::BI__builtin_ia32_kxnorhi:
15048 case X86::BI__builtin_ia32_kxnorsi:
15049 case X86::BI__builtin_ia32_kxnordi: {
15050 return HandleMaskBinOp(
15051 [](
const APSInt &LHS,
const APSInt &RHS) {
return ~(LHS ^ RHS); });
15054 case X86::BI__builtin_ia32_kxorqi:
15055 case X86::BI__builtin_ia32_kxorhi:
15056 case X86::BI__builtin_ia32_kxorsi:
15057 case X86::BI__builtin_ia32_kxordi: {
15058 return HandleMaskBinOp(
15059 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS ^ RHS; });
15062 case X86::BI__builtin_ia32_knotqi:
15063 case X86::BI__builtin_ia32_knothi:
15064 case X86::BI__builtin_ia32_knotsi:
15065 case X86::BI__builtin_ia32_knotdi: {
15073 case X86::BI__builtin_ia32_kaddqi:
15074 case X86::BI__builtin_ia32_kaddhi:
15075 case X86::BI__builtin_ia32_kaddsi:
15076 case X86::BI__builtin_ia32_kadddi: {
15077 return HandleMaskBinOp(
15078 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS + RHS; });
15081 case clang::X86::BI__builtin_ia32_vec_ext_v4hi:
15082 case clang::X86::BI__builtin_ia32_vec_ext_v16qi:
15083 case clang::X86::BI__builtin_ia32_vec_ext_v8hi:
15084 case clang::X86::BI__builtin_ia32_vec_ext_v4si:
15085 case clang::X86::BI__builtin_ia32_vec_ext_v2di:
15086 case clang::X86::BI__builtin_ia32_vec_ext_v32qi:
15087 case clang::X86::BI__builtin_ia32_vec_ext_v16hi:
15088 case clang::X86::BI__builtin_ia32_vec_ext_v8si:
15089 case clang::X86::BI__builtin_ia32_vec_ext_v4di: {
15096 unsigned Idx =
static_cast<unsigned>(IdxAPS.getZExtValue() & (N - 1));
15105 const LValue &LV) {
15108 if (!LV.getLValueBase())
15113 if (!LV.getLValueDesignator().Invalid &&
15114 !LV.getLValueDesignator().isOnePastTheEnd())
15124 if (LV.getLValueDesignator().Invalid)
15130 return LV.getLValueOffset() == Size;
15140class DataRecursiveIntBinOpEvaluator {
15141 struct EvalResult {
15143 bool Failed =
false;
15145 EvalResult() =
default;
15147 void swap(EvalResult &RHS) {
15149 Failed = RHS.Failed;
15150 RHS.Failed =
false;
15156 EvalResult LHSResult;
15157 enum { AnyExprKind, BinOpKind, BinOpVisitedLHSKind }
Kind;
15160 Job(Job &&) =
default;
15162 void startSpeculativeEval(EvalInfo &Info) {
15163 SpecEvalRAII = SpeculativeEvaluationRAII(Info);
15167 SpeculativeEvaluationRAII SpecEvalRAII;
15170 SmallVector<Job, 16> Queue;
15172 IntExprEvaluator &IntEval;
15177 DataRecursiveIntBinOpEvaluator(IntExprEvaluator &IntEval,
APValue &
Result)
15178 : IntEval(IntEval), Info(IntEval.getEvalInfo()), FinalResult(
Result) { }
15184 static bool shouldEnqueue(
const BinaryOperator *E) {
15191 bool Traverse(
const BinaryOperator *E) {
15193 EvalResult PrevResult;
15194 while (!Queue.empty())
15195 process(PrevResult);
15197 if (PrevResult.Failed)
return false;
15199 FinalResult.
swap(PrevResult.Val);
15210 bool Error(
const Expr *E) {
15211 return IntEval.Error(E);
15214 return IntEval.Error(E, D);
15217 OptionalDiagnostic CCEDiag(
const Expr *E,
diag::kind D) {
15218 return Info.CCEDiag(E, D);
15222 bool VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
15223 bool &SuppressRHSDiags);
15225 bool VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
15228 void EvaluateExpr(
const Expr *E, EvalResult &
Result) {
15234 void process(EvalResult &
Result);
15236 void enqueue(
const Expr *E) {
15238 Queue.resize(Queue.size()+1);
15239 Queue.back().E = E;
15240 Queue.back().Kind = Job::AnyExprKind;
15246bool DataRecursiveIntBinOpEvaluator::
15247 VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
15248 bool &SuppressRHSDiags) {
15251 if (LHSResult.Failed)
15252 return Info.noteSideEffect();
15261 if (LHSAsBool == (E->
getOpcode() == BO_LOr)) {
15262 Success(LHSAsBool, E, LHSResult.Val);
15266 LHSResult.Failed =
true;
15270 if (!Info.noteSideEffect())
15276 SuppressRHSDiags =
true;
15285 if (LHSResult.Failed && !Info.noteFailure())
15296 assert(!LVal.
hasLValuePath() &&
"have designator for integer lvalue");
15298 uint64_t Offset64 = Offset.getQuantity();
15299 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
15301 : Offset64 + Index64);
15304bool DataRecursiveIntBinOpEvaluator::
15305 VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
15308 if (RHSResult.Failed)
15315 bool lhsResult, rhsResult;
15330 if (rhsResult == (E->
getOpcode() == BO_LOr))
15341 if (LHSResult.Failed || RHSResult.Failed)
15344 const APValue &LHSVal = LHSResult.Val;
15345 const APValue &RHSVal = RHSResult.Val;
15369 if (!LHSExpr || !RHSExpr)
15371 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
15372 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
15373 if (!LHSAddrExpr || !RHSAddrExpr)
15398void DataRecursiveIntBinOpEvaluator::process(EvalResult &
Result) {
15399 Job &job = Queue.back();
15401 switch (job.Kind) {
15402 case Job::AnyExprKind: {
15403 if (
const BinaryOperator *Bop = dyn_cast<BinaryOperator>(job.E)) {
15404 if (shouldEnqueue(Bop)) {
15405 job.Kind = Job::BinOpKind;
15406 enqueue(Bop->getLHS());
15411 EvaluateExpr(job.E,
Result);
15416 case Job::BinOpKind: {
15418 bool SuppressRHSDiags =
false;
15419 if (!VisitBinOpLHSOnly(
Result, Bop, SuppressRHSDiags)) {
15423 if (SuppressRHSDiags)
15424 job.startSpeculativeEval(Info);
15425 job.LHSResult.swap(
Result);
15426 job.Kind = Job::BinOpVisitedLHSKind;
15431 case Job::BinOpVisitedLHSKind: {
15435 Result.Failed = !VisitBinOp(job.LHSResult, RHS, Bop,
Result.Val);
15441 llvm_unreachable(
"Invalid Job::Kind!");
15445enum class CmpResult {
15454template <
class SuccessCB,
class AfterCB>
15457 SuccessCB &&
Success, AfterCB &&DoAfter) {
15462 "unsupported binary expression evaluation");
15464 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
15478 if (!LHSOK && !Info.noteFailure())
15483 return Success(CmpResult::Less, E);
15485 return Success(CmpResult::Greater, E);
15486 return Success(CmpResult::Equal, E);
15494 if (!LHSOK && !Info.noteFailure())
15499 return Success(CmpResult::Less, E);
15501 return Success(CmpResult::Greater, E);
15502 return Success(CmpResult::Equal, E);
15506 ComplexValue LHS, RHS;
15515 LHS.makeComplexFloat();
15516 LHS.FloatImag = APFloat(LHS.FloatReal.getSemantics());
15521 if (!LHSOK && !Info.noteFailure())
15527 RHS.makeComplexFloat();
15528 RHS.FloatImag = APFloat(RHS.FloatReal.getSemantics());
15532 if (LHS.isComplexFloat()) {
15533 APFloat::cmpResult CR_r =
15534 LHS.getComplexFloatReal().compare(RHS.getComplexFloatReal());
15535 APFloat::cmpResult CR_i =
15536 LHS.getComplexFloatImag().compare(RHS.getComplexFloatImag());
15537 bool IsEqual = CR_r == APFloat::cmpEqual && CR_i == APFloat::cmpEqual;
15538 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal, E);
15540 assert(IsEquality &&
"invalid complex comparison");
15541 bool IsEqual = LHS.getComplexIntReal() == RHS.getComplexIntReal() &&
15542 LHS.getComplexIntImag() == RHS.getComplexIntImag();
15543 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal, E);
15549 APFloat RHS(0.0), LHS(0.0);
15552 if (!LHSOK && !Info.noteFailure())
15559 llvm::APFloatBase::cmpResult APFloatCmpResult = LHS.compare(RHS);
15560 if (!Info.InConstantContext &&
15561 APFloatCmpResult == APFloat::cmpUnordered &&
15564 Info.FFDiag(E, diag::note_constexpr_float_arithmetic_strict);
15567 auto GetCmpRes = [&]() {
15568 switch (APFloatCmpResult) {
15569 case APFloat::cmpEqual:
15570 return CmpResult::Equal;
15571 case APFloat::cmpLessThan:
15572 return CmpResult::Less;
15573 case APFloat::cmpGreaterThan:
15574 return CmpResult::Greater;
15575 case APFloat::cmpUnordered:
15576 return CmpResult::Unordered;
15578 llvm_unreachable(
"Unrecognised APFloat::cmpResult enum");
15580 return Success(GetCmpRes(), E);
15584 LValue LHSValue, RHSValue;
15587 if (!LHSOK && !Info.noteFailure())
15598 if (Info.checkingPotentialConstantExpression() &&
15599 (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown))
15601 auto DiagComparison = [&] (
unsigned DiagID,
bool Reversed =
false) {
15602 std::string LHS = LHSValue.toString(Info.Ctx, E->
getLHS()->
getType());
15603 std::string RHS = RHSValue.toString(Info.Ctx, E->
getRHS()->
getType());
15604 Info.FFDiag(E, DiagID)
15611 return DiagComparison(
15612 diag::note_constexpr_pointer_comparison_unspecified);
15618 if ((!LHSValue.Base && !LHSValue.Offset.
isZero()) ||
15619 (!RHSValue.Base && !RHSValue.Offset.
isZero()))
15620 return DiagComparison(diag::note_constexpr_pointer_constant_comparison,
15634 return DiagComparison(diag::note_constexpr_literal_comparison);
15636 return DiagComparison(diag::note_constexpr_opaque_call_comparison,
15641 return DiagComparison(diag::note_constexpr_pointer_weak_comparison,
15645 if (LHSValue.Base && LHSValue.Offset.
isZero() &&
15647 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
15649 if (RHSValue.Base && RHSValue.Offset.
isZero() &&
15651 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
15657 return DiagComparison(
15658 diag::note_constexpr_pointer_comparison_zero_sized);
15659 if (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown)
15660 return DiagComparison(
15661 diag::note_constexpr_pointer_comparison_unspecified);
15663 return Success(CmpResult::Unequal, E);
15666 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
15667 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
15669 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
15670 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
15680 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid && IsRelational) {
15681 bool WasArrayIndex;
15684 :
getType(LHSValue.Base).getNonReferenceType(),
15685 LHSDesignator, RHSDesignator, WasArrayIndex);
15692 if (!WasArrayIndex && Mismatch < LHSDesignator.Entries.size() &&
15693 Mismatch < RHSDesignator.Entries.size()) {
15694 const FieldDecl *LF = getAsField(LHSDesignator.Entries[Mismatch]);
15695 const FieldDecl *RF = getAsField(RHSDesignator.Entries[Mismatch]);
15697 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_classes);
15699 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
15700 << getAsBaseClass(LHSDesignator.Entries[Mismatch])
15703 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
15704 << getAsBaseClass(RHSDesignator.Entries[Mismatch])
15709 diag::note_constexpr_pointer_comparison_differing_access)
15720 assert(PtrSize <= 64 &&
"Unexpected pointer width");
15721 uint64_t Mask = ~0ULL >> (64 - PtrSize);
15722 CompareLHS &= Mask;
15723 CompareRHS &= Mask;
15728 if (!LHSValue.Base.
isNull() && IsRelational) {
15733 uint64_t OffsetLimit = Size.getQuantity();
15734 if (CompareLHS > OffsetLimit || CompareRHS > OffsetLimit)
15738 if (CompareLHS < CompareRHS)
15739 return Success(CmpResult::Less, E);
15740 if (CompareLHS > CompareRHS)
15741 return Success(CmpResult::Greater, E);
15742 return Success(CmpResult::Equal, E);
15746 assert(IsEquality &&
"unexpected member pointer operation");
15749 MemberPtr LHSValue, RHSValue;
15752 if (!LHSOK && !Info.noteFailure())
15760 if (LHSValue.getDecl() && LHSValue.getDecl()->isWeak()) {
15761 Info.FFDiag(E, diag::note_constexpr_mem_pointer_weak_comparison)
15762 << LHSValue.getDecl();
15765 if (RHSValue.getDecl() && RHSValue.getDecl()->isWeak()) {
15766 Info.FFDiag(E, diag::note_constexpr_mem_pointer_weak_comparison)
15767 << RHSValue.getDecl();
15774 if (!LHSValue.getDecl() || !RHSValue.getDecl()) {
15775 bool Equal = !LHSValue.getDecl() && !RHSValue.getDecl();
15776 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal, E);
15781 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(LHSValue.getDecl()))
15782 if (MD->isVirtual())
15783 Info.CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
15784 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(RHSValue.getDecl()))
15785 if (MD->isVirtual())
15786 Info.CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
15792 bool Equal = LHSValue == RHSValue;
15793 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal, E);
15798 assert(RHSTy->
isNullPtrType() &&
"missing pointer conversion");
15806 return Success(CmpResult::Equal, E);
15812bool RecordExprEvaluator::VisitBinCmp(
const BinaryOperator *E) {
15816 auto OnSuccess = [&](CmpResult CR,
const BinaryOperator *E) {
15819 case CmpResult::Unequal:
15820 llvm_unreachable(
"should never produce Unequal for three-way comparison");
15821 case CmpResult::Less:
15822 CCR = ComparisonCategoryResult::Less;
15824 case CmpResult::Equal:
15825 CCR = ComparisonCategoryResult::Equal;
15827 case CmpResult::Greater:
15828 CCR = ComparisonCategoryResult::Greater;
15830 case CmpResult::Unordered:
15831 CCR = ComparisonCategoryResult::Unordered;
15836 const ComparisonCategoryInfo &CmpInfo =
15845 ConstantExprKind::Normal);
15848 return ExprEvaluatorBaseTy::VisitBinCmp(E);
15852bool RecordExprEvaluator::VisitCXXParenListInitExpr(
15853 const CXXParenListInitExpr *E) {
15854 return VisitCXXParenListOrInitListExpr(E, E->
getInitExprs());
15857bool IntExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
15862 if (!Info.noteFailure())
15866 if (DataRecursiveIntBinOpEvaluator::shouldEnqueue(E))
15867 return DataRecursiveIntBinOpEvaluator(*
this,
Result).Traverse(E);
15871 "DataRecursiveIntBinOpEvaluator should have handled integral types");
15876 auto OnSuccess = [&](CmpResult CR,
const BinaryOperator *E) {
15877 assert((CR != CmpResult::Unequal || E->
isEqualityOp()) &&
15878 "should only produce Unequal for equality comparisons");
15879 bool IsEqual = CR == CmpResult::Equal,
15880 IsLess = CR == CmpResult::Less,
15881 IsGreater = CR == CmpResult::Greater;
15885 llvm_unreachable(
"unsupported binary operator");
15888 return Success(IsEqual == (Op == BO_EQ), E);
15892 return Success(IsGreater, E);
15894 return Success(IsEqual || IsLess, E);
15896 return Success(IsEqual || IsGreater, E);
15900 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
15909 LValue LHSValue, RHSValue;
15912 if (!LHSOK && !Info.noteFailure())
15921 if (Info.checkingPotentialConstantExpression() &&
15922 (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown))
15925 const Expr *LHSExpr = LHSValue.Base.
dyn_cast<
const Expr *>();
15926 const Expr *RHSExpr = RHSValue.Base.
dyn_cast<
const Expr *>();
15928 auto DiagArith = [&](
unsigned DiagID) {
15929 std::string LHS = LHSValue.toString(Info.Ctx, E->
getLHS()->
getType());
15930 std::string RHS = RHSValue.toString(Info.Ctx, E->
getRHS()->
getType());
15931 Info.FFDiag(E, DiagID) << LHS << RHS;
15932 if (LHSExpr && LHSExpr == RHSExpr)
15934 diag::note_constexpr_repeated_literal_eval)
15939 if (!LHSExpr || !RHSExpr)
15940 return DiagArith(diag::note_constexpr_pointer_arith_unspecified);
15943 return DiagArith(diag::note_constexpr_literal_arith);
15945 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
15946 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
15947 if (!LHSAddrExpr || !RHSAddrExpr)
15955 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
15956 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
15958 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
15959 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
15965 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid &&
15968 Info.CCEDiag(E, diag::note_constexpr_pointer_subtraction_not_same_array);
15973 CharUnits ElementSize;
15980 if (ElementSize.
isZero()) {
15981 Info.FFDiag(E, diag::note_constexpr_pointer_subtraction_zero_size)
15998 APSInt TrueResult = (LHS - RHS) / ElemSize;
16001 if (
Result.extend(65) != TrueResult &&
16007 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
16012bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr(
16013 const UnaryExprOrTypeTraitExpr *E) {
16015 case UETT_PreferredAlignOf:
16016 case UETT_AlignOf: {
16025 case UETT_PtrAuthTypeDiscriminator: {
16031 case UETT_VecStep: {
16035 unsigned n = Ty->
castAs<VectorType>()->getNumElements();
16047 case UETT_DataSizeOf:
16048 case UETT_SizeOf: {
16052 if (
const ReferenceType *Ref = SrcTy->
getAs<ReferenceType>())
16063 case UETT_OpenMPRequiredSimdAlign:
16070 case UETT_VectorElements: {
16074 if (
const auto *VT = Ty->
getAs<VectorType>())
16078 if (Info.InConstantContext)
16079 Info.CCEDiag(E, diag::note_constexpr_non_const_vectorelements)
16084 case UETT_CountOf: {
16090 if (
const auto *CAT =
16102 if (VAT->getElementType()->isArrayType()) {
16105 if (!VAT->getSizeExpr()) {
16110 std::optional<APSInt> Res =
16111 VAT->getSizeExpr()->getIntegerConstantExpr(Info.Ctx);
16117 Res->getZExtValue()};
16129 llvm_unreachable(
"unknown expr/type trait");
16132bool IntExprEvaluator::VisitOffsetOfExpr(
const OffsetOfExpr *OOE) {
16138 for (
unsigned i = 0; i != n; ++i) {
16151 Result += IdxResult.getSExtValue() * ElementSize;
16156 FieldDecl *MemberDecl = ON.
getField();
16163 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
16170 llvm_unreachable(
"dependent __builtin_offsetof");
16173 CXXBaseSpecifier *BaseSpec = ON.
getBase();
16185 CurrentType = BaseSpec->
getType();
16199bool IntExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
16218 if (Info.checkingForUndefinedBehavior())
16220 diag::warn_integer_constant_overflow)
16248bool IntExprEvaluator::VisitCastExpr(
const CastExpr *E) {
16250 QualType DestType = E->
getType();
16251 QualType SrcType = SubExpr->
getType();
16254 case CK_BaseToDerived:
16255 case CK_DerivedToBase:
16256 case CK_UncheckedDerivedToBase:
16259 case CK_ArrayToPointerDecay:
16260 case CK_FunctionToPointerDecay:
16261 case CK_NullToPointer:
16262 case CK_NullToMemberPointer:
16263 case CK_BaseToDerivedMemberPointer:
16264 case CK_DerivedToBaseMemberPointer:
16265 case CK_ReinterpretMemberPointer:
16266 case CK_ConstructorConversion:
16267 case CK_IntegralToPointer:
16269 case CK_VectorSplat:
16270 case CK_IntegralToFloating:
16271 case CK_FloatingCast:
16272 case CK_CPointerToObjCPointerCast:
16273 case CK_BlockPointerToObjCPointerCast:
16274 case CK_AnyPointerToBlockPointerCast:
16275 case CK_ObjCObjectLValueCast:
16276 case CK_FloatingRealToComplex:
16277 case CK_FloatingComplexToReal:
16278 case CK_FloatingComplexCast:
16279 case CK_FloatingComplexToIntegralComplex:
16280 case CK_IntegralRealToComplex:
16281 case CK_IntegralComplexCast:
16282 case CK_IntegralComplexToFloatingComplex:
16283 case CK_BuiltinFnToFnPtr:
16284 case CK_ZeroToOCLOpaqueType:
16285 case CK_NonAtomicToAtomic:
16286 case CK_AddressSpaceConversion:
16287 case CK_IntToOCLSampler:
16288 case CK_FloatingToFixedPoint:
16289 case CK_FixedPointToFloating:
16290 case CK_FixedPointCast:
16291 case CK_IntegralToFixedPoint:
16292 case CK_MatrixCast:
16293 case CK_HLSLAggregateSplatCast:
16294 llvm_unreachable(
"invalid cast kind for integral value");
16298 case CK_LValueBitCast:
16299 case CK_ARCProduceObject:
16300 case CK_ARCConsumeObject:
16301 case CK_ARCReclaimReturnedObject:
16302 case CK_ARCExtendBlockObject:
16303 case CK_CopyAndAutoreleaseBlockObject:
16306 case CK_UserDefinedConversion:
16307 case CK_LValueToRValue:
16308 case CK_AtomicToNonAtomic:
16310 case CK_LValueToRValueBitCast:
16311 case CK_HLSLArrayRValue:
16312 case CK_HLSLElementwiseCast:
16313 return ExprEvaluatorBaseTy::VisitCastExpr(E);
16315 case CK_MemberPointerToBoolean:
16316 case CK_PointerToBoolean:
16317 case CK_IntegralToBoolean:
16318 case CK_FloatingToBoolean:
16319 case CK_BooleanToSignedIntegral:
16320 case CK_FloatingComplexToBoolean:
16321 case CK_IntegralComplexToBoolean: {
16326 if (BoolResult && E->
getCastKind() == CK_BooleanToSignedIntegral)
16328 return Success(IntResult, E);
16331 case CK_FixedPointToIntegral: {
16336 llvm::APSInt
Result = Src.convertToInt(
16344 case CK_FixedPointToBoolean: {
16347 if (!
Evaluate(Val, Info, SubExpr))
16352 case CK_IntegralCast: {
16353 if (!Visit(SubExpr))
16362 if (
Result.isAddrLabelDiff())
16380 if (!ED->isFixed()) {
16384 ED->getValueRange(
Max,
Min);
16387 if (ED->getNumNegativeBits() &&
16388 (
Max.slt(
Result.getInt().getSExtValue()) ||
16389 Min.sgt(
Result.getInt().getSExtValue())))
16390 Info.CCEDiag(E, diag::note_constexpr_unscoped_enum_out_of_range)
16391 << llvm::toString(
Result.getInt(), 10) <<
Min.getSExtValue()
16392 <<
Max.getSExtValue() << ED;
16393 else if (!ED->getNumNegativeBits() &&
16394 Max.ult(
Result.getInt().getZExtValue()))
16395 Info.CCEDiag(E, diag::note_constexpr_unscoped_enum_out_of_range)
16396 << llvm::toString(
Result.getInt(), 10) <<
Min.getZExtValue()
16397 <<
Max.getZExtValue() << ED;
16405 case CK_PointerToIntegral: {
16406 CCEDiag(E, diag::note_constexpr_invalid_cast)
16407 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
16414 if (LV.getLValueBase()) {
16422 LV.Designator.setInvalid();
16430 if (!
V.toIntegralConstant(AsInt, SrcType, Info.Ctx))
16431 llvm_unreachable(
"Can't cast this!");
16436 case CK_IntegralComplexToReal: {
16440 return Success(
C.getComplexIntReal(), E);
16443 case CK_FloatingToIntegral: {
16453 case CK_HLSLVectorTruncation: {
16461 llvm_unreachable(
"unknown cast resulting in integral value");
16464bool IntExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
16469 if (!LV.isComplexInt())
16471 return Success(LV.getComplexIntReal(), E);
16477bool IntExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
16482 if (!LV.isComplexInt())
16484 return Success(LV.getComplexIntImag(), E);
16491bool IntExprEvaluator::VisitSizeOfPackExpr(
const SizeOfPackExpr *E) {
16495bool IntExprEvaluator::VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E) {
16499bool IntExprEvaluator::VisitConceptSpecializationExpr(
16500 const ConceptSpecializationExpr *E) {
16504bool IntExprEvaluator::VisitRequiresExpr(
const RequiresExpr *E) {
16508bool FixedPointExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
16518 if (!
Result.isFixedPoint())
16521 APFixedPoint Negated =
Result.getFixedPoint().negate(&Overflowed);
16535bool FixedPointExprEvaluator::VisitCastExpr(
const CastExpr *E) {
16537 QualType DestType = E->
getType();
16539 "Expected destination type to be a fixed point type");
16543 case CK_FixedPointCast: {
16548 APFixedPoint
Result = Src.convert(DestFXSema, &Overflowed);
16550 if (Info.checkingForUndefinedBehavior())
16552 diag::warn_fixedpoint_constant_overflow)
16559 case CK_IntegralToFixedPoint: {
16565 APFixedPoint IntResult = APFixedPoint::getFromIntValue(
16569 if (Info.checkingForUndefinedBehavior())
16571 diag::warn_fixedpoint_constant_overflow)
16572 << IntResult.toString() << E->
getType();
16577 return Success(IntResult, E);
16579 case CK_FloatingToFixedPoint: {
16585 APFixedPoint
Result = APFixedPoint::getFromFloatValue(
16589 if (Info.checkingForUndefinedBehavior())
16591 diag::warn_fixedpoint_constant_overflow)
16600 case CK_LValueToRValue:
16601 return ExprEvaluatorBaseTy::VisitCastExpr(E);
16607bool FixedPointExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
16609 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
16611 const Expr *LHS = E->
getLHS();
16612 const Expr *RHS = E->
getRHS();
16623 bool OpOverflow =
false, ConversionOverflow =
false;
16624 APFixedPoint
Result(LHSFX.getSemantics());
16627 Result = LHSFX.add(RHSFX, &OpOverflow)
16628 .convert(ResultFXSema, &ConversionOverflow);
16632 Result = LHSFX.sub(RHSFX, &OpOverflow)
16633 .convert(ResultFXSema, &ConversionOverflow);
16637 Result = LHSFX.mul(RHSFX, &OpOverflow)
16638 .convert(ResultFXSema, &ConversionOverflow);
16642 if (RHSFX.getValue() == 0) {
16643 Info.FFDiag(E, diag::note_expr_divide_by_zero);
16646 Result = LHSFX.div(RHSFX, &OpOverflow)
16647 .convert(ResultFXSema, &ConversionOverflow);
16653 llvm::APSInt RHSVal = RHSFX.getValue();
16656 LHSSema.getWidth() - (unsigned)LHSSema.hasUnsignedPadding();
16657 unsigned Amt = RHSVal.getLimitedValue(ShiftBW - 1);
16661 if (RHSVal.isNegative())
16662 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHSVal;
16663 else if (Amt != RHSVal)
16664 Info.CCEDiag(E, diag::note_constexpr_large_shift)
16665 << RHSVal << E->
getType() << ShiftBW;
16668 Result = LHSFX.shl(Amt, &OpOverflow);
16670 Result = LHSFX.shr(Amt, &OpOverflow);
16676 if (OpOverflow || ConversionOverflow) {
16677 if (Info.checkingForUndefinedBehavior())
16679 diag::warn_fixedpoint_constant_overflow)
16692class FloatExprEvaluator
16693 :
public ExprEvaluatorBase<FloatExprEvaluator> {
16696 FloatExprEvaluator(EvalInfo &info, APFloat &result)
16697 : ExprEvaluatorBaseTy(info),
Result(result) {}
16704 bool ZeroInitialization(
const Expr *E) {
16709 bool VisitCallExpr(
const CallExpr *E);
16711 bool VisitUnaryOperator(
const UnaryOperator *E);
16712 bool VisitBinaryOperator(
const BinaryOperator *E);
16713 bool VisitFloatingLiteral(
const FloatingLiteral *E);
16714 bool VisitCastExpr(
const CastExpr *E);
16716 bool VisitUnaryReal(
const UnaryOperator *E);
16717 bool VisitUnaryImag(
const UnaryOperator *E);
16726 return FloatExprEvaluator(Info, Result).Visit(E);
16733 llvm::APFloat &Result) {
16735 if (!S)
return false;
16737 const llvm::fltSemantics &Sem = Context.getFloatTypeSemantics(ResultTy);
16743 fill = llvm::APInt(32, 0);
16744 else if (S->
getString().getAsInteger(0, fill))
16747 if (Context.getTargetInfo().isNan2008()) {
16749 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
16751 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
16759 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
16761 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
16767bool FloatExprEvaluator::VisitCallExpr(
const CallExpr *E) {
16768 if (!IsConstantEvaluatedBuiltinCall(E))
16769 return ExprEvaluatorBaseTy::VisitCallExpr(E);
16775 case Builtin::BI__builtin_huge_val:
16776 case Builtin::BI__builtin_huge_valf:
16777 case Builtin::BI__builtin_huge_vall:
16778 case Builtin::BI__builtin_huge_valf16:
16779 case Builtin::BI__builtin_huge_valf128:
16780 case Builtin::BI__builtin_inf:
16781 case Builtin::BI__builtin_inff:
16782 case Builtin::BI__builtin_infl:
16783 case Builtin::BI__builtin_inff16:
16784 case Builtin::BI__builtin_inff128: {
16785 const llvm::fltSemantics &Sem =
16787 Result = llvm::APFloat::getInf(Sem);
16791 case Builtin::BI__builtin_nans:
16792 case Builtin::BI__builtin_nansf:
16793 case Builtin::BI__builtin_nansl:
16794 case Builtin::BI__builtin_nansf16:
16795 case Builtin::BI__builtin_nansf128:
16801 case Builtin::BI__builtin_nan:
16802 case Builtin::BI__builtin_nanf:
16803 case Builtin::BI__builtin_nanl:
16804 case Builtin::BI__builtin_nanf16:
16805 case Builtin::BI__builtin_nanf128:
16813 case Builtin::BI__builtin_elementwise_abs:
16814 case Builtin::BI__builtin_fabs:
16815 case Builtin::BI__builtin_fabsf:
16816 case Builtin::BI__builtin_fabsl:
16817 case Builtin::BI__builtin_fabsf128:
16826 if (
Result.isNegative())
16830 case Builtin::BI__arithmetic_fence:
16837 case Builtin::BI__builtin_copysign:
16838 case Builtin::BI__builtin_copysignf:
16839 case Builtin::BI__builtin_copysignl:
16840 case Builtin::BI__builtin_copysignf128: {
16849 case Builtin::BI__builtin_fmax:
16850 case Builtin::BI__builtin_fmaxf:
16851 case Builtin::BI__builtin_fmaxl:
16852 case Builtin::BI__builtin_fmaxf16:
16853 case Builtin::BI__builtin_fmaxf128: {
16862 case Builtin::BI__builtin_fmin:
16863 case Builtin::BI__builtin_fminf:
16864 case Builtin::BI__builtin_fminl:
16865 case Builtin::BI__builtin_fminf16:
16866 case Builtin::BI__builtin_fminf128: {
16875 case Builtin::BI__builtin_fmaximum_num:
16876 case Builtin::BI__builtin_fmaximum_numf:
16877 case Builtin::BI__builtin_fmaximum_numl:
16878 case Builtin::BI__builtin_fmaximum_numf16:
16879 case Builtin::BI__builtin_fmaximum_numf128: {
16888 case Builtin::BI__builtin_fminimum_num:
16889 case Builtin::BI__builtin_fminimum_numf:
16890 case Builtin::BI__builtin_fminimum_numl:
16891 case Builtin::BI__builtin_fminimum_numf16:
16892 case Builtin::BI__builtin_fminimum_numf128: {
16901 case Builtin::BI__builtin_elementwise_fma: {
16906 APFloat SourceY(0.), SourceZ(0.);
16912 (void)
Result.fusedMultiplyAdd(SourceY, SourceZ, RM);
16916 case clang::X86::BI__builtin_ia32_vec_ext_v4sf: {
16923 unsigned Idx =
static_cast<unsigned>(IdxAPS.getZExtValue() & (N - 1));
16929bool FloatExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
16941bool FloatExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
16952 Result = llvm::APFloat::getZero(Sem);
16956bool FloatExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
16958 default:
return Error(E);
16972bool FloatExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
16974 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
16978 if (!LHSOK && !Info.noteFailure())
16984bool FloatExprEvaluator::VisitFloatingLiteral(
const FloatingLiteral *E) {
16989bool FloatExprEvaluator::VisitCastExpr(
const CastExpr *E) {
16994 return ExprEvaluatorBaseTy::VisitCastExpr(E);
16996 case CK_IntegralToFloating: {
17005 case CK_FixedPointToFloating: {
17014 case CK_FloatingCast: {
17015 if (!Visit(SubExpr))
17021 case CK_FloatingComplexToReal: {
17025 Result =
V.getComplexFloatReal();
17028 case CK_HLSLVectorTruncation: {
17042class ComplexExprEvaluator
17043 :
public ExprEvaluatorBase<ComplexExprEvaluator> {
17047 ComplexExprEvaluator(EvalInfo &info, ComplexValue &
Result)
17055 bool ZeroInitialization(
const Expr *E);
17061 bool VisitImaginaryLiteral(
const ImaginaryLiteral *E);
17062 bool VisitCastExpr(
const CastExpr *E);
17063 bool VisitBinaryOperator(
const BinaryOperator *E);
17064 bool VisitUnaryOperator(
const UnaryOperator *E);
17065 bool VisitInitListExpr(
const InitListExpr *E);
17066 bool VisitCallExpr(
const CallExpr *E);
17074 return ComplexExprEvaluator(Info, Result).Visit(E);
17077bool ComplexExprEvaluator::ZeroInitialization(
const Expr *E) {
17078 QualType ElemTy = E->
getType()->
castAs<ComplexType>()->getElementType();
17080 Result.makeComplexFloat();
17085 Result.makeComplexInt();
17093bool ComplexExprEvaluator::VisitImaginaryLiteral(
const ImaginaryLiteral *E) {
17097 Result.makeComplexFloat();
17106 "Unexpected imaginary literal.");
17108 Result.makeComplexInt();
17113 Result.IntReal =
APSInt(Imag.getBitWidth(), !Imag.isSigned());
17118bool ComplexExprEvaluator::VisitCastExpr(
const CastExpr *E) {
17122 case CK_BaseToDerived:
17123 case CK_DerivedToBase:
17124 case CK_UncheckedDerivedToBase:
17127 case CK_ArrayToPointerDecay:
17128 case CK_FunctionToPointerDecay:
17129 case CK_NullToPointer:
17130 case CK_NullToMemberPointer:
17131 case CK_BaseToDerivedMemberPointer:
17132 case CK_DerivedToBaseMemberPointer:
17133 case CK_MemberPointerToBoolean:
17134 case CK_ReinterpretMemberPointer:
17135 case CK_ConstructorConversion:
17136 case CK_IntegralToPointer:
17137 case CK_PointerToIntegral:
17138 case CK_PointerToBoolean:
17140 case CK_VectorSplat:
17141 case CK_IntegralCast:
17142 case CK_BooleanToSignedIntegral:
17143 case CK_IntegralToBoolean:
17144 case CK_IntegralToFloating:
17145 case CK_FloatingToIntegral:
17146 case CK_FloatingToBoolean:
17147 case CK_FloatingCast:
17148 case CK_CPointerToObjCPointerCast:
17149 case CK_BlockPointerToObjCPointerCast:
17150 case CK_AnyPointerToBlockPointerCast:
17151 case CK_ObjCObjectLValueCast:
17152 case CK_FloatingComplexToReal:
17153 case CK_FloatingComplexToBoolean:
17154 case CK_IntegralComplexToReal:
17155 case CK_IntegralComplexToBoolean:
17156 case CK_ARCProduceObject:
17157 case CK_ARCConsumeObject:
17158 case CK_ARCReclaimReturnedObject:
17159 case CK_ARCExtendBlockObject:
17160 case CK_CopyAndAutoreleaseBlockObject:
17161 case CK_BuiltinFnToFnPtr:
17162 case CK_ZeroToOCLOpaqueType:
17163 case CK_NonAtomicToAtomic:
17164 case CK_AddressSpaceConversion:
17165 case CK_IntToOCLSampler:
17166 case CK_FloatingToFixedPoint:
17167 case CK_FixedPointToFloating:
17168 case CK_FixedPointCast:
17169 case CK_FixedPointToBoolean:
17170 case CK_FixedPointToIntegral:
17171 case CK_IntegralToFixedPoint:
17172 case CK_MatrixCast:
17173 case CK_HLSLVectorTruncation:
17174 case CK_HLSLElementwiseCast:
17175 case CK_HLSLAggregateSplatCast:
17176 llvm_unreachable(
"invalid cast kind for complex value");
17178 case CK_LValueToRValue:
17179 case CK_AtomicToNonAtomic:
17181 case CK_LValueToRValueBitCast:
17182 case CK_HLSLArrayRValue:
17183 return ExprEvaluatorBaseTy::VisitCastExpr(E);
17186 case CK_LValueBitCast:
17187 case CK_UserDefinedConversion:
17190 case CK_FloatingRealToComplex: {
17195 Result.makeComplexFloat();
17200 case CK_FloatingComplexCast: {
17204 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
17212 case CK_FloatingComplexToIntegralComplex: {
17216 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
17219 Result.makeComplexInt();
17226 case CK_IntegralRealToComplex: {
17231 Result.makeComplexInt();
17232 Result.IntImag =
APSInt(Real.getBitWidth(), !Real.isSigned());
17236 case CK_IntegralComplexCast: {
17240 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
17249 case CK_IntegralComplexToFloatingComplex: {
17255 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
17258 Result.makeComplexFloat();
17260 To,
Result.FloatReal) &&
17266 llvm_unreachable(
"unknown cast resulting in complex value");
17270 APFloat &ResR, APFloat &ResI) {
17276 APFloat AC = A *
C;
17277 APFloat BD = B * D;
17278 APFloat AD = A * D;
17279 APFloat BC = B *
C;
17282 if (ResR.isNaN() && ResI.isNaN()) {
17283 bool Recalc =
false;
17284 if (A.isInfinity() || B.isInfinity()) {
17285 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
17287 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
17290 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
17292 D = APFloat::copySign(APFloat(D.getSemantics()), D);
17295 if (
C.isInfinity() || D.isInfinity()) {
17296 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
17298 D = APFloat::copySign(APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0),
17301 A = APFloat::copySign(APFloat(A.getSemantics()), A);
17303 B = APFloat::copySign(APFloat(B.getSemantics()), B);
17306 if (!Recalc && (AC.isInfinity() || BD.isInfinity() || AD.isInfinity() ||
17307 BC.isInfinity())) {
17309 A = APFloat::copySign(APFloat(A.getSemantics()), A);
17311 B = APFloat::copySign(APFloat(B.getSemantics()), B);
17313 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
17315 D = APFloat::copySign(APFloat(D.getSemantics()), D);
17319 ResR = APFloat::getInf(A.getSemantics()) * (A *
C - B * D);
17320 ResI = APFloat::getInf(A.getSemantics()) * (A * D + B *
C);
17326 APFloat &ResR, APFloat &ResI) {
17333 APFloat MaxCD = maxnum(
abs(
C),
abs(D));
17334 if (MaxCD.isFinite()) {
17335 DenomLogB =
ilogb(MaxCD);
17336 C =
scalbn(
C, -DenomLogB, APFloat::rmNearestTiesToEven);
17337 D =
scalbn(D, -DenomLogB, APFloat::rmNearestTiesToEven);
17339 APFloat Denom =
C *
C + D * D;
17341 scalbn((A *
C + B * D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
17343 scalbn((B *
C - A * D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
17344 if (ResR.isNaN() && ResI.isNaN()) {
17345 if (Denom.isPosZero() && (!A.isNaN() || !B.isNaN())) {
17346 ResR = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * A;
17347 ResI = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * B;
17348 }
else if ((A.isInfinity() || B.isInfinity()) &&
C.isFinite() &&
17350 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
17352 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
17354 ResR = APFloat::getInf(ResR.getSemantics()) * (A *
C + B * D);
17355 ResI = APFloat::getInf(ResI.getSemantics()) * (B *
C - A * D);
17356 }
else if (MaxCD.isInfinity() && A.isFinite() && B.isFinite()) {
17357 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
17359 D = APFloat::copySign(APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0),
17361 ResR = APFloat::getZero(ResR.getSemantics()) * (A *
C + B * D);
17362 ResI = APFloat::getZero(ResI.getSemantics()) * (B *
C - A * D);
17367bool ComplexExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
17369 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
17373 bool LHSReal =
false, RHSReal =
false;
17381 Result.makeComplexFloat();
17385 LHSOK = Visit(E->
getLHS());
17387 if (!LHSOK && !Info.noteFailure())
17393 APFloat &Real = RHS.FloatReal;
17396 RHS.makeComplexFloat();
17397 RHS.FloatImag =
APFloat(Real.getSemantics());
17401 assert(!(LHSReal && RHSReal) &&
17402 "Cannot have both operands of a complex operation be real.");
17404 default:
return Error(E);
17406 if (
Result.isComplexFloat()) {
17407 Result.getComplexFloatReal().add(RHS.getComplexFloatReal(),
17408 APFloat::rmNearestTiesToEven);
17410 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
17412 Result.getComplexFloatImag().add(RHS.getComplexFloatImag(),
17413 APFloat::rmNearestTiesToEven);
17415 Result.getComplexIntReal() += RHS.getComplexIntReal();
17416 Result.getComplexIntImag() += RHS.getComplexIntImag();
17420 if (
Result.isComplexFloat()) {
17421 Result.getComplexFloatReal().subtract(RHS.getComplexFloatReal(),
17422 APFloat::rmNearestTiesToEven);
17424 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
17425 Result.getComplexFloatImag().changeSign();
17426 }
else if (!RHSReal) {
17427 Result.getComplexFloatImag().subtract(RHS.getComplexFloatImag(),
17428 APFloat::rmNearestTiesToEven);
17431 Result.getComplexIntReal() -= RHS.getComplexIntReal();
17432 Result.getComplexIntImag() -= RHS.getComplexIntImag();
17436 if (
Result.isComplexFloat()) {
17441 ComplexValue LHS =
Result;
17442 APFloat &A = LHS.getComplexFloatReal();
17443 APFloat &B = LHS.getComplexFloatImag();
17444 APFloat &
C = RHS.getComplexFloatReal();
17445 APFloat &D = RHS.getComplexFloatImag();
17449 assert(!RHSReal &&
"Cannot have two real operands for a complex op!");
17457 }
else if (RHSReal) {
17469 ComplexValue LHS =
Result;
17470 Result.getComplexIntReal() =
17471 (LHS.getComplexIntReal() * RHS.getComplexIntReal() -
17472 LHS.getComplexIntImag() * RHS.getComplexIntImag());
17473 Result.getComplexIntImag() =
17474 (LHS.getComplexIntReal() * RHS.getComplexIntImag() +
17475 LHS.getComplexIntImag() * RHS.getComplexIntReal());
17479 if (
Result.isComplexFloat()) {
17484 ComplexValue LHS =
Result;
17485 APFloat &A = LHS.getComplexFloatReal();
17486 APFloat &B = LHS.getComplexFloatImag();
17487 APFloat &
C = RHS.getComplexFloatReal();
17488 APFloat &D = RHS.getComplexFloatImag();
17502 B = APFloat::getZero(A.getSemantics());
17507 ComplexValue LHS =
Result;
17508 APSInt Den = RHS.getComplexIntReal() * RHS.getComplexIntReal() +
17509 RHS.getComplexIntImag() * RHS.getComplexIntImag();
17511 return Error(E, diag::note_expr_divide_by_zero);
17513 Result.getComplexIntReal() =
17514 (LHS.getComplexIntReal() * RHS.getComplexIntReal() +
17515 LHS.getComplexIntImag() * RHS.getComplexIntImag()) / Den;
17516 Result.getComplexIntImag() =
17517 (LHS.getComplexIntImag() * RHS.getComplexIntReal() -
17518 LHS.getComplexIntReal() * RHS.getComplexIntImag()) / Den;
17526bool ComplexExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
17540 if (
Result.isComplexFloat()) {
17541 Result.getComplexFloatReal().changeSign();
17542 Result.getComplexFloatImag().changeSign();
17545 Result.getComplexIntReal() = -
Result.getComplexIntReal();
17546 Result.getComplexIntImag() = -
Result.getComplexIntImag();
17550 if (
Result.isComplexFloat())
17551 Result.getComplexFloatImag().changeSign();
17553 Result.getComplexIntImag() = -
Result.getComplexIntImag();
17558bool ComplexExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
17561 Result.makeComplexFloat();
17567 Result.makeComplexInt();
17575 return ExprEvaluatorBaseTy::VisitInitListExpr(E);
17578bool ComplexExprEvaluator::VisitCallExpr(
const CallExpr *E) {
17579 if (!IsConstantEvaluatedBuiltinCall(E))
17580 return ExprEvaluatorBaseTy::VisitCallExpr(E);
17583 case Builtin::BI__builtin_complex:
17584 Result.makeComplexFloat();
17602class AtomicExprEvaluator :
17603 public ExprEvaluatorBase<AtomicExprEvaluator> {
17604 const LValue *
This;
17607 AtomicExprEvaluator(EvalInfo &Info,
const LValue *This,
APValue &
Result)
17615 bool ZeroInitialization(
const Expr *E) {
17616 ImplicitValueInitExpr VIE(
17624 bool VisitCastExpr(
const CastExpr *E) {
17627 return ExprEvaluatorBaseTy::VisitCastExpr(E);
17628 case CK_NullToPointer:
17630 return ZeroInitialization(E);
17631 case CK_NonAtomicToAtomic:
17643 return AtomicExprEvaluator(Info,
This, Result).Visit(E);
17652class VoidExprEvaluator
17653 :
public ExprEvaluatorBase<VoidExprEvaluator> {
17655 VoidExprEvaluator(EvalInfo &Info) : ExprEvaluatorBaseTy(Info) {}
17659 bool ZeroInitialization(
const Expr *E) {
return true; }
17661 bool VisitCastExpr(
const CastExpr *E) {
17664 return ExprEvaluatorBaseTy::VisitCastExpr(E);
17671 bool VisitCallExpr(
const CallExpr *E) {
17672 if (!IsConstantEvaluatedBuiltinCall(E))
17673 return ExprEvaluatorBaseTy::VisitCallExpr(E);
17676 case Builtin::BI__assume:
17677 case Builtin::BI__builtin_assume:
17681 case Builtin::BI__builtin_operator_delete:
17689 bool VisitCXXDeleteExpr(
const CXXDeleteExpr *E);
17693bool VoidExprEvaluator::VisitCXXDeleteExpr(
const CXXDeleteExpr *E) {
17695 if (Info.SpeculativeEvaluationDepth)
17699 if (!OperatorDelete
17700 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
17701 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
17711 if (
Pointer.Designator.Invalid)
17715 if (
Pointer.isNullPointer()) {
17719 if (!Info.getLangOpts().CPlusPlus20)
17720 Info.CCEDiag(E, diag::note_constexpr_new);
17728 QualType AllocType =
Pointer.Base.getDynamicAllocType();
17734 Info.FFDiag(E, diag::note_constexpr_delete_base_nonvirt_dtor)
17743 if (VirtualDelete &&
17745 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
17746 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
17753 (*Alloc)->Value, AllocType))
17756 if (!Info.HeapAllocs.erase(
Pointer.Base.dyn_cast<DynamicAllocLValue>())) {
17761 Info.FFDiag(E, diag::note_constexpr_double_delete);
17771 return VoidExprEvaluator(Info).Visit(E);
17783 if (E->
isGLValue() ||
T->isFunctionType()) {
17787 LV.moveInto(Result);
17788 }
else if (
T->isVectorType()) {
17791 }
else if (
T->isIntegralOrEnumerationType()) {
17792 if (!IntExprEvaluator(Info, Result).Visit(E))
17794 }
else if (
T->hasPointerRepresentation()) {
17798 LV.moveInto(Result);
17799 }
else if (
T->isRealFloatingType()) {
17800 llvm::APFloat F(0.0);
17804 }
else if (
T->isAnyComplexType()) {
17808 C.moveInto(Result);
17809 }
else if (
T->isFixedPointType()) {
17810 if (!FixedPointExprEvaluator(Info, Result).Visit(E))
return false;
17811 }
else if (
T->isMemberPointerType()) {
17815 P.moveInto(Result);
17817 }
else if (
T->isArrayType()) {
17820 Info.CurrentCall->createTemporary(E,
T, ScopeKind::FullExpression, LV);
17824 }
else if (
T->isRecordType()) {
17827 Info.CurrentCall->createTemporary(E,
T, ScopeKind::FullExpression, LV);
17831 }
else if (
T->isVoidType()) {
17832 if (!Info.getLangOpts().CPlusPlus11)
17833 Info.CCEDiag(E, diag::note_constexpr_nonliteral)
17837 }
else if (
T->isAtomicType()) {
17838 QualType Unqual =
T.getAtomicUnqualifiedType();
17842 E, Unqual, ScopeKind::FullExpression, LV);
17850 }
else if (Info.getLangOpts().CPlusPlus11) {
17851 Info.FFDiag(E, diag::note_constexpr_nonliteral) << E->
getType();
17854 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
17865 const Expr *E,
bool AllowNonLiteralTypes) {
17881 if (
T->isArrayType())
17883 else if (
T->isRecordType())
17885 else if (
T->isAtomicType()) {
17886 QualType Unqual =
T.getAtomicUnqualifiedType();
17907 if (Info.EnableNewConstInterp) {
17911 ConstantExprKind::Normal);
17920 LV.setFrom(Info.Ctx, Result);
17927 ConstantExprKind::Normal) &&
17935 if (
const auto *L = dyn_cast<IntegerLiteral>(Exp)) {
17937 APValue(
APSInt(L->getValue(), L->getType()->isUnsignedIntegerType()));
17942 if (
const auto *L = dyn_cast<CXXBoolLiteralExpr>(Exp)) {
17948 if (
const auto *FL = dyn_cast<FloatingLiteral>(Exp)) {
17949 Result =
APValue(FL->getValue());
17954 if (
const auto *L = dyn_cast<CharacterLiteral>(Exp)) {
17960 if (
const auto *CE = dyn_cast<ConstantExpr>(Exp)) {
17961 if (CE->hasAPValueResult()) {
17962 APValue APV = CE->getAPValueResult();
17964 Result = std::move(APV);
18040 bool InConstantContext)
const {
18042 "Expression evaluator can't be called on a dependent expression.");
18043 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsRValue");
18045 Info.InConstantContext = InConstantContext;
18046 return ::EvaluateAsRValue(
this,
Result, Ctx, Info);
18050 bool InConstantContext)
const {
18052 "Expression evaluator can't be called on a dependent expression.");
18053 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsBooleanCondition");
18061 bool InConstantContext)
const {
18063 "Expression evaluator can't be called on a dependent expression.");
18064 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsInt");
18066 Info.InConstantContext = InConstantContext;
18067 return ::EvaluateAsInt(
this,
Result, Ctx, AllowSideEffects, Info);
18072 bool InConstantContext)
const {
18074 "Expression evaluator can't be called on a dependent expression.");
18075 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFixedPoint");
18077 Info.InConstantContext = InConstantContext;
18078 return ::EvaluateAsFixedPoint(
this,
Result, Ctx, AllowSideEffects, Info);
18083 bool InConstantContext)
const {
18085 "Expression evaluator can't be called on a dependent expression.");
18087 if (!
getType()->isRealFloatingType())
18090 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFloat");
18102 bool InConstantContext)
const {
18104 "Expression evaluator can't be called on a dependent expression.");
18106 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsLValue");
18108 Info.InConstantContext = InConstantContext;
18112 if (Info.EnableNewConstInterp) {
18114 ConstantExprKind::Normal))
18117 LV.setFrom(Ctx,
Result.Val);
18120 ConstantExprKind::Normal, CheckedTemps);
18123 if (!
EvaluateLValue(
this, LV, Info) || !Info.discardCleanups() ||
18124 Result.HasSideEffects ||
18127 ConstantExprKind::Normal, CheckedTemps))
18130 LV.moveInto(
Result.Val);
18137 bool IsConstantDestruction) {
18138 EvalInfo Info(Ctx, EStatus,
18141 Info.setEvaluatingDecl(
Base, DestroyedValue,
18142 EvalInfo::EvaluatingDeclKind::Dtor);
18143 Info.InConstantContext = IsConstantDestruction;
18152 if (!Info.discardCleanups())
18153 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
18161 "Expression evaluator can't be called on a dependent expression.");
18167 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsConstantExpr");
18169 EvalInfo Info(Ctx,
Result, EM);
18170 Info.InConstantContext =
true;
18172 if (Info.EnableNewConstInterp) {
18176 getStorageType(Ctx,
this),
Result.Val, Kind);
18181 if (Kind == ConstantExprKind::ClassTemplateArgument)
18197 FullExpressionRAII
Scope(Info);
18202 if (!Info.discardCleanups())
18203 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
18213 if (Kind == ConstantExprKind::ClassTemplateArgument &&
18216 Result.HasSideEffects)) {
18228 bool IsConstantInitialization)
const {
18230 "Expression evaluator can't be called on a dependent expression.");
18231 assert(VD &&
"Need a valid VarDecl");
18233 llvm::TimeTraceScope TimeScope(
"EvaluateAsInitializer", [&] {
18235 llvm::raw_string_ostream OS(Name);
18241 EStatus.
Diag = &Notes;
18243 EvalInfo Info(Ctx, EStatus,
18244 (IsConstantInitialization &&
18248 Info.setEvaluatingDecl(VD,
Value);
18249 Info.InConstantContext = IsConstantInitialization;
18254 if (Info.EnableNewConstInterp) {
18255 auto &InterpCtx =
const_cast<ASTContext &
>(Ctx).getInterpContext();
18256 if (!InterpCtx.evaluateAsInitializer(Info, VD,
this,
Value))
18260 ConstantExprKind::Normal);
18275 FullExpressionRAII
Scope(Info);
18278 EStatus.HasSideEffects)
18284 Info.performLifetimeExtension();
18286 if (!Info.discardCleanups())
18287 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
18291 ConstantExprKind::Normal) &&
18298 EStatus.
Diag = &Notes;
18315 IsConstantDestruction) ||
18327 "Expression evaluator can't be called on a dependent expression.");
18336 "Expression evaluator can't be called on a dependent expression.");
18338 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstInt");
18341 Info.InConstantContext =
true;
18345 assert(
Result &&
"Could not evaluate expression");
18346 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
18348 return EVResult.Val.getInt();
18354 "Expression evaluator can't be called on a dependent expression.");
18356 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstIntCheckOverflow");
18358 EVResult.Diag =
Diag;
18360 Info.InConstantContext =
true;
18361 Info.CheckingForUndefinedBehavior =
true;
18365 assert(
Result &&
"Could not evaluate expression");
18366 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
18368 return EVResult.Val.getInt();
18373 "Expression evaluator can't be called on a dependent expression.");
18375 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateForOverflow");
18380 Info.CheckingForUndefinedBehavior =
true;
18386 assert(
Val.isLValue());
18412 IK_ICEIfUnevaluated,
18428static ICEDiag
Worst(ICEDiag A, ICEDiag B) {
return A.Kind >= B.Kind ? A : B; }
18435 Info.InConstantContext =
true;
18444 assert(!E->
isValueDependent() &&
"Should not see value dependent exprs!");
18449#define ABSTRACT_STMT(Node)
18450#define STMT(Node, Base) case Expr::Node##Class:
18451#define EXPR(Node, Base)
18452#include "clang/AST/StmtNodes.inc"
18453 case Expr::PredefinedExprClass:
18454 case Expr::FloatingLiteralClass:
18455 case Expr::ImaginaryLiteralClass:
18456 case Expr::StringLiteralClass:
18457 case Expr::ArraySubscriptExprClass:
18458 case Expr::MatrixSubscriptExprClass:
18459 case Expr::ArraySectionExprClass:
18460 case Expr::OMPArrayShapingExprClass:
18461 case Expr::OMPIteratorExprClass:
18462 case Expr::MemberExprClass:
18463 case Expr::CompoundAssignOperatorClass:
18464 case Expr::CompoundLiteralExprClass:
18465 case Expr::ExtVectorElementExprClass:
18466 case Expr::DesignatedInitExprClass:
18467 case Expr::ArrayInitLoopExprClass:
18468 case Expr::ArrayInitIndexExprClass:
18469 case Expr::NoInitExprClass:
18470 case Expr::DesignatedInitUpdateExprClass:
18471 case Expr::ImplicitValueInitExprClass:
18472 case Expr::ParenListExprClass:
18473 case Expr::VAArgExprClass:
18474 case Expr::AddrLabelExprClass:
18475 case Expr::StmtExprClass:
18476 case Expr::CXXMemberCallExprClass:
18477 case Expr::CUDAKernelCallExprClass:
18478 case Expr::CXXAddrspaceCastExprClass:
18479 case Expr::CXXDynamicCastExprClass:
18480 case Expr::CXXTypeidExprClass:
18481 case Expr::CXXUuidofExprClass:
18482 case Expr::MSPropertyRefExprClass:
18483 case Expr::MSPropertySubscriptExprClass:
18484 case Expr::CXXNullPtrLiteralExprClass:
18485 case Expr::UserDefinedLiteralClass:
18486 case Expr::CXXThisExprClass:
18487 case Expr::CXXThrowExprClass:
18488 case Expr::CXXNewExprClass:
18489 case Expr::CXXDeleteExprClass:
18490 case Expr::CXXPseudoDestructorExprClass:
18491 case Expr::UnresolvedLookupExprClass:
18492 case Expr::RecoveryExprClass:
18493 case Expr::DependentScopeDeclRefExprClass:
18494 case Expr::CXXConstructExprClass:
18495 case Expr::CXXInheritedCtorInitExprClass:
18496 case Expr::CXXStdInitializerListExprClass:
18497 case Expr::CXXBindTemporaryExprClass:
18498 case Expr::ExprWithCleanupsClass:
18499 case Expr::CXXTemporaryObjectExprClass:
18500 case Expr::CXXUnresolvedConstructExprClass:
18501 case Expr::CXXDependentScopeMemberExprClass:
18502 case Expr::UnresolvedMemberExprClass:
18503 case Expr::ObjCStringLiteralClass:
18504 case Expr::ObjCBoxedExprClass:
18505 case Expr::ObjCArrayLiteralClass:
18506 case Expr::ObjCDictionaryLiteralClass:
18507 case Expr::ObjCEncodeExprClass:
18508 case Expr::ObjCMessageExprClass:
18509 case Expr::ObjCSelectorExprClass:
18510 case Expr::ObjCProtocolExprClass:
18511 case Expr::ObjCIvarRefExprClass:
18512 case Expr::ObjCPropertyRefExprClass:
18513 case Expr::ObjCSubscriptRefExprClass:
18514 case Expr::ObjCIsaExprClass:
18515 case Expr::ObjCAvailabilityCheckExprClass:
18516 case Expr::ShuffleVectorExprClass:
18517 case Expr::ConvertVectorExprClass:
18518 case Expr::BlockExprClass:
18520 case Expr::OpaqueValueExprClass:
18521 case Expr::PackExpansionExprClass:
18522 case Expr::SubstNonTypeTemplateParmPackExprClass:
18523 case Expr::FunctionParmPackExprClass:
18524 case Expr::AsTypeExprClass:
18525 case Expr::ObjCIndirectCopyRestoreExprClass:
18526 case Expr::MaterializeTemporaryExprClass:
18527 case Expr::PseudoObjectExprClass:
18528 case Expr::AtomicExprClass:
18529 case Expr::LambdaExprClass:
18530 case Expr::CXXFoldExprClass:
18531 case Expr::CoawaitExprClass:
18532 case Expr::DependentCoawaitExprClass:
18533 case Expr::CoyieldExprClass:
18534 case Expr::SYCLUniqueStableNameExprClass:
18535 case Expr::CXXParenListInitExprClass:
18536 case Expr::HLSLOutArgExprClass:
18539 case Expr::InitListExprClass: {
18550 case Expr::SizeOfPackExprClass:
18551 case Expr::GNUNullExprClass:
18552 case Expr::SourceLocExprClass:
18553 case Expr::EmbedExprClass:
18554 case Expr::OpenACCAsteriskSizeExprClass:
18557 case Expr::PackIndexingExprClass:
18560 case Expr::SubstNonTypeTemplateParmExprClass:
18564 case Expr::ConstantExprClass:
18567 case Expr::ParenExprClass:
18569 case Expr::GenericSelectionExprClass:
18571 case Expr::IntegerLiteralClass:
18572 case Expr::FixedPointLiteralClass:
18573 case Expr::CharacterLiteralClass:
18574 case Expr::ObjCBoolLiteralExprClass:
18575 case Expr::CXXBoolLiteralExprClass:
18576 case Expr::CXXScalarValueInitExprClass:
18577 case Expr::TypeTraitExprClass:
18578 case Expr::ConceptSpecializationExprClass:
18579 case Expr::RequiresExprClass:
18580 case Expr::ArrayTypeTraitExprClass:
18581 case Expr::ExpressionTraitExprClass:
18582 case Expr::CXXNoexceptExprClass:
18584 case Expr::CallExprClass:
18585 case Expr::CXXOperatorCallExprClass: {
18594 case Expr::CXXRewrittenBinaryOperatorClass:
18597 case Expr::DeclRefExprClass: {
18611 const VarDecl *VD = dyn_cast<VarDecl>(D);
18618 case Expr::UnaryOperatorClass: {
18641 llvm_unreachable(
"invalid unary operator class");
18643 case Expr::OffsetOfExprClass: {
18652 case Expr::UnaryExprOrTypeTraitExprClass: {
18654 if ((Exp->
getKind() == UETT_SizeOf) &&
18657 if (Exp->
getKind() == UETT_CountOf) {
18664 if (VAT->getElementType()->isArrayType())
18676 case Expr::BinaryOperatorClass: {
18721 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE) {
18724 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
18725 if (REval.isSigned() && REval.isAllOnes()) {
18727 if (LEval.isMinSignedValue())
18728 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
18736 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE)
18737 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
18743 return Worst(LHSResult, RHSResult);
18749 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICEIfUnevaluated) {
18759 return Worst(LHSResult, RHSResult);
18762 llvm_unreachable(
"invalid binary operator kind");
18764 case Expr::ImplicitCastExprClass:
18765 case Expr::CStyleCastExprClass:
18766 case Expr::CXXFunctionalCastExprClass:
18767 case Expr::CXXStaticCastExprClass:
18768 case Expr::CXXReinterpretCastExprClass:
18769 case Expr::CXXConstCastExprClass:
18770 case Expr::ObjCBridgedCastExprClass: {
18777 APSInt IgnoredVal(DestWidth, !DestSigned);
18782 if (FL->getValue().convertToInteger(IgnoredVal,
18783 llvm::APFloat::rmTowardZero,
18784 &Ignored) & APFloat::opInvalidOp)
18790 case CK_LValueToRValue:
18791 case CK_AtomicToNonAtomic:
18792 case CK_NonAtomicToAtomic:
18794 case CK_IntegralToBoolean:
18795 case CK_IntegralCast:
18801 case Expr::BinaryConditionalOperatorClass: {
18804 if (CommonResult.Kind == IK_NotICE)
return CommonResult;
18806 if (FalseResult.Kind == IK_NotICE)
return FalseResult;
18807 if (CommonResult.Kind == IK_ICEIfUnevaluated)
return CommonResult;
18808 if (FalseResult.Kind == IK_ICEIfUnevaluated &&
18810 return FalseResult;
18812 case Expr::ConditionalOperatorClass: {
18820 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
18823 if (CondResult.Kind == IK_NotICE)
18829 if (TrueResult.Kind == IK_NotICE)
18831 if (FalseResult.Kind == IK_NotICE)
18832 return FalseResult;
18833 if (CondResult.Kind == IK_ICEIfUnevaluated)
18835 if (TrueResult.Kind == IK_ICE && FalseResult.Kind == IK_ICE)
18841 return FalseResult;
18844 case Expr::CXXDefaultArgExprClass:
18846 case Expr::CXXDefaultInitExprClass:
18848 case Expr::ChooseExprClass: {
18851 case Expr::BuiltinBitCastExprClass: {
18852 if (!checkBitCastConstexprEligibility(
nullptr, Ctx,
cast<CastExpr>(E)))
18858 llvm_unreachable(
"Invalid StmtClass!");
18864 llvm::APSInt *
Value) {
18872 if (!Result.isInt())
18881 "Expression evaluator can't be called on a dependent expression.");
18883 ExprTimeTraceScope TimeScope(
this, Ctx,
"isIntegerConstantExpr");
18889 if (D.Kind != IK_ICE)
18894std::optional<llvm::APSInt>
18898 return std::nullopt;
18905 return std::nullopt;
18909 return std::nullopt;
18918 Info.InConstantContext =
true;
18921 llvm_unreachable(
"ICE cannot be evaluated!");
18928 "Expression evaluator can't be called on a dependent expression.");
18930 return CheckICE(
this, Ctx).Kind == IK_ICE;
18935 "Expression evaluator can't be called on a dependent expression.");
18952 Status.Diag = &Diags;
18959 Info.discardCleanups() && !Status.HasSideEffects;
18961 return IsConstExpr && Diags.empty();
18969 "Expression evaluator can't be called on a dependent expression.");
18971 llvm::TimeTraceScope TimeScope(
"EvaluateWithSubstitution", [&] {
18973 llvm::raw_string_ostream OS(Name);
18981 Info.InConstantContext =
true;
18984 const LValue *ThisPtr =
nullptr;
18987 auto *MD = dyn_cast<CXXMethodDecl>(Callee);
18988 assert(MD &&
"Don't provide `this` for non-methods.");
18989 assert(MD->isImplicitObjectMemberFunction() &&
18990 "Don't provide `this` for methods without an implicit object.");
18992 if (!
This->isValueDependent() &&
18995 ThisPtr = &ThisVal;
19002 CallRef
Call = Info.CurrentCall->createCall(Callee);
19005 unsigned Idx = I - Args.begin();
19006 if (Idx >= Callee->getNumParams())
19008 const ParmVarDecl *PVD = Callee->getParamDecl(Idx);
19009 if ((*I)->isValueDependent() ||
19013 if (
APValue *Slot = Info.getParamSlot(
Call, PVD))
19024 Info.discardCleanups();
19028 CallStackFrame Frame(Info, Callee->getLocation(), Callee, ThisPtr,
This,
19031 FullExpressionRAII
Scope(Info);
19045 llvm::TimeTraceScope TimeScope(
"isPotentialConstantExpr", [&] {
19047 llvm::raw_string_ostream OS(Name);
19054 Status.
Diag = &Diags;
19058 Info.InConstantContext =
true;
19059 Info.CheckingPotentialConstantExpression =
true;
19062 if (Info.EnableNewConstInterp) {
19064 return Diags.empty();
19075 This.set({&VIE, Info.CurrentCall->Index});
19083 Info.setEvaluatingDecl(
This.getLValueBase(), Scratch);
19089 &VIE, Args, CallRef(), FD->
getBody(), Info, Scratch,
19093 return Diags.empty();
19101 "Expression evaluator can't be called on a dependent expression.");
19104 Status.
Diag = &Diags;
19108 Info.InConstantContext =
true;
19109 Info.CheckingPotentialConstantExpression =
true;
19111 if (Info.EnableNewConstInterp) {
19113 return Diags.empty();
19118 nullptr, CallRef());
19122 return Diags.empty();
19126 unsigned Type)
const {
19127 if (!
getType()->isPointerType())
19136 EvalInfo &Info, std::string *StringResult) {
19148 if (
const StringLiteral *S = dyn_cast_or_null<StringLiteral>(
19149 String.getLValueBase().dyn_cast<
const Expr *>())) {
19152 if (Off >= 0 && (uint64_t)Off <= (uint64_t)Str.size() &&
19156 Str = Str.substr(Off);
19158 StringRef::size_type Pos = Str.find(0);
19159 if (Pos != StringRef::npos)
19160 Str = Str.substr(0, Pos);
19162 Result = Str.size();
19164 *StringResult = Str;
19172 for (uint64_t Strlen = 0; ; ++Strlen) {
19180 }
else if (StringResult)
19181 StringResult->push_back(Char.
getInt().getExtValue());
19191 std::string StringResult;
19193 if (Info.EnableNewConstInterp) {
19195 return std::nullopt;
19196 return StringResult;
19200 return StringResult;
19201 return std::nullopt;
19204template <
typename T>
19206 const Expr *SizeExpression,
19207 const Expr *PtrExpression,
19211 Info.InConstantContext =
true;
19213 if (Info.EnableNewConstInterp)
19215 PtrExpression, Result);
19218 FullExpressionRAII
Scope(Info);
19223 uint64_t Size = SizeValue.getZExtValue();
19226 if constexpr (std::is_same_v<APValue, T>)
19229 if (Size < Result.max_size())
19230 Result.reserve(Size);
19236 for (uint64_t I = 0; I < Size; ++I) {
19242 if constexpr (std::is_same_v<APValue, T>) {
19243 Result.getArrayInitializedElt(I) = std::move(Char);
19247 assert(
C.getBitWidth() <= 8 &&
19248 "string element not representable in char");
19250 Result.push_back(
static_cast<char>(
C.getExtValue()));
19261 const Expr *SizeExpression,
19265 PtrExpression, Ctx, Status);
19269 const Expr *SizeExpression,
19273 PtrExpression, Ctx, Status);
19280 if (Info.EnableNewConstInterp)
19287struct IsWithinLifetimeHandler {
19290 using result_type = std::optional<bool>;
19291 std::optional<bool> failed() {
return std::nullopt; }
19292 template <
typename T>
19293 std::optional<bool> found(
T &Subobj,
QualType SubobjType) {
19298std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &IEE,
19299 const CallExpr *E) {
19300 EvalInfo &Info = IEE.Info;
19305 if (!Info.InConstantContext)
19306 return std::nullopt;
19308 const Expr *Arg = E->
getArg(0);
19310 return std::nullopt;
19313 return std::nullopt;
19315 if (Val.allowConstexprUnknown())
19319 bool CalledFromStd =
false;
19320 const auto *
Callee = Info.CurrentCall->getCallee();
19321 if (Callee &&
Callee->isInStdNamespace()) {
19322 const IdentifierInfo *Identifier =
Callee->getIdentifier();
19323 CalledFromStd = Identifier && Identifier->
isStr(
"is_within_lifetime");
19325 Info.CCEDiag(CalledFromStd ? Info.CurrentCall->getCallRange().getBegin()
19327 diag::err_invalid_is_within_lifetime)
19328 << (CalledFromStd ?
"std::is_within_lifetime"
19329 :
"__builtin_is_within_lifetime")
19331 return std::nullopt;
19341 if (Val.isNullPointer() || Val.getLValueBase().isNull())
19343 QualType
T = Val.getLValueBase().getType();
19345 "Pointers to functions should have been typed as function pointers "
19346 "which would have been rejected earlier");
19349 if (Val.getLValueDesignator().isOnePastTheEnd())
19351 assert(Val.getLValueDesignator().isValidSubobject() &&
19352 "Unchecked case for valid subobject");
19356 CompleteObject CO =
19360 if (Info.EvaluatingDeclValue && CO.Value == Info.EvaluatingDeclValue)
19365 IsWithinLifetimeHandler handler{Info};
19366 return findSubobject(Info, E, CO, Val.getLValueDesignator(), handler);
Defines the clang::ASTContext interface.
This file provides some common utility functions for processing Lambda related AST Constructs.
Defines enum values for all the target-independent builtin functions.
static Address castToBase(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy, Address OriginalBaseAddress, llvm::Value *Addr)
static Decl::Kind getKind(const Decl *D)
GCCTypeClass
Values returned by __builtin_classify_type, chosen to match the values produced by GCC's builtin.
@ PointerToMemberFunction
static bool isRead(AccessKinds AK)
static bool EvaluateCharRangeAsStringImpl(const Expr *, T &Result, const Expr *SizeExpression, const Expr *PtrExpression, ASTContext &Ctx, Expr::EvalResult &Status)
static bool EvaluateBuiltinStrLen(const Expr *E, uint64_t &Result, EvalInfo &Info, std::string *StringResult=nullptr)
static bool isValidIndeterminateAccess(AccessKinds AK)
Is this kind of access valid on an indeterminate object value?
static bool EvaluateMemberPointer(const Expr *E, MemberPtr &Result, EvalInfo &Info)
static bool hasUnacceptableSideEffect(Expr::EvalStatus &Result, Expr::SideEffectsKind SEK)
static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E, AccessKinds AK, const LValue &LVal, QualType LValType)
Find the complete object to which an LValue refers.
static bool evaluateLValueAsAllocSize(EvalInfo &Info, APValue::LValueBase Base, LValue &Result)
Attempts to evaluate the given LValueBase as the result of a call to a function with the alloc_size a...
static const CXXMethodDecl * HandleVirtualDispatch(EvalInfo &Info, const Expr *E, LValue &This, const CXXMethodDecl *Found, llvm::SmallVectorImpl< QualType > &CovariantAdjustmentPath)
Perform virtual dispatch.
static bool EvaluateVarDecl(EvalInfo &Info, const VarDecl *VD)
static bool CheckEvaluationResult(CheckEvaluationResultKind CERK, EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value, ConstantExprKind Kind, const FieldDecl *SubobjectDecl, CheckedTemporaries &CheckedTemps)
static bool HandleLValueComplexElement(EvalInfo &Info, const Expr *E, LValue &LVal, QualType EltTy, bool Imag)
Update an lvalue to refer to a component of a complex number.
static bool evalPackBuiltin(const CallExpr *E, EvalInfo &Info, APValue &Result, llvm::function_ref< APInt(const APSInt &)> PackFn)
static bool HandleSizeof(EvalInfo &Info, SourceLocation Loc, QualType Type, CharUnits &Size, SizeOfType SOT=SizeOfType::SizeOf)
Get the size of the given type in char units.
static bool HandleConstructorCall(const Expr *E, const LValue &This, CallRef Call, const CXXConstructorDecl *Definition, EvalInfo &Info, APValue &Result)
Evaluate a constructor call.
static bool ShouldPropagateBreakContinue(EvalInfo &Info, const Stmt *LoopOrSwitch, ArrayRef< BlockScopeRAII * > Scopes, EvalStmtResult &ESR)
Helper to implement named break/continue.
static EvalStmtResult EvaluateLoopBody(StmtResult &Result, EvalInfo &Info, const Stmt *Body, const SwitchCase *Case=nullptr)
Evaluate the body of a loop, and translate the result as appropriate.
static bool EvaluatePointer(const Expr *E, LValue &Result, EvalInfo &Info, bool InvalidBaseOK=false)
static bool CheckTrivialDefaultConstructor(EvalInfo &Info, SourceLocation Loc, const CXXConstructorDecl *CD, bool IsValueInitialization)
CheckTrivialDefaultConstructor - Check whether a constructor is a trivial default constructor.
static bool EvaluateVector(const Expr *E, APValue &Result, EvalInfo &Info)
static const ValueDecl * GetLValueBaseDecl(const LValue &LVal)
static bool TryEvaluateBuiltinNaN(const ASTContext &Context, QualType ResultTy, const Expr *Arg, bool SNaN, llvm::APFloat &Result)
static const Expr * ignorePointerCastsAndParens(const Expr *E)
A more selective version of E->IgnoreParenCasts for tryEvaluateBuiltinObjectSize. This ignores some c...
static bool isAnyAccess(AccessKinds AK)
static bool EvaluateComparisonBinaryOperator(EvalInfo &Info, const BinaryOperator *E, SuccessCB &&Success, AfterCB &&DoAfter)
static bool HandleClassZeroInitialization(EvalInfo &Info, const Expr *E, const RecordDecl *RD, const LValue &This, APValue &Result)
Perform zero-initialization on an object of non-union class type. C++11 [dcl.init]p5: To zero-initial...
static bool EvaluateComplex(const Expr *E, ComplexValue &Res, EvalInfo &Info)
static bool CheckMemoryLeaks(EvalInfo &Info)
Enforce C++2a [expr.const]/4.17, which disallows new-expressions unless "the allocated storage is dea...
static ICEDiag CheckEvalInICE(const Expr *E, const ASTContext &Ctx)
static llvm::APInt ConvertBoolVectorToInt(const APValue &Val)
static bool isBaseClassPublic(const CXXRecordDecl *Derived, const CXXRecordDecl *Base)
Determine whether Base, which is known to be a direct base class of Derived, is a public base class.
static bool hasVirtualDestructor(QualType T)
static bool HandleOverflow(EvalInfo &Info, const Expr *E, const T &SrcValue, QualType DestType)
static CharUnits getBaseAlignment(EvalInfo &Info, const LValue &Value)
static bool HandleLValueIndirectMember(EvalInfo &Info, const Expr *E, LValue &LVal, const IndirectFieldDecl *IFD)
Update LVal to refer to the given indirect field.
static ICEDiag Worst(ICEDiag A, ICEDiag B)
static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E, const VarDecl *VD, CallStackFrame *Frame, unsigned Version, APValue *&Result)
Try to evaluate the initializer for a variable declaration.
static bool handleDefaultInitValue(QualType T, APValue &Result)
Get the value to use for a default-initialized object of type T.
static bool HandleLValueVectorElement(EvalInfo &Info, const Expr *E, LValue &LVal, QualType EltTy, uint64_t Size, uint64_t Idx)
static void NoteLValueLocation(EvalInfo &Info, APValue::LValueBase Base)
static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc, QualType Type, const LValue &LVal, ConstantExprKind Kind, CheckedTemporaries &CheckedTemps)
Check that this reference or pointer core constant expression is a valid value for an address or refe...
static bool CheckedIntArithmetic(EvalInfo &Info, const Expr *E, const APSInt &LHS, const APSInt &RHS, unsigned BitWidth, Operation Op, APSInt &Result)
Perform the given integer operation, which is known to need at most BitWidth bits,...
static bool EvaluateTemporary(const Expr *E, LValue &Result, EvalInfo &Info)
Evaluate an expression of record type as a temporary.
static bool EvaluateArray(const Expr *E, const LValue &This, APValue &Result, EvalInfo &Info)
static bool truncateBitfieldValue(EvalInfo &Info, const Expr *E, APValue &Value, const FieldDecl *FD)
static bool handleVectorShuffle(EvalInfo &Info, const ShuffleVectorExpr *E, QualType ElemType, APValue const &VecVal1, APValue const &VecVal2, unsigned EltNum, APValue &Result)
static bool handleVectorElementCast(EvalInfo &Info, const FPOptions FPO, const Expr *E, QualType SourceTy, QualType DestTy, APValue const &Original, APValue &Result)
static const ValueDecl * HandleMemberPointerAccess(EvalInfo &Info, QualType LVType, LValue &LV, const Expr *RHS, bool IncludeMember=true)
HandleMemberPointerAccess - Evaluate a member access operation and build an lvalue referring to the r...
static bool HandleBaseToDerivedCast(EvalInfo &Info, const CastExpr *E, LValue &Result)
HandleBaseToDerivedCast - Apply the given base-to-derived cast operation on the provided lvalue,...
static bool EvaluateFloat(const Expr *E, APFloat &Result, EvalInfo &Info)
static bool IsOpaqueConstantCall(const CallExpr *E)
Should this call expression be treated as forming an opaque constant?
static bool CheckMemberPointerConstantExpression(EvalInfo &Info, SourceLocation Loc, QualType Type, const APValue &Value, ConstantExprKind Kind)
Member pointers are constant expressions unless they point to a non-virtual dllimport member function...
static bool EvaluateAsInt(const Expr *E, Expr::EvalResult &ExprResult, const ASTContext &Ctx, Expr::SideEffectsKind AllowSideEffects, EvalInfo &Info)
static bool handleLValueToRValueConversion(EvalInfo &Info, const Expr *Conv, QualType Type, const LValue &LVal, APValue &RVal, bool WantObjectRepresentation=false)
Perform an lvalue-to-rvalue conversion on the given glvalue.
static bool refersToCompleteObject(const LValue &LVal)
Tests to see if the LValue has a user-specified designator (that isn't necessarily valid)....
static bool AreElementsOfSameArray(QualType ObjType, const SubobjectDesignator &A, const SubobjectDesignator &B)
Determine whether the given subobject designators refer to elements of the same array object.
static bool EvaluateDecompositionDeclInit(EvalInfo &Info, const DecompositionDecl *DD)
static bool IsWeakLValue(const LValue &Value)
static bool EvaluateArrayNewConstructExpr(EvalInfo &Info, LValue &This, APValue &Result, const CXXConstructExpr *CCE, QualType AllocType)
static bool EvaluateRecord(const Expr *E, const LValue &This, APValue &Result, EvalInfo &Info)
static bool handleAssignment(EvalInfo &Info, const Expr *E, const LValue &LVal, QualType LValType, APValue &Val)
Perform an assignment of Val to LVal. Takes ownership of Val.
static bool CastToDerivedClass(EvalInfo &Info, const Expr *E, LValue &Result, const RecordDecl *TruncatedType, unsigned TruncatedElements)
Cast an lvalue referring to a base subobject to a derived class, by truncating the lvalue's path to t...
static bool EvaluateIgnoredValue(EvalInfo &Info, const Expr *E)
Evaluate an expression to see if it had side-effects, and discard its result.
static void addFlexibleArrayMemberInitSize(EvalInfo &Info, const QualType &T, const LValue &LV, CharUnits &Size)
If we're evaluating the object size of an instance of a struct that contains a flexible array member,...
static bool HandleLValueBasePath(EvalInfo &Info, const CastExpr *E, QualType Type, LValue &Result)
static QualType getSubobjectType(QualType ObjType, QualType SubobjType, bool IsMutable=false)
static bool EvaluateFixedPointOrInteger(const Expr *E, APFixedPoint &Result, EvalInfo &Info)
Evaluate an integer or fixed point expression into an APResult.
static bool HandleIntToFloatCast(EvalInfo &Info, const Expr *E, const FPOptions FPO, QualType SrcType, const APSInt &Value, QualType DestType, APFloat &Result)
static const CXXRecordDecl * getBaseClassType(SubobjectDesignator &Designator, unsigned PathLength)
static bool CastToBaseClass(EvalInfo &Info, const Expr *E, LValue &Result, const CXXRecordDecl *DerivedRD, const CXXRecordDecl *BaseRD)
Cast an lvalue referring to a derived class to a known base subobject.
static bool HandleLValueBase(EvalInfo &Info, const Expr *E, LValue &Obj, const CXXRecordDecl *DerivedDecl, const CXXBaseSpecifier *Base)
static bool HandleConversionToBool(const APValue &Val, bool &Result)
CharUnits GetAlignOfExpr(const ASTContext &Ctx, const Expr *E, UnaryExprOrTypeTrait ExprKind)
static bool isModification(AccessKinds AK)
static bool handleCompareOpForVector(const APValue &LHSValue, BinaryOperatorKind Opcode, const APValue &RHSValue, APInt &Result)
static bool MaybeElementDependentArrayFiller(const Expr *FillerExpr)
static bool EvaluateObjectArgument(EvalInfo &Info, const Expr *Object, LValue &This)
Build an lvalue for the object argument of a member function call.
static bool CheckLiteralType(EvalInfo &Info, const Expr *E, const LValue *This=nullptr)
Check that this core constant expression is of literal type, and if not, produce an appropriate diagn...
static bool EvaluateInteger(const Expr *E, APSInt &Result, EvalInfo &Info)
CheckEvaluationResultKind
static bool isZeroSized(const LValue &Value)
static APSInt extractStringLiteralCharacter(EvalInfo &Info, const Expr *Lit, uint64_t Index)
Extract the value of a character from a string literal.
static bool modifySubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, const SubobjectDesignator &Sub, APValue &NewVal)
Update the designated sub-object of an rvalue to the given value.
static bool EvaluateCPlusPlus11IntegralConstantExpr(const ASTContext &Ctx, const Expr *E, llvm::APSInt *Value)
Evaluate an expression as a C++11 integral constant expression.
static CharUnits GetAlignOfType(const ASTContext &Ctx, QualType T, UnaryExprOrTypeTrait ExprKind)
static bool getBuiltinAlignArguments(const CallExpr *E, EvalInfo &Info, APValue &Val, APSInt &Alignment)
static bool HandleLValueArrayAdjustment(EvalInfo &Info, const Expr *E, LValue &LVal, QualType EltTy, APSInt Adjustment)
Update a pointer value to model pointer arithmetic.
static bool extractSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, const SubobjectDesignator &Sub, APValue &Result, AccessKinds AK=AK_Read)
Extract the designated sub-object of an rvalue.
static bool HandleLValueMember(EvalInfo &Info, const Expr *E, LValue &LVal, const FieldDecl *FD, const ASTRecordLayout *RL=nullptr)
Update LVal to refer to the given field, which must be a member of the type currently described by LV...
static void addOrSubLValueAsInteger(APValue &LVal, const APSInt &Index, bool IsSub)
static bool IsDeclSourceLocationCurrent(const FunctionDecl *FD)
void HandleComplexComplexDiv(APFloat A, APFloat B, APFloat C, APFloat D, APFloat &ResR, APFloat &ResI)
static bool handleTrivialCopy(EvalInfo &Info, const ParmVarDecl *Param, const Expr *E, APValue &Result, bool CopyObjectRepresentation)
Perform a trivial copy from Param, which is the parameter of a copy or move constructor or assignment...
static bool checkFloatingPointResult(EvalInfo &Info, const Expr *E, APFloat::opStatus St)
Check if the given evaluation result is allowed for constant evaluation.
static bool EvaluateBuiltinConstantPForLValue(const APValue &LV)
EvaluateBuiltinConstantPForLValue - Determine the result of __builtin_constant_p when applied to the ...
static bool EvaluateBuiltinConstantP(EvalInfo &Info, const Expr *Arg)
EvaluateBuiltinConstantP - Evaluate __builtin_constant_p as similarly to GCC as we can manage.
static bool checkNonVirtualMemberCallThisPointer(EvalInfo &Info, const Expr *E, const LValue &This, const CXXMethodDecl *NamedMember)
Check that the pointee of the 'this' pointer in a member function call is either within its lifetime ...
static bool CheckConstantExpression(EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value, ConstantExprKind Kind)
Check that this core constant expression value is a valid value for a constant expression.
static bool EvaluateAsBooleanCondition(const Expr *E, bool &Result, EvalInfo &Info)
static std::optional< DynamicType > ComputeDynamicType(EvalInfo &Info, const Expr *E, LValue &This, AccessKinds AK)
Determine the dynamic type of an object.
static bool evalPshufBuiltin(EvalInfo &Info, const CallExpr *Call, bool IsShufHW, APValue &Out)
static bool EvaluateDecl(EvalInfo &Info, const Decl *D, bool EvaluateConditionDecl=false)
static void expandArray(APValue &Array, unsigned Index)
static bool handleLogicalOpForVector(const APInt &LHSValue, BinaryOperatorKind Opcode, const APInt &RHSValue, APInt &Result)
static unsigned FindDesignatorMismatch(QualType ObjType, const SubobjectDesignator &A, const SubobjectDesignator &B, bool &WasArrayIndex)
Find the position where two subobject designators diverge, or equivalently the length of the common i...
static bool isOnePastTheEndOfCompleteObject(const ASTContext &Ctx, const LValue &LV)
Determine whether this is a pointer past the end of the complete object referred to by the lvalue.
static unsigned getBaseIndex(const CXXRecordDecl *Derived, const CXXRecordDecl *Base)
Get the base index of the given base class within an APValue representing the given derived class.
static bool EvaluateFixedPoint(const Expr *E, APFixedPoint &Result, EvalInfo &Info)
Evaluate only a fixed point expression into an APResult.
void HandleComplexComplexMul(APFloat A, APFloat B, APFloat C, APFloat D, APFloat &ResR, APFloat &ResI)
static bool tryEvaluateBuiltinObjectSize(const Expr *E, unsigned Type, EvalInfo &Info, uint64_t &Size)
Tries to evaluate the __builtin_object_size for E. If successful, returns true and stores the result ...
static bool EvalPointerValueAsBool(const APValue &Value, bool &Result)
static bool handleVectorVectorBinOp(EvalInfo &Info, const BinaryOperator *E, BinaryOperatorKind Opcode, APValue &LHSValue, const APValue &RHSValue)
static const FunctionDecl * getVirtualOperatorDelete(QualType T)
static bool isDesignatorAtObjectEnd(const ASTContext &Ctx, const LValue &LVal)
Checks to see if the given LValue's Designator is at the end of the LValue's record layout....
static bool CheckArraySize(EvalInfo &Info, const ConstantArrayType *CAT, SourceLocation CallLoc={})
static bool EvaluateInPlace(APValue &Result, EvalInfo &Info, const LValue &This, const Expr *E, bool AllowNonLiteralTypes=false)
EvaluateInPlace - Evaluate an expression in-place in an APValue. In some cases, the in-place evaluati...
static bool handleFloatFloatBinOp(EvalInfo &Info, const BinaryOperator *E, APFloat &LHS, BinaryOperatorKind Opcode, const APFloat &RHS)
Perform the given binary floating-point operation, in-place, on LHS.
static std::optional< DynAlloc * > CheckDeleteKind(EvalInfo &Info, const Expr *E, const LValue &Pointer, DynAlloc::Kind DeallocKind)
Check that the given object is a suitable pointer to a heap allocation that still exists and is of th...
static bool EvaluateLValue(const Expr *E, LValue &Result, EvalInfo &Info, bool InvalidBaseOK=false)
Evaluate an expression as an lvalue. This can be legitimately called on expressions which are not glv...
static bool FastEvaluateAsRValue(const Expr *Exp, APValue &Result, const ASTContext &Ctx, bool &IsConst)
static bool HandleCovariantReturnAdjustment(EvalInfo &Info, const Expr *E, APValue &Result, ArrayRef< QualType > Path)
Perform the adjustment from a value returned by a virtual function to a value of the statically expec...
static EvalStmtResult EvaluateSwitch(StmtResult &Result, EvalInfo &Info, const SwitchStmt *SS)
Evaluate a switch statement.
static void expandStringLiteral(EvalInfo &Info, const StringLiteral *S, APValue &Result, QualType AllocType=QualType())
static bool EvaluateArgs(ArrayRef< const Expr * > Args, CallRef Call, EvalInfo &Info, const FunctionDecl *Callee, bool RightToLeft=false, LValue *ObjectArg=nullptr)
Evaluate the arguments to a function call.
static bool EvaluateAtomic(const Expr *E, const LValue *This, APValue &Result, EvalInfo &Info)
static bool getBytesReturnedByAllocSizeCall(const ASTContext &Ctx, const LValue &LVal, llvm::APInt &Result)
Convenience function. LVal's base must be a call to an alloc_size function.
static bool handleIntIntBinOp(EvalInfo &Info, const BinaryOperator *E, const APSInt &LHS, BinaryOperatorKind Opcode, APSInt RHS, APSInt &Result)
Perform the given binary integer operation.
static bool EvaluateInitForDeclOfReferenceType(EvalInfo &Info, const ValueDecl *D, const Expr *Init, LValue &Result, APValue &Val)
Evaluates the initializer of a reference.
static bool checkDynamicType(EvalInfo &Info, const Expr *E, const LValue &This, AccessKinds AK, bool Polymorphic)
Check that we can access the notional vptr of an object / determine its dynamic type.
static bool HandleFloatToIntCast(EvalInfo &Info, const Expr *E, QualType SrcType, const APFloat &Value, QualType DestType, APSInt &Result)
static bool getAlignmentArgument(const Expr *E, QualType ForType, EvalInfo &Info, APSInt &Alignment)
Evaluate the value of the alignment argument to __builtin_align_{up,down}, __builtin_is_aligned and _...
static bool CheckFullyInitialized(EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value)
Check that this evaluated value is fully-initialized and can be loaded by an lvalue-to-rvalue convers...
static SubobjectHandler::result_type findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, const SubobjectDesignator &Sub, SubobjectHandler &handler)
Find the designated sub-object of an rvalue.
static bool determineEndOffset(EvalInfo &Info, SourceLocation ExprLoc, unsigned Type, const LValue &LVal, CharUnits &EndOffset)
Helper for tryEvaluateBuiltinObjectSize – Given an LValue, this will determine how many bytes exist f...
static bool convertUnsignedAPIntToCharUnits(const llvm::APInt &Int, CharUnits &Result)
Converts the given APInt to CharUnits, assuming the APInt is unsigned. Fails if the conversion would ...
static bool EvaluateCallArg(const ParmVarDecl *PVD, const Expr *Arg, CallRef Call, EvalInfo &Info, bool NonNull=false, APValue **EvaluatedArg=nullptr)
llvm::SmallPtrSet< const MaterializeTemporaryExpr *, 8 > CheckedTemporaries
Materialized temporaries that we've already checked to determine if they're initializsed by a constan...
GCCTypeClass EvaluateBuiltinClassifyType(QualType T, const LangOptions &LangOpts)
EvaluateBuiltinClassifyType - Evaluate __builtin_classify_type the same way as GCC.
static bool EvaluateDependentExpr(const Expr *E, EvalInfo &Info)
static bool MaybeEvaluateDeferredVarDeclInit(EvalInfo &Info, const VarDecl *VD)
static APSInt HandleIntToIntCast(EvalInfo &Info, const Expr *E, QualType DestType, QualType SrcType, const APSInt &Value)
static std::optional< APValue > handleVectorUnaryOperator(ASTContext &Ctx, QualType ResultTy, UnaryOperatorKind Op, APValue Elt)
static bool lifetimeStartedInEvaluation(EvalInfo &Info, APValue::LValueBase Base, bool MutableSubobject=false)
static bool isOneByteCharacterType(QualType T)
static bool HandleLambdaCapture(EvalInfo &Info, const Expr *E, LValue &Result, const CXXMethodDecl *MD, const FieldDecl *FD, bool LValueToRValueConversion)
Get an lvalue to a field of a lambda's closure type.
static bool EvaluateCond(EvalInfo &Info, const VarDecl *CondDecl, const Expr *Cond, bool &Result)
Evaluate a condition (either a variable declaration or an expression).
static bool EvaluateAsFixedPoint(const Expr *E, Expr::EvalResult &ExprResult, const ASTContext &Ctx, Expr::SideEffectsKind AllowSideEffects, EvalInfo &Info)
static bool EvaluateAsRValue(EvalInfo &Info, const Expr *E, APValue &Result)
EvaluateAsRValue - Try to evaluate this expression, performing an implicit lvalue-to-rvalue cast if i...
static bool diagnoseMutableFields(EvalInfo &Info, const Expr *E, AccessKinds AK, QualType T)
Diagnose an attempt to read from any unreadable field within the specified type, which might be a cla...
static ICEDiag CheckICE(const Expr *E, const ASTContext &Ctx)
static bool CheckConstexprFunction(EvalInfo &Info, SourceLocation CallLoc, const FunctionDecl *Declaration, const FunctionDecl *Definition, const Stmt *Body)
CheckConstexprFunction - Check that a function can be called in a constant expression.
static bool EvaluateDestruction(const ASTContext &Ctx, APValue::LValueBase Base, APValue DestroyedValue, QualType Type, SourceLocation Loc, Expr::EvalStatus &EStatus, bool IsConstantDestruction)
static EvalStmtResult EvaluateStmt(StmtResult &Result, EvalInfo &Info, const Stmt *S, const SwitchCase *SC=nullptr)
static bool EvaluateArrayNewInitList(EvalInfo &Info, LValue &This, APValue &Result, const InitListExpr *ILE, QualType AllocType)
static bool HasSameBase(const LValue &A, const LValue &B)
static bool CheckLocalVariableDeclaration(EvalInfo &Info, const VarDecl *VD)
static bool HandleLValueDirectBase(EvalInfo &Info, const Expr *E, LValue &Obj, const CXXRecordDecl *Derived, const CXXRecordDecl *Base, const ASTRecordLayout *RL=nullptr)
static bool IsGlobalLValue(APValue::LValueBase B)
static llvm::RoundingMode getActiveRoundingMode(EvalInfo &Info, const Expr *E)
Get rounding mode to use in evaluation of the specified expression.
static QualType getObjectType(APValue::LValueBase B)
Retrieves the "underlying object type" of the given expression, as used by __builtin_object_size.
static bool handleCompareOpForVectorHelper(const APTy &LHSValue, BinaryOperatorKind Opcode, const APTy &RHSValue, APInt &Result)
static bool Evaluate(APValue &Result, EvalInfo &Info, const Expr *E)
static bool isReadByLvalueToRvalueConversion(const CXXRecordDecl *RD)
Determine whether a type would actually be read by an lvalue-to-rvalue conversion.
static void negateAsSigned(APSInt &Int)
Negate an APSInt in place, converting it to a signed form if necessary, and preserving its value (by ...
static bool HandleFunctionCall(SourceLocation CallLoc, const FunctionDecl *Callee, const LValue *ObjectArg, const Expr *E, ArrayRef< const Expr * > Args, CallRef Call, const Stmt *Body, EvalInfo &Info, APValue &Result, const LValue *ResultSlot)
Evaluate a function call.
static bool isUserWritingOffTheEnd(const ASTContext &Ctx, const LValue &LVal)
Attempts to detect a user writing into a piece of memory that's impossible to figure out the size of ...
static bool GetLValueBaseAsString(const EvalInfo &Info, const LValue &LVal, LValueBaseString &AsString)
static bool HandleOperatorDeleteCall(EvalInfo &Info, const CallExpr *E)
static bool EvaluateIntegerOrLValue(const Expr *E, APValue &Result, EvalInfo &Info)
EvaluateIntegerOrLValue - Evaluate an rvalue integral-typed expression, and produce either the intege...
static bool HandleDynamicCast(EvalInfo &Info, const ExplicitCastExpr *E, LValue &Ptr)
Apply the given dynamic cast operation on the provided lvalue.
static bool HandleOperatorNewCall(EvalInfo &Info, const CallExpr *E, LValue &Result)
Perform a call to 'operator new' or to ‘__builtin_operator_new’.
static bool HandleFloatToFloatCast(EvalInfo &Info, const Expr *E, QualType SrcType, QualType DestType, APFloat &Result)
static bool MaybeHandleUnionActiveMemberChange(EvalInfo &Info, const Expr *LHSExpr, const LValue &LHS)
Handle a builtin simple-assignment or a call to a trivial assignment operator whose left-hand side mi...
static bool isFormalAccess(AccessKinds AK)
Is this an access per the C++ definition?
static bool handleCompoundAssignment(EvalInfo &Info, const CompoundAssignOperator *E, const LValue &LVal, QualType LValType, QualType PromotedLValType, BinaryOperatorKind Opcode, const APValue &RVal)
Perform a compound assignment of LVal <op>= RVal.
static bool handleIncDec(EvalInfo &Info, const Expr *E, const LValue &LVal, QualType LValType, bool IsIncrement, APValue *Old)
Perform an increment or decrement on LVal.
static bool EvaluateVoid(const Expr *E, EvalInfo &Info)
static bool HandleDestruction(EvalInfo &Info, const Expr *E, const LValue &This, QualType ThisType)
Perform a destructor or pseudo-destructor call on the given object, which might in general not be a c...
static bool HandleDestructionImpl(EvalInfo &Info, SourceRange CallRange, const LValue &This, APValue &Value, QualType T)
static bool 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 evaluateString(State &Parent, const Expr *E, std::string &Result)
Evaluate.
bool evaluateStrlen(State &Parent, const Expr *E, uint64_t &Result)
Evalute.
void isPotentialConstantExprUnevaluated(State &Parent, const Expr *E, const FunctionDecl *FD)
bool isPotentialConstantExpr(State &Parent, const FunctionDecl *FD)
Checks if a function is a potential constant expression.
bool evaluateAsRValue(State &Parent, const Expr *E, APValue &Result)
Evaluates a toplevel expression as an rvalue.
bool evaluate(State &Parent, const Expr *E, APValue &Result, ConstantExprKind Kind)
Like evaluateAsRvalue(), but does no implicit lvalue-to-rvalue conversion.
Base class for stack frames, shared between VM and walker.
Interface for the VM to interact with the AST walker's context.
Defines the clang::TargetInfo interface.
bool computeOSLogBufferLayout(clang::ASTContext &Ctx, const clang::CallExpr *E, OSLogBufferLayout &layout)
static const FunctionDecl * getCallee(const CXXConstructExpr &D)
uint32_t Literal
Literals are represented as positive integers.
unsigned kind
All of the diagnostics that can be emitted by the frontend.
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)