56#include "llvm/ADT/APFixedPoint.h"
57#include "llvm/ADT/SmallBitVector.h"
58#include "llvm/ADT/StringExtras.h"
59#include "llvm/Support/Debug.h"
60#include "llvm/Support/SaveAndRestore.h"
61#include "llvm/Support/SipHash.h"
62#include "llvm/Support/TimeProfiler.h"
63#include "llvm/Support/raw_ostream.h"
68#define DEBUG_TYPE "exprconstant"
71using llvm::APFixedPoint;
75using llvm::FixedPointSemantics;
82 using SourceLocExprScopeGuard =
92 return dyn_cast_or_null<FieldDecl>(
E.getAsBaseOrMember().getPointer());
97 return dyn_cast_or_null<CXXRecordDecl>(
E.getAsBaseOrMember().getPointer());
102 return E.getAsBaseOrMember().getInt();
114 static const AllocSizeAttr *getAllocSizeAttr(
const CallExpr *CE) {
116 return DirectCallee->getAttr<AllocSizeAttr>();
118 return IndirectCallee->getAttr<AllocSizeAttr>();
126 static const CallExpr *tryUnwrapAllocSizeCall(
const Expr *
E) {
134 if (
const auto *FE = dyn_cast<FullExpr>(
E))
137 if (
const auto *Cast = dyn_cast<CastExpr>(
E))
138 E = Cast->getSubExpr()->IgnoreParens();
140 if (
const auto *CE = dyn_cast<CallExpr>(
E))
141 return getAllocSizeAttr(CE) ? CE :
nullptr;
148 const auto *
E =
Base.dyn_cast<
const Expr *>();
157 case ConstantExprKind::Normal:
158 case ConstantExprKind::ClassTemplateArgument:
159 case ConstantExprKind::ImmediateInvocation:
164 case ConstantExprKind::NonClassTemplateArgument:
167 llvm_unreachable(
"unknown ConstantExprKind");
172 case ConstantExprKind::Normal:
173 case ConstantExprKind::ImmediateInvocation:
176 case ConstantExprKind::ClassTemplateArgument:
177 case ConstantExprKind::NonClassTemplateArgument:
180 llvm_unreachable(
"unknown ConstantExprKind");
186 static const uint64_t AssumedSizeForUnsizedArray =
187 std::numeric_limits<uint64_t>::max() / 2;
197 bool &FirstEntryIsUnsizedArray) {
200 assert(!isBaseAnAllocSizeCall(
Base) &&
201 "Unsized arrays shouldn't appear here");
202 unsigned MostDerivedLength = 0;
205 for (
unsigned I = 0, N =
Path.size(); I != N; ++I) {
209 MostDerivedLength = I + 1;
212 if (
auto *CAT = dyn_cast<ConstantArrayType>(AT)) {
213 ArraySize = CAT->getZExtSize();
215 assert(I == 0 &&
"unexpected unsized array designator");
216 FirstEntryIsUnsizedArray =
true;
217 ArraySize = AssumedSizeForUnsizedArray;
223 MostDerivedLength = I + 1;
226 Type = VT->getElementType();
227 ArraySize = VT->getNumElements();
228 MostDerivedLength = I + 1;
231 Type = FD->getType();
233 MostDerivedLength = I + 1;
241 return MostDerivedLength;
245 struct SubobjectDesignator {
249 LLVM_PREFERRED_TYPE(
bool)
250 unsigned Invalid : 1;
253 LLVM_PREFERRED_TYPE(
bool)
254 unsigned IsOnePastTheEnd : 1;
257 LLVM_PREFERRED_TYPE(
bool)
258 unsigned FirstEntryIsAnUnsizedArray : 1;
261 LLVM_PREFERRED_TYPE(
bool)
262 unsigned MostDerivedIsArrayElement : 1;
266 unsigned MostDerivedPathLength : 28;
275 uint64_t MostDerivedArraySize;
284 SubobjectDesignator() : Invalid(
true) {}
287 : Invalid(
false), IsOnePastTheEnd(
false),
288 FirstEntryIsAnUnsizedArray(
false), MostDerivedIsArrayElement(
false),
289 MostDerivedPathLength(0), MostDerivedArraySize(0),
290 MostDerivedType(
T) {}
293 : Invalid(!
V.isLValue() || !
V.hasLValuePath()), IsOnePastTheEnd(
false),
294 FirstEntryIsAnUnsizedArray(
false), MostDerivedIsArrayElement(
false),
295 MostDerivedPathLength(0), MostDerivedArraySize(0) {
296 assert(
V.isLValue() &&
"Non-LValue used to make an LValue designator?");
298 IsOnePastTheEnd =
V.isLValueOnePastTheEnd();
300 Entries.insert(Entries.end(), VEntries.begin(), VEntries.end());
301 if (
V.getLValueBase()) {
302 bool IsArray =
false;
303 bool FirstIsUnsizedArray =
false;
304 MostDerivedPathLength = findMostDerivedSubobject(
305 Ctx,
V.getLValueBase(),
V.getLValuePath(), MostDerivedArraySize,
306 MostDerivedType, IsArray, FirstIsUnsizedArray);
307 MostDerivedIsArrayElement = IsArray;
308 FirstEntryIsAnUnsizedArray = FirstIsUnsizedArray;
314 unsigned NewLength) {
318 assert(
Base &&
"cannot truncate path for null pointer");
319 assert(NewLength <= Entries.size() &&
"not a truncation");
321 if (NewLength == Entries.size())
323 Entries.resize(NewLength);
325 bool IsArray =
false;
326 bool FirstIsUnsizedArray =
false;
327 MostDerivedPathLength = findMostDerivedSubobject(
328 Ctx,
Base, Entries, MostDerivedArraySize, MostDerivedType, IsArray,
329 FirstIsUnsizedArray);
330 MostDerivedIsArrayElement = IsArray;
331 FirstEntryIsAnUnsizedArray = FirstIsUnsizedArray;
341 bool isMostDerivedAnUnsizedArray()
const {
342 assert(!Invalid &&
"Calling this makes no sense on invalid designators");
343 return Entries.size() == 1 && FirstEntryIsAnUnsizedArray;
348 uint64_t getMostDerivedArraySize()
const {
349 assert(!isMostDerivedAnUnsizedArray() &&
"Unsized array has no size");
350 return MostDerivedArraySize;
354 bool isOnePastTheEnd()
const {
358 if (!isMostDerivedAnUnsizedArray() && MostDerivedIsArrayElement &&
359 Entries[MostDerivedPathLength - 1].getAsArrayIndex() ==
360 MostDerivedArraySize)
368 std::pair<uint64_t, uint64_t> validIndexAdjustments() {
369 if (Invalid || isMostDerivedAnUnsizedArray())
375 bool IsArray = MostDerivedPathLength == Entries.size() &&
376 MostDerivedIsArrayElement;
377 uint64_t ArrayIndex = IsArray ? Entries.back().getAsArrayIndex()
378 : (uint64_t)IsOnePastTheEnd;
380 IsArray ? getMostDerivedArraySize() : (uint64_t)1;
381 return {ArrayIndex, ArraySize - ArrayIndex};
385 bool isValidSubobject()
const {
388 return !isOnePastTheEnd();
396 assert(!Invalid &&
"invalid designator has no subobject type");
397 return MostDerivedPathLength == Entries.size()
408 MostDerivedIsArrayElement =
true;
410 MostDerivedPathLength = Entries.size();
414 void addUnsizedArrayUnchecked(
QualType ElemTy) {
417 MostDerivedType = ElemTy;
418 MostDerivedIsArrayElement =
true;
422 MostDerivedArraySize = AssumedSizeForUnsizedArray;
423 MostDerivedPathLength = Entries.size();
427 void addDeclUnchecked(
const Decl *
D,
bool Virtual =
false) {
431 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(
D)) {
432 MostDerivedType = FD->getType();
433 MostDerivedIsArrayElement =
false;
434 MostDerivedArraySize = 0;
435 MostDerivedPathLength = Entries.size();
439 void addComplexUnchecked(
QualType EltTy,
bool Imag) {
444 MostDerivedType = EltTy;
445 MostDerivedIsArrayElement =
true;
446 MostDerivedArraySize = 2;
447 MostDerivedPathLength = Entries.size();
450 void addVectorElementUnchecked(
QualType EltTy, uint64_t Size,
453 MostDerivedType = EltTy;
454 MostDerivedPathLength = Entries.size();
455 MostDerivedArraySize = 0;
456 MostDerivedIsArrayElement =
false;
459 void diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info,
const Expr *
E);
460 void diagnosePointerArithmetic(EvalInfo &Info,
const Expr *
E,
463 void adjustIndex(EvalInfo &Info,
const Expr *
E,
APSInt N) {
464 if (Invalid || !N)
return;
465 uint64_t TruncatedN = N.extOrTrunc(64).getZExtValue();
466 if (isMostDerivedAnUnsizedArray()) {
467 diagnoseUnsizedArrayPointerArithmetic(Info,
E);
472 Entries.back().getAsArrayIndex() + TruncatedN);
479 bool IsArray = MostDerivedPathLength == Entries.size() &&
480 MostDerivedIsArrayElement;
481 uint64_t ArrayIndex = IsArray ? Entries.back().getAsArrayIndex()
482 : (uint64_t)IsOnePastTheEnd;
484 IsArray ? getMostDerivedArraySize() : (uint64_t)1;
486 if (N < -(int64_t)ArrayIndex || N > ArraySize - ArrayIndex) {
489 N = N.extend(std::max<unsigned>(N.getBitWidth() + 1, 65));
490 (llvm::APInt&)N += ArrayIndex;
491 assert(N.ugt(ArraySize) &&
"bounds check failed for in-bounds index");
492 diagnosePointerArithmetic(Info,
E, N);
497 ArrayIndex += TruncatedN;
498 assert(ArrayIndex <= ArraySize &&
499 "bounds check succeeded for out-of-bounds index");
504 IsOnePastTheEnd = (ArrayIndex != 0);
509 enum class ScopeKind {
517 CallRef() : OrigCallee(), CallIndex(0), Version() {}
518 CallRef(
const FunctionDecl *Callee,
unsigned CallIndex,
unsigned Version)
519 : OrigCallee(Callee), CallIndex(CallIndex), Version(Version) {}
521 explicit operator bool()
const {
return OrigCallee; }
547 CallStackFrame *Caller;
569 typedef std::pair<const void *, unsigned> MapKeyTy;
570 typedef std::map<MapKeyTy, APValue>
MapTy;
582 unsigned CurTempVersion = TempVersionStack.back();
584 unsigned getTempVersion()
const {
return TempVersionStack.back(); }
586 void pushTempVersion() {
587 TempVersionStack.push_back(++CurTempVersion);
590 void popTempVersion() {
591 TempVersionStack.pop_back();
595 return {Callee, Index, ++CurTempVersion};
606 llvm::DenseMap<const ValueDecl *, FieldDecl *> LambdaCaptureFields;
607 FieldDecl *LambdaThisCaptureField =
nullptr;
609 CallStackFrame(EvalInfo &Info,
SourceRange CallRange,
615 APValue *getTemporary(
const void *Key,
unsigned Version) {
616 MapKeyTy KV(Key, Version);
617 auto LB = Temporaries.lower_bound(KV);
618 if (LB != Temporaries.end() && LB->first == KV)
624 APValue *getCurrentTemporary(
const void *Key) {
625 auto UB = Temporaries.upper_bound(MapKeyTy(Key,
UINT_MAX));
626 if (UB != Temporaries.begin() && std::prev(UB)->first.first == Key)
627 return &std::prev(UB)->second;
632 unsigned getCurrentTemporaryVersion(
const void *Key)
const {
633 auto UB = Temporaries.upper_bound(MapKeyTy(Key,
UINT_MAX));
634 if (UB != Temporaries.begin() && std::prev(UB)->first.first == Key)
635 return std::prev(UB)->first.second;
643 template<
typename KeyT>
645 ScopeKind
Scope, LValue &LV);
650 void describe(llvm::raw_ostream &OS)
const override;
652 Frame *getCaller()
const override {
return Caller; }
653 SourceRange getCallRange()
const override {
return CallRange; }
654 const FunctionDecl *getCallee()
const override {
return Callee; }
656 bool isStdFunction()
const {
657 for (
const DeclContext *DC = Callee; DC; DC = DC->getParent())
658 if (DC->isStdNamespace())
665 bool CanEvalMSConstexpr =
false;
673 class ThisOverrideRAII {
675 ThisOverrideRAII(CallStackFrame &Frame,
const LValue *NewThis,
bool Enable)
676 : Frame(Frame), OldThis(Frame.This) {
678 Frame.This = NewThis;
680 ~ThisOverrideRAII() {
681 Frame.This = OldThis;
684 CallStackFrame &Frame;
685 const LValue *OldThis;
690 class ExprTimeTraceScope {
692 ExprTimeTraceScope(
const Expr *
E,
const ASTContext &Ctx, StringRef Name)
693 : TimeScope(Name, [
E, &Ctx] {
698 llvm::TimeTraceScope TimeScope;
703 struct MSConstexprContextRAII {
704 CallStackFrame &Frame;
706 explicit MSConstexprContextRAII(CallStackFrame &Frame,
bool Value)
707 : Frame(Frame), OldValue(Frame.CanEvalMSConstexpr) {
708 Frame.CanEvalMSConstexpr =
Value;
711 ~MSConstexprContextRAII() { Frame.CanEvalMSConstexpr = OldValue; }
716 const LValue &This,
QualType ThisType);
724 llvm::PointerIntPair<APValue*, 2, ScopeKind>
Value;
735 bool isDestroyedAtEndOf(ScopeKind K)
const {
736 return (
int)
Value.getInt() >= (
int)K;
738 bool endLifetime(EvalInfo &Info,
bool RunDestructors) {
739 if (RunDestructors) {
742 Loc = VD->getLocation();
751 bool hasSideEffect() {
752 return T.isDestructedType();
757 struct ObjectUnderConstruction {
760 friend bool operator==(
const ObjectUnderConstruction &LHS,
761 const ObjectUnderConstruction &RHS) {
762 return LHS.Base == RHS.Base && LHS.Path == RHS.Path;
764 friend llvm::hash_code
hash_value(
const ObjectUnderConstruction &Obj) {
765 return llvm::hash_combine(Obj.Base, Obj.Path);
768 enum class ConstructionPhase {
779template<>
struct DenseMapInfo<ObjectUnderConstruction> {
780 using Base = DenseMapInfo<APValue::LValueBase>;
782 return {Base::getEmptyKey(), {}}; }
784 return {Base::getTombstoneKey(), {}};
789 static bool isEqual(
const ObjectUnderConstruction &LHS,
790 const ObjectUnderConstruction &RHS) {
804 const Expr *AllocExpr =
nullptr;
815 if (
auto *NE = dyn_cast<CXXNewExpr>(AllocExpr))
816 return NE->isArray() ? ArrayNew : New;
817 assert(isa<CallExpr>(AllocExpr));
822 struct DynAllocOrder {
850 CallStackFrame *CurrentCall;
853 unsigned CallStackDepth;
856 unsigned NextCallIndex;
865 bool EnableNewConstInterp;
869 CallStackFrame BottomFrame;
879 enum class EvaluatingDeclKind {
886 EvaluatingDeclKind IsEvaluatingDecl = EvaluatingDeclKind::None;
893 llvm::DenseMap<ObjectUnderConstruction, ConstructionPhase>
894 ObjectsUnderConstruction;
899 std::map<DynamicAllocLValue, DynAlloc, DynAllocOrder> HeapAllocs;
902 unsigned NumHeapAllocs = 0;
904 struct EvaluatingConstructorRAII {
906 ObjectUnderConstruction
Object;
908 EvaluatingConstructorRAII(EvalInfo &EI, ObjectUnderConstruction Object,
912 EI.ObjectsUnderConstruction
913 .insert({
Object, HasBases ? ConstructionPhase::Bases
914 : ConstructionPhase::AfterBases})
917 void finishedConstructingBases() {
918 EI.ObjectsUnderConstruction[
Object] = ConstructionPhase::AfterBases;
920 void finishedConstructingFields() {
921 EI.ObjectsUnderConstruction[
Object] = ConstructionPhase::AfterFields;
923 ~EvaluatingConstructorRAII() {
924 if (DidInsert) EI.ObjectsUnderConstruction.erase(Object);
928 struct EvaluatingDestructorRAII {
930 ObjectUnderConstruction
Object;
932 EvaluatingDestructorRAII(EvalInfo &EI, ObjectUnderConstruction Object)
934 DidInsert = EI.ObjectsUnderConstruction
935 .insert({
Object, ConstructionPhase::Destroying})
938 void startedDestroyingBases() {
939 EI.ObjectsUnderConstruction[
Object] =
940 ConstructionPhase::DestroyingBases;
942 ~EvaluatingDestructorRAII() {
944 EI.ObjectsUnderConstruction.erase(Object);
951 return ObjectsUnderConstruction.lookup({
Base,
Path});
956 unsigned SpeculativeEvaluationDepth = 0;
964 bool HasActiveDiagnostic;
968 bool HasFoldFailureDiagnostic;
973 bool CheckingPotentialConstantExpression =
false;
981 bool CheckingForUndefinedBehavior =
false;
983 enum EvaluationMode {
986 EM_ConstantExpression,
993 EM_ConstantExpressionUnevaluated,
1001 EM_IgnoreSideEffects,
1006 bool checkingPotentialConstantExpression()
const override {
1007 return CheckingPotentialConstantExpression;
1013 bool checkingForUndefinedBehavior()
const override {
1014 return CheckingForUndefinedBehavior;
1018 : Ctx(const_cast<
ASTContext &>(
C)), EvalStatus(S), CurrentCall(nullptr),
1019 CallStackDepth(0), NextCallIndex(1),
1020 StepsLeft(
C.getLangOpts().ConstexprStepLimit),
1021 EnableNewConstInterp(
C.getLangOpts().EnableNewConstInterp),
1024 nullptr, CallRef()),
1025 EvaluatingDecl((const
ValueDecl *)nullptr),
1026 EvaluatingDeclValue(nullptr), HasActiveDiagnostic(
false),
1027 HasFoldFailureDiagnostic(
false), EvalMode(Mode) {}
1033 ASTContext &getCtx()
const override {
return Ctx; }
1036 EvaluatingDeclKind EDK = EvaluatingDeclKind::Ctor) {
1037 EvaluatingDecl =
Base;
1038 IsEvaluatingDecl = EDK;
1039 EvaluatingDeclValue = &
Value;
1045 if (checkingPotentialConstantExpression() && CallStackDepth > 1)
1047 if (NextCallIndex == 0) {
1049 FFDiag(
Loc, diag::note_constexpr_call_limit_exceeded);
1052 if (CallStackDepth <= getLangOpts().ConstexprCallDepth)
1054 FFDiag(
Loc, diag::note_constexpr_depth_limit_exceeded)
1055 << getLangOpts().ConstexprCallDepth;
1060 uint64_t ElemCount,
bool Diag) {
1066 ElemCount >
uint64_t(std::numeric_limits<unsigned>::max())) {
1068 FFDiag(
Loc, diag::note_constexpr_new_too_large) << ElemCount;
1078 if (ElemCount > Limit) {
1080 FFDiag(
Loc, diag::note_constexpr_new_exceeds_limits)
1081 << ElemCount << Limit;
1087 std::pair<CallStackFrame *, unsigned>
1088 getCallFrameAndDepth(
unsigned CallIndex) {
1089 assert(CallIndex &&
"no call index in getCallFrameAndDepth");
1092 unsigned Depth = CallStackDepth;
1093 CallStackFrame *Frame = CurrentCall;
1094 while (Frame->Index > CallIndex) {
1095 Frame = Frame->Caller;
1098 if (Frame->Index == CallIndex)
1099 return {Frame, Depth};
1100 return {
nullptr, 0};
1103 bool nextStep(
const Stmt *S) {
1105 FFDiag(S->getBeginLoc(), diag::note_constexpr_step_limit_exceeded);
1115 std::optional<DynAlloc *> Result;
1116 auto It = HeapAllocs.find(DA);
1117 if (It != HeapAllocs.end())
1118 Result = &It->second;
1124 CallStackFrame *Frame = getCallFrameAndDepth(
Call.CallIndex).first;
1125 return Frame ? Frame->getTemporary(
Call.getOrigParam(PVD),
Call.Version)
1130 struct StdAllocatorCaller {
1131 unsigned FrameIndex;
1133 explicit operator bool()
const {
return FrameIndex != 0; };
1136 StdAllocatorCaller getStdAllocatorCaller(StringRef FnName)
const {
1137 for (
const CallStackFrame *
Call = CurrentCall;
Call != &BottomFrame;
1139 const auto *MD = dyn_cast_or_null<CXXMethodDecl>(
Call->Callee);
1143 if (!FnII || !FnII->
isStr(FnName))
1147 dyn_cast<ClassTemplateSpecializationDecl>(MD->getParent());
1153 if (CTSD->isInStdNamespace() && ClassII &&
1154 ClassII->
isStr(
"allocator") && TAL.
size() >= 1 &&
1156 return {
Call->Index, TAL[0].getAsType()};
1162 void performLifetimeExtension() {
1164 llvm::erase_if(CleanupStack, [](Cleanup &
C) {
1165 return !
C.isDestroyedAtEndOf(ScopeKind::FullExpression);
1172 bool discardCleanups() {
1173 for (Cleanup &
C : CleanupStack) {
1174 if (
C.hasSideEffect() && !noteSideEffect()) {
1175 CleanupStack.clear();
1179 CleanupStack.clear();
1184 interp::Frame *getCurrentFrame()
override {
return CurrentCall; }
1185 const interp::Frame *getBottomFrame()
const override {
return &BottomFrame; }
1187 bool hasActiveDiagnostic()
override {
return HasActiveDiagnostic; }
1188 void setActiveDiagnostic(
bool Flag)
override { HasActiveDiagnostic = Flag; }
1190 void setFoldFailureDiagnostic(
bool Flag)
override {
1191 HasFoldFailureDiagnostic = Flag;
1202 bool hasPriorDiagnostic()
override {
1203 if (!EvalStatus.
Diag->empty()) {
1205 case EM_ConstantFold:
1206 case EM_IgnoreSideEffects:
1207 if (!HasFoldFailureDiagnostic)
1211 case EM_ConstantExpression:
1212 case EM_ConstantExpressionUnevaluated:
1213 setActiveDiagnostic(
false);
1220 unsigned getCallStackDepth()
override {
return CallStackDepth; }
1225 bool keepEvaluatingAfterSideEffect() {
1227 case EM_IgnoreSideEffects:
1230 case EM_ConstantExpression:
1231 case EM_ConstantExpressionUnevaluated:
1232 case EM_ConstantFold:
1235 return checkingPotentialConstantExpression() ||
1236 checkingForUndefinedBehavior();
1238 llvm_unreachable(
"Missed EvalMode case");
1243 bool noteSideEffect() {
1245 return keepEvaluatingAfterSideEffect();
1249 bool keepEvaluatingAfterUndefinedBehavior() {
1251 case EM_IgnoreSideEffects:
1252 case EM_ConstantFold:
1255 case EM_ConstantExpression:
1256 case EM_ConstantExpressionUnevaluated:
1257 return checkingForUndefinedBehavior();
1259 llvm_unreachable(
"Missed EvalMode case");
1265 bool noteUndefinedBehavior()
override {
1267 return keepEvaluatingAfterUndefinedBehavior();
1272 bool keepEvaluatingAfterFailure()
const override {
1277 case EM_ConstantExpression:
1278 case EM_ConstantExpressionUnevaluated:
1279 case EM_ConstantFold:
1280 case EM_IgnoreSideEffects:
1281 return checkingPotentialConstantExpression() ||
1282 checkingForUndefinedBehavior();
1284 llvm_unreachable(
"Missed EvalMode case");
1297 [[nodiscard]]
bool noteFailure() {
1305 bool KeepGoing = keepEvaluatingAfterFailure();
1310 class ArrayInitLoopIndex {
1315 ArrayInitLoopIndex(EvalInfo &Info)
1316 : Info(Info), OuterIndex(Info.ArrayInitIndex) {
1317 Info.ArrayInitIndex = 0;
1319 ~ArrayInitLoopIndex() { Info.ArrayInitIndex = OuterIndex; }
1321 operator uint64_t&() {
return Info.ArrayInitIndex; }
1326 struct FoldConstant {
1329 bool HadNoPriorDiags;
1330 EvalInfo::EvaluationMode OldMode;
1332 explicit FoldConstant(EvalInfo &Info,
bool Enabled)
1335 HadNoPriorDiags(Info.EvalStatus.
Diag &&
1336 Info.EvalStatus.
Diag->empty() &&
1337 !Info.EvalStatus.HasSideEffects),
1338 OldMode(Info.EvalMode) {
1340 Info.EvalMode = EvalInfo::EM_ConstantFold;
1342 void keepDiagnostics() { Enabled =
false; }
1344 if (Enabled && HadNoPriorDiags && !Info.EvalStatus.Diag->empty() &&
1345 !Info.EvalStatus.HasSideEffects)
1346 Info.EvalStatus.Diag->clear();
1347 Info.EvalMode = OldMode;
1353 struct IgnoreSideEffectsRAII {
1355 EvalInfo::EvaluationMode OldMode;
1356 explicit IgnoreSideEffectsRAII(EvalInfo &Info)
1357 : Info(Info), OldMode(Info.EvalMode) {
1358 Info.EvalMode = EvalInfo::EM_IgnoreSideEffects;
1361 ~IgnoreSideEffectsRAII() { Info.EvalMode = OldMode; }
1366 class SpeculativeEvaluationRAII {
1367 EvalInfo *Info =
nullptr;
1369 unsigned OldSpeculativeEvaluationDepth = 0;
1371 void moveFromAndCancel(SpeculativeEvaluationRAII &&
Other) {
1373 OldStatus =
Other.OldStatus;
1374 OldSpeculativeEvaluationDepth =
Other.OldSpeculativeEvaluationDepth;
1375 Other.Info =
nullptr;
1378 void maybeRestoreState() {
1382 Info->EvalStatus = OldStatus;
1383 Info->SpeculativeEvaluationDepth = OldSpeculativeEvaluationDepth;
1387 SpeculativeEvaluationRAII() =
default;
1389 SpeculativeEvaluationRAII(
1391 : Info(&Info), OldStatus(Info.EvalStatus),
1392 OldSpeculativeEvaluationDepth(Info.SpeculativeEvaluationDepth) {
1393 Info.EvalStatus.Diag = NewDiag;
1394 Info.SpeculativeEvaluationDepth = Info.CallStackDepth + 1;
1397 SpeculativeEvaluationRAII(
const SpeculativeEvaluationRAII &
Other) =
delete;
1398 SpeculativeEvaluationRAII(SpeculativeEvaluationRAII &&
Other) {
1399 moveFromAndCancel(std::move(
Other));
1402 SpeculativeEvaluationRAII &operator=(SpeculativeEvaluationRAII &&
Other) {
1403 maybeRestoreState();
1404 moveFromAndCancel(std::move(
Other));
1408 ~SpeculativeEvaluationRAII() { maybeRestoreState(); }
1413 template<ScopeKind Kind>
1416 unsigned OldStackSize;
1418 ScopeRAII(EvalInfo &Info)
1419 : Info(Info), OldStackSize(Info.CleanupStack.size()) {
1422 Info.CurrentCall->pushTempVersion();
1424 bool destroy(
bool RunDestructors =
true) {
1425 bool OK =
cleanup(Info, RunDestructors, OldStackSize);
1430 if (OldStackSize != -1U)
1434 Info.CurrentCall->popTempVersion();
1437 static bool cleanup(EvalInfo &Info,
bool RunDestructors,
1438 unsigned OldStackSize) {
1439 assert(OldStackSize <= Info.CleanupStack.size() &&
1440 "running cleanups out of order?");
1445 for (
unsigned I = Info.CleanupStack.size(); I > OldStackSize; --I) {
1446 if (Info.CleanupStack[I - 1].isDestroyedAtEndOf(Kind)) {
1447 if (!Info.CleanupStack[I - 1].endLifetime(Info, RunDestructors)) {
1455 auto NewEnd = Info.CleanupStack.begin() + OldStackSize;
1456 if (Kind != ScopeKind::Block)
1458 std::remove_if(NewEnd, Info.CleanupStack.end(), [](Cleanup &
C) {
1459 return C.isDestroyedAtEndOf(Kind);
1461 Info.CleanupStack.erase(NewEnd, Info.CleanupStack.end());
1465 typedef ScopeRAII<ScopeKind::Block> BlockScopeRAII;
1466 typedef ScopeRAII<ScopeKind::FullExpression> FullExpressionRAII;
1467 typedef ScopeRAII<ScopeKind::Call> CallScopeRAII;
1470bool SubobjectDesignator::checkSubobject(EvalInfo &Info,
const Expr *
E,
1474 if (isOnePastTheEnd()) {
1475 Info.CCEDiag(
E, diag::note_constexpr_past_end_subobject)
1486void SubobjectDesignator::diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info,
1488 Info.CCEDiag(
E, diag::note_constexpr_unsized_array_indexed);
1493void SubobjectDesignator::diagnosePointerArithmetic(EvalInfo &Info,
1498 if (MostDerivedPathLength == Entries.size() && MostDerivedIsArrayElement)
1499 Info.CCEDiag(
E, diag::note_constexpr_array_index)
1501 <<
static_cast<unsigned>(getMostDerivedArraySize());
1503 Info.CCEDiag(
E, diag::note_constexpr_array_index)
1508CallStackFrame::CallStackFrame(EvalInfo &Info,
SourceRange CallRange,
1513 Index(Info.NextCallIndex++) {
1514 Info.CurrentCall =
this;
1515 ++Info.CallStackDepth;
1518CallStackFrame::~CallStackFrame() {
1519 assert(Info.CurrentCall ==
this &&
"calls retired out of order");
1520 --Info.CallStackDepth;
1521 Info.CurrentCall = Caller;
1543 llvm_unreachable(
"unknown access kind");
1577 llvm_unreachable(
"unknown access kind");
1581 struct ComplexValue {
1589 ComplexValue() : FloatReal(
APFloat::Bogus()), FloatImag(
APFloat::Bogus()) {}
1591 void makeComplexFloat() { IsInt =
false; }
1592 bool isComplexFloat()
const {
return !IsInt; }
1593 APFloat &getComplexFloatReal() {
return FloatReal; }
1594 APFloat &getComplexFloatImag() {
return FloatImag; }
1596 void makeComplexInt() { IsInt =
true; }
1597 bool isComplexInt()
const {
return IsInt; }
1598 APSInt &getComplexIntReal() {
return IntReal; }
1599 APSInt &getComplexIntImag() {
return IntImag; }
1602 if (isComplexFloat())
1608 assert(
v.isComplexFloat() ||
v.isComplexInt());
1609 if (
v.isComplexFloat()) {
1611 FloatReal =
v.getComplexFloatReal();
1612 FloatImag =
v.getComplexFloatImag();
1615 IntReal =
v.getComplexIntReal();
1616 IntImag =
v.getComplexIntImag();
1626 bool InvalidBase : 1;
1629 CharUnits &getLValueOffset() {
return Offset; }
1630 const CharUnits &getLValueOffset()
const {
return Offset; }
1631 SubobjectDesignator &getLValueDesignator() {
return Designator; }
1632 const SubobjectDesignator &getLValueDesignator()
const {
return Designator;}
1633 bool isNullPointer()
const {
return IsNullPtr;}
1635 unsigned getLValueCallIndex()
const {
return Base.getCallIndex(); }
1636 unsigned getLValueVersion()
const {
return Base.getVersion(); }
1642 assert(!InvalidBase &&
"APValues can't handle invalid LValue bases");
1648 assert(
V.isLValue() &&
"Setting LValue from a non-LValue?");
1649 Base =
V.getLValueBase();
1650 Offset =
V.getLValueOffset();
1651 InvalidBase =
false;
1653 IsNullPtr =
V.isNullPointer();
1660 const auto *
E = B.
get<
const Expr *>();
1661 assert((isa<MemberExpr>(
E) || tryUnwrapAllocSizeCall(
E)) &&
1662 "Unexpected type of invalid base");
1668 InvalidBase = BInvalid;
1669 Designator = SubobjectDesignator(getType(B));
1677 InvalidBase =
false;
1688 moveInto(Printable);
1695 template <
typename GenDiagType>
1696 bool checkNullPointerDiagnosingWith(
const GenDiagType &GenDiag) {
1708 bool checkNullPointer(EvalInfo &Info,
const Expr *
E,
1710 return checkNullPointerDiagnosingWith([&Info,
E, CSK] {
1711 Info.CCEDiag(
E, diag::note_constexpr_null_subobject) << CSK;
1715 bool checkNullPointerForFoldAccess(EvalInfo &Info,
const Expr *
E,
1717 return checkNullPointerDiagnosingWith([&Info,
E, AK] {
1718 Info.FFDiag(
E, diag::note_constexpr_access_null) << AK;
1729 void addDecl(EvalInfo &Info,
const Expr *
E,
1734 void addUnsizedArray(EvalInfo &Info,
const Expr *
E,
QualType ElemTy) {
1736 Info.CCEDiag(
E, diag::note_constexpr_unsupported_unsized_array);
1741 assert(getType(
Base)->isPointerType() || getType(
Base)->isArrayType());
1742 Designator.FirstEntryIsAnUnsizedArray =
true;
1750 void addComplex(EvalInfo &Info,
const Expr *
E,
QualType EltTy,
bool Imag) {
1754 void addVectorElement(EvalInfo &Info,
const Expr *
E,
QualType EltTy,
1755 uint64_t Size, uint64_t Idx) {
1757 Designator.addVectorElementUnchecked(EltTy, Size, Idx);
1759 void clearIsNullPointer() {
1762 void adjustOffsetAndIndex(EvalInfo &Info,
const Expr *
E,
1772 uint64_t Offset64 = Offset.getQuantity();
1774 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
1779 clearIsNullPointer();
1784 clearIsNullPointer();
1791 : DeclAndIsDerivedMember(
Decl,
false) {}
1796 return DeclAndIsDerivedMember.getPointer();
1799 bool isDerivedMember()
const {
1800 return DeclAndIsDerivedMember.getInt();
1804 return cast<CXXRecordDecl>(
1805 DeclAndIsDerivedMember.getPointer()->getDeclContext());
1812 assert(
V.isMemberPointer());
1813 DeclAndIsDerivedMember.setPointer(
V.getMemberPointerDecl());
1814 DeclAndIsDerivedMember.setInt(
V.isMemberPointerToDerivedMember());
1823 llvm::PointerIntPair<const ValueDecl*, 1, bool> DeclAndIsDerivedMember;
1831 assert(!
Path.empty());
1833 if (
Path.size() >= 2)
1837 if (
Expected->getCanonicalDecl() !=
Class->getCanonicalDecl()) {
1853 if (!isDerivedMember()) {
1854 Path.push_back(Derived);
1857 if (!castBack(Derived))
1860 DeclAndIsDerivedMember.setInt(
false);
1868 DeclAndIsDerivedMember.setInt(
true);
1869 if (isDerivedMember()) {
1873 return castBack(
Base);
1878 static bool operator==(
const MemberPtr &LHS,
const MemberPtr &RHS) {
1879 if (!LHS.getDecl() || !RHS.getDecl())
1880 return !LHS.getDecl() && !RHS.getDecl();
1881 if (LHS.getDecl()->getCanonicalDecl() != RHS.getDecl()->getCanonicalDecl())
1883 return LHS.Path == RHS.Path;
1889 const LValue &This,
const Expr *
E,
1890 bool AllowNonLiteralTypes =
false);
1892 bool InvalidBaseOK =
false);
1894 bool InvalidBaseOK =
false);
1908 std::string *StringResult =
nullptr);
1925 if (Int.isUnsigned() || Int.isMinSignedValue()) {
1926 Int = Int.extend(Int.getBitWidth() + 1);
1927 Int.setIsSigned(
true);
1932template<
typename KeyT>
1934 ScopeKind
Scope, LValue &LV) {
1935 unsigned Version = getTempVersion();
1944 assert(Args.CallIndex == Index &&
"creating parameter in wrong frame");
1950 return createLocal(
Base, PVD, PVD->
getType(), ScopeKind::Call);
1955 assert(
Base.getCallIndex() == Index &&
"lvalue for wrong frame");
1956 unsigned Version =
Base.getVersion();
1957 APValue &Result = Temporaries[MapKeyTy(Key, Version)];
1958 assert(Result.isAbsent() &&
"local created multiple times");
1964 if (Index <= Info.SpeculativeEvaluationDepth) {
1965 if (
T.isDestructedType())
1966 Info.noteSideEffect();
1968 Info.CleanupStack.push_back(Cleanup(&Result,
Base,
T,
Scope));
1975 FFDiag(
E, diag::note_constexpr_heap_alloc_limit_exceeded);
1981 auto Result = HeapAllocs.emplace(std::piecewise_construct,
1982 std::forward_as_tuple(DA), std::tuple<>());
1983 assert(Result.second &&
"reused a heap alloc index?");
1984 Result.first->second.AllocExpr =
E;
1985 return &Result.first->second.Value;
1989void CallStackFrame::describe(raw_ostream &Out)
const {
1990 unsigned ArgIndex = 0;
1992 isa<CXXMethodDecl>(Callee) && !isa<CXXConstructorDecl>(Callee) &&
1993 cast<CXXMethodDecl>(Callee)->isImplicitObjectMemberFunction();
1996 Callee->getNameForDiagnostic(Out, Info.Ctx.getPrintingPolicy(),
1999 if (This && IsMemberCall) {
2000 if (
const auto *MCE = dyn_cast_if_present<CXXMemberCallExpr>(
CallExpr)) {
2001 const Expr *
Object = MCE->getImplicitObjectArgument();
2002 Object->printPretty(Out,
nullptr, Info.Ctx.getPrintingPolicy(),
2004 if (
Object->getType()->isPointerType())
2008 }
else if (
const auto *OCE =
2009 dyn_cast_if_present<CXXOperatorCallExpr>(
CallExpr)) {
2010 OCE->getArg(0)->printPretty(Out,
nullptr,
2011 Info.Ctx.getPrintingPolicy(),
2016 This->moveInto(Val);
2019 Info.Ctx.getLValueReferenceType(
This->Designator.MostDerivedType));
2022 Callee->getNameForDiagnostic(Out, Info.Ctx.getPrintingPolicy(),
2024 IsMemberCall =
false;
2030 E =
Callee->param_end(); I !=
E; ++I, ++ArgIndex) {
2031 if (ArgIndex > (
unsigned)IsMemberCall)
2035 APValue *
V = Info.getParamSlot(Arguments, Param);
2037 V->printPretty(Out, Info.Ctx, Param->
getType());
2041 if (ArgIndex == 0 && IsMemberCall)
2042 Out <<
"->" << *
Callee <<
'(';
2056 return Info.noteSideEffect();
2062 unsigned Builtin =
E->getBuiltinCallee();
2063 return (Builtin == Builtin::BI__builtin___CFStringMakeConstantString ||
2064 Builtin == Builtin::BI__builtin___NSStringMakeConstantString ||
2065 Builtin == Builtin::BI__builtin_ptrauth_sign_constant ||
2066 Builtin == Builtin::BI__builtin_function_start);
2080 if (
const VarDecl *VD = dyn_cast<VarDecl>(
D))
2081 return VD->hasGlobalStorage();
2082 if (isa<TemplateParamObjectDecl>(
D))
2087 return isa<FunctionDecl, MSGuidDecl, UnnamedGlobalConstantDecl>(
D);
2097 case Expr::CompoundLiteralExprClass: {
2101 case Expr::MaterializeTemporaryExprClass:
2104 return cast<MaterializeTemporaryExpr>(
E)->getStorageDuration() ==
SD_Static;
2106 case Expr::StringLiteralClass:
2107 case Expr::PredefinedExprClass:
2108 case Expr::ObjCStringLiteralClass:
2109 case Expr::ObjCEncodeExprClass:
2111 case Expr::ObjCBoxedExprClass:
2112 return cast<ObjCBoxedExpr>(
E)->isExpressibleAsConstantInitializer();
2113 case Expr::CallExprClass:
2116 case Expr::AddrLabelExprClass:
2120 case Expr::BlockExprClass:
2121 return !cast<BlockExpr>(
E)->getBlockDecl()->hasCaptures();
2124 case Expr::SourceLocExprClass:
2126 case Expr::ImplicitValueInitExprClass:
2138 return LVal.Base.dyn_cast<
const ValueDecl*>();
2142 if (
Value.getLValueCallIndex())
2145 return E && !isa<MaterializeTemporaryExpr>(
E);
2155 if (isa_and_nonnull<VarDecl>(
Decl)) {
2165 if (!A.getLValueBase())
2166 return !B.getLValueBase();
2167 if (!B.getLValueBase())
2170 if (A.getLValueBase().getOpaqueValue() !=
2171 B.getLValueBase().getOpaqueValue())
2174 return A.getLValueCallIndex() == B.getLValueCallIndex() &&
2175 A.getLValueVersion() == B.getLValueVersion();
2179 assert(
Base &&
"no location for a null lvalue");
2185 if (
auto *PVD = dyn_cast_or_null<ParmVarDecl>(VD)) {
2187 for (CallStackFrame *F = Info.CurrentCall; F; F = F->Caller) {
2188 if (F->Arguments.CallIndex ==
Base.getCallIndex() &&
2189 F->Arguments.Version ==
Base.getVersion() && F->Callee &&
2190 Idx < F->Callee->getNumParams()) {
2191 VD = F->Callee->getParamDecl(Idx);
2198 Info.Note(VD->
getLocation(), diag::note_declared_at);
2200 Info.Note(
E->
getExprLoc(), diag::note_constexpr_temporary_here);
2203 if (std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA))
2204 Info.Note((*Alloc)->AllocExpr->getExprLoc(),
2205 diag::note_constexpr_dynamic_alloc_here);
2238 const SubobjectDesignator &
Designator = LVal.getLValueDesignator();
2246 if (isTemplateArgument(Kind)) {
2247 int InvalidBaseKind = -1;
2250 InvalidBaseKind = 0;
2251 else if (isa_and_nonnull<StringLiteral>(BaseE))
2252 InvalidBaseKind = 1;
2253 else if (isa_and_nonnull<MaterializeTemporaryExpr>(BaseE) ||
2254 isa_and_nonnull<LifetimeExtendedTemporaryDecl>(BaseVD))
2255 InvalidBaseKind = 2;
2256 else if (
auto *PE = dyn_cast_or_null<PredefinedExpr>(BaseE)) {
2257 InvalidBaseKind = 3;
2258 Ident = PE->getIdentKindName();
2261 if (InvalidBaseKind != -1) {
2262 Info.FFDiag(
Loc, diag::note_constexpr_invalid_template_arg)
2263 << IsReferenceType << !
Designator.Entries.empty() << InvalidBaseKind
2269 if (
auto *FD = dyn_cast_or_null<FunctionDecl>(BaseVD);
2270 FD && FD->isImmediateFunction()) {
2271 Info.FFDiag(
Loc, diag::note_consteval_address_accessible)
2273 Info.Note(FD->getLocation(), diag::note_declared_at);
2281 if (Info.getLangOpts().CPlusPlus11) {
2282 Info.FFDiag(
Loc, diag::note_constexpr_non_global, 1)
2283 << IsReferenceType << !
Designator.Entries.empty() << !!BaseVD
2285 auto *VarD = dyn_cast_or_null<VarDecl>(BaseVD);
2286 if (VarD && VarD->isConstexpr()) {
2292 Info.Note(VarD->getLocation(), diag::note_constexpr_not_static)
2304 assert((Info.checkingPotentialConstantExpression() ||
2305 LVal.getLValueCallIndex() == 0) &&
2306 "have call index for global lvalue");
2309 Info.FFDiag(
Loc, diag::note_constexpr_dynamic_alloc)
2310 << IsReferenceType << !
Designator.Entries.empty();
2316 if (
const VarDecl *Var = dyn_cast<const VarDecl>(BaseVD)) {
2318 if (Var->getTLSKind())
2324 if (!isForManglingOnly(Kind) && Var->hasAttr<DLLImportAttr>())
2330 if (Info.getCtx().getLangOpts().CUDA &&
2331 Info.getCtx().getLangOpts().CUDAIsDevice &&
2332 Info.getCtx().CUDAConstantEvalCtx.NoWrongSidedVars) {
2333 if ((!Var->hasAttr<CUDADeviceAttr>() &&
2334 !Var->hasAttr<CUDAConstantAttr>() &&
2335 !Var->getType()->isCUDADeviceBuiltinSurfaceType() &&
2336 !Var->getType()->isCUDADeviceBuiltinTextureType()) ||
2337 Var->hasAttr<HIPManagedAttr>())
2341 if (
const auto *FD = dyn_cast<const FunctionDecl>(BaseVD)) {
2352 if (Info.getLangOpts().CPlusPlus && !isForManglingOnly(Kind) &&
2353 FD->hasAttr<DLLImportAttr>())
2357 }
else if (
const auto *MTE =
2358 dyn_cast_or_null<MaterializeTemporaryExpr>(BaseE)) {
2359 if (CheckedTemps.insert(MTE).second) {
2362 Info.FFDiag(MTE->getExprLoc(),
2363 diag::note_constexpr_unsupported_temporary_nontrivial_dtor)
2368 APValue *
V = MTE->getOrCreateValue(
false);
2369 assert(
V &&
"evasluation result refers to uninitialised temporary");
2371 Info, MTE->getExprLoc(), TempType, *
V, Kind,
2372 nullptr, CheckedTemps))
2379 if (!IsReferenceType)
2391 Info.FFDiag(
Loc, diag::note_constexpr_past_end, 1)
2392 << !
Designator.Entries.empty() << !!BaseVD << BaseVD;
2407 const auto *FD = dyn_cast_or_null<CXXMethodDecl>(
Member);
2410 if (FD->isImmediateFunction()) {
2411 Info.FFDiag(
Loc, diag::note_consteval_address_accessible) << 0;
2412 Info.Note(FD->getLocation(), diag::note_declared_at);
2415 return isForManglingOnly(Kind) || FD->isVirtual() ||
2416 !FD->hasAttr<DLLImportAttr>();
2422 const LValue *This =
nullptr) {
2424 if (Info.getLangOpts().CPlusPlus23)
2443 if (This && Info.EvaluatingDecl == This->getLValueBase())
2447 if (Info.getLangOpts().CPlusPlus11)
2448 Info.FFDiag(
E, diag::note_constexpr_nonliteral)
2451 Info.FFDiag(
E, diag::note_invalid_subexpr_in_const_expr);
2462 if (SubobjectDecl) {
2463 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
2464 << 1 << SubobjectDecl;
2466 diag::note_constexpr_subobject_declared_here);
2468 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
2477 Type = AT->getValueType();
2482 if (
Value.isArray()) {
2484 for (
unsigned I = 0, N =
Value.getArrayInitializedElts(); I != N; ++I) {
2486 Value.getArrayInitializedElt(I), Kind,
2487 SubobjectDecl, CheckedTemps))
2490 if (!
Value.hasArrayFiller())
2493 Value.getArrayFiller(), Kind, SubobjectDecl,
2496 if (
Value.isUnion() &&
Value.getUnionField()) {
2499 Value.getUnionValue(), Kind,
Value.getUnionField(), CheckedTemps);
2501 if (
Value.isStruct()) {
2503 if (
const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {
2504 unsigned BaseIndex = 0;
2506 const APValue &BaseValue =
Value.getStructBase(BaseIndex);
2509 Info.FFDiag(TypeBeginLoc, diag::note_constexpr_uninitialized_base)
2510 << BS.getType() <<
SourceRange(TypeBeginLoc, BS.getEndLoc());
2520 for (
const auto *I : RD->
fields()) {
2521 if (I->isUnnamedBitField())
2525 Value.getStructField(I->getFieldIndex()), Kind,
2531 if (
Value.isLValue() &&
2532 CERK == CheckEvaluationResultKind::ConstantExpression) {
2534 LVal.setFrom(Info.Ctx,
Value);
2539 if (
Value.isMemberPointer() &&
2540 CERK == CheckEvaluationResultKind::ConstantExpression)
2560 nullptr, CheckedTemps);
2569 CheckEvaluationResultKind::FullyInitialized, Info, DiagLoc,
Type,
Value,
2570 ConstantExprKind::Normal,
nullptr, CheckedTemps);
2576 if (!Info.HeapAllocs.empty()) {
2580 Info.CCEDiag(Info.HeapAllocs.begin()->second.AllocExpr,
2581 diag::note_constexpr_memory_leak)
2582 <<
unsigned(Info.HeapAllocs.size() - 1);
2590 if (!
Value.getLValueBase()) {
2592 Result = !
Value.getLValueOffset().isZero();
2610 Result = Val.
getInt().getBoolValue();
2642 llvm_unreachable(
"unknown APValue kind");
2648 assert(
E->
isPRValue() &&
"missing lvalue-to-rvalue conv in bool condition");
2658 Info.CCEDiag(
E, diag::note_constexpr_overflow)
2659 << SrcValue << DestType;
2660 return Info.noteUndefinedBehavior();
2666 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
2670 Result =
APSInt(DestWidth, !DestSigned);
2672 if (
Value.convertToInteger(Result, llvm::APFloat::rmTowardZero, &ignored)
2673 & APFloat::opInvalidOp)
2684 llvm::RoundingMode RM =
2686 if (RM == llvm::RoundingMode::Dynamic)
2687 RM = llvm::RoundingMode::NearestTiesToEven;
2693 APFloat::opStatus St) {
2696 if (Info.InConstantContext)
2700 if ((St & APFloat::opInexact) &&
2704 Info.FFDiag(
E, diag::note_constexpr_dynamic_rounding);
2708 if ((St != APFloat::opOK) &&
2711 FPO.getAllowFEnvAccess())) {
2712 Info.FFDiag(
E, diag::note_constexpr_float_arithmetic_strict);
2716 if ((St & APFloat::opStatus::opInvalidOp) &&
2735 assert((isa<CastExpr>(
E) || isa<CompoundAssignOperator>(
E) ||
2736 isa<ConvertVectorExpr>(
E)) &&
2737 "HandleFloatToFloatCast has been checked with only CastExpr, "
2738 "CompoundAssignOperator and ConvertVectorExpr. Please either validate "
2739 "the new expression or address the root cause of this usage.");
2741 APFloat::opStatus St;
2742 APFloat
Value = Result;
2744 St = Result.convert(Info.Ctx.getFloatTypeSemantics(DestType), RM, &ignored);
2751 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
2757 Result =
Value.getBoolValue();
2764 QualType DestType, APFloat &Result) {
2765 Result = APFloat(Info.Ctx.getFloatTypeSemantics(DestType), 1);
2767 APFloat::opStatus St = Result.convertFromAPInt(
Value,
Value.isSigned(), RM);
2773 assert(FD->
isBitField() &&
"truncateBitfieldValue on non-bitfield");
2775 if (!
Value.isInt()) {
2779 assert(
Value.isLValue() &&
"integral value neither int nor lvalue?");
2785 unsigned OldBitWidth = Int.getBitWidth();
2787 if (NewBitWidth < OldBitWidth)
2788 Int = Int.trunc(NewBitWidth).extend(OldBitWidth);
2795template<
typename Operation>
2798 unsigned BitWidth, Operation Op,
2800 if (LHS.isUnsigned()) {
2801 Result = Op(LHS, RHS);
2805 APSInt Value(Op(LHS.extend(BitWidth), RHS.extend(BitWidth)),
false);
2806 Result =
Value.trunc(LHS.getBitWidth());
2807 if (Result.extend(BitWidth) !=
Value) {
2808 if (Info.checkingForUndefinedBehavior())
2810 diag::warn_integer_constant_overflow)
2811 <<
toString(Result, 10, Result.isSigned(),
false,
2823 bool HandleOverflowResult =
true;
2830 std::multiplies<APSInt>(), Result);
2833 std::plus<APSInt>(), Result);
2836 std::minus<APSInt>(), Result);
2837 case BO_And: Result = LHS & RHS;
return true;
2838 case BO_Xor: Result = LHS ^ RHS;
return true;
2839 case BO_Or: Result = LHS | RHS;
return true;
2843 Info.FFDiag(
E, diag::note_expr_divide_by_zero)
2849 if (RHS.isNegative() && RHS.isAllOnes() && LHS.isSigned() &&
2850 LHS.isMinSignedValue())
2852 Info,
E, -LHS.extend(LHS.getBitWidth() + 1),
E->
getType());
2853 Result = (Opcode == BO_Rem ? LHS % RHS : LHS / RHS);
2854 return HandleOverflowResult;
2856 if (Info.getLangOpts().OpenCL)
2858 RHS &=
APSInt(llvm::APInt(RHS.getBitWidth(),
2859 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2861 else if (RHS.isSigned() && RHS.isNegative()) {
2864 Info.CCEDiag(
E, diag::note_constexpr_negative_shift) << RHS;
2865 if (!Info.noteUndefinedBehavior())
2873 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
2875 Info.CCEDiag(
E, diag::note_constexpr_large_shift)
2876 << RHS <<
E->
getType() << LHS.getBitWidth();
2877 if (!Info.noteUndefinedBehavior())
2879 }
else if (LHS.isSigned() && !Info.getLangOpts().CPlusPlus20) {
2884 if (LHS.isNegative()) {
2885 Info.CCEDiag(
E, diag::note_constexpr_lshift_of_negative) << LHS;
2886 if (!Info.noteUndefinedBehavior())
2888 }
else if (LHS.countl_zero() < SA) {
2889 Info.CCEDiag(
E, diag::note_constexpr_lshift_discards);
2890 if (!Info.noteUndefinedBehavior())
2898 if (Info.getLangOpts().OpenCL)
2900 RHS &=
APSInt(llvm::APInt(RHS.getBitWidth(),
2901 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2903 else if (RHS.isSigned() && RHS.isNegative()) {
2906 Info.CCEDiag(
E, diag::note_constexpr_negative_shift) << RHS;
2907 if (!Info.noteUndefinedBehavior())
2915 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
2917 Info.CCEDiag(
E, diag::note_constexpr_large_shift)
2918 << RHS <<
E->
getType() << LHS.getBitWidth();
2919 if (!Info.noteUndefinedBehavior())
2927 case BO_LT: Result = LHS < RHS;
return true;
2928 case BO_GT: Result = LHS > RHS;
return true;
2929 case BO_LE: Result = LHS <= RHS;
return true;
2930 case BO_GE: Result = LHS >= RHS;
return true;
2931 case BO_EQ: Result = LHS == RHS;
return true;
2932 case BO_NE: Result = LHS != RHS;
return true;
2934 llvm_unreachable(
"BO_Cmp should be handled elsewhere");
2941 const APFloat &RHS) {
2943 APFloat::opStatus St;
2949 St = LHS.multiply(RHS, RM);
2952 St = LHS.add(RHS, RM);
2955 St = LHS.subtract(RHS, RM);
2961 Info.CCEDiag(
E, diag::note_expr_divide_by_zero);
2962 St = LHS.divide(RHS, RM);
2971 Info.CCEDiag(
E, diag::note_constexpr_float_arithmetic) << LHS.isNaN();
2972 return Info.noteUndefinedBehavior();
2980 const APInt &RHSValue, APInt &Result) {
2981 bool LHS = (LHSValue != 0);
2982 bool RHS = (RHSValue != 0);
2984 if (Opcode == BO_LAnd)
2985 Result = LHS && RHS;
2987 Result = LHS || RHS;
2992 const APFloat &RHSValue, APInt &Result) {
2993 bool LHS = !LHSValue.isZero();
2994 bool RHS = !RHSValue.isZero();
2996 if (Opcode == BO_LAnd)
2997 Result = LHS && RHS;
2999 Result = LHS || RHS;
3005 const APValue &RHSValue, APInt &Result) {
3009 RHSValue.
getInt(), Result);
3015template <
typename APTy>
3018 const APTy &RHSValue, APInt &Result) {
3021 llvm_unreachable(
"unsupported binary operator");
3023 Result = (LHSValue == RHSValue);
3026 Result = (LHSValue != RHSValue);
3029 Result = (LHSValue < RHSValue);
3032 Result = (LHSValue > RHSValue);
3035 Result = (LHSValue <= RHSValue);
3038 Result = (LHSValue >= RHSValue);
3052 const APValue &RHSValue, APInt &Result) {
3056 RHSValue.
getInt(), Result);
3067 assert(Opcode != BO_PtrMemD && Opcode != BO_PtrMemI &&
3068 "Operation not supported on vector types");
3072 QualType EltTy = VT->getElementType();
3079 "A vector result that isn't a vector OR uncalculated LValue");
3085 RHSValue.
getVectorLength() == NumElements &&
"Different vector sizes");
3089 for (
unsigned EltNum = 0; EltNum < NumElements; ++EltNum) {
3094 APSInt EltResult{Info.Ctx.getIntWidth(EltTy),
3104 RHSElt.
getInt(), EltResult);
3110 ResultElements.emplace_back(EltResult);
3115 "Mismatched LHS/RHS/Result Type");
3116 APFloat LHSFloat = LHSElt.
getFloat();
3124 ResultElements.emplace_back(LHSFloat);
3128 LHSValue =
APValue(ResultElements.data(), ResultElements.size());
3136 unsigned TruncatedElements) {
3137 SubobjectDesignator &
D = Result.Designator;
3140 if (TruncatedElements ==
D.Entries.size())
3142 assert(TruncatedElements >=
D.MostDerivedPathLength &&
3143 "not casting to a derived class");
3149 for (
unsigned I = TruncatedElements, N =
D.Entries.size(); I != N; ++I) {
3153 if (isVirtualBaseClass(
D.Entries[I]))
3159 D.Entries.resize(TruncatedElements);
3169 RL = &Info.Ctx.getASTRecordLayout(Derived);
3172 Obj.getLValueOffset() += RL->getBaseClassOffset(
Base);
3173 Obj.addDecl(Info,
E,
Base,
false);
3182 if (!
Base->isVirtual())
3185 SubobjectDesignator &
D = Obj.Designator;
3190 DerivedDecl =
D.MostDerivedType->getAsCXXRecordDecl();
3196 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(DerivedDecl);
3198 Obj.addDecl(Info,
E, BaseDecl,
true);
3205 PathE =
E->path_end();
3206 PathI != PathE; ++PathI) {
3210 Type = (*PathI)->getType();
3222 llvm_unreachable(
"Class must be derived from the passed in base class!");
3237 RL = &Info.Ctx.getASTRecordLayout(FD->
getParent());
3241 LVal.adjustOffset(Info.Ctx.toCharUnitsFromBits(RL->getFieldOffset(I)));
3242 LVal.addDecl(Info,
E, FD);
3250 for (
const auto *
C : IFD->
chain())
3283 if (SOT == SizeOfType::SizeOf)
3284 Size = Info.Ctx.getTypeSizeInChars(
Type);
3286 Size = Info.Ctx.getTypeInfoDataSizeInChars(
Type).Width;
3303 LVal.adjustOffsetAndIndex(Info,
E, Adjustment, SizeOfPointee);
3309 int64_t Adjustment) {
3311 APSInt::get(Adjustment));
3326 LVal.Offset += SizeOfComponent;
3328 LVal.addComplex(Info,
E, EltTy, Imag);
3334 uint64_t Size, uint64_t Idx) {
3339 LVal.Offset += SizeOfElement * Idx;
3341 LVal.addVectorElement(Info,
E, EltTy, Size, Idx);
3355 const VarDecl *VD, CallStackFrame *Frame,
3356 unsigned Version,
APValue *&Result) {
3361 Result = Frame->getTemporary(VD, Version);
3365 if (!isa<ParmVarDecl>(VD)) {
3372 "missing value for local variable");
3373 if (Info.checkingPotentialConstantExpression())
3378 diag::note_unimplemented_constexpr_lambda_feature_ast)
3379 <<
"captures not currently allowed";
3386 if (Info.EvaluatingDecl ==
Base) {
3387 Result = Info.EvaluatingDeclValue;
3391 if (isa<ParmVarDecl>(VD)) {
3394 if (!Info.checkingPotentialConstantExpression() ||
3395 !Info.CurrentCall->Callee ||
3397 if (Info.getLangOpts().CPlusPlus11) {
3398 Info.FFDiag(
E, diag::note_constexpr_function_param_value_unknown)
3418 if (!Info.checkingPotentialConstantExpression()) {
3419 Info.FFDiag(
E, diag::note_constexpr_var_init_unknown, 1)
3426 if (
Init->isValueDependent()) {
3433 if (!Info.checkingPotentialConstantExpression()) {
3434 Info.FFDiag(
E, Info.getLangOpts().CPlusPlus11
3435 ? diag::note_constexpr_ltor_non_constexpr
3436 : diag::note_constexpr_ltor_non_integral, 1)
3446 Info.FFDiag(
E, diag::note_constexpr_var_init_non_constant, 1) << VD;
3462 ((Info.getLangOpts().CPlusPlus || Info.getLangOpts().OpenCL) &&
3464 Info.CCEDiag(
E, diag::note_constexpr_var_init_non_constant, 1) << VD;
3471 Info.FFDiag(
E, diag::note_constexpr_var_init_weak) << VD;
3488 if (I->getType()->getAsCXXRecordDecl()->getCanonicalDecl() ==
Base)
3492 llvm_unreachable(
"base class missing from derived class's bases list");
3498 assert(!isa<SourceLocExpr>(Lit) &&
3499 "SourceLocExpr should have already been converted to a StringLiteral");
3502 if (
const auto *ObjCEnc = dyn_cast<ObjCEncodeExpr>(Lit)) {
3504 Info.Ctx.getObjCEncodingForType(ObjCEnc->getEncodedType(), Str);
3505 assert(Index <= Str.size() &&
"Index too large");
3506 return APSInt::getUnsigned(Str.c_str()[Index]);
3509 if (
auto PE = dyn_cast<PredefinedExpr>(Lit))
3510 Lit = PE->getFunctionName();
3513 Info.Ctx.getAsConstantArrayType(S->getType());
3514 assert(CAT &&
"string literal isn't an array");
3516 assert(CharType->
isIntegerType() &&
"unexpected character type");
3519 if (Index < S->getLength())
3520 Value = S->getCodeUnit(Index);
3532 AllocType.isNull() ? S->getType() : AllocType);
3533 assert(CAT &&
"string literal isn't an array");
3535 assert(CharType->
isIntegerType() &&
"unexpected character type");
3539 std::min(S->getLength(), Elts), Elts);
3542 if (Result.hasArrayFiller())
3544 for (
unsigned I = 0, N = Result.getArrayInitializedElts(); I != N; ++I) {
3545 Value = S->getCodeUnit(I);
3552 unsigned Size = Array.getArraySize();
3553 assert(Index < Size);
3556 unsigned OldElts = Array.getArrayInitializedElts();
3557 unsigned NewElts = std::max(Index+1, OldElts * 2);
3558 NewElts = std::min(Size, std::max(NewElts, 8u));
3562 for (
unsigned I = 0; I != OldElts; ++I)
3564 for (
unsigned I = OldElts; I != NewElts; ++I)
3568 Array.swap(NewValue);
3589 for (
auto *Field : RD->
fields())
3590 if (!Field->isUnnamedBitField() &&
3594 for (
auto &BaseSpec : RD->
bases())
3612 for (
auto *Field : RD->
fields()) {
3617 if (Field->isMutable() &&
3619 Info.FFDiag(
E, diag::note_constexpr_access_mutable, 1) << AK << Field;
3620 Info.Note(Field->getLocation(), diag::note_declared_at);
3628 for (
auto &BaseSpec : RD->
bases())
3638 bool MutableSubobject =
false) {
3643 switch (Info.IsEvaluatingDecl) {
3644 case EvalInfo::EvaluatingDeclKind::None:
3647 case EvalInfo::EvaluatingDeclKind::Ctor:
3649 if (Info.EvaluatingDecl ==
Base)
3654 if (
auto *BaseE =
Base.dyn_cast<
const Expr *>())
3655 if (
auto *BaseMTE = dyn_cast<MaterializeTemporaryExpr>(BaseE))
3656 return Info.EvaluatingDecl == BaseMTE->getExtendingDecl();
3659 case EvalInfo::EvaluatingDeclKind::Dtor:
3664 if (MutableSubobject ||
Base != Info.EvaluatingDecl)
3673 llvm_unreachable(
"unknown evaluating decl kind");
3678 return Info.CheckArraySize(
3687struct CompleteObject {
3695 CompleteObject() :
Value(nullptr) {}
3699 bool mayAccessMutableMembers(EvalInfo &Info,
AccessKinds AK)
const {
3710 if (!Info.getLangOpts().CPlusPlus14)
3715 explicit operator bool()
const {
return !
Type.isNull(); }
3720 bool IsMutable =
false) {
3734template<
typename Sub
objectHandler>
3735typename SubobjectHandler::result_type
3737 const SubobjectDesignator &Sub, SubobjectHandler &handler) {
3740 return handler.failed();
3741 if (Sub.isOnePastTheEnd() || Sub.isMostDerivedAnUnsizedArray()) {
3742 if (Info.getLangOpts().CPlusPlus11)
3743 Info.FFDiag(
E, Sub.isOnePastTheEnd()
3744 ? diag::note_constexpr_access_past_end
3745 : diag::note_constexpr_access_unsized_array)
3746 << handler.AccessKind;
3749 return handler.failed();
3755 const FieldDecl *VolatileField =
nullptr;
3758 for (
unsigned I = 0, N = Sub.Entries.size(); ; ++I) {
3763 if (!Info.checkingPotentialConstantExpression())
3764 Info.FFDiag(
E, diag::note_constexpr_access_uninit)
3767 return handler.failed();
3775 Info.isEvaluatingCtorDtor(
3778 ConstructionPhase::None) {
3788 if (Info.getLangOpts().CPlusPlus) {
3792 if (VolatileField) {
3795 Decl = VolatileField;
3796 }
else if (
auto *VD = Obj.Base.dyn_cast<
const ValueDecl*>()) {
3798 Loc = VD->getLocation();
3802 if (
auto *
E = Obj.Base.dyn_cast<
const Expr *>())
3805 Info.FFDiag(
E, diag::note_constexpr_access_volatile_obj, 1)
3806 << handler.AccessKind << DiagKind <<
Decl;
3807 Info.Note(
Loc, diag::note_constexpr_volatile_here) << DiagKind;
3809 Info.FFDiag(
E, diag::note_invalid_subexpr_in_const_expr);
3811 return handler.failed();
3819 !Obj.mayAccessMutableMembers(Info, handler.AccessKind) &&
3821 return handler.failed();
3825 if (!handler.found(*O, ObjType))
3837 LastField =
nullptr;
3841 assert(CAT &&
"vla in literal type?");
3842 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
3843 if (CAT->
getSize().ule(Index)) {
3846 if (Info.getLangOpts().CPlusPlus11)
3847 Info.FFDiag(
E, diag::note_constexpr_access_past_end)
3848 << handler.AccessKind;
3851 return handler.failed();
3858 else if (!
isRead(handler.AccessKind)) {
3860 return handler.failed();
3868 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
3870 if (Info.getLangOpts().CPlusPlus11)
3871 Info.FFDiag(
E, diag::note_constexpr_access_past_end)
3872 << handler.AccessKind;
3875 return handler.failed();
3881 assert(I == N - 1 &&
"extracting subobject of scalar?");
3891 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
3892 unsigned NumElements = VT->getNumElements();
3893 if (Index == NumElements) {
3894 if (Info.getLangOpts().CPlusPlus11)
3895 Info.FFDiag(
E, diag::note_constexpr_access_past_end)
3896 << handler.AccessKind;
3899 return handler.failed();
3902 if (Index > NumElements) {
3903 Info.CCEDiag(
E, diag::note_constexpr_array_index)
3904 << Index << 0 << NumElements;
3905 return handler.failed();
3908 ObjType = VT->getElementType();
3909 assert(I == N - 1 &&
"extracting subobject of scalar?");
3911 }
else if (
const FieldDecl *Field = getAsField(Sub.Entries[I])) {
3912 if (Field->isMutable() &&
3913 !Obj.mayAccessMutableMembers(Info, handler.AccessKind)) {
3914 Info.FFDiag(
E, diag::note_constexpr_access_mutable, 1)
3915 << handler.AccessKind << Field;
3916 Info.Note(Field->getLocation(), diag::note_declared_at);
3917 return handler.failed();
3926 if (I == N - 1 && handler.AccessKind ==
AK_Construct) {
3934 Info.FFDiag(
E, diag::note_constexpr_access_inactive_union_member)
3935 << handler.AccessKind << Field << !UnionField << UnionField;
3936 return handler.failed();
3945 if (Field->getType().isVolatileQualified())
3946 VolatileField = Field;
3959struct ExtractSubobjectHandler {
3965 typedef bool result_type;
3966 bool failed() {
return false; }
3986 const CompleteObject &Obj,
3987 const SubobjectDesignator &Sub,
APValue &Result,
3990 ExtractSubobjectHandler Handler = {Info,
E, Result, AK};
3995struct ModifySubobjectHandler {
4000 typedef bool result_type;
4006 Info.FFDiag(
E, diag::note_constexpr_modify_const_type) << QT;
4012 bool failed() {
return false; }
4014 if (!checkConst(SubobjType))
4017 Subobj.
swap(NewVal);
4021 if (!checkConst(SubobjType))
4023 if (!NewVal.
isInt()) {
4032 if (!checkConst(SubobjType))
4040const AccessKinds ModifySubobjectHandler::AccessKind;
4044 const CompleteObject &Obj,
4045 const SubobjectDesignator &Sub,
4047 ModifySubobjectHandler Handler = { Info, NewVal,
E };
4054 const SubobjectDesignator &A,
4055 const SubobjectDesignator &B,
4056 bool &WasArrayIndex) {
4057 unsigned I = 0, N = std::min(A.Entries.size(), B.Entries.size());
4058 for (; I != N; ++I) {
4062 if (A.Entries[I].getAsArrayIndex() != B.Entries[I].getAsArrayIndex()) {
4063 WasArrayIndex =
true;
4071 if (A.Entries[I].getAsBaseOrMember() !=
4072 B.Entries[I].getAsBaseOrMember()) {
4073 WasArrayIndex =
false;
4076 if (
const FieldDecl *FD = getAsField(A.Entries[I]))
4078 ObjType = FD->getType();
4084 WasArrayIndex =
false;
4091 const SubobjectDesignator &A,
4092 const SubobjectDesignator &B) {
4093 if (A.Entries.size() != B.Entries.size())
4096 bool IsArray = A.MostDerivedIsArrayElement;
4097 if (IsArray && A.MostDerivedPathLength != A.Entries.size())
4106 return CommonLength >= A.Entries.size() - IsArray;
4113 if (LVal.InvalidBase) {
4115 return CompleteObject();
4119 Info.FFDiag(
E, diag::note_constexpr_access_null) << AK;
4120 return CompleteObject();
4123 CallStackFrame *Frame =
nullptr;
4125 if (LVal.getLValueCallIndex()) {
4126 std::tie(Frame, Depth) =
4127 Info.getCallFrameAndDepth(LVal.getLValueCallIndex());
4129 Info.FFDiag(
E, diag::note_constexpr_lifetime_ended, 1)
4130 << AK << LVal.Base.is<
const ValueDecl*>();
4132 return CompleteObject();
4143 if (Info.getLangOpts().CPlusPlus)
4144 Info.FFDiag(
E, diag::note_constexpr_access_volatile_type)
4148 return CompleteObject();
4153 QualType BaseType = getType(LVal.Base);
4155 if (Info.getLangOpts().CPlusPlus14 && LVal.Base == Info.EvaluatingDecl &&
4159 BaseVal = Info.EvaluatingDeclValue;
4162 if (
auto *GD = dyn_cast<MSGuidDecl>(
D)) {
4165 Info.FFDiag(
E, diag::note_constexpr_modify_global);
4166 return CompleteObject();
4170 Info.FFDiag(
E, diag::note_constexpr_unsupported_layout)
4172 return CompleteObject();
4174 return CompleteObject(LVal.Base, &
V, GD->getType());
4178 if (
auto *GCD = dyn_cast<UnnamedGlobalConstantDecl>(
D)) {
4180 Info.FFDiag(
E, diag::note_constexpr_modify_global);
4181 return CompleteObject();
4183 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&GCD->getValue()),
4188 if (
auto *TPO = dyn_cast<TemplateParamObjectDecl>(
D)) {
4190 Info.FFDiag(
E, diag::note_constexpr_modify_global);
4191 return CompleteObject();
4193 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&TPO->getValue()),
4204 const VarDecl *VD = dyn_cast<VarDecl>(
D);
4211 return CompleteObject();
4214 bool IsConstant = BaseType.
isConstant(Info.Ctx);
4215 bool ConstexprVar =
false;
4216 if (
const auto *VD = dyn_cast_if_present<VarDecl>(
4217 Info.EvaluatingDecl.dyn_cast<
const ValueDecl *>()))
4223 if (IsAccess && isa<ParmVarDecl>(VD)) {
4227 }
else if (Info.getLangOpts().CPlusPlus14 &&
4234 Info.FFDiag(
E, diag::note_constexpr_modify_global);
4235 return CompleteObject();
4238 }
else if (Info.getLangOpts().C23 && ConstexprVar) {
4240 return CompleteObject();
4244 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4245 if (Info.getLangOpts().CPlusPlus) {
4246 Info.FFDiag(
E, diag::note_constexpr_ltor_non_const_int, 1) << VD;
4247 Info.Note(VD->
getLocation(), diag::note_declared_at);
4251 return CompleteObject();
4253 }
else if (!IsAccess) {
4254 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4255 }
else if (IsConstant && Info.checkingPotentialConstantExpression() &&
4258 }
else if (IsConstant) {
4262 if (Info.getLangOpts().CPlusPlus) {
4263 Info.CCEDiag(
E, Info.getLangOpts().CPlusPlus11
4264 ? diag::note_constexpr_ltor_non_constexpr
4265 : diag::note_constexpr_ltor_non_integral, 1)
4267 Info.Note(VD->
getLocation(), diag::note_declared_at);
4273 if (Info.getLangOpts().CPlusPlus) {
4274 Info.FFDiag(
E, Info.getLangOpts().CPlusPlus11
4275 ? diag::note_constexpr_ltor_non_constexpr
4276 : diag::note_constexpr_ltor_non_integral, 1)
4278 Info.Note(VD->
getLocation(), diag::note_declared_at);
4282 return CompleteObject();
4287 return CompleteObject();
4289 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
4291 Info.FFDiag(
E, diag::note_constexpr_access_deleted_object) << AK;
4292 return CompleteObject();
4294 return CompleteObject(LVal.Base, &(*Alloc)->Value,
4295 LVal.Base.getDynamicAllocType());
4301 dyn_cast_or_null<MaterializeTemporaryExpr>(
Base)) {
4302 assert(MTE->getStorageDuration() ==
SD_Static &&
4303 "should have a frame for a non-global materialized temporary");
4330 if (!MTE->isUsableInConstantExpressions(Info.Ctx) &&
4333 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4334 Info.FFDiag(
E, diag::note_constexpr_access_static_temporary, 1) << AK;
4335 Info.Note(MTE->getExprLoc(), diag::note_constexpr_temporary_here);
4336 return CompleteObject();
4339 BaseVal = MTE->getOrCreateValue(
false);
4340 assert(BaseVal &&
"got reference to unevaluated temporary");
4343 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4346 Info.FFDiag(
E, diag::note_constexpr_access_unreadable_object)
4349 Info.Ctx.getLValueReferenceType(LValType));
4351 return CompleteObject();
4354 BaseVal = Frame->getTemporary(
Base, LVal.Base.getVersion());
4355 assert(BaseVal &&
"missing value for temporary");
4366 unsigned VisibleDepth = Depth;
4367 if (llvm::isa_and_nonnull<ParmVarDecl>(
4368 LVal.Base.dyn_cast<
const ValueDecl *>()))
4370 if ((Frame && Info.getLangOpts().CPlusPlus14 &&
4371 Info.EvalStatus.HasSideEffects) ||
4372 (
isModification(AK) && VisibleDepth < Info.SpeculativeEvaluationDepth))
4373 return CompleteObject();
4375 return CompleteObject(LVal.getLValueBase(), BaseVal, BaseType);
4394 const LValue &LVal,
APValue &RVal,
4395 bool WantObjectRepresentation =
false) {
4396 if (LVal.Designator.Invalid)
4405 if (
Base && !LVal.getLValueCallIndex() && !
Type.isVolatileQualified()) {
4410 if (
Type.isVolatileQualified()) {
4416 if (!
Evaluate(Lit, Info, CLE->getInitializer()))
4436 Info.Note(CLE->getExprLoc(), diag::note_declared_at);
4441 CompleteObject LitObj(LVal.Base, &Lit,
Base->getType());
4443 }
else if (isa<StringLiteral>(
Base) || isa<PredefinedExpr>(
Base)) {
4446 assert(LVal.Designator.Entries.size() <= 1 &&
4447 "Can only read characters from string literals");
4448 if (LVal.Designator.Entries.empty()) {
4455 if (LVal.Designator.isOnePastTheEnd()) {
4456 if (Info.getLangOpts().CPlusPlus11)
4457 Info.FFDiag(Conv, diag::note_constexpr_access_past_end) << AK;
4462 uint64_t CharIndex = LVal.Designator.Entries[0].getAsArrayIndex();
4469 return Obj &&
extractSubobject(Info, Conv, Obj, LVal.Designator, RVal, AK);
4475 if (LVal.Designator.Invalid)
4478 if (!Info.getLangOpts().CPlusPlus14) {
4488struct CompoundAssignSubobjectHandler {
4497 typedef bool result_type;
4502 Info.FFDiag(
E, diag::note_constexpr_modify_const_type) << QT;
4508 bool failed() {
return false; }
4512 return found(Subobj.
getInt(), SubobjType);
4514 return found(Subobj.
getFloat(), SubobjType);
4521 return foundPointer(Subobj, SubobjType);
4523 return foundVector(Subobj, SubobjType);
4525 Info.FFDiag(
E, diag::note_constexpr_access_uninit)
4537 if (!checkConst(SubobjType))
4548 if (!checkConst(SubobjType))
4567 Info.Ctx.getLangOpts());
4570 PromotedLHSType, FValue) &&
4580 return checkConst(SubobjType) &&
4587 if (!checkConst(SubobjType))
4595 (Opcode != BO_Add && Opcode != BO_Sub)) {
4601 if (Opcode == BO_Sub)
4605 LVal.setFrom(Info.Ctx, Subobj);
4608 LVal.moveInto(Subobj);
4614const AccessKinds CompoundAssignSubobjectHandler::AccessKind;
4619 const LValue &LVal,
QualType LValType,
4623 if (LVal.Designator.Invalid)
4626 if (!Info.getLangOpts().CPlusPlus14) {
4632 CompoundAssignSubobjectHandler Handler = { Info,
E, PromotedLValType, Opcode,
4634 return Obj &&
findSubobject(Info,
E, Obj, LVal.Designator, Handler);
4638struct IncDecSubobjectHandler {
4644 typedef bool result_type;
4649 Info.FFDiag(
E, diag::note_constexpr_modify_const_type) << QT;
4655 bool failed() {
return false; }
4666 return found(Subobj.
getInt(), SubobjType);
4668 return found(Subobj.
getFloat(), SubobjType);
4678 return foundPointer(Subobj, SubobjType);
4686 if (!checkConst(SubobjType))
4708 bool WasNegative =
Value.isNegative();
4712 if (!WasNegative &&
Value.isNegative() &&
E->canOverflow()) {
4719 if (WasNegative && !
Value.isNegative() &&
E->canOverflow()) {
4720 unsigned BitWidth =
Value.getBitWidth();
4721 APSInt ActualValue(
Value.sext(BitWidth + 1),
false);
4722 ActualValue.setBit(BitWidth);
4729 if (!checkConst(SubobjType))
4736 APFloat::opStatus St;
4738 St =
Value.add(One, RM);
4740 St =
Value.subtract(One, RM);
4744 if (!checkConst(SubobjType))
4756 LVal.setFrom(Info.Ctx, Subobj);
4760 LVal.moveInto(Subobj);
4769 if (LVal.Designator.Invalid)
4772 if (!Info.getLangOpts().CPlusPlus14) {
4779 IncDecSubobjectHandler Handler = {Info, cast<UnaryOperator>(
E), AK, Old};
4780 return Obj &&
findSubobject(Info,
E, Obj, LVal.Designator, Handler);
4786 if (Object->getType()->isPointerType() && Object->isPRValue())
4789 if (Object->isGLValue())
4792 if (Object->getType()->isLiteralType(Info.Ctx))
4795 if (Object->getType()->isRecordType() && Object->isPRValue())
4798 Info.FFDiag(Object, diag::note_constexpr_nonliteral) << Object->getType();
4817 bool IncludeMember =
true) {
4824 if (!MemPtr.getDecl()) {
4830 if (MemPtr.isDerivedMember()) {
4834 if (LV.Designator.MostDerivedPathLength + MemPtr.Path.size() >
4835 LV.Designator.Entries.size()) {
4839 unsigned PathLengthToMember =
4840 LV.Designator.Entries.size() - MemPtr.Path.size();
4841 for (
unsigned I = 0, N = MemPtr.Path.size(); I != N; ++I) {
4843 LV.Designator.Entries[PathLengthToMember + I]);
4853 PathLengthToMember))
4855 }
else if (!MemPtr.Path.empty()) {
4857 LV.Designator.Entries.reserve(LV.Designator.Entries.size() +
4858 MemPtr.Path.size() + IncludeMember);
4864 assert(RD &&
"member pointer access on non-class-type expression");
4866 for (
unsigned I = 1, N = MemPtr.Path.size(); I != N; ++I) {
4874 MemPtr.getContainingRecord()))
4879 if (IncludeMember) {
4880 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(MemPtr.getDecl())) {
4884 dyn_cast<IndirectFieldDecl>(MemPtr.getDecl())) {
4888 llvm_unreachable(
"can't construct reference to bound member function");
4892 return MemPtr.getDecl();
4898 bool IncludeMember =
true) {
4902 if (Info.noteFailure()) {
4910 BO->
getRHS(), IncludeMember);
4917 SubobjectDesignator &
D = Result.Designator;
4918 if (
D.Invalid || !Result.checkNullPointer(Info,
E,
CSK_Derived))
4926 if (
D.MostDerivedPathLength +
E->path_size() >
D.Entries.size()) {
4927 Info.CCEDiag(
E, diag::note_constexpr_invalid_downcast)
4928 <<
D.MostDerivedType << TargetQT;
4934 unsigned NewEntriesSize =
D.Entries.size() -
E->path_size();
4937 if (NewEntriesSize ==
D.MostDerivedPathLength)
4938 FinalType =
D.MostDerivedType->getAsCXXRecordDecl();
4940 FinalType = getAsBaseClass(
D.Entries[NewEntriesSize - 1]);
4942 Info.CCEDiag(
E, diag::note_constexpr_invalid_downcast)
4943 <<
D.MostDerivedType << TargetQT;
4957 if (!Result.isAbsent())
4961 if (RD->isInvalidDecl()) {
4965 if (RD->isUnion()) {
4970 std::distance(RD->field_begin(), RD->field_end()));
4974 End = RD->bases_end();
4975 I != End; ++I, ++Index)
4979 for (
const auto *I : RD->fields()) {
4980 if (I->isUnnamedBitField())
4983 I->getType(), Result.getStructField(I->getFieldIndex()));
4991 if (Result.hasArrayFiller())
5003enum EvalStmtResult {
5027 APValue &Val = Info.CurrentCall->createTemporary(VD, VD->
getType(),
5028 ScopeKind::Block, Result);
5033 return Info.noteSideEffect();
5052 if (
const VarDecl *VD = dyn_cast<VarDecl>(
D))
5056 for (
auto *BD : DD->bindings())
5057 if (
auto *VD = BD->getHoldingVar())
5065 if (Info.noteSideEffect())
5067 assert(
E->
containsErrors() &&
"valid value-dependent expression should never "
5068 "reach invalid code path.");
5074 const Expr *Cond,
bool &Result) {
5077 FullExpressionRAII
Scope(Info);
5082 return Scope.destroy();
5095struct TempVersionRAII {
5096 CallStackFrame &Frame;
5098 TempVersionRAII(CallStackFrame &Frame) : Frame(Frame) {
5099 Frame.pushTempVersion();
5102 ~TempVersionRAII() {
5103 Frame.popTempVersion();
5117 BlockScopeRAII
Scope(Info);
5119 EvalStmtResult ESR =
EvaluateStmt(Result, Info, Body, Case);
5120 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5125 return ESR_Succeeded;
5128 return ESR_Continue;
5131 case ESR_CaseNotFound:
5134 llvm_unreachable(
"Invalid EvalStmtResult!");
5140 BlockScopeRAII
Scope(Info);
5147 if (ESR != ESR_Succeeded) {
5148 if (ESR != ESR_Failed && !
Scope.destroy())
5154 FullExpressionRAII CondScope(Info);
5166 if (!CondScope.destroy())
5175 if (isa<DefaultStmt>(SC)) {
5180 const CaseStmt *CS = cast<CaseStmt>(SC);
5191 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5195 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5200 return ESR_Succeeded;
5206 case ESR_CaseNotFound:
5209 Info.FFDiag(
Found->getBeginLoc(),
5210 diag::note_constexpr_stmt_expr_unsupported);
5213 llvm_unreachable(
"Invalid EvalStmtResult!");
5223 Info.CCEDiag(VD->
getLocation(), diag::note_constexpr_static_local)
5233 if (!Info.nextStep(S))
5239 switch (S->getStmtClass()) {
5240 case Stmt::CompoundStmtClass:
5244 case Stmt::LabelStmtClass:
5245 case Stmt::AttributedStmtClass:
5246 case Stmt::DoStmtClass:
5249 case Stmt::CaseStmtClass:
5250 case Stmt::DefaultStmtClass:
5255 case Stmt::IfStmtClass: {
5258 const IfStmt *IS = cast<IfStmt>(S);
5262 BlockScopeRAII
Scope(Info);
5268 if (ESR != ESR_CaseNotFound) {
5269 assert(ESR != ESR_Succeeded);
5280 if (ESR == ESR_Failed)
5282 if (ESR != ESR_CaseNotFound)
5283 return Scope.destroy() ? ESR : ESR_Failed;
5285 return ESR_CaseNotFound;
5288 if (ESR == ESR_Failed)
5290 if (ESR != ESR_CaseNotFound)
5291 return Scope.destroy() ? ESR : ESR_Failed;
5292 return ESR_CaseNotFound;
5295 case Stmt::WhileStmtClass: {
5296 EvalStmtResult ESR =
5298 if (ESR != ESR_Continue)
5303 case Stmt::ForStmtClass: {
5304 const ForStmt *FS = cast<ForStmt>(S);
5305 BlockScopeRAII
Scope(Info);
5309 if (
const Stmt *
Init = FS->getInit()) {
5311 if (ESR != ESR_CaseNotFound) {
5312 assert(ESR != ESR_Succeeded);
5317 EvalStmtResult ESR =
5319 if (ESR != ESR_Continue)
5321 if (
const auto *Inc = FS->getInc()) {
5322 if (Inc->isValueDependent()) {
5326 FullExpressionRAII IncScope(Info);
5334 case Stmt::DeclStmtClass: {
5337 const DeclStmt *DS = cast<DeclStmt>(S);
5338 for (
const auto *
D : DS->
decls()) {
5339 if (
const auto *VD = dyn_cast<VarDecl>(
D)) {
5342 if (VD->hasLocalStorage() && !VD->getInit())
5350 return ESR_CaseNotFound;
5354 return ESR_CaseNotFound;
5358 switch (S->getStmtClass()) {
5360 if (
const Expr *
E = dyn_cast<Expr>(S)) {
5369 FullExpressionRAII
Scope(Info);
5373 return ESR_Succeeded;
5376 Info.FFDiag(S->getBeginLoc()) << S->getSourceRange();
5379 case Stmt::NullStmtClass:
5380 return ESR_Succeeded;
5382 case Stmt::DeclStmtClass: {
5383 const DeclStmt *DS = cast<DeclStmt>(S);
5384 for (
const auto *
D : DS->
decls()) {
5385 const VarDecl *VD = dyn_cast_or_null<VarDecl>(
D);
5389 FullExpressionRAII
Scope(Info);
5392 if (!
Scope.destroy())
5395 return ESR_Succeeded;
5398 case Stmt::ReturnStmtClass: {
5399 const Expr *RetExpr = cast<ReturnStmt>(S)->getRetValue();
5400 FullExpressionRAII
Scope(Info);
5409 :
Evaluate(Result.Value, Info, RetExpr)))
5411 return Scope.destroy() ? ESR_Returned : ESR_Failed;
5414 case Stmt::CompoundStmtClass: {
5415 BlockScopeRAII
Scope(Info);
5418 for (
const auto *BI : CS->
body()) {
5419 EvalStmtResult ESR =
EvaluateStmt(Result, Info, BI, Case);
5420 if (ESR == ESR_Succeeded)
5422 else if (ESR != ESR_CaseNotFound) {
5423 if (ESR != ESR_Failed && !
Scope.destroy())
5429 return ESR_CaseNotFound;
5430 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5433 case Stmt::IfStmtClass: {
5434 const IfStmt *IS = cast<IfStmt>(S);
5437 BlockScopeRAII
Scope(Info);
5440 if (ESR != ESR_Succeeded) {
5441 if (ESR != ESR_Failed && !
Scope.destroy())
5451 if (!Info.InConstantContext)
5458 EvalStmtResult ESR =
EvaluateStmt(Result, Info, SubStmt);
5459 if (ESR != ESR_Succeeded) {
5460 if (ESR != ESR_Failed && !
Scope.destroy())
5465 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5468 case Stmt::WhileStmtClass: {
5469 const WhileStmt *WS = cast<WhileStmt>(S);
5471 BlockScopeRAII
Scope(Info);
5480 if (ESR != ESR_Continue) {
5481 if (ESR != ESR_Failed && !
Scope.destroy())
5485 if (!
Scope.destroy())
5488 return ESR_Succeeded;
5491 case Stmt::DoStmtClass: {
5492 const DoStmt *DS = cast<DoStmt>(S);
5496 if (ESR != ESR_Continue)
5505 FullExpressionRAII CondScope(Info);
5507 !CondScope.destroy())
5510 return ESR_Succeeded;
5513 case Stmt::ForStmtClass: {
5514 const ForStmt *FS = cast<ForStmt>(S);
5515 BlockScopeRAII ForScope(Info);
5516 if (FS->getInit()) {
5517 EvalStmtResult ESR =
EvaluateStmt(Result, Info, FS->getInit());
5518 if (ESR != ESR_Succeeded) {
5519 if (ESR != ESR_Failed && !ForScope.destroy())
5525 BlockScopeRAII IterScope(Info);
5526 bool Continue =
true;
5527 if (FS->getCond() && !
EvaluateCond(Info, FS->getConditionVariable(),
5528 FS->getCond(), Continue))
5534 if (ESR != ESR_Continue) {
5535 if (ESR != ESR_Failed && (!IterScope.destroy() || !ForScope.destroy()))
5540 if (
const auto *Inc = FS->getInc()) {
5541 if (Inc->isValueDependent()) {
5545 FullExpressionRAII IncScope(Info);
5551 if (!IterScope.destroy())
5554 return ForScope.destroy() ? ESR_Succeeded : ESR_Failed;
5557 case Stmt::CXXForRangeStmtClass: {
5559 BlockScopeRAII
Scope(Info);
5562 if (FS->getInit()) {
5563 EvalStmtResult ESR =
EvaluateStmt(Result, Info, FS->getInit());
5564 if (ESR != ESR_Succeeded) {
5565 if (ESR != ESR_Failed && !
Scope.destroy())
5572 EvalStmtResult ESR =
EvaluateStmt(Result, Info, FS->getRangeStmt());
5573 if (ESR != ESR_Succeeded) {
5574 if (ESR != ESR_Failed && !
Scope.destroy())
5581 if (!FS->getBeginStmt() || !FS->getEndStmt() || !FS->getCond())
5586 if (ESR != ESR_Succeeded) {
5587 if (ESR != ESR_Failed && !
Scope.destroy())
5592 if (ESR != ESR_Succeeded) {
5593 if (ESR != ESR_Failed && !
Scope.destroy())
5601 if (FS->getCond()->isValueDependent()) {
5606 bool Continue =
true;
5607 FullExpressionRAII CondExpr(Info);
5615 BlockScopeRAII InnerScope(Info);
5616 ESR =
EvaluateStmt(Result, Info, FS->getLoopVarStmt());
5617 if (ESR != ESR_Succeeded) {
5618 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
5625 if (ESR != ESR_Continue) {
5626 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
5630 if (FS->getInc()->isValueDependent()) {
5639 if (!InnerScope.destroy())
5643 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5646 case Stmt::SwitchStmtClass:
5649 case Stmt::ContinueStmtClass:
5650 return ESR_Continue;
5652 case Stmt::BreakStmtClass:
5655 case Stmt::LabelStmtClass:
5656 return EvaluateStmt(Result, Info, cast<LabelStmt>(S)->getSubStmt(), Case);
5658 case Stmt::AttributedStmtClass: {
5659 const auto *AS = cast<AttributedStmt>(S);
5660 const auto *SS = AS->getSubStmt();
5661 MSConstexprContextRAII ConstexprContext(
5662 *Info.CurrentCall, hasSpecificAttr<MSConstexprAttr>(AS->getAttrs()) &&
5663 isa<ReturnStmt>(SS));
5665 auto LO = Info.getCtx().getLangOpts();
5666 if (LO.CXXAssumptions && !LO.MSVCCompat) {
5667 for (
auto *
Attr : AS->getAttrs()) {
5668 auto *AA = dyn_cast<CXXAssumeAttr>(
Attr);
5672 auto *Assumption = AA->getAssumption();
5673 if (Assumption->isValueDependent())
5676 if (Assumption->HasSideEffects(Info.getCtx()))
5683 Info.CCEDiag(Assumption->getExprLoc(),
5684 diag::note_constexpr_assumption_failed);
5693 case Stmt::CaseStmtClass:
5694 case Stmt::DefaultStmtClass:
5695 return EvaluateStmt(Result, Info, cast<SwitchCase>(S)->getSubStmt(), Case);
5696 case Stmt::CXXTryStmtClass:
5698 return EvaluateStmt(Result, Info, cast<CXXTryStmt>(S)->getTryBlock(), Case);
5708 bool IsValueInitialization) {
5715 if (!CD->
isConstexpr() && !IsValueInitialization) {
5716 if (Info.getLangOpts().CPlusPlus11) {
5719 Info.CCEDiag(
Loc, diag::note_constexpr_invalid_function, 1)
5721 Info.Note(CD->
getLocation(), diag::note_declared_at);
5723 Info.CCEDiag(
Loc, diag::note_invalid_subexpr_in_const_expr);
5737 if (Info.checkingPotentialConstantExpression() && !
Definition &&
5745 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
5752 if (!Info.Ctx.getLangOpts().CPlusPlus20 && isa<CXXMethodDecl>(
Declaration) &&
5754 Info.CCEDiag(CallLoc, diag::note_constexpr_virtual_call);
5757 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
5763 (
Definition->isConstexpr() || (Info.CurrentCall->CanEvalMSConstexpr &&
5767 if (Info.getLangOpts().CPlusPlus11) {
5772 auto *CD = dyn_cast<CXXConstructorDecl>(DiagDecl);
5773 if (CD && CD->isInheritingConstructor()) {
5774 auto *Inherited = CD->getInheritedConstructor().getConstructor();
5775 if (!Inherited->isConstexpr())
5776 DiagDecl = CD = Inherited;
5782 if (CD && CD->isInheritingConstructor())
5783 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_inhctor, 1)
5784 << CD->getInheritedConstructor().getConstructor()->
getParent();
5786 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_function, 1)
5788 Info.Note(DiagDecl->
getLocation(), diag::note_declared_at);
5790 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
5796struct CheckDynamicTypeHandler {
5798 typedef bool result_type;
5799 bool failed() {
return false; }
5802 bool found(APFloat &
Value,
QualType SubobjType) {
return true; }
5810 if (This.Designator.Invalid)
5822 if (This.Designator.isOnePastTheEnd() ||
5823 This.Designator.isMostDerivedAnUnsizedArray()) {
5824 Info.FFDiag(
E, This.Designator.isOnePastTheEnd()
5825 ? diag::note_constexpr_access_past_end
5826 : diag::note_constexpr_access_unsized_array)
5829 }
else if (Polymorphic) {
5835 Info.Ctx.getLValueReferenceType(This.Designator.getType(Info.Ctx));
5836 Info.FFDiag(
E, diag::note_constexpr_polymorphic_unknown_dynamic_type)
5843 CheckDynamicTypeHandler Handler{AK};
5844 return Obj &&
findSubobject(Info,
E, Obj, This.Designator, Handler);
5866 unsigned PathLength) {
5867 assert(PathLength >=
Designator.MostDerivedPathLength && PathLength <=
5868 Designator.Entries.size() &&
"invalid path length");
5869 return (PathLength ==
Designator.MostDerivedPathLength)
5870 ?
Designator.MostDerivedType->getAsCXXRecordDecl()
5871 : getAsBaseClass(
Designator.Entries[PathLength - 1]);
5883 return std::nullopt;
5892 This.Designator.MostDerivedType->getAsCXXRecordDecl();
5895 return std::nullopt;
5903 for (
unsigned PathLength = This.Designator.MostDerivedPathLength;
5904 PathLength <=
Path.size(); ++PathLength) {
5905 switch (Info.isEvaluatingCtorDtor(This.getLValueBase(),
5906 Path.slice(0, PathLength))) {
5907 case ConstructionPhase::Bases:
5908 case ConstructionPhase::DestroyingBases:
5913 case ConstructionPhase::None:
5914 case ConstructionPhase::AfterBases:
5915 case ConstructionPhase::AfterFields:
5916 case ConstructionPhase::Destroying:
5928 return std::nullopt;
5946 unsigned PathLength = DynType->PathLength;
5947 for (; PathLength <= This.Designator.Entries.size(); ++PathLength) {
5950 Found->getCorrespondingMethodDeclaredInClass(
Class,
false);
5960 if (Callee->isPureVirtual()) {
5961 Info.FFDiag(
E, diag::note_constexpr_pure_virtual_call, 1) << Callee;
5962 Info.Note(Callee->getLocation(), diag::note_declared_at);
5968 if (!Info.Ctx.hasSameUnqualifiedType(Callee->getReturnType(),
5969 Found->getReturnType())) {
5970 CovariantAdjustmentPath.push_back(Callee->getReturnType());
5971 for (
unsigned CovariantPathLength = PathLength + 1;
5972 CovariantPathLength != This.Designator.Entries.size();
5973 ++CovariantPathLength) {
5977 Found->getCorrespondingMethodDeclaredInClass(NextClass,
false);
5978 if (Next && !Info.Ctx.hasSameUnqualifiedType(
5979 Next->getReturnType(), CovariantAdjustmentPath.back()))
5980 CovariantAdjustmentPath.push_back(Next->getReturnType());
5982 if (!Info.Ctx.hasSameUnqualifiedType(
Found->getReturnType(),
5983 CovariantAdjustmentPath.back()))
5984 CovariantAdjustmentPath.push_back(
Found->getReturnType());
6000 assert(Result.isLValue() &&
6001 "unexpected kind of APValue for covariant return");
6002 if (Result.isNullPointer())
6006 LVal.setFrom(Info.Ctx, Result);
6009 for (
unsigned I = 1; I !=
Path.size(); ++I) {
6011 assert(OldClass && NewClass &&
"unexpected kind of covariant return");
6012 if (OldClass != NewClass &&
6015 OldClass = NewClass;
6018 LVal.moveInto(Result);
6027 auto *BaseClass = BaseSpec.getType()->getAsCXXRecordDecl();
6029 return BaseSpec.getAccessSpecifier() ==
AS_public;
6031 llvm_unreachable(
"Base is not a direct base of Derived");
6041 SubobjectDesignator &
D = Ptr.Designator;
6053 std::optional<DynamicType> DynType =
6064 const CXXRecordDecl *
C =
E->getTypeAsWritten()->getPointeeCXXRecordDecl();
6065 assert(
C &&
"dynamic_cast target is not void pointer nor class");
6066 CanQualType CQT = Info.Ctx.getCanonicalType(Info.Ctx.getRecordType(
C));
6073 Ptr.setNull(Info.Ctx,
E->
getType());
6080 DynType->Type->isDerivedFrom(
C)))
6082 else if (!Paths || Paths->begin() == Paths->end())
6084 else if (Paths->isAmbiguous(CQT))
6087 assert(Paths->front().Access !=
AS_public &&
"why did the cast fail?");
6090 Info.FFDiag(
E, diag::note_constexpr_dynamic_cast_to_reference_failed)
6091 << DiagKind << Ptr.Designator.getType(Info.Ctx)
6092 << Info.Ctx.getRecordType(DynType->Type)
6100 for (
int PathLength = Ptr.Designator.Entries.size();
6101 PathLength >= (
int)DynType->PathLength; --PathLength) {
6106 if (PathLength > (
int)DynType->PathLength &&
6109 return RuntimeCheckFailed(
nullptr);
6116 if (DynType->Type->isDerivedFrom(
C, Paths) && !Paths.isAmbiguous(CQT) &&
6129 return RuntimeCheckFailed(&Paths);
6133struct StartLifetimeOfUnionMemberHandler {
6135 const Expr *LHSExpr;
6138 bool Failed =
false;
6141 typedef bool result_type;
6142 bool failed() {
return Failed; }
6158 }
else if (DuringInit) {
6162 Info.FFDiag(LHSExpr,
6163 diag::note_constexpr_union_member_change_during_init);
6172 llvm_unreachable(
"wrong value kind for union object");
6175 llvm_unreachable(
"wrong value kind for union object");
6180const AccessKinds StartLifetimeOfUnionMemberHandler::AccessKind;
6187 const Expr *LHSExpr,
6188 const LValue &LHS) {
6189 if (LHS.InvalidBase || LHS.Designator.Invalid)
6195 unsigned PathLength = LHS.Designator.Entries.size();
6196 for (
const Expr *
E = LHSExpr;
E !=
nullptr;) {
6198 if (
auto *ME = dyn_cast<MemberExpr>(
E)) {
6199 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
6202 if (!FD || FD->getType()->isReferenceType())
6206 if (FD->getParent()->isUnion()) {
6211 FD->getType()->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
6212 if (!RD || RD->hasTrivialDefaultConstructor())
6213 UnionPathLengths.push_back({PathLength - 1, FD});
6219 LHS.Designator.Entries[PathLength]
6220 .getAsBaseOrMember().getPointer()));
6224 }
else if (
auto *ASE = dyn_cast<ArraySubscriptExpr>(
E)) {
6226 auto *
Base = ASE->getBase()->IgnoreImplicit();
6227 if (!
Base->getType()->isArrayType())
6233 }
else if (
auto *ICE = dyn_cast<ImplicitCastExpr>(
E)) {
6235 E = ICE->getSubExpr();
6236 if (ICE->getCastKind() == CK_NoOp)
6238 if (ICE->getCastKind() != CK_DerivedToBase &&
6239 ICE->getCastKind() != CK_UncheckedDerivedToBase)
6243 if (Elt->isVirtual()) {
6252 LHS.Designator.Entries[PathLength]
6253 .getAsBaseOrMember().getPointer()));
6263 if (UnionPathLengths.empty())
6268 CompleteObject Obj =
6272 for (std::pair<unsigned, const FieldDecl *> LengthAndField :
6273 llvm::reverse(UnionPathLengths)) {
6275 SubobjectDesignator
D = LHS.Designator;
6276 D.truncate(Info.Ctx, LHS.Base, LengthAndField.first);
6278 bool DuringInit = Info.isEvaluatingCtorDtor(LHS.Base,
D.Entries) ==
6279 ConstructionPhase::AfterBases;
6280 StartLifetimeOfUnionMemberHandler StartLifetime{
6281 Info, LHSExpr, LengthAndField.second, DuringInit};
6290 CallRef
Call, EvalInfo &Info,
6298 APValue &
V = PVD ? Info.CurrentCall->createParam(
Call, PVD, LV)
6299 : Info.CurrentCall->createTemporary(Arg, Arg->
getType(),
6300 ScopeKind::Call, LV);
6306 if (
NonNull &&
V.isLValue() &&
V.isNullPointer()) {
6307 Info.CCEDiag(Arg, diag::note_non_null_attribute_failed);
6317 bool RightToLeft =
false) {
6319 llvm::SmallBitVector ForbiddenNullArgs;
6320 if (Callee->hasAttr<NonNullAttr>()) {
6321 ForbiddenNullArgs.resize(Args.size());
6322 for (
const auto *
Attr : Callee->specific_attrs<NonNullAttr>()) {
6323 if (!
Attr->args_size()) {
6324 ForbiddenNullArgs.set();
6327 for (
auto Idx :
Attr->args()) {
6328 unsigned ASTIdx = Idx.getASTIndex();
6329 if (ASTIdx >= Args.size())
6331 ForbiddenNullArgs[ASTIdx] =
true;
6335 for (
unsigned I = 0; I < Args.size(); I++) {
6336 unsigned Idx = RightToLeft ? Args.size() - I - 1 : I;
6338 Idx < Callee->getNumParams() ? Callee->getParamDecl(Idx) :
nullptr;
6339 bool NonNull = !ForbiddenNullArgs.empty() && ForbiddenNullArgs[Idx];
6343 if (!Info.noteFailure())
6355 bool CopyObjectRepresentation) {
6357 CallStackFrame *Frame = Info.CurrentCall;
6358 APValue *RefValue = Info.getParamSlot(Frame->Arguments, Param);
6366 RefLValue.setFrom(Info.Ctx, *RefValue);
6369 CopyObjectRepresentation);
6376 CallRef
Call,
const Stmt *Body, EvalInfo &Info,
6377 APValue &Result,
const LValue *ResultSlot) {
6378 if (!Info.CheckCallLimit(CallLoc))
6403 This->moveInto(Result);
6412 if (!Info.checkingPotentialConstantExpression())
6414 Frame.LambdaThisCaptureField);
6419 if (ESR == ESR_Succeeded) {
6420 if (Callee->getReturnType()->isVoidType())
6422 Info.FFDiag(Callee->getEndLoc(), diag::note_constexpr_no_return);
6424 return ESR == ESR_Returned;
6431 EvalInfo &Info,
APValue &Result) {
6433 if (!Info.CheckCallLimit(CallLoc))
6438 Info.FFDiag(CallLoc, diag::note_constexpr_virtual_base) << RD;
6442 EvalInfo::EvaluatingConstructorRAII EvalObj(
6444 ObjectUnderConstruction{This.getLValueBase(), This.Designator.Entries},
6456 if ((*I)->getInit()->isValueDependent()) {
6460 FullExpressionRAII InitScope(Info);
6462 !InitScope.destroy())
6485 if (!Result.hasValue()) {
6498 BlockScopeRAII LifetimeExtendedScope(Info);
6501 unsigned BasesSeen = 0;
6511 assert(
Indirect &&
"fields out of order?");
6517 assert(FieldIt != RD->
field_end() &&
"missing field?");
6518 if (!FieldIt->isUnnamedBitField())
6521 Result.getStructField(FieldIt->getFieldIndex()));
6526 LValue Subobject = This;
6527 LValue SubobjectParent = This;
6532 if (I->isBaseInitializer()) {
6533 QualType BaseType(I->getBaseClass(), 0);
6537 assert(!BaseIt->
isVirtual() &&
"virtual base for literal type");
6538 assert(Info.Ctx.hasSameUnqualifiedType(BaseIt->
getType(), BaseType) &&
6539 "base class initializers not in expected order");
6545 Value = &Result.getStructBase(BasesSeen++);
6546 }
else if ((FD = I->getMember())) {
6551 Value = &Result.getUnionValue();
6553 SkipToField(FD,
false);
6559 auto IndirectFieldChain = IFD->chain();
6560 for (
auto *
C : IndirectFieldChain) {
6561 FD = cast<FieldDecl>(
C);
6569 (
Value->isUnion() &&
Value->getUnionField() != FD)) {
6581 if (
C == IndirectFieldChain.back())
6582 SubobjectParent = Subobject;
6588 if (
C == IndirectFieldChain.front() && !RD->
isUnion())
6589 SkipToField(FD,
true);
6594 llvm_unreachable(
"unknown base initializer kind");
6601 if (
Init->isValueDependent()) {
6605 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &SubobjectParent,
6606 isa<CXXDefaultInitExpr>(
Init));
6607 FullExpressionRAII InitScope(Info);
6613 if (!Info.noteFailure())
6621 if (I->isBaseInitializer() && BasesSeen == RD->
getNumBases())
6622 EvalObj.finishedConstructingBases();
6627 for (; FieldIt != RD->
field_end(); ++FieldIt) {
6628 if (!FieldIt->isUnnamedBitField())
6631 Result.getStructField(FieldIt->getFieldIndex()));
6635 EvalObj.finishedConstructingFields();
6639 LifetimeExtendedScope.destroy();
6645 EvalInfo &Info,
APValue &Result) {
6646 CallScopeRAII CallScope(Info);
6652 CallScope.destroy();
6664 This.moveInto(Printable);
6666 diag::note_constexpr_destroy_out_of_lifetime)
6667 << Printable.
getAsString(Info.Ctx, Info.Ctx.getLValueReferenceType(
T));
6683 LValue ElemLV = This;
6684 ElemLV.addArray(Info, &LocE, CAT);
6691 if (Size && Size >
Value.getArrayInitializedElts())
6694 for (; Size != 0; --Size) {
6695 APValue &Elem =
Value.getArrayInitializedElt(Size - 1);
6708 if (
T.isDestructedType()) {
6710 diag::note_constexpr_unsupported_destruction)
6720 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_virtual_base) << RD;
6745 if (!Info.CheckCallLimit(CallRange.
getBegin()))
6754 CallStackFrame Frame(Info, CallRange,
Definition, &This,
nullptr,
6759 EvalInfo::EvaluatingDestructorRAII EvalObj(
6761 ObjectUnderConstruction{This.getLValueBase(), This.Designator.Entries});
6762 if (!EvalObj.DidInsert) {
6769 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_double_destroy);
6789 for (
const FieldDecl *FD : llvm::reverse(Fields)) {
6790 if (FD->isUnnamedBitField())
6793 LValue Subobject = This;
6797 APValue *SubobjectValue = &
Value.getStructField(FD->getFieldIndex());
6804 EvalObj.startedDestroyingBases();
6811 LValue Subobject = This;
6816 APValue *SubobjectValue = &
Value.getStructBase(BasesLeft);
6821 assert(BasesLeft == 0 &&
"NumBases was wrong?");
6829struct DestroyObjectHandler {
6835 typedef bool result_type;
6836 bool failed() {
return false; }
6842 Info.FFDiag(
E, diag::note_constexpr_destroy_complex_elem);
6846 Info.FFDiag(
E, diag::note_constexpr_destroy_complex_elem);
6855 const LValue &This,
QualType ThisType) {
6857 DestroyObjectHandler Handler = {Info,
E, This,
AK_Destroy};
6858 return Obj &&
findSubobject(Info,
E, Obj, This.Designator, Handler);
6867 if (Info.EvalStatus.HasSideEffects)
6878 if (Info.checkingPotentialConstantExpression() ||
6879 Info.SpeculativeEvaluationDepth)
6883 auto Caller = Info.getStdAllocatorCaller(
"allocate");
6885 Info.FFDiag(
E->
getExprLoc(), Info.getLangOpts().CPlusPlus20
6886 ? diag::note_constexpr_new_untyped
6887 : diag::note_constexpr_new);
6891 QualType ElemType = Caller.ElemType;
6894 diag::note_constexpr_new_not_complete_object_type)
6902 bool IsNothrow =
false;
6903 for (
unsigned I = 1, N =
E->getNumArgs(); I != N; ++I) {
6911 APInt Size, Remainder;
6912 APInt ElemSizeAP(ByteSize.getBitWidth(), ElemSize.
getQuantity());
6913 APInt::udivrem(ByteSize, ElemSizeAP, Size, Remainder);
6914 if (Remainder != 0) {
6916 Info.FFDiag(
E->
getExprLoc(), diag::note_constexpr_operator_new_bad_size)
6917 << ByteSize <<
APSInt(ElemSizeAP,
true) << ElemType;
6921 if (!Info.CheckArraySize(
E->
getBeginLoc(), ByteSize.getActiveBits(),
6922 Size.getZExtValue(), !IsNothrow)) {
6924 Result.setNull(Info.Ctx,
E->
getType());
6930 QualType AllocType = Info.Ctx.getConstantArrayType(
6931 ElemType, Size,
nullptr, ArraySizeModifier::Normal, 0);
6932 APValue *Val = Info.createHeapAlloc(
E, AllocType, Result);
6934 Result.addArray(Info,
E, cast<ConstantArrayType>(AllocType));
6941 return DD->isVirtual();
6948 return DD->isVirtual() ? DD->getOperatorDelete() :
nullptr;
6959 DynAlloc::Kind DeallocKind) {
6960 auto PointerAsString = [&] {
6961 return Pointer.toString(Info.Ctx, Info.Ctx.VoidPtrTy);
6966 Info.FFDiag(
E, diag::note_constexpr_delete_not_heap_alloc)
6967 << PointerAsString();
6970 return std::nullopt;
6973 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
6975 Info.FFDiag(
E, diag::note_constexpr_double_delete);
6976 return std::nullopt;
6979 if (DeallocKind != (*Alloc)->getKind()) {
6981 Info.FFDiag(
E, diag::note_constexpr_new_delete_mismatch)
6982 << DeallocKind << (*Alloc)->getKind() << AllocType;
6984 return std::nullopt;
6987 bool Subobject =
false;
6988 if (DeallocKind == DynAlloc::New) {
6989 Subobject =
Pointer.Designator.MostDerivedPathLength != 0 ||
6990 Pointer.Designator.isOnePastTheEnd();
6992 Subobject =
Pointer.Designator.Entries.size() != 1 ||
6993 Pointer.Designator.Entries[0].getAsArrayIndex() != 0;
6996 Info.FFDiag(
E, diag::note_constexpr_delete_subobject)
6997 << PointerAsString() <<
Pointer.Designator.isOnePastTheEnd();
6998 return std::nullopt;
7006 if (Info.checkingPotentialConstantExpression() ||
7007 Info.SpeculativeEvaluationDepth)
7011 if (!Info.getStdAllocatorCaller(
"deallocate")) {
7019 for (
unsigned I = 1, N =
E->getNumArgs(); I != N; ++I)
7022 if (
Pointer.Designator.Invalid)
7027 if (
Pointer.isNullPointer()) {
7028 Info.CCEDiag(
E->
getExprLoc(), diag::note_constexpr_deallocate_null);
7044class BitCastBuffer {
7052 static_assert(std::numeric_limits<unsigned char>::digits >= 8,
7053 "Need at least 8 bit unsigned char");
7055 bool TargetIsLittleEndian;
7058 BitCastBuffer(
CharUnits Width,
bool TargetIsLittleEndian)
7059 : Bytes(Width.getQuantity()),
7060 TargetIsLittleEndian(TargetIsLittleEndian) {}
7064 for (
CharUnits I = Offset,
E = Offset + Width; I !=
E; ++I) {
7067 if (!Bytes[I.getQuantity()])
7069 Output.push_back(*Bytes[I.getQuantity()]);
7071 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
7072 std::reverse(Output.begin(), Output.end());
7077 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
7078 std::reverse(Input.begin(), Input.end());
7081 for (
unsigned char Byte : Input) {
7082 assert(!Bytes[Offset.getQuantity() + Index] &&
"overwriting a byte?");
7083 Bytes[Offset.getQuantity() + Index] = Byte;
7088 size_t size() {
return Bytes.size(); }
7093class APValueToBufferConverter {
7095 BitCastBuffer Buffer;
7098 APValueToBufferConverter(EvalInfo &Info,
CharUnits ObjectWidth,
7101 Buffer(ObjectWidth, Info.Ctx.getTargetInfo().isLittleEndian()),
7110 assert((
size_t)Offset.getQuantity() <= Buffer.size());
7123 return visitInt(Val.
getInt(), Ty, Offset);
7125 return visitFloat(Val.
getFloat(), Ty, Offset);
7127 return visitArray(Val, Ty, Offset);
7129 return visitRecord(Val, Ty, Offset);
7131 return visitVector(Val, Ty, Offset);
7142 diag::note_constexpr_bit_cast_unsupported_type)
7148 llvm_unreachable(
"LValue subobject in bit_cast?");
7150 llvm_unreachable(
"Unhandled APValue::ValueKind");
7158 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
7159 for (
size_t I = 0,
E = CXXRD->getNumBases(); I !=
E; ++I) {
7170 unsigned FieldIdx = 0;
7172 if (FD->isBitField()) {
7174 diag::note_constexpr_bit_cast_unsupported_bitfield);
7180 assert(FieldOffsetBits % Info.Ctx.getCharWidth() == 0 &&
7181 "only bit-fields can have sub-char alignment");
7183 Info.Ctx.toCharUnitsFromBits(FieldOffsetBits) + Offset;
7203 for (
unsigned I = 0; I != NumInitializedElts; ++I) {
7205 if (!visit(SubObj, CAT->
getElementType(), Offset + I * ElemWidth))
7212 for (
unsigned I = NumInitializedElts; I != ArraySize; ++I) {
7213 if (!visit(Filler, CAT->
getElementType(), Offset + I * ElemWidth))
7228 if ((NElts * EltSize) % Info.Ctx.getCharWidth() != 0) {
7234 diag::note_constexpr_bit_cast_invalid_vector)
7236 << Info.Ctx.getCharWidth();
7240 if (EltTy->isRealFloatingType() && &Info.Ctx.getFloatTypeSemantics(EltTy) ==
7241 &APFloat::x87DoubleExtended()) {
7246 diag::note_constexpr_bit_cast_unsupported_type)
7260 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
7262 llvm::APInt Res = llvm::APInt::getZero(NElts);
7263 for (
unsigned I = 0; I < NElts; ++I) {
7265 assert(EltAsInt.isUnsigned() && EltAsInt.getBitWidth() == 1 &&
7266 "bool vector element must be 1-bit unsigned integer!");
7268 Res.insertBits(EltAsInt, BigEndian ? (NElts - I - 1) : I);
7272 llvm::StoreIntToMemory(Res, &*Bytes.begin(), NElts / 8);
7273 Buffer.writeObject(Offset, Bytes);
7277 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
7278 for (
unsigned I = 0; I < NElts; ++I) {
7279 if (!visit(Val.
getVectorElt(I), EltTy, Offset + I * EltSizeChars))
7288 APSInt AdjustedVal = Val;
7289 unsigned Width = AdjustedVal.getBitWidth();
7291 Width = Info.Ctx.getTypeSize(Ty);
7292 AdjustedVal = AdjustedVal.extend(Width);
7296 llvm::StoreIntToMemory(AdjustedVal, &*Bytes.begin(), Width / 8);
7297 Buffer.writeObject(Offset, Bytes);
7302 APSInt AsInt(Val.bitcastToAPInt());
7303 return visitInt(AsInt, Ty, Offset);
7307 static std::optional<BitCastBuffer>
7310 APValueToBufferConverter Converter(Info, DstSize, BCE);
7312 return std::nullopt;
7313 return Converter.Buffer;
7318class BufferToAPValueConverter {
7320 const BitCastBuffer &Buffer;
7323 BufferToAPValueConverter(EvalInfo &Info,
const BitCastBuffer &Buffer,
7325 : Info(Info), Buffer(Buffer), BCE(BCE) {}
7330 std::nullopt_t unsupportedType(
QualType Ty) {
7332 diag::note_constexpr_bit_cast_unsupported_type)
7334 return std::nullopt;
7337 std::nullopt_t unrepresentableValue(
QualType Ty,
const APSInt &Val) {
7339 diag::note_constexpr_bit_cast_unrepresentable_value)
7341 return std::nullopt;
7345 const EnumType *EnumSugar =
nullptr) {
7359 const llvm::fltSemantics &Semantics =
7360 Info.Ctx.getFloatTypeSemantics(
QualType(
T, 0));
7361 unsigned NumBits = llvm::APFloatBase::getSizeInBits(Semantics);
7362 assert(NumBits % 8 == 0);
7369 if (!Buffer.readObject(Offset,
SizeOf, Bytes)) {
7372 bool IsStdByte = EnumSugar && EnumSugar->isStdByteType();
7376 if (!IsStdByte && !IsUChar) {
7377 QualType DisplayType(EnumSugar ? (
const Type *)EnumSugar :
T, 0);
7379 diag::note_constexpr_bit_cast_indet_dest)
7380 << DisplayType << Info.Ctx.getLangOpts().CharIsSigned;
7381 return std::nullopt;
7387 APSInt Val(
SizeOf.getQuantity() * Info.Ctx.getCharWidth(),
true);
7388 llvm::LoadIntFromMemory(Val, &*Bytes.begin(), Bytes.size());
7393 unsigned IntWidth = Info.Ctx.getIntWidth(
QualType(
T, 0));
7394 if (IntWidth != Val.getBitWidth()) {
7395 APSInt Truncated = Val.trunc(IntWidth);
7396 if (Truncated.extend(Val.getBitWidth()) != Val)
7397 return unrepresentableValue(
QualType(
T, 0), Val);
7405 const llvm::fltSemantics &Semantics =
7406 Info.Ctx.getFloatTypeSemantics(
QualType(
T, 0));
7417 unsigned NumBases = 0;
7418 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
7419 NumBases = CXXRD->getNumBases();
7425 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
7426 for (
size_t I = 0,
E = CXXRD->getNumBases(); I !=
E; ++I) {
7430 std::optional<APValue> SubObj = visitType(
7433 return std::nullopt;
7434 ResultVal.getStructBase(I) = *SubObj;
7439 unsigned FieldIdx = 0;
7443 if (FD->isBitField()) {
7445 diag::note_constexpr_bit_cast_unsupported_bitfield);
7446 return std::nullopt;
7450 assert(FieldOffsetBits % Info.Ctx.getCharWidth() == 0);
7456 std::optional<APValue> SubObj = visitType(FieldTy, FieldOffset);
7458 return std::nullopt;
7459 ResultVal.getStructField(FieldIdx) = *SubObj;
7468 assert(!RepresentationType.
isNull() &&
7469 "enum forward decl should be caught by Sema");
7470 const auto *AsBuiltin =
7474 return visit(AsBuiltin, Offset, Ty);
7482 for (
size_t I = 0; I !=
Size; ++I) {
7483 std::optional<APValue> ElementValue =
7486 return std::nullopt;
7487 ArrayValue.getArrayInitializedElt(I) = std::move(*ElementValue);
7499 if ((NElts * EltSize) % Info.Ctx.getCharWidth() != 0) {
7505 diag::note_constexpr_bit_cast_invalid_vector)
7506 <<
QualType(VTy, 0) << EltSize << NElts << Info.Ctx.getCharWidth();
7507 return std::nullopt;
7511 &APFloat::x87DoubleExtended()) {
7516 diag::note_constexpr_bit_cast_unsupported_type)
7518 return std::nullopt;
7522 Elts.reserve(NElts);
7532 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
7535 Bytes.reserve(NElts / 8);
7537 return std::nullopt;
7539 APSInt SValInt(NElts,
true);
7540 llvm::LoadIntFromMemory(SValInt, &*Bytes.begin(), Bytes.size());
7542 for (
unsigned I = 0; I < NElts; ++I) {
7544 SValInt.extractBits(1, (BigEndian ? NElts - I - 1 : I) * EltSize);
7551 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
7552 for (
unsigned I = 0; I < NElts; ++I) {
7553 std::optional<APValue> EltValue =
7554 visitType(EltTy, Offset + I * EltSizeChars);
7556 return std::nullopt;
7557 Elts.push_back(std::move(*EltValue));
7561 return APValue(Elts.data(), Elts.size());
7564 std::optional<APValue> visit(
const Type *Ty,
CharUnits Offset) {
7565 return unsupportedType(
QualType(Ty, 0));
7572#define TYPE(Class, Base) \
7574 return visit(cast<Class##Type>(Can.getTypePtr()), Offset);
7575#define ABSTRACT_TYPE(Class, Base)
7576#define NON_CANONICAL_TYPE(Class, Base) \
7578 llvm_unreachable("non-canonical type should be impossible!");
7579#define DEPENDENT_TYPE(Class, Base) \
7582 "dependent types aren't supported in the constant evaluator!");
7583#define NON_CANONICAL_UNLESS_DEPENDENT(Class, Base) \
7585 llvm_unreachable("either dependent or not canonical!");
7586#include "clang/AST/TypeNodes.inc"
7588 llvm_unreachable(
"Unhandled Type::TypeClass");
7593 static std::optional<APValue> convert(EvalInfo &Info, BitCastBuffer &Buffer,
7595 BufferToAPValueConverter Converter(Info, Buffer, BCE);
7603 bool CheckingDest) {
7606 auto diag = [&](
int Reason) {
7608 Info->FFDiag(
Loc, diag::note_constexpr_bit_cast_invalid_type)
7609 << CheckingDest << (Reason == 4) << Reason;
7614 Info->
Note(NoteLoc, diag::note_constexpr_bit_cast_invalid_subtype)
7615 << NoteTy << Construct << Ty;
7629 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(
Record)) {
7631 if (!checkBitCastConstexprEligibilityType(
Loc, BS.
getType(), Info, Ctx,
7636 if (FD->getType()->isReferenceType())
7638 if (!checkBitCastConstexprEligibilityType(
Loc, FD->getType(), Info, Ctx,
7640 return note(0, FD->getType(), FD->getBeginLoc());
7646 Info, Ctx, CheckingDest))
7652static bool checkBitCastConstexprEligibility(EvalInfo *Info,
7655 bool DestOK = checkBitCastConstexprEligibilityType(
7657 bool SourceOK = DestOK && checkBitCastConstexprEligibilityType(
7663static bool handleRValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
7666 assert(
CHAR_BIT == 8 && Info.Ctx.getTargetInfo().getCharWidth() == 8 &&
7667 "no host or target supports non 8-bit chars");
7669 if (!checkBitCastConstexprEligibility(&Info, Info.Ctx, BCE))
7673 std::optional<BitCastBuffer> Buffer =
7674 APValueToBufferConverter::convert(Info, SourceRValue, BCE);
7679 std::optional<APValue> MaybeDestValue =
7680 BufferToAPValueConverter::convert(Info, *Buffer, BCE);
7681 if (!MaybeDestValue)
7684 DestValue = std::move(*MaybeDestValue);
7688static bool handleLValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
7691 assert(
CHAR_BIT == 8 && Info.Ctx.getTargetInfo().getCharWidth() == 8 &&
7692 "no host or target supports non 8-bit chars");
7694 "LValueToRValueBitcast requires an lvalue operand!");
7696 LValue SourceLValue;
7698 SourceLValue.setFrom(Info.Ctx, SourceValue);
7701 SourceRValue,
true))
7704 return handleRValueToRValueBitCast(Info, DestValue, SourceRValue, BCE);
7707template <
class Derived>
7708class ExprEvaluatorBase
7711 Derived &getDerived() {
return static_cast<Derived&
>(*this); }
7713 return getDerived().Success(
V,
E);
7715 bool DerivedZeroInitialization(
const Expr *
E) {
7716 return getDerived().ZeroInitialization(
E);
7722 template<
typename ConditionalOperator>
7724 assert(Info.checkingPotentialConstantExpression());
7729 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
7730 StmtVisitorTy::Visit(
E->getFalseExpr());
7736 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
7738 StmtVisitorTy::Visit(
E->getTrueExpr());
7743 Error(
E, diag::note_constexpr_conditional_never_const);
7747 template<
typename ConditionalOperator>
7751 if (Info.checkingPotentialConstantExpression() && Info.noteFailure()) {
7752 CheckPotentialConstantConditional(
E);
7755 if (Info.noteFailure()) {
7756 StmtVisitorTy::Visit(
E->getTrueExpr());
7757 StmtVisitorTy::Visit(
E->getFalseExpr());
7762 Expr *EvalExpr = BoolResult ?
E->getTrueExpr() :
E->getFalseExpr();
7763 return StmtVisitorTy::Visit(EvalExpr);
7769 typedef ExprEvaluatorBase ExprEvaluatorBaseTy;
7772 return Info.CCEDiag(
E,
D);
7775 bool ZeroInitialization(
const Expr *
E) {
return Error(
E); }
7777 bool IsConstantEvaluatedBuiltinCall(
const CallExpr *
E) {
7778 unsigned BuiltinOp =
E->getBuiltinCallee();
7779 return BuiltinOp != 0 &&
7780 Info.Ctx.BuiltinInfo.isConstantEvaluated(BuiltinOp);
7784 ExprEvaluatorBase(EvalInfo &Info) : Info(Info) {}
7786 EvalInfo &getEvalInfo() {
return Info; }
7795 return Error(
E, diag::note_invalid_subexpr_in_const_expr);
7798 bool VisitStmt(
const Stmt *) {
7799 llvm_unreachable(
"Expression evaluator should not be called on stmts");
7801 bool VisitExpr(
const Expr *
E) {
7806 const auto It =
E->begin();
7807 return StmtVisitorTy::Visit(*It);
7811 return StmtVisitorTy::Visit(
E->getFunctionName());
7814 if (
E->hasAPValueResult())
7815 return DerivedSuccess(
E->getAPValueResult(),
E);
7817 return StmtVisitorTy::Visit(
E->getSubExpr());
7821 {
return StmtVisitorTy::Visit(
E->getSubExpr()); }
7823 {
return StmtVisitorTy::Visit(
E->getSubExpr()); }
7825 {
return StmtVisitorTy::Visit(
E->getSubExpr()); }
7827 {
return StmtVisitorTy::Visit(
E->getChosenSubExpr()); }
7829 {
return StmtVisitorTy::Visit(
E->getResultExpr()); }
7831 {
return StmtVisitorTy::Visit(
E->getReplacement()); }
7833 TempVersionRAII RAII(*Info.CurrentCall);
7834 SourceLocExprScopeGuard Guard(
E, Info.CurrentCall->CurSourceLocExprScope);
7835 return StmtVisitorTy::Visit(
E->getExpr());
7838 TempVersionRAII RAII(*Info.CurrentCall);
7842 SourceLocExprScopeGuard Guard(
E, Info.CurrentCall->CurSourceLocExprScope);
7843 return StmtVisitorTy::Visit(
E->getExpr());
7847 FullExpressionRAII
Scope(Info);
7848 return StmtVisitorTy::Visit(
E->getSubExpr()) &&
Scope.destroy();
7854 return StmtVisitorTy::Visit(
E->getSubExpr());
7858 CCEDiag(
E, diag::note_constexpr_invalid_cast) << 0;
7859 return static_cast<Derived*
>(
this)->VisitCastExpr(
E);
7862 if (!Info.Ctx.getLangOpts().CPlusPlus20)
7863 CCEDiag(
E, diag::note_constexpr_invalid_cast) << 1;
7864 return static_cast<Derived*
>(
this)->VisitCastExpr(
E);
7867 return static_cast<Derived*
>(
this)->VisitCastExpr(
E);
7871 switch (
E->getOpcode()) {
7876 VisitIgnoredValue(
E->getLHS());
7877 return StmtVisitorTy::Visit(
E->getRHS());
7887 return DerivedSuccess(Result,
E);
7893 return StmtVisitorTy::Visit(
E->getSemanticForm());
7900 if (!
Evaluate(Info.CurrentCall->createTemporary(
7901 E->getOpaqueValue(),
7902 getStorageType(Info.Ctx,
E->getOpaqueValue()),
7903 ScopeKind::FullExpression, CommonLV),
7904 Info,
E->getCommon()))
7907 return HandleConditionalOperator(
E);
7911 bool IsBcpCall =
false;
7918 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
7925 if (Info.checkingPotentialConstantExpression() && IsBcpCall)
7928 FoldConstant Fold(Info, IsBcpCall);
7929 if (!HandleConditionalOperator(
E)) {
7930 Fold.keepDiagnostics();
7938 if (
APValue *
Value = Info.CurrentCall->getCurrentTemporary(
E);
7940 return DerivedSuccess(*
Value,
E);
7942 const Expr *Source =
E->getSourceExpr();
7946 assert(0 &&
"OpaqueValueExpr recursively refers to itself");
7949 return StmtVisitorTy::Visit(Source);
7953 for (
const Expr *SemE :
E->semantics()) {
7954 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
7958 if (SemE ==
E->getResultExpr())
7963 if (OVE->isUnique())
7967 if (!
Evaluate(Info.CurrentCall->createTemporary(
7968 OVE, getStorageType(Info.Ctx, OVE),
7969 ScopeKind::FullExpression, LV),
7970 Info, OVE->getSourceExpr()))
7972 }
else if (SemE ==
E->getResultExpr()) {
7973 if (!StmtVisitorTy::Visit(SemE))
7985 if (!handleCallExpr(
E, Result,
nullptr))
7987 return DerivedSuccess(Result,
E);
7991 const LValue *ResultSlot) {
7992 CallScopeRAII CallScope(Info);
7998 LValue *
This =
nullptr, ThisVal;
8000 bool HasQualifier =
false;
8007 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(Callee)) {
8011 Member = dyn_cast<CXXMethodDecl>(ME->getMemberDecl());
8013 return Error(Callee);
8015 HasQualifier = ME->hasQualifier();
8016 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(Callee)) {
8022 Member = dyn_cast<CXXMethodDecl>(
D);
8024 return Error(Callee);
8026 }
else if (
const auto *PDE = dyn_cast<CXXPseudoDestructorExpr>(Callee)) {
8027 if (!Info.getLangOpts().CPlusPlus20)
8028 Info.CCEDiag(PDE, diag::note_constexpr_pseudo_destructor);
8032 return Error(Callee);
8039 if (!CalleeLV.getLValueOffset().isZero())
8040 return Error(Callee);
8041 if (CalleeLV.isNullPointer()) {
8042 Info.FFDiag(Callee, diag::note_constexpr_null_callee)
8046 FD = dyn_cast_or_null<FunctionDecl>(
8047 CalleeLV.getLValueBase().dyn_cast<
const ValueDecl *>());
8049 return Error(Callee);
8052 if (!Info.Ctx.hasSameFunctionTypeIgnoringExceptionSpec(
8059 auto *OCE = dyn_cast<CXXOperatorCallExpr>(
E);
8060 if (OCE && OCE->isAssignmentOp()) {
8061 assert(Args.size() == 2 &&
"wrong number of arguments in assignment");
8062 Call = Info.CurrentCall->createCall(FD);
8063 bool HasThis =
false;
8064 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FD))
8065 HasThis = MD->isImplicitObjectMemberFunction();
8093 if (Info.getLangOpts().CPlusPlus20 && OCE &&
8094 OCE->getOperator() == OO_Equal && MD->
isTrivial() &&
8098 Args = Args.slice(1);
8107 "Number of captures must be zero for conversion to function-ptr");
8118 "A generic lambda's static-invoker function must be a "
8119 "template specialization");
8123 void *InsertPos =
nullptr;
8126 assert(CorrespondingCallOpSpecialization &&
8127 "We must always have a function call operator specialization "
8128 "that corresponds to our static invoker specialization");
8129 assert(isa<CXXMethodDecl>(CorrespondingCallOpSpecialization));
8130 FD = CorrespondingCallOpSpecialization;
8139 Ptr.moveInto(Result);
8140 return CallScope.destroy();
8150 Call = Info.CurrentCall->createCall(FD);
8157 auto *NamedMember = dyn_cast<CXXMethodDecl>(FD);
8158 if (NamedMember && NamedMember->isVirtual() && !HasQualifier) {
8161 CovariantAdjustmentPath);
8164 }
else if (NamedMember && NamedMember->isImplicitObjectMemberFunction()) {
8174 if (
auto *DD = dyn_cast<CXXDestructorDecl>(FD)) {
8175 assert(This &&
"no 'this' pointer for destructor call");
8177 Info.Ctx.getRecordType(DD->getParent())) &&
8178 CallScope.destroy();
8186 Body, Info, Result, ResultSlot))
8189 if (!CovariantAdjustmentPath.empty() &&
8191 CovariantAdjustmentPath))
8194 return CallScope.destroy();
8198 return StmtVisitorTy::Visit(
E->getInitializer());
8201 if (
E->getNumInits() == 0)
8202 return DerivedZeroInitialization(
E);
8203 if (
E->getNumInits() == 1)
8204 return StmtVisitorTy::Visit(
E->getInit(0));
8208 return DerivedZeroInitialization(
E);
8211 return DerivedZeroInitialization(
E);
8214 return DerivedZeroInitialization(
E);
8219 assert(!Info.Ctx.getLangOpts().CPlusPlus11 &&
8220 "missing temporary materialization conversion");
8221 assert(!
E->isArrow() &&
"missing call to bound member function?");
8229 const FieldDecl *FD = dyn_cast<FieldDecl>(
E->getMemberDecl());
8230 if (!FD)
return Error(
E);
8244 DerivedSuccess(Result,
E);
8254 E->getEncodedElementAccess(Indices);
8255 if (Indices.size() == 1) {
8261 for (
unsigned I = 0; I < Indices.size(); ++I) {
8264 APValue VecResult(Elts.data(), Indices.size());
8265 return DerivedSuccess(VecResult,
E);
8273 switch (
E->getCastKind()) {
8277 case CK_AtomicToNonAtomic: {
8282 if (!
Evaluate(AtomicVal, Info,
E->getSubExpr()))
8284 return DerivedSuccess(AtomicVal,
E);
8288 case CK_UserDefinedConversion:
8289 return StmtVisitorTy::Visit(
E->getSubExpr());
8291 case CK_LValueToRValue: {
8300 return DerivedSuccess(RVal,
E);
8302 case CK_LValueToRValueBitCast: {
8303 APValue DestValue, SourceValue;
8304 if (!
Evaluate(SourceValue, Info,
E->getSubExpr()))
8306 if (!handleLValueToRValueBitCast(Info, DestValue, SourceValue,
E))
8308 return DerivedSuccess(DestValue,
E);
8311 case CK_AddressSpaceConversion: {
8315 return DerivedSuccess(
Value,
E);
8323 return VisitUnaryPostIncDec(UO);
8326 return VisitUnaryPostIncDec(UO);
8329 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
8339 return DerivedSuccess(RVal, UO);
8352 BlockScopeRAII
Scope(Info);
8357 const Expr *FinalExpr = dyn_cast<Expr>(*BI);
8359 Info.FFDiag((*BI)->getBeginLoc(),
8360 diag::note_constexpr_stmt_expr_unsupported);
8363 return this->Visit(FinalExpr) &&
Scope.destroy();
8369 if (ESR != ESR_Succeeded) {
8373 if (ESR != ESR_Failed)
8374 Info.FFDiag((*BI)->getBeginLoc(),
8375 diag::note_constexpr_stmt_expr_unsupported);
8380 llvm_unreachable(
"Return from function from the loop above.");
8384 return StmtVisitorTy::Visit(
E->getSelectedExpr());
8388 void VisitIgnoredValue(
const Expr *
E) {
8393 void VisitIgnoredBaseExpression(
const Expr *
E) {
8398 VisitIgnoredValue(
E);
8408template<
class Derived>
8409class LValueExprEvaluatorBase
8410 :
public ExprEvaluatorBase<Derived> {
8414 typedef LValueExprEvaluatorBase LValueExprEvaluatorBaseTy;
8415 typedef ExprEvaluatorBase<Derived> ExprEvaluatorBaseTy;
8422 bool evaluatePointer(
const Expr *
E, LValue &Result) {
8427 LValueExprEvaluatorBase(EvalInfo &Info, LValue &Result,
bool InvalidBaseOK)
8428 : ExprEvaluatorBaseTy(Info), Result(Result),
8429 InvalidBaseOK(InvalidBaseOK) {}
8432 Result.setFrom(this->Info.Ctx,
V);
8441 EvalOK = evaluatePointer(
E->getBase(), Result);
8448 EvalOK = this->Visit(
E->getBase());
8454 Result.setInvalid(
E);
8459 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(
E->getMemberDecl())) {
8482 switch (
E->getOpcode()) {
8484 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
8493 switch (
E->getCastKind()) {
8495 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
8497 case CK_DerivedToBase:
8498 case CK_UncheckedDerivedToBase:
8499 if (!this->Visit(
E->getSubExpr()))
8545class LValueExprEvaluator
8546 :
public LValueExprEvaluatorBase<LValueExprEvaluator> {
8548 LValueExprEvaluator(EvalInfo &Info, LValue &Result,
bool InvalidBaseOK) :
8549 LValueExprEvaluatorBaseTy(Info, Result, InvalidBaseOK) {}
8570 return VisitUnaryPreIncDec(UO);
8573 return VisitUnaryPreIncDec(UO);
8579 switch (
E->getCastKind()) {
8581 return LValueExprEvaluatorBaseTy::VisitCastExpr(
E);
8583 case CK_LValueBitCast:
8584 this->CCEDiag(
E, diag::note_constexpr_invalid_cast)
8585 << 2 << Info.Ctx.getLangOpts().CPlusPlus;
8586 if (!Visit(
E->getSubExpr()))
8588 Result.Designator.setInvalid();
8591 case CK_BaseToDerived:
8592 if (!Visit(
E->getSubExpr()))
8597 if (!Visit(
E->getSubExpr()))
8608 bool LValueToRValueConversion) {
8612 assert(Info.CurrentCall->This ==
nullptr &&
8613 "This should not be set for a static call operator");
8621 if (Self->getType()->isReferenceType()) {
8622 APValue *RefValue = Info.getParamSlot(Info.CurrentCall->Arguments, Self);
8623 Result.setFrom(Info.Ctx, *RefValue);
8625 const ParmVarDecl *VD = Info.CurrentCall->Arguments.getOrigParam(Self);
8626 CallStackFrame *Frame =
8627 Info.getCallFrameAndDepth(Info.CurrentCall->Arguments.CallIndex)
8629 unsigned Version = Info.CurrentCall->Arguments.Version;
8630 Result.set({VD, Frame->Index, Version});
8633 Result = *Info.CurrentCall->This;
8643 if (LValueToRValueConversion) {
8647 Result.setFrom(Info.Ctx, RVal);
8658 bool InvalidBaseOK) {
8662 return LValueExprEvaluator(Info, Result, InvalidBaseOK).Visit(
E);
8665bool LValueExprEvaluator::VisitDeclRefExpr(
const DeclRefExpr *
E) {
8669 return Success(cast<ValueDecl>(
D));
8670 if (
const VarDecl *VD = dyn_cast<VarDecl>(
D))
8671 return VisitVarDecl(
E, VD);
8673 return Visit(BD->getBinding());
8678bool LValueExprEvaluator::VisitVarDecl(
const Expr *
E,
const VarDecl *VD) {
8685 isa<DeclRefExpr>(
E) &&
8686 cast<DeclRefExpr>(
E)->refersToEnclosingVariableOrCapture()) {
8691 if (Info.checkingPotentialConstantExpression())
8694 if (
auto *FD = Info.CurrentCall->LambdaCaptureFields.lookup(VD)) {
8695 const auto *MD = cast<CXXMethodDecl>(Info.CurrentCall->Callee);
8701 CallStackFrame *Frame =
nullptr;
8702 unsigned Version = 0;
8710 CallStackFrame *CurrFrame = Info.CurrentCall;
8711 if (CurrFrame->Callee && CurrFrame->Callee->Equals(VD->
getDeclContext())) {
8715 if (
auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
8716 if (CurrFrame->Arguments) {
8717 VD = CurrFrame->Arguments.getOrigParam(PVD);
8719 Info.getCallFrameAndDepth(CurrFrame->Arguments.CallIndex).first;
8720 Version = CurrFrame->Arguments.Version;
8724 Version = CurrFrame->getCurrentTemporaryVersion(VD);
8731 Result.set({VD, Frame->Index, Version});
8737 if (!Info.getLangOpts().CPlusPlus11) {
8738 Info.CCEDiag(
E, diag::note_constexpr_ltor_non_integral, 1)
8740 Info.Note(VD->
getLocation(), diag::note_declared_at);
8746 if (!
V->hasValue()) {
8749 if (!Info.checkingPotentialConstantExpression())
8750 Info.FFDiag(
E, diag::note_constexpr_use_uninit_reference);
8756bool LValueExprEvaluator::VisitCallExpr(
const CallExpr *
E) {
8757 if (!IsConstantEvaluatedBuiltinCall(
E))
8758 return ExprEvaluatorBaseTy::VisitCallExpr(
E);
8760 switch (
E->getBuiltinCallee()) {
8763 case Builtin::BIas_const:
8764 case Builtin::BIforward:
8765 case Builtin::BIforward_like:
8766 case Builtin::BImove:
8767 case Builtin::BImove_if_noexcept:
8768 if (cast<FunctionDecl>(
E->getCalleeDecl())->isConstexpr())
8769 return Visit(
E->getArg(0));
8773 return ExprEvaluatorBaseTy::VisitCallExpr(
E);
8776bool LValueExprEvaluator::VisitMaterializeTemporaryExpr(
8785 for (
const Expr *
E : CommaLHSs)
8794 if (Info.EvalMode == EvalInfo::EM_ConstantFold)
8797 Value =
E->getOrCreateValue(
true);
8801 Value = &Info.CurrentCall->createTemporary(
8802 E, Inner->getType(),
8817 for (
unsigned I = Adjustments.size(); I != 0; ) {
8819 switch (Adjustments[I].Kind) {
8824 Type = Adjustments[I].DerivedToBase.BasePath->getType();
8830 Type = Adjustments[I].Field->getType();
8835 Adjustments[I].Ptr.RHS))
8837 Type = Adjustments[I].Ptr.MPT->getPointeeType();
8847 assert((!Info.getLangOpts().CPlusPlus ||
E->isFileScope()) &&
8848 "lvalue compound literal in c++?");
8854bool LValueExprEvaluator::VisitCXXTypeidExpr(
const CXXTypeidExpr *
E) {
8857 if (!
E->isPotentiallyEvaluated()) {
8858 if (
E->isTypeOperand())
8863 if (!Info.Ctx.getLangOpts().CPlusPlus20) {
8864 Info.CCEDiag(
E, diag::note_constexpr_typeid_polymorphic)
8869 if (!Visit(
E->getExprOperand()))
8872 std::optional<DynamicType> DynType =
8878 TypeInfoLValue(Info.Ctx.getRecordType(DynType->Type).getTypePtr());
8884bool LValueExprEvaluator::VisitCXXUuidofExpr(
const CXXUuidofExpr *
E) {
8888bool LValueExprEvaluator::VisitMemberExpr(
const MemberExpr *
E) {
8890 if (
const VarDecl *VD = dyn_cast<VarDecl>(
E->getMemberDecl())) {
8891 VisitIgnoredBaseExpression(
E->getBase());
8892 return VisitVarDecl(
E, VD);
8896 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(
E->getMemberDecl())) {
8897 if (MD->isStatic()) {
8898 VisitIgnoredBaseExpression(
E->getBase());
8904 return LValueExprEvaluatorBaseTy::VisitMemberExpr(
E);
8907bool LValueExprEvaluator::VisitExtVectorElementExpr(
8912 if (!
Evaluate(Val, Info,
E->getBase())) {
8913 if (!Info.noteFailure())
8919 E->getEncodedElementAccess(Indices);
8921 if (Indices.size() > 1)
8925 Result.setFrom(Info.Ctx, Val);
8928 VT->getNumElements(), Indices[0]);
8943 if (!
Evaluate(Val, Info,
E->getBase())) {
8944 if (!Info.noteFailure())
8950 if (!Info.noteFailure())
8956 Result.setFrom(Info.Ctx, Val);
8958 VT->getNumElements(), Index.getExtValue());
8966 for (
const Expr *SubExpr : {
E->getLHS(),
E->getRHS()}) {
8967 if (SubExpr ==
E->getBase() ? !evaluatePointer(SubExpr, Result)
8969 if (!Info.noteFailure())
8979bool LValueExprEvaluator::VisitUnaryDeref(
const UnaryOperator *
E) {
8980 return evaluatePointer(
E->getSubExpr(), Result);
8983bool LValueExprEvaluator::VisitUnaryReal(
const UnaryOperator *
E) {
8984 if (!Visit(
E->getSubExpr()))
8992bool LValueExprEvaluator::VisitUnaryImag(
const UnaryOperator *
E) {
8994 "lvalue __imag__ on scalar?");
8995 if (!Visit(
E->getSubExpr()))
9001bool LValueExprEvaluator::VisitUnaryPreIncDec(
const UnaryOperator *UO) {
9002 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9013bool LValueExprEvaluator::VisitCompoundAssignOperator(
9015 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9023 if (!Info.noteFailure())
9039 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9046 if (!
Evaluate(NewVal, this->Info,
E->getRHS())) {
9047 if (!Info.noteFailure())
9052 if (!this->Visit(
E->getLHS()) || !
Success)
9055 if (Info.getLangOpts().CPlusPlus20 &&
9075 llvm::APInt &Result) {
9076 const AllocSizeAttr *AllocSize = getAllocSizeAttr(
Call);
9078 assert(AllocSize && AllocSize->getElemSizeParam().isValid());
9079 unsigned SizeArgNo = AllocSize->getElemSizeParam().getASTIndex();
9081 if (
Call->getNumArgs() <= SizeArgNo)
9084 auto EvaluateAsSizeT = [&](
const Expr *
E,
APSInt &Into) {
9089 if (Into.isNegative() || !Into.isIntN(BitsInSizeT))
9091 Into = Into.zext(BitsInSizeT);
9096 if (!EvaluateAsSizeT(
Call->getArg(SizeArgNo), SizeOfElem))
9099 if (!AllocSize->getNumElemsParam().isValid()) {
9100 Result = std::move(SizeOfElem);
9105 unsigned NumArgNo = AllocSize->getNumElemsParam().getASTIndex();
9106 if (!EvaluateAsSizeT(
Call->getArg(NumArgNo), NumberOfElems))
9110 llvm::APInt BytesAvailable = SizeOfElem.umul_ov(NumberOfElems, Overflow);
9114 Result = std::move(BytesAvailable);
9122 llvm::APInt &Result) {
9123 assert(isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
9124 "Can't get the size of a non alloc_size function");
9125 const auto *
Base = LVal.getLValueBase().get<
const Expr *>();
9145 dyn_cast_or_null<VarDecl>(
Base.dyn_cast<
const ValueDecl *>());
9150 if (!
Init ||
Init->getType().isNull())
9154 if (!tryUnwrapAllocSizeCall(
E))
9159 Result.setInvalid(
E);
9162 Result.addUnsizedArray(Info,
E, Pointee);
9167class PointerExprEvaluator
9168 :
public ExprEvaluatorBase<PointerExprEvaluator> {
9177 bool evaluateLValue(
const Expr *
E, LValue &Result) {
9181 bool evaluatePointer(
const Expr *
E, LValue &Result) {
9185 bool visitNonBuiltinCallExpr(
const CallExpr *
E);
9188 PointerExprEvaluator(EvalInfo &info, LValue &Result,
bool InvalidBaseOK)
9189 : ExprEvaluatorBaseTy(info), Result(Result),
9190 InvalidBaseOK(InvalidBaseOK) {}
9193 Result.setFrom(Info.Ctx,
V);
9196 bool ZeroInitialization(
const Expr *
E) {
9197 Result.setNull(Info.Ctx,
E->
getType());
9207 if (
E->isExpressibleAsConstantInitializer())
9209 if (Info.noteFailure())
9216 bool VisitBuiltinCallExpr(
const CallExpr *
E,
unsigned BuiltinOp);
9218 if (!
E->getBlockDecl()->hasCaptures())
9223 auto DiagnoseInvalidUseOfThis = [&] {
9224 if (Info.getLangOpts().CPlusPlus11)
9225 Info.FFDiag(
E, diag::note_constexpr_this) <<
E->isImplicit();
9231 if (Info.checkingPotentialConstantExpression())
9234 bool IsExplicitLambda =
9236 if (!IsExplicitLambda) {
9237 if (!Info.CurrentCall->This) {
9238 DiagnoseInvalidUseOfThis();
9242 Result = *Info.CurrentCall->This;
9250 if (!Info.CurrentCall->LambdaThisCaptureField) {
9251 if (IsExplicitLambda && !Info.CurrentCall->This) {
9252 DiagnoseInvalidUseOfThis();
9259 const auto *MD = cast<CXXMethodDecl>(Info.CurrentCall->Callee);
9261 Info,
E, Result, MD, Info.CurrentCall->LambdaThisCaptureField,
9270 assert(!
E->isIntType() &&
"SourceLocExpr isn't a pointer type?");
9271 APValue LValResult =
E->EvaluateInContext(
9272 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.getDefaultExpr());
9273 Result.setFrom(Info.Ctx, LValResult);
9278 llvm::report_fatal_error(
"Not yet implemented for ExprConstant.cpp");
9283 std::string ResultStr =
E->ComputeName(Info.Ctx);
9286 APInt Size(Info.Ctx.getTypeSize(Info.Ctx.getSizeType()),
9287 ResultStr.size() + 1);
9288 QualType ArrayTy = Info.Ctx.getConstantArrayType(
9289 CharTy, Size,
nullptr, ArraySizeModifier::Normal, 0);
9293 false, ArrayTy,
E->getLocation());
9295 evaluateLValue(SL, Result);
9296 Result.addArray(Info,
E, cast<ConstantArrayType>(ArrayTy));
9305 bool InvalidBaseOK) {
9308 return PointerExprEvaluator(Info, Result, InvalidBaseOK).Visit(
E);
9311bool PointerExprEvaluator::VisitBinaryOperator(
const BinaryOperator *
E) {
9312 if (
E->getOpcode() != BO_Add &&
9313 E->getOpcode() != BO_Sub)
9314 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
9316 const Expr *PExp =
E->getLHS();
9317 const Expr *IExp =
E->getRHS();
9319 std::swap(PExp, IExp);
9321 bool EvalPtrOK = evaluatePointer(PExp, Result);
9322 if (!EvalPtrOK && !Info.noteFailure())
9325 llvm::APSInt Offset;
9329 if (
E->getOpcode() == BO_Sub)
9336bool PointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *
E) {
9337 return evaluateLValue(
E->getSubExpr(), Result);
9345 if (!FnII || !FnII->
isStr(
"current"))
9348 const auto *RD = dyn_cast<RecordDecl>(FD->
getParent());
9356bool PointerExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
9357 const Expr *SubExpr =
E->getSubExpr();
9359 switch (
E->getCastKind()) {
9363 case CK_CPointerToObjCPointerCast:
9364 case CK_BlockPointerToObjCPointerCast:
9365 case CK_AnyPointerToBlockPointerCast:
9366 case CK_AddressSpaceConversion:
9367 if (!Visit(SubExpr))
9375 bool HasValidResult = !Result.InvalidBase && !Result.Designator.Invalid &&
9377 bool VoidPtrCastMaybeOK =
9380 Info.Ctx.hasSimilarType(Result.Designator.getType(Info.Ctx),
9389 if (VoidPtrCastMaybeOK &&
9390 (Info.getStdAllocatorCaller(
"allocate") ||
9392 Info.getLangOpts().CPlusPlus26)) {
9396 Info.getLangOpts().CPlusPlus) {
9398 CCEDiag(
E, diag::note_constexpr_invalid_void_star_cast)
9399 << SubExpr->
getType() << Info.getLangOpts().CPlusPlus26
9400 << Result.Designator.getType(Info.Ctx).getCanonicalType()
9403 CCEDiag(
E, diag::note_constexpr_invalid_cast)
9406 CCEDiag(
E, diag::note_constexpr_invalid_cast)
9407 << 2 << Info.Ctx.getLangOpts().CPlusPlus;
9408 Result.Designator.setInvalid();
9411 if (
E->getCastKind() == CK_AddressSpaceConversion && Result.IsNullPtr)
9412 ZeroInitialization(
E);
9415 case CK_DerivedToBase:
9416 case CK_UncheckedDerivedToBase:
9417 if (!evaluatePointer(
E->getSubExpr(), Result))
9419 if (!Result.Base && Result.Offset.isZero())
9428 case CK_BaseToDerived:
9429 if (!Visit(
E->getSubExpr()))
9431 if (!Result.Base && Result.Offset.isZero())
9436 if (!Visit(
E->getSubExpr()))
9440 case CK_NullToPointer:
9441 VisitIgnoredValue(
E->getSubExpr());
9442 return ZeroInitialization(
E);
9444 case CK_IntegralToPointer: {
9445 CCEDiag(
E, diag::note_constexpr_invalid_cast)
9446 << 2 << Info.Ctx.getLangOpts().CPlusPlus;
9452 if (
Value.isInt()) {
9454 uint64_t N =
Value.getInt().extOrTrunc(Size).getZExtValue();
9455 Result.Base = (
Expr*)
nullptr;
9456 Result.InvalidBase =
false;
9458 Result.Designator.setInvalid();
9459 Result.IsNullPtr =
false;
9466 if (!
Value.isLValue())
9470 Result.setFrom(Info.Ctx,
Value);
9475 case CK_ArrayToPointerDecay: {
9477 if (!evaluateLValue(SubExpr, Result))
9481 SubExpr, SubExpr->
getType(), ScopeKind::FullExpression, Result);
9486 auto *AT = Info.Ctx.getAsArrayType(SubExpr->
getType());
9487 if (
auto *CAT = dyn_cast<ConstantArrayType>(AT))
9488 Result.addArray(Info,
E, CAT);
9490 Result.addUnsizedArray(Info,
E, AT->getElementType());
9494 case CK_FunctionToPointerDecay:
9495 return evaluateLValue(SubExpr, Result);
9497 case CK_LValueToRValue: {
9499 if (!evaluateLValue(
E->getSubExpr(), LVal))
9506 return InvalidBaseOK &&
9512 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
9520 T =
T.getNonReferenceType();
9522 if (
T.getQualifiers().hasUnaligned())
9525 const bool AlignOfReturnsPreferred =
9526 Info.Ctx.getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver7;
9531 if (ExprKind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
9532 return Info.Ctx.toCharUnitsFromBits(
9533 Info.Ctx.getPreferredTypeAlign(
T.getTypePtr()));
9535 else if (ExprKind == UETT_AlignOf)
9536 return Info.Ctx.getTypeAlignInChars(
T.getTypePtr());
9538 llvm_unreachable(
"GetAlignOfType on a non-alignment ExprKind");
9552 return Info.Ctx.getDeclAlign(DRE->getDecl(),
9555 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(
E))
9556 return Info.Ctx.getDeclAlign(ME->getMemberDecl(),
9564 return Info.Ctx.getDeclAlign(VD);
9565 if (
const auto *
E =
Value.Base.dyn_cast<
const Expr *>())
9573 EvalInfo &Info,
APSInt &Alignment) {
9576 if (Alignment < 0 || !Alignment.isPowerOf2()) {
9577 Info.FFDiag(
E, diag::note_constexpr_invalid_alignment) << Alignment;
9580 unsigned SrcWidth = Info.Ctx.getIntWidth(ForType);
9581 APSInt MaxValue(APInt::getOneBitSet(SrcWidth, SrcWidth - 1));
9582 if (APSInt::compareValues(Alignment, MaxValue) > 0) {
9583 Info.FFDiag(
E, diag::note_constexpr_alignment_too_big)
9584 << MaxValue << ForType << Alignment;
9590 APSInt(Alignment.zextOrTrunc(SrcWidth),
true);
9591 assert(APSInt::compareValues(Alignment, ExtAlignment) == 0 &&
9592 "Alignment should not be changed by ext/trunc");
9593 Alignment = ExtAlignment;
9594 assert(Alignment.getBitWidth() == SrcWidth);
9599bool PointerExprEvaluator::visitNonBuiltinCallExpr(
const CallExpr *
E) {
9600 if (ExprEvaluatorBaseTy::VisitCallExpr(
E))
9603 if (!(InvalidBaseOK && getAllocSizeAttr(
E)))
9606 Result.setInvalid(
E);
9608 Result.addUnsizedArray(Info,
E, PointeeTy);
9612bool PointerExprEvaluator::VisitCallExpr(
const CallExpr *
E) {
9613 if (!IsConstantEvaluatedBuiltinCall(
E))
9614 return visitNonBuiltinCallExpr(
E);
9615 return VisitBuiltinCallExpr(
E,
E->getBuiltinCallee());
9624bool PointerExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *
E,
9625 unsigned BuiltinOp) {
9629 switch (BuiltinOp) {
9630 case Builtin::BIaddressof:
9631 case Builtin::BI__addressof:
9632 case Builtin::BI__builtin_addressof:
9633 return evaluateLValue(
E->getArg(0), Result);
9634 case Builtin::BI__builtin_assume_aligned: {
9638 if (!evaluatePointer(
E->getArg(0), Result))
9641 LValue OffsetResult(Result);
9648 if (
E->getNumArgs() > 2) {
9653 int64_t AdditionalOffset = -Offset.getZExtValue();
9658 if (OffsetResult.Base) {
9661 if (BaseAlignment < Align) {
9662 Result.Designator.setInvalid();
9664 CCEDiag(
E->getArg(0),
9665 diag::note_constexpr_baa_insufficient_alignment) << 0
9673 if (OffsetResult.Offset.alignTo(Align) != OffsetResult.Offset) {
9674 Result.Designator.setInvalid();
9677 ? CCEDiag(
E->getArg(0),
9678 diag::note_constexpr_baa_insufficient_alignment) << 1
9679 : CCEDiag(
E->getArg(0),
9680 diag::note_constexpr_baa_value_insufficient_alignment))
9681 << (
int)OffsetResult.Offset.getQuantity()
9688 case Builtin::BI__builtin_align_up:
9689 case Builtin::BI__builtin_align_down: {
9690 if (!evaluatePointer(
E->getArg(0), Result))
9709 assert(Alignment.getBitWidth() <= 64 &&
9710 "Cannot handle > 64-bit address-space");
9711 uint64_t Alignment64 = Alignment.getZExtValue();
9713 BuiltinOp == Builtin::BI__builtin_align_down
9714 ? llvm::alignDown(Result.Offset.getQuantity(), Alignment64)
9715 : llvm::alignTo(Result.Offset.getQuantity(), Alignment64));
9716 Result.adjustOffset(NewOffset - Result.Offset);
9721 Info.FFDiag(
E->getArg(0), diag::note_constexpr_alignment_adjust)
9725 case Builtin::BI__builtin_operator_new:
9727 case Builtin::BI__builtin_launder:
9728 return evaluatePointer(
E->getArg(0), Result);
9729 case Builtin::BIstrchr:
9730 case Builtin::BIwcschr:
9731 case Builtin::BImemchr:
9732 case Builtin::BIwmemchr:
9733 if (Info.getLangOpts().CPlusPlus11)
9734 Info.CCEDiag(
E, diag::note_constexpr_invalid_function)
9736 << (
"'" + Info.Ctx.BuiltinInfo.getName(BuiltinOp) +
"'").str();
9738 Info.CCEDiag(
E, diag::note_invalid_subexpr_in_const_expr);
9740 case Builtin::BI__builtin_strchr:
9741 case Builtin::BI__builtin_wcschr:
9742 case Builtin::BI__builtin_memchr:
9743 case Builtin::BI__builtin_char_memchr:
9744 case Builtin::BI__builtin_wmemchr: {
9745 if (!Visit(
E->getArg(0)))
9751 if (BuiltinOp != Builtin::BIstrchr &&
9752 BuiltinOp != Builtin::BIwcschr &&
9753 BuiltinOp != Builtin::BI__builtin_strchr &&
9754 BuiltinOp != Builtin::BI__builtin_wcschr) {
9758 MaxLength = N.getZExtValue();
9761 if (MaxLength == 0u)
9762 return ZeroInitialization(
E);
9763 if (!Result.checkNullPointerForFoldAccess(Info,
E,
AK_Read) ||
9764 Result.Designator.Invalid)
9766 QualType CharTy = Result.Designator.getType(Info.Ctx);
9767 bool IsRawByte = BuiltinOp == Builtin::BImemchr ||
9768 BuiltinOp == Builtin::BI__builtin_memchr;
9770 Info.Ctx.hasSameUnqualifiedType(
9774 Info.FFDiag(
E, diag::note_constexpr_ltor_incomplete_type) << CharTy;
9780 Info.FFDiag(
E, diag::note_constexpr_memchr_unsupported)
9781 << (
"'" + Info.Ctx.BuiltinInfo.getName(BuiltinOp) +
"'").str()
9788 bool StopAtNull =
false;
9789 switch (BuiltinOp) {
9790 case Builtin::BIstrchr:
9791 case Builtin::BI__builtin_strchr:
9798 return ZeroInitialization(
E);
9801 case Builtin::BImemchr:
9802 case Builtin::BI__builtin_memchr:
9803 case Builtin::BI__builtin_char_memchr:
9807 DesiredVal = Desired.trunc(Info.Ctx.getCharWidth()).getZExtValue();
9810 case Builtin::BIwcschr:
9811 case Builtin::BI__builtin_wcschr:
9814 case Builtin::BIwmemchr:
9815 case Builtin::BI__builtin_wmemchr:
9817 DesiredVal = Desired.getZExtValue();
9821 for (; MaxLength; --MaxLength) {
9826 if (Char.
getInt().getZExtValue() == DesiredVal)
9828 if (StopAtNull && !Char.
getInt())
9834 return ZeroInitialization(
E);
9837 case Builtin::BImemcpy:
9838 case Builtin::BImemmove:
9839 case Builtin::BIwmemcpy:
9840 case Builtin::BIwmemmove:
9841 if (Info.getLangOpts().CPlusPlus11)
9842 Info.CCEDiag(
E, diag::note_constexpr_invalid_function)
9844 << (
"'" + Info.Ctx.BuiltinInfo.getName(BuiltinOp) +
"'").str();
9846 Info.CCEDiag(
E, diag::note_invalid_subexpr_in_const_expr);
9848 case Builtin::BI__builtin_memcpy:
9849 case Builtin::BI__builtin_memmove:
9850 case Builtin::BI__builtin_wmemcpy:
9851 case Builtin::BI__builtin_wmemmove: {
9852 bool WChar = BuiltinOp == Builtin::BIwmemcpy ||
9853 BuiltinOp == Builtin::BIwmemmove ||
9854 BuiltinOp == Builtin::BI__builtin_wmemcpy ||
9855 BuiltinOp == Builtin::BI__builtin_wmemmove;
9856 bool Move = BuiltinOp == Builtin::BImemmove ||
9857 BuiltinOp == Builtin::BIwmemmove ||
9858 BuiltinOp == Builtin::BI__builtin_memmove ||
9859 BuiltinOp == Builtin::BI__builtin_wmemmove;
9862 if (!Visit(
E->getArg(0)))
9864 LValue Dest = Result;
9873 assert(!N.isSigned() &&
"memcpy and friends take an unsigned size");
9883 if (!Src.Base || !Dest.Base) {
9885 (!Src.Base ? Src : Dest).moveInto(Val);
9886 Info.FFDiag(
E, diag::note_constexpr_memcpy_null)
9887 <<
Move << WChar << !!Src.Base
9891 if (Src.Designator.Invalid || Dest.Designator.Invalid)
9897 QualType T = Dest.Designator.getType(Info.Ctx);
9898 QualType SrcT = Src.Designator.getType(Info.Ctx);
9899 if (!Info.Ctx.hasSameUnqualifiedType(
T, SrcT)) {
9901 Info.FFDiag(
E, diag::note_constexpr_memcpy_type_pun) <<
Move << SrcT <<
T;
9905 Info.FFDiag(
E, diag::note_constexpr_memcpy_incomplete_type) <<
Move <<
T;
9908 if (!
T.isTriviallyCopyableType(Info.Ctx)) {
9909 Info.FFDiag(
E, diag::note_constexpr_memcpy_nontrivial) <<
Move <<
T;
9914 uint64_t TSize = Info.Ctx.getTypeSizeInChars(
T).getQuantity();
9919 llvm::APInt OrigN = N;
9920 llvm::APInt::udivrem(OrigN, TSize, N, Remainder);
9922 Info.FFDiag(
E, diag::note_constexpr_memcpy_unsupported)
9932 uint64_t RemainingSrcSize = Src.Designator.validIndexAdjustments().second;
9933 uint64_t RemainingDestSize = Dest.Designator.validIndexAdjustments().second;
9934 if (N.ugt(RemainingSrcSize) || N.ugt(RemainingDestSize)) {
9935 Info.FFDiag(
E, diag::note_constexpr_memcpy_unsupported)
9936 <<
Move << WChar << (N.ugt(RemainingSrcSize) ? 1 : 2) <<
T
9940 uint64_t NElems = N.getZExtValue();
9946 uint64_t SrcOffset = Src.getLValueOffset().getQuantity();
9947 uint64_t DestOffset = Dest.getLValueOffset().getQuantity();
9948 if (DestOffset >= SrcOffset && DestOffset - SrcOffset < NBytes) {
9951 Info.FFDiag(
E, diag::note_constexpr_memcpy_overlap) << WChar;
9959 }
else if (!Move && SrcOffset >= DestOffset &&
9960 SrcOffset - DestOffset < NBytes) {
9962 Info.FFDiag(
E, diag::note_constexpr_memcpy_overlap) << WChar;
9997bool PointerExprEvaluator::VisitCXXNewExpr(
const CXXNewExpr *
E) {
9998 if (!Info.getLangOpts().CPlusPlus20)
9999 Info.CCEDiag(
E, diag::note_constexpr_new);
10002 if (Info.SpeculativeEvaluationDepth)
10007 bool IsNothrow =
false;
10008 bool IsPlacement =
false;
10010 Info.CurrentCall->isStdFunction() && !
E->isArray()) {
10012 assert(
E->getNumPlacementArgs() == 1);
10015 if (Result.Designator.Invalid)
10017 IsPlacement =
true;
10019 Info.FFDiag(
E, diag::note_constexpr_new_non_replaceable)
10020 << isa<CXXMethodDecl>(OperatorNew) << OperatorNew;
10022 }
else if (
E->getNumPlacementArgs()) {
10033 if (
E->getNumPlacementArgs() != 1 ||
10035 return Error(
E, diag::note_constexpr_new_placement);
10043 const Expr *
Init =
E->getInitializer();
10046 bool ValueInit =
false;
10048 QualType AllocType =
E->getAllocatedType();
10049 if (std::optional<const Expr *> ArraySize =
E->getArraySize()) {
10050 const Expr *Stripped = *ArraySize;
10051 for (;
auto *ICE = dyn_cast<ImplicitCastExpr>(Stripped);
10052 Stripped = ICE->getSubExpr())
10053 if (ICE->getCastKind() != CK_NoOp &&
10054 ICE->getCastKind() != CK_IntegralCast)
10057 llvm::APSInt ArrayBound;
10065 if (ArrayBound.isSigned() && ArrayBound.isNegative()) {
10067 return ZeroInitialization(
E);
10069 Info.FFDiag(*ArraySize, diag::note_constexpr_new_negative)
10070 << ArrayBound << (*ArraySize)->getSourceRange();
10076 if (!Info.CheckArraySize(ArraySize.value()->getExprLoc(),
10078 Info.Ctx, AllocType, ArrayBound),
10079 ArrayBound.getZExtValue(), !IsNothrow)) {
10081 return ZeroInitialization(
E);
10090 }
else if (isa<CXXScalarValueInitExpr>(
Init) ||
10091 isa<ImplicitValueInitExpr>(
Init)) {
10093 }
else if (
auto *CCE = dyn_cast<CXXConstructExpr>(
Init)) {
10094 ResizedArrayCCE = CCE;
10096 auto *CAT = Info.Ctx.getAsConstantArrayType(
Init->getType());
10097 assert(CAT &&
"unexpected type for array initializer");
10101 llvm::APInt InitBound = CAT->
getSize().zext(Bits);
10102 llvm::APInt AllocBound = ArrayBound.zext(Bits);
10103 if (InitBound.ugt(AllocBound)) {
10105 return ZeroInitialization(
E);
10107 Info.FFDiag(*ArraySize, diag::note_constexpr_new_too_small)
10108 <<
toString(AllocBound, 10,
false)
10110 << (*ArraySize)->getSourceRange();
10116 if (InitBound != AllocBound)
10117 ResizedArrayILE = cast<InitListExpr>(
Init);
10120 AllocType = Info.Ctx.getConstantArrayType(AllocType, ArrayBound,
nullptr,
10121 ArraySizeModifier::Normal, 0);
10124 "array allocation with non-array new");
10130 struct FindObjectHandler {
10137 typedef bool result_type;
10138 bool failed() {
return false; }
10142 if (!Info.Ctx.hasSameUnqualifiedType(SubobjType, AllocType)) {
10143 Info.FFDiag(
E, diag::note_constexpr_placement_new_wrong_type) <<
10144 SubobjType << AllocType;
10151 Info.FFDiag(
E, diag::note_constexpr_construct_complex_elem);
10155 Info.FFDiag(
E, diag::note_constexpr_construct_complex_elem);
10158 } Handler = {Info,
E, AllocType, AK,
nullptr};
10161 if (!Obj || !
findSubobject(Info,
E, Obj, Result.Designator, Handler))
10164 Val = Handler.Value;
10173 Val = Info.createHeapAlloc(
E, AllocType, Result);
10182 }
else if (ResizedArrayILE) {
10186 }
else if (ResizedArrayCCE) {
10200 Result.addArray(Info,
E, cast<ConstantArrayType>(AT));
10209class MemberPointerExprEvaluator
10210 :
public ExprEvaluatorBase<MemberPointerExprEvaluator> {
10214 Result = MemberPtr(
D);
10219 MemberPointerExprEvaluator(EvalInfo &Info, MemberPtr &Result)
10220 : ExprEvaluatorBaseTy(Info), Result(Result) {}
10226 bool ZeroInitialization(
const Expr *
E) {
10239 return MemberPointerExprEvaluator(Info, Result).Visit(
E);
10242bool MemberPointerExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
10243 switch (
E->getCastKind()) {
10245 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
10247 case CK_NullToMemberPointer:
10248 VisitIgnoredValue(
E->getSubExpr());
10249 return ZeroInitialization(
E);
10251 case CK_BaseToDerivedMemberPointer: {
10252 if (!Visit(
E->getSubExpr()))
10254 if (
E->path_empty())
10259 typedef std::reverse_iterator<CastExpr::path_const_iterator> ReverseIter;
10260 for (ReverseIter PathI(
E->path_end() - 1), PathE(
E->path_begin());
10261 PathI != PathE; ++PathI) {
10262 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
10263 const CXXRecordDecl *Derived = (*PathI)->getType()->getAsCXXRecordDecl();
10264 if (!Result.castToDerived(Derived))
10273 case CK_DerivedToBaseMemberPointer:
10274 if (!Visit(
E->getSubExpr()))
10277 PathE =
E->path_end(); PathI != PathE; ++PathI) {
10278 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
10280 if (!Result.castToBase(
Base))
10287bool MemberPointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *
E) {
10290 return Success(cast<DeclRefExpr>(
E->getSubExpr())->getDecl());
10298 class RecordExprEvaluator
10299 :
public ExprEvaluatorBase<RecordExprEvaluator> {
10300 const LValue &
This;
10304 RecordExprEvaluator(EvalInfo &info,
const LValue &This,
APValue &Result)
10305 : ExprEvaluatorBaseTy(info),
This(
This), Result(Result) {}
10311 bool ZeroInitialization(
const Expr *
E) {
10312 return ZeroInitialization(
E,
E->
getType());
10316 bool VisitCallExpr(
const CallExpr *
E) {
10317 return handleCallExpr(
E, Result, &This);
10322 return VisitCXXConstructExpr(
E,
E->
getType());
10330 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
10344 const LValue &This,
APValue &Result) {
10345 assert(!RD->
isUnion() &&
"Expected non-union class type");
10354 unsigned Index = 0;
10356 End = CD->
bases_end(); I != End; ++I, ++Index) {
10358 LValue Subobject = This;
10362 Result.getStructBase(Index)))
10367 for (
const auto *I : RD->
fields()) {
10369 if (I->isUnnamedBitField() || I->getType()->isReferenceType())
10372 LValue Subobject = This;
10378 Result.getStructField(I->getFieldIndex()), Info, Subobject, &VIE))
10385bool RecordExprEvaluator::ZeroInitialization(
const Expr *
E,
QualType T) {
10392 while (I != RD->
field_end() && (*I)->isUnnamedBitField())
10399 LValue Subobject =
This;
10404 return EvaluateInPlace(Result.getUnionValue(), Info, Subobject, &VIE);
10407 if (isa<CXXRecordDecl>(RD) && cast<CXXRecordDecl>(RD)->getNumVBases()) {
10408 Info.FFDiag(
E, diag::note_constexpr_virtual_base) << RD;
10415bool RecordExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
10416 switch (
E->getCastKind()) {
10418 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
10420 case CK_ConstructorConversion:
10421 return Visit(
E->getSubExpr());
10423 case CK_DerivedToBase:
10424 case CK_UncheckedDerivedToBase: {
10426 if (!
Evaluate(DerivedObject, Info,
E->getSubExpr()))
10429 return Error(
E->getSubExpr());
10435 PathE =
E->path_end(); PathI != PathE; ++PathI) {
10436 assert(!(*PathI)->isVirtual() &&
"record rvalue with virtual base");
10447bool RecordExprEvaluator::VisitInitListExpr(
const InitListExpr *
E) {
10448 if (
E->isTransparent())
10449 return Visit(
E->getInit(0));
10450 return VisitCXXParenListOrInitListExpr(
E,
E->inits());
10453bool RecordExprEvaluator::VisitCXXParenListOrInitListExpr(
10459 auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
10461 EvalInfo::EvaluatingConstructorRAII EvalObj(
10463 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries},
10464 CXXRD && CXXRD->getNumBases());
10468 if (
auto *ILE = dyn_cast<InitListExpr>(ExprToVisit)) {
10469 Field = ILE->getInitializedFieldInUnion();
10470 }
else if (
auto *PLIE = dyn_cast<CXXParenListInitExpr>(ExprToVisit)) {
10471 Field = PLIE->getInitializedFieldInUnion();
10474 "Expression is neither an init list nor a C++ paren list");
10487 const Expr *InitExpr = Args.empty() ? &VIE : Args[0];
10489 LValue Subobject =
This;
10494 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
10495 isa<CXXDefaultInitExpr>(InitExpr));
10497 if (
EvaluateInPlace(Result.getUnionValue(), Info, Subobject, InitExpr)) {
10498 if (
Field->isBitField())
10507 if (!Result.hasValue())
10510 unsigned ElementNo = 0;
10514 if (CXXRD && CXXRD->getNumBases()) {
10515 for (
const auto &
Base : CXXRD->bases()) {
10516 assert(ElementNo < Args.size() &&
"missing init for base class");
10517 const Expr *
Init = Args[ElementNo];
10519 LValue Subobject =
This;
10523 APValue &FieldVal = Result.getStructBase(ElementNo);
10525 if (!Info.noteFailure())
10532 EvalObj.finishedConstructingBases();
10536 for (
const auto *Field : RD->
fields()) {
10539 if (
Field->isUnnamedBitField())
10542 LValue Subobject =
This;
10544 bool HaveInit = ElementNo < Args.size();
10549 Subobject, Field, &Layout))
10555 const Expr *
Init = HaveInit ? Args[ElementNo++] : &VIE;
10557 if (
Field->getType()->isIncompleteArrayType()) {
10558 if (
auto *CAT = Info.Ctx.getAsConstantArrayType(
Init->getType())) {
10562 Info.FFDiag(
Init, diag::note_constexpr_unsupported_flexible_array);
10569 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
10570 isa<CXXDefaultInitExpr>(
Init));
10572 APValue &FieldVal = Result.getStructField(
Field->getFieldIndex());
10575 FieldVal, Field))) {
10576 if (!Info.noteFailure())
10582 EvalObj.finishedConstructingFields();
10594 bool ZeroInit =
E->requiresZeroInitialization();
10597 if (Result.hasValue())
10601 return ZeroInitialization(
E,
T);
10613 if (
E->isElidable() && !ZeroInit) {
10619 const Expr *SrcObj =
E->getArg(0);
10621 assert(Info.Ctx.hasSameUnqualifiedType(
E->
getType(), SrcObj->
getType()));
10623 dyn_cast<MaterializeTemporaryExpr>(SrcObj))
10624 return Visit(ME->getSubExpr());
10627 if (ZeroInit && !ZeroInitialization(
E,
T))
10636bool RecordExprEvaluator::VisitCXXInheritedCtorInitExpr(
10638 if (!Info.CurrentCall) {
10639 assert(Info.checkingPotentialConstantExpression());
10658bool RecordExprEvaluator::VisitCXXStdInitializerListExpr(
10661 Info.Ctx.getAsConstantArrayType(
E->getSubExpr()->
getType());
10667 assert(
ArrayType &&
"unexpected type for array initializer");
10674 Array.moveInto(Result.getStructField(0));
10678 assert(Field !=
Record->field_end() &&
10679 Info.Ctx.hasSameType(
Field->getType()->getPointeeType(),
10681 "Expected std::initializer_list first field to be const E *");
10683 assert(Field !=
Record->field_end() &&
10684 "Expected std::initializer_list to have two fields");
10686 if (Info.Ctx.hasSameType(
Field->getType(), Info.Ctx.getSizeType())) {
10691 assert(Info.Ctx.hasSameType(
Field->getType()->getPointeeType(),
10693 "Expected std::initializer_list second field to be const E *");
10698 Array.moveInto(Result.getStructField(1));
10701 assert(++Field ==
Record->field_end() &&
10702 "Expected std::initializer_list to only have two fields");
10707bool RecordExprEvaluator::VisitLambdaExpr(
const LambdaExpr *
E) {
10712 const size_t NumFields =
10715 assert(NumFields == (
size_t)std::distance(
E->capture_init_begin(),
10716 E->capture_init_end()) &&
10717 "The number of lambda capture initializers should equal the number of "
10718 "fields within the closure type");
10723 auto *CaptureInitIt =
E->capture_init_begin();
10725 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(ClosureClass);
10726 for (
const auto *Field : ClosureClass->
fields()) {
10727 assert(CaptureInitIt !=
E->capture_init_end());
10729 Expr *
const CurFieldInit = *CaptureInitIt++;
10736 LValue Subobject =
This;
10741 APValue &FieldVal = Result.getStructField(
Field->getFieldIndex());
10743 if (!Info.keepEvaluatingAfterFailure())
10752 APValue &Result, EvalInfo &Info) {
10755 "can't evaluate expression as a record rvalue");
10756 return RecordExprEvaluator(Info, This, Result).Visit(
E);
10767class TemporaryExprEvaluator
10768 :
public LValueExprEvaluatorBase<TemporaryExprEvaluator> {
10770 TemporaryExprEvaluator(EvalInfo &Info, LValue &Result) :
10771 LValueExprEvaluatorBaseTy(Info, Result,
false) {}
10774 bool VisitConstructExpr(
const Expr *
E) {
10776 E,
E->
getType(), ScopeKind::FullExpression, Result);
10780 bool VisitCastExpr(
const CastExpr *
E) {
10781 switch (
E->getCastKind()) {
10783 return LValueExprEvaluatorBaseTy::VisitCastExpr(
E);
10785 case CK_ConstructorConversion:
10786 return VisitConstructExpr(
E->getSubExpr());
10790 return VisitConstructExpr(
E);
10793 return VisitConstructExpr(
E);
10795 bool VisitCallExpr(
const CallExpr *
E) {
10796 return VisitConstructExpr(
E);
10799 return VisitConstructExpr(
E);
10802 return VisitConstructExpr(
E);
10811 return TemporaryExprEvaluator(Info, Result).Visit(
E);
10819 class VectorExprEvaluator
10820 :
public ExprEvaluatorBase<VectorExprEvaluator> {
10824 VectorExprEvaluator(EvalInfo &info,
APValue &Result)
10825 : ExprEvaluatorBaseTy(info), Result(Result) {}
10834 assert(
V.isVector());
10838 bool ZeroInitialization(
const Expr *
E);
10841 {
return Visit(
E->getSubExpr()); }
10857 "not a vector prvalue");
10858 return VectorExprEvaluator(Info, Result).Visit(
E);
10861bool VectorExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
10865 const Expr *SE =
E->getSubExpr();
10868 switch (
E->getCastKind()) {
10869 case CK_VectorSplat: {
10875 Val =
APValue(std::move(IntResult));
10880 Val =
APValue(std::move(FloatResult));
10897 Info.FFDiag(
E, diag::note_constexpr_invalid_cast)
10898 << 2 << Info.Ctx.getLangOpts().CPlusPlus;
10902 if (!handleRValueToRValueBitCast(Info, Result, SVal,
E))
10908 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
10913VectorExprEvaluator::VisitInitListExpr(
const InitListExpr *
E) {
10915 unsigned NumInits =
E->getNumInits();
10925 unsigned CountInits = 0, CountElts = 0;
10926 while (CountElts < NumElements) {
10928 if (CountInits < NumInits
10933 unsigned vlen =
v.getVectorLength();
10934 for (
unsigned j = 0; j < vlen; j++)
10935 Elements.push_back(
v.getVectorElt(j));
10938 llvm::APSInt sInt(32);
10939 if (CountInits < NumInits) {
10943 sInt = Info.Ctx.MakeIntValue(0, EltTy);
10944 Elements.push_back(
APValue(sInt));
10947 llvm::APFloat f(0.0);
10948 if (CountInits < NumInits) {
10952 f = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy));
10953 Elements.push_back(
APValue(f));
10962VectorExprEvaluator::ZeroInitialization(
const Expr *
E) {
10966 if (EltTy->isIntegerType())
10967 ZeroElement =
APValue(Info.Ctx.MakeIntValue(0, EltTy));
10970 APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy)));
10976bool VectorExprEvaluator::VisitUnaryImag(
const UnaryOperator *
E) {
10977 VisitIgnoredValue(
E->getSubExpr());
10978 return ZeroInitialization(
E);
10981bool VectorExprEvaluator::VisitBinaryOperator(
const BinaryOperator *
E) {
10983 assert(Op != BO_PtrMemD && Op != BO_PtrMemI && Op != BO_Cmp &&
10984 "Operation not supported on vector types");
10986 if (Op == BO_Comma)
10987 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
10989 Expr *LHS =
E->getLHS();
10990 Expr *RHS =
E->getRHS();
10993 "Must both be vector types");
11000 "All operands must be the same size.");
11004 bool LHSOK =
Evaluate(LHSValue, Info, LHS);
11005 if (!LHSOK && !Info.noteFailure())
11007 if (!
Evaluate(RHSValue, Info, RHS) || !LHSOK)
11029 "Vector can only be int or float type");
11037 "Vector operator ~ can only be int");
11038 Elt.
getInt().flipAllBits();
11048 "Vector can only be int or float type");
11054 EltResult.setAllBits();
11056 EltResult.clearAllBits();
11062 return std::nullopt;
11066bool VectorExprEvaluator::VisitUnaryOperator(
const UnaryOperator *
E) {
11067 Expr *SubExpr =
E->getSubExpr();
11072 const QualType ResultEltTy = VD->getElementType();
11076 if (!
Evaluate(SubExprValue, Info, SubExpr))
11089 "Vector length doesn't match type?");
11092 for (
unsigned EltNum = 0; EltNum < VD->getNumElements(); ++EltNum) {
11094 Info.Ctx, ResultEltTy, Op, SubExprValue.
getVectorElt(EltNum));
11097 ResultElements.push_back(*Elt);
11099 return Success(
APValue(ResultElements.data(), ResultElements.size()),
E);
11108 Result =
APValue(APFloat(0.0));
11110 DestTy, Result.getFloat());
11121 Result.getFloat());
11126 DestTy, Result.getInt());
11130 Info.FFDiag(
E, diag::err_convertvector_constexpr_unsupported_vector_cast)
11131 << SourceTy << DestTy;
11148 ResultElements.reserve(SourceLen);
11149 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11154 ResultElements.push_back(std::move(Elt));
11157 return Success(
APValue(ResultElements.data(), ResultElements.size()),
E);
11162 APValue const &VecVal2,
unsigned EltNum,
11164 unsigned const TotalElementsInInputVector1 = VecVal1.
getVectorLength();
11165 unsigned const TotalElementsInInputVector2 = VecVal2.
getVectorLength();
11167 APSInt IndexVal =
E->getShuffleMaskIdx(Info.Ctx, EltNum);
11168 int64_t index = IndexVal.getExtValue();
11175 E, diag::err_shufflevector_minus_one_is_undefined_behavior_constexpr)
11181 index >= TotalElementsInInputVector1 + TotalElementsInInputVector2)
11182 llvm_unreachable(
"Out of bounds shuffle index");
11184 if (index >= TotalElementsInInputVector1)
11185 Result = VecVal2.
getVectorElt(index - TotalElementsInInputVector1);
11193 const Expr *Vec1 =
E->getExpr(0);
11197 const Expr *Vec2 =
E->getExpr(1);
11207 ResultElements.reserve(TotalElementsInOutputVector);
11208 for (
unsigned EltNum = 0; EltNum < TotalElementsInOutputVector; ++EltNum) {
11212 ResultElements.push_back(std::move(Elt));
11215 return Success(
APValue(ResultElements.data(), ResultElements.size()),
E);
11223 class ArrayExprEvaluator
11224 :
public ExprEvaluatorBase<ArrayExprEvaluator> {
11225 const LValue &
This;
11229 ArrayExprEvaluator(EvalInfo &Info,
const LValue &This,
APValue &Result)
11230 : ExprEvaluatorBaseTy(Info),
This(
This), Result(Result) {}
11233 assert(
V.isArray() &&
"expected array");
11238 bool ZeroInitialization(
const Expr *
E) {
11240 Info.Ctx.getAsConstantArrayType(
E->
getType());
11254 if (!Result.hasArrayFiller())
11258 LValue Subobject =
This;
11259 Subobject.addArray(Info,
E, CAT);
11261 return EvaluateInPlace(Result.getArrayFiller(), Info, Subobject, &VIE);
11264 bool VisitCallExpr(
const CallExpr *
E) {
11265 return handleCallExpr(
E, Result, &This);
11272 const LValue &Subobject,
11280 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
11282 const Expr *ArrayFiller,
11288 APValue &Result, EvalInfo &Info) {
11291 "not an array prvalue");
11292 return ArrayExprEvaluator(Info, This, Result).Visit(
E);
11300 "not an array prvalue");
11301 return ArrayExprEvaluator(Info, This, Result)
11302 .VisitInitListExpr(ILE, AllocType);
11311 "not an array prvalue");
11312 return ArrayExprEvaluator(Info, This, Result)
11313 .VisitCXXConstructExpr(CCE, This, &Result, AllocType);
11320 if (isa<ImplicitValueInitExpr>(FillerExpr))
11322 if (
const InitListExpr *ILE = dyn_cast<InitListExpr>(FillerExpr)) {
11323 for (
unsigned I = 0,
E = ILE->getNumInits(); I !=
E; ++I) {
11328 if (ILE->hasArrayFiller() &&
11337bool ArrayExprEvaluator::VisitInitListExpr(
const InitListExpr *
E,
11346 if (
E->isStringLiteralInit()) {
11352 return VisitStringLiteral(SL, AllocType);
11356 assert(!
E->isTransparent() &&
11357 "transparent array list initialization is not string literal init?");
11359 return VisitCXXParenListOrInitListExpr(
E,
E->inits(),
E->getArrayFiller(),
11363bool ArrayExprEvaluator::VisitCXXParenListOrInitListExpr(
11371 assert((!Result.isArray() || Result.getArrayInitializedElts() == 0) &&
11372 "zero-initialized array shouldn't have any initialized elts");
11374 if (Result.isArray() && Result.hasArrayFiller())
11375 Filler = Result.getArrayFiller();
11377 unsigned NumEltsToInit = Args.size();
11382 if (NumEltsToInit != NumElts &&
11384 NumEltsToInit = NumElts;
11386 for (
auto *
Init : Args) {
11387 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts()))
11388 NumEltsToInit += EmbedS->getDataElementCount() - 1;
11390 if (NumEltsToInit > NumElts)
11391 NumEltsToInit = NumElts;
11394 LLVM_DEBUG(llvm::dbgs() <<
"The number of elements to initialize: "
11395 << NumEltsToInit <<
".\n");
11402 for (
unsigned I = 0,
E = Result.getArrayInitializedElts(); I !=
E; ++I)
11403 Result.getArrayInitializedElt(I) = Filler;
11404 if (Result.hasArrayFiller())
11405 Result.getArrayFiller() = Filler;
11408 LValue Subobject =
This;
11409 Subobject.addArray(Info, ExprToVisit, CAT);
11410 auto Eval = [&](
const Expr *
Init,
unsigned ArrayIndex) {
11411 if (!
EvaluateInPlace(Result.getArrayInitializedElt(ArrayIndex), Info,
11412 Subobject,
Init) ||
11415 if (!Info.noteFailure())
11421 unsigned ArrayIndex = 0;
11424 for (
unsigned Index = 0; Index != NumEltsToInit; ++Index) {
11425 const Expr *
Init = Index < Args.size() ? Args[Index] : ArrayFiller;
11426 if (ArrayIndex >= NumEltsToInit)
11428 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
11430 for (
unsigned I = EmbedS->getStartingElementPos(),
11431 N = EmbedS->getDataElementCount();
11432 I != EmbedS->getStartingElementPos() + N; ++I) {
11435 Result.getArrayInitializedElt(ArrayIndex) =
APValue(
Value);
11439 Init->getFPFeaturesInEffect(Info.Ctx.getLangOpts());
11444 Result.getArrayInitializedElt(ArrayIndex) =
APValue(FValue);
11449 if (!Eval(
Init, ArrayIndex))
11455 if (!Result.hasArrayFiller())
11460 assert(ArrayFiller &&
"no array filler for incomplete init list");
11468 if (
E->getCommonExpr() &&
11469 !
Evaluate(Info.CurrentCall->createTemporary(
11470 E->getCommonExpr(),
11471 getStorageType(Info.Ctx,
E->getCommonExpr()),
11472 ScopeKind::FullExpression, CommonLV),
11473 Info,
E->getCommonExpr()->getSourceExpr()))
11481 LValue Subobject =
This;
11482 Subobject.addArray(Info,
E, CAT);
11485 for (EvalInfo::ArrayInitLoopIndex Index(Info); Index != Elements; ++Index) {
11494 FullExpressionRAII
Scope(Info);
11497 Info, Subobject,
E->getSubExpr()) ||
11500 if (!Info.noteFailure())
11513 return VisitCXXConstructExpr(
E, This, &Result,
E->
getType());
11517 const LValue &Subobject,
11527 HadZeroInit &&
Value->hasArrayFiller() ?
Value->getArrayFiller()
11531 if (FinalSize == 0)
11536 E->requiresZeroInitialization());
11537 LValue ArrayElt = Subobject;
11538 ArrayElt.addArray(Info,
E, CAT);
11544 for (
const unsigned N : {1u, FinalSize}) {
11545 unsigned OldElts =
Value->getArrayInitializedElts();
11551 for (
unsigned I = 0; I < OldElts; ++I)
11552 NewValue.getArrayInitializedElt(I).swap(
11553 Value->getArrayInitializedElt(I));
11554 Value->swap(NewValue);
11557 for (
unsigned I = OldElts; I < N; ++I)
11558 Value->getArrayInitializedElt(I) = Filler;
11560 if (HasTrivialConstructor && N == FinalSize && FinalSize != 1) {
11563 APValue &FirstResult =
Value->getArrayInitializedElt(0);
11564 for (
unsigned I = OldElts; I < FinalSize; ++I)
11565 Value->getArrayInitializedElt(I) = FirstResult;
11567 for (
unsigned I = OldElts; I < N; ++I) {
11568 if (!VisitCXXConstructExpr(
E, ArrayElt,
11569 &
Value->getArrayInitializedElt(I),
11576 if (Info.EvalStatus.Diag && !Info.EvalStatus.Diag->empty() &&
11577 !Info.keepEvaluatingAfterFailure())
11589 return RecordExprEvaluator(Info, Subobject, *
Value)
11590 .VisitCXXConstructExpr(
E,
Type);
11593bool ArrayExprEvaluator::VisitCXXParenListInitExpr(
11596 "Expression result is not a constant array type");
11598 return VisitCXXParenListOrInitListExpr(
E,
E->getInitExprs(),
11599 E->getArrayFiller());
11611class IntExprEvaluator
11612 :
public ExprEvaluatorBase<IntExprEvaluator> {
11615 IntExprEvaluator(EvalInfo &info,
APValue &result)
11616 : ExprEvaluatorBaseTy(info), Result(result) {}
11620 "Invalid evaluation result.");
11622 "Invalid evaluation result.");
11623 assert(SI.getBitWidth() == Info.Ctx.getIntWidth(
E->
getType()) &&
11624 "Invalid evaluation result.");
11634 "Invalid evaluation result.");
11635 assert(I.getBitWidth() == Info.Ctx.getIntWidth(
E->
getType()) &&
11636 "Invalid evaluation result.");
11638 Result.getInt().setIsUnsigned(
11648 "Invalid evaluation result.");
11661 if (
V.isLValue() ||
V.isAddrLabelDiff() ||
V.isIndeterminate()) {
11668 bool ZeroInitialization(
const Expr *
E) {
return Success(0,
E); }
11681 bool CheckReferencedDecl(
const Expr *
E,
const Decl *
D);
11683 if (CheckReferencedDecl(
E,
E->getDecl()))
11686 return ExprEvaluatorBaseTy::VisitDeclRefExpr(
E);
11689 if (CheckReferencedDecl(
E,
E->getMemberDecl())) {
11690 VisitIgnoredBaseExpression(
E->getBase());
11694 return ExprEvaluatorBaseTy::VisitMemberExpr(
E);
11698 bool VisitBuiltinCallExpr(
const CallExpr *
E,
unsigned BuiltinOp);
11715 if (Info.ArrayInitIndex ==
uint64_t(-1)) {
11721 return Success(Info.ArrayInitIndex,
E);
11726 return ZeroInitialization(
E);
11752class FixedPointExprEvaluator
11753 :
public ExprEvaluatorBase<FixedPointExprEvaluator> {
11757 FixedPointExprEvaluator(EvalInfo &info,
APValue &result)
11758 : ExprEvaluatorBaseTy(info), Result(result) {}
11762 APFixedPoint(I, Info.Ctx.getFixedPointSemantics(
E->
getType())),
E);
11767 APFixedPoint(
Value, Info.Ctx.getFixedPointSemantics(
E->
getType())),
E);
11776 assert(
V.getWidth() == Info.Ctx.getIntWidth(
E->
getType()) &&
11777 "Invalid evaluation result.");
11782 bool ZeroInitialization(
const Expr *
E) {
11812 return IntExprEvaluator(Info, Result).Visit(
E);
11820 if (!Val.
isInt()) {
11823 Info.FFDiag(
E, diag::note_invalid_subexpr_in_const_expr);
11830bool IntExprEvaluator::VisitSourceLocExpr(
const SourceLocExpr *
E) {
11832 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.getDefaultExpr());
11841 if (!FixedPointExprEvaluator(Info, Val).Visit(
E))
11856 auto FXSema = Info.Ctx.getFixedPointSemantics(
E->
getType());
11860 Result = APFixedPoint(Val, FXSema);
11871bool IntExprEvaluator::CheckReferencedDecl(
const Expr*
E,
const Decl*
D) {
11875 bool SameSign = (ECD->getInitVal().isSigned()
11877 bool SameWidth = (ECD->getInitVal().getBitWidth()
11878 == Info.Ctx.getIntWidth(
E->
getType()));
11879 if (SameSign && SameWidth)
11880 return Success(ECD->getInitVal(),
E);
11884 llvm::APSInt Val = ECD->getInitVal();
11886 Val.setIsSigned(!ECD->getInitVal().isSigned());
11888 Val = Val.extOrTrunc(Info.Ctx.getIntWidth(
E->
getType()));
11904#define TYPE(ID, BASE)
11905#define DEPENDENT_TYPE(ID, BASE) case Type::ID:
11906#define NON_CANONICAL_TYPE(ID, BASE) case Type::ID:
11907#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(ID, BASE) case Type::ID:
11908#include "clang/AST/TypeNodes.inc"
11910 case Type::DeducedTemplateSpecialization:
11911 llvm_unreachable(
"unexpected non-canonical or dependent type");
11913 case Type::Builtin:
11914 switch (cast<BuiltinType>(CanTy)->
getKind()) {
11915#define BUILTIN_TYPE(ID, SINGLETON_ID)
11916#define SIGNED_TYPE(ID, SINGLETON_ID) \
11917 case BuiltinType::ID: return GCCTypeClass::Integer;
11918#define FLOATING_TYPE(ID, SINGLETON_ID) \
11919 case BuiltinType::ID: return GCCTypeClass::RealFloat;
11920#define PLACEHOLDER_TYPE(ID, SINGLETON_ID) \
11921 case BuiltinType::ID: break;
11922#include "clang/AST/BuiltinTypes.def"
11923 case BuiltinType::Void:
11924 return GCCTypeClass::Void;
11926 case BuiltinType::Bool:
11927 return GCCTypeClass::Bool;
11929 case BuiltinType::Char_U:
11930 case BuiltinType::UChar:
11931 case BuiltinType::WChar_U:
11932 case BuiltinType::Char8:
11933 case BuiltinType::Char16:
11934 case BuiltinType::Char32:
11935 case BuiltinType::UShort:
11936 case BuiltinType::UInt:
11937 case BuiltinType::ULong:
11938 case BuiltinType::ULongLong:
11939 case BuiltinType::UInt128:
11940 return GCCTypeClass::Integer;
11942 case BuiltinType::UShortAccum:
11943 case BuiltinType::UAccum:
11944 case BuiltinType::ULongAccum:
11945 case BuiltinType::UShortFract:
11946 case BuiltinType::UFract:
11947 case BuiltinType::ULongFract:
11948 case BuiltinType::SatUShortAccum:
11949 case BuiltinType::SatUAccum:
11950 case BuiltinType::SatULongAccum:
11951 case BuiltinType::SatUShortFract:
11952 case BuiltinType::SatUFract:
11953 case BuiltinType::SatULongFract:
11954 return GCCTypeClass::None;
11956 case BuiltinType::NullPtr:
11958 case BuiltinType::ObjCId:
11959 case BuiltinType::ObjCClass:
11960 case BuiltinType::ObjCSel:
11961#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
11962 case BuiltinType::Id:
11963#include "clang/Basic/OpenCLImageTypes.def"
11964#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
11965 case BuiltinType::Id:
11966#include "clang/Basic/OpenCLExtensionTypes.def"
11967 case BuiltinType::OCLSampler:
11968 case BuiltinType::OCLEvent:
11969 case BuiltinType::OCLClkEvent:
11970 case BuiltinType::OCLQueue:
11971 case BuiltinType::OCLReserveID:
11972#define SVE_TYPE(Name, Id, SingletonId) \
11973 case BuiltinType::Id:
11974#include "clang/Basic/AArch64SVEACLETypes.def"
11975#define PPC_VECTOR_TYPE(Name, Id, Size) \
11976 case BuiltinType::Id:
11977#include "clang/Basic/PPCTypes.def"
11978#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
11979#include "clang/Basic/RISCVVTypes.def"
11980#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
11981#include "clang/Basic/WebAssemblyReferenceTypes.def"
11982#define AMDGPU_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
11983#include "clang/Basic/AMDGPUTypes.def"
11984#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
11985#include "clang/Basic/HLSLIntangibleTypes.def"
11986 return GCCTypeClass::None;
11988 case BuiltinType::Dependent:
11989 llvm_unreachable(
"unexpected dependent type");
11991 llvm_unreachable(
"unexpected placeholder type");
11994 return LangOpts.CPlusPlus ? GCCTypeClass::Enum : GCCTypeClass::Integer;
11996 case Type::Pointer:
11997 case Type::ConstantArray:
11998 case Type::VariableArray:
11999 case Type::IncompleteArray:
12000 case Type::FunctionNoProto:
12001 case Type::FunctionProto:
12002 case Type::ArrayParameter:
12003 return GCCTypeClass::Pointer;
12005 case Type::MemberPointer:
12007 ? GCCTypeClass::PointerToDataMember
12008 : GCCTypeClass::PointerToMemberFunction;
12010 case Type::Complex:
12011 return GCCTypeClass::Complex;
12014 return CanTy->
isUnionType() ? GCCTypeClass::Union
12015 : GCCTypeClass::ClassOrStruct;
12023 case Type::ExtVector:
12024 return GCCTypeClass::Vector;
12026 case Type::BlockPointer:
12027 case Type::ConstantMatrix:
12028 case Type::ObjCObject:
12029 case Type::ObjCInterface:
12030 case Type::ObjCObjectPointer:
12034 return GCCTypeClass::None;
12037 return GCCTypeClass::BitInt;
12039 case Type::LValueReference:
12040 case Type::RValueReference:
12041 llvm_unreachable(
"invalid type for expression");
12044 llvm_unreachable(
"unexpected type class");
12053 if (
E->getNumArgs() == 0)
12054 return GCCTypeClass::None;
12069 if (
Base.isNull()) {
12072 }
else if (
const Expr *
E =
Base.dyn_cast<
const Expr *>()) {
12073 if (!isa<StringLiteral>(
E))
12091 SpeculativeEvaluationRAII SpeculativeEval(Info);
12096 FoldConstant Fold(Info,
true);
12119 Fold.keepDiagnostics();
12128 return V.hasValue();
12139 if (
const VarDecl *VD = dyn_cast<VarDecl>(
D))
12142 if (isa<CompoundLiteralExpr>(
E))
12163 const auto *Cast = dyn_cast<CastExpr>(NoParens);
12164 if (Cast ==
nullptr)
12169 auto CastKind = Cast->getCastKind();
12171 CastKind != CK_AddressSpaceConversion)
12174 const auto *SubExpr = Cast->getSubExpr();
12196 assert(!LVal.Designator.Invalid);
12198 auto IsLastOrInvalidFieldDecl = [&Ctx](
const FieldDecl *FD,
bool &
Invalid) {
12207 auto &
Base = LVal.getLValueBase();
12208 if (
auto *ME = dyn_cast_or_null<MemberExpr>(
Base.dyn_cast<
const Expr *>())) {
12209 if (
auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
12211 if (!IsLastOrInvalidFieldDecl(FD,
Invalid))
12213 }
else if (
auto *IFD = dyn_cast<IndirectFieldDecl>(ME->getMemberDecl())) {
12214 for (
auto *FD : IFD->chain()) {
12216 if (!IsLastOrInvalidFieldDecl(cast<FieldDecl>(FD),
Invalid))
12224 if (LVal.Designator.FirstEntryIsAnUnsizedArray) {
12234 for (
unsigned E = LVal.Designator.Entries.size(); I !=
E; ++I) {
12235 const auto &Entry = LVal.Designator.Entries[I];
12241 const auto *CAT = cast<ConstantArrayType>(Ctx.
getAsArrayType(BaseType));
12242 uint64_t Index = Entry.getAsArrayIndex();
12248 uint64_t Index = Entry.getAsArrayIndex();
12251 BaseType = CT->getElementType();
12252 }
else if (
auto *FD = getAsField(Entry)) {
12254 if (!IsLastOrInvalidFieldDecl(FD,
Invalid))
12258 assert(getAsBaseClass(Entry) &&
"Expecting cast to a base class");
12270 if (LVal.Designator.Invalid)
12273 if (!LVal.Designator.Entries.empty())
12274 return LVal.Designator.isMostDerivedAnUnsizedArray();
12276 if (!LVal.InvalidBase)
12281 const auto *
E = LVal.Base.dyn_cast<
const Expr *>();
12282 return !
E || !isa<MemberExpr>(
E);
12288 const SubobjectDesignator &
Designator = LVal.Designator;
12300 auto isFlexibleArrayMember = [&] {
12302 FAMKind StrictFlexArraysLevel =
12305 if (
Designator.isMostDerivedAnUnsizedArray())
12308 if (StrictFlexArraysLevel == FAMKind::Default)
12311 if (
Designator.getMostDerivedArraySize() == 0 &&
12312 StrictFlexArraysLevel != FAMKind::IncompleteOnly)
12315 if (
Designator.getMostDerivedArraySize() == 1 &&
12316 StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete)
12322 return LVal.InvalidBase &&
12324 Designator.MostDerivedIsArrayElement && isFlexibleArrayMember() &&
12332 auto CharUnitsMax = std::numeric_limits<CharUnits::QuantityType>::max();
12333 if (Int.ugt(CharUnitsMax))
12345 if (
const auto *
V = LV.getLValueBase().dyn_cast<
const ValueDecl *>())
12346 if (
const auto *VD = dyn_cast<VarDecl>(
V))
12358 unsigned Type,
const LValue &LVal,
12371 if (!(
Type & 1) || LVal.Designator.Invalid || DetermineForCompleteObject) {
12373 if (
Type == 3 && !DetermineForCompleteObject)
12376 llvm::APInt APEndOffset;
12377 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
12381 if (LVal.InvalidBase)
12385 const bool Ret = CheckedHandleSizeof(BaseTy, EndOffset);
12391 const SubobjectDesignator &
Designator = LVal.Designator;
12403 llvm::APInt APEndOffset;
12404 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
12416 if (!CheckedHandleSizeof(
Designator.MostDerivedType, BytesPerElem))
12422 int64_t ElemsRemaining;
12425 uint64_t ArraySize =
Designator.getMostDerivedArraySize();
12426 uint64_t ArrayIndex =
Designator.Entries.back().getAsArrayIndex();
12427 ElemsRemaining = ArraySize <= ArrayIndex ? 0 : ArraySize - ArrayIndex;
12429 ElemsRemaining =
Designator.isOnePastTheEnd() ? 0 : 1;
12432 EndOffset = LVal.getLValueOffset() + BytesPerElem * ElemsRemaining;
12442 EvalInfo &Info, uint64_t &Size) {
12449 SpeculativeEvaluationRAII SpeculativeEval(Info);
12450 IgnoreSideEffectsRAII Fold(Info);
12458 LVal.setFrom(Info.Ctx, RVal);
12466 if (LVal.getLValueOffset().isNegative()) {
12477 if (EndOffset <= LVal.getLValueOffset())
12480 Size = (EndOffset - LVal.getLValueOffset()).getQuantity();
12484bool IntExprEvaluator::VisitCallExpr(
const CallExpr *
E) {
12485 if (!IsConstantEvaluatedBuiltinCall(
E))
12486 return ExprEvaluatorBaseTy::VisitCallExpr(
E);
12487 return VisitBuiltinCallExpr(
E,
E->getBuiltinCallee());
12503 Info.FFDiag(
E->getArg(0));
12509 assert(SrcInt.getBitWidth() >= Alignment.getBitWidth() &&
12510 "Bit widths must be the same");
12517bool IntExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *
E,
12518 unsigned BuiltinOp) {
12519 switch (BuiltinOp) {
12523 case Builtin::BI__builtin_dynamic_object_size:
12524 case Builtin::BI__builtin_object_size: {
12528 assert(
Type <= 3 &&
"unexpected type");
12539 switch (Info.EvalMode) {
12540 case EvalInfo::EM_ConstantExpression:
12541 case EvalInfo::EM_ConstantFold:
12542 case EvalInfo::EM_IgnoreSideEffects:
12545 case EvalInfo::EM_ConstantExpressionUnevaluated:
12550 llvm_unreachable(
"unexpected EvalMode");
12553 case Builtin::BI__builtin_os_log_format_buffer_size: {
12559 case Builtin::BI__builtin_is_aligned: {
12567 Ptr.setFrom(Info.Ctx, Src);
12573 assert(Alignment.isPowerOf2());
12586 Info.FFDiag(
E->getArg(0), diag::note_constexpr_alignment_compute)
12590 assert(Src.
isInt());
12591 return Success((Src.
getInt() & (Alignment - 1)) == 0 ? 1 : 0,
E);
12593 case Builtin::BI__builtin_align_up: {
12601 APSInt((Src.
getInt() + (Alignment - 1)) & ~(Alignment - 1),
12602 Src.
getInt().isUnsigned());
12603 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
12606 case Builtin::BI__builtin_align_down: {
12615 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
12619 case Builtin::BI__builtin_bitreverse8:
12620 case Builtin::BI__builtin_bitreverse16:
12621 case Builtin::BI__builtin_bitreverse32:
12622 case Builtin::BI__builtin_bitreverse64: {
12627 return Success(Val.reverseBits(),
E);
12630 case Builtin::BI__builtin_bswap16:
12631 case Builtin::BI__builtin_bswap32:
12632 case Builtin::BI__builtin_bswap64: {
12637 return Success(Val.byteSwap(),
E);
12640 case Builtin::BI__builtin_classify_type:
12643 case Builtin::BI__builtin_clrsb:
12644 case Builtin::BI__builtin_clrsbl:
12645 case Builtin::BI__builtin_clrsbll: {
12650 return Success(Val.getBitWidth() - Val.getSignificantBits(),
E);
12653 case Builtin::BI__builtin_clz:
12654 case Builtin::BI__builtin_clzl:
12655 case Builtin::BI__builtin_clzll:
12656 case Builtin::BI__builtin_clzs:
12657 case Builtin::BI__builtin_clzg:
12658 case Builtin::BI__lzcnt16:
12659 case Builtin::BI__lzcnt:
12660 case Builtin::BI__lzcnt64: {
12665 std::optional<APSInt> Fallback;
12666 if (BuiltinOp == Builtin::BI__builtin_clzg &&
E->getNumArgs() > 1) {
12670 Fallback = FallbackTemp;
12680 bool ZeroIsUndefined = BuiltinOp != Builtin::BI__lzcnt16 &&
12681 BuiltinOp != Builtin::BI__lzcnt &&
12682 BuiltinOp != Builtin::BI__lzcnt64;
12684 if (ZeroIsUndefined)
12688 return Success(Val.countl_zero(),
E);
12691 case Builtin::BI__builtin_constant_p: {
12692 const Expr *Arg =
E->getArg(0);
12701 Info.FFDiag(
E, diag::note_invalid_subexpr_in_const_expr);
12705 case Builtin::BI__builtin_is_constant_evaluated: {
12706 const auto *
Callee = Info.CurrentCall->getCallee();
12707 if (Info.InConstantContext && !Info.CheckingPotentialConstantExpression &&
12708 (Info.CallStackDepth == 1 ||
12709 (Info.CallStackDepth == 2 &&
Callee->isInStdNamespace() &&
12710 Callee->getIdentifier() &&
12711 Callee->getIdentifier()->isStr(
"is_constant_evaluated")))) {
12713 if (Info.EvalStatus.Diag)
12714 Info.report((Info.CallStackDepth == 1)
12716 : Info.CurrentCall->getCallRange().getBegin(),
12717 diag::warn_is_constant_evaluated_always_true_constexpr)
12718 << (Info.CallStackDepth == 1 ?
"__builtin_is_constant_evaluated"
12719 :
"std::is_constant_evaluated");
12722 return Success(Info.InConstantContext,
E);
12725 case Builtin::BI__builtin_ctz:
12726 case Builtin::BI__builtin_ctzl:
12727 case Builtin::BI__builtin_ctzll:
12728 case Builtin::BI__builtin_ctzs:
12729 case Builtin::BI__builtin_ctzg: {
12734 std::optional<APSInt> Fallback;
12735 if (BuiltinOp == Builtin::BI__builtin_ctzg &&
E->getNumArgs() > 1) {
12739 Fallback = FallbackTemp;
12749 return Success(Val.countr_zero(),
E);
12752 case Builtin::BI__builtin_eh_return_data_regno: {
12754 Operand = Info.Ctx.getTargetInfo().getEHDataRegisterNumber(Operand);
12758 case Builtin::BI__builtin_expect:
12759 case Builtin::BI__builtin_expect_with_probability:
12760 return Visit(
E->getArg(0));
12762 case Builtin::BI__builtin_ptrauth_string_discriminator: {
12769 case Builtin::BI__builtin_ffs:
12770 case Builtin::BI__builtin_ffsl:
12771 case Builtin::BI__builtin_ffsll: {
12776 unsigned N = Val.countr_zero();
12777 return Success(N == Val.getBitWidth() ? 0 : N + 1,
E);
12780 case Builtin::BI__builtin_fpclassify: {
12785 switch (Val.getCategory()) {
12786 case APFloat::fcNaN: Arg = 0;
break;
12787 case APFloat::fcInfinity: Arg = 1;
break;
12788 case APFloat::fcNormal: Arg = Val.isDenormal() ? 3 : 2;
break;
12789 case APFloat::fcZero: Arg = 4;
break;
12791 return Visit(
E->getArg(Arg));
12794 case Builtin::BI__builtin_isinf_sign: {
12797 Success(Val.isInfinity() ? (Val.isNegative() ? -1 : 1) : 0,
E);
12800 case Builtin::BI__builtin_isinf: {
12803 Success(Val.isInfinity() ? 1 : 0,
E);
12806 case Builtin::BI__builtin_isfinite: {
12809 Success(Val.isFinite() ? 1 : 0,
E);
12812 case Builtin::BI__builtin_isnan: {
12818 case Builtin::BI__builtin_isnormal: {
12821 Success(Val.isNormal() ? 1 : 0,
E);
12824 case Builtin::BI__builtin_issubnormal: {
12827 Success(Val.isDenormal() ? 1 : 0,
E);
12830 case Builtin::BI__builtin_iszero: {
12836 case Builtin::BI__builtin_signbit:
12837 case Builtin::BI__builtin_signbitf:
12838 case Builtin::BI__builtin_signbitl: {
12841 Success(Val.isNegative() ? 1 : 0,
E);
12844 case Builtin::BI__builtin_isgreater:
12845 case Builtin::BI__builtin_isgreaterequal:
12846 case Builtin::BI__builtin_isless:
12847 case Builtin::BI__builtin_islessequal:
12848 case Builtin::BI__builtin_islessgreater:
12849 case Builtin::BI__builtin_isunordered: {
12858 switch (BuiltinOp) {
12859 case Builtin::BI__builtin_isgreater:
12861 case Builtin::BI__builtin_isgreaterequal:
12863 case Builtin::BI__builtin_isless:
12865 case Builtin::BI__builtin_islessequal:
12867 case Builtin::BI__builtin_islessgreater: {
12868 APFloat::cmpResult cmp = LHS.compare(RHS);
12869 return cmp == APFloat::cmpResult::cmpLessThan ||
12870 cmp == APFloat::cmpResult::cmpGreaterThan;
12872 case Builtin::BI__builtin_isunordered:
12873 return LHS.compare(RHS) == APFloat::cmpResult::cmpUnordered;
12875 llvm_unreachable(
"Unexpected builtin ID: Should be a floating "
12876 "point comparison function");
12884 case Builtin::BI__builtin_issignaling: {
12887 Success(Val.isSignaling() ? 1 : 0,
E);
12890 case Builtin::BI__builtin_isfpclass: {
12894 unsigned Test =
static_cast<llvm::FPClassTest
>(MaskVal.getZExtValue());
12897 Success((Val.classify() & Test) ? 1 : 0,
E);
12900 case Builtin::BI__builtin_parity:
12901 case Builtin::BI__builtin_parityl:
12902 case Builtin::BI__builtin_parityll: {
12907 return Success(Val.popcount() % 2,
E);
12910 case Builtin::BI__builtin_popcount:
12911 case Builtin::BI__builtin_popcountl:
12912 case Builtin::BI__builtin_popcountll:
12913 case Builtin::BI__builtin_popcountg:
12914 case Builtin::BI__popcnt16:
12915 case Builtin::BI__popcnt:
12916 case Builtin::BI__popcnt64: {
12921 return Success(Val.popcount(),
E);
12924 case Builtin::BI__builtin_rotateleft8:
12925 case Builtin::BI__builtin_rotateleft16:
12926 case Builtin::BI__builtin_rotateleft32:
12927 case Builtin::BI__builtin_rotateleft64:
12928 case Builtin::BI_rotl8:
12929 case Builtin::BI_rotl16:
12930 case Builtin::BI_rotl:
12931 case Builtin::BI_lrotl:
12932 case Builtin::BI_rotl64: {
12938 return Success(Val.rotl(Amt.urem(Val.getBitWidth())),
E);
12941 case Builtin::BI__builtin_rotateright8:
12942 case Builtin::BI__builtin_rotateright16:
12943 case Builtin::BI__builtin_rotateright32:
12944 case Builtin::BI__builtin_rotateright64:
12945 case Builtin::BI_rotr8:
12946 case Builtin::BI_rotr16:
12947 case Builtin::BI_rotr:
12948 case Builtin::BI_lrotr:
12949 case Builtin::BI_rotr64: {
12955 return Success(Val.rotr(Amt.urem(Val.getBitWidth())),
E);
12958 case Builtin::BIstrlen:
12959 case Builtin::BIwcslen:
12961 if (Info.getLangOpts().CPlusPlus11)
12962 Info.CCEDiag(
E, diag::note_constexpr_invalid_function)
12964 << (
"'" + Info.Ctx.BuiltinInfo.getName(BuiltinOp) +
"'").str();
12966 Info.CCEDiag(
E, diag::note_invalid_subexpr_in_const_expr);
12968 case Builtin::BI__builtin_strlen:
12969 case Builtin::BI__builtin_wcslen: {
12978 case Builtin::BIstrcmp:
12979 case Builtin::BIwcscmp:
12980 case Builtin::BIstrncmp:
12981 case Builtin::BIwcsncmp:
12982 case Builtin::BImemcmp:
12983 case Builtin::BIbcmp:
12984 case Builtin::BIwmemcmp:
12986 if (Info.getLangOpts().CPlusPlus11)
12987 Info.CCEDiag(
E, diag::note_constexpr_invalid_function)
12989 << (
"'" + Info.Ctx.BuiltinInfo.getName(BuiltinOp) +
"'").str();
12991 Info.CCEDiag(
E, diag::note_invalid_subexpr_in_const_expr);
12993 case Builtin::BI__builtin_strcmp:
12994 case Builtin::BI__builtin_wcscmp:
12995 case Builtin::BI__builtin_strncmp:
12996 case Builtin::BI__builtin_wcsncmp:
12997 case Builtin::BI__builtin_memcmp:
12998 case Builtin::BI__builtin_bcmp:
12999 case Builtin::BI__builtin_wmemcmp: {
13000 LValue String1, String2;
13006 if (BuiltinOp != Builtin::BIstrcmp &&
13007 BuiltinOp != Builtin::BIwcscmp &&
13008 BuiltinOp != Builtin::BI__builtin_strcmp &&
13009 BuiltinOp != Builtin::BI__builtin_wcscmp) {
13013 MaxLength = N.getZExtValue();
13017 if (MaxLength == 0u)
13020 if (!String1.checkNullPointerForFoldAccess(Info,
E,
AK_Read) ||
13021 !String2.checkNullPointerForFoldAccess(Info,
E,
AK_Read) ||
13022 String1.Designator.Invalid || String2.Designator.Invalid)
13025 QualType CharTy1 = String1.Designator.getType(Info.Ctx);
13026 QualType CharTy2 = String2.Designator.getType(Info.Ctx);
13028 bool IsRawByte = BuiltinOp == Builtin::BImemcmp ||
13029 BuiltinOp == Builtin::BIbcmp ||
13030 BuiltinOp == Builtin::BI__builtin_memcmp ||
13031 BuiltinOp == Builtin::BI__builtin_bcmp;
13033 assert(IsRawByte ||
13034 (Info.Ctx.hasSameUnqualifiedType(
13036 Info.Ctx.hasSameUnqualifiedType(CharTy1, CharTy2)));
13043 Info.FFDiag(
E, diag::note_constexpr_memcmp_unsupported)
13044 << (
"'" + Info.Ctx.BuiltinInfo.getName(BuiltinOp) +
"'").str()
13045 << CharTy1 << CharTy2;
13049 const auto &ReadCurElems = [&](
APValue &Char1,
APValue &Char2) {
13052 Char1.
isInt() && Char2.isInt();
13054 const auto &AdvanceElems = [&] {
13060 (BuiltinOp != Builtin::BImemcmp && BuiltinOp != Builtin::BIbcmp &&
13061 BuiltinOp != Builtin::BIwmemcmp &&
13062 BuiltinOp != Builtin::BI__builtin_memcmp &&
13063 BuiltinOp != Builtin::BI__builtin_bcmp &&
13064 BuiltinOp != Builtin::BI__builtin_wmemcmp);
13065 bool IsWide = BuiltinOp == Builtin::BIwcscmp ||
13066 BuiltinOp == Builtin::BIwcsncmp ||
13067 BuiltinOp == Builtin::BIwmemcmp ||
13068 BuiltinOp == Builtin::BI__builtin_wcscmp ||
13069 BuiltinOp == Builtin::BI__builtin_wcsncmp ||
13070 BuiltinOp == Builtin::BI__builtin_wmemcmp;
13072 for (; MaxLength; --MaxLength) {
13074 if (!ReadCurElems(Char1, Char2))
13082 if (StopAtNull && !Char1.
getInt())
13084 assert(!(StopAtNull && !Char2.
getInt()));
13085 if (!AdvanceElems())
13092 case Builtin::BI__atomic_always_lock_free:
13093 case Builtin::BI__atomic_is_lock_free:
13094 case Builtin::BI__c11_atomic_is_lock_free: {
13110 if (
Size.isPowerOfTwo()) {
13112 unsigned InlineWidthBits =
13113 Info.Ctx.getTargetInfo().getMaxAtomicInlineWidth();
13114 if (Size <= Info.Ctx.toCharUnitsFromBits(InlineWidthBits)) {
13115 if (BuiltinOp == Builtin::BI__c11_atomic_is_lock_free ||
13121 const Expr *PtrArg =
E->getArg(1);
13127 IntResult.isAligned(
Size.getAsAlign()))
13131 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(PtrArg)) {
13134 if (ICE->getCastKind() == CK_BitCast)
13135 PtrArg = ICE->getSubExpr();
13141 Info.Ctx.getTypeAlignInChars(PointeeType) >= Size) {
13149 return BuiltinOp == Builtin::BI__atomic_always_lock_free ?
13152 case Builtin::BI__builtin_addcb:
13153 case Builtin::BI__builtin_addcs:
13154 case Builtin::BI__builtin_addc:
13155 case Builtin::BI__builtin_addcl:
13156 case Builtin::BI__builtin_addcll:
13157 case Builtin::BI__builtin_subcb:
13158 case Builtin::BI__builtin_subcs:
13159 case Builtin::BI__builtin_subc:
13160 case Builtin::BI__builtin_subcl:
13161 case Builtin::BI__builtin_subcll: {
13162 LValue CarryOutLValue;
13163 APSInt LHS, RHS, CarryIn, CarryOut, Result;
13174 bool FirstOverflowed =
false;
13175 bool SecondOverflowed =
false;
13176 switch (BuiltinOp) {
13178 llvm_unreachable(
"Invalid value for BuiltinOp");
13179 case Builtin::BI__builtin_addcb:
13180 case Builtin::BI__builtin_addcs:
13181 case Builtin::BI__builtin_addc:
13182 case Builtin::BI__builtin_addcl:
13183 case Builtin::BI__builtin_addcll:
13185 LHS.uadd_ov(RHS, FirstOverflowed).uadd_ov(CarryIn, SecondOverflowed);
13187 case Builtin::BI__builtin_subcb:
13188 case Builtin::BI__builtin_subcs:
13189 case Builtin::BI__builtin_subc:
13190 case Builtin::BI__builtin_subcl:
13191 case Builtin::BI__builtin_subcll:
13193 LHS.usub_ov(RHS, FirstOverflowed).usub_ov(CarryIn, SecondOverflowed);
13199 CarryOut = (
uint64_t)(FirstOverflowed | SecondOverflowed);
13205 case Builtin::BI__builtin_add_overflow:
13206 case Builtin::BI__builtin_sub_overflow:
13207 case Builtin::BI__builtin_mul_overflow:
13208 case Builtin::BI__builtin_sadd_overflow:
13209 case Builtin::BI__builtin_uadd_overflow:
13210 case Builtin::BI__builtin_uaddl_overflow:
13211 case Builtin::BI__builtin_uaddll_overflow:
13212 case Builtin::BI__builtin_usub_overflow:
13213 case Builtin::BI__builtin_usubl_overflow:
13214 case Builtin::BI__builtin_usubll_overflow:
13215 case Builtin::BI__builtin_umul_overflow:
13216 case Builtin::BI__builtin_umull_overflow:
13217 case Builtin::BI__builtin_umulll_overflow:
13218 case Builtin::BI__builtin_saddl_overflow:
13219 case Builtin::BI__builtin_saddll_overflow:
13220 case Builtin::BI__builtin_ssub_overflow:
13221 case Builtin::BI__builtin_ssubl_overflow:
13222 case Builtin::BI__builtin_ssubll_overflow:
13223 case Builtin::BI__builtin_smul_overflow:
13224 case Builtin::BI__builtin_smull_overflow:
13225 case Builtin::BI__builtin_smulll_overflow: {
13226 LValue ResultLValue;
13236 bool DidOverflow =
false;
13239 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
13240 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
13241 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
13242 bool IsSigned = LHS.isSigned() || RHS.isSigned() ||
13244 bool AllSigned = LHS.isSigned() && RHS.isSigned() &&
13246 uint64_t LHSSize = LHS.getBitWidth();
13247 uint64_t RHSSize = RHS.getBitWidth();
13248 uint64_t ResultSize = Info.Ctx.getTypeSize(ResultType);
13249 uint64_t MaxBits = std::max(std::max(LHSSize, RHSSize), ResultSize);
13255 if (IsSigned && !AllSigned)
13258 LHS =
APSInt(LHS.extOrTrunc(MaxBits), !IsSigned);
13259 RHS =
APSInt(RHS.extOrTrunc(MaxBits), !IsSigned);
13260 Result =
APSInt(MaxBits, !IsSigned);
13264 switch (BuiltinOp) {
13266 llvm_unreachable(
"Invalid value for BuiltinOp");
13267 case Builtin::BI__builtin_add_overflow:
13268 case Builtin::BI__builtin_sadd_overflow:
13269 case Builtin::BI__builtin_saddl_overflow:
13270 case Builtin::BI__builtin_saddll_overflow:
13271 case Builtin::BI__builtin_uadd_overflow:
13272 case Builtin::BI__builtin_uaddl_overflow:
13273 case Builtin::BI__builtin_uaddll_overflow:
13274 Result = LHS.isSigned() ? LHS.sadd_ov(RHS, DidOverflow)
13275 : LHS.uadd_ov(RHS, DidOverflow);
13277 case Builtin::BI__builtin_sub_overflow:
13278 case Builtin::BI__builtin_ssub_overflow:
13279 case Builtin::BI__builtin_ssubl_overflow:
13280 case Builtin::BI__builtin_ssubll_overflow:
13281 case Builtin::BI__builtin_usub_overflow:
13282 case Builtin::BI__builtin_usubl_overflow:
13283 case Builtin::BI__builtin_usubll_overflow:
13284 Result = LHS.isSigned() ? LHS.ssub_ov(RHS, DidOverflow)
13285 : LHS.usub_ov(RHS, DidOverflow);
13287 case Builtin::BI__builtin_mul_overflow:
13288 case Builtin::BI__builtin_smul_overflow:
13289 case Builtin::BI__builtin_smull_overflow:
13290 case Builtin::BI__builtin_smulll_overflow:
13291 case Builtin::BI__builtin_umul_overflow:
13292 case Builtin::BI__builtin_umull_overflow:
13293 case Builtin::BI__builtin_umulll_overflow:
13294 Result = LHS.isSigned() ? LHS.smul_ov(RHS, DidOverflow)
13295 : LHS.umul_ov(RHS, DidOverflow);
13301 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
13302 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
13303 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
13309 APSInt Temp = Result.extOrTrunc(Info.Ctx.getTypeSize(ResultType));
13312 if (!APSInt::isSameValue(Temp, Result))
13313 DidOverflow =
true;
13328 const LValue &LV) {
13331 if (!LV.getLValueBase())
13336 if (!LV.getLValueDesignator().Invalid &&
13337 !LV.getLValueDesignator().isOnePastTheEnd())
13342 QualType Ty = getType(LV.getLValueBase());
13347 if (LV.getLValueDesignator().Invalid)
13353 return LV.getLValueOffset() == Size;
13363class DataRecursiveIntBinOpEvaluator {
13364 struct EvalResult {
13366 bool Failed =
false;
13368 EvalResult() =
default;
13370 void swap(EvalResult &RHS) {
13372 Failed = RHS.Failed;
13373 RHS.Failed =
false;
13379 EvalResult LHSResult;
13380 enum { AnyExprKind, BinOpKind, BinOpVisitedLHSKind }
Kind;
13383 Job(Job &&) =
default;
13385 void startSpeculativeEval(EvalInfo &Info) {
13386 SpecEvalRAII = SpeculativeEvaluationRAII(Info);
13390 SpeculativeEvaluationRAII SpecEvalRAII;
13395 IntExprEvaluator &IntEval;
13400 DataRecursiveIntBinOpEvaluator(IntExprEvaluator &IntEval,
APValue &Result)
13401 : IntEval(IntEval), Info(IntEval.getEvalInfo()), FinalResult(Result) { }
13408 return E->getOpcode() == BO_Comma ||
E->isLogicalOp() ||
13416 EvalResult PrevResult;
13417 while (!Queue.empty())
13418 process(PrevResult);
13420 if (PrevResult.Failed)
return false;
13422 FinalResult.
swap(PrevResult.Val);
13428 return IntEval.Success(
Value,
E, Result);
13431 return IntEval.Success(
Value,
E, Result);
13434 return IntEval.Error(
E);
13437 return IntEval.Error(
E,
D);
13441 return Info.CCEDiag(
E,
D);
13445 bool VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *
E,
13446 bool &SuppressRHSDiags);
13448 bool VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
13451 void EvaluateExpr(
const Expr *
E, EvalResult &Result) {
13452 Result.Failed = !
Evaluate(Result.Val, Info,
E);
13457 void process(EvalResult &Result);
13459 void enqueue(
const Expr *
E) {
13461 Queue.resize(Queue.size()+1);
13462 Queue.back().E =
E;
13463 Queue.back().Kind = Job::AnyExprKind;
13469bool DataRecursiveIntBinOpEvaluator::
13471 bool &SuppressRHSDiags) {
13472 if (
E->getOpcode() == BO_Comma) {
13474 if (LHSResult.Failed)
13475 return Info.noteSideEffect();
13479 if (
E->isLogicalOp()) {
13484 if (LHSAsBool == (
E->getOpcode() == BO_LOr)) {
13485 Success(LHSAsBool,
E, LHSResult.Val);
13489 LHSResult.Failed =
true;
13493 if (!Info.noteSideEffect())
13499 SuppressRHSDiags =
true;
13508 if (LHSResult.Failed && !Info.noteFailure())
13519 assert(!LVal.
hasLValuePath() &&
"have designator for integer lvalue");
13521 uint64_t Offset64 = Offset.getQuantity();
13522 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
13524 : Offset64 + Index64);
13527bool DataRecursiveIntBinOpEvaluator::
13528 VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
13530 if (
E->getOpcode() == BO_Comma) {
13531 if (RHSResult.Failed)
13533 Result = RHSResult.Val;
13537 if (
E->isLogicalOp()) {
13538 bool lhsResult, rhsResult;
13544 if (
E->getOpcode() == BO_LOr)
13545 return Success(lhsResult || rhsResult,
E, Result);
13547 return Success(lhsResult && rhsResult,
E, Result);
13553 if (rhsResult == (
E->getOpcode() == BO_LOr))
13554 return Success(rhsResult,
E, Result);
13564 if (LHSResult.Failed || RHSResult.Failed)
13567 const APValue &LHSVal = LHSResult.Val;
13568 const APValue &RHSVal = RHSResult.Val;
13578 if (
E->getOpcode() == BO_Add &&
13592 if (!LHSExpr || !RHSExpr)
13594 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
13595 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
13596 if (!LHSAddrExpr || !RHSAddrExpr)
13602 Result =
APValue(LHSAddrExpr, RHSAddrExpr);
13621void DataRecursiveIntBinOpEvaluator::process(EvalResult &Result) {
13622 Job &job = Queue.back();
13624 switch (job.Kind) {
13625 case Job::AnyExprKind: {
13626 if (
const BinaryOperator *Bop = dyn_cast<BinaryOperator>(job.E)) {
13627 if (shouldEnqueue(Bop)) {
13628 job.Kind = Job::BinOpKind;
13629 enqueue(Bop->getLHS());
13634 EvaluateExpr(job.E, Result);
13639 case Job::BinOpKind: {
13641 bool SuppressRHSDiags =
false;
13642 if (!VisitBinOpLHSOnly(Result, Bop, SuppressRHSDiags)) {
13646 if (SuppressRHSDiags)
13647 job.startSpeculativeEval(Info);
13648 job.LHSResult.swap(Result);
13649 job.Kind = Job::BinOpVisitedLHSKind;
13654 case Job::BinOpVisitedLHSKind: {
13658 Result.Failed = !VisitBinOp(job.LHSResult, RHS, Bop, Result.Val);
13664 llvm_unreachable(
"Invalid Job::Kind!");
13668enum class CmpResult {
13677template <
class SuccessCB,
class AfterCB>
13680 SuccessCB &&
Success, AfterCB &&DoAfter) {
13682 assert(
E->isComparisonOp() &&
"expected comparison operator");
13683 assert((
E->getOpcode() == BO_Cmp ||
13685 "unsupported binary expression evaluation");
13686 auto Error = [&](
const Expr *
E) {
13687 Info.FFDiag(
E, diag::note_invalid_subexpr_in_const_expr);
13691 bool IsRelational =
E->isRelationalOp() ||
E->getOpcode() == BO_Cmp;
13692 bool IsEquality =
E->isEqualityOp();
13701 if (!LHSOK && !Info.noteFailure())
13706 return Success(CmpResult::Less,
E);
13708 return Success(CmpResult::Greater,
E);
13709 return Success(CmpResult::Equal,
E);
13713 APFixedPoint LHSFX(Info.Ctx.getFixedPointSemantics(LHSTy));
13714 APFixedPoint RHSFX(Info.Ctx.getFixedPointSemantics(RHSTy));
13717 if (!LHSOK && !Info.noteFailure())
13722 return Success(CmpResult::Less,
E);
13724 return Success(CmpResult::Greater,
E);
13725 return Success(CmpResult::Equal,
E);
13729 ComplexValue LHS, RHS;
13731 if (
E->isAssignmentOp()) {
13738 LHS.makeComplexFloat();
13739 LHS.FloatImag = APFloat(LHS.FloatReal.getSemantics());
13744 if (!LHSOK && !Info.noteFailure())
13750 RHS.makeComplexFloat();
13751 RHS.FloatImag = APFloat(RHS.FloatReal.getSemantics());
13755 if (LHS.isComplexFloat()) {
13756 APFloat::cmpResult CR_r =
13757 LHS.getComplexFloatReal().compare(RHS.getComplexFloatReal());
13758 APFloat::cmpResult CR_i =
13759 LHS.getComplexFloatImag().compare(RHS.getComplexFloatImag());
13760 bool IsEqual = CR_r == APFloat::cmpEqual && CR_i == APFloat::cmpEqual;
13761 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal,
E);
13763 assert(IsEquality &&
"invalid complex comparison");
13764 bool IsEqual = LHS.getComplexIntReal() == RHS.getComplexIntReal() &&
13765 LHS.getComplexIntImag() == RHS.getComplexIntImag();
13766 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal,
E);
13772 APFloat RHS(0.0), LHS(0.0);
13775 if (!LHSOK && !Info.noteFailure())
13781 assert(
E->isComparisonOp() &&
"Invalid binary operator!");
13782 llvm::APFloatBase::cmpResult APFloatCmpResult = LHS.compare(RHS);
13783 if (!Info.InConstantContext &&
13784 APFloatCmpResult == APFloat::cmpUnordered &&
13787 Info.FFDiag(
E, diag::note_constexpr_float_arithmetic_strict);
13790 auto GetCmpRes = [&]() {
13791 switch (APFloatCmpResult) {
13792 case APFloat::cmpEqual:
13793 return CmpResult::Equal;
13794 case APFloat::cmpLessThan:
13795 return CmpResult::Less;
13796 case APFloat::cmpGreaterThan:
13797 return CmpResult::Greater;
13798 case APFloat::cmpUnordered:
13799 return CmpResult::Unordered;
13801 llvm_unreachable(
"Unrecognised APFloat::cmpResult enum");
13807 LValue LHSValue, RHSValue;
13810 if (!LHSOK && !Info.noteFailure())
13819 auto DiagComparison = [&] (
unsigned DiagID,
bool Reversed =
false) {
13820 std::string LHS = LHSValue.toString(Info.Ctx,
E->getLHS()->
getType());
13821 std::string RHS = RHSValue.toString(Info.Ctx,
E->getRHS()->
getType());
13822 Info.FFDiag(
E, DiagID)
13829 return DiagComparison(
13830 diag::note_constexpr_pointer_comparison_unspecified);
13836 if ((!LHSValue.Base && !LHSValue.Offset.isZero()) ||
13837 (!RHSValue.Base && !RHSValue.Offset.isZero()))
13838 return DiagComparison(diag::note_constexpr_pointer_constant_comparison,
13845 LHSValue.Base && RHSValue.Base)
13846 return DiagComparison(diag::note_constexpr_literal_comparison);
13850 return DiagComparison(diag::note_constexpr_pointer_weak_comparison,
13854 if (LHSValue.Base && LHSValue.Offset.isZero() &&
13856 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
13858 if (RHSValue.Base && RHSValue.Offset.isZero() &&
13860 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
13866 return DiagComparison(
13867 diag::note_constexpr_pointer_comparison_zero_sized);
13868 return Success(CmpResult::Unequal,
E);
13871 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
13872 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
13874 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
13875 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
13885 Info.CCEDiag(
E, diag::note_constexpr_void_comparison);
13895 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid && IsRelational) {
13896 bool WasArrayIndex;
13898 getType(LHSValue.Base), LHSDesignator, RHSDesignator, WasArrayIndex);
13905 if (!WasArrayIndex && Mismatch < LHSDesignator.Entries.size() &&
13906 Mismatch < RHSDesignator.Entries.size()) {
13907 const FieldDecl *LF = getAsField(LHSDesignator.Entries[Mismatch]);
13908 const FieldDecl *RF = getAsField(RHSDesignator.Entries[Mismatch]);
13910 Info.CCEDiag(
E, diag::note_constexpr_pointer_comparison_base_classes);
13912 Info.CCEDiag(
E, diag::note_constexpr_pointer_comparison_base_field)
13913 << getAsBaseClass(LHSDesignator.Entries[Mismatch])
13916 Info.CCEDiag(
E, diag::note_constexpr_pointer_comparison_base_field)
13917 << getAsBaseClass(RHSDesignator.Entries[Mismatch])
13922 diag::note_constexpr_pointer_comparison_differing_access)
13930 unsigned PtrSize = Info.Ctx.getTypeSize(LHSTy);
13933 assert(PtrSize <= 64 &&
"Unexpected pointer width");
13934 uint64_t Mask = ~0ULL >> (64 - PtrSize);
13935 CompareLHS &= Mask;
13936 CompareRHS &= Mask;
13941 if (!LHSValue.Base.isNull() && IsRelational) {
13942 QualType BaseTy = getType(LHSValue.Base);
13945 CharUnits Size = Info.Ctx.getTypeSizeInChars(BaseTy);
13946 uint64_t OffsetLimit = Size.getQuantity();
13947 if (CompareLHS > OffsetLimit || CompareRHS > OffsetLimit)
13951 if (CompareLHS < CompareRHS)
13952 return Success(CmpResult::Less,
E);
13953 if (CompareLHS > CompareRHS)
13954 return Success(CmpResult::Greater,
E);
13955 return Success(CmpResult::Equal,
E);
13959 assert(IsEquality &&
"unexpected member pointer operation");
13962 MemberPtr LHSValue, RHSValue;
13965 if (!LHSOK && !Info.noteFailure())
13973 if (LHSValue.getDecl() && LHSValue.getDecl()->isWeak()) {
13974 Info.FFDiag(
E, diag::note_constexpr_mem_pointer_weak_comparison)
13975 << LHSValue.getDecl();
13978 if (RHSValue.getDecl() && RHSValue.getDecl()->isWeak()) {
13979 Info.FFDiag(
E, diag::note_constexpr_mem_pointer_weak_comparison)
13980 << RHSValue.getDecl();
13987 if (!LHSValue.getDecl() || !RHSValue.getDecl()) {
13988 bool Equal = !LHSValue.getDecl() && !RHSValue.getDecl();
13989 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal,
E);
13994 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(LHSValue.getDecl()))
13995 if (MD->isVirtual())
13996 Info.CCEDiag(
E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
13997 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(RHSValue.getDecl()))
13998 if (MD->isVirtual())
13999 Info.CCEDiag(
E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
14005 bool Equal = LHSValue == RHSValue;
14006 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal,
E);
14010 assert(
E->isComparisonOp() &&
"unexpected nullptr operation");
14011 assert(RHSTy->
isNullPtrType() &&
"missing pointer conversion");
14019 return Success(CmpResult::Equal,
E);
14032 case CmpResult::Unequal:
14033 llvm_unreachable(
"should never produce Unequal for three-way comparison");
14034 case CmpResult::Less:
14035 CCR = ComparisonCategoryResult::Less;
14037 case CmpResult::Equal:
14038 CCR = ComparisonCategoryResult::Equal;
14040 case CmpResult::Greater:
14041 CCR = ComparisonCategoryResult::Greater;
14043 case CmpResult::Unordered:
14044 CCR = ComparisonCategoryResult::Unordered;
14058 ConstantExprKind::Normal);
14061 return ExprEvaluatorBaseTy::VisitBinCmp(
E);
14065bool RecordExprEvaluator::VisitCXXParenListInitExpr(
14067 return VisitCXXParenListOrInitListExpr(
E,
E->getInitExprs());
14073 if (
E->isAssignmentOp()) {
14075 if (!Info.noteFailure())
14079 if (DataRecursiveIntBinOpEvaluator::shouldEnqueue(
E))
14080 return DataRecursiveIntBinOpEvaluator(*
this, Result).Traverse(
E);
14084 "DataRecursiveIntBinOpEvaluator should have handled integral types");
14086 if (
E->isComparisonOp()) {
14090 assert((CR != CmpResult::Unequal ||
E->isEqualityOp()) &&
14091 "should only produce Unequal for equality comparisons");
14092 bool IsEqual = CR == CmpResult::Equal,
14093 IsLess = CR == CmpResult::Less,
14094 IsGreater = CR == CmpResult::Greater;
14095 auto Op =
E->getOpcode();
14098 llvm_unreachable(
"unsupported binary operator");
14101 return Success(IsEqual == (Op == BO_EQ),
E);
14107 return Success(IsEqual || IsLess,
E);
14109 return Success(IsEqual || IsGreater,
E);
14113 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
14121 E->getOpcode() == BO_Sub) {
14122 LValue LHSValue, RHSValue;
14125 if (!LHSOK && !Info.noteFailure())
14135 if (!LHSValue.Offset.isZero() || !RHSValue.Offset.isZero())
14137 const Expr *LHSExpr = LHSValue.Base.dyn_cast<
const Expr *>();
14138 const Expr *RHSExpr = RHSValue.Base.dyn_cast<
const Expr *>();
14139 if (!LHSExpr || !RHSExpr)
14141 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
14142 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
14143 if (!LHSAddrExpr || !RHSAddrExpr)
14151 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
14152 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
14154 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
14155 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
14161 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid &&
14164 Info.CCEDiag(
E, diag::note_constexpr_pointer_subtraction_not_same_array);
14176 if (ElementSize.
isZero()) {
14177 Info.FFDiag(
E, diag::note_constexpr_pointer_subtraction_zero_size)
14194 APSInt TrueResult = (LHS - RHS) / ElemSize;
14195 APSInt Result = TrueResult.trunc(Info.Ctx.getIntWidth(
E->
getType()));
14197 if (Result.extend(65) != TrueResult &&
14203 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
14208bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr(
14210 switch(
E->getKind()) {
14211 case UETT_PreferredAlignOf:
14212 case UETT_AlignOf: {
14213 if (
E->isArgumentType())
14221 case UETT_PtrAuthTypeDiscriminator: {
14222 if (
E->getArgumentType()->isDependentType())
14225 Info.Ctx.getPointerAuthTypeDiscriminator(
E->getArgumentType()),
E);
14227 case UETT_VecStep: {
14243 case UETT_DataSizeOf:
14244 case UETT_SizeOf: {
14245 QualType SrcTy =
E->getTypeOfArgument();
14253 E->getKind() == UETT_DataSizeOf ? SizeOfType::DataSizeOf
14254 : SizeOfType::SizeOf)) {
14259 case UETT_OpenMPRequiredSimdAlign:
14260 assert(
E->isArgumentType());
14262 Info.Ctx.toCharUnitsFromBits(
14263 Info.Ctx.getOpenMPDefaultSimdAlign(
E->getArgumentType()))
14266 case UETT_VectorElements: {
14274 if (Info.InConstantContext)
14275 Info.CCEDiag(
E, diag::note_constexpr_non_const_vectorelements)
14282 llvm_unreachable(
"unknown expr/type trait");
14285bool IntExprEvaluator::VisitOffsetOfExpr(
const OffsetOfExpr *OOE) {
14291 for (
unsigned i = 0; i != n; ++i) {
14299 const ArrayType *AT = Info.Ctx.getAsArrayType(CurrentType);
14303 CharUnits ElementSize = Info.Ctx.getTypeSizeInChars(CurrentType);
14304 Result += IdxResult.getSExtValue() * ElementSize;
14317 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
14324 llvm_unreachable(
"dependent __builtin_offsetof");
14340 CurrentType = BaseSpec->
getType();
14354bool IntExprEvaluator::VisitUnaryOperator(
const UnaryOperator *
E) {
14355 switch (
E->getOpcode()) {
14363 return Visit(
E->getSubExpr());
14366 return Visit(
E->getSubExpr());
14368 if (!Visit(
E->getSubExpr()))
14370 if (!Result.isInt())
return Error(
E);
14372 if (
Value.isSigned() &&
Value.isMinSignedValue() &&
E->canOverflow()) {
14373 if (Info.checkingForUndefinedBehavior())
14374 Info.Ctx.getDiagnostics().Report(
E->
getExprLoc(),
14375 diag::warn_integer_constant_overflow)
14387 if (!Visit(
E->getSubExpr()))
14389 if (!Result.isInt())
return Error(
E);
14390 return Success(~Result.getInt(),
E);
14403bool IntExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
14404 const Expr *SubExpr =
E->getSubExpr();
14408 switch (
E->getCastKind()) {
14409 case CK_BaseToDerived:
14410 case CK_DerivedToBase:
14411 case CK_UncheckedDerivedToBase:
14414 case CK_ArrayToPointerDecay:
14415 case CK_FunctionToPointerDecay:
14416 case CK_NullToPointer:
14417 case CK_NullToMemberPointer:
14418 case CK_BaseToDerivedMemberPointer:
14419 case CK_DerivedToBaseMemberPointer:
14420 case CK_ReinterpretMemberPointer:
14421 case CK_ConstructorConversion:
14422 case CK_IntegralToPointer:
14424 case CK_VectorSplat:
14425 case CK_IntegralToFloating:
14426 case CK_FloatingCast:
14427 case CK_CPointerToObjCPointerCast:
14428 case CK_BlockPointerToObjCPointerCast:
14429 case CK_AnyPointerToBlockPointerCast:
14430 case CK_ObjCObjectLValueCast:
14431 case CK_FloatingRealToComplex:
14432 case CK_FloatingComplexToReal:
14433 case CK_FloatingComplexCast:
14434 case CK_FloatingComplexToIntegralComplex:
14435 case CK_IntegralRealToComplex:
14436 case CK_IntegralComplexCast:
14437 case CK_IntegralComplexToFloatingComplex:
14438 case CK_BuiltinFnToFnPtr:
14439 case CK_ZeroToOCLOpaqueType:
14440 case CK_NonAtomicToAtomic:
14441 case CK_AddressSpaceConversion:
14442 case CK_IntToOCLSampler:
14443 case CK_FloatingToFixedPoint:
14444 case CK_FixedPointToFloating:
14445 case CK_FixedPointCast:
14446 case CK_IntegralToFixedPoint:
14447 case CK_MatrixCast:
14448 case CK_HLSLVectorTruncation:
14449 llvm_unreachable(
"invalid cast kind for integral value");
14453 case CK_LValueBitCast:
14454 case CK_ARCProduceObject:
14455 case CK_ARCConsumeObject:
14456 case CK_ARCReclaimReturnedObject:
14457 case CK_ARCExtendBlockObject:
14458 case CK_CopyAndAutoreleaseBlockObject:
14461 case CK_UserDefinedConversion:
14462 case CK_LValueToRValue:
14463 case CK_AtomicToNonAtomic:
14465 case CK_LValueToRValueBitCast:
14466 case CK_HLSLArrayRValue:
14467 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
14469 case CK_MemberPointerToBoolean:
14470 case CK_PointerToBoolean:
14471 case CK_IntegralToBoolean:
14472 case CK_FloatingToBoolean:
14473 case CK_BooleanToSignedIntegral:
14474 case CK_FloatingComplexToBoolean:
14475 case CK_IntegralComplexToBoolean: {
14480 if (BoolResult &&
E->getCastKind() == CK_BooleanToSignedIntegral)
14485 case CK_FixedPointToIntegral: {
14486 APFixedPoint Src(Info.Ctx.getFixedPointSemantics(SrcType));
14490 llvm::APSInt Result = Src.convertToInt(
14491 Info.Ctx.getIntWidth(DestType),
14498 case CK_FixedPointToBoolean: {
14501 if (!
Evaluate(Val, Info, SubExpr))
14506 case CK_IntegralCast: {
14507 if (!Visit(SubExpr))
14510 if (!Result.isInt()) {
14516 if (Result.isAddrLabelDiff())
14517 return Info.Ctx.getTypeSize(DestType) <= Info.Ctx.getTypeSize(SrcType);
14519 return Info.Ctx.getTypeSize(DestType) == Info.Ctx.getTypeSize(SrcType);
14522 if (Info.Ctx.getLangOpts().CPlusPlus && Info.InConstantContext &&
14523 Info.EvalMode == EvalInfo::EM_ConstantExpression &&
14526 bool ConstexprVar =
true;
14533 if (
const auto *VD = dyn_cast_or_null<VarDecl>(
14534 Info.EvaluatingDecl.dyn_cast<
const ValueDecl *>()))
14557 (
Max.slt(Result.getInt().getSExtValue()) ||
14558 Min.sgt(Result.getInt().getSExtValue())))
14559 Info.CCEDiag(
E, diag::note_constexpr_unscoped_enum_out_of_range)
14560 << llvm::toString(Result.getInt(), 10) <<
Min.getSExtValue()
14561 <<
Max.getSExtValue() << ED;
14563 Max.ult(Result.getInt().getZExtValue()))
14564 Info.CCEDiag(
E, diag::note_constexpr_unscoped_enum_out_of_range)
14565 << llvm::toString(Result.getInt(), 10) <<
Min.getZExtValue()
14566 <<
Max.getZExtValue() << ED;
14571 Result.getInt()),
E);
14574 case CK_PointerToIntegral: {
14575 CCEDiag(
E, diag::note_constexpr_invalid_cast)
14582 if (LV.getLValueBase()) {
14587 if (Info.Ctx.getTypeSize(DestType) != Info.Ctx.getTypeSize(SrcType))
14590 LV.Designator.setInvalid();
14591 LV.moveInto(Result);
14598 if (!
V.toIntegralConstant(AsInt, SrcType, Info.Ctx))
14599 llvm_unreachable(
"Can't cast this!");
14604 case CK_IntegralComplexToReal: {
14608 return Success(
C.getComplexIntReal(),
E);
14611 case CK_FloatingToIntegral: {
14623 llvm_unreachable(
"unknown cast resulting in integral value");
14631 if (!LV.isComplexInt())
14633 return Success(LV.getComplexIntReal(),
E);
14636 return Visit(
E->getSubExpr());
14644 if (!LV.isComplexInt())
14646 return Success(LV.getComplexIntImag(),
E);
14649 VisitIgnoredValue(
E->getSubExpr());
14661bool IntExprEvaluator::VisitConceptSpecializationExpr(
14666bool IntExprEvaluator::VisitRequiresExpr(
const RequiresExpr *
E) {
14670bool FixedPointExprEvaluator::VisitUnaryOperator(
const UnaryOperator *
E) {
14671 switch (
E->getOpcode()) {
14677 return Visit(
E->getSubExpr());
14679 if (!Visit(
E->getSubExpr()))
return false;
14680 if (!Result.isFixedPoint())
14683 APFixedPoint Negated = Result.getFixedPoint().negate(&Overflowed);
14697bool FixedPointExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
14698 const Expr *SubExpr =
E->getSubExpr();
14701 "Expected destination type to be a fixed point type");
14702 auto DestFXSema = Info.Ctx.getFixedPointSemantics(DestType);
14704 switch (
E->getCastKind()) {
14705 case CK_FixedPointCast: {
14706 APFixedPoint Src(Info.Ctx.getFixedPointSemantics(SubExpr->
getType()));
14710 APFixedPoint Result = Src.convert(DestFXSema, &Overflowed);
14712 if (Info.checkingForUndefinedBehavior())
14713 Info.Ctx.getDiagnostics().Report(
E->
getExprLoc(),
14714 diag::warn_fixedpoint_constant_overflow)
14715 << Result.toString() <<
E->
getType();
14721 case CK_IntegralToFixedPoint: {
14727 APFixedPoint IntResult = APFixedPoint::getFromIntValue(
14728 Src, Info.Ctx.getFixedPointSemantics(DestType), &Overflowed);
14731 if (Info.checkingForUndefinedBehavior())
14732 Info.Ctx.getDiagnostics().Report(
E->
getExprLoc(),
14733 diag::warn_fixedpoint_constant_overflow)
14734 << IntResult.toString() <<
E->
getType();
14741 case CK_FloatingToFixedPoint: {
14747 APFixedPoint Result = APFixedPoint::getFromFloatValue(
14748 Src, Info.Ctx.getFixedPointSemantics(DestType), &Overflowed);
14751 if (Info.checkingForUndefinedBehavior())
14752 Info.Ctx.getDiagnostics().Report(
E->
getExprLoc(),
14753 diag::warn_fixedpoint_constant_overflow)
14754 << Result.toString() <<
E->
getType();
14762 case CK_LValueToRValue:
14763 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
14769bool FixedPointExprEvaluator::VisitBinaryOperator(
const BinaryOperator *
E) {
14770 if (
E->isPtrMemOp() ||
E->isAssignmentOp() ||
E->getOpcode() == BO_Comma)
14771 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
14773 const Expr *LHS =
E->getLHS();
14774 const Expr *RHS =
E->getRHS();
14775 FixedPointSemantics ResultFXSema =
14776 Info.Ctx.getFixedPointSemantics(
E->
getType());
14778 APFixedPoint LHSFX(Info.Ctx.getFixedPointSemantics(LHS->
getType()));
14781 APFixedPoint RHSFX(Info.Ctx.getFixedPointSemantics(RHS->
getType()));
14785 bool OpOverflow =
false, ConversionOverflow =
false;
14786 APFixedPoint Result(LHSFX.getSemantics());
14787 switch (
E->getOpcode()) {
14789 Result = LHSFX.
add(RHSFX, &OpOverflow)
14790 .convert(ResultFXSema, &ConversionOverflow);
14794 Result = LHSFX.sub(RHSFX, &OpOverflow)
14795 .convert(ResultFXSema, &ConversionOverflow);
14799 Result = LHSFX.mul(RHSFX, &OpOverflow)
14800 .convert(ResultFXSema, &ConversionOverflow);
14804 if (RHSFX.getValue() == 0) {
14805 Info.FFDiag(
E, diag::note_expr_divide_by_zero);
14808 Result = LHSFX.div(RHSFX, &OpOverflow)
14809 .convert(ResultFXSema, &ConversionOverflow);
14814 FixedPointSemantics LHSSema = LHSFX.getSemantics();
14815 llvm::APSInt RHSVal = RHSFX.getValue();
14818 LHSSema.getWidth() - (
unsigned)LHSSema.hasUnsignedPadding();
14819 unsigned Amt = RHSVal.getLimitedValue(ShiftBW - 1);
14823 if (RHSVal.isNegative())
14824 Info.CCEDiag(
E, diag::note_constexpr_negative_shift) << RHSVal;
14825 else if (Amt != RHSVal)
14826 Info.CCEDiag(
E, diag::note_constexpr_large_shift)
14827 << RHSVal <<
E->
getType() << ShiftBW;
14829 if (
E->getOpcode() == BO_Shl)
14830 Result = LHSFX.shl(Amt, &OpOverflow);
14832 Result = LHSFX.shr(Amt, &OpOverflow);
14838 if (OpOverflow || ConversionOverflow) {
14839 if (Info.checkingForUndefinedBehavior())
14840 Info.Ctx.getDiagnostics().Report(
E->
getExprLoc(),
14841 diag::warn_fixedpoint_constant_overflow)
14842 << Result.toString() <<
E->
getType();
14854class FloatExprEvaluator
14855 :
public ExprEvaluatorBase<FloatExprEvaluator> {
14858 FloatExprEvaluator(EvalInfo &info, APFloat &result)
14859 : ExprEvaluatorBaseTy(info), Result(result) {}
14862 Result =
V.getFloat();
14866 bool ZeroInitialization(
const Expr *
E) {
14867 Result = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(
E->
getType()));
14888 return FloatExprEvaluator(Info, Result).Visit(
E);
14895 llvm::APFloat &Result) {
14897 if (!S)
return false;
14904 if (S->getString().empty())
14905 fill = llvm::APInt(32, 0);
14906 else if (S->getString().getAsInteger(0, fill))
14911 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
14913 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
14921 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
14923 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
14929bool FloatExprEvaluator::VisitCallExpr(
const CallExpr *
E) {
14930 if (!IsConstantEvaluatedBuiltinCall(
E))
14931 return ExprEvaluatorBaseTy::VisitCallExpr(
E);
14933 switch (
E->getBuiltinCallee()) {
14937 case Builtin::BI__builtin_huge_val:
14938 case Builtin::BI__builtin_huge_valf:
14939 case Builtin::BI__builtin_huge_vall:
14940 case Builtin::BI__builtin_huge_valf16:
14941 case Builtin::BI__builtin_huge_valf128:
14942 case Builtin::BI__builtin_inf:
14943 case Builtin::BI__builtin_inff:
14944 case Builtin::BI__builtin_infl:
14945 case Builtin::BI__builtin_inff16:
14946 case Builtin::BI__builtin_inff128: {
14947 const llvm::fltSemantics &Sem =
14948 Info.Ctx.getFloatTypeSemantics(
E->
getType());
14949 Result = llvm::APFloat::getInf(Sem);
14953 case Builtin::BI__builtin_nans:
14954 case Builtin::BI__builtin_nansf:
14955 case Builtin::BI__builtin_nansl:
14956 case Builtin::BI__builtin_nansf16:
14957 case Builtin::BI__builtin_nansf128:
14963 case Builtin::BI__builtin_nan:
14964 case Builtin::BI__builtin_nanf:
14965 case Builtin::BI__builtin_nanl:
14966 case Builtin::BI__builtin_nanf16:
14967 case Builtin::BI__builtin_nanf128:
14975 case Builtin::BI__builtin_fabs:
14976 case Builtin::BI__builtin_fabsf:
14977 case Builtin::BI__builtin_fabsl:
14978 case Builtin::BI__builtin_fabsf128:
14987 if (Result.isNegative())
14988 Result.changeSign();
14991 case Builtin::BI__arithmetic_fence:
14998 case Builtin::BI__builtin_copysign:
14999 case Builtin::BI__builtin_copysignf:
15000 case Builtin::BI__builtin_copysignl:
15001 case Builtin::BI__builtin_copysignf128: {
15006 Result.copySign(RHS);
15010 case Builtin::BI__builtin_fmax:
15011 case Builtin::BI__builtin_fmaxf:
15012 case Builtin::BI__builtin_fmaxl:
15013 case Builtin::BI__builtin_fmaxf16:
15014 case Builtin::BI__builtin_fmaxf128: {
15021 if (Result.isZero() && RHS.isZero() && Result.isNegative())
15023 else if (Result.isNaN() || RHS > Result)
15028 case Builtin::BI__builtin_fmin:
15029 case Builtin::BI__builtin_fminf:
15030 case Builtin::BI__builtin_fminl:
15031 case Builtin::BI__builtin_fminf16:
15032 case Builtin::BI__builtin_fminf128: {
15039 if (Result.isZero() && RHS.isZero() && RHS.isNegative())
15041 else if (Result.isNaN() || RHS < Result)
15048bool FloatExprEvaluator::VisitUnaryReal(
const UnaryOperator *
E) {
15053 Result = CV.FloatReal;
15057 return Visit(
E->getSubExpr());
15060bool FloatExprEvaluator::VisitUnaryImag(
const UnaryOperator *
E) {
15065 Result = CV.FloatImag;
15069 VisitIgnoredValue(
E->getSubExpr());
15070 const llvm::fltSemantics &Sem = Info.Ctx.getFloatTypeSemantics(
E->
getType());
15071 Result = llvm::APFloat::getZero(Sem);
15075bool FloatExprEvaluator::VisitUnaryOperator(
const UnaryOperator *
E) {
15076 switch (
E->getOpcode()) {
15077 default:
return Error(
E);
15086 Result.changeSign();
15091bool FloatExprEvaluator::VisitBinaryOperator(
const BinaryOperator *
E) {
15092 if (
E->isPtrMemOp() ||
E->isAssignmentOp() ||
E->getOpcode() == BO_Comma)
15093 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
15097 if (!LHSOK && !Info.noteFailure())
15104 Result =
E->getValue();
15108bool FloatExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
15109 const Expr* SubExpr =
E->getSubExpr();
15111 switch (
E->getCastKind()) {
15113 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
15115 case CK_IntegralToFloating: {
15118 Info.Ctx.getLangOpts());
15124 case CK_FixedPointToFloating: {
15125 APFixedPoint FixResult(Info.Ctx.getFixedPointSemantics(SubExpr->
getType()));
15129 FixResult.convertToFloat(Info.Ctx.getFloatTypeSemantics(
E->
getType()));
15133 case CK_FloatingCast: {
15134 if (!Visit(SubExpr))
15140 case CK_FloatingComplexToReal: {
15144 Result =
V.getComplexFloatReal();
15155class ComplexExprEvaluator
15156 :
public ExprEvaluatorBase<ComplexExprEvaluator> {
15157 ComplexValue &Result;
15160 ComplexExprEvaluator(EvalInfo &info, ComplexValue &Result)
15161 : ExprEvaluatorBaseTy(info), Result(Result) {}
15168 bool ZeroInitialization(
const Expr *
E);
15187 return ComplexExprEvaluator(Info, Result).Visit(
E);
15190bool ComplexExprEvaluator::ZeroInitialization(
const Expr *
E) {
15193 Result.makeComplexFloat();
15194 APFloat Zero = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(ElemTy));
15195 Result.FloatReal =
Zero;
15196 Result.FloatImag =
Zero;
15198 Result.makeComplexInt();
15199 APSInt Zero = Info.Ctx.MakeIntValue(0, ElemTy);
15200 Result.IntReal =
Zero;
15201 Result.IntImag =
Zero;
15207 const Expr* SubExpr =
E->getSubExpr();
15210 Result.makeComplexFloat();
15211 APFloat &Imag = Result.FloatImag;
15215 Result.FloatReal =
APFloat(Imag.getSemantics());
15219 "Unexpected imaginary literal.");
15221 Result.makeComplexInt();
15222 APSInt &Imag = Result.IntImag;
15226 Result.IntReal =
APSInt(Imag.getBitWidth(), !Imag.isSigned());
15231bool ComplexExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
15233 switch (
E->getCastKind()) {
15235 case CK_BaseToDerived:
15236 case CK_DerivedToBase:
15237 case CK_UncheckedDerivedToBase:
15240 case CK_ArrayToPointerDecay:
15241 case CK_FunctionToPointerDecay:
15242 case CK_NullToPointer:
15243 case CK_NullToMemberPointer:
15244 case CK_BaseToDerivedMemberPointer:
15245 case CK_DerivedToBaseMemberPointer:
15246 case CK_MemberPointerToBoolean:
15247 case CK_ReinterpretMemberPointer:
15248 case CK_ConstructorConversion:
15249 case CK_IntegralToPointer:
15250 case CK_PointerToIntegral:
15251 case CK_PointerToBoolean:
15253 case CK_VectorSplat:
15254 case CK_IntegralCast:
15255 case CK_BooleanToSignedIntegral:
15256 case CK_IntegralToBoolean:
15257 case CK_IntegralToFloating:
15258 case CK_FloatingToIntegral:
15259 case CK_FloatingToBoolean:
15260 case CK_FloatingCast:
15261 case CK_CPointerToObjCPointerCast:
15262 case CK_BlockPointerToObjCPointerCast:
15263 case CK_AnyPointerToBlockPointerCast:
15264 case CK_ObjCObjectLValueCast:
15265 case CK_FloatingComplexToReal:
15266 case CK_FloatingComplexToBoolean:
15267 case CK_IntegralComplexToReal:
15268 case CK_IntegralComplexToBoolean:
15269 case CK_ARCProduceObject:
15270 case CK_ARCConsumeObject:
15271 case CK_ARCReclaimReturnedObject:
15272 case CK_ARCExtendBlockObject:
15273 case CK_CopyAndAutoreleaseBlockObject:
15274 case CK_BuiltinFnToFnPtr:
15275 case CK_ZeroToOCLOpaqueType:
15276 case CK_NonAtomicToAtomic:
15277 case CK_AddressSpaceConversion:
15278 case CK_IntToOCLSampler:
15279 case CK_FloatingToFixedPoint:
15280 case CK_FixedPointToFloating:
15281 case CK_FixedPointCast:
15282 case CK_FixedPointToBoolean:
15283 case CK_FixedPointToIntegral:
15284 case CK_IntegralToFixedPoint:
15285 case CK_MatrixCast:
15286 case CK_HLSLVectorTruncation:
15287 llvm_unreachable(
"invalid cast kind for complex value");
15289 case CK_LValueToRValue:
15290 case CK_AtomicToNonAtomic:
15292 case CK_LValueToRValueBitCast:
15293 case CK_HLSLArrayRValue:
15294 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
15297 case CK_LValueBitCast:
15298 case CK_UserDefinedConversion:
15301 case CK_FloatingRealToComplex: {
15302 APFloat &Real = Result.FloatReal;
15306 Result.makeComplexFloat();
15307 Result.FloatImag =
APFloat(Real.getSemantics());
15311 case CK_FloatingComplexCast: {
15312 if (!Visit(
E->getSubExpr()))
15323 case CK_FloatingComplexToIntegralComplex: {
15324 if (!Visit(
E->getSubExpr()))
15330 Result.makeComplexInt();
15332 To, Result.IntReal) &&
15334 To, Result.IntImag);
15337 case CK_IntegralRealToComplex: {
15338 APSInt &Real = Result.IntReal;
15342 Result.makeComplexInt();
15343 Result.IntImag =
APSInt(Real.getBitWidth(), !Real.isSigned());
15347 case CK_IntegralComplexCast: {
15348 if (!Visit(
E->getSubExpr()))
15360 case CK_IntegralComplexToFloatingComplex: {
15361 if (!Visit(
E->getSubExpr()))
15365 Info.Ctx.getLangOpts());
15369 Result.makeComplexFloat();
15371 To, Result.FloatReal) &&
15373 To, Result.FloatImag);
15377 llvm_unreachable(
"unknown cast resulting in complex value");
15381 APFloat &ResR, APFloat &ResI) {
15387 APFloat AC = A *
C;
15388 APFloat BD = B *
D;
15389 APFloat AD = A *
D;
15390 APFloat BC = B *
C;
15393 if (ResR.isNaN() && ResI.isNaN()) {
15394 bool Recalc =
false;
15395 if (A.isInfinity() || B.isInfinity()) {
15396 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
15398 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
15401 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
15403 D = APFloat::copySign(APFloat(
D.getSemantics()),
D);
15406 if (
C.isInfinity() ||
D.isInfinity()) {
15407 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
15409 D = APFloat::copySign(APFloat(
D.getSemantics(),
D.isInfinity() ? 1 : 0),
15412 A = APFloat::copySign(APFloat(A.getSemantics()), A);
15414 B = APFloat::copySign(APFloat(B.getSemantics()), B);
15417 if (!Recalc && (AC.isInfinity() || BD.isInfinity() || AD.isInfinity() ||
15418 BC.isInfinity())) {
15420 A = APFloat::copySign(APFloat(A.getSemantics()), A);
15422 B = APFloat::copySign(APFloat(B.getSemantics()), B);
15424 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
15426 D = APFloat::copySign(APFloat(
D.getSemantics()),
D);
15430 ResR = APFloat::getInf(A.getSemantics()) * (A *
C - B *
D);
15431 ResI = APFloat::getInf(A.getSemantics()) * (A *
D + B *
C);
15437 APFloat &ResR, APFloat &ResI) {
15444 APFloat MaxCD = maxnum(
abs(
C),
abs(
D));
15445 if (MaxCD.isFinite()) {
15446 DenomLogB =
ilogb(MaxCD);
15447 C =
scalbn(
C, -DenomLogB, APFloat::rmNearestTiesToEven);
15448 D =
scalbn(
D, -DenomLogB, APFloat::rmNearestTiesToEven);
15450 APFloat Denom =
C *
C +
D *
D;
15452 scalbn((A *
C + B *
D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
15454 scalbn((B *
C - A *
D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
15455 if (ResR.isNaN() && ResI.isNaN()) {
15456 if (Denom.isPosZero() && (!A.isNaN() || !B.isNaN())) {
15457 ResR = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * A;
15458 ResI = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * B;
15459 }
else if ((A.isInfinity() || B.isInfinity()) &&
C.isFinite() &&
15461 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
15463 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
15465 ResR = APFloat::getInf(ResR.getSemantics()) * (A *
C + B *
D);
15466 ResI = APFloat::getInf(ResI.getSemantics()) * (B *
C - A *
D);
15467 }
else if (MaxCD.isInfinity() && A.isFinite() && B.isFinite()) {
15468 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
15470 D = APFloat::copySign(APFloat(
D.getSemantics(),
D.isInfinity() ? 1 : 0),
15472 ResR = APFloat::getZero(ResR.getSemantics()) * (A *
C + B *
D);
15473 ResI = APFloat::getZero(ResI.getSemantics()) * (B *
C - A *
D);
15478bool ComplexExprEvaluator::VisitBinaryOperator(
const BinaryOperator *
E) {
15479 if (
E->isPtrMemOp() ||
E->isAssignmentOp() ||
E->getOpcode() == BO_Comma)
15480 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
15484 bool LHSReal =
false, RHSReal =
false;
15489 APFloat &Real = Result.FloatReal;
15492 Result.makeComplexFloat();
15493 Result.FloatImag =
APFloat(Real.getSemantics());
15496 LHSOK = Visit(
E->getLHS());
15498 if (!LHSOK && !Info.noteFailure())
15504 APFloat &Real = RHS.FloatReal;
15507 RHS.makeComplexFloat();
15508 RHS.FloatImag =
APFloat(Real.getSemantics());
15512 assert(!(LHSReal && RHSReal) &&
15513 "Cannot have both operands of a complex operation be real.");
15514 switch (
E->getOpcode()) {
15515 default:
return Error(
E);
15517 if (Result.isComplexFloat()) {
15518 Result.getComplexFloatReal().
add(RHS.getComplexFloatReal(),
15519 APFloat::rmNearestTiesToEven);
15521 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
15523 Result.getComplexFloatImag().
add(RHS.getComplexFloatImag(),
15524 APFloat::rmNearestTiesToEven);
15526 Result.getComplexIntReal() += RHS.getComplexIntReal();
15527 Result.getComplexIntImag() += RHS.getComplexIntImag();
15531 if (Result.isComplexFloat()) {
15532 Result.getComplexFloatReal().subtract(RHS.getComplexFloatReal(),
15533 APFloat::rmNearestTiesToEven);
15535 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
15536 Result.getComplexFloatImag().changeSign();
15537 }
else if (!RHSReal) {
15538 Result.getComplexFloatImag().subtract(RHS.getComplexFloatImag(),
15539 APFloat::rmNearestTiesToEven);
15542 Result.getComplexIntReal() -= RHS.getComplexIntReal();
15543 Result.getComplexIntImag() -= RHS.getComplexIntImag();
15547 if (Result.isComplexFloat()) {
15552 ComplexValue LHS = Result;
15553 APFloat &A = LHS.getComplexFloatReal();
15554 APFloat &B = LHS.getComplexFloatImag();
15555 APFloat &
C = RHS.getComplexFloatReal();
15556 APFloat &
D = RHS.getComplexFloatImag();
15557 APFloat &ResR = Result.getComplexFloatReal();
15558 APFloat &ResI = Result.getComplexFloatImag();
15560 assert(!RHSReal &&
"Cannot have two real operands for a complex op!");
15568 }
else if (RHSReal) {
15580 ComplexValue LHS = Result;
15581 Result.getComplexIntReal() =
15582 (LHS.getComplexIntReal() * RHS.getComplexIntReal() -
15583 LHS.getComplexIntImag() * RHS.getComplexIntImag());
15584 Result.getComplexIntImag() =
15585 (LHS.getComplexIntReal() * RHS.getComplexIntImag() +
15586 LHS.getComplexIntImag() * RHS.getComplexIntReal());
15590 if (Result.isComplexFloat()) {
15595 ComplexValue LHS = Result;
15596 APFloat &A = LHS.getComplexFloatReal();
15597 APFloat &B = LHS.getComplexFloatImag();
15598 APFloat &
C = RHS.getComplexFloatReal();
15599 APFloat &
D = RHS.getComplexFloatImag();
15600 APFloat &ResR = Result.getComplexFloatReal();
15601 APFloat &ResI = Result.getComplexFloatImag();
15613 B = APFloat::getZero(A.getSemantics());
15618 ComplexValue LHS = Result;
15619 APSInt Den = RHS.getComplexIntReal() * RHS.getComplexIntReal() +
15620 RHS.getComplexIntImag() * RHS.getComplexIntImag();
15622 return Error(
E, diag::note_expr_divide_by_zero);
15624 Result.getComplexIntReal() =
15625 (LHS.getComplexIntReal() * RHS.getComplexIntReal() +
15626 LHS.getComplexIntImag() * RHS.getComplexIntImag()) / Den;
15627 Result.getComplexIntImag() =
15628 (LHS.getComplexIntImag() * RHS.getComplexIntReal() -
15629 LHS.getComplexIntReal() * RHS.getComplexIntImag()) / Den;
15637bool ComplexExprEvaluator::VisitUnaryOperator(
const UnaryOperator *
E) {
15639 if (!Visit(
E->getSubExpr()))
15642 switch (
E->getOpcode()) {
15651 if (Result.isComplexFloat()) {
15652 Result.getComplexFloatReal().changeSign();
15653 Result.getComplexFloatImag().changeSign();
15656 Result.getComplexIntReal() = -Result.getComplexIntReal();
15657 Result.getComplexIntImag() = -Result.getComplexIntImag();
15661 if (Result.isComplexFloat())
15662 Result.getComplexFloatImag().changeSign();
15664 Result.getComplexIntImag() = -Result.getComplexIntImag();
15669bool ComplexExprEvaluator::VisitInitListExpr(
const InitListExpr *
E) {
15670 if (
E->getNumInits() == 2) {
15672 Result.makeComplexFloat();
15678 Result.makeComplexInt();
15686 return ExprEvaluatorBaseTy::VisitInitListExpr(
E);
15689bool ComplexExprEvaluator::VisitCallExpr(
const CallExpr *
E) {
15690 if (!IsConstantEvaluatedBuiltinCall(
E))
15691 return ExprEvaluatorBaseTy::VisitCallExpr(
E);
15693 switch (
E->getBuiltinCallee()) {
15694 case Builtin::BI__builtin_complex:
15695 Result.makeComplexFloat();
15713class AtomicExprEvaluator :
15714 public ExprEvaluatorBase<AtomicExprEvaluator> {
15715 const LValue *
This;
15718 AtomicExprEvaluator(EvalInfo &Info,
const LValue *This,
APValue &Result)
15719 : ExprEvaluatorBaseTy(Info),
This(
This), Result(Result) {}
15726 bool ZeroInitialization(
const Expr *
E) {
15735 bool VisitCastExpr(
const CastExpr *
E) {
15736 switch (
E->getCastKind()) {
15738 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
15739 case CK_NullToPointer:
15740 VisitIgnoredValue(
E->getSubExpr());
15741 return ZeroInitialization(
E);
15742 case CK_NonAtomicToAtomic:
15744 :
Evaluate(Result, Info,
E->getSubExpr());
15754 return AtomicExprEvaluator(Info, This, Result).Visit(
E);
15763class VoidExprEvaluator
15764 :
public ExprEvaluatorBase<VoidExprEvaluator> {
15766 VoidExprEvaluator(EvalInfo &Info) : ExprEvaluatorBaseTy(Info) {}
15770 bool ZeroInitialization(
const Expr *
E) {
return true; }
15772 bool VisitCastExpr(
const CastExpr *
E) {
15773 switch (
E->getCastKind()) {
15775 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
15777 VisitIgnoredValue(
E->getSubExpr());
15782 bool VisitCallExpr(
const CallExpr *
E) {
15783 if (!IsConstantEvaluatedBuiltinCall(
E))
15784 return ExprEvaluatorBaseTy::VisitCallExpr(
E);
15786 switch (
E->getBuiltinCallee()) {
15787 case Builtin::BI__assume:
15788 case Builtin::BI__builtin_assume:
15792 case Builtin::BI__builtin_operator_delete:
15804bool VoidExprEvaluator::VisitCXXDeleteExpr(
const CXXDeleteExpr *
E) {
15806 if (Info.SpeculativeEvaluationDepth)
15811 Info.FFDiag(
E, diag::note_constexpr_new_non_replaceable)
15812 << isa<CXXMethodDecl>(OperatorDelete) << OperatorDelete;
15816 const Expr *Arg =
E->getArgument();
15821 if (
Pointer.Designator.Invalid)
15825 if (
Pointer.isNullPointer()) {
15829 if (!Info.getLangOpts().CPlusPlus20)
15830 Info.CCEDiag(
E, diag::note_constexpr_new);
15835 Info,
E,
Pointer,
E->isArrayForm() ? DynAlloc::ArrayNew : DynAlloc::New);
15842 if (!
E->isArrayForm() &&
Pointer.Designator.Entries.size() != 0 &&
15844 Info.FFDiag(
E, diag::note_constexpr_delete_base_nonvirt_dtor)
15851 if (!
E->isArrayForm() && !
E->isGlobalDelete()) {
15853 if (VirtualDelete &&
15855 Info.FFDiag(
E, diag::note_constexpr_new_non_replaceable)
15856 << isa<CXXMethodDecl>(VirtualDelete) << VirtualDelete;
15862 (*Alloc)->Value, AllocType))
15870 Info.FFDiag(
E, diag::note_constexpr_double_delete);
15880 return VoidExprEvaluator(Info).Visit(
E);
15896 LV.moveInto(Result);
15901 if (!IntExprEvaluator(Info, Result).Visit(
E))
15907 LV.moveInto(Result);
15909 llvm::APFloat F(0.0);
15917 C.moveInto(Result);
15919 if (!FixedPointExprEvaluator(Info, Result).Visit(
E))
return false;
15924 P.moveInto(Result);
15929 Info.CurrentCall->createTemporary(
E,
T, ScopeKind::FullExpression, LV);
15936 Info.CurrentCall->createTemporary(
E,
T, ScopeKind::FullExpression, LV);
15941 if (!Info.getLangOpts().CPlusPlus11)
15942 Info.CCEDiag(
E, diag::note_constexpr_nonliteral)
15947 QualType Unqual =
T.getAtomicUnqualifiedType();
15951 E, Unqual, ScopeKind::FullExpression, LV);
15959 }
else if (Info.getLangOpts().CPlusPlus11) {
15960 Info.FFDiag(
E, diag::note_constexpr_nonliteral) <<
E->
getType();
15963 Info.FFDiag(
E, diag::note_invalid_subexpr_in_const_expr);
15974 const Expr *
E,
bool AllowNonLiteralTypes) {
15989 QualType Unqual =
T.getAtomicUnqualifiedType();
16010 if (Info.EnableNewConstInterp) {
16011 if (!Info.Ctx.getInterpContext().evaluateAsRValue(Info,
E, Result))
16014 ConstantExprKind::Normal);
16023 LV.setFrom(Info.Ctx, Result);
16030 ConstantExprKind::Normal) &&
16040 L->getType()->isUnsignedIntegerType()));
16045 if (
const auto *L = dyn_cast<CXXBoolLiteralExpr>(Exp)) {
16051 if (
const auto *CE = dyn_cast<ConstantExpr>(Exp)) {
16052 if (CE->hasAPValueResult()) {
16053 APValue APV = CE->getAPValueResult();
16055 Result.Val = std::move(APV);
16131 bool InConstantContext)
const {
16132 assert(!isValueDependent() &&
16133 "Expression evaluator can't be called on a dependent expression.");
16134 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsRValue");
16135 EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
16136 Info.InConstantContext = InConstantContext;
16137 return ::EvaluateAsRValue(
this, Result, Ctx, Info);
16141 bool InConstantContext)
const {
16142 assert(!isValueDependent() &&
16143 "Expression evaluator can't be called on a dependent expression.");
16144 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsBooleanCondition");
16152 bool InConstantContext)
const {
16153 assert(!isValueDependent() &&
16154 "Expression evaluator can't be called on a dependent expression.");
16155 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsInt");
16156 EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
16157 Info.InConstantContext = InConstantContext;
16158 return ::EvaluateAsInt(
this, Result, Ctx, AllowSideEffects, Info);
16163 bool InConstantContext)
const {
16164 assert(!isValueDependent() &&
16165 "Expression evaluator can't be called on a dependent expression.");
16166 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFixedPoint");
16167 EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
16168 Info.InConstantContext = InConstantContext;
16169 return ::EvaluateAsFixedPoint(
this, Result, Ctx, AllowSideEffects, Info);
16174 bool InConstantContext)
const {
16175 assert(!isValueDependent() &&
16176 "Expression evaluator can't be called on a dependent expression.");
16178 if (!getType()->isRealFloatingType())
16181 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFloat");
16193 bool InConstantContext)
const {
16194 assert(!isValueDependent() &&
16195 "Expression evaluator can't be called on a dependent expression.");
16197 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsLValue");
16198 EvalInfo Info(Ctx, Result, EvalInfo::EM_ConstantFold);
16199 Info.InConstantContext = InConstantContext;
16202 if (!
EvaluateLValue(
this, LV, Info) || !Info.discardCleanups() ||
16203 Result.HasSideEffects ||
16206 ConstantExprKind::Normal, CheckedTemps))
16209 LV.moveInto(Result.Val);
16216 bool IsConstantDestruction) {
16217 EvalInfo Info(Ctx, EStatus,
16218 IsConstantDestruction ? EvalInfo::EM_ConstantExpression
16219 : EvalInfo::EM_ConstantFold);
16220 Info.setEvaluatingDecl(
Base, DestroyedValue,
16221 EvalInfo::EvaluatingDeclKind::Dtor);
16222 Info.InConstantContext = IsConstantDestruction;
16231 if (!Info.discardCleanups())
16232 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
16239 assert(!isValueDependent() &&
16240 "Expression evaluator can't be called on a dependent expression.");
16245 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsConstantExpr");
16246 EvalInfo::EvaluationMode EM = EvalInfo::EM_ConstantExpression;
16247 EvalInfo Info(Ctx, Result, EM);
16248 Info.InConstantContext =
true;
16250 if (Info.EnableNewConstInterp) {
16251 if (!Info.Ctx.getInterpContext().evaluate(Info,
this, Result.Val))
16254 getStorageType(Ctx,
this), Result.Val, Kind);
16259 if (Kind == ConstantExprKind::ClassTemplateArgument)
16267 Info.setEvaluatingDecl(
Base, Result.Val);
16269 if (Info.EnableNewConstInterp) {
16270 if (!Info.Ctx.getInterpContext().evaluateAsRValue(Info,
this, Result.Val))
16279 FullExpressionRAII
Scope(Info);
16281 Result.HasSideEffects || !
Scope.destroy())
16284 if (!Info.discardCleanups())
16285 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
16296 if (Kind == ConstantExprKind::ClassTemplateArgument &&
16299 Result.HasSideEffects)) {
16311 bool IsConstantInitialization)
const {
16312 assert(!isValueDependent() &&
16313 "Expression evaluator can't be called on a dependent expression.");
16315 llvm::TimeTraceScope TimeScope(
"EvaluateAsInitializer", [&] {
16317 llvm::raw_string_ostream OS(Name);
16323 EStatus.
Diag = &Notes;
16325 EvalInfo Info(Ctx, EStatus,
16326 (IsConstantInitialization &&
16328 ? EvalInfo::EM_ConstantExpression
16329 : EvalInfo::EM_ConstantFold);
16330 Info.setEvaluatingDecl(VD,
Value);
16331 Info.InConstantContext = IsConstantInitialization;
16336 if (Info.EnableNewConstInterp) {
16337 auto &InterpCtx =
const_cast<ASTContext &
>(Ctx).getInterpContext();
16338 if (!InterpCtx.evaluateAsInitializer(Info, VD,
Value))
16342 ConstantExprKind::Normal);
16357 FullExpressionRAII
Scope(Info);
16360 EStatus.HasSideEffects)
16366 Info.performLifetimeExtension();
16368 if (!Info.discardCleanups())
16369 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
16373 ConstantExprKind::Normal) &&
16380 EStatus.
Diag = &Notes;
16384 bool IsConstantDestruction = hasConstantInitialization();
16390 if (getEvaluatedValue() && !getEvaluatedValue()->isAbsent())
16391 DestroyedValue = *getEvaluatedValue();
16396 getType(), getLocation(), EStatus,
16397 IsConstantDestruction) ||
16401 ensureEvaluatedStmt()->HasConstantDestruction =
true;
16408 assert(!isValueDependent() &&
16409 "Expression evaluator can't be called on a dependent expression.");
16418 assert(!isValueDependent() &&
16419 "Expression evaluator can't be called on a dependent expression.");
16421 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstInt");
16424 EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
16425 Info.InConstantContext =
true;
16429 assert(Result &&
"Could not evaluate expression");
16430 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
16432 return EVResult.Val.getInt();
16437 assert(!isValueDependent() &&
16438 "Expression evaluator can't be called on a dependent expression.");
16440 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstIntCheckOverflow");
16443 EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
16444 Info.InConstantContext =
true;
16445 Info.CheckingForUndefinedBehavior =
true;
16449 assert(Result &&
"Could not evaluate expression");
16450 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
16452 return EVResult.Val.getInt();
16456 assert(!isValueDependent() &&
16457 "Expression evaluator can't be called on a dependent expression.");
16459 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateForOverflow");
16463 EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
16464 Info.CheckingForUndefinedBehavior =
true;
16497 IK_ICEIfUnevaluated,
16513static ICEDiag
Worst(ICEDiag A, ICEDiag B) {
return A.Kind >= B.Kind ? A : B; }
16518 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
16520 Info.InConstantContext =
true;
16534#define ABSTRACT_STMT(Node)
16535#define STMT(Node, Base) case Expr::Node##Class:
16536#define EXPR(Node, Base)
16537#include "clang/AST/StmtNodes.inc"
16538 case Expr::PredefinedExprClass:
16539 case Expr::FloatingLiteralClass:
16540 case Expr::ImaginaryLiteralClass:
16541 case Expr::StringLiteralClass:
16542 case Expr::ArraySubscriptExprClass:
16543 case Expr::MatrixSubscriptExprClass:
16544 case Expr::ArraySectionExprClass:
16545 case Expr::OMPArrayShapingExprClass:
16546 case Expr::OMPIteratorExprClass:
16547 case Expr::MemberExprClass:
16548 case Expr::CompoundAssignOperatorClass:
16549 case Expr::CompoundLiteralExprClass:
16550 case Expr::ExtVectorElementExprClass:
16551 case Expr::DesignatedInitExprClass:
16552 case Expr::ArrayInitLoopExprClass:
16553 case Expr::ArrayInitIndexExprClass:
16554 case Expr::NoInitExprClass:
16555 case Expr::DesignatedInitUpdateExprClass:
16556 case Expr::ImplicitValueInitExprClass:
16557 case Expr::ParenListExprClass:
16558 case Expr::VAArgExprClass:
16559 case Expr::AddrLabelExprClass:
16560 case Expr::StmtExprClass:
16561 case Expr::CXXMemberCallExprClass:
16562 case Expr::CUDAKernelCallExprClass:
16563 case Expr::CXXAddrspaceCastExprClass:
16564 case Expr::CXXDynamicCastExprClass:
16565 case Expr::CXXTypeidExprClass:
16566 case Expr::CXXUuidofExprClass:
16567 case Expr::MSPropertyRefExprClass:
16568 case Expr::MSPropertySubscriptExprClass:
16569 case Expr::CXXNullPtrLiteralExprClass:
16570 case Expr::UserDefinedLiteralClass:
16571 case Expr::CXXThisExprClass:
16572 case Expr::CXXThrowExprClass:
16573 case Expr::CXXNewExprClass:
16574 case Expr::CXXDeleteExprClass:
16575 case Expr::CXXPseudoDestructorExprClass:
16576 case Expr::UnresolvedLookupExprClass:
16577 case Expr::TypoExprClass:
16578 case Expr::RecoveryExprClass:
16579 case Expr::DependentScopeDeclRefExprClass:
16580 case Expr::CXXConstructExprClass:
16581 case Expr::CXXInheritedCtorInitExprClass:
16582 case Expr::CXXStdInitializerListExprClass:
16583 case Expr::CXXBindTemporaryExprClass:
16584 case Expr::ExprWithCleanupsClass:
16585 case Expr::CXXTemporaryObjectExprClass:
16586 case Expr::CXXUnresolvedConstructExprClass:
16587 case Expr::CXXDependentScopeMemberExprClass:
16588 case Expr::UnresolvedMemberExprClass:
16589 case Expr::ObjCStringLiteralClass:
16590 case Expr::ObjCBoxedExprClass:
16591 case Expr::ObjCArrayLiteralClass:
16592 case Expr::ObjCDictionaryLiteralClass:
16593 case Expr::ObjCEncodeExprClass:
16594 case Expr::ObjCMessageExprClass:
16595 case Expr::ObjCSelectorExprClass:
16596 case Expr::ObjCProtocolExprClass:
16597 case Expr::ObjCIvarRefExprClass:
16598 case Expr::ObjCPropertyRefExprClass:
16599 case Expr::ObjCSubscriptRefExprClass:
16600 case Expr::ObjCIsaExprClass:
16601 case Expr::ObjCAvailabilityCheckExprClass:
16602 case Expr::ShuffleVectorExprClass:
16603 case Expr::ConvertVectorExprClass:
16604 case Expr::BlockExprClass:
16605 case Expr::NoStmtClass:
16606 case Expr::OpaqueValueExprClass:
16607 case Expr::PackExpansionExprClass:
16608 case Expr::SubstNonTypeTemplateParmPackExprClass:
16609 case Expr::FunctionParmPackExprClass:
16610 case Expr::AsTypeExprClass:
16611 case Expr::ObjCIndirectCopyRestoreExprClass:
16612 case Expr::MaterializeTemporaryExprClass:
16613 case Expr::PseudoObjectExprClass:
16614 case Expr::AtomicExprClass:
16615 case Expr::LambdaExprClass:
16616 case Expr::CXXFoldExprClass:
16617 case Expr::CoawaitExprClass:
16618 case Expr::DependentCoawaitExprClass:
16619 case Expr::CoyieldExprClass:
16620 case Expr::SYCLUniqueStableNameExprClass:
16621 case Expr::CXXParenListInitExprClass:
16624 case Expr::InitListExprClass: {
16630 if (cast<InitListExpr>(
E)->getNumInits() == 1)
16631 return CheckICE(cast<InitListExpr>(
E)->getInit(0), Ctx);
16635 case Expr::SizeOfPackExprClass:
16636 case Expr::GNUNullExprClass:
16637 case Expr::SourceLocExprClass:
16638 case Expr::EmbedExprClass:
16641 case Expr::PackIndexingExprClass:
16642 return CheckICE(cast<PackIndexingExpr>(
E)->getSelectedExpr(), Ctx);
16644 case Expr::SubstNonTypeTemplateParmExprClass:
16646 CheckICE(cast<SubstNonTypeTemplateParmExpr>(
E)->getReplacement(), Ctx);
16648 case Expr::ConstantExprClass:
16649 return CheckICE(cast<ConstantExpr>(
E)->getSubExpr(), Ctx);
16651 case Expr::ParenExprClass:
16652 return CheckICE(cast<ParenExpr>(
E)->getSubExpr(), Ctx);
16653 case Expr::GenericSelectionExprClass:
16654 return CheckICE(cast<GenericSelectionExpr>(
E)->getResultExpr(), Ctx);
16655 case Expr::IntegerLiteralClass:
16656 case Expr::FixedPointLiteralClass:
16657 case Expr::CharacterLiteralClass:
16658 case Expr::ObjCBoolLiteralExprClass:
16659 case Expr::CXXBoolLiteralExprClass:
16660 case Expr::CXXScalarValueInitExprClass:
16661 case Expr::TypeTraitExprClass:
16662 case Expr::ConceptSpecializationExprClass:
16663 case Expr::RequiresExprClass:
16664 case Expr::ArrayTypeTraitExprClass:
16665 case Expr::ExpressionTraitExprClass:
16666 case Expr::CXXNoexceptExprClass:
16668 case Expr::CallExprClass:
16669 case Expr::CXXOperatorCallExprClass: {
16673 const CallExpr *CE = cast<CallExpr>(
E);
16678 case Expr::CXXRewrittenBinaryOperatorClass:
16679 return CheckICE(cast<CXXRewrittenBinaryOperator>(
E)->getSemanticForm(),
16681 case Expr::DeclRefExprClass: {
16682 const NamedDecl *
D = cast<DeclRefExpr>(
E)->getDecl();
16683 if (isa<EnumConstantDecl>(
D))
16695 const VarDecl *VD = dyn_cast<VarDecl>(
D);
16702 case Expr::UnaryOperatorClass: {
16725 llvm_unreachable(
"invalid unary operator class");
16727 case Expr::OffsetOfExprClass: {
16736 case Expr::UnaryExprOrTypeTraitExprClass: {
16738 if ((Exp->
getKind() == UETT_SizeOf) &&
16743 case Expr::BinaryOperatorClass: {
16788 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE) {
16791 return ICEDiag(IK_ICEIfUnevaluated,
E->
getBeginLoc());
16792 if (REval.isSigned() && REval.isAllOnes()) {
16794 if (LEval.isMinSignedValue())
16795 return ICEDiag(IK_ICEIfUnevaluated,
E->
getBeginLoc());
16803 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE)
16804 return ICEDiag(IK_ICEIfUnevaluated,
E->
getBeginLoc());
16810 return Worst(LHSResult, RHSResult);
16816 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICEIfUnevaluated) {
16826 return Worst(LHSResult, RHSResult);
16829 llvm_unreachable(
"invalid binary operator kind");
16831 case Expr::ImplicitCastExprClass:
16832 case Expr::CStyleCastExprClass:
16833 case Expr::CXXFunctionalCastExprClass:
16834 case Expr::CXXStaticCastExprClass:
16835 case Expr::CXXReinterpretCastExprClass:
16836 case Expr::CXXConstCastExprClass:
16837 case Expr::ObjCBridgedCastExprClass: {
16838 const Expr *SubExpr = cast<CastExpr>(
E)->getSubExpr();
16839 if (isa<ExplicitCastExpr>(
E)) {
16844 APSInt IgnoredVal(DestWidth, !DestSigned);
16849 if (FL->getValue().convertToInteger(IgnoredVal,
16850 llvm::APFloat::rmTowardZero,
16851 &Ignored) & APFloat::opInvalidOp)
16856 switch (cast<CastExpr>(
E)->getCastKind()) {
16857 case CK_LValueToRValue:
16858 case CK_AtomicToNonAtomic:
16859 case CK_NonAtomicToAtomic:
16861 case CK_IntegralToBoolean:
16862 case CK_IntegralCast:
16868 case Expr::BinaryConditionalOperatorClass: {
16871 if (CommonResult.Kind == IK_NotICE)
return CommonResult;
16873 if (FalseResult.Kind == IK_NotICE)
return FalseResult;
16874 if (CommonResult.Kind == IK_ICEIfUnevaluated)
return CommonResult;
16875 if (FalseResult.Kind == IK_ICEIfUnevaluated &&
16877 return FalseResult;
16879 case Expr::ConditionalOperatorClass: {
16887 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
16890 if (CondResult.Kind == IK_NotICE)
16896 if (TrueResult.Kind == IK_NotICE)
16898 if (FalseResult.Kind == IK_NotICE)
16899 return FalseResult;
16900 if (CondResult.Kind == IK_ICEIfUnevaluated)
16902 if (TrueResult.Kind == IK_ICE && FalseResult.Kind == IK_ICE)
16908 return FalseResult;
16911 case Expr::CXXDefaultArgExprClass:
16912 return CheckICE(cast<CXXDefaultArgExpr>(
E)->getExpr(), Ctx);
16913 case Expr::CXXDefaultInitExprClass:
16914 return CheckICE(cast<CXXDefaultInitExpr>(
E)->getExpr(), Ctx);
16915 case Expr::ChooseExprClass: {
16916 return CheckICE(cast<ChooseExpr>(
E)->getChosenSubExpr(), Ctx);
16918 case Expr::BuiltinBitCastExprClass: {
16919 if (!checkBitCastConstexprEligibility(
nullptr, Ctx, cast<CastExpr>(
E)))
16921 return CheckICE(cast<CastExpr>(
E)->getSubExpr(), Ctx);
16925 llvm_unreachable(
"Invalid StmtClass!");
16931 llvm::APSInt *
Value,
16942 if (!Result.isInt()) {
16953 assert(!isValueDependent() &&
16954 "Expression evaluator can't be called on a dependent expression.");
16956 ExprTimeTraceScope TimeScope(
this, Ctx,
"isIntegerConstantExpr");
16962 if (
D.
Kind != IK_ICE) {
16969std::optional<llvm::APSInt>
16971 if (isValueDependent()) {
16973 return std::nullopt;
16981 return std::nullopt;
16984 if (!isIntegerConstantExpr(Ctx,
Loc))
16985 return std::nullopt;
16993 EvalInfo Info(Ctx, Status, EvalInfo::EM_IgnoreSideEffects);
16994 Info.InConstantContext =
true;
16997 llvm_unreachable(
"ICE cannot be evaluated!");
17003 assert(!isValueDependent() &&
17004 "Expression evaluator can't be called on a dependent expression.");
17006 return CheckICE(
this, Ctx).Kind == IK_ICE;
17011 assert(!isValueDependent() &&
17012 "Expression evaluator can't be called on a dependent expression.");
17021 Status.Diag = &Diags;
17022 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
17029 Info.discardCleanups() && !Status.HasSideEffects;
17031 if (!Diags.empty()) {
17032 IsConstExpr =
false;
17033 if (
Loc) *
Loc = Diags[0].first;
17034 }
else if (!IsConstExpr) {
17036 if (
Loc) *
Loc = getExprLoc();
17039 return IsConstExpr;
17045 const Expr *This)
const {
17046 assert(!isValueDependent() &&
17047 "Expression evaluator can't be called on a dependent expression.");
17049 llvm::TimeTraceScope TimeScope(
"EvaluateWithSubstitution", [&] {
17051 llvm::raw_string_ostream OS(Name);
17058 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpressionUnevaluated);
17059 Info.InConstantContext =
true;
17062 const LValue *ThisPtr =
nullptr;
17065 auto *MD = dyn_cast<CXXMethodDecl>(Callee);
17066 assert(MD &&
"Don't provide `this` for non-methods.");
17067 assert(MD->isImplicitObjectMemberFunction() &&
17068 "Don't provide `this` for methods without an implicit object.");
17070 if (!This->isValueDependent() &&
17072 !Info.EvalStatus.HasSideEffects)
17073 ThisPtr = &ThisVal;
17077 Info.EvalStatus.HasSideEffects =
false;
17080 CallRef
Call = Info.CurrentCall->createCall(Callee);
17083 unsigned Idx = I - Args.begin();
17084 if (Idx >= Callee->getNumParams())
17086 const ParmVarDecl *PVD = Callee->getParamDecl(Idx);
17087 if ((*I)->isValueDependent() ||
17089 Info.EvalStatus.HasSideEffects) {
17091 if (
APValue *Slot = Info.getParamSlot(
Call, PVD))
17097 Info.EvalStatus.HasSideEffects =
false;
17102 Info.discardCleanups();
17103 Info.EvalStatus.HasSideEffects =
false;
17106 CallStackFrame Frame(Info, Callee->getLocation(), Callee, ThisPtr, This,
17109 FullExpressionRAII
Scope(Info);
17111 !Info.EvalStatus.HasSideEffects;
17123 llvm::TimeTraceScope TimeScope(
"isPotentialConstantExpr", [&] {
17125 llvm::raw_string_ostream OS(Name);
17132 Status.Diag = &Diags;
17134 EvalInfo Info(FD->
getASTContext(), Status, EvalInfo::EM_ConstantExpression);
17135 Info.InConstantContext =
true;
17136 Info.CheckingPotentialConstantExpression =
true;
17139 if (Info.EnableNewConstInterp) {
17140 Info.Ctx.getInterpContext().isPotentialConstantExpr(Info, FD);
17141 return Diags.empty();
17151 This.set({&VIE, Info.CurrentCall->Index});
17159 Info.setEvaluatingDecl(This.getLValueBase(), Scratch);
17165 &VIE, Args, CallRef(), FD->
getBody(), Info, Scratch,
17169 return Diags.empty();
17177 "Expression evaluator can't be called on a dependent expression.");
17180 Status.Diag = &Diags;
17183 EvalInfo::EM_ConstantExpressionUnevaluated);
17184 Info.InConstantContext =
true;
17185 Info.CheckingPotentialConstantExpression =
true;
17189 nullptr, CallRef());
17193 return Diags.empty();
17197 unsigned Type)
const {
17198 if (!getType()->isPointerType())
17202 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantFold);
17207 EvalInfo &Info, std::string *StringResult) {
17219 if (
const StringLiteral *S = dyn_cast_or_null<StringLiteral>(
17220 String.getLValueBase().dyn_cast<
const Expr *>())) {
17221 StringRef Str = S->getBytes();
17222 int64_t Off = String.Offset.getQuantity();
17223 if (Off >= 0 && (uint64_t)Off <= (uint64_t)Str.size() &&
17224 S->getCharByteWidth() == 1 &&
17226 Info.Ctx.hasSameUnqualifiedType(CharTy, Info.Ctx.CharTy)) {
17227 Str = Str.substr(Off);
17229 StringRef::size_type Pos = Str.find(0);
17230 if (Pos != StringRef::npos)
17231 Str = Str.substr(0, Pos);
17233 Result = Str.size();
17235 *StringResult = Str;
17243 for (uint64_t Strlen = 0; ; ++Strlen) {
17251 }
else if (StringResult)
17252 StringResult->push_back(Char.
getInt().getExtValue());
17260 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantFold);
17262 std::string StringResult;
17265 return StringResult;
17270 const Expr *SizeExpression,
17274 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
17275 Info.InConstantContext =
true;
17277 FullExpressionRAII
Scope(Info);
17282 uint64_t Size = SizeValue.getZExtValue();
17288 for (uint64_t I = 0; I < Size; ++I) {
17295 Result.push_back(
static_cast<char>(
C.getExtValue()));
17299 if (!
Scope.destroy())
17310 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantFold);
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)
enum clang::sema::@1655::IndirectLocalPathEntry::EntryKind Kind
static Decl::Kind getKind(const Decl *D)
GCCTypeClass
Values returned by __builtin_classify_type, chosen to match the values produced by GCC's builtin.
static bool isRead(AccessKinds AK)
static bool EvaluateBuiltinStrLen(const Expr *E, uint64_t &Result, EvalInfo &Info, std::string *StringResult=nullptr)
static bool isValidIndeterminateAccess(AccessKinds AK)
Is this kind of axcess 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 CharUnits GetAlignOfType(EvalInfo &Info, QualType T, UnaryExprOrTypeTrait ExprKind)
static const CXXMethodDecl * HandleVirtualDispatch(EvalInfo &Info, const Expr *E, LValue &This, const CXXMethodDecl *Found, llvm::SmallVectorImpl< QualType > &CovariantAdjustmentPath)
Perform virtual dispatch.
static bool EvaluateVarDecl(EvalInfo &Info, const VarDecl *VD)
static bool CheckEvaluationResult(CheckEvaluationResultKind CERK, EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value, ConstantExprKind Kind, const FieldDecl *SubobjectDecl, CheckedTemporaries &CheckedTemps)
static bool HandleLValueComplexElement(EvalInfo &Info, const Expr *E, LValue &LVal, QualType EltTy, bool Imag)
Update an lvalue to refer to a component of a complex number.
static bool HandleSizeof(EvalInfo &Info, SourceLocation Loc, QualType Type, CharUnits &Size, SizeOfType SOT=SizeOfType::SizeOf)
Get the size of the given type in char units.
static bool FastEvaluateAsRValue(const Expr *Exp, Expr::EvalResult &Result, const ASTContext &Ctx, bool &IsConst)
static bool HandleConstructorCall(const Expr *E, const LValue &This, CallRef Call, const CXXConstructorDecl *Definition, EvalInfo &Info, APValue &Result)
Evaluate a constructor call.
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.
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.
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 bool IsLiteralLValue(const LValue &Value)
static bool HandleFunctionCall(SourceLocation CallLoc, const FunctionDecl *Callee, const LValue *This, 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 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.
bool HandleOperatorDeleteCall(EvalInfo &Info, const CallExpr *E)
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 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 CharUnits GetAlignOfExpr(EvalInfo &Info, const Expr *E, UnaryExprOrTypeTrait ExprKind)
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.
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 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 bool EvaluateArgs(ArrayRef< const Expr * > Args, CallRef Call, EvalInfo &Info, const FunctionDecl *Callee, bool RightToLeft=false)
Evaluate the arguments to a function call.
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)
static bool IsNoOpCall(const CallExpr *E)
Should this call expression be treated as a no-op?
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 getBytesReturnedByAllocSizeCall(const ASTContext &Ctx, const CallExpr *Call, llvm::APInt &Result)
Attempts to compute the number of bytes available at the pointer returned by a function with the allo...
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 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 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 bool EvaluateCPlusPlus11IntegralConstantExpr(const ASTContext &Ctx, const Expr *E, llvm::APSInt *Value, SourceLocation *Loc)
Evaluate an expression as a C++11 integral constant expression.
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.
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.
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.
static bool EvaluateCallArg(const ParmVarDecl *PVD, const Expr *Arg, CallRef Call, EvalInfo &Info, bool NonNull=false)
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 EvaluateAtomic(const Expr *E, const LValue *This, APValue &Result, EvalInfo &Info)
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 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 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.
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 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 bool EvaluateDecl(EvalInfo &Info, const Decl *D)
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 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 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 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.
static QualType getPointeeType(const MemRegion *R)
Defines the clang::TypeLoc interface and its subclasses.
__DEVICE__ long long abs(long long __n)
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.
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
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()
unsigned getIntWidth(QualType T) const
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
QualType getRecordType(const RecordDecl *Decl) const
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,...
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified 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<=>,...
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
const clang::PrintingPolicy & getPrintingPolicy() const
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
const TargetInfo & getTargetInfo() const
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.
AddrLabelExpr - The GNU address of label extension, representing &&label.
LabelDecl * getLabel() const
Represents the index of the current element of an array being initialized by an ArrayInitLoopExpr.
Represents a loop initializing the elements of an array.
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
An Embarcadero array type trait, as used in the implementation of __array_rank and __array_extent.
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; ...
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".
bool isComparisonOp() const
static Opcode getOpForCompoundAssignment(Opcode Opc)
A binding in a decomposition declaration.
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Represents a C++2a __builtin_bit_cast(T, v) expression.
This class is used for builtin types like 'int'.
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
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.
Represents binding an expression to a temporary.
A boolean literal, per ([C++ lex.bool] Boolean literals).
Represents a call to a C++ constructor.
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.
A default argument (C++ [dcl.fct.default]).
A use of a default initializer in a constructor or in aggregate initialization.
Represents a delete expression for memory deallocation and destructor calls, e.g.
Represents a C++ destructor within a class.
A C++ dynamic_cast expression (C++ [expr.dynamic.cast]).
CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for statement, represented as 'for (ra...
Represents a call to an inherited base class constructor from an inheriting constructor.
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...
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
QualType getThisType() const
Return the type of the this pointer.
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 ...
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).
The null pointer literal (C++11 [lex.nullptr])
Represents a list-initialization with parenthesis.
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)
capture_const_iterator captures_end() const
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()
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.
capture_const_iterator captures_begin() const
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.
A C++ reinterpret_cast expression (C++ [expr.reinterpret.cast]).
A rewritten comparison expression that was originally written using operator syntax.
An expression "T()" which creates an rvalue of a non-class type T.
Implicit construction of a std::initializer_list<T> object from an array temporary within list-initia...
Represents the this expression in C++.
A C++ typeid expression (C++ [expr.typeid]), which gets the type_info that corresponds to the supplie...
A Microsoft C++ __uuidof expression, which gets the _GUID that corresponds to the supplied type or ex...
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
unsigned getBuiltinCallee() const
getBuiltinCallee - If this is a call to a builtin, return the builtin ID of the callee.
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
CaseStmt - Represent a case statement.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
const CXXBaseSpecifier *const * path_const_iterator
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.
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
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].
CompoundStmt - This represents a group of statements like { stmt stmt }.
Stmt *const * const_body_iterator
body_iterator body_begin()
Represents the specialization of a concept - evaluates to a prvalue of type bool.
ConditionalOperator - The ?: ternary operator.
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 ?: operator.
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
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.
ConstantExpr - An expression that occurs in a constant context and optionally the result of evaluatin...
ConvertVectorExpr - Clang builtin function __builtin_convertvector This AST node provides support for...
Represents the current source location and context used to determine the value of the source location...
specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext,...
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 isDependentContext() const
Determines whether this context is dependent on a template parameter.
A reference to a declared variable, function, enum, etc.
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
Kind
Lists the kind of concrete classes of Decl.
bool isInvalidDecl() const
SourceLocation getLocation() const
DeclContext * getDeclContext()
AccessSpecifier getAccess() const
OverloadedOperatorKind getCXXOverloadedOperator() const
If this name is the name of an overloadable operator in C++ (e.g., operator+), retrieve the kind of o...
A decomposition declaration.
Designator - A designator in a C99 designated initializer.
DoStmt - This represents a 'do/while' stmt.
Symbolic representation of a dynamic allocation.
static unsigned getMaxIndex()
Represents a reference to #emded data.
An instance of this object exists for each enum constant that is defined.
unsigned getNumNegativeBits() const
Returns the width in bits required to store all the negative enumerators of this enum.
bool isFixed() const
Returns true if this is an Objective-C, C++11, or Microsoft-style enumeration with a fixed underlying...
QualType getIntegerType() const
Return the integer type this enum decl corresponds to.
void getValueRange(llvm::APInt &Max, llvm::APInt &Min) const
Calculates the [Min,Max) values the enum can store based on the NumPositiveBits and NumNegativeBits.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
EnumDecl * getDecl() const
ExplicitCastExpr - An explicit cast written in the source code.
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
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...
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 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.
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...
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
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, e.g.
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...
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 isIntegerConstantExpr(const ASTContext &Ctx, SourceLocation *Loc=nullptr) const
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...
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx, SourceLocation *Loc=nullptr) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
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 isCXX11ConstantExpr(const ASTContext &Ctx, APValue *Result=nullptr, SourceLocation *Loc=nullptr) const
isCXX11ConstantExpr - Return true if this expression is a constant expression in C++11.
An expression trait intrinsic.
ExtVectorElementExpr - This represents access to specific elements of a vector, and may occur on the ...
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 getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
unsigned getBitWidthValue(const ASTContext &Ctx) const
Computes the bit width of this field, if this is a bit field.
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.
ForStmt - This represents a 'for (init;cond;inc)' stmt.
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 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 isReservedGlobalPlacementOperator() const
Determines whether this operator new or delete is one of the reserved global placement operators: voi...
bool isReplaceableGlobalAllocationFunction(std::optional< unsigned > *AlignmentParam=nullptr, bool *IsNothrow=nullptr) const
Determines whether this function is one of the replaceable global allocation functions: void *operato...
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.
Declaration of a template function.
FunctionDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
GNUNullExpr - Implements the GNU __null extension, which is a name for a null pointer constant that h...
Represents a C11 generic selection.
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.
ImaginaryLiteral - We support imaginary integer and floating point literals, like "1....
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.
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
StrictFlexArraysLevelKind
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.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
A pointer to member type per C++ 8.3.3 - Pointers to members.
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
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...
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
ObjCBoxedExpr - used for generalized expression boxing.
ObjCEncodeExpr, used for @encode in Objective-C.
ObjCStringLiteral, used for Objective-C string literals i.e.
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type,...
Expr * getIndexExpr(unsigned Idx)
const OffsetOfNode & getComponent(unsigned Idx) const
TypeSourceInfo * getTypeSourceInfo() const
unsigned getNumComponents() const
Helper class for OffsetOfExpr.
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.
A partial diagnostic which we might know in advance that we are not going to emit.
ParenExpr - This represents a parenthesized expression, e.g.
Represents a parameter to a function.
unsigned getFunctionScopeIndex() const
Returns the index of this parameter in its prototype or method scope.
PointerType - C99 6.7.5.1 - Pointer Declarators.
[C99 6.4.2.2] - A predefined identifier such as func.
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
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.
bool isConstant(const ASTContext &Ctx) const
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()
QualType withCVRQualifiers(unsigned CVR) const
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.
bool hasFlexibleArrayMember() const
field_iterator field_end() const
field_range fields() const
bool isAnonymousStructOrUnion() const
Whether this is an anonymous struct or union.
field_iterator field_begin() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
RecordDecl * getDecl() const
Base for LValueReferenceType and RValueReferenceType.
C++2a [expr.prim.req]: A requires-expression provides a concise way to express requirements on templa...
Scope - A scope is a transient data structure that is used while parsing the program.
ShuffleVectorExpr - clang-specific builtin-in function __builtin_shufflevector.
Represents an expression that computes the length of a parameter pack.
Represents a function call to one of __builtin_LINE(), __builtin_COLUMN(), __builtin_FUNCTION(),...
Encodes a location in the source.
A trivial tuple used to represent a source range.
SourceLocation getBegin() const
StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
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.
uint32_t getCodeUnit(size_t i) const
static StringLiteral * Create(const ASTContext &Ctx, StringRef Str, StringLiteralKind Kind, bool Pascal, QualType Ty, const SourceLocation *Loc, unsigned NumConcatenated)
This is the "fully general" constructor that allows representation of strings formed from multiple co...
Represents a reference to a non-type template parameter that has been substituted with a template arg...
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.
virtual bool isNan2008() const
Returns true if NaN encoding is IEEE 754-2008.
A template argument list.
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.
A template parameter object.
Symbolic representation of typeid(T) for some type T.
QualType getType() const
Return the type wrapped by this type source info.
A type trait used in the implementation of various C++11 and Library TR1 trait templates.
The base class of the type hierarchy.
bool isStructureType() const
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isBooleanType() const
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
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.
bool isConstantArrayType() const
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
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...
bool isAnyComplexType() const
bool isFixedPointType() const
Return true if this is a fixed point type according to ISO/IEC JTC1 SC22 WG14 N1169.
const RecordType * getAsStructureType() const
const Type * getBaseElementTypeUnsafe() const
Get the base element type of this type, potentially discarding type qualifiers.
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 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...
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.
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
QualType getTypeOfArgument() const
Gets the argument type, or the type of the argument expression, whichever is appropriate.
UnaryExprOrTypeTrait getKind() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Expr * getSubExpr() const
static bool isIncrementOp(Opcode Op)
An artificial decl, representing a global anonymous constant value which is uniquified by value withi...
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...
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.
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.
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)
uint32_t Literal
Literals are represented as positive integers.
bool NE(InterpState &S, CodePtr OpPC)
bool This(InterpState &S, CodePtr OpPC)
bool Zero(InterpState &S, CodePtr OpPC)
bool Alloc(InterpState &S, CodePtr OpPC, const Descriptor *Desc)
bool ReturnValue(const InterpState &S, const T &V, APValue &R)
Convert a value to an APValue.
The JSON file list parser is used to communicate input to InstallAPI.
@ NonNull
Values of this type can never be null.
bool operator==(const CallGraphNode::CallRecord &LHS, const CallGraphNode::CallRecord &RHS)
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)
AccessKinds
Kinds of access we can perform on an object, for diagnostics.
@ AK_ReadObjectRepresentation
ActionResult< Expr * > ExprResult
CastKind
CastKind - The kind of operation required for a conversion.
llvm::hash_code hash_value(const CustomizableOptional< T > &O)
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
const FunctionProtoType * T
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs.
@ Success
Template argument deduction was successful.
@ None
The alignment was not explicit in code.
@ Class
The "class" keyword introduces the elaborated-type-specifier.
@ Other
Other implicit parameter.
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.
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
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 HasUndefinedBehavior
Whether the evaluation hit undefined behavior.
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)