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 = FD->getType();
228 MostDerivedLength = I + 1;
236 return MostDerivedLength;
240 struct SubobjectDesignator {
244 LLVM_PREFERRED_TYPE(
bool)
245 unsigned Invalid : 1;
248 LLVM_PREFERRED_TYPE(
bool)
249 unsigned IsOnePastTheEnd : 1;
252 LLVM_PREFERRED_TYPE(
bool)
253 unsigned FirstEntryIsAnUnsizedArray : 1;
256 LLVM_PREFERRED_TYPE(
bool)
257 unsigned MostDerivedIsArrayElement : 1;
261 unsigned MostDerivedPathLength : 28;
270 uint64_t MostDerivedArraySize;
280 SubobjectDesignator() : Invalid(
true) {}
283 : Invalid(
false), IsOnePastTheEnd(
false),
284 FirstEntryIsAnUnsizedArray(
false), MostDerivedIsArrayElement(
false),
285 MostDerivedPathLength(0), MostDerivedArraySize(0),
286 MostDerivedType(
T) {}
289 : Invalid(!
V.isLValue() || !
V.hasLValuePath()), IsOnePastTheEnd(
false),
290 FirstEntryIsAnUnsizedArray(
false), MostDerivedIsArrayElement(
false),
291 MostDerivedPathLength(0), MostDerivedArraySize(0) {
292 assert(
V.isLValue() &&
"Non-LValue used to make an LValue designator?");
294 IsOnePastTheEnd =
V.isLValueOnePastTheEnd();
296 Entries.insert(Entries.end(), VEntries.begin(), VEntries.end());
297 if (
V.getLValueBase()) {
298 bool IsArray =
false;
299 bool FirstIsUnsizedArray =
false;
300 MostDerivedPathLength = findMostDerivedSubobject(
301 Ctx,
V.getLValueBase(),
V.getLValuePath(), MostDerivedArraySize,
302 MostDerivedType, IsArray, FirstIsUnsizedArray);
303 MostDerivedIsArrayElement = IsArray;
304 FirstEntryIsAnUnsizedArray = FirstIsUnsizedArray;
310 unsigned NewLength) {
314 assert(
Base &&
"cannot truncate path for null pointer");
315 assert(NewLength <= Entries.size() &&
"not a truncation");
317 if (NewLength == Entries.size())
319 Entries.resize(NewLength);
321 bool IsArray =
false;
322 bool FirstIsUnsizedArray =
false;
323 MostDerivedPathLength = findMostDerivedSubobject(
324 Ctx,
Base, Entries, MostDerivedArraySize, MostDerivedType, IsArray,
325 FirstIsUnsizedArray);
326 MostDerivedIsArrayElement = IsArray;
327 FirstEntryIsAnUnsizedArray = FirstIsUnsizedArray;
337 bool isMostDerivedAnUnsizedArray()
const {
338 assert(!Invalid &&
"Calling this makes no sense on invalid designators");
339 return Entries.size() == 1 && FirstEntryIsAnUnsizedArray;
344 uint64_t getMostDerivedArraySize()
const {
345 assert(!isMostDerivedAnUnsizedArray() &&
"Unsized array has no size");
346 return MostDerivedArraySize;
350 bool isOnePastTheEnd()
const {
354 if (!isMostDerivedAnUnsizedArray() && MostDerivedIsArrayElement &&
355 Entries[MostDerivedPathLength - 1].getAsArrayIndex() ==
356 MostDerivedArraySize)
364 std::pair<uint64_t, uint64_t> validIndexAdjustments() {
365 if (Invalid || isMostDerivedAnUnsizedArray())
371 bool IsArray = MostDerivedPathLength == Entries.size() &&
372 MostDerivedIsArrayElement;
373 uint64_t ArrayIndex = IsArray ? Entries.back().getAsArrayIndex()
374 : (uint64_t)IsOnePastTheEnd;
376 IsArray ? getMostDerivedArraySize() : (uint64_t)1;
377 return {ArrayIndex, ArraySize - ArrayIndex};
381 bool isValidSubobject()
const {
384 return !isOnePastTheEnd();
392 assert(!Invalid &&
"invalid designator has no subobject type");
393 return MostDerivedPathLength == Entries.size()
404 MostDerivedIsArrayElement =
true;
406 MostDerivedPathLength = Entries.size();
410 void addUnsizedArrayUnchecked(
QualType ElemTy) {
413 MostDerivedType = ElemTy;
414 MostDerivedIsArrayElement =
true;
418 MostDerivedArraySize = AssumedSizeForUnsizedArray;
419 MostDerivedPathLength = Entries.size();
423 void addDeclUnchecked(
const Decl *
D,
bool Virtual =
false) {
427 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(
D)) {
428 MostDerivedType = FD->getType();
429 MostDerivedIsArrayElement =
false;
430 MostDerivedArraySize = 0;
431 MostDerivedPathLength = Entries.size();
435 void addComplexUnchecked(
QualType EltTy,
bool Imag) {
440 MostDerivedType = EltTy;
441 MostDerivedIsArrayElement =
true;
442 MostDerivedArraySize = 2;
443 MostDerivedPathLength = Entries.size();
445 void diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info,
const Expr *
E);
446 void diagnosePointerArithmetic(EvalInfo &Info,
const Expr *
E,
449 void adjustIndex(EvalInfo &Info,
const Expr *
E,
APSInt N) {
450 if (Invalid || !N)
return;
451 uint64_t TruncatedN = N.extOrTrunc(64).getZExtValue();
452 if (isMostDerivedAnUnsizedArray()) {
453 diagnoseUnsizedArrayPointerArithmetic(Info,
E);
458 Entries.back().getAsArrayIndex() + TruncatedN);
465 bool IsArray = MostDerivedPathLength == Entries.size() &&
466 MostDerivedIsArrayElement;
467 uint64_t ArrayIndex = IsArray ? Entries.back().getAsArrayIndex()
468 : (uint64_t)IsOnePastTheEnd;
470 IsArray ? getMostDerivedArraySize() : (uint64_t)1;
472 if (N < -(int64_t)ArrayIndex || N > ArraySize - ArrayIndex) {
475 N = N.extend(std::max<unsigned>(N.getBitWidth() + 1, 65));
476 (llvm::APInt&)N += ArrayIndex;
477 assert(N.ugt(ArraySize) &&
"bounds check failed for in-bounds index");
478 diagnosePointerArithmetic(Info,
E, N);
483 ArrayIndex += TruncatedN;
484 assert(ArrayIndex <= ArraySize &&
485 "bounds check succeeded for out-of-bounds index");
490 IsOnePastTheEnd = (ArrayIndex != 0);
495 enum class ScopeKind {
503 CallRef() : OrigCallee(), CallIndex(0), Version() {}
504 CallRef(
const FunctionDecl *Callee,
unsigned CallIndex,
unsigned Version)
505 : OrigCallee(Callee), CallIndex(CallIndex), Version(Version) {}
507 explicit operator bool()
const {
return OrigCallee; }
533 CallStackFrame *Caller;
555 typedef std::pair<const void *, unsigned> MapKeyTy;
556 typedef std::map<MapKeyTy, APValue>
MapTy;
568 unsigned CurTempVersion = TempVersionStack.back();
570 unsigned getTempVersion()
const {
return TempVersionStack.back(); }
572 void pushTempVersion() {
573 TempVersionStack.push_back(++CurTempVersion);
576 void popTempVersion() {
577 TempVersionStack.pop_back();
581 return {Callee, Index, ++CurTempVersion};
592 llvm::DenseMap<const ValueDecl *, FieldDecl *> LambdaCaptureFields;
593 FieldDecl *LambdaThisCaptureField =
nullptr;
595 CallStackFrame(EvalInfo &Info,
SourceRange CallRange,
601 APValue *getTemporary(
const void *Key,
unsigned Version) {
602 MapKeyTy KV(Key, Version);
603 auto LB = Temporaries.lower_bound(KV);
604 if (LB != Temporaries.end() && LB->first == KV)
610 APValue *getCurrentTemporary(
const void *Key) {
611 auto UB = Temporaries.upper_bound(MapKeyTy(Key,
UINT_MAX));
612 if (UB != Temporaries.begin() && std::prev(UB)->first.first == Key)
613 return &std::prev(UB)->second;
618 unsigned getCurrentTemporaryVersion(
const void *Key)
const {
619 auto UB = Temporaries.upper_bound(MapKeyTy(Key,
UINT_MAX));
620 if (UB != Temporaries.begin() && std::prev(UB)->first.first == Key)
621 return std::prev(UB)->first.second;
629 template<
typename KeyT>
631 ScopeKind
Scope, LValue &LV);
636 void describe(llvm::raw_ostream &OS)
const override;
638 Frame *getCaller()
const override {
return Caller; }
639 SourceRange getCallRange()
const override {
return CallRange; }
640 const FunctionDecl *getCallee()
const override {
return Callee; }
642 bool isStdFunction()
const {
643 for (
const DeclContext *DC = Callee; DC; DC = DC->getParent())
644 if (DC->isStdNamespace())
651 bool CanEvalMSConstexpr =
false;
659 class ThisOverrideRAII {
661 ThisOverrideRAII(CallStackFrame &Frame,
const LValue *NewThis,
bool Enable)
662 : Frame(Frame), OldThis(Frame.This) {
664 Frame.This = NewThis;
666 ~ThisOverrideRAII() {
667 Frame.This = OldThis;
670 CallStackFrame &Frame;
671 const LValue *OldThis;
676 class ExprTimeTraceScope {
678 ExprTimeTraceScope(
const Expr *
E,
const ASTContext &Ctx, StringRef Name)
679 : TimeScope(Name, [
E, &Ctx] {
684 llvm::TimeTraceScope TimeScope;
689 struct MSConstexprContextRAII {
690 CallStackFrame &Frame;
692 explicit MSConstexprContextRAII(CallStackFrame &Frame,
bool Value)
693 : Frame(Frame), OldValue(Frame.CanEvalMSConstexpr) {
694 Frame.CanEvalMSConstexpr =
Value;
697 ~MSConstexprContextRAII() { Frame.CanEvalMSConstexpr = OldValue; }
702 const LValue &This,
QualType ThisType);
710 llvm::PointerIntPair<APValue*, 2, ScopeKind>
Value;
721 bool isDestroyedAtEndOf(ScopeKind K)
const {
722 return (
int)
Value.getInt() >= (
int)K;
724 bool endLifetime(EvalInfo &Info,
bool RunDestructors) {
725 if (RunDestructors) {
728 Loc = VD->getLocation();
737 bool hasSideEffect() {
738 return T.isDestructedType();
743 struct ObjectUnderConstruction {
746 friend bool operator==(
const ObjectUnderConstruction &LHS,
747 const ObjectUnderConstruction &RHS) {
748 return LHS.Base == RHS.Base && LHS.Path == RHS.Path;
750 friend llvm::hash_code
hash_value(
const ObjectUnderConstruction &Obj) {
751 return llvm::hash_combine(Obj.Base, Obj.Path);
754 enum class ConstructionPhase {
765template<>
struct DenseMapInfo<ObjectUnderConstruction> {
766 using Base = DenseMapInfo<APValue::LValueBase>;
768 return {Base::getEmptyKey(), {}}; }
770 return {Base::getTombstoneKey(), {}};
775 static bool isEqual(
const ObjectUnderConstruction &LHS,
776 const ObjectUnderConstruction &RHS) {
790 const Expr *AllocExpr =
nullptr;
801 if (
auto *NE = dyn_cast<CXXNewExpr>(AllocExpr))
802 return NE->isArray() ? ArrayNew : New;
803 assert(isa<CallExpr>(AllocExpr));
808 struct DynAllocOrder {
836 CallStackFrame *CurrentCall;
839 unsigned CallStackDepth;
842 unsigned NextCallIndex;
851 bool EnableNewConstInterp;
855 CallStackFrame BottomFrame;
865 enum class EvaluatingDeclKind {
872 EvaluatingDeclKind IsEvaluatingDecl = EvaluatingDeclKind::None;
879 llvm::DenseMap<ObjectUnderConstruction, ConstructionPhase>
880 ObjectsUnderConstruction;
885 std::map<DynamicAllocLValue, DynAlloc, DynAllocOrder> HeapAllocs;
888 unsigned NumHeapAllocs = 0;
890 struct EvaluatingConstructorRAII {
892 ObjectUnderConstruction
Object;
894 EvaluatingConstructorRAII(EvalInfo &EI, ObjectUnderConstruction Object,
898 EI.ObjectsUnderConstruction
899 .insert({
Object, HasBases ? ConstructionPhase::Bases
900 : ConstructionPhase::AfterBases})
903 void finishedConstructingBases() {
904 EI.ObjectsUnderConstruction[
Object] = ConstructionPhase::AfterBases;
906 void finishedConstructingFields() {
907 EI.ObjectsUnderConstruction[
Object] = ConstructionPhase::AfterFields;
909 ~EvaluatingConstructorRAII() {
910 if (DidInsert) EI.ObjectsUnderConstruction.erase(Object);
914 struct EvaluatingDestructorRAII {
916 ObjectUnderConstruction
Object;
918 EvaluatingDestructorRAII(EvalInfo &EI, ObjectUnderConstruction Object)
920 DidInsert = EI.ObjectsUnderConstruction
921 .insert({
Object, ConstructionPhase::Destroying})
924 void startedDestroyingBases() {
925 EI.ObjectsUnderConstruction[
Object] =
926 ConstructionPhase::DestroyingBases;
928 ~EvaluatingDestructorRAII() {
930 EI.ObjectsUnderConstruction.erase(Object);
937 return ObjectsUnderConstruction.lookup({
Base,
Path});
942 unsigned SpeculativeEvaluationDepth = 0;
950 bool HasActiveDiagnostic;
954 bool HasFoldFailureDiagnostic;
959 bool CheckingPotentialConstantExpression =
false;
967 bool CheckingForUndefinedBehavior =
false;
969 enum EvaluationMode {
972 EM_ConstantExpression,
979 EM_ConstantExpressionUnevaluated,
987 EM_IgnoreSideEffects,
992 bool checkingPotentialConstantExpression()
const override {
993 return CheckingPotentialConstantExpression;
999 bool checkingForUndefinedBehavior()
const override {
1000 return CheckingForUndefinedBehavior;
1004 : Ctx(const_cast<
ASTContext &>(
C)), EvalStatus(S), CurrentCall(nullptr),
1005 CallStackDepth(0), NextCallIndex(1),
1006 StepsLeft(
C.getLangOpts().ConstexprStepLimit),
1007 EnableNewConstInterp(
C.getLangOpts().EnableNewConstInterp),
1010 nullptr, CallRef()),
1011 EvaluatingDecl((const
ValueDecl *)nullptr),
1012 EvaluatingDeclValue(nullptr), HasActiveDiagnostic(
false),
1013 HasFoldFailureDiagnostic(
false), EvalMode(Mode) {}
1019 ASTContext &getCtx()
const override {
return Ctx; }
1022 EvaluatingDeclKind EDK = EvaluatingDeclKind::Ctor) {
1023 EvaluatingDecl =
Base;
1024 IsEvaluatingDecl = EDK;
1025 EvaluatingDeclValue = &
Value;
1031 if (checkingPotentialConstantExpression() && CallStackDepth > 1)
1033 if (NextCallIndex == 0) {
1035 FFDiag(
Loc, diag::note_constexpr_call_limit_exceeded);
1038 if (CallStackDepth <= getLangOpts().ConstexprCallDepth)
1040 FFDiag(
Loc, diag::note_constexpr_depth_limit_exceeded)
1041 << getLangOpts().ConstexprCallDepth;
1046 uint64_t ElemCount,
bool Diag) {
1052 ElemCount >
uint64_t(std::numeric_limits<unsigned>::max())) {
1054 FFDiag(
Loc, diag::note_constexpr_new_too_large) << ElemCount;
1064 if (ElemCount > Limit) {
1066 FFDiag(
Loc, diag::note_constexpr_new_exceeds_limits)
1067 << ElemCount << Limit;
1073 std::pair<CallStackFrame *, unsigned>
1074 getCallFrameAndDepth(
unsigned CallIndex) {
1075 assert(CallIndex &&
"no call index in getCallFrameAndDepth");
1078 unsigned Depth = CallStackDepth;
1079 CallStackFrame *Frame = CurrentCall;
1080 while (Frame->Index > CallIndex) {
1081 Frame = Frame->Caller;
1084 if (Frame->Index == CallIndex)
1085 return {Frame, Depth};
1086 return {
nullptr, 0};
1089 bool nextStep(
const Stmt *S) {
1091 FFDiag(S->getBeginLoc(), diag::note_constexpr_step_limit_exceeded);
1101 std::optional<DynAlloc *> Result;
1102 auto It = HeapAllocs.find(DA);
1103 if (It != HeapAllocs.end())
1104 Result = &It->second;
1110 CallStackFrame *Frame = getCallFrameAndDepth(
Call.CallIndex).first;
1111 return Frame ? Frame->getTemporary(
Call.getOrigParam(PVD),
Call.Version)
1116 struct StdAllocatorCaller {
1117 unsigned FrameIndex;
1119 explicit operator bool()
const {
return FrameIndex != 0; };
1122 StdAllocatorCaller getStdAllocatorCaller(StringRef FnName)
const {
1123 for (
const CallStackFrame *
Call = CurrentCall;
Call != &BottomFrame;
1125 const auto *MD = dyn_cast_or_null<CXXMethodDecl>(
Call->Callee);
1129 if (!FnII || !FnII->
isStr(FnName))
1133 dyn_cast<ClassTemplateSpecializationDecl>(MD->getParent());
1139 if (CTSD->isInStdNamespace() && ClassII &&
1140 ClassII->
isStr(
"allocator") && TAL.
size() >= 1 &&
1142 return {
Call->Index, TAL[0].getAsType()};
1148 void performLifetimeExtension() {
1150 llvm::erase_if(CleanupStack, [](Cleanup &
C) {
1151 return !
C.isDestroyedAtEndOf(ScopeKind::FullExpression);
1158 bool discardCleanups() {
1159 for (Cleanup &
C : CleanupStack) {
1160 if (
C.hasSideEffect() && !noteSideEffect()) {
1161 CleanupStack.clear();
1165 CleanupStack.clear();
1170 interp::Frame *getCurrentFrame()
override {
return CurrentCall; }
1171 const interp::Frame *getBottomFrame()
const override {
return &BottomFrame; }
1173 bool hasActiveDiagnostic()
override {
return HasActiveDiagnostic; }
1174 void setActiveDiagnostic(
bool Flag)
override { HasActiveDiagnostic = Flag; }
1176 void setFoldFailureDiagnostic(
bool Flag)
override {
1177 HasFoldFailureDiagnostic = Flag;
1188 bool hasPriorDiagnostic()
override {
1189 if (!EvalStatus.
Diag->empty()) {
1191 case EM_ConstantFold:
1192 case EM_IgnoreSideEffects:
1193 if (!HasFoldFailureDiagnostic)
1197 case EM_ConstantExpression:
1198 case EM_ConstantExpressionUnevaluated:
1199 setActiveDiagnostic(
false);
1206 unsigned getCallStackDepth()
override {
return CallStackDepth; }
1211 bool keepEvaluatingAfterSideEffect() {
1213 case EM_IgnoreSideEffects:
1216 case EM_ConstantExpression:
1217 case EM_ConstantExpressionUnevaluated:
1218 case EM_ConstantFold:
1221 return checkingPotentialConstantExpression() ||
1222 checkingForUndefinedBehavior();
1224 llvm_unreachable(
"Missed EvalMode case");
1229 bool noteSideEffect() {
1231 return keepEvaluatingAfterSideEffect();
1235 bool keepEvaluatingAfterUndefinedBehavior() {
1237 case EM_IgnoreSideEffects:
1238 case EM_ConstantFold:
1241 case EM_ConstantExpression:
1242 case EM_ConstantExpressionUnevaluated:
1243 return checkingForUndefinedBehavior();
1245 llvm_unreachable(
"Missed EvalMode case");
1251 bool noteUndefinedBehavior()
override {
1253 return keepEvaluatingAfterUndefinedBehavior();
1258 bool keepEvaluatingAfterFailure()
const override {
1263 case EM_ConstantExpression:
1264 case EM_ConstantExpressionUnevaluated:
1265 case EM_ConstantFold:
1266 case EM_IgnoreSideEffects:
1267 return checkingPotentialConstantExpression() ||
1268 checkingForUndefinedBehavior();
1270 llvm_unreachable(
"Missed EvalMode case");
1283 [[nodiscard]]
bool noteFailure() {
1291 bool KeepGoing = keepEvaluatingAfterFailure();
1296 class ArrayInitLoopIndex {
1301 ArrayInitLoopIndex(EvalInfo &Info)
1302 : Info(Info), OuterIndex(Info.ArrayInitIndex) {
1303 Info.ArrayInitIndex = 0;
1305 ~ArrayInitLoopIndex() { Info.ArrayInitIndex = OuterIndex; }
1307 operator uint64_t&() {
return Info.ArrayInitIndex; }
1312 struct FoldConstant {
1315 bool HadNoPriorDiags;
1316 EvalInfo::EvaluationMode OldMode;
1318 explicit FoldConstant(EvalInfo &Info,
bool Enabled)
1321 HadNoPriorDiags(Info.EvalStatus.
Diag &&
1322 Info.EvalStatus.
Diag->empty() &&
1323 !Info.EvalStatus.HasSideEffects),
1324 OldMode(Info.EvalMode) {
1326 Info.EvalMode = EvalInfo::EM_ConstantFold;
1328 void keepDiagnostics() { Enabled =
false; }
1330 if (Enabled && HadNoPriorDiags && !Info.EvalStatus.Diag->empty() &&
1331 !Info.EvalStatus.HasSideEffects)
1332 Info.EvalStatus.Diag->clear();
1333 Info.EvalMode = OldMode;
1339 struct IgnoreSideEffectsRAII {
1341 EvalInfo::EvaluationMode OldMode;
1342 explicit IgnoreSideEffectsRAII(EvalInfo &Info)
1343 : Info(Info), OldMode(Info.EvalMode) {
1344 Info.EvalMode = EvalInfo::EM_IgnoreSideEffects;
1347 ~IgnoreSideEffectsRAII() { Info.EvalMode = OldMode; }
1352 class SpeculativeEvaluationRAII {
1353 EvalInfo *Info =
nullptr;
1355 unsigned OldSpeculativeEvaluationDepth = 0;
1357 void moveFromAndCancel(SpeculativeEvaluationRAII &&
Other) {
1359 OldStatus =
Other.OldStatus;
1360 OldSpeculativeEvaluationDepth =
Other.OldSpeculativeEvaluationDepth;
1361 Other.Info =
nullptr;
1364 void maybeRestoreState() {
1368 Info->EvalStatus = OldStatus;
1369 Info->SpeculativeEvaluationDepth = OldSpeculativeEvaluationDepth;
1373 SpeculativeEvaluationRAII() =
default;
1375 SpeculativeEvaluationRAII(
1377 : Info(&Info), OldStatus(Info.EvalStatus),
1378 OldSpeculativeEvaluationDepth(Info.SpeculativeEvaluationDepth) {
1379 Info.EvalStatus.Diag = NewDiag;
1380 Info.SpeculativeEvaluationDepth = Info.CallStackDepth + 1;
1383 SpeculativeEvaluationRAII(
const SpeculativeEvaluationRAII &
Other) =
delete;
1384 SpeculativeEvaluationRAII(SpeculativeEvaluationRAII &&
Other) {
1385 moveFromAndCancel(std::move(
Other));
1388 SpeculativeEvaluationRAII &operator=(SpeculativeEvaluationRAII &&
Other) {
1389 maybeRestoreState();
1390 moveFromAndCancel(std::move(
Other));
1394 ~SpeculativeEvaluationRAII() { maybeRestoreState(); }
1399 template<ScopeKind Kind>
1402 unsigned OldStackSize;
1404 ScopeRAII(EvalInfo &Info)
1405 : Info(Info), OldStackSize(Info.CleanupStack.size()) {
1408 Info.CurrentCall->pushTempVersion();
1410 bool destroy(
bool RunDestructors =
true) {
1411 bool OK =
cleanup(Info, RunDestructors, OldStackSize);
1416 if (OldStackSize != -1U)
1420 Info.CurrentCall->popTempVersion();
1423 static bool cleanup(EvalInfo &Info,
bool RunDestructors,
1424 unsigned OldStackSize) {
1425 assert(OldStackSize <= Info.CleanupStack.size() &&
1426 "running cleanups out of order?");
1431 for (
unsigned I = Info.CleanupStack.size(); I > OldStackSize; --I) {
1432 if (Info.CleanupStack[I - 1].isDestroyedAtEndOf(Kind)) {
1433 if (!Info.CleanupStack[I - 1].endLifetime(Info, RunDestructors)) {
1441 auto NewEnd = Info.CleanupStack.begin() + OldStackSize;
1442 if (Kind != ScopeKind::Block)
1444 std::remove_if(NewEnd, Info.CleanupStack.end(), [](Cleanup &
C) {
1445 return C.isDestroyedAtEndOf(Kind);
1447 Info.CleanupStack.erase(NewEnd, Info.CleanupStack.end());
1451 typedef ScopeRAII<ScopeKind::Block> BlockScopeRAII;
1452 typedef ScopeRAII<ScopeKind::FullExpression> FullExpressionRAII;
1453 typedef ScopeRAII<ScopeKind::Call> CallScopeRAII;
1456bool SubobjectDesignator::checkSubobject(EvalInfo &Info,
const Expr *
E,
1460 if (isOnePastTheEnd()) {
1461 Info.CCEDiag(
E, diag::note_constexpr_past_end_subobject)
1472void SubobjectDesignator::diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info,
1474 Info.CCEDiag(
E, diag::note_constexpr_unsized_array_indexed);
1479void SubobjectDesignator::diagnosePointerArithmetic(EvalInfo &Info,
1484 if (MostDerivedPathLength == Entries.size() && MostDerivedIsArrayElement)
1485 Info.CCEDiag(
E, diag::note_constexpr_array_index)
1487 <<
static_cast<unsigned>(getMostDerivedArraySize());
1489 Info.CCEDiag(
E, diag::note_constexpr_array_index)
1494CallStackFrame::CallStackFrame(EvalInfo &Info,
SourceRange CallRange,
1499 Index(Info.NextCallIndex++) {
1500 Info.CurrentCall =
this;
1501 ++Info.CallStackDepth;
1504CallStackFrame::~CallStackFrame() {
1505 assert(Info.CurrentCall ==
this &&
"calls retired out of order");
1506 --Info.CallStackDepth;
1507 Info.CurrentCall = Caller;
1529 llvm_unreachable(
"unknown access kind");
1563 llvm_unreachable(
"unknown access kind");
1567 struct ComplexValue {
1575 ComplexValue() : FloatReal(
APFloat::Bogus()), FloatImag(
APFloat::Bogus()) {}
1577 void makeComplexFloat() { IsInt =
false; }
1578 bool isComplexFloat()
const {
return !IsInt; }
1579 APFloat &getComplexFloatReal() {
return FloatReal; }
1580 APFloat &getComplexFloatImag() {
return FloatImag; }
1582 void makeComplexInt() { IsInt =
true; }
1583 bool isComplexInt()
const {
return IsInt; }
1584 APSInt &getComplexIntReal() {
return IntReal; }
1585 APSInt &getComplexIntImag() {
return IntImag; }
1588 if (isComplexFloat())
1594 assert(
v.isComplexFloat() ||
v.isComplexInt());
1595 if (
v.isComplexFloat()) {
1597 FloatReal =
v.getComplexFloatReal();
1598 FloatImag =
v.getComplexFloatImag();
1601 IntReal =
v.getComplexIntReal();
1602 IntImag =
v.getComplexIntImag();
1612 bool InvalidBase : 1;
1615 CharUnits &getLValueOffset() {
return Offset; }
1616 const CharUnits &getLValueOffset()
const {
return Offset; }
1617 SubobjectDesignator &getLValueDesignator() {
return Designator; }
1618 const SubobjectDesignator &getLValueDesignator()
const {
return Designator;}
1619 bool isNullPointer()
const {
return IsNullPtr;}
1621 unsigned getLValueCallIndex()
const {
return Base.getCallIndex(); }
1622 unsigned getLValueVersion()
const {
return Base.getVersion(); }
1628 assert(!InvalidBase &&
"APValues can't handle invalid LValue bases");
1634 assert(
V.isLValue() &&
"Setting LValue from a non-LValue?");
1635 Base =
V.getLValueBase();
1636 Offset =
V.getLValueOffset();
1637 InvalidBase =
false;
1639 IsNullPtr =
V.isNullPointer();
1646 const auto *
E = B.
get<
const Expr *>();
1647 assert((isa<MemberExpr>(
E) || tryUnwrapAllocSizeCall(
E)) &&
1648 "Unexpected type of invalid base");
1654 InvalidBase = BInvalid;
1655 Designator = SubobjectDesignator(getType(B));
1663 InvalidBase =
false;
1674 moveInto(Printable);
1681 template <
typename GenDiagType>
1682 bool checkNullPointerDiagnosingWith(
const GenDiagType &GenDiag) {
1694 bool checkNullPointer(EvalInfo &Info,
const Expr *
E,
1696 return checkNullPointerDiagnosingWith([&Info,
E, CSK] {
1697 Info.CCEDiag(
E, diag::note_constexpr_null_subobject) << CSK;
1701 bool checkNullPointerForFoldAccess(EvalInfo &Info,
const Expr *
E,
1703 return checkNullPointerDiagnosingWith([&Info,
E, AK] {
1704 Info.FFDiag(
E, diag::note_constexpr_access_null) << AK;
1715 void addDecl(EvalInfo &Info,
const Expr *
E,
1720 void addUnsizedArray(EvalInfo &Info,
const Expr *
E,
QualType ElemTy) {
1722 Info.CCEDiag(
E, diag::note_constexpr_unsupported_unsized_array);
1727 assert(getType(
Base)->isPointerType() || getType(
Base)->isArrayType());
1728 Designator.FirstEntryIsAnUnsizedArray =
true;
1736 void addComplex(EvalInfo &Info,
const Expr *
E,
QualType EltTy,
bool Imag) {
1740 void clearIsNullPointer() {
1743 void adjustOffsetAndIndex(EvalInfo &Info,
const Expr *
E,
1753 uint64_t Offset64 = Offset.getQuantity();
1755 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
1760 clearIsNullPointer();
1765 clearIsNullPointer();
1772 : DeclAndIsDerivedMember(
Decl,
false) {}
1777 return DeclAndIsDerivedMember.getPointer();
1780 bool isDerivedMember()
const {
1781 return DeclAndIsDerivedMember.getInt();
1785 return cast<CXXRecordDecl>(
1786 DeclAndIsDerivedMember.getPointer()->getDeclContext());
1793 assert(
V.isMemberPointer());
1794 DeclAndIsDerivedMember.setPointer(
V.getMemberPointerDecl());
1795 DeclAndIsDerivedMember.setInt(
V.isMemberPointerToDerivedMember());
1804 llvm::PointerIntPair<const ValueDecl*, 1, bool> DeclAndIsDerivedMember;
1812 assert(!
Path.empty());
1814 if (
Path.size() >= 2)
1818 if (
Expected->getCanonicalDecl() !=
Class->getCanonicalDecl()) {
1834 if (!isDerivedMember()) {
1835 Path.push_back(Derived);
1838 if (!castBack(Derived))
1841 DeclAndIsDerivedMember.setInt(
false);
1849 DeclAndIsDerivedMember.setInt(
true);
1850 if (isDerivedMember()) {
1854 return castBack(
Base);
1859 static bool operator==(
const MemberPtr &LHS,
const MemberPtr &RHS) {
1860 if (!LHS.getDecl() || !RHS.getDecl())
1861 return !LHS.getDecl() && !RHS.getDecl();
1862 if (LHS.getDecl()->getCanonicalDecl() != RHS.getDecl()->getCanonicalDecl())
1864 return LHS.Path == RHS.Path;
1870 const LValue &This,
const Expr *
E,
1871 bool AllowNonLiteralTypes =
false);
1873 bool InvalidBaseOK =
false);
1875 bool InvalidBaseOK =
false);
1889 std::string *StringResult =
nullptr);
1906 if (Int.isUnsigned() || Int.isMinSignedValue()) {
1907 Int = Int.extend(Int.getBitWidth() + 1);
1908 Int.setIsSigned(
true);
1913template<
typename KeyT>
1915 ScopeKind
Scope, LValue &LV) {
1916 unsigned Version = getTempVersion();
1925 assert(Args.CallIndex == Index &&
"creating parameter in wrong frame");
1931 return createLocal(
Base, PVD, PVD->
getType(), ScopeKind::Call);
1936 assert(
Base.getCallIndex() == Index &&
"lvalue for wrong frame");
1937 unsigned Version =
Base.getVersion();
1938 APValue &Result = Temporaries[MapKeyTy(Key, Version)];
1939 assert(Result.isAbsent() &&
"local created multiple times");
1945 if (Index <= Info.SpeculativeEvaluationDepth) {
1946 if (
T.isDestructedType())
1947 Info.noteSideEffect();
1949 Info.CleanupStack.push_back(Cleanup(&Result,
Base,
T,
Scope));
1956 FFDiag(
E, diag::note_constexpr_heap_alloc_limit_exceeded);
1962 auto Result = HeapAllocs.emplace(std::piecewise_construct,
1963 std::forward_as_tuple(DA), std::tuple<>());
1964 assert(Result.second &&
"reused a heap alloc index?");
1965 Result.first->second.AllocExpr =
E;
1966 return &Result.first->second.Value;
1970void CallStackFrame::describe(raw_ostream &Out)
const {
1971 unsigned ArgIndex = 0;
1973 isa<CXXMethodDecl>(Callee) && !isa<CXXConstructorDecl>(Callee) &&
1974 cast<CXXMethodDecl>(Callee)->isImplicitObjectMemberFunction();
1977 Callee->getNameForDiagnostic(Out, Info.Ctx.getPrintingPolicy(),
1980 if (This && IsMemberCall) {
1981 if (
const auto *MCE = dyn_cast_if_present<CXXMemberCallExpr>(
CallExpr)) {
1982 const Expr *
Object = MCE->getImplicitObjectArgument();
1983 Object->printPretty(Out,
nullptr, Info.Ctx.getPrintingPolicy(),
1985 if (
Object->getType()->isPointerType())
1989 }
else if (
const auto *OCE =
1990 dyn_cast_if_present<CXXOperatorCallExpr>(
CallExpr)) {
1991 OCE->getArg(0)->printPretty(Out,
nullptr,
1992 Info.Ctx.getPrintingPolicy(),
1997 This->moveInto(Val);
2000 Info.Ctx.getLValueReferenceType(
This->Designator.MostDerivedType));
2003 Callee->getNameForDiagnostic(Out, Info.Ctx.getPrintingPolicy(),
2005 IsMemberCall =
false;
2011 E =
Callee->param_end(); I !=
E; ++I, ++ArgIndex) {
2012 if (ArgIndex > (
unsigned)IsMemberCall)
2016 APValue *
V = Info.getParamSlot(Arguments, Param);
2018 V->printPretty(Out, Info.Ctx, Param->
getType());
2022 if (ArgIndex == 0 && IsMemberCall)
2023 Out <<
"->" << *
Callee <<
'(';
2037 return Info.noteSideEffect();
2043 unsigned Builtin =
E->getBuiltinCallee();
2044 return (Builtin == Builtin::BI__builtin___CFStringMakeConstantString ||
2045 Builtin == Builtin::BI__builtin___NSStringMakeConstantString ||
2046 Builtin == Builtin::BI__builtin_ptrauth_sign_constant ||
2047 Builtin == Builtin::BI__builtin_function_start);
2061 if (
const VarDecl *VD = dyn_cast<VarDecl>(
D))
2062 return VD->hasGlobalStorage();
2063 if (isa<TemplateParamObjectDecl>(
D))
2068 return isa<FunctionDecl, MSGuidDecl, UnnamedGlobalConstantDecl>(
D);
2078 case Expr::CompoundLiteralExprClass: {
2082 case Expr::MaterializeTemporaryExprClass:
2085 return cast<MaterializeTemporaryExpr>(
E)->getStorageDuration() ==
SD_Static;
2087 case Expr::StringLiteralClass:
2088 case Expr::PredefinedExprClass:
2089 case Expr::ObjCStringLiteralClass:
2090 case Expr::ObjCEncodeExprClass:
2092 case Expr::ObjCBoxedExprClass:
2093 return cast<ObjCBoxedExpr>(
E)->isExpressibleAsConstantInitializer();
2094 case Expr::CallExprClass:
2097 case Expr::AddrLabelExprClass:
2101 case Expr::BlockExprClass:
2102 return !cast<BlockExpr>(
E)->getBlockDecl()->hasCaptures();
2105 case Expr::SourceLocExprClass:
2107 case Expr::ImplicitValueInitExprClass:
2119 return LVal.Base.dyn_cast<
const ValueDecl*>();
2123 if (
Value.getLValueCallIndex())
2126 return E && !isa<MaterializeTemporaryExpr>(
E);
2136 if (isa_and_nonnull<VarDecl>(
Decl)) {
2146 if (!A.getLValueBase())
2147 return !B.getLValueBase();
2148 if (!B.getLValueBase())
2151 if (A.getLValueBase().getOpaqueValue() !=
2152 B.getLValueBase().getOpaqueValue())
2155 return A.getLValueCallIndex() == B.getLValueCallIndex() &&
2156 A.getLValueVersion() == B.getLValueVersion();
2160 assert(
Base &&
"no location for a null lvalue");
2166 if (
auto *PVD = dyn_cast_or_null<ParmVarDecl>(VD)) {
2168 for (CallStackFrame *F = Info.CurrentCall; F; F = F->Caller) {
2169 if (F->Arguments.CallIndex ==
Base.getCallIndex() &&
2170 F->Arguments.Version ==
Base.getVersion() && F->Callee &&
2171 Idx < F->Callee->getNumParams()) {
2172 VD = F->Callee->getParamDecl(Idx);
2179 Info.Note(VD->
getLocation(), diag::note_declared_at);
2181 Info.Note(
E->
getExprLoc(), diag::note_constexpr_temporary_here);
2184 if (std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA))
2185 Info.Note((*Alloc)->AllocExpr->getExprLoc(),
2186 diag::note_constexpr_dynamic_alloc_here);
2219 const SubobjectDesignator &
Designator = LVal.getLValueDesignator();
2227 if (isTemplateArgument(Kind)) {
2228 int InvalidBaseKind = -1;
2231 InvalidBaseKind = 0;
2232 else if (isa_and_nonnull<StringLiteral>(BaseE))
2233 InvalidBaseKind = 1;
2234 else if (isa_and_nonnull<MaterializeTemporaryExpr>(BaseE) ||
2235 isa_and_nonnull<LifetimeExtendedTemporaryDecl>(BaseVD))
2236 InvalidBaseKind = 2;
2237 else if (
auto *PE = dyn_cast_or_null<PredefinedExpr>(BaseE)) {
2238 InvalidBaseKind = 3;
2239 Ident = PE->getIdentKindName();
2242 if (InvalidBaseKind != -1) {
2243 Info.FFDiag(
Loc, diag::note_constexpr_invalid_template_arg)
2244 << IsReferenceType << !
Designator.Entries.empty() << InvalidBaseKind
2250 if (
auto *FD = dyn_cast_or_null<FunctionDecl>(BaseVD);
2251 FD && FD->isImmediateFunction()) {
2252 Info.FFDiag(
Loc, diag::note_consteval_address_accessible)
2254 Info.Note(FD->getLocation(), diag::note_declared_at);
2262 if (Info.getLangOpts().CPlusPlus11) {
2263 Info.FFDiag(
Loc, diag::note_constexpr_non_global, 1)
2264 << IsReferenceType << !
Designator.Entries.empty() << !!BaseVD
2266 auto *VarD = dyn_cast_or_null<VarDecl>(BaseVD);
2267 if (VarD && VarD->isConstexpr()) {
2273 Info.Note(VarD->getLocation(), diag::note_constexpr_not_static)
2285 assert((Info.checkingPotentialConstantExpression() ||
2286 LVal.getLValueCallIndex() == 0) &&
2287 "have call index for global lvalue");
2290 Info.FFDiag(
Loc, diag::note_constexpr_dynamic_alloc)
2291 << IsReferenceType << !
Designator.Entries.empty();
2297 if (
const VarDecl *Var = dyn_cast<const VarDecl>(BaseVD)) {
2299 if (Var->getTLSKind())
2305 if (!isForManglingOnly(Kind) && Var->hasAttr<DLLImportAttr>())
2311 if (Info.getCtx().getLangOpts().CUDA &&
2312 Info.getCtx().getLangOpts().CUDAIsDevice &&
2313 Info.getCtx().CUDAConstantEvalCtx.NoWrongSidedVars) {
2314 if ((!Var->hasAttr<CUDADeviceAttr>() &&
2315 !Var->hasAttr<CUDAConstantAttr>() &&
2316 !Var->getType()->isCUDADeviceBuiltinSurfaceType() &&
2317 !Var->getType()->isCUDADeviceBuiltinTextureType()) ||
2318 Var->hasAttr<HIPManagedAttr>())
2322 if (
const auto *FD = dyn_cast<const FunctionDecl>(BaseVD)) {
2333 if (Info.getLangOpts().CPlusPlus && !isForManglingOnly(Kind) &&
2334 FD->hasAttr<DLLImportAttr>())
2338 }
else if (
const auto *MTE =
2339 dyn_cast_or_null<MaterializeTemporaryExpr>(BaseE)) {
2340 if (CheckedTemps.insert(MTE).second) {
2343 Info.FFDiag(MTE->getExprLoc(),
2344 diag::note_constexpr_unsupported_temporary_nontrivial_dtor)
2349 APValue *
V = MTE->getOrCreateValue(
false);
2350 assert(
V &&
"evasluation result refers to uninitialised temporary");
2352 Info, MTE->getExprLoc(), TempType, *
V, Kind,
2353 nullptr, CheckedTemps))
2360 if (!IsReferenceType)
2372 Info.FFDiag(
Loc, diag::note_constexpr_past_end, 1)
2373 << !
Designator.Entries.empty() << !!BaseVD << BaseVD;
2388 const auto *FD = dyn_cast_or_null<CXXMethodDecl>(
Member);
2391 if (FD->isImmediateFunction()) {
2392 Info.FFDiag(
Loc, diag::note_consteval_address_accessible) << 0;
2393 Info.Note(FD->getLocation(), diag::note_declared_at);
2396 return isForManglingOnly(Kind) || FD->isVirtual() ||
2397 !FD->hasAttr<DLLImportAttr>();
2403 const LValue *This =
nullptr) {
2405 if (Info.getLangOpts().CPlusPlus23)
2424 if (This && Info.EvaluatingDecl == This->getLValueBase())
2428 if (Info.getLangOpts().CPlusPlus11)
2429 Info.FFDiag(
E, diag::note_constexpr_nonliteral)
2432 Info.FFDiag(
E, diag::note_invalid_subexpr_in_const_expr);
2443 if (SubobjectDecl) {
2444 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
2445 << 1 << SubobjectDecl;
2447 diag::note_constexpr_subobject_declared_here);
2449 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
2458 Type = AT->getValueType();
2463 if (
Value.isArray()) {
2465 for (
unsigned I = 0, N =
Value.getArrayInitializedElts(); I != N; ++I) {
2467 Value.getArrayInitializedElt(I), Kind,
2468 SubobjectDecl, CheckedTemps))
2471 if (!
Value.hasArrayFiller())
2474 Value.getArrayFiller(), Kind, SubobjectDecl,
2477 if (
Value.isUnion() &&
Value.getUnionField()) {
2480 Value.getUnionValue(), Kind,
Value.getUnionField(), CheckedTemps);
2482 if (
Value.isStruct()) {
2484 if (
const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {
2485 unsigned BaseIndex = 0;
2487 const APValue &BaseValue =
Value.getStructBase(BaseIndex);
2490 Info.FFDiag(TypeBeginLoc, diag::note_constexpr_uninitialized_base)
2491 << BS.getType() <<
SourceRange(TypeBeginLoc, BS.getEndLoc());
2501 for (
const auto *I : RD->
fields()) {
2502 if (I->isUnnamedBitField())
2506 Value.getStructField(I->getFieldIndex()), Kind,
2512 if (
Value.isLValue() &&
2513 CERK == CheckEvaluationResultKind::ConstantExpression) {
2515 LVal.setFrom(Info.Ctx,
Value);
2520 if (
Value.isMemberPointer() &&
2521 CERK == CheckEvaluationResultKind::ConstantExpression)
2541 nullptr, CheckedTemps);
2550 CheckEvaluationResultKind::FullyInitialized, Info, DiagLoc,
Type,
Value,
2551 ConstantExprKind::Normal,
nullptr, CheckedTemps);
2557 if (!Info.HeapAllocs.empty()) {
2561 Info.CCEDiag(Info.HeapAllocs.begin()->second.AllocExpr,
2562 diag::note_constexpr_memory_leak)
2563 <<
unsigned(Info.HeapAllocs.size() - 1);
2571 if (!
Value.getLValueBase()) {
2573 Result = !
Value.getLValueOffset().isZero();
2591 Result = Val.
getInt().getBoolValue();
2623 llvm_unreachable(
"unknown APValue kind");
2629 assert(
E->
isPRValue() &&
"missing lvalue-to-rvalue conv in bool condition");
2639 Info.CCEDiag(
E, diag::note_constexpr_overflow)
2640 << SrcValue << DestType;
2641 return Info.noteUndefinedBehavior();
2647 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
2651 Result =
APSInt(DestWidth, !DestSigned);
2653 if (
Value.convertToInteger(Result, llvm::APFloat::rmTowardZero, &ignored)
2654 & APFloat::opInvalidOp)
2665 llvm::RoundingMode RM =
2667 if (RM == llvm::RoundingMode::Dynamic)
2668 RM = llvm::RoundingMode::NearestTiesToEven;
2674 APFloat::opStatus St) {
2677 if (Info.InConstantContext)
2681 if ((St & APFloat::opInexact) &&
2685 Info.FFDiag(
E, diag::note_constexpr_dynamic_rounding);
2689 if ((St != APFloat::opOK) &&
2692 FPO.getAllowFEnvAccess())) {
2693 Info.FFDiag(
E, diag::note_constexpr_float_arithmetic_strict);
2697 if ((St & APFloat::opStatus::opInvalidOp) &&
2716 assert((isa<CastExpr>(
E) || isa<CompoundAssignOperator>(
E) ||
2717 isa<ConvertVectorExpr>(
E)) &&
2718 "HandleFloatToFloatCast has been checked with only CastExpr, "
2719 "CompoundAssignOperator and ConvertVectorExpr. Please either validate "
2720 "the new expression or address the root cause of this usage.");
2722 APFloat::opStatus St;
2723 APFloat
Value = Result;
2725 St = Result.convert(Info.Ctx.getFloatTypeSemantics(DestType), RM, &ignored);
2732 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
2738 Result =
Value.getBoolValue();
2745 QualType DestType, APFloat &Result) {
2746 Result = APFloat(Info.Ctx.getFloatTypeSemantics(DestType), 1);
2748 APFloat::opStatus St = Result.convertFromAPInt(
Value,
Value.isSigned(), RM);
2754 assert(FD->
isBitField() &&
"truncateBitfieldValue on non-bitfield");
2756 if (!
Value.isInt()) {
2760 assert(
Value.isLValue() &&
"integral value neither int nor lvalue?");
2766 unsigned OldBitWidth = Int.getBitWidth();
2768 if (NewBitWidth < OldBitWidth)
2769 Int = Int.trunc(NewBitWidth).extend(OldBitWidth);
2776template<
typename Operation>
2779 unsigned BitWidth, Operation Op,
2781 if (LHS.isUnsigned()) {
2782 Result = Op(LHS, RHS);
2786 APSInt Value(Op(LHS.extend(BitWidth), RHS.extend(BitWidth)),
false);
2787 Result =
Value.trunc(LHS.getBitWidth());
2788 if (Result.extend(BitWidth) !=
Value) {
2789 if (Info.checkingForUndefinedBehavior())
2791 diag::warn_integer_constant_overflow)
2792 <<
toString(Result, 10, Result.isSigned(),
false,
2804 bool HandleOverflowResult =
true;
2811 std::multiplies<APSInt>(), Result);
2814 std::plus<APSInt>(), Result);
2817 std::minus<APSInt>(), Result);
2818 case BO_And: Result = LHS & RHS;
return true;
2819 case BO_Xor: Result = LHS ^ RHS;
return true;
2820 case BO_Or: Result = LHS | RHS;
return true;
2824 Info.FFDiag(
E, diag::note_expr_divide_by_zero)
2830 if (RHS.isNegative() && RHS.isAllOnes() && LHS.isSigned() &&
2831 LHS.isMinSignedValue())
2833 Info,
E, -LHS.extend(LHS.getBitWidth() + 1),
E->
getType());
2834 Result = (Opcode == BO_Rem ? LHS % RHS : LHS / RHS);
2835 return HandleOverflowResult;
2837 if (Info.getLangOpts().OpenCL)
2839 RHS &=
APSInt(llvm::APInt(RHS.getBitWidth(),
2840 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2842 else if (RHS.isSigned() && RHS.isNegative()) {
2845 Info.CCEDiag(
E, diag::note_constexpr_negative_shift) << RHS;
2846 if (!Info.noteUndefinedBehavior())
2854 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
2856 Info.CCEDiag(
E, diag::note_constexpr_large_shift)
2857 << RHS <<
E->
getType() << LHS.getBitWidth();
2858 if (!Info.noteUndefinedBehavior())
2860 }
else if (LHS.isSigned() && !Info.getLangOpts().CPlusPlus20) {
2865 if (LHS.isNegative()) {
2866 Info.CCEDiag(
E, diag::note_constexpr_lshift_of_negative) << LHS;
2867 if (!Info.noteUndefinedBehavior())
2869 }
else if (LHS.countl_zero() < SA) {
2870 Info.CCEDiag(
E, diag::note_constexpr_lshift_discards);
2871 if (!Info.noteUndefinedBehavior())
2879 if (Info.getLangOpts().OpenCL)
2881 RHS &=
APSInt(llvm::APInt(RHS.getBitWidth(),
2882 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2884 else if (RHS.isSigned() && RHS.isNegative()) {
2887 Info.CCEDiag(
E, diag::note_constexpr_negative_shift) << RHS;
2888 if (!Info.noteUndefinedBehavior())
2896 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
2898 Info.CCEDiag(
E, diag::note_constexpr_large_shift)
2899 << RHS <<
E->
getType() << LHS.getBitWidth();
2900 if (!Info.noteUndefinedBehavior())
2908 case BO_LT: Result = LHS < RHS;
return true;
2909 case BO_GT: Result = LHS > RHS;
return true;
2910 case BO_LE: Result = LHS <= RHS;
return true;
2911 case BO_GE: Result = LHS >= RHS;
return true;
2912 case BO_EQ: Result = LHS == RHS;
return true;
2913 case BO_NE: Result = LHS != RHS;
return true;
2915 llvm_unreachable(
"BO_Cmp should be handled elsewhere");
2922 const APFloat &RHS) {
2924 APFloat::opStatus St;
2930 St = LHS.multiply(RHS, RM);
2933 St = LHS.add(RHS, RM);
2936 St = LHS.subtract(RHS, RM);
2942 Info.CCEDiag(
E, diag::note_expr_divide_by_zero);
2943 St = LHS.divide(RHS, RM);
2952 Info.CCEDiag(
E, diag::note_constexpr_float_arithmetic) << LHS.isNaN();
2953 return Info.noteUndefinedBehavior();
2961 const APInt &RHSValue, APInt &Result) {
2962 bool LHS = (LHSValue != 0);
2963 bool RHS = (RHSValue != 0);
2965 if (Opcode == BO_LAnd)
2966 Result = LHS && RHS;
2968 Result = LHS || RHS;
2973 const APFloat &RHSValue, APInt &Result) {
2974 bool LHS = !LHSValue.isZero();
2975 bool RHS = !RHSValue.isZero();
2977 if (Opcode == BO_LAnd)
2978 Result = LHS && RHS;
2980 Result = LHS || RHS;
2986 const APValue &RHSValue, APInt &Result) {
2990 RHSValue.
getInt(), Result);
2996template <
typename APTy>
2999 const APTy &RHSValue, APInt &Result) {
3002 llvm_unreachable(
"unsupported binary operator");
3004 Result = (LHSValue == RHSValue);
3007 Result = (LHSValue != RHSValue);
3010 Result = (LHSValue < RHSValue);
3013 Result = (LHSValue > RHSValue);
3016 Result = (LHSValue <= RHSValue);
3019 Result = (LHSValue >= RHSValue);
3033 const APValue &RHSValue, APInt &Result) {
3037 RHSValue.
getInt(), Result);
3048 assert(Opcode != BO_PtrMemD && Opcode != BO_PtrMemI &&
3049 "Operation not supported on vector types");
3053 QualType EltTy = VT->getElementType();
3060 "A vector result that isn't a vector OR uncalculated LValue");
3066 RHSValue.
getVectorLength() == NumElements &&
"Different vector sizes");
3070 for (
unsigned EltNum = 0; EltNum < NumElements; ++EltNum) {
3075 APSInt EltResult{Info.Ctx.getIntWidth(EltTy),
3085 RHSElt.
getInt(), EltResult);
3091 ResultElements.emplace_back(EltResult);
3096 "Mismatched LHS/RHS/Result Type");
3097 APFloat LHSFloat = LHSElt.
getFloat();
3105 ResultElements.emplace_back(LHSFloat);
3109 LHSValue =
APValue(ResultElements.data(), ResultElements.size());
3117 unsigned TruncatedElements) {
3118 SubobjectDesignator &
D = Result.Designator;
3121 if (TruncatedElements ==
D.Entries.size())
3123 assert(TruncatedElements >=
D.MostDerivedPathLength &&
3124 "not casting to a derived class");
3130 for (
unsigned I = TruncatedElements, N =
D.Entries.size(); I != N; ++I) {
3134 if (isVirtualBaseClass(
D.Entries[I]))
3140 D.Entries.resize(TruncatedElements);
3150 RL = &Info.Ctx.getASTRecordLayout(Derived);
3153 Obj.getLValueOffset() += RL->getBaseClassOffset(
Base);
3154 Obj.addDecl(Info,
E,
Base,
false);
3163 if (!
Base->isVirtual())
3166 SubobjectDesignator &
D = Obj.Designator;
3171 DerivedDecl =
D.MostDerivedType->getAsCXXRecordDecl();
3177 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(DerivedDecl);
3179 Obj.addDecl(Info,
E, BaseDecl,
true);
3186 PathE =
E->path_end();
3187 PathI != PathE; ++PathI) {
3191 Type = (*PathI)->getType();
3203 llvm_unreachable(
"Class must be derived from the passed in base class!");
3218 RL = &Info.Ctx.getASTRecordLayout(FD->
getParent());
3222 LVal.adjustOffset(Info.Ctx.toCharUnitsFromBits(RL->getFieldOffset(I)));
3223 LVal.addDecl(Info,
E, FD);
3231 for (
const auto *
C : IFD->
chain())
3264 if (SOT == SizeOfType::SizeOf)
3265 Size = Info.Ctx.getTypeSizeInChars(
Type);
3267 Size = Info.Ctx.getTypeInfoDataSizeInChars(
Type).Width;
3284 LVal.adjustOffsetAndIndex(Info,
E, Adjustment, SizeOfPointee);
3290 int64_t Adjustment) {
3292 APSInt::get(Adjustment));
3307 LVal.Offset += SizeOfComponent;
3309 LVal.addComplex(Info,
E, EltTy, Imag);
3323 const VarDecl *VD, CallStackFrame *Frame,
3324 unsigned Version,
APValue *&Result) {
3329 Result = Frame->getTemporary(VD, Version);
3333 if (!isa<ParmVarDecl>(VD)) {
3340 "missing value for local variable");
3341 if (Info.checkingPotentialConstantExpression())
3346 diag::note_unimplemented_constexpr_lambda_feature_ast)
3347 <<
"captures not currently allowed";
3354 if (Info.EvaluatingDecl ==
Base) {
3355 Result = Info.EvaluatingDeclValue;
3359 if (isa<ParmVarDecl>(VD)) {
3362 if (!Info.checkingPotentialConstantExpression() ||
3363 !Info.CurrentCall->Callee ||
3365 if (Info.getLangOpts().CPlusPlus11) {
3366 Info.FFDiag(
E, diag::note_constexpr_function_param_value_unknown)
3386 if (!Info.checkingPotentialConstantExpression()) {
3387 Info.FFDiag(
E, diag::note_constexpr_var_init_unknown, 1)
3394 if (
Init->isValueDependent()) {
3401 if (!Info.checkingPotentialConstantExpression()) {
3402 Info.FFDiag(
E, Info.getLangOpts().CPlusPlus11
3403 ? diag::note_constexpr_ltor_non_constexpr
3404 : diag::note_constexpr_ltor_non_integral, 1)
3414 Info.FFDiag(
E, diag::note_constexpr_var_init_non_constant, 1) << VD;
3430 ((Info.getLangOpts().CPlusPlus || Info.getLangOpts().OpenCL) &&
3432 Info.CCEDiag(
E, diag::note_constexpr_var_init_non_constant, 1) << VD;
3439 Info.FFDiag(
E, diag::note_constexpr_var_init_weak) << VD;
3456 if (I->getType()->getAsCXXRecordDecl()->getCanonicalDecl() ==
Base)
3460 llvm_unreachable(
"base class missing from derived class's bases list");
3466 assert(!isa<SourceLocExpr>(Lit) &&
3467 "SourceLocExpr should have already been converted to a StringLiteral");
3470 if (
const auto *ObjCEnc = dyn_cast<ObjCEncodeExpr>(Lit)) {
3472 Info.Ctx.getObjCEncodingForType(ObjCEnc->getEncodedType(), Str);
3473 assert(Index <= Str.size() &&
"Index too large");
3474 return APSInt::getUnsigned(Str.c_str()[Index]);
3477 if (
auto PE = dyn_cast<PredefinedExpr>(Lit))
3478 Lit = PE->getFunctionName();
3481 Info.Ctx.getAsConstantArrayType(S->getType());
3482 assert(CAT &&
"string literal isn't an array");
3484 assert(CharType->
isIntegerType() &&
"unexpected character type");
3487 if (Index < S->getLength())
3488 Value = S->getCodeUnit(Index);
3500 AllocType.isNull() ? S->getType() : AllocType);
3501 assert(CAT &&
"string literal isn't an array");
3503 assert(CharType->
isIntegerType() &&
"unexpected character type");
3507 std::min(S->getLength(), Elts), Elts);
3510 if (Result.hasArrayFiller())
3512 for (
unsigned I = 0, N = Result.getArrayInitializedElts(); I != N; ++I) {
3513 Value = S->getCodeUnit(I);
3520 unsigned Size = Array.getArraySize();
3521 assert(Index < Size);
3524 unsigned OldElts = Array.getArrayInitializedElts();
3525 unsigned NewElts = std::max(Index+1, OldElts * 2);
3526 NewElts = std::min(Size, std::max(NewElts, 8u));
3530 for (
unsigned I = 0; I != OldElts; ++I)
3532 for (
unsigned I = OldElts; I != NewElts; ++I)
3536 Array.swap(NewValue);
3557 for (
auto *Field : RD->
fields())
3558 if (!Field->isUnnamedBitField() &&
3562 for (
auto &BaseSpec : RD->
bases())
3580 for (
auto *Field : RD->
fields()) {
3585 if (Field->isMutable() &&
3587 Info.FFDiag(
E, diag::note_constexpr_access_mutable, 1) << AK << Field;
3588 Info.Note(Field->getLocation(), diag::note_declared_at);
3596 for (
auto &BaseSpec : RD->
bases())
3606 bool MutableSubobject =
false) {
3611 switch (Info.IsEvaluatingDecl) {
3612 case EvalInfo::EvaluatingDeclKind::None:
3615 case EvalInfo::EvaluatingDeclKind::Ctor:
3617 if (Info.EvaluatingDecl ==
Base)
3622 if (
auto *BaseE =
Base.dyn_cast<
const Expr *>())
3623 if (
auto *BaseMTE = dyn_cast<MaterializeTemporaryExpr>(BaseE))
3624 return Info.EvaluatingDecl == BaseMTE->getExtendingDecl();
3627 case EvalInfo::EvaluatingDeclKind::Dtor:
3632 if (MutableSubobject ||
Base != Info.EvaluatingDecl)
3641 llvm_unreachable(
"unknown evaluating decl kind");
3646 return Info.CheckArraySize(
3655struct CompleteObject {
3663 CompleteObject() :
Value(nullptr) {}
3667 bool mayAccessMutableMembers(EvalInfo &Info,
AccessKinds AK)
const {
3678 if (!Info.getLangOpts().CPlusPlus14)
3683 explicit operator bool()
const {
return !
Type.isNull(); }
3688 bool IsMutable =
false) {
3702template<
typename Sub
objectHandler>
3703typename SubobjectHandler::result_type
3705 const SubobjectDesignator &Sub, SubobjectHandler &handler) {
3708 return handler.failed();
3709 if (Sub.isOnePastTheEnd() || Sub.isMostDerivedAnUnsizedArray()) {
3710 if (Info.getLangOpts().CPlusPlus11)
3711 Info.FFDiag(
E, Sub.isOnePastTheEnd()
3712 ? diag::note_constexpr_access_past_end
3713 : diag::note_constexpr_access_unsized_array)
3714 << handler.AccessKind;
3717 return handler.failed();
3723 const FieldDecl *VolatileField =
nullptr;
3726 for (
unsigned I = 0, N = Sub.Entries.size(); ; ++I) {
3731 if (!Info.checkingPotentialConstantExpression())
3732 Info.FFDiag(
E, diag::note_constexpr_access_uninit)
3735 return handler.failed();
3743 Info.isEvaluatingCtorDtor(
3746 ConstructionPhase::None) {
3756 if (Info.getLangOpts().CPlusPlus) {
3760 if (VolatileField) {
3763 Decl = VolatileField;
3764 }
else if (
auto *VD = Obj.Base.dyn_cast<
const ValueDecl*>()) {
3766 Loc = VD->getLocation();
3770 if (
auto *
E = Obj.Base.dyn_cast<
const Expr *>())
3773 Info.FFDiag(
E, diag::note_constexpr_access_volatile_obj, 1)
3774 << handler.AccessKind << DiagKind <<
Decl;
3775 Info.Note(
Loc, diag::note_constexpr_volatile_here) << DiagKind;
3777 Info.FFDiag(
E, diag::note_invalid_subexpr_in_const_expr);
3779 return handler.failed();
3787 !Obj.mayAccessMutableMembers(Info, handler.AccessKind) &&
3789 return handler.failed();
3793 if (!handler.found(*O, ObjType))
3805 LastField =
nullptr;
3809 assert(CAT &&
"vla in literal type?");
3810 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
3811 if (CAT->
getSize().ule(Index)) {
3814 if (Info.getLangOpts().CPlusPlus11)
3815 Info.FFDiag(
E, diag::note_constexpr_access_past_end)
3816 << handler.AccessKind;
3819 return handler.failed();
3826 else if (!
isRead(handler.AccessKind)) {
3828 return handler.failed();
3836 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
3838 if (Info.getLangOpts().CPlusPlus11)
3839 Info.FFDiag(
E, diag::note_constexpr_access_past_end)
3840 << handler.AccessKind;
3843 return handler.failed();
3849 assert(I == N - 1 &&
"extracting subobject of scalar?");
3858 }
else if (
const FieldDecl *Field = getAsField(Sub.Entries[I])) {
3859 if (Field->isMutable() &&
3860 !Obj.mayAccessMutableMembers(Info, handler.AccessKind)) {
3861 Info.FFDiag(
E, diag::note_constexpr_access_mutable, 1)
3862 << handler.AccessKind << Field;
3863 Info.Note(Field->getLocation(), diag::note_declared_at);
3864 return handler.failed();
3873 if (I == N - 1 && handler.AccessKind ==
AK_Construct) {
3881 Info.FFDiag(
E, diag::note_constexpr_access_inactive_union_member)
3882 << handler.AccessKind << Field << !UnionField << UnionField;
3883 return handler.failed();
3892 if (Field->getType().isVolatileQualified())
3893 VolatileField = Field;
3906struct ExtractSubobjectHandler {
3912 typedef bool result_type;
3913 bool failed() {
return false; }
3933 const CompleteObject &Obj,
3934 const SubobjectDesignator &Sub,
APValue &Result,
3937 ExtractSubobjectHandler Handler = {Info,
E, Result, AK};
3942struct ModifySubobjectHandler {
3947 typedef bool result_type;
3953 Info.FFDiag(
E, diag::note_constexpr_modify_const_type) << QT;
3959 bool failed() {
return false; }
3961 if (!checkConst(SubobjType))
3964 Subobj.
swap(NewVal);
3968 if (!checkConst(SubobjType))
3970 if (!NewVal.
isInt()) {
3979 if (!checkConst(SubobjType))
3987const AccessKinds ModifySubobjectHandler::AccessKind;
3991 const CompleteObject &Obj,
3992 const SubobjectDesignator &Sub,
3994 ModifySubobjectHandler Handler = { Info, NewVal,
E };
4001 const SubobjectDesignator &A,
4002 const SubobjectDesignator &B,
4003 bool &WasArrayIndex) {
4004 unsigned I = 0, N = std::min(A.Entries.size(), B.Entries.size());
4005 for (; I != N; ++I) {
4009 if (A.Entries[I].getAsArrayIndex() != B.Entries[I].getAsArrayIndex()) {
4010 WasArrayIndex =
true;
4018 if (A.Entries[I].getAsBaseOrMember() !=
4019 B.Entries[I].getAsBaseOrMember()) {
4020 WasArrayIndex =
false;
4023 if (
const FieldDecl *FD = getAsField(A.Entries[I]))
4025 ObjType = FD->getType();
4031 WasArrayIndex =
false;
4038 const SubobjectDesignator &A,
4039 const SubobjectDesignator &B) {
4040 if (A.Entries.size() != B.Entries.size())
4043 bool IsArray = A.MostDerivedIsArrayElement;
4044 if (IsArray && A.MostDerivedPathLength != A.Entries.size())
4053 return CommonLength >= A.Entries.size() - IsArray;
4060 if (LVal.InvalidBase) {
4062 return CompleteObject();
4066 Info.FFDiag(
E, diag::note_constexpr_access_null) << AK;
4067 return CompleteObject();
4070 CallStackFrame *Frame =
nullptr;
4072 if (LVal.getLValueCallIndex()) {
4073 std::tie(Frame, Depth) =
4074 Info.getCallFrameAndDepth(LVal.getLValueCallIndex());
4076 Info.FFDiag(
E, diag::note_constexpr_lifetime_ended, 1)
4077 << AK << LVal.Base.is<
const ValueDecl*>();
4079 return CompleteObject();
4090 if (Info.getLangOpts().CPlusPlus)
4091 Info.FFDiag(
E, diag::note_constexpr_access_volatile_type)
4095 return CompleteObject();
4100 QualType BaseType = getType(LVal.Base);
4102 if (Info.getLangOpts().CPlusPlus14 && LVal.Base == Info.EvaluatingDecl &&
4106 BaseVal = Info.EvaluatingDeclValue;
4109 if (
auto *GD = dyn_cast<MSGuidDecl>(
D)) {
4112 Info.FFDiag(
E, diag::note_constexpr_modify_global);
4113 return CompleteObject();
4117 Info.FFDiag(
E, diag::note_constexpr_unsupported_layout)
4119 return CompleteObject();
4121 return CompleteObject(LVal.Base, &
V, GD->getType());
4125 if (
auto *GCD = dyn_cast<UnnamedGlobalConstantDecl>(
D)) {
4127 Info.FFDiag(
E, diag::note_constexpr_modify_global);
4128 return CompleteObject();
4130 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&GCD->getValue()),
4135 if (
auto *TPO = dyn_cast<TemplateParamObjectDecl>(
D)) {
4137 Info.FFDiag(
E, diag::note_constexpr_modify_global);
4138 return CompleteObject();
4140 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&TPO->getValue()),
4151 const VarDecl *VD = dyn_cast<VarDecl>(
D);
4158 return CompleteObject();
4161 bool IsConstant = BaseType.
isConstant(Info.Ctx);
4162 bool ConstexprVar =
false;
4163 if (
const auto *VD = dyn_cast_if_present<VarDecl>(
4164 Info.EvaluatingDecl.dyn_cast<
const ValueDecl *>()))
4170 if (IsAccess && isa<ParmVarDecl>(VD)) {
4174 }
else if (Info.getLangOpts().CPlusPlus14 &&
4181 Info.FFDiag(
E, diag::note_constexpr_modify_global);
4182 return CompleteObject();
4185 }
else if (Info.getLangOpts().C23 && ConstexprVar) {
4187 return CompleteObject();
4191 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4192 if (Info.getLangOpts().CPlusPlus) {
4193 Info.FFDiag(
E, diag::note_constexpr_ltor_non_const_int, 1) << VD;
4194 Info.Note(VD->
getLocation(), diag::note_declared_at);
4198 return CompleteObject();
4200 }
else if (!IsAccess) {
4201 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4202 }
else if (IsConstant && Info.checkingPotentialConstantExpression() &&
4205 }
else if (IsConstant) {
4209 if (Info.getLangOpts().CPlusPlus) {
4210 Info.CCEDiag(
E, Info.getLangOpts().CPlusPlus11
4211 ? diag::note_constexpr_ltor_non_constexpr
4212 : diag::note_constexpr_ltor_non_integral, 1)
4214 Info.Note(VD->
getLocation(), diag::note_declared_at);
4220 if (Info.getLangOpts().CPlusPlus) {
4221 Info.FFDiag(
E, Info.getLangOpts().CPlusPlus11
4222 ? diag::note_constexpr_ltor_non_constexpr
4223 : diag::note_constexpr_ltor_non_integral, 1)
4225 Info.Note(VD->
getLocation(), diag::note_declared_at);
4229 return CompleteObject();
4234 return CompleteObject();
4236 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
4238 Info.FFDiag(
E, diag::note_constexpr_access_deleted_object) << AK;
4239 return CompleteObject();
4241 return CompleteObject(LVal.Base, &(*Alloc)->Value,
4242 LVal.Base.getDynamicAllocType());
4248 dyn_cast_or_null<MaterializeTemporaryExpr>(
Base)) {
4249 assert(MTE->getStorageDuration() ==
SD_Static &&
4250 "should have a frame for a non-global materialized temporary");
4277 if (!MTE->isUsableInConstantExpressions(Info.Ctx) &&
4280 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4281 Info.FFDiag(
E, diag::note_constexpr_access_static_temporary, 1) << AK;
4282 Info.Note(MTE->getExprLoc(), diag::note_constexpr_temporary_here);
4283 return CompleteObject();
4286 BaseVal = MTE->getOrCreateValue(
false);
4287 assert(BaseVal &&
"got reference to unevaluated temporary");
4290 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4293 Info.FFDiag(
E, diag::note_constexpr_access_unreadable_object)
4296 Info.Ctx.getLValueReferenceType(LValType));
4298 return CompleteObject();
4301 BaseVal = Frame->getTemporary(
Base, LVal.Base.getVersion());
4302 assert(BaseVal &&
"missing value for temporary");
4313 unsigned VisibleDepth = Depth;
4314 if (llvm::isa_and_nonnull<ParmVarDecl>(
4315 LVal.Base.dyn_cast<
const ValueDecl *>()))
4317 if ((Frame && Info.getLangOpts().CPlusPlus14 &&
4318 Info.EvalStatus.HasSideEffects) ||
4319 (
isModification(AK) && VisibleDepth < Info.SpeculativeEvaluationDepth))
4320 return CompleteObject();
4322 return CompleteObject(LVal.getLValueBase(), BaseVal, BaseType);
4341 const LValue &LVal,
APValue &RVal,
4342 bool WantObjectRepresentation =
false) {
4343 if (LVal.Designator.Invalid)
4352 if (
Base && !LVal.getLValueCallIndex() && !
Type.isVolatileQualified()) {
4357 if (
Type.isVolatileQualified()) {
4363 if (!
Evaluate(Lit, Info, CLE->getInitializer()))
4383 Info.Note(CLE->getExprLoc(), diag::note_declared_at);
4388 CompleteObject LitObj(LVal.Base, &Lit,
Base->getType());
4390 }
else if (isa<StringLiteral>(
Base) || isa<PredefinedExpr>(
Base)) {
4393 assert(LVal.Designator.Entries.size() <= 1 &&
4394 "Can only read characters from string literals");
4395 if (LVal.Designator.Entries.empty()) {
4402 if (LVal.Designator.isOnePastTheEnd()) {
4403 if (Info.getLangOpts().CPlusPlus11)
4404 Info.FFDiag(Conv, diag::note_constexpr_access_past_end) << AK;
4409 uint64_t CharIndex = LVal.Designator.Entries[0].getAsArrayIndex();
4416 return Obj &&
extractSubobject(Info, Conv, Obj, LVal.Designator, RVal, AK);
4422 if (LVal.Designator.Invalid)
4425 if (!Info.getLangOpts().CPlusPlus14) {
4435struct CompoundAssignSubobjectHandler {
4444 typedef bool result_type;
4449 Info.FFDiag(
E, diag::note_constexpr_modify_const_type) << QT;
4455 bool failed() {
return false; }
4459 return found(Subobj.
getInt(), SubobjType);
4461 return found(Subobj.
getFloat(), SubobjType);
4468 return foundPointer(Subobj, SubobjType);
4470 return foundVector(Subobj, SubobjType);
4472 Info.FFDiag(
E, diag::note_constexpr_access_uninit)
4484 if (!checkConst(SubobjType))
4495 if (!checkConst(SubobjType))
4514 Info.Ctx.getLangOpts());
4517 PromotedLHSType, FValue) &&
4527 return checkConst(SubobjType) &&
4534 if (!checkConst(SubobjType))
4542 (Opcode != BO_Add && Opcode != BO_Sub)) {
4548 if (Opcode == BO_Sub)
4552 LVal.setFrom(Info.Ctx, Subobj);
4555 LVal.moveInto(Subobj);
4561const AccessKinds CompoundAssignSubobjectHandler::AccessKind;
4566 const LValue &LVal,
QualType LValType,
4570 if (LVal.Designator.Invalid)
4573 if (!Info.getLangOpts().CPlusPlus14) {
4579 CompoundAssignSubobjectHandler Handler = { Info,
E, PromotedLValType, Opcode,
4581 return Obj &&
findSubobject(Info,
E, Obj, LVal.Designator, Handler);
4585struct IncDecSubobjectHandler {
4591 typedef bool result_type;
4596 Info.FFDiag(
E, diag::note_constexpr_modify_const_type) << QT;
4602 bool failed() {
return false; }
4613 return found(Subobj.
getInt(), SubobjType);
4615 return found(Subobj.
getFloat(), SubobjType);
4625 return foundPointer(Subobj, SubobjType);
4633 if (!checkConst(SubobjType))
4655 bool WasNegative =
Value.isNegative();
4659 if (!WasNegative &&
Value.isNegative() &&
E->canOverflow()) {
4666 if (WasNegative && !
Value.isNegative() &&
E->canOverflow()) {
4667 unsigned BitWidth =
Value.getBitWidth();
4668 APSInt ActualValue(
Value.sext(BitWidth + 1),
false);
4669 ActualValue.setBit(BitWidth);
4676 if (!checkConst(SubobjType))
4683 APFloat::opStatus St;
4685 St =
Value.add(One, RM);
4687 St =
Value.subtract(One, RM);
4691 if (!checkConst(SubobjType))
4703 LVal.setFrom(Info.Ctx, Subobj);
4707 LVal.moveInto(Subobj);
4716 if (LVal.Designator.Invalid)
4719 if (!Info.getLangOpts().CPlusPlus14) {
4726 IncDecSubobjectHandler Handler = {Info, cast<UnaryOperator>(
E), AK, Old};
4727 return Obj &&
findSubobject(Info,
E, Obj, LVal.Designator, Handler);
4733 if (Object->getType()->isPointerType() && Object->isPRValue())
4736 if (Object->isGLValue())
4739 if (Object->getType()->isLiteralType(Info.Ctx))
4742 if (Object->getType()->isRecordType() && Object->isPRValue())
4745 Info.FFDiag(Object, diag::note_constexpr_nonliteral) << Object->getType();
4764 bool IncludeMember =
true) {
4771 if (!MemPtr.getDecl()) {
4777 if (MemPtr.isDerivedMember()) {
4781 if (LV.Designator.MostDerivedPathLength + MemPtr.Path.size() >
4782 LV.Designator.Entries.size()) {
4786 unsigned PathLengthToMember =
4787 LV.Designator.Entries.size() - MemPtr.Path.size();
4788 for (
unsigned I = 0, N = MemPtr.Path.size(); I != N; ++I) {
4790 LV.Designator.Entries[PathLengthToMember + I]);
4800 PathLengthToMember))
4802 }
else if (!MemPtr.Path.empty()) {
4804 LV.Designator.Entries.reserve(LV.Designator.Entries.size() +
4805 MemPtr.Path.size() + IncludeMember);
4811 assert(RD &&
"member pointer access on non-class-type expression");
4813 for (
unsigned I = 1, N = MemPtr.Path.size(); I != N; ++I) {
4821 MemPtr.getContainingRecord()))
4826 if (IncludeMember) {
4827 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(MemPtr.getDecl())) {
4831 dyn_cast<IndirectFieldDecl>(MemPtr.getDecl())) {
4835 llvm_unreachable(
"can't construct reference to bound member function");
4839 return MemPtr.getDecl();
4845 bool IncludeMember =
true) {
4849 if (Info.noteFailure()) {
4857 BO->
getRHS(), IncludeMember);
4864 SubobjectDesignator &
D = Result.Designator;
4865 if (
D.Invalid || !Result.checkNullPointer(Info,
E,
CSK_Derived))
4873 if (
D.MostDerivedPathLength +
E->path_size() >
D.Entries.size()) {
4874 Info.CCEDiag(
E, diag::note_constexpr_invalid_downcast)
4875 <<
D.MostDerivedType << TargetQT;
4881 unsigned NewEntriesSize =
D.Entries.size() -
E->path_size();
4884 if (NewEntriesSize ==
D.MostDerivedPathLength)
4885 FinalType =
D.MostDerivedType->getAsCXXRecordDecl();
4887 FinalType = getAsBaseClass(
D.Entries[NewEntriesSize - 1]);
4889 Info.CCEDiag(
E, diag::note_constexpr_invalid_downcast)
4890 <<
D.MostDerivedType << TargetQT;
4904 if (!Result.isAbsent())
4908 if (RD->isInvalidDecl()) {
4912 if (RD->isUnion()) {
4917 std::distance(RD->field_begin(), RD->field_end()));
4921 End = RD->bases_end();
4922 I != End; ++I, ++Index)
4926 for (
const auto *I : RD->fields()) {
4927 if (I->isUnnamedBitField())
4930 I->getType(), Result.getStructField(I->getFieldIndex()));
4938 if (Result.hasArrayFiller())
4950enum EvalStmtResult {
4974 APValue &Val = Info.CurrentCall->createTemporary(VD, VD->
getType(),
4975 ScopeKind::Block, Result);
4980 return Info.noteSideEffect();
4999 if (
const VarDecl *VD = dyn_cast<VarDecl>(
D))
5003 for (
auto *BD : DD->bindings())
5004 if (
auto *VD = BD->getHoldingVar())
5012 if (Info.noteSideEffect())
5014 assert(
E->
containsErrors() &&
"valid value-dependent expression should never "
5015 "reach invalid code path.");
5021 const Expr *Cond,
bool &Result) {
5024 FullExpressionRAII
Scope(Info);
5029 return Scope.destroy();
5042struct TempVersionRAII {
5043 CallStackFrame &Frame;
5045 TempVersionRAII(CallStackFrame &Frame) : Frame(Frame) {
5046 Frame.pushTempVersion();
5049 ~TempVersionRAII() {
5050 Frame.popTempVersion();
5064 BlockScopeRAII
Scope(Info);
5066 EvalStmtResult ESR =
EvaluateStmt(Result, Info, Body, Case);
5067 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5072 return ESR_Succeeded;
5075 return ESR_Continue;
5078 case ESR_CaseNotFound:
5081 llvm_unreachable(
"Invalid EvalStmtResult!");
5087 BlockScopeRAII
Scope(Info);
5094 if (ESR != ESR_Succeeded) {
5095 if (ESR != ESR_Failed && !
Scope.destroy())
5101 FullExpressionRAII CondScope(Info);
5113 if (!CondScope.destroy())
5122 if (isa<DefaultStmt>(SC)) {
5127 const CaseStmt *CS = cast<CaseStmt>(SC);
5138 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5142 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5147 return ESR_Succeeded;
5153 case ESR_CaseNotFound:
5156 Info.FFDiag(
Found->getBeginLoc(),
5157 diag::note_constexpr_stmt_expr_unsupported);
5160 llvm_unreachable(
"Invalid EvalStmtResult!");
5170 Info.CCEDiag(VD->
getLocation(), diag::note_constexpr_static_local)
5180 if (!Info.nextStep(S))
5186 switch (S->getStmtClass()) {
5187 case Stmt::CompoundStmtClass:
5191 case Stmt::LabelStmtClass:
5192 case Stmt::AttributedStmtClass:
5193 case Stmt::DoStmtClass:
5196 case Stmt::CaseStmtClass:
5197 case Stmt::DefaultStmtClass:
5202 case Stmt::IfStmtClass: {
5205 const IfStmt *IS = cast<IfStmt>(S);
5209 BlockScopeRAII
Scope(Info);
5215 if (ESR != ESR_CaseNotFound) {
5216 assert(ESR != ESR_Succeeded);
5227 if (ESR == ESR_Failed)
5229 if (ESR != ESR_CaseNotFound)
5230 return Scope.destroy() ? ESR : ESR_Failed;
5232 return ESR_CaseNotFound;
5235 if (ESR == ESR_Failed)
5237 if (ESR != ESR_CaseNotFound)
5238 return Scope.destroy() ? ESR : ESR_Failed;
5239 return ESR_CaseNotFound;
5242 case Stmt::WhileStmtClass: {
5243 EvalStmtResult ESR =
5245 if (ESR != ESR_Continue)
5250 case Stmt::ForStmtClass: {
5251 const ForStmt *FS = cast<ForStmt>(S);
5252 BlockScopeRAII
Scope(Info);
5256 if (
const Stmt *
Init = FS->getInit()) {
5258 if (ESR != ESR_CaseNotFound) {
5259 assert(ESR != ESR_Succeeded);
5264 EvalStmtResult ESR =
5266 if (ESR != ESR_Continue)
5268 if (
const auto *Inc = FS->getInc()) {
5269 if (Inc->isValueDependent()) {
5273 FullExpressionRAII IncScope(Info);
5281 case Stmt::DeclStmtClass: {
5284 const DeclStmt *DS = cast<DeclStmt>(S);
5285 for (
const auto *
D : DS->
decls()) {
5286 if (
const auto *VD = dyn_cast<VarDecl>(
D)) {
5289 if (VD->hasLocalStorage() && !VD->getInit())
5297 return ESR_CaseNotFound;
5301 return ESR_CaseNotFound;
5305 switch (S->getStmtClass()) {
5307 if (
const Expr *
E = dyn_cast<Expr>(S)) {
5316 FullExpressionRAII
Scope(Info);
5320 return ESR_Succeeded;
5323 Info.FFDiag(S->getBeginLoc()) << S->getSourceRange();
5326 case Stmt::NullStmtClass:
5327 return ESR_Succeeded;
5329 case Stmt::DeclStmtClass: {
5330 const DeclStmt *DS = cast<DeclStmt>(S);
5331 for (
const auto *
D : DS->
decls()) {
5332 const VarDecl *VD = dyn_cast_or_null<VarDecl>(
D);
5336 FullExpressionRAII
Scope(Info);
5339 if (!
Scope.destroy())
5342 return ESR_Succeeded;
5345 case Stmt::ReturnStmtClass: {
5346 const Expr *RetExpr = cast<ReturnStmt>(S)->getRetValue();
5347 FullExpressionRAII
Scope(Info);
5356 :
Evaluate(Result.Value, Info, RetExpr)))
5358 return Scope.destroy() ? ESR_Returned : ESR_Failed;
5361 case Stmt::CompoundStmtClass: {
5362 BlockScopeRAII
Scope(Info);
5365 for (
const auto *BI : CS->
body()) {
5366 EvalStmtResult ESR =
EvaluateStmt(Result, Info, BI, Case);
5367 if (ESR == ESR_Succeeded)
5369 else if (ESR != ESR_CaseNotFound) {
5370 if (ESR != ESR_Failed && !
Scope.destroy())
5376 return ESR_CaseNotFound;
5377 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5380 case Stmt::IfStmtClass: {
5381 const IfStmt *IS = cast<IfStmt>(S);
5384 BlockScopeRAII
Scope(Info);
5387 if (ESR != ESR_Succeeded) {
5388 if (ESR != ESR_Failed && !
Scope.destroy())
5398 if (!Info.InConstantContext)
5405 EvalStmtResult ESR =
EvaluateStmt(Result, Info, SubStmt);
5406 if (ESR != ESR_Succeeded) {
5407 if (ESR != ESR_Failed && !
Scope.destroy())
5412 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5415 case Stmt::WhileStmtClass: {
5416 const WhileStmt *WS = cast<WhileStmt>(S);
5418 BlockScopeRAII
Scope(Info);
5427 if (ESR != ESR_Continue) {
5428 if (ESR != ESR_Failed && !
Scope.destroy())
5432 if (!
Scope.destroy())
5435 return ESR_Succeeded;
5438 case Stmt::DoStmtClass: {
5439 const DoStmt *DS = cast<DoStmt>(S);
5443 if (ESR != ESR_Continue)
5452 FullExpressionRAII CondScope(Info);
5454 !CondScope.destroy())
5457 return ESR_Succeeded;
5460 case Stmt::ForStmtClass: {
5461 const ForStmt *FS = cast<ForStmt>(S);
5462 BlockScopeRAII ForScope(Info);
5463 if (FS->getInit()) {
5464 EvalStmtResult ESR =
EvaluateStmt(Result, Info, FS->getInit());
5465 if (ESR != ESR_Succeeded) {
5466 if (ESR != ESR_Failed && !ForScope.destroy())
5472 BlockScopeRAII IterScope(Info);
5473 bool Continue =
true;
5474 if (FS->getCond() && !
EvaluateCond(Info, FS->getConditionVariable(),
5475 FS->getCond(), Continue))
5481 if (ESR != ESR_Continue) {
5482 if (ESR != ESR_Failed && (!IterScope.destroy() || !ForScope.destroy()))
5487 if (
const auto *Inc = FS->getInc()) {
5488 if (Inc->isValueDependent()) {
5492 FullExpressionRAII IncScope(Info);
5498 if (!IterScope.destroy())
5501 return ForScope.destroy() ? ESR_Succeeded : ESR_Failed;
5504 case Stmt::CXXForRangeStmtClass: {
5506 BlockScopeRAII
Scope(Info);
5509 if (FS->getInit()) {
5510 EvalStmtResult ESR =
EvaluateStmt(Result, Info, FS->getInit());
5511 if (ESR != ESR_Succeeded) {
5512 if (ESR != ESR_Failed && !
Scope.destroy())
5519 EvalStmtResult ESR =
EvaluateStmt(Result, Info, FS->getRangeStmt());
5520 if (ESR != ESR_Succeeded) {
5521 if (ESR != ESR_Failed && !
Scope.destroy())
5528 if (!FS->getBeginStmt() || !FS->getEndStmt() || !FS->getCond())
5533 if (ESR != ESR_Succeeded) {
5534 if (ESR != ESR_Failed && !
Scope.destroy())
5539 if (ESR != ESR_Succeeded) {
5540 if (ESR != ESR_Failed && !
Scope.destroy())
5548 if (FS->getCond()->isValueDependent()) {
5553 bool Continue =
true;
5554 FullExpressionRAII CondExpr(Info);
5562 BlockScopeRAII InnerScope(Info);
5563 ESR =
EvaluateStmt(Result, Info, FS->getLoopVarStmt());
5564 if (ESR != ESR_Succeeded) {
5565 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
5572 if (ESR != ESR_Continue) {
5573 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
5577 if (FS->getInc()->isValueDependent()) {
5586 if (!InnerScope.destroy())
5590 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5593 case Stmt::SwitchStmtClass:
5596 case Stmt::ContinueStmtClass:
5597 return ESR_Continue;
5599 case Stmt::BreakStmtClass:
5602 case Stmt::LabelStmtClass:
5603 return EvaluateStmt(Result, Info, cast<LabelStmt>(S)->getSubStmt(), Case);
5605 case Stmt::AttributedStmtClass: {
5606 const auto *AS = cast<AttributedStmt>(S);
5607 const auto *SS = AS->getSubStmt();
5608 MSConstexprContextRAII ConstexprContext(
5609 *Info.CurrentCall, hasSpecificAttr<MSConstexprAttr>(AS->getAttrs()) &&
5610 isa<ReturnStmt>(SS));
5612 auto LO = Info.getCtx().getLangOpts();
5613 if (LO.CXXAssumptions && !LO.MSVCCompat) {
5614 for (
auto *
Attr : AS->getAttrs()) {
5615 auto *AA = dyn_cast<CXXAssumeAttr>(
Attr);
5619 auto *Assumption = AA->getAssumption();
5620 if (Assumption->isValueDependent())
5623 if (Assumption->HasSideEffects(Info.getCtx()))
5630 Info.CCEDiag(Assumption->getExprLoc(),
5631 diag::note_constexpr_assumption_failed);
5640 case Stmt::CaseStmtClass:
5641 case Stmt::DefaultStmtClass:
5642 return EvaluateStmt(Result, Info, cast<SwitchCase>(S)->getSubStmt(), Case);
5643 case Stmt::CXXTryStmtClass:
5645 return EvaluateStmt(Result, Info, cast<CXXTryStmt>(S)->getTryBlock(), Case);
5655 bool IsValueInitialization) {
5662 if (!CD->
isConstexpr() && !IsValueInitialization) {
5663 if (Info.getLangOpts().CPlusPlus11) {
5666 Info.CCEDiag(
Loc, diag::note_constexpr_invalid_function, 1)
5668 Info.Note(CD->
getLocation(), diag::note_declared_at);
5670 Info.CCEDiag(
Loc, diag::note_invalid_subexpr_in_const_expr);
5684 if (Info.checkingPotentialConstantExpression() && !
Definition &&
5692 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
5699 if (!Info.Ctx.getLangOpts().CPlusPlus20 && isa<CXXMethodDecl>(
Declaration) &&
5701 Info.CCEDiag(CallLoc, diag::note_constexpr_virtual_call);
5704 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
5710 (
Definition->isConstexpr() || (Info.CurrentCall->CanEvalMSConstexpr &&
5714 if (Info.getLangOpts().CPlusPlus11) {
5719 auto *CD = dyn_cast<CXXConstructorDecl>(DiagDecl);
5720 if (CD && CD->isInheritingConstructor()) {
5721 auto *Inherited = CD->getInheritedConstructor().getConstructor();
5722 if (!Inherited->isConstexpr())
5723 DiagDecl = CD = Inherited;
5729 if (CD && CD->isInheritingConstructor())
5730 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_inhctor, 1)
5731 << CD->getInheritedConstructor().getConstructor()->
getParent();
5733 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_function, 1)
5735 Info.Note(DiagDecl->
getLocation(), diag::note_declared_at);
5737 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
5743struct CheckDynamicTypeHandler {
5745 typedef bool result_type;
5746 bool failed() {
return false; }
5749 bool found(APFloat &
Value,
QualType SubobjType) {
return true; }
5757 if (This.Designator.Invalid)
5769 if (This.Designator.isOnePastTheEnd() ||
5770 This.Designator.isMostDerivedAnUnsizedArray()) {
5771 Info.FFDiag(
E, This.Designator.isOnePastTheEnd()
5772 ? diag::note_constexpr_access_past_end
5773 : diag::note_constexpr_access_unsized_array)
5776 }
else if (Polymorphic) {
5782 Info.Ctx.getLValueReferenceType(This.Designator.getType(Info.Ctx));
5783 Info.FFDiag(
E, diag::note_constexpr_polymorphic_unknown_dynamic_type)
5790 CheckDynamicTypeHandler Handler{AK};
5791 return Obj &&
findSubobject(Info,
E, Obj, This.Designator, Handler);
5813 unsigned PathLength) {
5814 assert(PathLength >=
Designator.MostDerivedPathLength && PathLength <=
5815 Designator.Entries.size() &&
"invalid path length");
5816 return (PathLength ==
Designator.MostDerivedPathLength)
5817 ?
Designator.MostDerivedType->getAsCXXRecordDecl()
5818 : getAsBaseClass(
Designator.Entries[PathLength - 1]);
5830 return std::nullopt;
5839 This.Designator.MostDerivedType->getAsCXXRecordDecl();
5842 return std::nullopt;
5850 for (
unsigned PathLength = This.Designator.MostDerivedPathLength;
5851 PathLength <=
Path.size(); ++PathLength) {
5852 switch (Info.isEvaluatingCtorDtor(This.getLValueBase(),
5853 Path.slice(0, PathLength))) {
5854 case ConstructionPhase::Bases:
5855 case ConstructionPhase::DestroyingBases:
5860 case ConstructionPhase::None:
5861 case ConstructionPhase::AfterBases:
5862 case ConstructionPhase::AfterFields:
5863 case ConstructionPhase::Destroying:
5875 return std::nullopt;
5893 unsigned PathLength = DynType->PathLength;
5894 for (; PathLength <= This.Designator.Entries.size(); ++PathLength) {
5897 Found->getCorrespondingMethodDeclaredInClass(
Class,
false);
5907 if (Callee->isPureVirtual()) {
5908 Info.FFDiag(
E, diag::note_constexpr_pure_virtual_call, 1) << Callee;
5909 Info.Note(Callee->getLocation(), diag::note_declared_at);
5915 if (!Info.Ctx.hasSameUnqualifiedType(Callee->getReturnType(),
5916 Found->getReturnType())) {
5917 CovariantAdjustmentPath.push_back(Callee->getReturnType());
5918 for (
unsigned CovariantPathLength = PathLength + 1;
5919 CovariantPathLength != This.Designator.Entries.size();
5920 ++CovariantPathLength) {
5924 Found->getCorrespondingMethodDeclaredInClass(NextClass,
false);
5925 if (Next && !Info.Ctx.hasSameUnqualifiedType(
5926 Next->getReturnType(), CovariantAdjustmentPath.back()))
5927 CovariantAdjustmentPath.push_back(Next->getReturnType());
5929 if (!Info.Ctx.hasSameUnqualifiedType(
Found->getReturnType(),
5930 CovariantAdjustmentPath.back()))
5931 CovariantAdjustmentPath.push_back(
Found->getReturnType());
5947 assert(Result.isLValue() &&
5948 "unexpected kind of APValue for covariant return");
5949 if (Result.isNullPointer())
5953 LVal.setFrom(Info.Ctx, Result);
5956 for (
unsigned I = 1; I !=
Path.size(); ++I) {
5958 assert(OldClass && NewClass &&
"unexpected kind of covariant return");
5959 if (OldClass != NewClass &&
5962 OldClass = NewClass;
5965 LVal.moveInto(Result);
5974 auto *BaseClass = BaseSpec.getType()->getAsCXXRecordDecl();
5976 return BaseSpec.getAccessSpecifier() ==
AS_public;
5978 llvm_unreachable(
"Base is not a direct base of Derived");
5988 SubobjectDesignator &
D = Ptr.Designator;
6000 std::optional<DynamicType> DynType =
6011 const CXXRecordDecl *
C =
E->getTypeAsWritten()->getPointeeCXXRecordDecl();
6012 assert(
C &&
"dynamic_cast target is not void pointer nor class");
6013 CanQualType CQT = Info.Ctx.getCanonicalType(Info.Ctx.getRecordType(
C));
6020 Ptr.setNull(Info.Ctx,
E->
getType());
6027 DynType->Type->isDerivedFrom(
C)))
6029 else if (!Paths || Paths->begin() == Paths->end())
6031 else if (Paths->isAmbiguous(CQT))
6034 assert(Paths->front().Access !=
AS_public &&
"why did the cast fail?");
6037 Info.FFDiag(
E, diag::note_constexpr_dynamic_cast_to_reference_failed)
6038 << DiagKind << Ptr.Designator.getType(Info.Ctx)
6039 << Info.Ctx.getRecordType(DynType->Type)
6047 for (
int PathLength = Ptr.Designator.Entries.size();
6048 PathLength >= (
int)DynType->PathLength; --PathLength) {
6053 if (PathLength > (
int)DynType->PathLength &&
6056 return RuntimeCheckFailed(
nullptr);
6063 if (DynType->Type->isDerivedFrom(
C, Paths) && !Paths.isAmbiguous(CQT) &&
6076 return RuntimeCheckFailed(&Paths);
6080struct StartLifetimeOfUnionMemberHandler {
6082 const Expr *LHSExpr;
6085 bool Failed =
false;
6088 typedef bool result_type;
6089 bool failed() {
return Failed; }
6105 }
else if (DuringInit) {
6109 Info.FFDiag(LHSExpr,
6110 diag::note_constexpr_union_member_change_during_init);
6119 llvm_unreachable(
"wrong value kind for union object");
6122 llvm_unreachable(
"wrong value kind for union object");
6127const AccessKinds StartLifetimeOfUnionMemberHandler::AccessKind;
6134 const Expr *LHSExpr,
6135 const LValue &LHS) {
6136 if (LHS.InvalidBase || LHS.Designator.Invalid)
6142 unsigned PathLength = LHS.Designator.Entries.size();
6143 for (
const Expr *
E = LHSExpr;
E !=
nullptr;) {
6145 if (
auto *ME = dyn_cast<MemberExpr>(
E)) {
6146 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
6149 if (!FD || FD->getType()->isReferenceType())
6153 if (FD->getParent()->isUnion()) {
6158 FD->getType()->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
6159 if (!RD || RD->hasTrivialDefaultConstructor())
6160 UnionPathLengths.push_back({PathLength - 1, FD});
6166 LHS.Designator.Entries[PathLength]
6167 .getAsBaseOrMember().getPointer()));
6171 }
else if (
auto *ASE = dyn_cast<ArraySubscriptExpr>(
E)) {
6173 auto *
Base = ASE->getBase()->IgnoreImplicit();
6174 if (!
Base->getType()->isArrayType())
6180 }
else if (
auto *ICE = dyn_cast<ImplicitCastExpr>(
E)) {
6182 E = ICE->getSubExpr();
6183 if (ICE->getCastKind() == CK_NoOp)
6185 if (ICE->getCastKind() != CK_DerivedToBase &&
6186 ICE->getCastKind() != CK_UncheckedDerivedToBase)
6190 if (Elt->isVirtual()) {
6199 LHS.Designator.Entries[PathLength]
6200 .getAsBaseOrMember().getPointer()));
6210 if (UnionPathLengths.empty())
6215 CompleteObject Obj =
6219 for (std::pair<unsigned, const FieldDecl *> LengthAndField :
6220 llvm::reverse(UnionPathLengths)) {
6222 SubobjectDesignator
D = LHS.Designator;
6223 D.truncate(Info.Ctx, LHS.Base, LengthAndField.first);
6225 bool DuringInit = Info.isEvaluatingCtorDtor(LHS.Base,
D.Entries) ==
6226 ConstructionPhase::AfterBases;
6227 StartLifetimeOfUnionMemberHandler StartLifetime{
6228 Info, LHSExpr, LengthAndField.second, DuringInit};
6237 CallRef
Call, EvalInfo &Info,
6245 APValue &
V = PVD ? Info.CurrentCall->createParam(
Call, PVD, LV)
6246 : Info.CurrentCall->createTemporary(Arg, Arg->
getType(),
6247 ScopeKind::Call, LV);
6253 if (
NonNull &&
V.isLValue() &&
V.isNullPointer()) {
6254 Info.CCEDiag(Arg, diag::note_non_null_attribute_failed);
6264 bool RightToLeft =
false) {
6266 llvm::SmallBitVector ForbiddenNullArgs;
6267 if (Callee->hasAttr<NonNullAttr>()) {
6268 ForbiddenNullArgs.resize(Args.size());
6269 for (
const auto *
Attr : Callee->specific_attrs<NonNullAttr>()) {
6270 if (!
Attr->args_size()) {
6271 ForbiddenNullArgs.set();
6274 for (
auto Idx :
Attr->args()) {
6275 unsigned ASTIdx = Idx.getASTIndex();
6276 if (ASTIdx >= Args.size())
6278 ForbiddenNullArgs[ASTIdx] =
true;
6282 for (
unsigned I = 0; I < Args.size(); I++) {
6283 unsigned Idx = RightToLeft ? Args.size() - I - 1 : I;
6285 Idx < Callee->getNumParams() ? Callee->getParamDecl(Idx) :
nullptr;
6286 bool NonNull = !ForbiddenNullArgs.empty() && ForbiddenNullArgs[Idx];
6290 if (!Info.noteFailure())
6302 bool CopyObjectRepresentation) {
6304 CallStackFrame *Frame = Info.CurrentCall;
6305 APValue *RefValue = Info.getParamSlot(Frame->Arguments, Param);
6313 RefLValue.setFrom(Info.Ctx, *RefValue);
6316 CopyObjectRepresentation);
6323 CallRef
Call,
const Stmt *Body, EvalInfo &Info,
6324 APValue &Result,
const LValue *ResultSlot) {
6325 if (!Info.CheckCallLimit(CallLoc))
6350 This->moveInto(Result);
6359 if (!Info.checkingPotentialConstantExpression())
6361 Frame.LambdaThisCaptureField);
6366 if (ESR == ESR_Succeeded) {
6367 if (Callee->getReturnType()->isVoidType())
6369 Info.FFDiag(Callee->getEndLoc(), diag::note_constexpr_no_return);
6371 return ESR == ESR_Returned;
6378 EvalInfo &Info,
APValue &Result) {
6380 if (!Info.CheckCallLimit(CallLoc))
6385 Info.FFDiag(CallLoc, diag::note_constexpr_virtual_base) << RD;
6389 EvalInfo::EvaluatingConstructorRAII EvalObj(
6391 ObjectUnderConstruction{This.getLValueBase(), This.Designator.Entries},
6403 if ((*I)->getInit()->isValueDependent()) {
6407 FullExpressionRAII InitScope(Info);
6409 !InitScope.destroy())
6432 if (!Result.hasValue()) {
6445 BlockScopeRAII LifetimeExtendedScope(Info);
6448 unsigned BasesSeen = 0;
6458 assert(
Indirect &&
"fields out of order?");
6464 assert(FieldIt != RD->
field_end() &&
"missing field?");
6465 if (!FieldIt->isUnnamedBitField())
6468 Result.getStructField(FieldIt->getFieldIndex()));
6473 LValue Subobject = This;
6474 LValue SubobjectParent = This;
6479 if (I->isBaseInitializer()) {
6480 QualType BaseType(I->getBaseClass(), 0);
6484 assert(!BaseIt->
isVirtual() &&
"virtual base for literal type");
6485 assert(Info.Ctx.hasSameUnqualifiedType(BaseIt->
getType(), BaseType) &&
6486 "base class initializers not in expected order");
6492 Value = &Result.getStructBase(BasesSeen++);
6493 }
else if ((FD = I->getMember())) {
6498 Value = &Result.getUnionValue();
6500 SkipToField(FD,
false);
6506 auto IndirectFieldChain = IFD->chain();
6507 for (
auto *
C : IndirectFieldChain) {
6508 FD = cast<FieldDecl>(
C);
6516 (
Value->isUnion() &&
Value->getUnionField() != FD)) {
6528 if (
C == IndirectFieldChain.back())
6529 SubobjectParent = Subobject;
6535 if (
C == IndirectFieldChain.front() && !RD->
isUnion())
6536 SkipToField(FD,
true);
6541 llvm_unreachable(
"unknown base initializer kind");
6548 if (
Init->isValueDependent()) {
6552 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &SubobjectParent,
6553 isa<CXXDefaultInitExpr>(
Init));
6554 FullExpressionRAII InitScope(Info);
6560 if (!Info.noteFailure())
6568 if (I->isBaseInitializer() && BasesSeen == RD->
getNumBases())
6569 EvalObj.finishedConstructingBases();
6574 for (; FieldIt != RD->
field_end(); ++FieldIt) {
6575 if (!FieldIt->isUnnamedBitField())
6578 Result.getStructField(FieldIt->getFieldIndex()));
6582 EvalObj.finishedConstructingFields();
6586 LifetimeExtendedScope.destroy();
6592 EvalInfo &Info,
APValue &Result) {
6593 CallScopeRAII CallScope(Info);
6599 CallScope.destroy();
6611 This.moveInto(Printable);
6613 diag::note_constexpr_destroy_out_of_lifetime)
6614 << Printable.
getAsString(Info.Ctx, Info.Ctx.getLValueReferenceType(
T));
6630 LValue ElemLV = This;
6631 ElemLV.addArray(Info, &LocE, CAT);
6638 if (Size && Size >
Value.getArrayInitializedElts())
6641 for (; Size != 0; --Size) {
6642 APValue &Elem =
Value.getArrayInitializedElt(Size - 1);
6655 if (
T.isDestructedType()) {
6657 diag::note_constexpr_unsupported_destruction)
6667 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_virtual_base) << RD;
6692 if (!Info.CheckCallLimit(CallRange.
getBegin()))
6701 CallStackFrame Frame(Info, CallRange,
Definition, &This,
nullptr,
6706 EvalInfo::EvaluatingDestructorRAII EvalObj(
6708 ObjectUnderConstruction{This.getLValueBase(), This.Designator.Entries});
6709 if (!EvalObj.DidInsert) {
6716 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_double_destroy);
6736 for (
const FieldDecl *FD : llvm::reverse(Fields)) {
6737 if (FD->isUnnamedBitField())
6740 LValue Subobject = This;
6744 APValue *SubobjectValue = &
Value.getStructField(FD->getFieldIndex());
6751 EvalObj.startedDestroyingBases();
6758 LValue Subobject = This;
6763 APValue *SubobjectValue = &
Value.getStructBase(BasesLeft);
6768 assert(BasesLeft == 0 &&
"NumBases was wrong?");
6776struct DestroyObjectHandler {
6782 typedef bool result_type;
6783 bool failed() {
return false; }
6789 Info.FFDiag(
E, diag::note_constexpr_destroy_complex_elem);
6793 Info.FFDiag(
E, diag::note_constexpr_destroy_complex_elem);
6802 const LValue &This,
QualType ThisType) {
6804 DestroyObjectHandler Handler = {Info,
E, This,
AK_Destroy};
6805 return Obj &&
findSubobject(Info,
E, Obj, This.Designator, Handler);
6814 if (Info.EvalStatus.HasSideEffects)
6825 if (Info.checkingPotentialConstantExpression() ||
6826 Info.SpeculativeEvaluationDepth)
6830 auto Caller = Info.getStdAllocatorCaller(
"allocate");
6832 Info.FFDiag(
E->
getExprLoc(), Info.getLangOpts().CPlusPlus20
6833 ? diag::note_constexpr_new_untyped
6834 : diag::note_constexpr_new);
6838 QualType ElemType = Caller.ElemType;
6841 diag::note_constexpr_new_not_complete_object_type)
6849 bool IsNothrow =
false;
6850 for (
unsigned I = 1, N =
E->getNumArgs(); I != N; ++I) {
6858 APInt Size, Remainder;
6859 APInt ElemSizeAP(ByteSize.getBitWidth(), ElemSize.
getQuantity());
6860 APInt::udivrem(ByteSize, ElemSizeAP, Size, Remainder);
6861 if (Remainder != 0) {
6863 Info.FFDiag(
E->
getExprLoc(), diag::note_constexpr_operator_new_bad_size)
6864 << ByteSize <<
APSInt(ElemSizeAP,
true) << ElemType;
6868 if (!Info.CheckArraySize(
E->
getBeginLoc(), ByteSize.getActiveBits(),
6869 Size.getZExtValue(), !IsNothrow)) {
6871 Result.setNull(Info.Ctx,
E->
getType());
6877 QualType AllocType = Info.Ctx.getConstantArrayType(
6878 ElemType, Size,
nullptr, ArraySizeModifier::Normal, 0);
6879 APValue *Val = Info.createHeapAlloc(
E, AllocType, Result);
6881 Result.addArray(Info,
E, cast<ConstantArrayType>(AllocType));
6888 return DD->isVirtual();
6895 return DD->isVirtual() ? DD->getOperatorDelete() :
nullptr;
6906 DynAlloc::Kind DeallocKind) {
6907 auto PointerAsString = [&] {
6908 return Pointer.toString(Info.Ctx, Info.Ctx.VoidPtrTy);
6913 Info.FFDiag(
E, diag::note_constexpr_delete_not_heap_alloc)
6914 << PointerAsString();
6917 return std::nullopt;
6920 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
6922 Info.FFDiag(
E, diag::note_constexpr_double_delete);
6923 return std::nullopt;
6926 if (DeallocKind != (*Alloc)->getKind()) {
6928 Info.FFDiag(
E, diag::note_constexpr_new_delete_mismatch)
6929 << DeallocKind << (*Alloc)->getKind() << AllocType;
6931 return std::nullopt;
6934 bool Subobject =
false;
6935 if (DeallocKind == DynAlloc::New) {
6936 Subobject =
Pointer.Designator.MostDerivedPathLength != 0 ||
6937 Pointer.Designator.isOnePastTheEnd();
6939 Subobject =
Pointer.Designator.Entries.size() != 1 ||
6940 Pointer.Designator.Entries[0].getAsArrayIndex() != 0;
6943 Info.FFDiag(
E, diag::note_constexpr_delete_subobject)
6944 << PointerAsString() <<
Pointer.Designator.isOnePastTheEnd();
6945 return std::nullopt;
6953 if (Info.checkingPotentialConstantExpression() ||
6954 Info.SpeculativeEvaluationDepth)
6958 if (!Info.getStdAllocatorCaller(
"deallocate")) {
6966 for (
unsigned I = 1, N =
E->getNumArgs(); I != N; ++I)
6969 if (
Pointer.Designator.Invalid)
6974 if (
Pointer.isNullPointer()) {
6975 Info.CCEDiag(
E->
getExprLoc(), diag::note_constexpr_deallocate_null);
6991class BitCastBuffer {
6999 static_assert(std::numeric_limits<unsigned char>::digits >= 8,
7000 "Need at least 8 bit unsigned char");
7002 bool TargetIsLittleEndian;
7005 BitCastBuffer(
CharUnits Width,
bool TargetIsLittleEndian)
7006 : Bytes(Width.getQuantity()),
7007 TargetIsLittleEndian(TargetIsLittleEndian) {}
7011 for (
CharUnits I = Offset,
E = Offset + Width; I !=
E; ++I) {
7014 if (!Bytes[I.getQuantity()])
7016 Output.push_back(*Bytes[I.getQuantity()]);
7018 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
7019 std::reverse(Output.begin(), Output.end());
7024 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
7025 std::reverse(Input.begin(), Input.end());
7028 for (
unsigned char Byte : Input) {
7029 assert(!Bytes[Offset.getQuantity() + Index] &&
"overwriting a byte?");
7030 Bytes[Offset.getQuantity() + Index] = Byte;
7035 size_t size() {
return Bytes.size(); }
7040class APValueToBufferConverter {
7042 BitCastBuffer Buffer;
7045 APValueToBufferConverter(EvalInfo &Info,
CharUnits ObjectWidth,
7048 Buffer(ObjectWidth, Info.Ctx.getTargetInfo().isLittleEndian()),
7057 assert((
size_t)Offset.getQuantity() <= Buffer.size());
7070 return visitInt(Val.
getInt(), Ty, Offset);
7072 return visitFloat(Val.
getFloat(), Ty, Offset);
7074 return visitArray(Val, Ty, Offset);
7076 return visitRecord(Val, Ty, Offset);
7078 return visitVector(Val, Ty, Offset);
7089 diag::note_constexpr_bit_cast_unsupported_type)
7095 llvm_unreachable(
"LValue subobject in bit_cast?");
7097 llvm_unreachable(
"Unhandled APValue::ValueKind");
7105 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
7106 for (
size_t I = 0,
E = CXXRD->getNumBases(); I !=
E; ++I) {
7117 unsigned FieldIdx = 0;
7119 if (FD->isBitField()) {
7121 diag::note_constexpr_bit_cast_unsupported_bitfield);
7127 assert(FieldOffsetBits % Info.Ctx.getCharWidth() == 0 &&
7128 "only bit-fields can have sub-char alignment");
7130 Info.Ctx.toCharUnitsFromBits(FieldOffsetBits) + Offset;
7150 for (
unsigned I = 0; I != NumInitializedElts; ++I) {
7152 if (!visit(SubObj, CAT->
getElementType(), Offset + I * ElemWidth))
7159 for (
unsigned I = NumInitializedElts; I != ArraySize; ++I) {
7160 if (!visit(Filler, CAT->
getElementType(), Offset + I * ElemWidth))
7175 if ((NElts * EltSize) % Info.Ctx.getCharWidth() != 0) {
7181 diag::note_constexpr_bit_cast_invalid_vector)
7183 << Info.Ctx.getCharWidth();
7187 if (EltTy->isRealFloatingType() && &Info.Ctx.getFloatTypeSemantics(EltTy) ==
7188 &APFloat::x87DoubleExtended()) {
7193 diag::note_constexpr_bit_cast_unsupported_type)
7207 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
7209 llvm::APInt Res = llvm::APInt::getZero(NElts);
7210 for (
unsigned I = 0; I < NElts; ++I) {
7212 assert(EltAsInt.isUnsigned() && EltAsInt.getBitWidth() == 1 &&
7213 "bool vector element must be 1-bit unsigned integer!");
7215 Res.insertBits(EltAsInt, BigEndian ? (NElts - I - 1) : I);
7219 llvm::StoreIntToMemory(Res, &*Bytes.begin(), NElts / 8);
7220 Buffer.writeObject(Offset, Bytes);
7224 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
7225 for (
unsigned I = 0; I < NElts; ++I) {
7226 if (!visit(Val.
getVectorElt(I), EltTy, Offset + I * EltSizeChars))
7235 APSInt AdjustedVal = Val;
7236 unsigned Width = AdjustedVal.getBitWidth();
7238 Width = Info.Ctx.getTypeSize(Ty);
7239 AdjustedVal = AdjustedVal.extend(Width);
7243 llvm::StoreIntToMemory(AdjustedVal, &*Bytes.begin(), Width / 8);
7244 Buffer.writeObject(Offset, Bytes);
7249 APSInt AsInt(Val.bitcastToAPInt());
7250 return visitInt(AsInt, Ty, Offset);
7254 static std::optional<BitCastBuffer>
7257 APValueToBufferConverter Converter(Info, DstSize, BCE);
7259 return std::nullopt;
7260 return Converter.Buffer;
7265class BufferToAPValueConverter {
7267 const BitCastBuffer &Buffer;
7270 BufferToAPValueConverter(EvalInfo &Info,
const BitCastBuffer &Buffer,
7272 : Info(Info), Buffer(Buffer), BCE(BCE) {}
7277 std::nullopt_t unsupportedType(
QualType Ty) {
7279 diag::note_constexpr_bit_cast_unsupported_type)
7281 return std::nullopt;
7284 std::nullopt_t unrepresentableValue(
QualType Ty,
const APSInt &Val) {
7286 diag::note_constexpr_bit_cast_unrepresentable_value)
7288 return std::nullopt;
7292 const EnumType *EnumSugar =
nullptr) {
7306 const llvm::fltSemantics &Semantics =
7307 Info.Ctx.getFloatTypeSemantics(
QualType(
T, 0));
7308 unsigned NumBits = llvm::APFloatBase::getSizeInBits(Semantics);
7309 assert(NumBits % 8 == 0);
7316 if (!Buffer.readObject(Offset,
SizeOf, Bytes)) {
7319 bool IsStdByte = EnumSugar && EnumSugar->isStdByteType();
7323 if (!IsStdByte && !IsUChar) {
7324 QualType DisplayType(EnumSugar ? (
const Type *)EnumSugar :
T, 0);
7326 diag::note_constexpr_bit_cast_indet_dest)
7327 << DisplayType << Info.Ctx.getLangOpts().CharIsSigned;
7328 return std::nullopt;
7334 APSInt Val(
SizeOf.getQuantity() * Info.Ctx.getCharWidth(),
true);
7335 llvm::LoadIntFromMemory(Val, &*Bytes.begin(), Bytes.size());
7340 unsigned IntWidth = Info.Ctx.getIntWidth(
QualType(
T, 0));
7341 if (IntWidth != Val.getBitWidth()) {
7342 APSInt Truncated = Val.trunc(IntWidth);
7343 if (Truncated.extend(Val.getBitWidth()) != Val)
7344 return unrepresentableValue(
QualType(
T, 0), Val);
7352 const llvm::fltSemantics &Semantics =
7353 Info.Ctx.getFloatTypeSemantics(
QualType(
T, 0));
7364 unsigned NumBases = 0;
7365 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
7366 NumBases = CXXRD->getNumBases();
7372 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
7373 for (
size_t I = 0,
E = CXXRD->getNumBases(); I !=
E; ++I) {
7377 std::optional<APValue> SubObj = visitType(
7380 return std::nullopt;
7381 ResultVal.getStructBase(I) = *SubObj;
7386 unsigned FieldIdx = 0;
7390 if (FD->isBitField()) {
7392 diag::note_constexpr_bit_cast_unsupported_bitfield);
7393 return std::nullopt;
7397 assert(FieldOffsetBits % Info.Ctx.getCharWidth() == 0);
7403 std::optional<APValue> SubObj = visitType(FieldTy, FieldOffset);
7405 return std::nullopt;
7406 ResultVal.getStructField(FieldIdx) = *SubObj;
7415 assert(!RepresentationType.
isNull() &&
7416 "enum forward decl should be caught by Sema");
7417 const auto *AsBuiltin =
7421 return visit(AsBuiltin, Offset, Ty);
7429 for (
size_t I = 0; I !=
Size; ++I) {
7430 std::optional<APValue> ElementValue =
7433 return std::nullopt;
7434 ArrayValue.getArrayInitializedElt(I) = std::move(*ElementValue);
7446 if ((NElts * EltSize) % Info.Ctx.getCharWidth() != 0) {
7452 diag::note_constexpr_bit_cast_invalid_vector)
7453 <<
QualType(VTy, 0) << EltSize << NElts << Info.Ctx.getCharWidth();
7454 return std::nullopt;
7458 &APFloat::x87DoubleExtended()) {
7463 diag::note_constexpr_bit_cast_unsupported_type)
7465 return std::nullopt;
7469 Elts.reserve(NElts);
7479 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
7482 Bytes.reserve(NElts / 8);
7484 return std::nullopt;
7486 APSInt SValInt(NElts,
true);
7487 llvm::LoadIntFromMemory(SValInt, &*Bytes.begin(), Bytes.size());
7489 for (
unsigned I = 0; I < NElts; ++I) {
7491 SValInt.extractBits(1, (BigEndian ? NElts - I - 1 : I) * EltSize);
7498 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
7499 for (
unsigned I = 0; I < NElts; ++I) {
7500 std::optional<APValue> EltValue =
7501 visitType(EltTy, Offset + I * EltSizeChars);
7503 return std::nullopt;
7504 Elts.push_back(std::move(*EltValue));
7508 return APValue(Elts.data(), Elts.size());
7511 std::optional<APValue> visit(
const Type *Ty,
CharUnits Offset) {
7512 return unsupportedType(
QualType(Ty, 0));
7519#define TYPE(Class, Base) \
7521 return visit(cast<Class##Type>(Can.getTypePtr()), Offset);
7522#define ABSTRACT_TYPE(Class, Base)
7523#define NON_CANONICAL_TYPE(Class, Base) \
7525 llvm_unreachable("non-canonical type should be impossible!");
7526#define DEPENDENT_TYPE(Class, Base) \
7529 "dependent types aren't supported in the constant evaluator!");
7530#define NON_CANONICAL_UNLESS_DEPENDENT(Class, Base) \
7532 llvm_unreachable("either dependent or not canonical!");
7533#include "clang/AST/TypeNodes.inc"
7535 llvm_unreachable(
"Unhandled Type::TypeClass");
7540 static std::optional<APValue> convert(EvalInfo &Info, BitCastBuffer &Buffer,
7542 BufferToAPValueConverter Converter(Info, Buffer, BCE);
7550 bool CheckingDest) {
7553 auto diag = [&](
int Reason) {
7555 Info->FFDiag(
Loc, diag::note_constexpr_bit_cast_invalid_type)
7556 << CheckingDest << (Reason == 4) << Reason;
7561 Info->
Note(NoteLoc, diag::note_constexpr_bit_cast_invalid_subtype)
7562 << NoteTy << Construct << Ty;
7576 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(
Record)) {
7578 if (!checkBitCastConstexprEligibilityType(
Loc, BS.
getType(), Info, Ctx,
7583 if (FD->getType()->isReferenceType())
7585 if (!checkBitCastConstexprEligibilityType(
Loc, FD->getType(), Info, Ctx,
7587 return note(0, FD->getType(), FD->getBeginLoc());
7593 Info, Ctx, CheckingDest))
7599static bool checkBitCastConstexprEligibility(EvalInfo *Info,
7602 bool DestOK = checkBitCastConstexprEligibilityType(
7604 bool SourceOK = DestOK && checkBitCastConstexprEligibilityType(
7610static bool handleRValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
7613 assert(
CHAR_BIT == 8 && Info.Ctx.getTargetInfo().getCharWidth() == 8 &&
7614 "no host or target supports non 8-bit chars");
7616 if (!checkBitCastConstexprEligibility(&Info, Info.Ctx, BCE))
7620 std::optional<BitCastBuffer> Buffer =
7621 APValueToBufferConverter::convert(Info, SourceRValue, BCE);
7626 std::optional<APValue> MaybeDestValue =
7627 BufferToAPValueConverter::convert(Info, *Buffer, BCE);
7628 if (!MaybeDestValue)
7631 DestValue = std::move(*MaybeDestValue);
7635static bool handleLValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
7638 assert(
CHAR_BIT == 8 && Info.Ctx.getTargetInfo().getCharWidth() == 8 &&
7639 "no host or target supports non 8-bit chars");
7641 "LValueToRValueBitcast requires an lvalue operand!");
7643 LValue SourceLValue;
7645 SourceLValue.setFrom(Info.Ctx, SourceValue);
7648 SourceRValue,
true))
7651 return handleRValueToRValueBitCast(Info, DestValue, SourceRValue, BCE);
7654template <
class Derived>
7655class ExprEvaluatorBase
7658 Derived &getDerived() {
return static_cast<Derived&
>(*this); }
7660 return getDerived().Success(
V,
E);
7662 bool DerivedZeroInitialization(
const Expr *
E) {
7663 return getDerived().ZeroInitialization(
E);
7669 template<
typename ConditionalOperator>
7671 assert(Info.checkingPotentialConstantExpression());
7676 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
7677 StmtVisitorTy::Visit(
E->getFalseExpr());
7683 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
7685 StmtVisitorTy::Visit(
E->getTrueExpr());
7690 Error(
E, diag::note_constexpr_conditional_never_const);
7694 template<
typename ConditionalOperator>
7698 if (Info.checkingPotentialConstantExpression() && Info.noteFailure()) {
7699 CheckPotentialConstantConditional(
E);
7702 if (Info.noteFailure()) {
7703 StmtVisitorTy::Visit(
E->getTrueExpr());
7704 StmtVisitorTy::Visit(
E->getFalseExpr());
7709 Expr *EvalExpr = BoolResult ?
E->getTrueExpr() :
E->getFalseExpr();
7710 return StmtVisitorTy::Visit(EvalExpr);
7716 typedef ExprEvaluatorBase ExprEvaluatorBaseTy;
7719 return Info.CCEDiag(
E,
D);
7722 bool ZeroInitialization(
const Expr *
E) {
return Error(
E); }
7724 bool IsConstantEvaluatedBuiltinCall(
const CallExpr *
E) {
7725 unsigned BuiltinOp =
E->getBuiltinCallee();
7726 return BuiltinOp != 0 &&
7727 Info.Ctx.BuiltinInfo.isConstantEvaluated(BuiltinOp);
7731 ExprEvaluatorBase(EvalInfo &Info) : Info(Info) {}
7733 EvalInfo &getEvalInfo() {
return Info; }
7742 return Error(
E, diag::note_invalid_subexpr_in_const_expr);
7745 bool VisitStmt(
const Stmt *) {
7746 llvm_unreachable(
"Expression evaluator should not be called on stmts");
7748 bool VisitExpr(
const Expr *
E) {
7753 const auto It =
E->begin();
7754 return StmtVisitorTy::Visit(*It);
7758 return StmtVisitorTy::Visit(
E->getFunctionName());
7761 if (
E->hasAPValueResult())
7762 return DerivedSuccess(
E->getAPValueResult(),
E);
7764 return StmtVisitorTy::Visit(
E->getSubExpr());
7768 {
return StmtVisitorTy::Visit(
E->getSubExpr()); }
7770 {
return StmtVisitorTy::Visit(
E->getSubExpr()); }
7772 {
return StmtVisitorTy::Visit(
E->getSubExpr()); }
7774 {
return StmtVisitorTy::Visit(
E->getChosenSubExpr()); }
7776 {
return StmtVisitorTy::Visit(
E->getResultExpr()); }
7778 {
return StmtVisitorTy::Visit(
E->getReplacement()); }
7780 TempVersionRAII RAII(*Info.CurrentCall);
7781 SourceLocExprScopeGuard Guard(
E, Info.CurrentCall->CurSourceLocExprScope);
7782 return StmtVisitorTy::Visit(
E->getExpr());
7785 TempVersionRAII RAII(*Info.CurrentCall);
7789 SourceLocExprScopeGuard Guard(
E, Info.CurrentCall->CurSourceLocExprScope);
7790 return StmtVisitorTy::Visit(
E->getExpr());
7794 FullExpressionRAII
Scope(Info);
7795 return StmtVisitorTy::Visit(
E->getSubExpr()) &&
Scope.destroy();
7801 return StmtVisitorTy::Visit(
E->getSubExpr());
7805 CCEDiag(
E, diag::note_constexpr_invalid_cast) << 0;
7806 return static_cast<Derived*
>(
this)->VisitCastExpr(
E);
7809 if (!Info.Ctx.getLangOpts().CPlusPlus20)
7810 CCEDiag(
E, diag::note_constexpr_invalid_cast) << 1;
7811 return static_cast<Derived*
>(
this)->VisitCastExpr(
E);
7814 return static_cast<Derived*
>(
this)->VisitCastExpr(
E);
7818 switch (
E->getOpcode()) {
7823 VisitIgnoredValue(
E->getLHS());
7824 return StmtVisitorTy::Visit(
E->getRHS());
7834 return DerivedSuccess(Result,
E);
7840 return StmtVisitorTy::Visit(
E->getSemanticForm());
7847 if (!
Evaluate(Info.CurrentCall->createTemporary(
7848 E->getOpaqueValue(),
7849 getStorageType(Info.Ctx,
E->getOpaqueValue()),
7850 ScopeKind::FullExpression, CommonLV),
7851 Info,
E->getCommon()))
7854 return HandleConditionalOperator(
E);
7858 bool IsBcpCall =
false;
7865 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
7872 if (Info.checkingPotentialConstantExpression() && IsBcpCall)
7875 FoldConstant Fold(Info, IsBcpCall);
7876 if (!HandleConditionalOperator(
E)) {
7877 Fold.keepDiagnostics();
7885 if (
APValue *
Value = Info.CurrentCall->getCurrentTemporary(
E);
7887 return DerivedSuccess(*
Value,
E);
7889 const Expr *Source =
E->getSourceExpr();
7893 assert(0 &&
"OpaqueValueExpr recursively refers to itself");
7896 return StmtVisitorTy::Visit(Source);
7900 for (
const Expr *SemE :
E->semantics()) {
7901 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
7905 if (SemE ==
E->getResultExpr())
7910 if (OVE->isUnique())
7914 if (!
Evaluate(Info.CurrentCall->createTemporary(
7915 OVE, getStorageType(Info.Ctx, OVE),
7916 ScopeKind::FullExpression, LV),
7917 Info, OVE->getSourceExpr()))
7919 }
else if (SemE ==
E->getResultExpr()) {
7920 if (!StmtVisitorTy::Visit(SemE))
7932 if (!handleCallExpr(
E, Result,
nullptr))
7934 return DerivedSuccess(Result,
E);
7938 const LValue *ResultSlot) {
7939 CallScopeRAII CallScope(Info);
7945 LValue *
This =
nullptr, ThisVal;
7947 bool HasQualifier =
false;
7954 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(Callee)) {
7958 Member = dyn_cast<CXXMethodDecl>(ME->getMemberDecl());
7960 return Error(Callee);
7962 HasQualifier = ME->hasQualifier();
7963 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(Callee)) {
7969 Member = dyn_cast<CXXMethodDecl>(
D);
7971 return Error(Callee);
7973 }
else if (
const auto *PDE = dyn_cast<CXXPseudoDestructorExpr>(Callee)) {
7974 if (!Info.getLangOpts().CPlusPlus20)
7975 Info.CCEDiag(PDE, diag::note_constexpr_pseudo_destructor);
7979 return Error(Callee);
7986 if (!CalleeLV.getLValueOffset().isZero())
7987 return Error(Callee);
7988 if (CalleeLV.isNullPointer()) {
7989 Info.FFDiag(Callee, diag::note_constexpr_null_callee)
7993 FD = dyn_cast_or_null<FunctionDecl>(
7994 CalleeLV.getLValueBase().dyn_cast<
const ValueDecl *>());
7996 return Error(Callee);
7999 if (!Info.Ctx.hasSameFunctionTypeIgnoringExceptionSpec(
8006 auto *OCE = dyn_cast<CXXOperatorCallExpr>(
E);
8007 if (OCE && OCE->isAssignmentOp()) {
8008 assert(Args.size() == 2 &&
"wrong number of arguments in assignment");
8009 Call = Info.CurrentCall->createCall(FD);
8010 bool HasThis =
false;
8011 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FD))
8012 HasThis = MD->isImplicitObjectMemberFunction();
8040 if (Info.getLangOpts().CPlusPlus20 && OCE &&
8041 OCE->getOperator() == OO_Equal && MD->
isTrivial() &&
8045 Args = Args.slice(1);
8054 "Number of captures must be zero for conversion to function-ptr");
8065 "A generic lambda's static-invoker function must be a "
8066 "template specialization");
8070 void *InsertPos =
nullptr;
8073 assert(CorrespondingCallOpSpecialization &&
8074 "We must always have a function call operator specialization "
8075 "that corresponds to our static invoker specialization");
8076 assert(isa<CXXMethodDecl>(CorrespondingCallOpSpecialization));
8077 FD = CorrespondingCallOpSpecialization;
8086 Ptr.moveInto(Result);
8087 return CallScope.destroy();
8097 Call = Info.CurrentCall->createCall(FD);
8104 auto *NamedMember = dyn_cast<CXXMethodDecl>(FD);
8105 if (NamedMember && NamedMember->isVirtual() && !HasQualifier) {
8108 CovariantAdjustmentPath);
8111 }
else if (NamedMember && NamedMember->isImplicitObjectMemberFunction()) {
8121 if (
auto *DD = dyn_cast<CXXDestructorDecl>(FD)) {
8122 assert(This &&
"no 'this' pointer for destructor call");
8124 Info.Ctx.getRecordType(DD->getParent())) &&
8125 CallScope.destroy();
8133 Body, Info, Result, ResultSlot))
8136 if (!CovariantAdjustmentPath.empty() &&
8138 CovariantAdjustmentPath))
8141 return CallScope.destroy();
8145 return StmtVisitorTy::Visit(
E->getInitializer());
8148 if (
E->getNumInits() == 0)
8149 return DerivedZeroInitialization(
E);
8150 if (
E->getNumInits() == 1)
8151 return StmtVisitorTy::Visit(
E->getInit(0));
8155 return DerivedZeroInitialization(
E);
8158 return DerivedZeroInitialization(
E);
8161 return DerivedZeroInitialization(
E);
8166 assert(!Info.Ctx.getLangOpts().CPlusPlus11 &&
8167 "missing temporary materialization conversion");
8168 assert(!
E->isArrow() &&
"missing call to bound member function?");
8176 const FieldDecl *FD = dyn_cast<FieldDecl>(
E->getMemberDecl());
8177 if (!FD)
return Error(
E);
8191 DerivedSuccess(Result,
E);
8201 E->getEncodedElementAccess(Indices);
8202 if (Indices.size() == 1) {
8208 for (
unsigned I = 0; I < Indices.size(); ++I) {
8211 APValue VecResult(Elts.data(), Indices.size());
8212 return DerivedSuccess(VecResult,
E);
8220 switch (
E->getCastKind()) {
8224 case CK_AtomicToNonAtomic: {
8229 if (!
Evaluate(AtomicVal, Info,
E->getSubExpr()))
8231 return DerivedSuccess(AtomicVal,
E);
8235 case CK_UserDefinedConversion:
8236 return StmtVisitorTy::Visit(
E->getSubExpr());
8238 case CK_LValueToRValue: {
8247 return DerivedSuccess(RVal,
E);
8249 case CK_LValueToRValueBitCast: {
8250 APValue DestValue, SourceValue;
8251 if (!
Evaluate(SourceValue, Info,
E->getSubExpr()))
8253 if (!handleLValueToRValueBitCast(Info, DestValue, SourceValue,
E))
8255 return DerivedSuccess(DestValue,
E);
8258 case CK_AddressSpaceConversion: {
8262 return DerivedSuccess(
Value,
E);
8270 return VisitUnaryPostIncDec(UO);
8273 return VisitUnaryPostIncDec(UO);
8276 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
8286 return DerivedSuccess(RVal, UO);
8299 BlockScopeRAII
Scope(Info);
8304 const Expr *FinalExpr = dyn_cast<Expr>(*BI);
8306 Info.FFDiag((*BI)->getBeginLoc(),
8307 diag::note_constexpr_stmt_expr_unsupported);
8310 return this->Visit(FinalExpr) &&
Scope.destroy();
8316 if (ESR != ESR_Succeeded) {
8320 if (ESR != ESR_Failed)
8321 Info.FFDiag((*BI)->getBeginLoc(),
8322 diag::note_constexpr_stmt_expr_unsupported);
8327 llvm_unreachable(
"Return from function from the loop above.");
8331 return StmtVisitorTy::Visit(
E->getSelectedExpr());
8335 void VisitIgnoredValue(
const Expr *
E) {
8340 void VisitIgnoredBaseExpression(
const Expr *
E) {
8345 VisitIgnoredValue(
E);
8355template<
class Derived>
8356class LValueExprEvaluatorBase
8357 :
public ExprEvaluatorBase<Derived> {
8361 typedef LValueExprEvaluatorBase LValueExprEvaluatorBaseTy;
8362 typedef ExprEvaluatorBase<Derived> ExprEvaluatorBaseTy;
8369 bool evaluatePointer(
const Expr *
E, LValue &Result) {
8374 LValueExprEvaluatorBase(EvalInfo &Info, LValue &Result,
bool InvalidBaseOK)
8375 : ExprEvaluatorBaseTy(Info), Result(Result),
8376 InvalidBaseOK(InvalidBaseOK) {}
8379 Result.setFrom(this->Info.Ctx,
V);
8388 EvalOK = evaluatePointer(
E->getBase(), Result);
8395 EvalOK = this->Visit(
E->getBase());
8401 Result.setInvalid(
E);
8406 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(
E->getMemberDecl())) {
8429 switch (
E->getOpcode()) {
8431 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
8440 switch (
E->getCastKind()) {
8442 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
8444 case CK_DerivedToBase:
8445 case CK_UncheckedDerivedToBase:
8446 if (!this->Visit(
E->getSubExpr()))
8492class LValueExprEvaluator
8493 :
public LValueExprEvaluatorBase<LValueExprEvaluator> {
8495 LValueExprEvaluator(EvalInfo &Info, LValue &Result,
bool InvalidBaseOK) :
8496 LValueExprEvaluatorBaseTy(Info, Result, InvalidBaseOK) {}
8516 return VisitUnaryPreIncDec(UO);
8519 return VisitUnaryPreIncDec(UO);
8525 switch (
E->getCastKind()) {
8527 return LValueExprEvaluatorBaseTy::VisitCastExpr(
E);
8529 case CK_LValueBitCast:
8530 this->CCEDiag(
E, diag::note_constexpr_invalid_cast)
8531 << 2 << Info.Ctx.getLangOpts().CPlusPlus;
8532 if (!Visit(
E->getSubExpr()))
8534 Result.Designator.setInvalid();
8537 case CK_BaseToDerived:
8538 if (!Visit(
E->getSubExpr()))
8543 if (!Visit(
E->getSubExpr()))
8554 bool LValueToRValueConversion) {
8558 assert(Info.CurrentCall->This ==
nullptr &&
8559 "This should not be set for a static call operator");
8567 if (Self->getType()->isReferenceType()) {
8568 APValue *RefValue = Info.getParamSlot(Info.CurrentCall->Arguments, Self);
8569 Result.setFrom(Info.Ctx, *RefValue);
8571 const ParmVarDecl *VD = Info.CurrentCall->Arguments.getOrigParam(Self);
8572 CallStackFrame *Frame =
8573 Info.getCallFrameAndDepth(Info.CurrentCall->Arguments.CallIndex)
8575 unsigned Version = Info.CurrentCall->Arguments.Version;
8576 Result.set({VD, Frame->Index, Version});
8579 Result = *Info.CurrentCall->This;
8589 if (LValueToRValueConversion) {
8593 Result.setFrom(Info.Ctx, RVal);
8604 bool InvalidBaseOK) {
8608 return LValueExprEvaluator(Info, Result, InvalidBaseOK).Visit(
E);
8611bool LValueExprEvaluator::VisitDeclRefExpr(
const DeclRefExpr *
E) {
8615 return Success(cast<ValueDecl>(
D));
8616 if (
const VarDecl *VD = dyn_cast<VarDecl>(
D))
8617 return VisitVarDecl(
E, VD);
8619 return Visit(BD->getBinding());
8624bool LValueExprEvaluator::VisitVarDecl(
const Expr *
E,
const VarDecl *VD) {
8631 isa<DeclRefExpr>(
E) &&
8632 cast<DeclRefExpr>(
E)->refersToEnclosingVariableOrCapture()) {
8637 if (Info.checkingPotentialConstantExpression())
8640 if (
auto *FD = Info.CurrentCall->LambdaCaptureFields.lookup(VD)) {
8641 const auto *MD = cast<CXXMethodDecl>(Info.CurrentCall->Callee);
8647 CallStackFrame *Frame =
nullptr;
8648 unsigned Version = 0;
8656 CallStackFrame *CurrFrame = Info.CurrentCall;
8657 if (CurrFrame->Callee && CurrFrame->Callee->Equals(VD->
getDeclContext())) {
8661 if (
auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
8662 if (CurrFrame->Arguments) {
8663 VD = CurrFrame->Arguments.getOrigParam(PVD);
8665 Info.getCallFrameAndDepth(CurrFrame->Arguments.CallIndex).first;
8666 Version = CurrFrame->Arguments.Version;
8670 Version = CurrFrame->getCurrentTemporaryVersion(VD);
8677 Result.set({VD, Frame->Index, Version});
8683 if (!Info.getLangOpts().CPlusPlus11) {
8684 Info.CCEDiag(
E, diag::note_constexpr_ltor_non_integral, 1)
8686 Info.Note(VD->
getLocation(), diag::note_declared_at);
8692 if (!
V->hasValue()) {
8695 if (!Info.checkingPotentialConstantExpression())
8696 Info.FFDiag(
E, diag::note_constexpr_use_uninit_reference);
8702bool LValueExprEvaluator::VisitCallExpr(
const CallExpr *
E) {
8703 if (!IsConstantEvaluatedBuiltinCall(
E))
8704 return ExprEvaluatorBaseTy::VisitCallExpr(
E);
8706 switch (
E->getBuiltinCallee()) {
8709 case Builtin::BIas_const:
8710 case Builtin::BIforward:
8711 case Builtin::BIforward_like:
8712 case Builtin::BImove:
8713 case Builtin::BImove_if_noexcept:
8714 if (cast<FunctionDecl>(
E->getCalleeDecl())->isConstexpr())
8715 return Visit(
E->getArg(0));
8719 return ExprEvaluatorBaseTy::VisitCallExpr(
E);
8722bool LValueExprEvaluator::VisitMaterializeTemporaryExpr(
8731 for (
const Expr *
E : CommaLHSs)
8740 if (Info.EvalMode == EvalInfo::EM_ConstantFold)
8743 Value =
E->getOrCreateValue(
true);
8747 Value = &Info.CurrentCall->createTemporary(
8748 E, Inner->getType(),
8763 for (
unsigned I = Adjustments.size(); I != 0; ) {
8765 switch (Adjustments[I].Kind) {
8770 Type = Adjustments[I].DerivedToBase.BasePath->getType();
8776 Type = Adjustments[I].Field->getType();
8781 Adjustments[I].Ptr.RHS))
8783 Type = Adjustments[I].Ptr.MPT->getPointeeType();
8793 assert((!Info.getLangOpts().CPlusPlus ||
E->isFileScope()) &&
8794 "lvalue compound literal in c++?");
8800bool LValueExprEvaluator::VisitCXXTypeidExpr(
const CXXTypeidExpr *
E) {
8803 if (!
E->isPotentiallyEvaluated()) {
8804 if (
E->isTypeOperand())
8809 if (!Info.Ctx.getLangOpts().CPlusPlus20) {
8810 Info.CCEDiag(
E, diag::note_constexpr_typeid_polymorphic)
8815 if (!Visit(
E->getExprOperand()))
8818 std::optional<DynamicType> DynType =
8824 TypeInfoLValue(Info.Ctx.getRecordType(DynType->Type).getTypePtr());
8830bool LValueExprEvaluator::VisitCXXUuidofExpr(
const CXXUuidofExpr *
E) {
8834bool LValueExprEvaluator::VisitMemberExpr(
const MemberExpr *
E) {
8836 if (
const VarDecl *VD = dyn_cast<VarDecl>(
E->getMemberDecl())) {
8837 VisitIgnoredBaseExpression(
E->getBase());
8838 return VisitVarDecl(
E, VD);
8842 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(
E->getMemberDecl())) {
8843 if (MD->isStatic()) {
8844 VisitIgnoredBaseExpression(
E->getBase());
8850 return LValueExprEvaluatorBaseTy::VisitMemberExpr(
E);
8864 for (
const Expr *SubExpr : {
E->getLHS(),
E->getRHS()}) {
8865 if (SubExpr ==
E->getBase() ? !evaluatePointer(SubExpr, Result)
8867 if (!Info.noteFailure())
8877bool LValueExprEvaluator::VisitUnaryDeref(
const UnaryOperator *
E) {
8878 return evaluatePointer(
E->getSubExpr(), Result);
8881bool LValueExprEvaluator::VisitUnaryReal(
const UnaryOperator *
E) {
8882 if (!Visit(
E->getSubExpr()))
8890bool LValueExprEvaluator::VisitUnaryImag(
const UnaryOperator *
E) {
8892 "lvalue __imag__ on scalar?");
8893 if (!Visit(
E->getSubExpr()))
8899bool LValueExprEvaluator::VisitUnaryPreIncDec(
const UnaryOperator *UO) {
8900 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
8911bool LValueExprEvaluator::VisitCompoundAssignOperator(
8913 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
8921 if (!Info.noteFailure())
8937 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
8944 if (!
Evaluate(NewVal, this->Info,
E->getRHS())) {
8945 if (!Info.noteFailure())
8950 if (!this->Visit(
E->getLHS()) || !
Success)
8953 if (Info.getLangOpts().CPlusPlus20 &&
8973 llvm::APInt &Result) {
8974 const AllocSizeAttr *AllocSize = getAllocSizeAttr(
Call);
8976 assert(AllocSize && AllocSize->getElemSizeParam().isValid());
8977 unsigned SizeArgNo = AllocSize->getElemSizeParam().getASTIndex();
8979 if (
Call->getNumArgs() <= SizeArgNo)
8982 auto EvaluateAsSizeT = [&](
const Expr *
E,
APSInt &Into) {
8987 if (Into.isNegative() || !Into.isIntN(BitsInSizeT))
8989 Into = Into.zext(BitsInSizeT);
8994 if (!EvaluateAsSizeT(
Call->getArg(SizeArgNo), SizeOfElem))
8997 if (!AllocSize->getNumElemsParam().isValid()) {
8998 Result = std::move(SizeOfElem);
9003 unsigned NumArgNo = AllocSize->getNumElemsParam().getASTIndex();
9004 if (!EvaluateAsSizeT(
Call->getArg(NumArgNo), NumberOfElems))
9008 llvm::APInt BytesAvailable = SizeOfElem.umul_ov(NumberOfElems, Overflow);
9012 Result = std::move(BytesAvailable);
9020 llvm::APInt &Result) {
9021 assert(isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
9022 "Can't get the size of a non alloc_size function");
9023 const auto *
Base = LVal.getLValueBase().get<
const Expr *>();
9043 dyn_cast_or_null<VarDecl>(
Base.dyn_cast<
const ValueDecl *>());
9048 if (!
Init ||
Init->getType().isNull())
9052 if (!tryUnwrapAllocSizeCall(
E))
9057 Result.setInvalid(
E);
9060 Result.addUnsizedArray(Info,
E, Pointee);
9065class PointerExprEvaluator
9066 :
public ExprEvaluatorBase<PointerExprEvaluator> {
9075 bool evaluateLValue(
const Expr *
E, LValue &Result) {
9079 bool evaluatePointer(
const Expr *
E, LValue &Result) {
9083 bool visitNonBuiltinCallExpr(
const CallExpr *
E);
9086 PointerExprEvaluator(EvalInfo &info, LValue &Result,
bool InvalidBaseOK)
9087 : ExprEvaluatorBaseTy(info), Result(Result),
9088 InvalidBaseOK(InvalidBaseOK) {}
9091 Result.setFrom(Info.Ctx,
V);
9094 bool ZeroInitialization(
const Expr *
E) {
9095 Result.setNull(Info.Ctx,
E->
getType());
9105 if (
E->isExpressibleAsConstantInitializer())
9107 if (Info.noteFailure())
9114 bool VisitBuiltinCallExpr(
const CallExpr *
E,
unsigned BuiltinOp);
9116 if (!
E->getBlockDecl()->hasCaptures())
9121 auto DiagnoseInvalidUseOfThis = [&] {
9122 if (Info.getLangOpts().CPlusPlus11)
9123 Info.FFDiag(
E, diag::note_constexpr_this) <<
E->isImplicit();
9129 if (Info.checkingPotentialConstantExpression())
9132 bool IsExplicitLambda =
9134 if (!IsExplicitLambda) {
9135 if (!Info.CurrentCall->This) {
9136 DiagnoseInvalidUseOfThis();
9140 Result = *Info.CurrentCall->This;
9148 if (!Info.CurrentCall->LambdaThisCaptureField) {
9149 if (IsExplicitLambda && !Info.CurrentCall->This) {
9150 DiagnoseInvalidUseOfThis();
9157 const auto *MD = cast<CXXMethodDecl>(Info.CurrentCall->Callee);
9159 Info,
E, Result, MD, Info.CurrentCall->LambdaThisCaptureField,
9168 assert(!
E->isIntType() &&
"SourceLocExpr isn't a pointer type?");
9169 APValue LValResult =
E->EvaluateInContext(
9170 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.getDefaultExpr());
9171 Result.setFrom(Info.Ctx, LValResult);
9176 llvm::report_fatal_error(
"Not yet implemented for ExprConstant.cpp");
9181 std::string ResultStr =
E->ComputeName(Info.Ctx);
9184 APInt Size(Info.Ctx.getTypeSize(Info.Ctx.getSizeType()),
9185 ResultStr.size() + 1);
9186 QualType ArrayTy = Info.Ctx.getConstantArrayType(
9187 CharTy, Size,
nullptr, ArraySizeModifier::Normal, 0);
9191 false, ArrayTy,
E->getLocation());
9193 evaluateLValue(SL, Result);
9194 Result.addArray(Info,
E, cast<ConstantArrayType>(ArrayTy));
9203 bool InvalidBaseOK) {
9206 return PointerExprEvaluator(Info, Result, InvalidBaseOK).Visit(
E);
9209bool PointerExprEvaluator::VisitBinaryOperator(
const BinaryOperator *
E) {
9210 if (
E->getOpcode() != BO_Add &&
9211 E->getOpcode() != BO_Sub)
9212 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
9214 const Expr *PExp =
E->getLHS();
9215 const Expr *IExp =
E->getRHS();
9217 std::swap(PExp, IExp);
9219 bool EvalPtrOK = evaluatePointer(PExp, Result);
9220 if (!EvalPtrOK && !Info.noteFailure())
9223 llvm::APSInt Offset;
9227 if (
E->getOpcode() == BO_Sub)
9234bool PointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *
E) {
9235 return evaluateLValue(
E->getSubExpr(), Result);
9243 if (!FnII || !FnII->
isStr(
"current"))
9246 const auto *RD = dyn_cast<RecordDecl>(FD->
getParent());
9254bool PointerExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
9255 const Expr *SubExpr =
E->getSubExpr();
9257 switch (
E->getCastKind()) {
9261 case CK_CPointerToObjCPointerCast:
9262 case CK_BlockPointerToObjCPointerCast:
9263 case CK_AnyPointerToBlockPointerCast:
9264 case CK_AddressSpaceConversion:
9265 if (!Visit(SubExpr))
9273 bool HasValidResult = !Result.InvalidBase && !Result.Designator.Invalid &&
9275 bool VoidPtrCastMaybeOK =
9278 Info.Ctx.hasSimilarType(Result.Designator.getType(Info.Ctx),
9287 if (VoidPtrCastMaybeOK &&
9288 (Info.getStdAllocatorCaller(
"allocate") ||
9290 Info.getLangOpts().CPlusPlus26)) {
9294 Info.getLangOpts().CPlusPlus) {
9296 CCEDiag(
E, diag::note_constexpr_invalid_void_star_cast)
9297 << SubExpr->
getType() << Info.getLangOpts().CPlusPlus26
9298 << Result.Designator.getType(Info.Ctx).getCanonicalType()
9301 CCEDiag(
E, diag::note_constexpr_invalid_cast)
9304 CCEDiag(
E, diag::note_constexpr_invalid_cast)
9305 << 2 << Info.Ctx.getLangOpts().CPlusPlus;
9306 Result.Designator.setInvalid();
9309 if (
E->getCastKind() == CK_AddressSpaceConversion && Result.IsNullPtr)
9310 ZeroInitialization(
E);
9313 case CK_DerivedToBase:
9314 case CK_UncheckedDerivedToBase:
9315 if (!evaluatePointer(
E->getSubExpr(), Result))
9317 if (!Result.Base && Result.Offset.isZero())
9326 case CK_BaseToDerived:
9327 if (!Visit(
E->getSubExpr()))
9329 if (!Result.Base && Result.Offset.isZero())
9334 if (!Visit(
E->getSubExpr()))
9338 case CK_NullToPointer:
9339 VisitIgnoredValue(
E->getSubExpr());
9340 return ZeroInitialization(
E);
9342 case CK_IntegralToPointer: {
9343 CCEDiag(
E, diag::note_constexpr_invalid_cast)
9344 << 2 << Info.Ctx.getLangOpts().CPlusPlus;
9350 if (
Value.isInt()) {
9352 uint64_t N =
Value.getInt().extOrTrunc(Size).getZExtValue();
9353 Result.Base = (
Expr*)
nullptr;
9354 Result.InvalidBase =
false;
9356 Result.Designator.setInvalid();
9357 Result.IsNullPtr =
false;
9364 if (!
Value.isLValue())
9368 Result.setFrom(Info.Ctx,
Value);
9373 case CK_ArrayToPointerDecay: {
9375 if (!evaluateLValue(SubExpr, Result))
9379 SubExpr, SubExpr->
getType(), ScopeKind::FullExpression, Result);
9384 auto *AT = Info.Ctx.getAsArrayType(SubExpr->
getType());
9385 if (
auto *CAT = dyn_cast<ConstantArrayType>(AT))
9386 Result.addArray(Info,
E, CAT);
9388 Result.addUnsizedArray(Info,
E, AT->getElementType());
9392 case CK_FunctionToPointerDecay:
9393 return evaluateLValue(SubExpr, Result);
9395 case CK_LValueToRValue: {
9397 if (!evaluateLValue(
E->getSubExpr(), LVal))
9404 return InvalidBaseOK &&
9410 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
9418 T =
T.getNonReferenceType();
9420 if (
T.getQualifiers().hasUnaligned())
9423 const bool AlignOfReturnsPreferred =
9424 Info.Ctx.getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver7;
9429 if (ExprKind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
9430 return Info.Ctx.toCharUnitsFromBits(
9431 Info.Ctx.getPreferredTypeAlign(
T.getTypePtr()));
9433 else if (ExprKind == UETT_AlignOf)
9434 return Info.Ctx.getTypeAlignInChars(
T.getTypePtr());
9436 llvm_unreachable(
"GetAlignOfType on a non-alignment ExprKind");
9450 return Info.Ctx.getDeclAlign(DRE->getDecl(),
9453 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(
E))
9454 return Info.Ctx.getDeclAlign(ME->getMemberDecl(),
9462 return Info.Ctx.getDeclAlign(VD);
9463 if (
const auto *
E =
Value.Base.dyn_cast<
const Expr *>())
9471 EvalInfo &Info,
APSInt &Alignment) {
9474 if (Alignment < 0 || !Alignment.isPowerOf2()) {
9475 Info.FFDiag(
E, diag::note_constexpr_invalid_alignment) << Alignment;
9478 unsigned SrcWidth = Info.Ctx.getIntWidth(ForType);
9479 APSInt MaxValue(APInt::getOneBitSet(SrcWidth, SrcWidth - 1));
9480 if (APSInt::compareValues(Alignment, MaxValue) > 0) {
9481 Info.FFDiag(
E, diag::note_constexpr_alignment_too_big)
9482 << MaxValue << ForType << Alignment;
9488 APSInt(Alignment.zextOrTrunc(SrcWidth),
true);
9489 assert(APSInt::compareValues(Alignment, ExtAlignment) == 0 &&
9490 "Alignment should not be changed by ext/trunc");
9491 Alignment = ExtAlignment;
9492 assert(Alignment.getBitWidth() == SrcWidth);
9497bool PointerExprEvaluator::visitNonBuiltinCallExpr(
const CallExpr *
E) {
9498 if (ExprEvaluatorBaseTy::VisitCallExpr(
E))
9501 if (!(InvalidBaseOK && getAllocSizeAttr(
E)))
9504 Result.setInvalid(
E);
9506 Result.addUnsizedArray(Info,
E, PointeeTy);
9510bool PointerExprEvaluator::VisitCallExpr(
const CallExpr *
E) {
9511 if (!IsConstantEvaluatedBuiltinCall(
E))
9512 return visitNonBuiltinCallExpr(
E);
9513 return VisitBuiltinCallExpr(
E,
E->getBuiltinCallee());
9522bool PointerExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *
E,
9523 unsigned BuiltinOp) {
9527 switch (BuiltinOp) {
9528 case Builtin::BIaddressof:
9529 case Builtin::BI__addressof:
9530 case Builtin::BI__builtin_addressof:
9531 return evaluateLValue(
E->getArg(0), Result);
9532 case Builtin::BI__builtin_assume_aligned: {
9536 if (!evaluatePointer(
E->getArg(0), Result))
9539 LValue OffsetResult(Result);
9546 if (
E->getNumArgs() > 2) {
9551 int64_t AdditionalOffset = -Offset.getZExtValue();
9556 if (OffsetResult.Base) {
9559 if (BaseAlignment < Align) {
9560 Result.Designator.setInvalid();
9562 CCEDiag(
E->getArg(0),
9563 diag::note_constexpr_baa_insufficient_alignment) << 0
9571 if (OffsetResult.Offset.alignTo(Align) != OffsetResult.Offset) {
9572 Result.Designator.setInvalid();
9575 ? CCEDiag(
E->getArg(0),
9576 diag::note_constexpr_baa_insufficient_alignment) << 1
9577 : CCEDiag(
E->getArg(0),
9578 diag::note_constexpr_baa_value_insufficient_alignment))
9579 << (
int)OffsetResult.Offset.getQuantity()
9586 case Builtin::BI__builtin_align_up:
9587 case Builtin::BI__builtin_align_down: {
9588 if (!evaluatePointer(
E->getArg(0), Result))
9607 assert(Alignment.getBitWidth() <= 64 &&
9608 "Cannot handle > 64-bit address-space");
9609 uint64_t Alignment64 = Alignment.getZExtValue();
9611 BuiltinOp == Builtin::BI__builtin_align_down
9612 ? llvm::alignDown(Result.Offset.getQuantity(), Alignment64)
9613 : llvm::alignTo(Result.Offset.getQuantity(), Alignment64));
9614 Result.adjustOffset(NewOffset - Result.Offset);
9619 Info.FFDiag(
E->getArg(0), diag::note_constexpr_alignment_adjust)
9623 case Builtin::BI__builtin_operator_new:
9625 case Builtin::BI__builtin_launder:
9626 return evaluatePointer(
E->getArg(0), Result);
9627 case Builtin::BIstrchr:
9628 case Builtin::BIwcschr:
9629 case Builtin::BImemchr:
9630 case Builtin::BIwmemchr:
9631 if (Info.getLangOpts().CPlusPlus11)
9632 Info.CCEDiag(
E, diag::note_constexpr_invalid_function)
9634 << (
"'" + Info.Ctx.BuiltinInfo.getName(BuiltinOp) +
"'").str();
9636 Info.CCEDiag(
E, diag::note_invalid_subexpr_in_const_expr);
9638 case Builtin::BI__builtin_strchr:
9639 case Builtin::BI__builtin_wcschr:
9640 case Builtin::BI__builtin_memchr:
9641 case Builtin::BI__builtin_char_memchr:
9642 case Builtin::BI__builtin_wmemchr: {
9643 if (!Visit(
E->getArg(0)))
9649 if (BuiltinOp != Builtin::BIstrchr &&
9650 BuiltinOp != Builtin::BIwcschr &&
9651 BuiltinOp != Builtin::BI__builtin_strchr &&
9652 BuiltinOp != Builtin::BI__builtin_wcschr) {
9656 MaxLength = N.getZExtValue();
9659 if (MaxLength == 0u)
9660 return ZeroInitialization(
E);
9661 if (!Result.checkNullPointerForFoldAccess(Info,
E,
AK_Read) ||
9662 Result.Designator.Invalid)
9664 QualType CharTy = Result.Designator.getType(Info.Ctx);
9665 bool IsRawByte = BuiltinOp == Builtin::BImemchr ||
9666 BuiltinOp == Builtin::BI__builtin_memchr;
9668 Info.Ctx.hasSameUnqualifiedType(
9672 Info.FFDiag(
E, diag::note_constexpr_ltor_incomplete_type) << CharTy;
9678 Info.FFDiag(
E, diag::note_constexpr_memchr_unsupported)
9679 << (
"'" + Info.Ctx.BuiltinInfo.getName(BuiltinOp) +
"'").str()
9686 bool StopAtNull =
false;
9687 switch (BuiltinOp) {
9688 case Builtin::BIstrchr:
9689 case Builtin::BI__builtin_strchr:
9696 return ZeroInitialization(
E);
9699 case Builtin::BImemchr:
9700 case Builtin::BI__builtin_memchr:
9701 case Builtin::BI__builtin_char_memchr:
9705 DesiredVal = Desired.trunc(Info.Ctx.getCharWidth()).getZExtValue();
9708 case Builtin::BIwcschr:
9709 case Builtin::BI__builtin_wcschr:
9712 case Builtin::BIwmemchr:
9713 case Builtin::BI__builtin_wmemchr:
9715 DesiredVal = Desired.getZExtValue();
9719 for (; MaxLength; --MaxLength) {
9724 if (Char.
getInt().getZExtValue() == DesiredVal)
9726 if (StopAtNull && !Char.
getInt())
9732 return ZeroInitialization(
E);
9735 case Builtin::BImemcpy:
9736 case Builtin::BImemmove:
9737 case Builtin::BIwmemcpy:
9738 case Builtin::BIwmemmove:
9739 if (Info.getLangOpts().CPlusPlus11)
9740 Info.CCEDiag(
E, diag::note_constexpr_invalid_function)
9742 << (
"'" + Info.Ctx.BuiltinInfo.getName(BuiltinOp) +
"'").str();
9744 Info.CCEDiag(
E, diag::note_invalid_subexpr_in_const_expr);
9746 case Builtin::BI__builtin_memcpy:
9747 case Builtin::BI__builtin_memmove:
9748 case Builtin::BI__builtin_wmemcpy:
9749 case Builtin::BI__builtin_wmemmove: {
9750 bool WChar = BuiltinOp == Builtin::BIwmemcpy ||
9751 BuiltinOp == Builtin::BIwmemmove ||
9752 BuiltinOp == Builtin::BI__builtin_wmemcpy ||
9753 BuiltinOp == Builtin::BI__builtin_wmemmove;
9754 bool Move = BuiltinOp == Builtin::BImemmove ||
9755 BuiltinOp == Builtin::BIwmemmove ||
9756 BuiltinOp == Builtin::BI__builtin_memmove ||
9757 BuiltinOp == Builtin::BI__builtin_wmemmove;
9760 if (!Visit(
E->getArg(0)))
9762 LValue Dest = Result;
9771 assert(!N.isSigned() &&
"memcpy and friends take an unsigned size");
9781 if (!Src.Base || !Dest.Base) {
9783 (!Src.Base ? Src : Dest).moveInto(Val);
9784 Info.FFDiag(
E, diag::note_constexpr_memcpy_null)
9785 <<
Move << WChar << !!Src.Base
9789 if (Src.Designator.Invalid || Dest.Designator.Invalid)
9795 QualType T = Dest.Designator.getType(Info.Ctx);
9796 QualType SrcT = Src.Designator.getType(Info.Ctx);
9797 if (!Info.Ctx.hasSameUnqualifiedType(
T, SrcT)) {
9799 Info.FFDiag(
E, diag::note_constexpr_memcpy_type_pun) <<
Move << SrcT <<
T;
9803 Info.FFDiag(
E, diag::note_constexpr_memcpy_incomplete_type) <<
Move <<
T;
9806 if (!
T.isTriviallyCopyableType(Info.Ctx)) {
9807 Info.FFDiag(
E, diag::note_constexpr_memcpy_nontrivial) <<
Move <<
T;
9812 uint64_t TSize = Info.Ctx.getTypeSizeInChars(
T).getQuantity();
9817 llvm::APInt OrigN = N;
9818 llvm::APInt::udivrem(OrigN, TSize, N, Remainder);
9820 Info.FFDiag(
E, diag::note_constexpr_memcpy_unsupported)
9830 uint64_t RemainingSrcSize = Src.Designator.validIndexAdjustments().second;
9831 uint64_t RemainingDestSize = Dest.Designator.validIndexAdjustments().second;
9832 if (N.ugt(RemainingSrcSize) || N.ugt(RemainingDestSize)) {
9833 Info.FFDiag(
E, diag::note_constexpr_memcpy_unsupported)
9834 <<
Move << WChar << (N.ugt(RemainingSrcSize) ? 1 : 2) <<
T
9838 uint64_t NElems = N.getZExtValue();
9844 uint64_t SrcOffset = Src.getLValueOffset().getQuantity();
9845 uint64_t DestOffset = Dest.getLValueOffset().getQuantity();
9846 if (DestOffset >= SrcOffset && DestOffset - SrcOffset < NBytes) {
9849 Info.FFDiag(
E, diag::note_constexpr_memcpy_overlap) << WChar;
9857 }
else if (!Move && SrcOffset >= DestOffset &&
9858 SrcOffset - DestOffset < NBytes) {
9860 Info.FFDiag(
E, diag::note_constexpr_memcpy_overlap) << WChar;
9895bool PointerExprEvaluator::VisitCXXNewExpr(
const CXXNewExpr *
E) {
9896 if (!Info.getLangOpts().CPlusPlus20)
9897 Info.CCEDiag(
E, diag::note_constexpr_new);
9900 if (Info.SpeculativeEvaluationDepth)
9905 bool IsNothrow =
false;
9906 bool IsPlacement =
false;
9908 Info.CurrentCall->isStdFunction() && !
E->isArray()) {
9910 assert(
E->getNumPlacementArgs() == 1);
9913 if (Result.Designator.Invalid)
9917 Info.FFDiag(
E, diag::note_constexpr_new_non_replaceable)
9918 << isa<CXXMethodDecl>(OperatorNew) << OperatorNew;
9920 }
else if (
E->getNumPlacementArgs()) {
9931 if (
E->getNumPlacementArgs() != 1 ||
9933 return Error(
E, diag::note_constexpr_new_placement);
9944 bool ValueInit =
false;
9946 QualType AllocType =
E->getAllocatedType();
9947 if (std::optional<const Expr *> ArraySize =
E->getArraySize()) {
9948 const Expr *Stripped = *ArraySize;
9949 for (;
auto *ICE = dyn_cast<ImplicitCastExpr>(Stripped);
9950 Stripped = ICE->getSubExpr())
9951 if (ICE->getCastKind() != CK_NoOp &&
9952 ICE->getCastKind() != CK_IntegralCast)
9955 llvm::APSInt ArrayBound;
9963 if (ArrayBound.isSigned() && ArrayBound.isNegative()) {
9965 return ZeroInitialization(
E);
9967 Info.FFDiag(*ArraySize, diag::note_constexpr_new_negative)
9968 << ArrayBound << (*ArraySize)->getSourceRange();
9974 if (!Info.CheckArraySize(ArraySize.value()->getExprLoc(),
9976 Info.Ctx, AllocType, ArrayBound),
9977 ArrayBound.getZExtValue(), !IsNothrow)) {
9979 return ZeroInitialization(
E);
9988 }
else if (isa<CXXScalarValueInitExpr>(
Init) ||
9989 isa<ImplicitValueInitExpr>(
Init)) {
9991 }
else if (
auto *CCE = dyn_cast<CXXConstructExpr>(
Init)) {
9992 ResizedArrayCCE = CCE;
9994 auto *CAT = Info.Ctx.getAsConstantArrayType(
Init->getType());
9995 assert(CAT &&
"unexpected type for array initializer");
9999 llvm::APInt InitBound = CAT->
getSize().zext(Bits);
10000 llvm::APInt AllocBound = ArrayBound.zext(Bits);
10001 if (InitBound.ugt(AllocBound)) {
10003 return ZeroInitialization(
E);
10005 Info.FFDiag(*ArraySize, diag::note_constexpr_new_too_small)
10006 <<
toString(AllocBound, 10,
false)
10008 << (*ArraySize)->getSourceRange();
10014 if (InitBound != AllocBound)
10015 ResizedArrayILE = cast<InitListExpr>(
Init);
10018 AllocType = Info.Ctx.getConstantArrayType(AllocType, ArrayBound,
nullptr,
10019 ArraySizeModifier::Normal, 0);
10022 "array allocation with non-array new");
10028 struct FindObjectHandler {
10035 typedef bool result_type;
10036 bool failed() {
return false; }
10040 if (!Info.Ctx.hasSameUnqualifiedType(SubobjType, AllocType)) {
10041 Info.FFDiag(
E, diag::note_constexpr_placement_new_wrong_type) <<
10042 SubobjType << AllocType;
10049 Info.FFDiag(
E, diag::note_constexpr_construct_complex_elem);
10053 Info.FFDiag(
E, diag::note_constexpr_construct_complex_elem);
10056 } Handler = {Info,
E, AllocType, AK,
nullptr};
10059 if (!Obj || !
findSubobject(Info,
E, Obj, Result.Designator, Handler))
10062 Val = Handler.Value;
10071 Val = Info.createHeapAlloc(
E, AllocType, Result);
10080 }
else if (ResizedArrayILE) {
10084 }
else if (ResizedArrayCCE) {
10098 Result.addArray(Info,
E, cast<ConstantArrayType>(AT));
10107class MemberPointerExprEvaluator
10108 :
public ExprEvaluatorBase<MemberPointerExprEvaluator> {
10112 Result = MemberPtr(
D);
10117 MemberPointerExprEvaluator(EvalInfo &Info, MemberPtr &Result)
10118 : ExprEvaluatorBaseTy(Info), Result(Result) {}
10124 bool ZeroInitialization(
const Expr *
E) {
10137 return MemberPointerExprEvaluator(Info, Result).Visit(
E);
10140bool MemberPointerExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
10141 switch (
E->getCastKind()) {
10143 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
10145 case CK_NullToMemberPointer:
10146 VisitIgnoredValue(
E->getSubExpr());
10147 return ZeroInitialization(
E);
10149 case CK_BaseToDerivedMemberPointer: {
10150 if (!Visit(
E->getSubExpr()))
10152 if (
E->path_empty())
10157 typedef std::reverse_iterator<CastExpr::path_const_iterator> ReverseIter;
10158 for (ReverseIter PathI(
E->path_end() - 1), PathE(
E->path_begin());
10159 PathI != PathE; ++PathI) {
10160 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
10161 const CXXRecordDecl *Derived = (*PathI)->getType()->getAsCXXRecordDecl();
10162 if (!Result.castToDerived(Derived))
10171 case CK_DerivedToBaseMemberPointer:
10172 if (!Visit(
E->getSubExpr()))
10175 PathE =
E->path_end(); PathI != PathE; ++PathI) {
10176 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
10178 if (!Result.castToBase(
Base))
10185bool MemberPointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *
E) {
10188 return Success(cast<DeclRefExpr>(
E->getSubExpr())->getDecl());
10196 class RecordExprEvaluator
10197 :
public ExprEvaluatorBase<RecordExprEvaluator> {
10198 const LValue &
This;
10202 RecordExprEvaluator(EvalInfo &info,
const LValue &This,
APValue &Result)
10203 : ExprEvaluatorBaseTy(info),
This(
This), Result(Result) {}
10209 bool ZeroInitialization(
const Expr *
E) {
10210 return ZeroInitialization(
E,
E->
getType());
10214 bool VisitCallExpr(
const CallExpr *
E) {
10215 return handleCallExpr(
E, Result, &This);
10220 return VisitCXXConstructExpr(
E,
E->
getType());
10228 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
10242 const LValue &This,
APValue &Result) {
10243 assert(!RD->
isUnion() &&
"Expected non-union class type");
10252 unsigned Index = 0;
10254 End = CD->
bases_end(); I != End; ++I, ++Index) {
10256 LValue Subobject = This;
10260 Result.getStructBase(Index)))
10265 for (
const auto *I : RD->
fields()) {
10267 if (I->isUnnamedBitField() || I->getType()->isReferenceType())
10270 LValue Subobject = This;
10276 Result.getStructField(I->getFieldIndex()), Info, Subobject, &VIE))
10283bool RecordExprEvaluator::ZeroInitialization(
const Expr *
E,
QualType T) {
10290 while (I != RD->
field_end() && (*I)->isUnnamedBitField())
10297 LValue Subobject =
This;
10302 return EvaluateInPlace(Result.getUnionValue(), Info, Subobject, &VIE);
10305 if (isa<CXXRecordDecl>(RD) && cast<CXXRecordDecl>(RD)->getNumVBases()) {
10306 Info.FFDiag(
E, diag::note_constexpr_virtual_base) << RD;
10313bool RecordExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
10314 switch (
E->getCastKind()) {
10316 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
10318 case CK_ConstructorConversion:
10319 return Visit(
E->getSubExpr());
10321 case CK_DerivedToBase:
10322 case CK_UncheckedDerivedToBase: {
10324 if (!
Evaluate(DerivedObject, Info,
E->getSubExpr()))
10327 return Error(
E->getSubExpr());
10333 PathE =
E->path_end(); PathI != PathE; ++PathI) {
10334 assert(!(*PathI)->isVirtual() &&
"record rvalue with virtual base");
10345bool RecordExprEvaluator::VisitInitListExpr(
const InitListExpr *
E) {
10346 if (
E->isTransparent())
10347 return Visit(
E->getInit(0));
10348 return VisitCXXParenListOrInitListExpr(
E,
E->inits());
10351bool RecordExprEvaluator::VisitCXXParenListOrInitListExpr(
10357 auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
10359 EvalInfo::EvaluatingConstructorRAII EvalObj(
10361 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries},
10362 CXXRD && CXXRD->getNumBases());
10366 if (
auto *ILE = dyn_cast<InitListExpr>(ExprToVisit)) {
10367 Field = ILE->getInitializedFieldInUnion();
10368 }
else if (
auto *PLIE = dyn_cast<CXXParenListInitExpr>(ExprToVisit)) {
10369 Field = PLIE->getInitializedFieldInUnion();
10372 "Expression is neither an init list nor a C++ paren list");
10385 const Expr *InitExpr = Args.empty() ? &VIE : Args[0];
10387 LValue Subobject =
This;
10392 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
10393 isa<CXXDefaultInitExpr>(InitExpr));
10395 if (
EvaluateInPlace(Result.getUnionValue(), Info, Subobject, InitExpr)) {
10396 if (
Field->isBitField())
10405 if (!Result.hasValue())
10408 unsigned ElementNo = 0;
10412 if (CXXRD && CXXRD->getNumBases()) {
10413 for (
const auto &
Base : CXXRD->bases()) {
10414 assert(ElementNo < Args.size() &&
"missing init for base class");
10415 const Expr *
Init = Args[ElementNo];
10417 LValue Subobject =
This;
10421 APValue &FieldVal = Result.getStructBase(ElementNo);
10423 if (!Info.noteFailure())
10430 EvalObj.finishedConstructingBases();
10434 for (
const auto *Field : RD->
fields()) {
10437 if (
Field->isUnnamedBitField())
10440 LValue Subobject =
This;
10442 bool HaveInit = ElementNo < Args.size();
10447 Subobject, Field, &Layout))
10453 const Expr *
Init = HaveInit ? Args[ElementNo++] : &VIE;
10455 if (
Field->getType()->isIncompleteArrayType()) {
10456 if (
auto *CAT = Info.Ctx.getAsConstantArrayType(
Init->getType())) {
10460 Info.FFDiag(
Init, diag::note_constexpr_unsupported_flexible_array);
10467 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
10468 isa<CXXDefaultInitExpr>(
Init));
10470 APValue &FieldVal = Result.getStructField(
Field->getFieldIndex());
10473 FieldVal, Field))) {
10474 if (!Info.noteFailure())
10480 EvalObj.finishedConstructingFields();
10492 bool ZeroInit =
E->requiresZeroInitialization();
10495 if (Result.hasValue())
10499 return ZeroInitialization(
E,
T);
10511 if (
E->isElidable() && !ZeroInit) {
10517 const Expr *SrcObj =
E->getArg(0);
10519 assert(Info.Ctx.hasSameUnqualifiedType(
E->
getType(), SrcObj->
getType()));
10521 dyn_cast<MaterializeTemporaryExpr>(SrcObj))
10522 return Visit(ME->getSubExpr());
10525 if (ZeroInit && !ZeroInitialization(
E,
T))
10534bool RecordExprEvaluator::VisitCXXInheritedCtorInitExpr(
10536 if (!Info.CurrentCall) {
10537 assert(Info.checkingPotentialConstantExpression());
10556bool RecordExprEvaluator::VisitCXXStdInitializerListExpr(
10559 Info.Ctx.getAsConstantArrayType(
E->getSubExpr()->
getType());
10565 assert(
ArrayType &&
"unexpected type for array initializer");
10572 Array.moveInto(Result.getStructField(0));
10576 assert(Field !=
Record->field_end() &&
10577 Info.Ctx.hasSameType(
Field->getType()->getPointeeType(),
10579 "Expected std::initializer_list first field to be const E *");
10581 assert(Field !=
Record->field_end() &&
10582 "Expected std::initializer_list to have two fields");
10584 if (Info.Ctx.hasSameType(
Field->getType(), Info.Ctx.getSizeType())) {
10589 assert(Info.Ctx.hasSameType(
Field->getType()->getPointeeType(),
10591 "Expected std::initializer_list second field to be const E *");
10596 Array.moveInto(Result.getStructField(1));
10599 assert(++Field ==
Record->field_end() &&
10600 "Expected std::initializer_list to only have two fields");
10605bool RecordExprEvaluator::VisitLambdaExpr(
const LambdaExpr *
E) {
10610 const size_t NumFields =
10613 assert(NumFields == (
size_t)std::distance(
E->capture_init_begin(),
10614 E->capture_init_end()) &&
10615 "The number of lambda capture initializers should equal the number of "
10616 "fields within the closure type");
10621 auto *CaptureInitIt =
E->capture_init_begin();
10623 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(ClosureClass);
10624 for (
const auto *Field : ClosureClass->
fields()) {
10625 assert(CaptureInitIt !=
E->capture_init_end());
10627 Expr *
const CurFieldInit = *CaptureInitIt++;
10634 LValue Subobject =
This;
10639 APValue &FieldVal = Result.getStructField(
Field->getFieldIndex());
10641 if (!Info.keepEvaluatingAfterFailure())
10650 APValue &Result, EvalInfo &Info) {
10653 "can't evaluate expression as a record rvalue");
10654 return RecordExprEvaluator(Info, This, Result).Visit(
E);
10665class TemporaryExprEvaluator
10666 :
public LValueExprEvaluatorBase<TemporaryExprEvaluator> {
10668 TemporaryExprEvaluator(EvalInfo &Info, LValue &Result) :
10669 LValueExprEvaluatorBaseTy(Info, Result,
false) {}
10672 bool VisitConstructExpr(
const Expr *
E) {
10674 E,
E->
getType(), ScopeKind::FullExpression, Result);
10678 bool VisitCastExpr(
const CastExpr *
E) {
10679 switch (
E->getCastKind()) {
10681 return LValueExprEvaluatorBaseTy::VisitCastExpr(
E);
10683 case CK_ConstructorConversion:
10684 return VisitConstructExpr(
E->getSubExpr());
10688 return VisitConstructExpr(
E);
10691 return VisitConstructExpr(
E);
10693 bool VisitCallExpr(
const CallExpr *
E) {
10694 return VisitConstructExpr(
E);
10697 return VisitConstructExpr(
E);
10700 return VisitConstructExpr(
E);
10709 return TemporaryExprEvaluator(Info, Result).Visit(
E);
10717 class VectorExprEvaluator
10718 :
public ExprEvaluatorBase<VectorExprEvaluator> {
10722 VectorExprEvaluator(EvalInfo &info,
APValue &Result)
10723 : ExprEvaluatorBaseTy(info), Result(Result) {}
10732 assert(
V.isVector());
10736 bool ZeroInitialization(
const Expr *
E);
10739 {
return Visit(
E->getSubExpr()); }
10755 "not a vector prvalue");
10756 return VectorExprEvaluator(Info, Result).Visit(
E);
10759bool VectorExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
10763 const Expr *SE =
E->getSubExpr();
10766 switch (
E->getCastKind()) {
10767 case CK_VectorSplat: {
10773 Val =
APValue(std::move(IntResult));
10778 Val =
APValue(std::move(FloatResult));
10795 Info.FFDiag(
E, diag::note_constexpr_invalid_cast)
10796 << 2 << Info.Ctx.getLangOpts().CPlusPlus;
10800 if (!handleRValueToRValueBitCast(Info, Result, SVal,
E))
10806 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
10811VectorExprEvaluator::VisitInitListExpr(
const InitListExpr *
E) {
10813 unsigned NumInits =
E->getNumInits();
10823 unsigned CountInits = 0, CountElts = 0;
10824 while (CountElts < NumElements) {
10826 if (CountInits < NumInits
10831 unsigned vlen =
v.getVectorLength();
10832 for (
unsigned j = 0; j < vlen; j++)
10833 Elements.push_back(
v.getVectorElt(j));
10836 llvm::APSInt sInt(32);
10837 if (CountInits < NumInits) {
10841 sInt = Info.Ctx.MakeIntValue(0, EltTy);
10842 Elements.push_back(
APValue(sInt));
10845 llvm::APFloat f(0.0);
10846 if (CountInits < NumInits) {
10850 f = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy));
10851 Elements.push_back(
APValue(f));
10860VectorExprEvaluator::ZeroInitialization(
const Expr *
E) {
10864 if (EltTy->isIntegerType())
10865 ZeroElement =
APValue(Info.Ctx.MakeIntValue(0, EltTy));
10868 APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy)));
10874bool VectorExprEvaluator::VisitUnaryImag(
const UnaryOperator *
E) {
10875 VisitIgnoredValue(
E->getSubExpr());
10876 return ZeroInitialization(
E);
10879bool VectorExprEvaluator::VisitBinaryOperator(
const BinaryOperator *
E) {
10881 assert(Op != BO_PtrMemD && Op != BO_PtrMemI && Op != BO_Cmp &&
10882 "Operation not supported on vector types");
10884 if (Op == BO_Comma)
10885 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
10887 Expr *LHS =
E->getLHS();
10888 Expr *RHS =
E->getRHS();
10891 "Must both be vector types");
10898 "All operands must be the same size.");
10902 bool LHSOK =
Evaluate(LHSValue, Info, LHS);
10903 if (!LHSOK && !Info.noteFailure())
10905 if (!
Evaluate(RHSValue, Info, RHS) || !LHSOK)
10927 "Vector can only be int or float type");
10935 "Vector operator ~ can only be int");
10936 Elt.
getInt().flipAllBits();
10946 "Vector can only be int or float type");
10952 EltResult.setAllBits();
10954 EltResult.clearAllBits();
10960 return std::nullopt;
10964bool VectorExprEvaluator::VisitUnaryOperator(
const UnaryOperator *
E) {
10965 Expr *SubExpr =
E->getSubExpr();
10970 const QualType ResultEltTy = VD->getElementType();
10974 if (!
Evaluate(SubExprValue, Info, SubExpr))
10987 "Vector length doesn't match type?");
10990 for (
unsigned EltNum = 0; EltNum < VD->getNumElements(); ++EltNum) {
10992 Info.Ctx, ResultEltTy, Op, SubExprValue.
getVectorElt(EltNum));
10995 ResultElements.push_back(*Elt);
10997 return Success(
APValue(ResultElements.data(), ResultElements.size()),
E);
11006 Result =
APValue(APFloat(0.0));
11008 DestTy, Result.getFloat());
11019 Result.getFloat());
11024 DestTy, Result.getInt());
11028 Info.FFDiag(
E, diag::err_convertvector_constexpr_unsupported_vector_cast)
11029 << SourceTy << DestTy;
11046 ResultElements.reserve(SourceLen);
11047 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11052 ResultElements.push_back(std::move(Elt));
11055 return Success(
APValue(ResultElements.data(), ResultElements.size()),
E);
11060 APValue const &VecVal2,
unsigned EltNum,
11062 unsigned const TotalElementsInInputVector1 = VecVal1.
getVectorLength();
11063 unsigned const TotalElementsInInputVector2 = VecVal2.
getVectorLength();
11065 APSInt IndexVal =
E->getShuffleMaskIdx(Info.Ctx, EltNum);
11066 int64_t index = IndexVal.getExtValue();
11073 E, diag::err_shufflevector_minus_one_is_undefined_behavior_constexpr)
11079 index >= TotalElementsInInputVector1 + TotalElementsInInputVector2)
11080 llvm_unreachable(
"Out of bounds shuffle index");
11082 if (index >= TotalElementsInInputVector1)
11083 Result = VecVal2.
getVectorElt(index - TotalElementsInInputVector1);
11091 const Expr *Vec1 =
E->getExpr(0);
11095 const Expr *Vec2 =
E->getExpr(1);
11105 ResultElements.reserve(TotalElementsInOutputVector);
11106 for (
unsigned EltNum = 0; EltNum < TotalElementsInOutputVector; ++EltNum) {
11110 ResultElements.push_back(std::move(Elt));
11113 return Success(
APValue(ResultElements.data(), ResultElements.size()),
E);
11121 class ArrayExprEvaluator
11122 :
public ExprEvaluatorBase<ArrayExprEvaluator> {
11123 const LValue &
This;
11127 ArrayExprEvaluator(EvalInfo &Info,
const LValue &This,
APValue &Result)
11128 : ExprEvaluatorBaseTy(Info),
This(
This), Result(Result) {}
11131 assert(
V.isArray() &&
"expected array");
11136 bool ZeroInitialization(
const Expr *
E) {
11138 Info.Ctx.getAsConstantArrayType(
E->
getType());
11152 if (!Result.hasArrayFiller())
11156 LValue Subobject =
This;
11157 Subobject.addArray(Info,
E, CAT);
11159 return EvaluateInPlace(Result.getArrayFiller(), Info, Subobject, &VIE);
11162 bool VisitCallExpr(
const CallExpr *
E) {
11163 return handleCallExpr(
E, Result, &This);
11170 const LValue &Subobject,
11178 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
11180 const Expr *ArrayFiller,
11186 APValue &Result, EvalInfo &Info) {
11189 "not an array prvalue");
11190 return ArrayExprEvaluator(Info, This, Result).Visit(
E);
11198 "not an array prvalue");
11199 return ArrayExprEvaluator(Info, This, Result)
11200 .VisitInitListExpr(ILE, AllocType);
11209 "not an array prvalue");
11210 return ArrayExprEvaluator(Info, This, Result)
11211 .VisitCXXConstructExpr(CCE, This, &Result, AllocType);
11218 if (isa<ImplicitValueInitExpr>(FillerExpr))
11220 if (
const InitListExpr *ILE = dyn_cast<InitListExpr>(FillerExpr)) {
11221 for (
unsigned I = 0,
E = ILE->getNumInits(); I !=
E; ++I) {
11226 if (ILE->hasArrayFiller() &&
11235bool ArrayExprEvaluator::VisitInitListExpr(
const InitListExpr *
E,
11244 if (
E->isStringLiteralInit()) {
11250 return VisitStringLiteral(SL, AllocType);
11254 assert(!
E->isTransparent() &&
11255 "transparent array list initialization is not string literal init?");
11257 return VisitCXXParenListOrInitListExpr(
E,
E->inits(),
E->getArrayFiller(),
11261bool ArrayExprEvaluator::VisitCXXParenListOrInitListExpr(
11269 assert((!Result.isArray() || Result.getArrayInitializedElts() == 0) &&
11270 "zero-initialized array shouldn't have any initialized elts");
11272 if (Result.isArray() && Result.hasArrayFiller())
11273 Filler = Result.getArrayFiller();
11275 unsigned NumEltsToInit = Args.size();
11280 if (NumEltsToInit != NumElts &&
11282 NumEltsToInit = NumElts;
11284 for (
auto *
Init : Args) {
11285 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts()))
11286 NumEltsToInit += EmbedS->getDataElementCount() - 1;
11288 if (NumEltsToInit > NumElts)
11289 NumEltsToInit = NumElts;
11292 LLVM_DEBUG(llvm::dbgs() <<
"The number of elements to initialize: "
11293 << NumEltsToInit <<
".\n");
11300 for (
unsigned I = 0,
E = Result.getArrayInitializedElts(); I !=
E; ++I)
11301 Result.getArrayInitializedElt(I) = Filler;
11302 if (Result.hasArrayFiller())
11303 Result.getArrayFiller() = Filler;
11306 LValue Subobject =
This;
11307 Subobject.addArray(Info, ExprToVisit, CAT);
11308 auto Eval = [&](
const Expr *
Init,
unsigned ArrayIndex) {
11309 if (!
EvaluateInPlace(Result.getArrayInitializedElt(ArrayIndex), Info,
11310 Subobject,
Init) ||
11313 if (!Info.noteFailure())
11319 unsigned ArrayIndex = 0;
11322 for (
unsigned Index = 0; Index != NumEltsToInit; ++Index) {
11323 const Expr *
Init = Index < Args.size() ? Args[Index] : ArrayFiller;
11324 if (ArrayIndex >= NumEltsToInit)
11326 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
11328 for (
unsigned I = EmbedS->getStartingElementPos(),
11329 N = EmbedS->getDataElementCount();
11330 I != EmbedS->getStartingElementPos() + N; ++I) {
11333 Result.getArrayInitializedElt(ArrayIndex) =
APValue(
Value);
11337 Init->getFPFeaturesInEffect(Info.Ctx.getLangOpts());
11342 Result.getArrayInitializedElt(ArrayIndex) =
APValue(FValue);
11347 if (!Eval(
Init, ArrayIndex))
11353 if (!Result.hasArrayFiller())
11358 assert(ArrayFiller &&
"no array filler for incomplete init list");
11366 if (
E->getCommonExpr() &&
11367 !
Evaluate(Info.CurrentCall->createTemporary(
11368 E->getCommonExpr(),
11369 getStorageType(Info.Ctx,
E->getCommonExpr()),
11370 ScopeKind::FullExpression, CommonLV),
11371 Info,
E->getCommonExpr()->getSourceExpr()))
11379 LValue Subobject =
This;
11380 Subobject.addArray(Info,
E, CAT);
11383 for (EvalInfo::ArrayInitLoopIndex Index(Info); Index != Elements; ++Index) {
11392 FullExpressionRAII
Scope(Info);
11395 Info, Subobject,
E->getSubExpr()) ||
11398 if (!Info.noteFailure())
11411 return VisitCXXConstructExpr(
E, This, &Result,
E->
getType());
11415 const LValue &Subobject,
11425 HadZeroInit &&
Value->hasArrayFiller() ?
Value->getArrayFiller()
11429 if (FinalSize == 0)
11434 E->requiresZeroInitialization());
11435 LValue ArrayElt = Subobject;
11436 ArrayElt.addArray(Info,
E, CAT);
11442 for (
const unsigned N : {1u, FinalSize}) {
11443 unsigned OldElts =
Value->getArrayInitializedElts();
11449 for (
unsigned I = 0; I < OldElts; ++I)
11450 NewValue.getArrayInitializedElt(I).swap(
11451 Value->getArrayInitializedElt(I));
11452 Value->swap(NewValue);
11455 for (
unsigned I = OldElts; I < N; ++I)
11456 Value->getArrayInitializedElt(I) = Filler;
11458 if (HasTrivialConstructor && N == FinalSize && FinalSize != 1) {
11461 APValue &FirstResult =
Value->getArrayInitializedElt(0);
11462 for (
unsigned I = OldElts; I < FinalSize; ++I)
11463 Value->getArrayInitializedElt(I) = FirstResult;
11465 for (
unsigned I = OldElts; I < N; ++I) {
11466 if (!VisitCXXConstructExpr(
E, ArrayElt,
11467 &
Value->getArrayInitializedElt(I),
11474 if (Info.EvalStatus.Diag && !Info.EvalStatus.Diag->empty() &&
11475 !Info.keepEvaluatingAfterFailure())
11487 return RecordExprEvaluator(Info, Subobject, *
Value)
11488 .VisitCXXConstructExpr(
E,
Type);
11491bool ArrayExprEvaluator::VisitCXXParenListInitExpr(
11494 "Expression result is not a constant array type");
11496 return VisitCXXParenListOrInitListExpr(
E,
E->getInitExprs(),
11497 E->getArrayFiller());
11509class IntExprEvaluator
11510 :
public ExprEvaluatorBase<IntExprEvaluator> {
11513 IntExprEvaluator(EvalInfo &info,
APValue &result)
11514 : ExprEvaluatorBaseTy(info), Result(result) {}
11518 "Invalid evaluation result.");
11520 "Invalid evaluation result.");
11521 assert(SI.getBitWidth() == Info.Ctx.getIntWidth(
E->
getType()) &&
11522 "Invalid evaluation result.");
11532 "Invalid evaluation result.");
11533 assert(I.getBitWidth() == Info.Ctx.getIntWidth(
E->
getType()) &&
11534 "Invalid evaluation result.");
11536 Result.getInt().setIsUnsigned(
11546 "Invalid evaluation result.");
11559 if (
V.isLValue() ||
V.isAddrLabelDiff() ||
V.isIndeterminate()) {
11566 bool ZeroInitialization(
const Expr *
E) {
return Success(0,
E); }
11579 bool CheckReferencedDecl(
const Expr *
E,
const Decl *
D);
11581 if (CheckReferencedDecl(
E,
E->getDecl()))
11584 return ExprEvaluatorBaseTy::VisitDeclRefExpr(
E);
11587 if (CheckReferencedDecl(
E,
E->getMemberDecl())) {
11588 VisitIgnoredBaseExpression(
E->getBase());
11592 return ExprEvaluatorBaseTy::VisitMemberExpr(
E);
11596 bool VisitBuiltinCallExpr(
const CallExpr *
E,
unsigned BuiltinOp);
11613 if (Info.ArrayInitIndex ==
uint64_t(-1)) {
11619 return Success(Info.ArrayInitIndex,
E);
11624 return ZeroInitialization(
E);
11650class FixedPointExprEvaluator
11651 :
public ExprEvaluatorBase<FixedPointExprEvaluator> {
11655 FixedPointExprEvaluator(EvalInfo &info,
APValue &result)
11656 : ExprEvaluatorBaseTy(info), Result(result) {}
11660 APFixedPoint(I, Info.Ctx.getFixedPointSemantics(
E->
getType())),
E);
11665 APFixedPoint(
Value, Info.Ctx.getFixedPointSemantics(
E->
getType())),
E);
11674 assert(
V.getWidth() == Info.Ctx.getIntWidth(
E->
getType()) &&
11675 "Invalid evaluation result.");
11680 bool ZeroInitialization(
const Expr *
E) {
11710 return IntExprEvaluator(Info, Result).Visit(
E);
11718 if (!Val.
isInt()) {
11721 Info.FFDiag(
E, diag::note_invalid_subexpr_in_const_expr);
11728bool IntExprEvaluator::VisitSourceLocExpr(
const SourceLocExpr *
E) {
11730 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.getDefaultExpr());
11739 if (!FixedPointExprEvaluator(Info, Val).Visit(
E))
11754 auto FXSema = Info.Ctx.getFixedPointSemantics(
E->
getType());
11758 Result = APFixedPoint(Val, FXSema);
11769bool IntExprEvaluator::CheckReferencedDecl(
const Expr*
E,
const Decl*
D) {
11773 bool SameSign = (ECD->getInitVal().isSigned()
11775 bool SameWidth = (ECD->getInitVal().getBitWidth()
11776 == Info.Ctx.getIntWidth(
E->
getType()));
11777 if (SameSign && SameWidth)
11778 return Success(ECD->getInitVal(),
E);
11782 llvm::APSInt Val = ECD->getInitVal();
11784 Val.setIsSigned(!ECD->getInitVal().isSigned());
11786 Val = Val.extOrTrunc(Info.Ctx.getIntWidth(
E->
getType()));
11802#define TYPE(ID, BASE)
11803#define DEPENDENT_TYPE(ID, BASE) case Type::ID:
11804#define NON_CANONICAL_TYPE(ID, BASE) case Type::ID:
11805#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(ID, BASE) case Type::ID:
11806#include "clang/AST/TypeNodes.inc"
11808 case Type::DeducedTemplateSpecialization:
11809 llvm_unreachable(
"unexpected non-canonical or dependent type");
11811 case Type::Builtin:
11812 switch (cast<BuiltinType>(CanTy)->
getKind()) {
11813#define BUILTIN_TYPE(ID, SINGLETON_ID)
11814#define SIGNED_TYPE(ID, SINGLETON_ID) \
11815 case BuiltinType::ID: return GCCTypeClass::Integer;
11816#define FLOATING_TYPE(ID, SINGLETON_ID) \
11817 case BuiltinType::ID: return GCCTypeClass::RealFloat;
11818#define PLACEHOLDER_TYPE(ID, SINGLETON_ID) \
11819 case BuiltinType::ID: break;
11820#include "clang/AST/BuiltinTypes.def"
11821 case BuiltinType::Void:
11822 return GCCTypeClass::Void;
11824 case BuiltinType::Bool:
11825 return GCCTypeClass::Bool;
11827 case BuiltinType::Char_U:
11828 case BuiltinType::UChar:
11829 case BuiltinType::WChar_U:
11830 case BuiltinType::Char8:
11831 case BuiltinType::Char16:
11832 case BuiltinType::Char32:
11833 case BuiltinType::UShort:
11834 case BuiltinType::UInt:
11835 case BuiltinType::ULong:
11836 case BuiltinType::ULongLong:
11837 case BuiltinType::UInt128:
11838 return GCCTypeClass::Integer;
11840 case BuiltinType::UShortAccum:
11841 case BuiltinType::UAccum:
11842 case BuiltinType::ULongAccum:
11843 case BuiltinType::UShortFract:
11844 case BuiltinType::UFract:
11845 case BuiltinType::ULongFract:
11846 case BuiltinType::SatUShortAccum:
11847 case BuiltinType::SatUAccum:
11848 case BuiltinType::SatULongAccum:
11849 case BuiltinType::SatUShortFract:
11850 case BuiltinType::SatUFract:
11851 case BuiltinType::SatULongFract:
11852 return GCCTypeClass::None;
11854 case BuiltinType::NullPtr:
11856 case BuiltinType::ObjCId:
11857 case BuiltinType::ObjCClass:
11858 case BuiltinType::ObjCSel:
11859#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
11860 case BuiltinType::Id:
11861#include "clang/Basic/OpenCLImageTypes.def"
11862#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
11863 case BuiltinType::Id:
11864#include "clang/Basic/OpenCLExtensionTypes.def"
11865 case BuiltinType::OCLSampler:
11866 case BuiltinType::OCLEvent:
11867 case BuiltinType::OCLClkEvent:
11868 case BuiltinType::OCLQueue:
11869 case BuiltinType::OCLReserveID:
11870#define SVE_TYPE(Name, Id, SingletonId) \
11871 case BuiltinType::Id:
11872#include "clang/Basic/AArch64SVEACLETypes.def"
11873#define PPC_VECTOR_TYPE(Name, Id, Size) \
11874 case BuiltinType::Id:
11875#include "clang/Basic/PPCTypes.def"
11876#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
11877#include "clang/Basic/RISCVVTypes.def"
11878#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
11879#include "clang/Basic/WebAssemblyReferenceTypes.def"
11880#define AMDGPU_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
11881#include "clang/Basic/AMDGPUTypes.def"
11882 return GCCTypeClass::None;
11884 case BuiltinType::Dependent:
11885 llvm_unreachable(
"unexpected dependent type");
11887 llvm_unreachable(
"unexpected placeholder type");
11890 return LangOpts.CPlusPlus ? GCCTypeClass::Enum : GCCTypeClass::Integer;
11892 case Type::Pointer:
11893 case Type::ConstantArray:
11894 case Type::VariableArray:
11895 case Type::IncompleteArray:
11896 case Type::FunctionNoProto:
11897 case Type::FunctionProto:
11898 case Type::ArrayParameter:
11899 return GCCTypeClass::Pointer;
11901 case Type::MemberPointer:
11903 ? GCCTypeClass::PointerToDataMember
11904 : GCCTypeClass::PointerToMemberFunction;
11906 case Type::Complex:
11907 return GCCTypeClass::Complex;
11910 return CanTy->
isUnionType() ? GCCTypeClass::Union
11911 : GCCTypeClass::ClassOrStruct;
11919 case Type::ExtVector:
11920 return GCCTypeClass::Vector;
11922 case Type::BlockPointer:
11923 case Type::ConstantMatrix:
11924 case Type::ObjCObject:
11925 case Type::ObjCInterface:
11926 case Type::ObjCObjectPointer:
11930 return GCCTypeClass::None;
11933 return GCCTypeClass::BitInt;
11935 case Type::LValueReference:
11936 case Type::RValueReference:
11937 llvm_unreachable(
"invalid type for expression");
11940 llvm_unreachable(
"unexpected type class");
11949 if (
E->getNumArgs() == 0)
11950 return GCCTypeClass::None;
11965 if (
Base.isNull()) {
11968 }
else if (
const Expr *
E =
Base.dyn_cast<
const Expr *>()) {
11969 if (!isa<StringLiteral>(
E))
11987 SpeculativeEvaluationRAII SpeculativeEval(Info);
11992 FoldConstant Fold(Info,
true);
12015 Fold.keepDiagnostics();
12024 return V.hasValue();
12035 if (
const VarDecl *VD = dyn_cast<VarDecl>(
D))
12038 if (isa<CompoundLiteralExpr>(
E))
12059 const auto *Cast = dyn_cast<CastExpr>(NoParens);
12060 if (Cast ==
nullptr)
12065 auto CastKind = Cast->getCastKind();
12067 CastKind != CK_AddressSpaceConversion)
12070 const auto *SubExpr = Cast->getSubExpr();
12092 assert(!LVal.Designator.Invalid);
12094 auto IsLastOrInvalidFieldDecl = [&Ctx](
const FieldDecl *FD,
bool &
Invalid) {
12103 auto &
Base = LVal.getLValueBase();
12104 if (
auto *ME = dyn_cast_or_null<MemberExpr>(
Base.dyn_cast<
const Expr *>())) {
12105 if (
auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
12107 if (!IsLastOrInvalidFieldDecl(FD,
Invalid))
12109 }
else if (
auto *IFD = dyn_cast<IndirectFieldDecl>(ME->getMemberDecl())) {
12110 for (
auto *FD : IFD->chain()) {
12112 if (!IsLastOrInvalidFieldDecl(cast<FieldDecl>(FD),
Invalid))
12120 if (LVal.Designator.FirstEntryIsAnUnsizedArray) {
12130 for (
unsigned E = LVal.Designator.Entries.size(); I !=
E; ++I) {
12131 const auto &Entry = LVal.Designator.Entries[I];
12137 const auto *CAT = cast<ConstantArrayType>(Ctx.
getAsArrayType(BaseType));
12138 uint64_t Index = Entry.getAsArrayIndex();
12144 uint64_t Index = Entry.getAsArrayIndex();
12147 BaseType = CT->getElementType();
12148 }
else if (
auto *FD = getAsField(Entry)) {
12150 if (!IsLastOrInvalidFieldDecl(FD,
Invalid))
12154 assert(getAsBaseClass(Entry) &&
"Expecting cast to a base class");
12166 if (LVal.Designator.Invalid)
12169 if (!LVal.Designator.Entries.empty())
12170 return LVal.Designator.isMostDerivedAnUnsizedArray();
12172 if (!LVal.InvalidBase)
12177 const auto *
E = LVal.Base.dyn_cast<
const Expr *>();
12178 return !
E || !isa<MemberExpr>(
E);
12184 const SubobjectDesignator &
Designator = LVal.Designator;
12196 auto isFlexibleArrayMember = [&] {
12198 FAMKind StrictFlexArraysLevel =
12201 if (
Designator.isMostDerivedAnUnsizedArray())
12204 if (StrictFlexArraysLevel == FAMKind::Default)
12207 if (
Designator.getMostDerivedArraySize() == 0 &&
12208 StrictFlexArraysLevel != FAMKind::IncompleteOnly)
12211 if (
Designator.getMostDerivedArraySize() == 1 &&
12212 StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete)
12218 return LVal.InvalidBase &&
12220 Designator.MostDerivedIsArrayElement && isFlexibleArrayMember() &&
12228 auto CharUnitsMax = std::numeric_limits<CharUnits::QuantityType>::max();
12229 if (Int.ugt(CharUnitsMax))
12241 if (
const auto *
V = LV.getLValueBase().dyn_cast<
const ValueDecl *>())
12242 if (
const auto *VD = dyn_cast<VarDecl>(
V))
12254 unsigned Type,
const LValue &LVal,
12267 if (!(
Type & 1) || LVal.Designator.Invalid || DetermineForCompleteObject) {
12269 if (
Type == 3 && !DetermineForCompleteObject)
12272 llvm::APInt APEndOffset;
12273 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
12277 if (LVal.InvalidBase)
12281 const bool Ret = CheckedHandleSizeof(BaseTy, EndOffset);
12287 const SubobjectDesignator &
Designator = LVal.Designator;
12299 llvm::APInt APEndOffset;
12300 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
12312 if (!CheckedHandleSizeof(
Designator.MostDerivedType, BytesPerElem))
12318 int64_t ElemsRemaining;
12321 uint64_t ArraySize =
Designator.getMostDerivedArraySize();
12322 uint64_t ArrayIndex =
Designator.Entries.back().getAsArrayIndex();
12323 ElemsRemaining = ArraySize <= ArrayIndex ? 0 : ArraySize - ArrayIndex;
12325 ElemsRemaining =
Designator.isOnePastTheEnd() ? 0 : 1;
12328 EndOffset = LVal.getLValueOffset() + BytesPerElem * ElemsRemaining;
12338 EvalInfo &Info, uint64_t &Size) {
12345 SpeculativeEvaluationRAII SpeculativeEval(Info);
12346 IgnoreSideEffectsRAII Fold(Info);
12354 LVal.setFrom(Info.Ctx, RVal);
12362 if (LVal.getLValueOffset().isNegative()) {
12373 if (EndOffset <= LVal.getLValueOffset())
12376 Size = (EndOffset - LVal.getLValueOffset()).getQuantity();
12380bool IntExprEvaluator::VisitCallExpr(
const CallExpr *
E) {
12381 if (!IsConstantEvaluatedBuiltinCall(
E))
12382 return ExprEvaluatorBaseTy::VisitCallExpr(
E);
12383 return VisitBuiltinCallExpr(
E,
E->getBuiltinCallee());
12399 Info.FFDiag(
E->getArg(0));
12405 assert(SrcInt.getBitWidth() >= Alignment.getBitWidth() &&
12406 "Bit widths must be the same");
12413bool IntExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *
E,
12414 unsigned BuiltinOp) {
12415 switch (BuiltinOp) {
12419 case Builtin::BI__builtin_dynamic_object_size:
12420 case Builtin::BI__builtin_object_size: {
12424 assert(
Type <= 3 &&
"unexpected type");
12435 switch (Info.EvalMode) {
12436 case EvalInfo::EM_ConstantExpression:
12437 case EvalInfo::EM_ConstantFold:
12438 case EvalInfo::EM_IgnoreSideEffects:
12441 case EvalInfo::EM_ConstantExpressionUnevaluated:
12446 llvm_unreachable(
"unexpected EvalMode");
12449 case Builtin::BI__builtin_os_log_format_buffer_size: {
12455 case Builtin::BI__builtin_is_aligned: {
12463 Ptr.setFrom(Info.Ctx, Src);
12469 assert(Alignment.isPowerOf2());
12482 Info.FFDiag(
E->getArg(0), diag::note_constexpr_alignment_compute)
12486 assert(Src.
isInt());
12487 return Success((Src.
getInt() & (Alignment - 1)) == 0 ? 1 : 0,
E);
12489 case Builtin::BI__builtin_align_up: {
12497 APSInt((Src.
getInt() + (Alignment - 1)) & ~(Alignment - 1),
12498 Src.
getInt().isUnsigned());
12499 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
12502 case Builtin::BI__builtin_align_down: {
12511 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
12515 case Builtin::BI__builtin_bitreverse8:
12516 case Builtin::BI__builtin_bitreverse16:
12517 case Builtin::BI__builtin_bitreverse32:
12518 case Builtin::BI__builtin_bitreverse64: {
12523 return Success(Val.reverseBits(),
E);
12526 case Builtin::BI__builtin_bswap16:
12527 case Builtin::BI__builtin_bswap32:
12528 case Builtin::BI__builtin_bswap64: {
12533 return Success(Val.byteSwap(),
E);
12536 case Builtin::BI__builtin_classify_type:
12539 case Builtin::BI__builtin_clrsb:
12540 case Builtin::BI__builtin_clrsbl:
12541 case Builtin::BI__builtin_clrsbll: {
12546 return Success(Val.getBitWidth() - Val.getSignificantBits(),
E);
12549 case Builtin::BI__builtin_clz:
12550 case Builtin::BI__builtin_clzl:
12551 case Builtin::BI__builtin_clzll:
12552 case Builtin::BI__builtin_clzs:
12553 case Builtin::BI__builtin_clzg:
12554 case Builtin::BI__lzcnt16:
12555 case Builtin::BI__lzcnt:
12556 case Builtin::BI__lzcnt64: {
12561 std::optional<APSInt> Fallback;
12562 if (BuiltinOp == Builtin::BI__builtin_clzg &&
E->getNumArgs() > 1) {
12566 Fallback = FallbackTemp;
12576 bool ZeroIsUndefined = BuiltinOp != Builtin::BI__lzcnt16 &&
12577 BuiltinOp != Builtin::BI__lzcnt &&
12578 BuiltinOp != Builtin::BI__lzcnt64;
12580 if (ZeroIsUndefined)
12584 return Success(Val.countl_zero(),
E);
12587 case Builtin::BI__builtin_constant_p: {
12588 const Expr *Arg =
E->getArg(0);
12597 Info.FFDiag(
E, diag::note_invalid_subexpr_in_const_expr);
12601 case Builtin::BI__builtin_is_constant_evaluated: {
12602 const auto *
Callee = Info.CurrentCall->getCallee();
12603 if (Info.InConstantContext && !Info.CheckingPotentialConstantExpression &&
12604 (Info.CallStackDepth == 1 ||
12605 (Info.CallStackDepth == 2 &&
Callee->isInStdNamespace() &&
12606 Callee->getIdentifier() &&
12607 Callee->getIdentifier()->isStr(
"is_constant_evaluated")))) {
12609 if (Info.EvalStatus.Diag)
12610 Info.report((Info.CallStackDepth == 1)
12612 : Info.CurrentCall->getCallRange().getBegin(),
12613 diag::warn_is_constant_evaluated_always_true_constexpr)
12614 << (Info.CallStackDepth == 1 ?
"__builtin_is_constant_evaluated"
12615 :
"std::is_constant_evaluated");
12618 return Success(Info.InConstantContext,
E);
12621 case Builtin::BI__builtin_ctz:
12622 case Builtin::BI__builtin_ctzl:
12623 case Builtin::BI__builtin_ctzll:
12624 case Builtin::BI__builtin_ctzs:
12625 case Builtin::BI__builtin_ctzg: {
12630 std::optional<APSInt> Fallback;
12631 if (BuiltinOp == Builtin::BI__builtin_ctzg &&
E->getNumArgs() > 1) {
12635 Fallback = FallbackTemp;
12645 return Success(Val.countr_zero(),
E);
12648 case Builtin::BI__builtin_eh_return_data_regno: {
12650 Operand = Info.Ctx.getTargetInfo().getEHDataRegisterNumber(Operand);
12654 case Builtin::BI__builtin_expect:
12655 case Builtin::BI__builtin_expect_with_probability:
12656 return Visit(
E->getArg(0));
12658 case Builtin::BI__builtin_ptrauth_string_discriminator: {
12665 case Builtin::BI__builtin_ffs:
12666 case Builtin::BI__builtin_ffsl:
12667 case Builtin::BI__builtin_ffsll: {
12672 unsigned N = Val.countr_zero();
12673 return Success(N == Val.getBitWidth() ? 0 : N + 1,
E);
12676 case Builtin::BI__builtin_fpclassify: {
12681 switch (Val.getCategory()) {
12682 case APFloat::fcNaN: Arg = 0;
break;
12683 case APFloat::fcInfinity: Arg = 1;
break;
12684 case APFloat::fcNormal: Arg = Val.isDenormal() ? 3 : 2;
break;
12685 case APFloat::fcZero: Arg = 4;
break;
12687 return Visit(
E->getArg(Arg));
12690 case Builtin::BI__builtin_isinf_sign: {
12693 Success(Val.isInfinity() ? (Val.isNegative() ? -1 : 1) : 0,
E);
12696 case Builtin::BI__builtin_isinf: {
12699 Success(Val.isInfinity() ? 1 : 0,
E);
12702 case Builtin::BI__builtin_isfinite: {
12705 Success(Val.isFinite() ? 1 : 0,
E);
12708 case Builtin::BI__builtin_isnan: {
12714 case Builtin::BI__builtin_isnormal: {
12717 Success(Val.isNormal() ? 1 : 0,
E);
12720 case Builtin::BI__builtin_issubnormal: {
12723 Success(Val.isDenormal() ? 1 : 0,
E);
12726 case Builtin::BI__builtin_iszero: {
12732 case Builtin::BI__builtin_issignaling: {
12735 Success(Val.isSignaling() ? 1 : 0,
E);
12738 case Builtin::BI__builtin_isfpclass: {
12742 unsigned Test =
static_cast<llvm::FPClassTest
>(MaskVal.getZExtValue());
12745 Success((Val.classify() & Test) ? 1 : 0,
E);
12748 case Builtin::BI__builtin_parity:
12749 case Builtin::BI__builtin_parityl:
12750 case Builtin::BI__builtin_parityll: {
12755 return Success(Val.popcount() % 2,
E);
12758 case Builtin::BI__builtin_popcount:
12759 case Builtin::BI__builtin_popcountl:
12760 case Builtin::BI__builtin_popcountll:
12761 case Builtin::BI__builtin_popcountg:
12762 case Builtin::BI__popcnt16:
12763 case Builtin::BI__popcnt:
12764 case Builtin::BI__popcnt64: {
12769 return Success(Val.popcount(),
E);
12772 case Builtin::BI__builtin_rotateleft8:
12773 case Builtin::BI__builtin_rotateleft16:
12774 case Builtin::BI__builtin_rotateleft32:
12775 case Builtin::BI__builtin_rotateleft64:
12776 case Builtin::BI_rotl8:
12777 case Builtin::BI_rotl16:
12778 case Builtin::BI_rotl:
12779 case Builtin::BI_lrotl:
12780 case Builtin::BI_rotl64: {
12786 return Success(Val.rotl(Amt.urem(Val.getBitWidth())),
E);
12789 case Builtin::BI__builtin_rotateright8:
12790 case Builtin::BI__builtin_rotateright16:
12791 case Builtin::BI__builtin_rotateright32:
12792 case Builtin::BI__builtin_rotateright64:
12793 case Builtin::BI_rotr8:
12794 case Builtin::BI_rotr16:
12795 case Builtin::BI_rotr:
12796 case Builtin::BI_lrotr:
12797 case Builtin::BI_rotr64: {
12803 return Success(Val.rotr(Amt.urem(Val.getBitWidth())),
E);
12806 case Builtin::BIstrlen:
12807 case Builtin::BIwcslen:
12809 if (Info.getLangOpts().CPlusPlus11)
12810 Info.CCEDiag(
E, diag::note_constexpr_invalid_function)
12812 << (
"'" + Info.Ctx.BuiltinInfo.getName(BuiltinOp) +
"'").str();
12814 Info.CCEDiag(
E, diag::note_invalid_subexpr_in_const_expr);
12816 case Builtin::BI__builtin_strlen:
12817 case Builtin::BI__builtin_wcslen: {
12826 case Builtin::BIstrcmp:
12827 case Builtin::BIwcscmp:
12828 case Builtin::BIstrncmp:
12829 case Builtin::BIwcsncmp:
12830 case Builtin::BImemcmp:
12831 case Builtin::BIbcmp:
12832 case Builtin::BIwmemcmp:
12834 if (Info.getLangOpts().CPlusPlus11)
12835 Info.CCEDiag(
E, diag::note_constexpr_invalid_function)
12837 << (
"'" + Info.Ctx.BuiltinInfo.getName(BuiltinOp) +
"'").str();
12839 Info.CCEDiag(
E, diag::note_invalid_subexpr_in_const_expr);
12841 case Builtin::BI__builtin_strcmp:
12842 case Builtin::BI__builtin_wcscmp:
12843 case Builtin::BI__builtin_strncmp:
12844 case Builtin::BI__builtin_wcsncmp:
12845 case Builtin::BI__builtin_memcmp:
12846 case Builtin::BI__builtin_bcmp:
12847 case Builtin::BI__builtin_wmemcmp: {
12848 LValue String1, String2;
12854 if (BuiltinOp != Builtin::BIstrcmp &&
12855 BuiltinOp != Builtin::BIwcscmp &&
12856 BuiltinOp != Builtin::BI__builtin_strcmp &&
12857 BuiltinOp != Builtin::BI__builtin_wcscmp) {
12861 MaxLength = N.getZExtValue();
12865 if (MaxLength == 0u)
12868 if (!String1.checkNullPointerForFoldAccess(Info,
E,
AK_Read) ||
12869 !String2.checkNullPointerForFoldAccess(Info,
E,
AK_Read) ||
12870 String1.Designator.Invalid || String2.Designator.Invalid)
12873 QualType CharTy1 = String1.Designator.getType(Info.Ctx);
12874 QualType CharTy2 = String2.Designator.getType(Info.Ctx);
12876 bool IsRawByte = BuiltinOp == Builtin::BImemcmp ||
12877 BuiltinOp == Builtin::BIbcmp ||
12878 BuiltinOp == Builtin::BI__builtin_memcmp ||
12879 BuiltinOp == Builtin::BI__builtin_bcmp;
12881 assert(IsRawByte ||
12882 (Info.Ctx.hasSameUnqualifiedType(
12884 Info.Ctx.hasSameUnqualifiedType(CharTy1, CharTy2)));
12891 Info.FFDiag(
E, diag::note_constexpr_memcmp_unsupported)
12892 << (
"'" + Info.Ctx.BuiltinInfo.getName(BuiltinOp) +
"'").str()
12893 << CharTy1 << CharTy2;
12897 const auto &ReadCurElems = [&](
APValue &Char1,
APValue &Char2) {
12900 Char1.
isInt() && Char2.isInt();
12902 const auto &AdvanceElems = [&] {
12908 (BuiltinOp != Builtin::BImemcmp && BuiltinOp != Builtin::BIbcmp &&
12909 BuiltinOp != Builtin::BIwmemcmp &&
12910 BuiltinOp != Builtin::BI__builtin_memcmp &&
12911 BuiltinOp != Builtin::BI__builtin_bcmp &&
12912 BuiltinOp != Builtin::BI__builtin_wmemcmp);
12913 bool IsWide = BuiltinOp == Builtin::BIwcscmp ||
12914 BuiltinOp == Builtin::BIwcsncmp ||
12915 BuiltinOp == Builtin::BIwmemcmp ||
12916 BuiltinOp == Builtin::BI__builtin_wcscmp ||
12917 BuiltinOp == Builtin::BI__builtin_wcsncmp ||
12918 BuiltinOp == Builtin::BI__builtin_wmemcmp;
12920 for (; MaxLength; --MaxLength) {
12922 if (!ReadCurElems(Char1, Char2))
12930 if (StopAtNull && !Char1.
getInt())
12932 assert(!(StopAtNull && !Char2.
getInt()));
12933 if (!AdvanceElems())
12940 case Builtin::BI__atomic_always_lock_free:
12941 case Builtin::BI__atomic_is_lock_free:
12942 case Builtin::BI__c11_atomic_is_lock_free: {
12958 if (
Size.isPowerOfTwo()) {
12960 unsigned InlineWidthBits =
12961 Info.Ctx.getTargetInfo().getMaxAtomicInlineWidth();
12962 if (Size <= Info.Ctx.toCharUnitsFromBits(InlineWidthBits)) {
12963 if (BuiltinOp == Builtin::BI__c11_atomic_is_lock_free ||
12969 const Expr *PtrArg =
E->getArg(1);
12975 IntResult.isAligned(
Size.getAsAlign()))
12979 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(PtrArg)) {
12982 if (ICE->getCastKind() == CK_BitCast)
12983 PtrArg = ICE->getSubExpr();
12989 Info.Ctx.getTypeAlignInChars(PointeeType) >= Size) {
12997 return BuiltinOp == Builtin::BI__atomic_always_lock_free ?
13000 case Builtin::BI__builtin_addcb:
13001 case Builtin::BI__builtin_addcs:
13002 case Builtin::BI__builtin_addc:
13003 case Builtin::BI__builtin_addcl:
13004 case Builtin::BI__builtin_addcll:
13005 case Builtin::BI__builtin_subcb:
13006 case Builtin::BI__builtin_subcs:
13007 case Builtin::BI__builtin_subc:
13008 case Builtin::BI__builtin_subcl:
13009 case Builtin::BI__builtin_subcll: {
13010 LValue CarryOutLValue;
13011 APSInt LHS, RHS, CarryIn, CarryOut, Result;
13022 bool FirstOverflowed =
false;
13023 bool SecondOverflowed =
false;
13024 switch (BuiltinOp) {
13026 llvm_unreachable(
"Invalid value for BuiltinOp");
13027 case Builtin::BI__builtin_addcb:
13028 case Builtin::BI__builtin_addcs:
13029 case Builtin::BI__builtin_addc:
13030 case Builtin::BI__builtin_addcl:
13031 case Builtin::BI__builtin_addcll:
13033 LHS.uadd_ov(RHS, FirstOverflowed).uadd_ov(CarryIn, SecondOverflowed);
13035 case Builtin::BI__builtin_subcb:
13036 case Builtin::BI__builtin_subcs:
13037 case Builtin::BI__builtin_subc:
13038 case Builtin::BI__builtin_subcl:
13039 case Builtin::BI__builtin_subcll:
13041 LHS.usub_ov(RHS, FirstOverflowed).usub_ov(CarryIn, SecondOverflowed);
13047 CarryOut = (
uint64_t)(FirstOverflowed | SecondOverflowed);
13053 case Builtin::BI__builtin_add_overflow:
13054 case Builtin::BI__builtin_sub_overflow:
13055 case Builtin::BI__builtin_mul_overflow:
13056 case Builtin::BI__builtin_sadd_overflow:
13057 case Builtin::BI__builtin_uadd_overflow:
13058 case Builtin::BI__builtin_uaddl_overflow:
13059 case Builtin::BI__builtin_uaddll_overflow:
13060 case Builtin::BI__builtin_usub_overflow:
13061 case Builtin::BI__builtin_usubl_overflow:
13062 case Builtin::BI__builtin_usubll_overflow:
13063 case Builtin::BI__builtin_umul_overflow:
13064 case Builtin::BI__builtin_umull_overflow:
13065 case Builtin::BI__builtin_umulll_overflow:
13066 case Builtin::BI__builtin_saddl_overflow:
13067 case Builtin::BI__builtin_saddll_overflow:
13068 case Builtin::BI__builtin_ssub_overflow:
13069 case Builtin::BI__builtin_ssubl_overflow:
13070 case Builtin::BI__builtin_ssubll_overflow:
13071 case Builtin::BI__builtin_smul_overflow:
13072 case Builtin::BI__builtin_smull_overflow:
13073 case Builtin::BI__builtin_smulll_overflow: {
13074 LValue ResultLValue;
13084 bool DidOverflow =
false;
13087 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
13088 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
13089 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
13090 bool IsSigned = LHS.isSigned() || RHS.isSigned() ||
13092 bool AllSigned = LHS.isSigned() && RHS.isSigned() &&
13094 uint64_t LHSSize = LHS.getBitWidth();
13095 uint64_t RHSSize = RHS.getBitWidth();
13096 uint64_t ResultSize = Info.Ctx.getTypeSize(ResultType);
13097 uint64_t MaxBits = std::max(std::max(LHSSize, RHSSize), ResultSize);
13103 if (IsSigned && !AllSigned)
13106 LHS =
APSInt(LHS.extOrTrunc(MaxBits), !IsSigned);
13107 RHS =
APSInt(RHS.extOrTrunc(MaxBits), !IsSigned);
13108 Result =
APSInt(MaxBits, !IsSigned);
13112 switch (BuiltinOp) {
13114 llvm_unreachable(
"Invalid value for BuiltinOp");
13115 case Builtin::BI__builtin_add_overflow:
13116 case Builtin::BI__builtin_sadd_overflow:
13117 case Builtin::BI__builtin_saddl_overflow:
13118 case Builtin::BI__builtin_saddll_overflow:
13119 case Builtin::BI__builtin_uadd_overflow:
13120 case Builtin::BI__builtin_uaddl_overflow:
13121 case Builtin::BI__builtin_uaddll_overflow:
13122 Result = LHS.isSigned() ? LHS.sadd_ov(RHS, DidOverflow)
13123 : LHS.uadd_ov(RHS, DidOverflow);
13125 case Builtin::BI__builtin_sub_overflow:
13126 case Builtin::BI__builtin_ssub_overflow:
13127 case Builtin::BI__builtin_ssubl_overflow:
13128 case Builtin::BI__builtin_ssubll_overflow:
13129 case Builtin::BI__builtin_usub_overflow:
13130 case Builtin::BI__builtin_usubl_overflow:
13131 case Builtin::BI__builtin_usubll_overflow:
13132 Result = LHS.isSigned() ? LHS.ssub_ov(RHS, DidOverflow)
13133 : LHS.usub_ov(RHS, DidOverflow);
13135 case Builtin::BI__builtin_mul_overflow:
13136 case Builtin::BI__builtin_smul_overflow:
13137 case Builtin::BI__builtin_smull_overflow:
13138 case Builtin::BI__builtin_smulll_overflow:
13139 case Builtin::BI__builtin_umul_overflow:
13140 case Builtin::BI__builtin_umull_overflow:
13141 case Builtin::BI__builtin_umulll_overflow:
13142 Result = LHS.isSigned() ? LHS.smul_ov(RHS, DidOverflow)
13143 : LHS.umul_ov(RHS, DidOverflow);
13149 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
13150 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
13151 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
13157 APSInt Temp = Result.extOrTrunc(Info.Ctx.getTypeSize(ResultType));
13160 if (!APSInt::isSameValue(Temp, Result))
13161 DidOverflow =
true;
13176 const LValue &LV) {
13179 if (!LV.getLValueBase())
13184 if (!LV.getLValueDesignator().Invalid &&
13185 !LV.getLValueDesignator().isOnePastTheEnd())
13190 QualType Ty = getType(LV.getLValueBase());
13195 if (LV.getLValueDesignator().Invalid)
13201 return LV.getLValueOffset() == Size;
13211class DataRecursiveIntBinOpEvaluator {
13212 struct EvalResult {
13214 bool Failed =
false;
13216 EvalResult() =
default;
13218 void swap(EvalResult &RHS) {
13220 Failed = RHS.Failed;
13221 RHS.Failed =
false;
13227 EvalResult LHSResult;
13228 enum { AnyExprKind, BinOpKind, BinOpVisitedLHSKind }
Kind;
13231 Job(Job &&) =
default;
13233 void startSpeculativeEval(EvalInfo &Info) {
13234 SpecEvalRAII = SpeculativeEvaluationRAII(Info);
13238 SpeculativeEvaluationRAII SpecEvalRAII;
13243 IntExprEvaluator &IntEval;
13248 DataRecursiveIntBinOpEvaluator(IntExprEvaluator &IntEval,
APValue &Result)
13249 : IntEval(IntEval), Info(IntEval.getEvalInfo()), FinalResult(Result) { }
13256 return E->getOpcode() == BO_Comma ||
E->isLogicalOp() ||
13264 EvalResult PrevResult;
13265 while (!Queue.empty())
13266 process(PrevResult);
13268 if (PrevResult.Failed)
return false;
13270 FinalResult.
swap(PrevResult.Val);
13276 return IntEval.Success(
Value,
E, Result);
13279 return IntEval.Success(
Value,
E, Result);
13282 return IntEval.Error(
E);
13285 return IntEval.Error(
E,
D);
13289 return Info.CCEDiag(
E,
D);
13293 bool VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *
E,
13294 bool &SuppressRHSDiags);
13296 bool VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
13299 void EvaluateExpr(
const Expr *
E, EvalResult &Result) {
13300 Result.Failed = !
Evaluate(Result.Val, Info,
E);
13305 void process(EvalResult &Result);
13307 void enqueue(
const Expr *
E) {
13309 Queue.resize(Queue.size()+1);
13310 Queue.back().E =
E;
13311 Queue.back().Kind = Job::AnyExprKind;
13317bool DataRecursiveIntBinOpEvaluator::
13319 bool &SuppressRHSDiags) {
13320 if (
E->getOpcode() == BO_Comma) {
13322 if (LHSResult.Failed)
13323 return Info.noteSideEffect();
13327 if (
E->isLogicalOp()) {
13332 if (LHSAsBool == (
E->getOpcode() == BO_LOr)) {
13333 Success(LHSAsBool,
E, LHSResult.Val);
13337 LHSResult.Failed =
true;
13341 if (!Info.noteSideEffect())
13347 SuppressRHSDiags =
true;
13356 if (LHSResult.Failed && !Info.noteFailure())
13367 assert(!LVal.
hasLValuePath() &&
"have designator for integer lvalue");
13369 uint64_t Offset64 = Offset.getQuantity();
13370 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
13372 : Offset64 + Index64);
13375bool DataRecursiveIntBinOpEvaluator::
13376 VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
13378 if (
E->getOpcode() == BO_Comma) {
13379 if (RHSResult.Failed)
13381 Result = RHSResult.Val;
13385 if (
E->isLogicalOp()) {
13386 bool lhsResult, rhsResult;
13392 if (
E->getOpcode() == BO_LOr)
13393 return Success(lhsResult || rhsResult,
E, Result);
13395 return Success(lhsResult && rhsResult,
E, Result);
13401 if (rhsResult == (
E->getOpcode() == BO_LOr))
13402 return Success(rhsResult,
E, Result);
13412 if (LHSResult.Failed || RHSResult.Failed)
13415 const APValue &LHSVal = LHSResult.Val;
13416 const APValue &RHSVal = RHSResult.Val;
13426 if (
E->getOpcode() == BO_Add &&
13440 if (!LHSExpr || !RHSExpr)
13442 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
13443 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
13444 if (!LHSAddrExpr || !RHSAddrExpr)
13450 Result =
APValue(LHSAddrExpr, RHSAddrExpr);
13469void DataRecursiveIntBinOpEvaluator::process(EvalResult &Result) {
13470 Job &job = Queue.back();
13472 switch (job.Kind) {
13473 case Job::AnyExprKind: {
13474 if (
const BinaryOperator *Bop = dyn_cast<BinaryOperator>(job.E)) {
13475 if (shouldEnqueue(Bop)) {
13476 job.Kind = Job::BinOpKind;
13477 enqueue(Bop->getLHS());
13482 EvaluateExpr(job.E, Result);
13487 case Job::BinOpKind: {
13489 bool SuppressRHSDiags =
false;
13490 if (!VisitBinOpLHSOnly(Result, Bop, SuppressRHSDiags)) {
13494 if (SuppressRHSDiags)
13495 job.startSpeculativeEval(Info);
13496 job.LHSResult.swap(Result);
13497 job.Kind = Job::BinOpVisitedLHSKind;
13502 case Job::BinOpVisitedLHSKind: {
13506 Result.Failed = !VisitBinOp(job.LHSResult, RHS, Bop, Result.Val);
13512 llvm_unreachable(
"Invalid Job::Kind!");
13516enum class CmpResult {
13525template <
class SuccessCB,
class AfterCB>
13528 SuccessCB &&
Success, AfterCB &&DoAfter) {
13530 assert(
E->isComparisonOp() &&
"expected comparison operator");
13531 assert((
E->getOpcode() == BO_Cmp ||
13533 "unsupported binary expression evaluation");
13534 auto Error = [&](
const Expr *
E) {
13535 Info.FFDiag(
E, diag::note_invalid_subexpr_in_const_expr);
13539 bool IsRelational =
E->isRelationalOp() ||
E->getOpcode() == BO_Cmp;
13540 bool IsEquality =
E->isEqualityOp();
13549 if (!LHSOK && !Info.noteFailure())
13554 return Success(CmpResult::Less,
E);
13556 return Success(CmpResult::Greater,
E);
13557 return Success(CmpResult::Equal,
E);
13561 APFixedPoint LHSFX(Info.Ctx.getFixedPointSemantics(LHSTy));
13562 APFixedPoint RHSFX(Info.Ctx.getFixedPointSemantics(RHSTy));
13565 if (!LHSOK && !Info.noteFailure())
13570 return Success(CmpResult::Less,
E);
13572 return Success(CmpResult::Greater,
E);
13573 return Success(CmpResult::Equal,
E);
13577 ComplexValue LHS, RHS;
13579 if (
E->isAssignmentOp()) {
13586 LHS.makeComplexFloat();
13587 LHS.FloatImag = APFloat(LHS.FloatReal.getSemantics());
13592 if (!LHSOK && !Info.noteFailure())
13598 RHS.makeComplexFloat();
13599 RHS.FloatImag = APFloat(RHS.FloatReal.getSemantics());
13603 if (LHS.isComplexFloat()) {
13604 APFloat::cmpResult CR_r =
13605 LHS.getComplexFloatReal().compare(RHS.getComplexFloatReal());
13606 APFloat::cmpResult CR_i =
13607 LHS.getComplexFloatImag().compare(RHS.getComplexFloatImag());
13608 bool IsEqual = CR_r == APFloat::cmpEqual && CR_i == APFloat::cmpEqual;
13609 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal,
E);
13611 assert(IsEquality &&
"invalid complex comparison");
13612 bool IsEqual = LHS.getComplexIntReal() == RHS.getComplexIntReal() &&
13613 LHS.getComplexIntImag() == RHS.getComplexIntImag();
13614 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal,
E);
13620 APFloat RHS(0.0), LHS(0.0);
13623 if (!LHSOK && !Info.noteFailure())
13629 assert(
E->isComparisonOp() &&
"Invalid binary operator!");
13630 llvm::APFloatBase::cmpResult APFloatCmpResult = LHS.compare(RHS);
13631 if (!Info.InConstantContext &&
13632 APFloatCmpResult == APFloat::cmpUnordered &&
13635 Info.FFDiag(
E, diag::note_constexpr_float_arithmetic_strict);
13638 auto GetCmpRes = [&]() {
13639 switch (APFloatCmpResult) {
13640 case APFloat::cmpEqual:
13641 return CmpResult::Equal;
13642 case APFloat::cmpLessThan:
13643 return CmpResult::Less;
13644 case APFloat::cmpGreaterThan:
13645 return CmpResult::Greater;
13646 case APFloat::cmpUnordered:
13647 return CmpResult::Unordered;
13649 llvm_unreachable(
"Unrecognised APFloat::cmpResult enum");
13655 LValue LHSValue, RHSValue;
13658 if (!LHSOK && !Info.noteFailure())
13667 auto DiagComparison = [&] (
unsigned DiagID,
bool Reversed =
false) {
13668 std::string LHS = LHSValue.toString(Info.Ctx,
E->getLHS()->
getType());
13669 std::string RHS = RHSValue.toString(Info.Ctx,
E->getRHS()->
getType());
13670 Info.FFDiag(
E, DiagID)
13677 return DiagComparison(
13678 diag::note_constexpr_pointer_comparison_unspecified);
13684 if ((!LHSValue.Base && !LHSValue.Offset.isZero()) ||
13685 (!RHSValue.Base && !RHSValue.Offset.isZero()))
13686 return DiagComparison(diag::note_constexpr_pointer_constant_comparison,
13693 LHSValue.Base && RHSValue.Base)
13694 return DiagComparison(diag::note_constexpr_literal_comparison);
13698 return DiagComparison(diag::note_constexpr_pointer_weak_comparison,
13702 if (LHSValue.Base && LHSValue.Offset.isZero() &&
13704 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
13706 if (RHSValue.Base && RHSValue.Offset.isZero() &&
13708 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
13714 return DiagComparison(
13715 diag::note_constexpr_pointer_comparison_zero_sized);
13716 return Success(CmpResult::Unequal,
E);
13719 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
13720 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
13722 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
13723 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
13733 Info.CCEDiag(
E, diag::note_constexpr_void_comparison);
13743 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid && IsRelational) {
13744 bool WasArrayIndex;
13746 getType(LHSValue.Base), LHSDesignator, RHSDesignator, WasArrayIndex);
13753 if (!WasArrayIndex && Mismatch < LHSDesignator.Entries.size() &&
13754 Mismatch < RHSDesignator.Entries.size()) {
13755 const FieldDecl *LF = getAsField(LHSDesignator.Entries[Mismatch]);
13756 const FieldDecl *RF = getAsField(RHSDesignator.Entries[Mismatch]);
13758 Info.CCEDiag(
E, diag::note_constexpr_pointer_comparison_base_classes);
13760 Info.CCEDiag(
E, diag::note_constexpr_pointer_comparison_base_field)
13761 << getAsBaseClass(LHSDesignator.Entries[Mismatch])
13764 Info.CCEDiag(
E, diag::note_constexpr_pointer_comparison_base_field)
13765 << getAsBaseClass(RHSDesignator.Entries[Mismatch])
13770 diag::note_constexpr_pointer_comparison_differing_access)
13778 unsigned PtrSize = Info.Ctx.getTypeSize(LHSTy);
13781 assert(PtrSize <= 64 &&
"Unexpected pointer width");
13782 uint64_t Mask = ~0ULL >> (64 - PtrSize);
13783 CompareLHS &= Mask;
13784 CompareRHS &= Mask;
13789 if (!LHSValue.Base.isNull() && IsRelational) {
13790 QualType BaseTy = getType(LHSValue.Base);
13793 CharUnits Size = Info.Ctx.getTypeSizeInChars(BaseTy);
13794 uint64_t OffsetLimit = Size.getQuantity();
13795 if (CompareLHS > OffsetLimit || CompareRHS > OffsetLimit)
13799 if (CompareLHS < CompareRHS)
13800 return Success(CmpResult::Less,
E);
13801 if (CompareLHS > CompareRHS)
13802 return Success(CmpResult::Greater,
E);
13803 return Success(CmpResult::Equal,
E);
13807 assert(IsEquality &&
"unexpected member pointer operation");
13810 MemberPtr LHSValue, RHSValue;
13813 if (!LHSOK && !Info.noteFailure())
13821 if (LHSValue.getDecl() && LHSValue.getDecl()->isWeak()) {
13822 Info.FFDiag(
E, diag::note_constexpr_mem_pointer_weak_comparison)
13823 << LHSValue.getDecl();
13826 if (RHSValue.getDecl() && RHSValue.getDecl()->isWeak()) {
13827 Info.FFDiag(
E, diag::note_constexpr_mem_pointer_weak_comparison)
13828 << RHSValue.getDecl();
13835 if (!LHSValue.getDecl() || !RHSValue.getDecl()) {
13836 bool Equal = !LHSValue.getDecl() && !RHSValue.getDecl();
13837 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal,
E);
13842 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(LHSValue.getDecl()))
13843 if (MD->isVirtual())
13844 Info.CCEDiag(
E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
13845 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(RHSValue.getDecl()))
13846 if (MD->isVirtual())
13847 Info.CCEDiag(
E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
13853 bool Equal = LHSValue == RHSValue;
13854 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal,
E);
13858 assert(
E->isComparisonOp() &&
"unexpected nullptr operation");
13859 assert(RHSTy->
isNullPtrType() &&
"missing pointer conversion");
13867 return Success(CmpResult::Equal,
E);
13880 case CmpResult::Unequal:
13881 llvm_unreachable(
"should never produce Unequal for three-way comparison");
13882 case CmpResult::Less:
13883 CCR = ComparisonCategoryResult::Less;
13885 case CmpResult::Equal:
13886 CCR = ComparisonCategoryResult::Equal;
13888 case CmpResult::Greater:
13889 CCR = ComparisonCategoryResult::Greater;
13891 case CmpResult::Unordered:
13892 CCR = ComparisonCategoryResult::Unordered;
13906 ConstantExprKind::Normal);
13909 return ExprEvaluatorBaseTy::VisitBinCmp(
E);
13913bool RecordExprEvaluator::VisitCXXParenListInitExpr(
13915 return VisitCXXParenListOrInitListExpr(
E,
E->getInitExprs());
13921 if (
E->isAssignmentOp()) {
13923 if (!Info.noteFailure())
13927 if (DataRecursiveIntBinOpEvaluator::shouldEnqueue(
E))
13928 return DataRecursiveIntBinOpEvaluator(*
this, Result).Traverse(
E);
13932 "DataRecursiveIntBinOpEvaluator should have handled integral types");
13934 if (
E->isComparisonOp()) {
13938 assert((CR != CmpResult::Unequal ||
E->isEqualityOp()) &&
13939 "should only produce Unequal for equality comparisons");
13940 bool IsEqual = CR == CmpResult::Equal,
13941 IsLess = CR == CmpResult::Less,
13942 IsGreater = CR == CmpResult::Greater;
13943 auto Op =
E->getOpcode();
13946 llvm_unreachable(
"unsupported binary operator");
13949 return Success(IsEqual == (Op == BO_EQ),
E);
13955 return Success(IsEqual || IsLess,
E);
13957 return Success(IsEqual || IsGreater,
E);
13961 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
13969 E->getOpcode() == BO_Sub) {
13970 LValue LHSValue, RHSValue;
13973 if (!LHSOK && !Info.noteFailure())
13983 if (!LHSValue.Offset.isZero() || !RHSValue.Offset.isZero())
13985 const Expr *LHSExpr = LHSValue.Base.dyn_cast<
const Expr *>();
13986 const Expr *RHSExpr = RHSValue.Base.dyn_cast<
const Expr *>();
13987 if (!LHSExpr || !RHSExpr)
13989 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
13990 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
13991 if (!LHSAddrExpr || !RHSAddrExpr)
13999 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
14000 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
14002 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
14003 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
14009 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid &&
14012 Info.CCEDiag(
E, diag::note_constexpr_pointer_subtraction_not_same_array);
14024 if (ElementSize.
isZero()) {
14025 Info.FFDiag(
E, diag::note_constexpr_pointer_subtraction_zero_size)
14042 APSInt TrueResult = (LHS - RHS) / ElemSize;
14043 APSInt Result = TrueResult.trunc(Info.Ctx.getIntWidth(
E->
getType()));
14045 if (Result.extend(65) != TrueResult &&
14051 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
14056bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr(
14058 switch(
E->getKind()) {
14059 case UETT_PreferredAlignOf:
14060 case UETT_AlignOf: {
14061 if (
E->isArgumentType())
14069 case UETT_PtrAuthTypeDiscriminator: {
14070 if (
E->getArgumentType()->isDependentType())
14073 Info.Ctx.getPointerAuthTypeDiscriminator(
E->getArgumentType()),
E);
14075 case UETT_VecStep: {
14091 case UETT_DataSizeOf:
14092 case UETT_SizeOf: {
14093 QualType SrcTy =
E->getTypeOfArgument();
14101 E->getKind() == UETT_DataSizeOf ? SizeOfType::DataSizeOf
14102 : SizeOfType::SizeOf)) {
14107 case UETT_OpenMPRequiredSimdAlign:
14108 assert(
E->isArgumentType());
14110 Info.Ctx.toCharUnitsFromBits(
14111 Info.Ctx.getOpenMPDefaultSimdAlign(
E->getArgumentType()))
14114 case UETT_VectorElements: {
14122 if (Info.InConstantContext)
14123 Info.CCEDiag(
E, diag::note_constexpr_non_const_vectorelements)
14130 llvm_unreachable(
"unknown expr/type trait");
14133bool IntExprEvaluator::VisitOffsetOfExpr(
const OffsetOfExpr *OOE) {
14139 for (
unsigned i = 0; i != n; ++i) {
14147 const ArrayType *AT = Info.Ctx.getAsArrayType(CurrentType);
14151 CharUnits ElementSize = Info.Ctx.getTypeSizeInChars(CurrentType);
14152 Result += IdxResult.getSExtValue() * ElementSize;
14165 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
14172 llvm_unreachable(
"dependent __builtin_offsetof");
14188 CurrentType = BaseSpec->
getType();
14202bool IntExprEvaluator::VisitUnaryOperator(
const UnaryOperator *
E) {
14203 switch (
E->getOpcode()) {
14211 return Visit(
E->getSubExpr());
14214 return Visit(
E->getSubExpr());
14216 if (!Visit(
E->getSubExpr()))
14218 if (!Result.isInt())
return Error(
E);
14220 if (
Value.isSigned() &&
Value.isMinSignedValue() &&
E->canOverflow()) {
14221 if (Info.checkingForUndefinedBehavior())
14222 Info.Ctx.getDiagnostics().Report(
E->
getExprLoc(),
14223 diag::warn_integer_constant_overflow)
14235 if (!Visit(
E->getSubExpr()))
14237 if (!Result.isInt())
return Error(
E);
14238 return Success(~Result.getInt(),
E);
14251bool IntExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
14252 const Expr *SubExpr =
E->getSubExpr();
14256 switch (
E->getCastKind()) {
14257 case CK_BaseToDerived:
14258 case CK_DerivedToBase:
14259 case CK_UncheckedDerivedToBase:
14262 case CK_ArrayToPointerDecay:
14263 case CK_FunctionToPointerDecay:
14264 case CK_NullToPointer:
14265 case CK_NullToMemberPointer:
14266 case CK_BaseToDerivedMemberPointer:
14267 case CK_DerivedToBaseMemberPointer:
14268 case CK_ReinterpretMemberPointer:
14269 case CK_ConstructorConversion:
14270 case CK_IntegralToPointer:
14272 case CK_VectorSplat:
14273 case CK_IntegralToFloating:
14274 case CK_FloatingCast:
14275 case CK_CPointerToObjCPointerCast:
14276 case CK_BlockPointerToObjCPointerCast:
14277 case CK_AnyPointerToBlockPointerCast:
14278 case CK_ObjCObjectLValueCast:
14279 case CK_FloatingRealToComplex:
14280 case CK_FloatingComplexToReal:
14281 case CK_FloatingComplexCast:
14282 case CK_FloatingComplexToIntegralComplex:
14283 case CK_IntegralRealToComplex:
14284 case CK_IntegralComplexCast:
14285 case CK_IntegralComplexToFloatingComplex:
14286 case CK_BuiltinFnToFnPtr:
14287 case CK_ZeroToOCLOpaqueType:
14288 case CK_NonAtomicToAtomic:
14289 case CK_AddressSpaceConversion:
14290 case CK_IntToOCLSampler:
14291 case CK_FloatingToFixedPoint:
14292 case CK_FixedPointToFloating:
14293 case CK_FixedPointCast:
14294 case CK_IntegralToFixedPoint:
14295 case CK_MatrixCast:
14296 case CK_HLSLVectorTruncation:
14297 llvm_unreachable(
"invalid cast kind for integral value");
14301 case CK_LValueBitCast:
14302 case CK_ARCProduceObject:
14303 case CK_ARCConsumeObject:
14304 case CK_ARCReclaimReturnedObject:
14305 case CK_ARCExtendBlockObject:
14306 case CK_CopyAndAutoreleaseBlockObject:
14309 case CK_UserDefinedConversion:
14310 case CK_LValueToRValue:
14311 case CK_AtomicToNonAtomic:
14313 case CK_LValueToRValueBitCast:
14314 case CK_HLSLArrayRValue:
14315 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
14317 case CK_MemberPointerToBoolean:
14318 case CK_PointerToBoolean:
14319 case CK_IntegralToBoolean:
14320 case CK_FloatingToBoolean:
14321 case CK_BooleanToSignedIntegral:
14322 case CK_FloatingComplexToBoolean:
14323 case CK_IntegralComplexToBoolean: {
14328 if (BoolResult &&
E->getCastKind() == CK_BooleanToSignedIntegral)
14333 case CK_FixedPointToIntegral: {
14334 APFixedPoint Src(Info.Ctx.getFixedPointSemantics(SrcType));
14338 llvm::APSInt Result = Src.convertToInt(
14339 Info.Ctx.getIntWidth(DestType),
14346 case CK_FixedPointToBoolean: {
14349 if (!
Evaluate(Val, Info, SubExpr))
14354 case CK_IntegralCast: {
14355 if (!Visit(SubExpr))
14358 if (!Result.isInt()) {
14364 if (Result.isAddrLabelDiff())
14365 return Info.Ctx.getTypeSize(DestType) <= Info.Ctx.getTypeSize(SrcType);
14367 return Info.Ctx.getTypeSize(DestType) == Info.Ctx.getTypeSize(SrcType);
14370 if (Info.Ctx.getLangOpts().CPlusPlus && Info.InConstantContext &&
14371 Info.EvalMode == EvalInfo::EM_ConstantExpression &&
14374 bool ConstexprVar =
true;
14381 if (
const auto *VD = dyn_cast_or_null<VarDecl>(
14382 Info.EvaluatingDecl.dyn_cast<
const ValueDecl *>()))
14405 (
Max.slt(Result.getInt().getSExtValue()) ||
14406 Min.sgt(Result.getInt().getSExtValue())))
14407 Info.Ctx.getDiagnostics().Report(
14408 E->
getExprLoc(), diag::warn_constexpr_unscoped_enum_out_of_range)
14409 << llvm::toString(Result.getInt(), 10) <<
Min.getSExtValue()
14410 <<
Max.getSExtValue() << ED;
14412 Max.ult(Result.getInt().getZExtValue()))
14413 Info.Ctx.getDiagnostics().Report(
14414 E->
getExprLoc(), diag::warn_constexpr_unscoped_enum_out_of_range)
14415 << llvm::toString(Result.getInt(), 10) <<
Min.getZExtValue()
14416 <<
Max.getZExtValue() << ED;
14421 Result.getInt()),
E);
14424 case CK_PointerToIntegral: {
14425 CCEDiag(
E, diag::note_constexpr_invalid_cast)
14432 if (LV.getLValueBase()) {
14437 if (Info.Ctx.getTypeSize(DestType) != Info.Ctx.getTypeSize(SrcType))
14440 LV.Designator.setInvalid();
14441 LV.moveInto(Result);
14448 if (!
V.toIntegralConstant(AsInt, SrcType, Info.Ctx))
14449 llvm_unreachable(
"Can't cast this!");
14454 case CK_IntegralComplexToReal: {
14458 return Success(
C.getComplexIntReal(),
E);
14461 case CK_FloatingToIntegral: {
14473 llvm_unreachable(
"unknown cast resulting in integral value");
14481 if (!LV.isComplexInt())
14483 return Success(LV.getComplexIntReal(),
E);
14486 return Visit(
E->getSubExpr());
14494 if (!LV.isComplexInt())
14496 return Success(LV.getComplexIntImag(),
E);
14499 VisitIgnoredValue(
E->getSubExpr());
14511bool IntExprEvaluator::VisitConceptSpecializationExpr(
14516bool IntExprEvaluator::VisitRequiresExpr(
const RequiresExpr *
E) {
14520bool FixedPointExprEvaluator::VisitUnaryOperator(
const UnaryOperator *
E) {
14521 switch (
E->getOpcode()) {
14527 return Visit(
E->getSubExpr());
14529 if (!Visit(
E->getSubExpr()))
return false;
14530 if (!Result.isFixedPoint())
14533 APFixedPoint Negated = Result.getFixedPoint().negate(&Overflowed);
14547bool FixedPointExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
14548 const Expr *SubExpr =
E->getSubExpr();
14551 "Expected destination type to be a fixed point type");
14552 auto DestFXSema = Info.Ctx.getFixedPointSemantics(DestType);
14554 switch (
E->getCastKind()) {
14555 case CK_FixedPointCast: {
14556 APFixedPoint Src(Info.Ctx.getFixedPointSemantics(SubExpr->
getType()));
14560 APFixedPoint Result = Src.convert(DestFXSema, &Overflowed);
14562 if (Info.checkingForUndefinedBehavior())
14563 Info.Ctx.getDiagnostics().Report(
E->
getExprLoc(),
14564 diag::warn_fixedpoint_constant_overflow)
14565 << Result.toString() <<
E->
getType();
14571 case CK_IntegralToFixedPoint: {
14577 APFixedPoint IntResult = APFixedPoint::getFromIntValue(
14578 Src, Info.Ctx.getFixedPointSemantics(DestType), &Overflowed);
14581 if (Info.checkingForUndefinedBehavior())
14582 Info.Ctx.getDiagnostics().Report(
E->
getExprLoc(),
14583 diag::warn_fixedpoint_constant_overflow)
14584 << IntResult.toString() <<
E->
getType();
14591 case CK_FloatingToFixedPoint: {
14597 APFixedPoint Result = APFixedPoint::getFromFloatValue(
14598 Src, Info.Ctx.getFixedPointSemantics(DestType), &Overflowed);
14601 if (Info.checkingForUndefinedBehavior())
14602 Info.Ctx.getDiagnostics().Report(
E->
getExprLoc(),
14603 diag::warn_fixedpoint_constant_overflow)
14604 << Result.toString() <<
E->
getType();
14612 case CK_LValueToRValue:
14613 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
14619bool FixedPointExprEvaluator::VisitBinaryOperator(
const BinaryOperator *
E) {
14620 if (
E->isPtrMemOp() ||
E->isAssignmentOp() ||
E->getOpcode() == BO_Comma)
14621 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
14623 const Expr *LHS =
E->getLHS();
14624 const Expr *RHS =
E->getRHS();
14625 FixedPointSemantics ResultFXSema =
14626 Info.Ctx.getFixedPointSemantics(
E->
getType());
14628 APFixedPoint LHSFX(Info.Ctx.getFixedPointSemantics(LHS->
getType()));
14631 APFixedPoint RHSFX(Info.Ctx.getFixedPointSemantics(RHS->
getType()));
14635 bool OpOverflow =
false, ConversionOverflow =
false;
14636 APFixedPoint Result(LHSFX.getSemantics());
14637 switch (
E->getOpcode()) {
14639 Result = LHSFX.
add(RHSFX, &OpOverflow)
14640 .convert(ResultFXSema, &ConversionOverflow);
14644 Result = LHSFX.sub(RHSFX, &OpOverflow)
14645 .convert(ResultFXSema, &ConversionOverflow);
14649 Result = LHSFX.mul(RHSFX, &OpOverflow)
14650 .convert(ResultFXSema, &ConversionOverflow);
14654 if (RHSFX.getValue() == 0) {
14655 Info.FFDiag(
E, diag::note_expr_divide_by_zero);
14658 Result = LHSFX.div(RHSFX, &OpOverflow)
14659 .convert(ResultFXSema, &ConversionOverflow);
14664 FixedPointSemantics LHSSema = LHSFX.getSemantics();
14665 llvm::APSInt RHSVal = RHSFX.getValue();
14668 LHSSema.getWidth() - (
unsigned)LHSSema.hasUnsignedPadding();
14669 unsigned Amt = RHSVal.getLimitedValue(ShiftBW - 1);
14673 if (RHSVal.isNegative())
14674 Info.CCEDiag(
E, diag::note_constexpr_negative_shift) << RHSVal;
14675 else if (Amt != RHSVal)
14676 Info.CCEDiag(
E, diag::note_constexpr_large_shift)
14677 << RHSVal <<
E->
getType() << ShiftBW;
14679 if (
E->getOpcode() == BO_Shl)
14680 Result = LHSFX.shl(Amt, &OpOverflow);
14682 Result = LHSFX.shr(Amt, &OpOverflow);
14688 if (OpOverflow || ConversionOverflow) {
14689 if (Info.checkingForUndefinedBehavior())
14690 Info.Ctx.getDiagnostics().Report(
E->
getExprLoc(),
14691 diag::warn_fixedpoint_constant_overflow)
14692 << Result.toString() <<
E->
getType();
14704class FloatExprEvaluator
14705 :
public ExprEvaluatorBase<FloatExprEvaluator> {
14708 FloatExprEvaluator(EvalInfo &info, APFloat &result)
14709 : ExprEvaluatorBaseTy(info), Result(result) {}
14712 Result =
V.getFloat();
14716 bool ZeroInitialization(
const Expr *
E) {
14717 Result = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(
E->
getType()));
14738 return FloatExprEvaluator(Info, Result).Visit(
E);
14745 llvm::APFloat &Result) {
14747 if (!S)
return false;
14754 if (S->getString().empty())
14755 fill = llvm::APInt(32, 0);
14756 else if (S->getString().getAsInteger(0, fill))
14761 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
14763 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
14771 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
14773 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
14779bool FloatExprEvaluator::VisitCallExpr(
const CallExpr *
E) {
14780 if (!IsConstantEvaluatedBuiltinCall(
E))
14781 return ExprEvaluatorBaseTy::VisitCallExpr(
E);
14783 switch (
E->getBuiltinCallee()) {
14787 case Builtin::BI__builtin_huge_val:
14788 case Builtin::BI__builtin_huge_valf:
14789 case Builtin::BI__builtin_huge_vall:
14790 case Builtin::BI__builtin_huge_valf16:
14791 case Builtin::BI__builtin_huge_valf128:
14792 case Builtin::BI__builtin_inf:
14793 case Builtin::BI__builtin_inff:
14794 case Builtin::BI__builtin_infl:
14795 case Builtin::BI__builtin_inff16:
14796 case Builtin::BI__builtin_inff128: {
14797 const llvm::fltSemantics &Sem =
14798 Info.Ctx.getFloatTypeSemantics(
E->
getType());
14799 Result = llvm::APFloat::getInf(Sem);
14803 case Builtin::BI__builtin_nans:
14804 case Builtin::BI__builtin_nansf:
14805 case Builtin::BI__builtin_nansl:
14806 case Builtin::BI__builtin_nansf16:
14807 case Builtin::BI__builtin_nansf128:
14813 case Builtin::BI__builtin_nan:
14814 case Builtin::BI__builtin_nanf:
14815 case Builtin::BI__builtin_nanl:
14816 case Builtin::BI__builtin_nanf16:
14817 case Builtin::BI__builtin_nanf128:
14825 case Builtin::BI__builtin_fabs:
14826 case Builtin::BI__builtin_fabsf:
14827 case Builtin::BI__builtin_fabsl:
14828 case Builtin::BI__builtin_fabsf128:
14837 if (Result.isNegative())
14838 Result.changeSign();
14841 case Builtin::BI__arithmetic_fence:
14848 case Builtin::BI__builtin_copysign:
14849 case Builtin::BI__builtin_copysignf:
14850 case Builtin::BI__builtin_copysignl:
14851 case Builtin::BI__builtin_copysignf128: {
14856 Result.copySign(RHS);
14860 case Builtin::BI__builtin_fmax:
14861 case Builtin::BI__builtin_fmaxf:
14862 case Builtin::BI__builtin_fmaxl:
14863 case Builtin::BI__builtin_fmaxf16:
14864 case Builtin::BI__builtin_fmaxf128: {
14871 if (Result.isZero() && RHS.isZero() && Result.isNegative())
14873 else if (Result.isNaN() || RHS > Result)
14878 case Builtin::BI__builtin_fmin:
14879 case Builtin::BI__builtin_fminf:
14880 case Builtin::BI__builtin_fminl:
14881 case Builtin::BI__builtin_fminf16:
14882 case Builtin::BI__builtin_fminf128: {
14889 if (Result.isZero() && RHS.isZero() && RHS.isNegative())
14891 else if (Result.isNaN() || RHS < Result)
14898bool FloatExprEvaluator::VisitUnaryReal(
const UnaryOperator *
E) {
14903 Result = CV.FloatReal;
14907 return Visit(
E->getSubExpr());
14910bool FloatExprEvaluator::VisitUnaryImag(
const UnaryOperator *
E) {
14915 Result = CV.FloatImag;
14919 VisitIgnoredValue(
E->getSubExpr());
14920 const llvm::fltSemantics &Sem = Info.Ctx.getFloatTypeSemantics(
E->
getType());
14921 Result = llvm::APFloat::getZero(Sem);
14925bool FloatExprEvaluator::VisitUnaryOperator(
const UnaryOperator *
E) {
14926 switch (
E->getOpcode()) {
14927 default:
return Error(
E);
14936 Result.changeSign();
14941bool FloatExprEvaluator::VisitBinaryOperator(
const BinaryOperator *
E) {
14942 if (
E->isPtrMemOp() ||
E->isAssignmentOp() ||
E->getOpcode() == BO_Comma)
14943 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
14947 if (!LHSOK && !Info.noteFailure())
14954 Result =
E->getValue();
14958bool FloatExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
14959 const Expr* SubExpr =
E->getSubExpr();
14961 switch (
E->getCastKind()) {
14963 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
14965 case CK_IntegralToFloating: {
14968 Info.Ctx.getLangOpts());
14974 case CK_FixedPointToFloating: {
14975 APFixedPoint FixResult(Info.Ctx.getFixedPointSemantics(SubExpr->
getType()));
14979 FixResult.convertToFloat(Info.Ctx.getFloatTypeSemantics(
E->
getType()));
14983 case CK_FloatingCast: {
14984 if (!Visit(SubExpr))
14990 case CK_FloatingComplexToReal: {
14994 Result =
V.getComplexFloatReal();
15005class ComplexExprEvaluator
15006 :
public ExprEvaluatorBase<ComplexExprEvaluator> {
15007 ComplexValue &Result;
15010 ComplexExprEvaluator(EvalInfo &info, ComplexValue &Result)
15011 : ExprEvaluatorBaseTy(info), Result(Result) {}
15018 bool ZeroInitialization(
const Expr *
E);
15037 return ComplexExprEvaluator(Info, Result).Visit(
E);
15040bool ComplexExprEvaluator::ZeroInitialization(
const Expr *
E) {
15043 Result.makeComplexFloat();
15044 APFloat Zero = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(ElemTy));
15045 Result.FloatReal =
Zero;
15046 Result.FloatImag =
Zero;
15048 Result.makeComplexInt();
15049 APSInt Zero = Info.Ctx.MakeIntValue(0, ElemTy);
15050 Result.IntReal =
Zero;
15051 Result.IntImag =
Zero;
15057 const Expr* SubExpr =
E->getSubExpr();
15060 Result.makeComplexFloat();
15061 APFloat &Imag = Result.FloatImag;
15065 Result.FloatReal =
APFloat(Imag.getSemantics());
15069 "Unexpected imaginary literal.");
15071 Result.makeComplexInt();
15072 APSInt &Imag = Result.IntImag;
15076 Result.IntReal =
APSInt(Imag.getBitWidth(), !Imag.isSigned());
15081bool ComplexExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
15083 switch (
E->getCastKind()) {
15085 case CK_BaseToDerived:
15086 case CK_DerivedToBase:
15087 case CK_UncheckedDerivedToBase:
15090 case CK_ArrayToPointerDecay:
15091 case CK_FunctionToPointerDecay:
15092 case CK_NullToPointer:
15093 case CK_NullToMemberPointer:
15094 case CK_BaseToDerivedMemberPointer:
15095 case CK_DerivedToBaseMemberPointer:
15096 case CK_MemberPointerToBoolean:
15097 case CK_ReinterpretMemberPointer:
15098 case CK_ConstructorConversion:
15099 case CK_IntegralToPointer:
15100 case CK_PointerToIntegral:
15101 case CK_PointerToBoolean:
15103 case CK_VectorSplat:
15104 case CK_IntegralCast:
15105 case CK_BooleanToSignedIntegral:
15106 case CK_IntegralToBoolean:
15107 case CK_IntegralToFloating:
15108 case CK_FloatingToIntegral:
15109 case CK_FloatingToBoolean:
15110 case CK_FloatingCast:
15111 case CK_CPointerToObjCPointerCast:
15112 case CK_BlockPointerToObjCPointerCast:
15113 case CK_AnyPointerToBlockPointerCast:
15114 case CK_ObjCObjectLValueCast:
15115 case CK_FloatingComplexToReal:
15116 case CK_FloatingComplexToBoolean:
15117 case CK_IntegralComplexToReal:
15118 case CK_IntegralComplexToBoolean:
15119 case CK_ARCProduceObject:
15120 case CK_ARCConsumeObject:
15121 case CK_ARCReclaimReturnedObject:
15122 case CK_ARCExtendBlockObject:
15123 case CK_CopyAndAutoreleaseBlockObject:
15124 case CK_BuiltinFnToFnPtr:
15125 case CK_ZeroToOCLOpaqueType:
15126 case CK_NonAtomicToAtomic:
15127 case CK_AddressSpaceConversion:
15128 case CK_IntToOCLSampler:
15129 case CK_FloatingToFixedPoint:
15130 case CK_FixedPointToFloating:
15131 case CK_FixedPointCast:
15132 case CK_FixedPointToBoolean:
15133 case CK_FixedPointToIntegral:
15134 case CK_IntegralToFixedPoint:
15135 case CK_MatrixCast:
15136 case CK_HLSLVectorTruncation:
15137 llvm_unreachable(
"invalid cast kind for complex value");
15139 case CK_LValueToRValue:
15140 case CK_AtomicToNonAtomic:
15142 case CK_LValueToRValueBitCast:
15143 case CK_HLSLArrayRValue:
15144 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
15147 case CK_LValueBitCast:
15148 case CK_UserDefinedConversion:
15151 case CK_FloatingRealToComplex: {
15152 APFloat &Real = Result.FloatReal;
15156 Result.makeComplexFloat();
15157 Result.FloatImag =
APFloat(Real.getSemantics());
15161 case CK_FloatingComplexCast: {
15162 if (!Visit(
E->getSubExpr()))
15173 case CK_FloatingComplexToIntegralComplex: {
15174 if (!Visit(
E->getSubExpr()))
15180 Result.makeComplexInt();
15182 To, Result.IntReal) &&
15184 To, Result.IntImag);
15187 case CK_IntegralRealToComplex: {
15188 APSInt &Real = Result.IntReal;
15192 Result.makeComplexInt();
15193 Result.IntImag =
APSInt(Real.getBitWidth(), !Real.isSigned());
15197 case CK_IntegralComplexCast: {
15198 if (!Visit(
E->getSubExpr()))
15210 case CK_IntegralComplexToFloatingComplex: {
15211 if (!Visit(
E->getSubExpr()))
15215 Info.Ctx.getLangOpts());
15219 Result.makeComplexFloat();
15221 To, Result.FloatReal) &&
15223 To, Result.FloatImag);
15227 llvm_unreachable(
"unknown cast resulting in complex value");
15231 APFloat &ResR, APFloat &ResI) {
15237 APFloat AC = A *
C;
15238 APFloat BD = B *
D;
15239 APFloat AD = A *
D;
15240 APFloat BC = B *
C;
15243 if (ResR.isNaN() && ResI.isNaN()) {
15244 bool Recalc =
false;
15245 if (A.isInfinity() || B.isInfinity()) {
15246 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
15248 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
15251 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
15253 D = APFloat::copySign(APFloat(
D.getSemantics()),
D);
15256 if (
C.isInfinity() ||
D.isInfinity()) {
15257 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
15259 D = APFloat::copySign(APFloat(
D.getSemantics(),
D.isInfinity() ? 1 : 0),
15262 A = APFloat::copySign(APFloat(A.getSemantics()), A);
15264 B = APFloat::copySign(APFloat(B.getSemantics()), B);
15267 if (!Recalc && (AC.isInfinity() || BD.isInfinity() || AD.isInfinity() ||
15268 BC.isInfinity())) {
15270 A = APFloat::copySign(APFloat(A.getSemantics()), A);
15272 B = APFloat::copySign(APFloat(B.getSemantics()), B);
15274 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
15276 D = APFloat::copySign(APFloat(
D.getSemantics()),
D);
15280 ResR = APFloat::getInf(A.getSemantics()) * (A *
C - B *
D);
15281 ResI = APFloat::getInf(A.getSemantics()) * (A *
D + B *
C);
15287 APFloat &ResR, APFloat &ResI) {
15294 APFloat MaxCD = maxnum(
abs(
C),
abs(
D));
15295 if (MaxCD.isFinite()) {
15296 DenomLogB =
ilogb(MaxCD);
15297 C =
scalbn(
C, -DenomLogB, APFloat::rmNearestTiesToEven);
15298 D =
scalbn(
D, -DenomLogB, APFloat::rmNearestTiesToEven);
15300 APFloat Denom =
C *
C +
D *
D;
15302 scalbn((A *
C + B *
D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
15304 scalbn((B *
C - A *
D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
15305 if (ResR.isNaN() && ResI.isNaN()) {
15306 if (Denom.isPosZero() && (!A.isNaN() || !B.isNaN())) {
15307 ResR = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * A;
15308 ResI = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * B;
15309 }
else if ((A.isInfinity() || B.isInfinity()) &&
C.isFinite() &&
15311 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
15313 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
15315 ResR = APFloat::getInf(ResR.getSemantics()) * (A *
C + B *
D);
15316 ResI = APFloat::getInf(ResI.getSemantics()) * (B *
C - A *
D);
15317 }
else if (MaxCD.isInfinity() && A.isFinite() && B.isFinite()) {
15318 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
15320 D = APFloat::copySign(APFloat(
D.getSemantics(),
D.isInfinity() ? 1 : 0),
15322 ResR = APFloat::getZero(ResR.getSemantics()) * (A *
C + B *
D);
15323 ResI = APFloat::getZero(ResI.getSemantics()) * (B *
C - A *
D);
15328bool ComplexExprEvaluator::VisitBinaryOperator(
const BinaryOperator *
E) {
15329 if (
E->isPtrMemOp() ||
E->isAssignmentOp() ||
E->getOpcode() == BO_Comma)
15330 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
15334 bool LHSReal =
false, RHSReal =
false;
15339 APFloat &Real = Result.FloatReal;
15342 Result.makeComplexFloat();
15343 Result.FloatImag =
APFloat(Real.getSemantics());
15346 LHSOK = Visit(
E->getLHS());
15348 if (!LHSOK && !Info.noteFailure())
15354 APFloat &Real = RHS.FloatReal;
15357 RHS.makeComplexFloat();
15358 RHS.FloatImag =
APFloat(Real.getSemantics());
15362 assert(!(LHSReal && RHSReal) &&
15363 "Cannot have both operands of a complex operation be real.");
15364 switch (
E->getOpcode()) {
15365 default:
return Error(
E);
15367 if (Result.isComplexFloat()) {
15368 Result.getComplexFloatReal().
add(RHS.getComplexFloatReal(),
15369 APFloat::rmNearestTiesToEven);
15371 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
15373 Result.getComplexFloatImag().
add(RHS.getComplexFloatImag(),
15374 APFloat::rmNearestTiesToEven);
15376 Result.getComplexIntReal() += RHS.getComplexIntReal();
15377 Result.getComplexIntImag() += RHS.getComplexIntImag();
15381 if (Result.isComplexFloat()) {
15382 Result.getComplexFloatReal().subtract(RHS.getComplexFloatReal(),
15383 APFloat::rmNearestTiesToEven);
15385 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
15386 Result.getComplexFloatImag().changeSign();
15387 }
else if (!RHSReal) {
15388 Result.getComplexFloatImag().subtract(RHS.getComplexFloatImag(),
15389 APFloat::rmNearestTiesToEven);
15392 Result.getComplexIntReal() -= RHS.getComplexIntReal();
15393 Result.getComplexIntImag() -= RHS.getComplexIntImag();
15397 if (Result.isComplexFloat()) {
15402 ComplexValue LHS = Result;
15403 APFloat &A = LHS.getComplexFloatReal();
15404 APFloat &B = LHS.getComplexFloatImag();
15405 APFloat &
C = RHS.getComplexFloatReal();
15406 APFloat &
D = RHS.getComplexFloatImag();
15407 APFloat &ResR = Result.getComplexFloatReal();
15408 APFloat &ResI = Result.getComplexFloatImag();
15410 assert(!RHSReal &&
"Cannot have two real operands for a complex op!");
15418 }
else if (RHSReal) {
15430 ComplexValue LHS = Result;
15431 Result.getComplexIntReal() =
15432 (LHS.getComplexIntReal() * RHS.getComplexIntReal() -
15433 LHS.getComplexIntImag() * RHS.getComplexIntImag());
15434 Result.getComplexIntImag() =
15435 (LHS.getComplexIntReal() * RHS.getComplexIntImag() +
15436 LHS.getComplexIntImag() * RHS.getComplexIntReal());
15440 if (Result.isComplexFloat()) {
15445 ComplexValue LHS = Result;
15446 APFloat &A = LHS.getComplexFloatReal();
15447 APFloat &B = LHS.getComplexFloatImag();
15448 APFloat &
C = RHS.getComplexFloatReal();
15449 APFloat &
D = RHS.getComplexFloatImag();
15450 APFloat &ResR = Result.getComplexFloatReal();
15451 APFloat &ResI = Result.getComplexFloatImag();
15463 B = APFloat::getZero(A.getSemantics());
15468 if (RHS.getComplexIntReal() == 0 && RHS.getComplexIntImag() == 0)
15469 return Error(
E, diag::note_expr_divide_by_zero);
15471 ComplexValue LHS = Result;
15472 APSInt Den = RHS.getComplexIntReal() * RHS.getComplexIntReal() +
15473 RHS.getComplexIntImag() * RHS.getComplexIntImag();
15474 Result.getComplexIntReal() =
15475 (LHS.getComplexIntReal() * RHS.getComplexIntReal() +
15476 LHS.getComplexIntImag() * RHS.getComplexIntImag()) / Den;
15477 Result.getComplexIntImag() =
15478 (LHS.getComplexIntImag() * RHS.getComplexIntReal() -
15479 LHS.getComplexIntReal() * RHS.getComplexIntImag()) / Den;
15487bool ComplexExprEvaluator::VisitUnaryOperator(
const UnaryOperator *
E) {
15489 if (!Visit(
E->getSubExpr()))
15492 switch (
E->getOpcode()) {
15501 if (Result.isComplexFloat()) {
15502 Result.getComplexFloatReal().changeSign();
15503 Result.getComplexFloatImag().changeSign();
15506 Result.getComplexIntReal() = -Result.getComplexIntReal();
15507 Result.getComplexIntImag() = -Result.getComplexIntImag();
15511 if (Result.isComplexFloat())
15512 Result.getComplexFloatImag().changeSign();
15514 Result.getComplexIntImag() = -Result.getComplexIntImag();
15519bool ComplexExprEvaluator::VisitInitListExpr(
const InitListExpr *
E) {
15520 if (
E->getNumInits() == 2) {
15522 Result.makeComplexFloat();
15528 Result.makeComplexInt();
15536 return ExprEvaluatorBaseTy::VisitInitListExpr(
E);
15539bool ComplexExprEvaluator::VisitCallExpr(
const CallExpr *
E) {
15540 if (!IsConstantEvaluatedBuiltinCall(
E))
15541 return ExprEvaluatorBaseTy::VisitCallExpr(
E);
15543 switch (
E->getBuiltinCallee()) {
15544 case Builtin::BI__builtin_complex:
15545 Result.makeComplexFloat();
15563class AtomicExprEvaluator :
15564 public ExprEvaluatorBase<AtomicExprEvaluator> {
15565 const LValue *
This;
15568 AtomicExprEvaluator(EvalInfo &Info,
const LValue *This,
APValue &Result)
15569 : ExprEvaluatorBaseTy(Info),
This(
This), Result(Result) {}
15576 bool ZeroInitialization(
const Expr *
E) {
15585 bool VisitCastExpr(
const CastExpr *
E) {
15586 switch (
E->getCastKind()) {
15588 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
15589 case CK_NullToPointer:
15590 VisitIgnoredValue(
E->getSubExpr());
15591 return ZeroInitialization(
E);
15592 case CK_NonAtomicToAtomic:
15594 :
Evaluate(Result, Info,
E->getSubExpr());
15604 return AtomicExprEvaluator(Info, This, Result).Visit(
E);
15613class VoidExprEvaluator
15614 :
public ExprEvaluatorBase<VoidExprEvaluator> {
15616 VoidExprEvaluator(EvalInfo &Info) : ExprEvaluatorBaseTy(Info) {}
15620 bool ZeroInitialization(
const Expr *
E) {
return true; }
15622 bool VisitCastExpr(
const CastExpr *
E) {
15623 switch (
E->getCastKind()) {
15625 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
15627 VisitIgnoredValue(
E->getSubExpr());
15632 bool VisitCallExpr(
const CallExpr *
E) {
15633 if (!IsConstantEvaluatedBuiltinCall(
E))
15634 return ExprEvaluatorBaseTy::VisitCallExpr(
E);
15636 switch (
E->getBuiltinCallee()) {
15637 case Builtin::BI__assume:
15638 case Builtin::BI__builtin_assume:
15642 case Builtin::BI__builtin_operator_delete:
15654bool VoidExprEvaluator::VisitCXXDeleteExpr(
const CXXDeleteExpr *
E) {
15656 if (Info.SpeculativeEvaluationDepth)
15661 Info.FFDiag(
E, diag::note_constexpr_new_non_replaceable)
15662 << isa<CXXMethodDecl>(OperatorDelete) << OperatorDelete;
15666 const Expr *Arg =
E->getArgument();
15671 if (
Pointer.Designator.Invalid)
15675 if (
Pointer.isNullPointer()) {
15679 if (!Info.getLangOpts().CPlusPlus20)
15680 Info.CCEDiag(
E, diag::note_constexpr_new);
15685 Info,
E,
Pointer,
E->isArrayForm() ? DynAlloc::ArrayNew : DynAlloc::New);
15692 if (!
E->isArrayForm() &&
Pointer.Designator.Entries.size() != 0 &&
15694 Info.FFDiag(
E, diag::note_constexpr_delete_base_nonvirt_dtor)
15701 if (!
E->isArrayForm() && !
E->isGlobalDelete()) {
15703 if (VirtualDelete &&
15705 Info.FFDiag(
E, diag::note_constexpr_new_non_replaceable)
15706 << isa<CXXMethodDecl>(VirtualDelete) << VirtualDelete;
15712 (*Alloc)->Value, AllocType))
15720 Info.FFDiag(
E, diag::note_constexpr_double_delete);
15730 return VoidExprEvaluator(Info).Visit(
E);
15746 LV.moveInto(Result);
15751 if (!IntExprEvaluator(Info, Result).Visit(
E))
15757 LV.moveInto(Result);
15759 llvm::APFloat F(0.0);
15767 C.moveInto(Result);
15769 if (!FixedPointExprEvaluator(Info, Result).Visit(
E))
return false;
15774 P.moveInto(Result);
15779 Info.CurrentCall->createTemporary(
E,
T, ScopeKind::FullExpression, LV);
15786 Info.CurrentCall->createTemporary(
E,
T, ScopeKind::FullExpression, LV);
15791 if (!Info.getLangOpts().CPlusPlus11)
15792 Info.CCEDiag(
E, diag::note_constexpr_nonliteral)
15797 QualType Unqual =
T.getAtomicUnqualifiedType();
15801 E, Unqual, ScopeKind::FullExpression, LV);
15809 }
else if (Info.getLangOpts().CPlusPlus11) {
15810 Info.FFDiag(
E, diag::note_constexpr_nonliteral) <<
E->
getType();
15813 Info.FFDiag(
E, diag::note_invalid_subexpr_in_const_expr);
15824 const Expr *
E,
bool AllowNonLiteralTypes) {
15839 QualType Unqual =
T.getAtomicUnqualifiedType();
15860 if (Info.EnableNewConstInterp) {
15861 if (!Info.Ctx.getInterpContext().evaluateAsRValue(Info,
E, Result))
15864 ConstantExprKind::Normal);
15873 LV.setFrom(Info.Ctx, Result);
15880 ConstantExprKind::Normal) &&
15890 L->getType()->isUnsignedIntegerType()));
15895 if (
const auto *L = dyn_cast<CXXBoolLiteralExpr>(Exp)) {
15901 if (
const auto *CE = dyn_cast<ConstantExpr>(Exp)) {
15902 if (CE->hasAPValueResult()) {
15903 APValue APV = CE->getAPValueResult();
15905 Result.Val = std::move(APV);
15981 bool InConstantContext)
const {
15982 assert(!isValueDependent() &&
15983 "Expression evaluator can't be called on a dependent expression.");
15984 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsRValue");
15985 EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
15986 Info.InConstantContext = InConstantContext;
15987 return ::EvaluateAsRValue(
this, Result, Ctx, Info);
15991 bool InConstantContext)
const {
15992 assert(!isValueDependent() &&
15993 "Expression evaluator can't be called on a dependent expression.");
15994 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsBooleanCondition");
16002 bool InConstantContext)
const {
16003 assert(!isValueDependent() &&
16004 "Expression evaluator can't be called on a dependent expression.");
16005 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsInt");
16006 EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
16007 Info.InConstantContext = InConstantContext;
16008 return ::EvaluateAsInt(
this, Result, Ctx, AllowSideEffects, Info);
16013 bool InConstantContext)
const {
16014 assert(!isValueDependent() &&
16015 "Expression evaluator can't be called on a dependent expression.");
16016 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFixedPoint");
16017 EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
16018 Info.InConstantContext = InConstantContext;
16019 return ::EvaluateAsFixedPoint(
this, Result, Ctx, AllowSideEffects, Info);
16024 bool InConstantContext)
const {
16025 assert(!isValueDependent() &&
16026 "Expression evaluator can't be called on a dependent expression.");
16028 if (!getType()->isRealFloatingType())
16031 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFloat");
16043 bool InConstantContext)
const {
16044 assert(!isValueDependent() &&
16045 "Expression evaluator can't be called on a dependent expression.");
16047 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsLValue");
16048 EvalInfo Info(Ctx, Result, EvalInfo::EM_ConstantFold);
16049 Info.InConstantContext = InConstantContext;
16052 if (!
EvaluateLValue(
this, LV, Info) || !Info.discardCleanups() ||
16053 Result.HasSideEffects ||
16056 ConstantExprKind::Normal, CheckedTemps))
16059 LV.moveInto(Result.Val);
16066 bool IsConstantDestruction) {
16067 EvalInfo Info(Ctx, EStatus,
16068 IsConstantDestruction ? EvalInfo::EM_ConstantExpression
16069 : EvalInfo::EM_ConstantFold);
16070 Info.setEvaluatingDecl(
Base, DestroyedValue,
16071 EvalInfo::EvaluatingDeclKind::Dtor);
16072 Info.InConstantContext = IsConstantDestruction;
16081 if (!Info.discardCleanups())
16082 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
16089 assert(!isValueDependent() &&
16090 "Expression evaluator can't be called on a dependent expression.");
16095 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsConstantExpr");
16096 EvalInfo::EvaluationMode EM = EvalInfo::EM_ConstantExpression;
16097 EvalInfo Info(Ctx, Result, EM);
16098 Info.InConstantContext =
true;
16100 if (Info.EnableNewConstInterp) {
16101 if (!Info.Ctx.getInterpContext().evaluate(Info,
this, Result.Val))
16104 getStorageType(Ctx,
this), Result.Val, Kind);
16109 if (Kind == ConstantExprKind::ClassTemplateArgument)
16117 Info.setEvaluatingDecl(
Base, Result.Val);
16119 if (Info.EnableNewConstInterp) {
16120 if (!Info.Ctx.getInterpContext().evaluateAsRValue(Info,
this, Result.Val))
16129 FullExpressionRAII
Scope(Info);
16131 Result.HasSideEffects || !
Scope.destroy())
16134 if (!Info.discardCleanups())
16135 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
16146 if (Kind == ConstantExprKind::ClassTemplateArgument &&
16149 Result.HasSideEffects)) {
16161 bool IsConstantInitialization)
const {
16162 assert(!isValueDependent() &&
16163 "Expression evaluator can't be called on a dependent expression.");
16165 llvm::TimeTraceScope TimeScope(
"EvaluateAsInitializer", [&] {
16167 llvm::raw_string_ostream OS(Name);
16173 EStatus.
Diag = &Notes;
16175 EvalInfo Info(Ctx, EStatus,
16176 (IsConstantInitialization &&
16178 ? EvalInfo::EM_ConstantExpression
16179 : EvalInfo::EM_ConstantFold);
16180 Info.setEvaluatingDecl(VD,
Value);
16181 Info.InConstantContext = IsConstantInitialization;
16186 if (Info.EnableNewConstInterp) {
16187 auto &InterpCtx =
const_cast<ASTContext &
>(Ctx).getInterpContext();
16188 if (!InterpCtx.evaluateAsInitializer(Info, VD,
Value))
16192 ConstantExprKind::Normal);
16207 FullExpressionRAII
Scope(Info);
16210 EStatus.HasSideEffects)
16216 Info.performLifetimeExtension();
16218 if (!Info.discardCleanups())
16219 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
16223 ConstantExprKind::Normal) &&
16230 EStatus.
Diag = &Notes;
16234 bool IsConstantDestruction = hasConstantInitialization();
16240 if (getEvaluatedValue() && !getEvaluatedValue()->isAbsent())
16241 DestroyedValue = *getEvaluatedValue();
16246 getType(), getLocation(), EStatus,
16247 IsConstantDestruction) ||
16251 ensureEvaluatedStmt()->HasConstantDestruction =
true;
16258 assert(!isValueDependent() &&
16259 "Expression evaluator can't be called on a dependent expression.");
16268 assert(!isValueDependent() &&
16269 "Expression evaluator can't be called on a dependent expression.");
16271 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstInt");
16274 EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
16275 Info.InConstantContext =
true;
16279 assert(Result &&
"Could not evaluate expression");
16280 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
16282 return EVResult.Val.getInt();
16287 assert(!isValueDependent() &&
16288 "Expression evaluator can't be called on a dependent expression.");
16290 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstIntCheckOverflow");
16293 EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
16294 Info.InConstantContext =
true;
16295 Info.CheckingForUndefinedBehavior =
true;
16299 assert(Result &&
"Could not evaluate expression");
16300 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
16302 return EVResult.Val.getInt();
16306 assert(!isValueDependent() &&
16307 "Expression evaluator can't be called on a dependent expression.");
16309 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateForOverflow");
16313 EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
16314 Info.CheckingForUndefinedBehavior =
true;
16347 IK_ICEIfUnevaluated,
16363static ICEDiag
Worst(ICEDiag A, ICEDiag B) {
return A.Kind >= B.Kind ? A : B; }
16368 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
16370 Info.InConstantContext =
true;
16384#define ABSTRACT_STMT(Node)
16385#define STMT(Node, Base) case Expr::Node##Class:
16386#define EXPR(Node, Base)
16387#include "clang/AST/StmtNodes.inc"
16388 case Expr::PredefinedExprClass:
16389 case Expr::FloatingLiteralClass:
16390 case Expr::ImaginaryLiteralClass:
16391 case Expr::StringLiteralClass:
16392 case Expr::ArraySubscriptExprClass:
16393 case Expr::MatrixSubscriptExprClass:
16394 case Expr::ArraySectionExprClass:
16395 case Expr::OMPArrayShapingExprClass:
16396 case Expr::OMPIteratorExprClass:
16397 case Expr::MemberExprClass:
16398 case Expr::CompoundAssignOperatorClass:
16399 case Expr::CompoundLiteralExprClass:
16400 case Expr::ExtVectorElementExprClass:
16401 case Expr::DesignatedInitExprClass:
16402 case Expr::ArrayInitLoopExprClass:
16403 case Expr::ArrayInitIndexExprClass:
16404 case Expr::NoInitExprClass:
16405 case Expr::DesignatedInitUpdateExprClass:
16406 case Expr::ImplicitValueInitExprClass:
16407 case Expr::ParenListExprClass:
16408 case Expr::VAArgExprClass:
16409 case Expr::AddrLabelExprClass:
16410 case Expr::StmtExprClass:
16411 case Expr::CXXMemberCallExprClass:
16412 case Expr::CUDAKernelCallExprClass:
16413 case Expr::CXXAddrspaceCastExprClass:
16414 case Expr::CXXDynamicCastExprClass:
16415 case Expr::CXXTypeidExprClass:
16416 case Expr::CXXUuidofExprClass:
16417 case Expr::MSPropertyRefExprClass:
16418 case Expr::MSPropertySubscriptExprClass:
16419 case Expr::CXXNullPtrLiteralExprClass:
16420 case Expr::UserDefinedLiteralClass:
16421 case Expr::CXXThisExprClass:
16422 case Expr::CXXThrowExprClass:
16423 case Expr::CXXNewExprClass:
16424 case Expr::CXXDeleteExprClass:
16425 case Expr::CXXPseudoDestructorExprClass:
16426 case Expr::UnresolvedLookupExprClass:
16427 case Expr::TypoExprClass:
16428 case Expr::RecoveryExprClass:
16429 case Expr::DependentScopeDeclRefExprClass:
16430 case Expr::CXXConstructExprClass:
16431 case Expr::CXXInheritedCtorInitExprClass:
16432 case Expr::CXXStdInitializerListExprClass:
16433 case Expr::CXXBindTemporaryExprClass:
16434 case Expr::ExprWithCleanupsClass:
16435 case Expr::CXXTemporaryObjectExprClass:
16436 case Expr::CXXUnresolvedConstructExprClass:
16437 case Expr::CXXDependentScopeMemberExprClass:
16438 case Expr::UnresolvedMemberExprClass:
16439 case Expr::ObjCStringLiteralClass:
16440 case Expr::ObjCBoxedExprClass:
16441 case Expr::ObjCArrayLiteralClass:
16442 case Expr::ObjCDictionaryLiteralClass:
16443 case Expr::ObjCEncodeExprClass:
16444 case Expr::ObjCMessageExprClass:
16445 case Expr::ObjCSelectorExprClass:
16446 case Expr::ObjCProtocolExprClass:
16447 case Expr::ObjCIvarRefExprClass:
16448 case Expr::ObjCPropertyRefExprClass:
16449 case Expr::ObjCSubscriptRefExprClass:
16450 case Expr::ObjCIsaExprClass:
16451 case Expr::ObjCAvailabilityCheckExprClass:
16452 case Expr::ShuffleVectorExprClass:
16453 case Expr::ConvertVectorExprClass:
16454 case Expr::BlockExprClass:
16455 case Expr::NoStmtClass:
16456 case Expr::OpaqueValueExprClass:
16457 case Expr::PackExpansionExprClass:
16458 case Expr::SubstNonTypeTemplateParmPackExprClass:
16459 case Expr::FunctionParmPackExprClass:
16460 case Expr::AsTypeExprClass:
16461 case Expr::ObjCIndirectCopyRestoreExprClass:
16462 case Expr::MaterializeTemporaryExprClass:
16463 case Expr::PseudoObjectExprClass:
16464 case Expr::AtomicExprClass:
16465 case Expr::LambdaExprClass:
16466 case Expr::CXXFoldExprClass:
16467 case Expr::CoawaitExprClass:
16468 case Expr::DependentCoawaitExprClass:
16469 case Expr::CoyieldExprClass:
16470 case Expr::SYCLUniqueStableNameExprClass:
16471 case Expr::CXXParenListInitExprClass:
16474 case Expr::InitListExprClass: {
16480 if (cast<InitListExpr>(
E)->getNumInits() == 1)
16481 return CheckICE(cast<InitListExpr>(
E)->getInit(0), Ctx);
16485 case Expr::SizeOfPackExprClass:
16486 case Expr::GNUNullExprClass:
16487 case Expr::SourceLocExprClass:
16488 case Expr::EmbedExprClass:
16491 case Expr::PackIndexingExprClass:
16492 return CheckICE(cast<PackIndexingExpr>(
E)->getSelectedExpr(), Ctx);
16494 case Expr::SubstNonTypeTemplateParmExprClass:
16496 CheckICE(cast<SubstNonTypeTemplateParmExpr>(
E)->getReplacement(), Ctx);
16498 case Expr::ConstantExprClass:
16499 return CheckICE(cast<ConstantExpr>(
E)->getSubExpr(), Ctx);
16501 case Expr::ParenExprClass:
16502 return CheckICE(cast<ParenExpr>(
E)->getSubExpr(), Ctx);
16503 case Expr::GenericSelectionExprClass:
16504 return CheckICE(cast<GenericSelectionExpr>(
E)->getResultExpr(), Ctx);
16505 case Expr::IntegerLiteralClass:
16506 case Expr::FixedPointLiteralClass:
16507 case Expr::CharacterLiteralClass:
16508 case Expr::ObjCBoolLiteralExprClass:
16509 case Expr::CXXBoolLiteralExprClass:
16510 case Expr::CXXScalarValueInitExprClass:
16511 case Expr::TypeTraitExprClass:
16512 case Expr::ConceptSpecializationExprClass:
16513 case Expr::RequiresExprClass:
16514 case Expr::ArrayTypeTraitExprClass:
16515 case Expr::ExpressionTraitExprClass:
16516 case Expr::CXXNoexceptExprClass:
16518 case Expr::CallExprClass:
16519 case Expr::CXXOperatorCallExprClass: {
16523 const CallExpr *CE = cast<CallExpr>(
E);
16528 case Expr::CXXRewrittenBinaryOperatorClass:
16529 return CheckICE(cast<CXXRewrittenBinaryOperator>(
E)->getSemanticForm(),
16531 case Expr::DeclRefExprClass: {
16532 const NamedDecl *
D = cast<DeclRefExpr>(
E)->getDecl();
16533 if (isa<EnumConstantDecl>(
D))
16545 const VarDecl *VD = dyn_cast<VarDecl>(
D);
16552 case Expr::UnaryOperatorClass: {
16575 llvm_unreachable(
"invalid unary operator class");
16577 case Expr::OffsetOfExprClass: {
16586 case Expr::UnaryExprOrTypeTraitExprClass: {
16588 if ((Exp->
getKind() == UETT_SizeOf) &&
16593 case Expr::BinaryOperatorClass: {
16638 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE) {
16641 return ICEDiag(IK_ICEIfUnevaluated,
E->
getBeginLoc());
16642 if (REval.isSigned() && REval.isAllOnes()) {
16644 if (LEval.isMinSignedValue())
16645 return ICEDiag(IK_ICEIfUnevaluated,
E->
getBeginLoc());
16653 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE)
16654 return ICEDiag(IK_ICEIfUnevaluated,
E->
getBeginLoc());
16660 return Worst(LHSResult, RHSResult);
16666 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICEIfUnevaluated) {
16676 return Worst(LHSResult, RHSResult);
16679 llvm_unreachable(
"invalid binary operator kind");
16681 case Expr::ImplicitCastExprClass:
16682 case Expr::CStyleCastExprClass:
16683 case Expr::CXXFunctionalCastExprClass:
16684 case Expr::CXXStaticCastExprClass:
16685 case Expr::CXXReinterpretCastExprClass:
16686 case Expr::CXXConstCastExprClass:
16687 case Expr::ObjCBridgedCastExprClass: {
16688 const Expr *SubExpr = cast<CastExpr>(
E)->getSubExpr();
16689 if (isa<ExplicitCastExpr>(
E)) {
16694 APSInt IgnoredVal(DestWidth, !DestSigned);
16699 if (FL->getValue().convertToInteger(IgnoredVal,
16700 llvm::APFloat::rmTowardZero,
16701 &Ignored) & APFloat::opInvalidOp)
16706 switch (cast<CastExpr>(
E)->getCastKind()) {
16707 case CK_LValueToRValue:
16708 case CK_AtomicToNonAtomic:
16709 case CK_NonAtomicToAtomic:
16711 case CK_IntegralToBoolean:
16712 case CK_IntegralCast:
16718 case Expr::BinaryConditionalOperatorClass: {
16721 if (CommonResult.Kind == IK_NotICE)
return CommonResult;
16723 if (FalseResult.Kind == IK_NotICE)
return FalseResult;
16724 if (CommonResult.Kind == IK_ICEIfUnevaluated)
return CommonResult;
16725 if (FalseResult.Kind == IK_ICEIfUnevaluated &&
16727 return FalseResult;
16729 case Expr::ConditionalOperatorClass: {
16737 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
16740 if (CondResult.Kind == IK_NotICE)
16746 if (TrueResult.Kind == IK_NotICE)
16748 if (FalseResult.Kind == IK_NotICE)
16749 return FalseResult;
16750 if (CondResult.Kind == IK_ICEIfUnevaluated)
16752 if (TrueResult.Kind == IK_ICE && FalseResult.Kind == IK_ICE)
16758 return FalseResult;
16761 case Expr::CXXDefaultArgExprClass:
16762 return CheckICE(cast<CXXDefaultArgExpr>(
E)->getExpr(), Ctx);
16763 case Expr::CXXDefaultInitExprClass:
16764 return CheckICE(cast<CXXDefaultInitExpr>(
E)->getExpr(), Ctx);
16765 case Expr::ChooseExprClass: {
16766 return CheckICE(cast<ChooseExpr>(
E)->getChosenSubExpr(), Ctx);
16768 case Expr::BuiltinBitCastExprClass: {
16769 if (!checkBitCastConstexprEligibility(
nullptr, Ctx, cast<CastExpr>(
E)))
16771 return CheckICE(cast<CastExpr>(
E)->getSubExpr(), Ctx);
16775 llvm_unreachable(
"Invalid StmtClass!");
16781 llvm::APSInt *
Value,
16792 if (!Result.isInt()) {
16803 assert(!isValueDependent() &&
16804 "Expression evaluator can't be called on a dependent expression.");
16806 ExprTimeTraceScope TimeScope(
this, Ctx,
"isIntegerConstantExpr");
16812 if (
D.
Kind != IK_ICE) {
16819std::optional<llvm::APSInt>
16821 if (isValueDependent()) {
16823 return std::nullopt;
16831 return std::nullopt;
16834 if (!isIntegerConstantExpr(Ctx,
Loc))
16835 return std::nullopt;
16843 EvalInfo Info(Ctx, Status, EvalInfo::EM_IgnoreSideEffects);
16844 Info.InConstantContext =
true;
16847 llvm_unreachable(
"ICE cannot be evaluated!");
16853 assert(!isValueDependent() &&
16854 "Expression evaluator can't be called on a dependent expression.");
16856 return CheckICE(
this, Ctx).Kind == IK_ICE;
16861 assert(!isValueDependent() &&
16862 "Expression evaluator can't be called on a dependent expression.");
16871 Status.Diag = &Diags;
16872 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
16879 Info.discardCleanups() && !Status.HasSideEffects;
16881 if (!Diags.empty()) {
16882 IsConstExpr =
false;
16883 if (
Loc) *
Loc = Diags[0].first;
16884 }
else if (!IsConstExpr) {
16886 if (
Loc) *
Loc = getExprLoc();
16889 return IsConstExpr;
16895 const Expr *This)
const {
16896 assert(!isValueDependent() &&
16897 "Expression evaluator can't be called on a dependent expression.");
16899 llvm::TimeTraceScope TimeScope(
"EvaluateWithSubstitution", [&] {
16901 llvm::raw_string_ostream OS(Name);
16908 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpressionUnevaluated);
16909 Info.InConstantContext =
true;
16912 const LValue *ThisPtr =
nullptr;
16915 auto *MD = dyn_cast<CXXMethodDecl>(Callee);
16916 assert(MD &&
"Don't provide `this` for non-methods.");
16917 assert(MD->isImplicitObjectMemberFunction() &&
16918 "Don't provide `this` for methods without an implicit object.");
16920 if (!This->isValueDependent() &&
16922 !Info.EvalStatus.HasSideEffects)
16923 ThisPtr = &ThisVal;
16927 Info.EvalStatus.HasSideEffects =
false;
16930 CallRef
Call = Info.CurrentCall->createCall(Callee);
16933 unsigned Idx = I - Args.begin();
16934 if (Idx >= Callee->getNumParams())
16936 const ParmVarDecl *PVD = Callee->getParamDecl(Idx);
16937 if ((*I)->isValueDependent() ||
16939 Info.EvalStatus.HasSideEffects) {
16941 if (
APValue *Slot = Info.getParamSlot(
Call, PVD))
16947 Info.EvalStatus.HasSideEffects =
false;
16952 Info.discardCleanups();
16953 Info.EvalStatus.HasSideEffects =
false;
16956 CallStackFrame Frame(Info, Callee->getLocation(), Callee, ThisPtr, This,
16959 FullExpressionRAII
Scope(Info);
16961 !Info.EvalStatus.HasSideEffects;
16973 llvm::TimeTraceScope TimeScope(
"isPotentialConstantExpr", [&] {
16975 llvm::raw_string_ostream OS(Name);
16982 Status.Diag = &Diags;
16984 EvalInfo Info(FD->
getASTContext(), Status, EvalInfo::EM_ConstantExpression);
16985 Info.InConstantContext =
true;
16986 Info.CheckingPotentialConstantExpression =
true;
16989 if (Info.EnableNewConstInterp) {
16990 Info.Ctx.getInterpContext().isPotentialConstantExpr(Info, FD);
16991 return Diags.empty();
17001 This.set({&VIE, Info.CurrentCall->Index});
17009 Info.setEvaluatingDecl(This.getLValueBase(), Scratch);
17015 &VIE, Args, CallRef(), FD->
getBody(), Info, Scratch,
17019 return Diags.empty();
17027 "Expression evaluator can't be called on a dependent expression.");
17030 Status.Diag = &Diags;
17033 EvalInfo::EM_ConstantExpressionUnevaluated);
17034 Info.InConstantContext =
true;
17035 Info.CheckingPotentialConstantExpression =
true;
17039 nullptr, CallRef());
17043 return Diags.empty();
17047 unsigned Type)
const {
17048 if (!getType()->isPointerType())
17052 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantFold);
17057 EvalInfo &Info, std::string *StringResult) {
17069 if (
const StringLiteral *S = dyn_cast_or_null<StringLiteral>(
17070 String.getLValueBase().dyn_cast<
const Expr *>())) {
17071 StringRef Str = S->getBytes();
17072 int64_t Off = String.Offset.getQuantity();
17073 if (Off >= 0 && (uint64_t)Off <= (uint64_t)Str.size() &&
17074 S->getCharByteWidth() == 1 &&
17076 Info.Ctx.hasSameUnqualifiedType(CharTy, Info.Ctx.CharTy)) {
17077 Str = Str.substr(Off);
17079 StringRef::size_type Pos = Str.find(0);
17080 if (Pos != StringRef::npos)
17081 Str = Str.substr(0, Pos);
17083 Result = Str.size();
17085 *StringResult = Str;
17093 for (uint64_t Strlen = 0; ; ++Strlen) {
17101 }
else if (StringResult)
17102 StringResult->push_back(Char.
getInt().getExtValue());
17110 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantFold);
17112 std::string StringResult;
17115 return StringResult;
17120 const Expr *SizeExpression,
17124 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
17125 Info.InConstantContext =
true;
17127 FullExpressionRAII
Scope(Info);
17132 uint64_t Size = SizeValue.getZExtValue();
17138 for (uint64_t I = 0; I < Size; ++I) {
17145 Result.push_back(
static_cast<char>(
C.getExtValue()));
17149 if (!
Scope.destroy())
17160 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::@1651::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 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 a value-initialized rvalue of type T, which is a non-class type.
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)