57#include "llvm/ADT/APFixedPoint.h"
58#include "llvm/ADT/Sequence.h"
59#include "llvm/ADT/SmallBitVector.h"
60#include "llvm/ADT/StringExtras.h"
61#include "llvm/Support/Casting.h"
62#include "llvm/Support/Debug.h"
63#include "llvm/Support/SaveAndRestore.h"
64#include "llvm/Support/SipHash.h"
65#include "llvm/Support/TimeProfiler.h"
66#include "llvm/Support/raw_ostream.h"
72#define DEBUG_TYPE "exprconstant"
75using llvm::APFixedPoint;
79using llvm::FixedPointSemantics;
86 using SourceLocExprScopeGuard =
96 return dyn_cast_or_null<FieldDecl>(
E.getAsBaseOrMember().getPointer());
101 return dyn_cast_or_null<CXXRecordDecl>(
E.getAsBaseOrMember().getPointer());
106 return E.getAsBaseOrMember().getInt();
121 static const CallExpr *tryUnwrapAllocSizeCall(
const Expr *
E) {
129 if (
const auto *FE = dyn_cast<FullExpr>(
E))
132 if (
const auto *Cast = dyn_cast<CastExpr>(
E))
133 E = Cast->getSubExpr()->IgnoreParens();
135 if (
const auto *CE = dyn_cast<CallExpr>(
E))
136 return CE->getCalleeAllocSizeAttr() ? CE :
nullptr;
143 const auto *
E =
Base.dyn_cast<
const Expr *>();
152 case ConstantExprKind::Normal:
153 case ConstantExprKind::ClassTemplateArgument:
154 case ConstantExprKind::ImmediateInvocation:
159 case ConstantExprKind::NonClassTemplateArgument:
162 llvm_unreachable(
"unknown ConstantExprKind");
167 case ConstantExprKind::Normal:
168 case ConstantExprKind::ImmediateInvocation:
171 case ConstantExprKind::ClassTemplateArgument:
172 case ConstantExprKind::NonClassTemplateArgument:
175 llvm_unreachable(
"unknown ConstantExprKind");
181 static const uint64_t AssumedSizeForUnsizedArray =
182 std::numeric_limits<uint64_t>::max() / 2;
192 bool &FirstEntryIsUnsizedArray) {
195 assert(!isBaseAnAllocSizeCall(
Base) &&
196 "Unsized arrays shouldn't appear here");
197 unsigned MostDerivedLength = 0;
200 Type = getType(
Base).getNonReferenceType();
202 for (
unsigned I = 0, N =
Path.size(); I != N; ++I) {
206 MostDerivedLength = I + 1;
209 if (
auto *CAT = dyn_cast<ConstantArrayType>(AT)) {
210 ArraySize = CAT->getZExtSize();
212 assert(I == 0 &&
"unexpected unsized array designator");
213 FirstEntryIsUnsizedArray =
true;
214 ArraySize = AssumedSizeForUnsizedArray;
220 MostDerivedLength = I + 1;
223 Type = VT->getElementType();
224 ArraySize = VT->getNumElements();
225 MostDerivedLength = I + 1;
228 Type = FD->getType();
230 MostDerivedLength = I + 1;
238 return MostDerivedLength;
242 struct SubobjectDesignator {
246 LLVM_PREFERRED_TYPE(
bool)
247 unsigned Invalid : 1;
250 LLVM_PREFERRED_TYPE(
bool)
251 unsigned IsOnePastTheEnd : 1;
254 LLVM_PREFERRED_TYPE(
bool)
255 unsigned FirstEntryIsAnUnsizedArray : 1;
258 LLVM_PREFERRED_TYPE(
bool)
259 unsigned MostDerivedIsArrayElement : 1;
263 unsigned MostDerivedPathLength : 28;
272 uint64_t MostDerivedArraySize;
281 SubobjectDesignator() : Invalid(
true) {}
284 : Invalid(
false), IsOnePastTheEnd(
false),
285 FirstEntryIsAnUnsizedArray(
false), MostDerivedIsArrayElement(
false),
286 MostDerivedPathLength(0), MostDerivedArraySize(0),
287 MostDerivedType(
T.isNull() ?
QualType() :
T.getNonReferenceType()) {}
290 : Invalid(!
V.isLValue() || !
V.hasLValuePath()), IsOnePastTheEnd(
false),
291 FirstEntryIsAnUnsizedArray(
false), MostDerivedIsArrayElement(
false),
292 MostDerivedPathLength(0), MostDerivedArraySize(0) {
293 assert(
V.isLValue() &&
"Non-LValue used to make an LValue designator?");
295 IsOnePastTheEnd =
V.isLValueOnePastTheEnd();
296 llvm::append_range(Entries,
V.getLValuePath());
297 if (
V.getLValueBase()) {
298 bool IsArray =
false;
299 bool FirstIsUnsizedArray =
false;
300 MostDerivedPathLength = findMostDerivedSubobject(
301 Ctx,
V.getLValueBase(),
V.getLValuePath(), MostDerivedArraySize,
302 MostDerivedType, IsArray, FirstIsUnsizedArray);
303 MostDerivedIsArrayElement = IsArray;
304 FirstEntryIsAnUnsizedArray = FirstIsUnsizedArray;
310 unsigned NewLength) {
314 assert(
Base &&
"cannot truncate path for null pointer");
315 assert(NewLength <= Entries.size() &&
"not a truncation");
317 if (NewLength == Entries.size())
319 Entries.resize(NewLength);
321 bool IsArray =
false;
322 bool FirstIsUnsizedArray =
false;
323 MostDerivedPathLength = findMostDerivedSubobject(
324 Ctx,
Base, Entries, MostDerivedArraySize, MostDerivedType, IsArray,
325 FirstIsUnsizedArray);
326 MostDerivedIsArrayElement = IsArray;
327 FirstEntryIsAnUnsizedArray = FirstIsUnsizedArray;
337 bool isMostDerivedAnUnsizedArray()
const {
338 assert(!Invalid &&
"Calling this makes no sense on invalid designators");
339 return Entries.size() == 1 && FirstEntryIsAnUnsizedArray;
344 uint64_t getMostDerivedArraySize()
const {
345 assert(!isMostDerivedAnUnsizedArray() &&
"Unsized array has no size");
346 return MostDerivedArraySize;
350 bool isOnePastTheEnd()
const {
354 if (!isMostDerivedAnUnsizedArray() && MostDerivedIsArrayElement &&
355 Entries[MostDerivedPathLength - 1].getAsArrayIndex() ==
356 MostDerivedArraySize)
364 std::pair<uint64_t, uint64_t> validIndexAdjustments() {
365 if (Invalid || isMostDerivedAnUnsizedArray())
371 bool IsArray = MostDerivedPathLength == Entries.size() &&
372 MostDerivedIsArrayElement;
373 uint64_t ArrayIndex = IsArray ? Entries.back().getAsArrayIndex()
374 : (uint64_t)IsOnePastTheEnd;
376 IsArray ? getMostDerivedArraySize() : (uint64_t)1;
377 return {ArrayIndex, ArraySize - ArrayIndex};
381 bool isValidSubobject()
const {
384 return !isOnePastTheEnd();
392 assert(!Invalid &&
"invalid designator has no subobject type");
393 return MostDerivedPathLength == Entries.size()
404 MostDerivedIsArrayElement =
true;
406 MostDerivedPathLength = Entries.size();
410 void addUnsizedArrayUnchecked(
QualType ElemTy) {
413 MostDerivedType = ElemTy;
414 MostDerivedIsArrayElement =
true;
418 MostDerivedArraySize = AssumedSizeForUnsizedArray;
419 MostDerivedPathLength = Entries.size();
423 void addDeclUnchecked(
const Decl *
D,
bool Virtual =
false) {
427 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(
D)) {
428 MostDerivedType = FD->getType();
429 MostDerivedIsArrayElement =
false;
430 MostDerivedArraySize = 0;
431 MostDerivedPathLength = Entries.size();
435 void addComplexUnchecked(
QualType EltTy,
bool Imag) {
440 MostDerivedType = EltTy;
441 MostDerivedIsArrayElement =
true;
442 MostDerivedArraySize = 2;
443 MostDerivedPathLength = Entries.size();
446 void addVectorElementUnchecked(
QualType EltTy, uint64_t Size,
449 MostDerivedType = EltTy;
450 MostDerivedPathLength = Entries.size();
451 MostDerivedArraySize = 0;
452 MostDerivedIsArrayElement =
false;
455 void diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info,
const Expr *
E);
456 void diagnosePointerArithmetic(EvalInfo &Info,
const Expr *
E,
459 void adjustIndex(EvalInfo &Info,
const Expr *
E,
APSInt N) {
460 if (Invalid || !N)
return;
461 uint64_t TruncatedN = N.extOrTrunc(64).getZExtValue();
462 if (isMostDerivedAnUnsizedArray()) {
463 diagnoseUnsizedArrayPointerArithmetic(Info,
E);
468 Entries.back().getAsArrayIndex() + TruncatedN);
475 bool IsArray = MostDerivedPathLength == Entries.size() &&
476 MostDerivedIsArrayElement;
477 uint64_t ArrayIndex = IsArray ? Entries.back().getAsArrayIndex()
478 : (uint64_t)IsOnePastTheEnd;
480 IsArray ? getMostDerivedArraySize() : (uint64_t)1;
482 if (N < -(int64_t)ArrayIndex || N > ArraySize - ArrayIndex) {
485 N = N.extend(std::max<unsigned>(N.getBitWidth() + 1, 65));
486 (llvm::APInt&)N += ArrayIndex;
487 assert(N.ugt(ArraySize) &&
"bounds check failed for in-bounds index");
488 diagnosePointerArithmetic(Info,
E, N);
493 ArrayIndex += TruncatedN;
494 assert(ArrayIndex <= ArraySize &&
495 "bounds check succeeded for out-of-bounds index");
500 IsOnePastTheEnd = (ArrayIndex != 0);
505 enum class ScopeKind {
513 CallRef() : OrigCallee(), CallIndex(0), Version() {}
514 CallRef(
const FunctionDecl *Callee,
unsigned CallIndex,
unsigned Version)
515 : OrigCallee(Callee), CallIndex(CallIndex), Version(Version) {}
517 explicit operator bool()
const {
return OrigCallee; }
543 CallStackFrame *Caller;
565 typedef std::pair<const void *, unsigned> MapKeyTy;
566 typedef std::map<MapKeyTy, APValue>
MapTy;
578 unsigned CurTempVersion = TempVersionStack.back();
580 unsigned getTempVersion()
const {
return TempVersionStack.back(); }
582 void pushTempVersion() {
583 TempVersionStack.push_back(++CurTempVersion);
586 void popTempVersion() {
587 TempVersionStack.pop_back();
591 return {Callee, Index, ++CurTempVersion};
602 llvm::DenseMap<const ValueDecl *, FieldDecl *> LambdaCaptureFields;
603 FieldDecl *LambdaThisCaptureField =
nullptr;
605 CallStackFrame(EvalInfo &Info,
SourceRange CallRange,
611 APValue *getTemporary(
const void *Key,
unsigned Version) {
612 MapKeyTy KV(Key, Version);
613 auto LB = Temporaries.lower_bound(KV);
614 if (LB != Temporaries.end() && LB->first == KV)
620 APValue *getCurrentTemporary(
const void *Key) {
621 auto UB = Temporaries.upper_bound(MapKeyTy(Key,
UINT_MAX));
622 if (UB != Temporaries.begin() && std::prev(UB)->first.first == Key)
623 return &std::prev(UB)->second;
628 unsigned getCurrentTemporaryVersion(
const void *Key)
const {
629 auto UB = Temporaries.upper_bound(MapKeyTy(Key,
UINT_MAX));
630 if (UB != Temporaries.begin() && std::prev(UB)->first.first == Key)
631 return std::prev(UB)->first.second;
639 template<
typename KeyT>
641 ScopeKind
Scope, LValue &LV);
646 void describe(llvm::raw_ostream &OS)
const override;
648 Frame *getCaller()
const override {
return Caller; }
649 SourceRange getCallRange()
const override {
return CallRange; }
652 bool isStdFunction()
const {
653 for (
const DeclContext *DC = Callee; DC; DC = DC->getParent())
654 if (DC->isStdNamespace())
661 bool CanEvalMSConstexpr =
false;
669 class ThisOverrideRAII {
671 ThisOverrideRAII(CallStackFrame &Frame,
const LValue *NewThis,
bool Enable)
672 : Frame(Frame), OldThis(Frame.This) {
674 Frame.This = NewThis;
676 ~ThisOverrideRAII() {
677 Frame.This = OldThis;
680 CallStackFrame &Frame;
681 const LValue *OldThis;
686 class ExprTimeTraceScope {
688 ExprTimeTraceScope(
const Expr *
E,
const ASTContext &Ctx, StringRef Name)
689 : TimeScope(Name, [
E, &Ctx] {
694 llvm::TimeTraceScope TimeScope;
699 struct MSConstexprContextRAII {
700 CallStackFrame &Frame;
702 explicit MSConstexprContextRAII(CallStackFrame &Frame,
bool Value)
703 : Frame(Frame), OldValue(Frame.CanEvalMSConstexpr) {
704 Frame.CanEvalMSConstexpr =
Value;
707 ~MSConstexprContextRAII() { Frame.CanEvalMSConstexpr = OldValue; }
720 llvm::PointerIntPair<APValue*, 2, ScopeKind>
Value;
731 bool isDestroyedAtEndOf(ScopeKind K)
const {
732 return (
int)
Value.getInt() >= (
int)K;
734 bool endLifetime(EvalInfo &Info,
bool RunDestructors) {
735 if (RunDestructors) {
738 Loc = VD->getLocation();
747 bool hasSideEffect() {
748 return T.isDestructedType();
753 struct ObjectUnderConstruction {
756 friend bool operator==(
const ObjectUnderConstruction &LHS,
757 const ObjectUnderConstruction &RHS) {
758 return LHS.Base == RHS.Base && LHS.Path == RHS.Path;
760 friend llvm::hash_code
hash_value(
const ObjectUnderConstruction &Obj) {
761 return llvm::hash_combine(Obj.Base, Obj.Path);
764 enum class ConstructionPhase {
775template<>
struct DenseMapInfo<ObjectUnderConstruction> {
776 using Base = DenseMapInfo<APValue::LValueBase>;
778 return {Base::getEmptyKey(), {}}; }
780 return {Base::getTombstoneKey(), {}};
785 static bool isEqual(
const ObjectUnderConstruction &LHS,
786 const ObjectUnderConstruction &RHS) {
800 const Expr *AllocExpr =
nullptr;
811 if (
auto *NE = dyn_cast<CXXNewExpr>(AllocExpr))
812 return NE->isArray() ? ArrayNew :
New;
813 assert(isa<CallExpr>(AllocExpr));
818 struct DynAllocOrder {
846 CallStackFrame *CurrentCall;
849 unsigned CallStackDepth;
852 unsigned NextCallIndex;
861 bool EnableNewConstInterp;
865 CallStackFrame BottomFrame;
875 enum class EvaluatingDeclKind {
882 EvaluatingDeclKind IsEvaluatingDecl = EvaluatingDeclKind::None;
889 llvm::DenseMap<ObjectUnderConstruction, ConstructionPhase>
890 ObjectsUnderConstruction;
895 std::map<DynamicAllocLValue, DynAlloc, DynAllocOrder> HeapAllocs;
898 unsigned NumHeapAllocs = 0;
900 struct EvaluatingConstructorRAII {
902 ObjectUnderConstruction
Object;
904 EvaluatingConstructorRAII(EvalInfo &EI, ObjectUnderConstruction Object,
908 EI.ObjectsUnderConstruction
909 .insert({
Object, HasBases ? ConstructionPhase::Bases
910 : ConstructionPhase::AfterBases})
913 void finishedConstructingBases() {
914 EI.ObjectsUnderConstruction[
Object] = ConstructionPhase::AfterBases;
916 void finishedConstructingFields() {
917 EI.ObjectsUnderConstruction[
Object] = ConstructionPhase::AfterFields;
919 ~EvaluatingConstructorRAII() {
920 if (DidInsert) EI.ObjectsUnderConstruction.erase(Object);
924 struct EvaluatingDestructorRAII {
926 ObjectUnderConstruction
Object;
928 EvaluatingDestructorRAII(EvalInfo &EI, ObjectUnderConstruction Object)
930 DidInsert = EI.ObjectsUnderConstruction
931 .insert({
Object, ConstructionPhase::Destroying})
934 void startedDestroyingBases() {
935 EI.ObjectsUnderConstruction[
Object] =
936 ConstructionPhase::DestroyingBases;
938 ~EvaluatingDestructorRAII() {
940 EI.ObjectsUnderConstruction.erase(Object);
947 return ObjectsUnderConstruction.lookup({
Base,
Path});
952 unsigned SpeculativeEvaluationDepth = 0;
960 bool HasActiveDiagnostic;
964 bool HasFoldFailureDiagnostic;
969 bool CheckingPotentialConstantExpression =
false;
977 bool CheckingForUndefinedBehavior =
false;
979 enum EvaluationMode {
982 EM_ConstantExpression,
989 EM_ConstantExpressionUnevaluated,
997 EM_IgnoreSideEffects,
1002 bool checkingPotentialConstantExpression()
const override {
1003 return CheckingPotentialConstantExpression;
1009 bool checkingForUndefinedBehavior()
const override {
1010 return CheckingForUndefinedBehavior;
1014 : Ctx(const_cast<
ASTContext &>(
C)), EvalStatus(S), CurrentCall(nullptr),
1015 CallStackDepth(0), NextCallIndex(1),
1016 StepsLeft(
C.getLangOpts().ConstexprStepLimit),
1017 EnableNewConstInterp(
C.getLangOpts().EnableNewConstInterp),
1020 nullptr, CallRef()),
1021 EvaluatingDecl((const
ValueDecl *)nullptr),
1022 EvaluatingDeclValue(nullptr), HasActiveDiagnostic(
false),
1023 HasFoldFailureDiagnostic(
false), EvalMode(Mode) {}
1029 ASTContext &getASTContext()
const override {
return Ctx; }
1032 EvaluatingDeclKind EDK = EvaluatingDeclKind::Ctor) {
1033 EvaluatingDecl =
Base;
1034 IsEvaluatingDecl = EDK;
1035 EvaluatingDeclValue = &
Value;
1041 if (checkingPotentialConstantExpression() && CallStackDepth > 1)
1043 if (NextCallIndex == 0) {
1045 FFDiag(
Loc, diag::note_constexpr_call_limit_exceeded);
1048 if (CallStackDepth <= getLangOpts().ConstexprCallDepth)
1050 FFDiag(
Loc, diag::note_constexpr_depth_limit_exceeded)
1051 << getLangOpts().ConstexprCallDepth;
1056 uint64_t ElemCount,
bool Diag) {
1062 ElemCount >
uint64_t(std::numeric_limits<unsigned>::max())) {
1064 FFDiag(
Loc, diag::note_constexpr_new_too_large) << ElemCount;
1074 if (ElemCount > Limit) {
1076 FFDiag(
Loc, diag::note_constexpr_new_exceeds_limits)
1077 << ElemCount << Limit;
1083 std::pair<CallStackFrame *, unsigned>
1084 getCallFrameAndDepth(
unsigned CallIndex) {
1085 assert(CallIndex &&
"no call index in getCallFrameAndDepth");
1088 unsigned Depth = CallStackDepth;
1089 CallStackFrame *Frame = CurrentCall;
1090 while (Frame->Index > CallIndex) {
1091 Frame = Frame->Caller;
1094 if (Frame->Index == CallIndex)
1095 return {Frame, Depth};
1096 return {
nullptr, 0};
1099 bool nextStep(
const Stmt *S) {
1101 FFDiag(S->getBeginLoc(), diag::note_constexpr_step_limit_exceeded);
1111 std::optional<DynAlloc *> Result;
1112 auto It = HeapAllocs.find(DA);
1113 if (It != HeapAllocs.end())
1114 Result = &It->second;
1120 CallStackFrame *Frame = getCallFrameAndDepth(
Call.CallIndex).first;
1121 return Frame ? Frame->getTemporary(
Call.getOrigParam(PVD),
Call.Version)
1126 struct StdAllocatorCaller {
1127 unsigned FrameIndex;
1130 explicit operator bool()
const {
return FrameIndex != 0; };
1133 StdAllocatorCaller getStdAllocatorCaller(StringRef FnName)
const {
1134 for (
const CallStackFrame *
Call = CurrentCall;
Call != &BottomFrame;
1136 const auto *MD = dyn_cast_or_null<CXXMethodDecl>(
Call->Callee);
1140 if (!FnII || !FnII->
isStr(FnName))
1144 dyn_cast<ClassTemplateSpecializationDecl>(MD->getParent());
1150 if (CTSD->isInStdNamespace() && ClassII &&
1151 ClassII->
isStr(
"allocator") && TAL.
size() >= 1 &&
1153 return {
Call->Index, TAL[0].getAsType(),
Call->CallExpr};
1159 void performLifetimeExtension() {
1161 llvm::erase_if(CleanupStack, [](Cleanup &
C) {
1162 return !
C.isDestroyedAtEndOf(ScopeKind::FullExpression);
1169 bool discardCleanups() {
1170 for (Cleanup &
C : CleanupStack) {
1171 if (
C.hasSideEffect() && !noteSideEffect()) {
1172 CleanupStack.clear();
1176 CleanupStack.clear();
1181 interp::Frame *getCurrentFrame()
override {
return CurrentCall; }
1182 const interp::Frame *getBottomFrame()
const override {
return &BottomFrame; }
1184 bool hasActiveDiagnostic()
override {
return HasActiveDiagnostic; }
1185 void setActiveDiagnostic(
bool Flag)
override { HasActiveDiagnostic = Flag; }
1187 void setFoldFailureDiagnostic(
bool Flag)
override {
1188 HasFoldFailureDiagnostic = Flag;
1199 bool hasPriorDiagnostic()
override {
1200 if (!EvalStatus.
Diag->empty()) {
1202 case EM_ConstantFold:
1203 case EM_IgnoreSideEffects:
1204 if (!HasFoldFailureDiagnostic)
1208 case EM_ConstantExpression:
1209 case EM_ConstantExpressionUnevaluated:
1210 setActiveDiagnostic(
false);
1217 unsigned getCallStackDepth()
override {
return CallStackDepth; }
1222 bool keepEvaluatingAfterSideEffect()
const override {
1224 case EM_IgnoreSideEffects:
1227 case EM_ConstantExpression:
1228 case EM_ConstantExpressionUnevaluated:
1229 case EM_ConstantFold:
1232 return checkingPotentialConstantExpression() ||
1233 checkingForUndefinedBehavior();
1235 llvm_unreachable(
"Missed EvalMode case");
1240 bool noteSideEffect()
override {
1242 return keepEvaluatingAfterSideEffect();
1246 bool keepEvaluatingAfterUndefinedBehavior() {
1248 case EM_IgnoreSideEffects:
1249 case EM_ConstantFold:
1252 case EM_ConstantExpression:
1253 case EM_ConstantExpressionUnevaluated:
1254 return checkingForUndefinedBehavior();
1256 llvm_unreachable(
"Missed EvalMode case");
1262 bool noteUndefinedBehavior()
override {
1264 return keepEvaluatingAfterUndefinedBehavior();
1269 bool keepEvaluatingAfterFailure()
const override {
1274 case EM_ConstantExpression:
1275 case EM_ConstantExpressionUnevaluated:
1276 case EM_ConstantFold:
1277 case EM_IgnoreSideEffects:
1278 return checkingPotentialConstantExpression() ||
1279 checkingForUndefinedBehavior();
1281 llvm_unreachable(
"Missed EvalMode case");
1294 [[nodiscard]]
bool noteFailure() {
1302 bool KeepGoing = keepEvaluatingAfterFailure();
1307 class ArrayInitLoopIndex {
1312 ArrayInitLoopIndex(EvalInfo &Info)
1313 : Info(Info), OuterIndex(Info.ArrayInitIndex) {
1314 Info.ArrayInitIndex = 0;
1316 ~ArrayInitLoopIndex() { Info.ArrayInitIndex = OuterIndex; }
1318 operator uint64_t&() {
return Info.ArrayInitIndex; }
1323 struct FoldConstant {
1326 bool HadNoPriorDiags;
1327 EvalInfo::EvaluationMode OldMode;
1329 explicit FoldConstant(EvalInfo &Info,
bool Enabled)
1332 HadNoPriorDiags(Info.EvalStatus.
Diag &&
1333 Info.EvalStatus.
Diag->empty() &&
1334 !Info.EvalStatus.HasSideEffects),
1335 OldMode(Info.EvalMode) {
1337 Info.EvalMode = EvalInfo::EM_ConstantFold;
1339 void keepDiagnostics() { Enabled =
false; }
1341 if (Enabled && HadNoPriorDiags && !Info.EvalStatus.Diag->empty() &&
1342 !Info.EvalStatus.HasSideEffects)
1343 Info.EvalStatus.Diag->clear();
1344 Info.EvalMode = OldMode;
1350 struct IgnoreSideEffectsRAII {
1352 EvalInfo::EvaluationMode OldMode;
1353 explicit IgnoreSideEffectsRAII(EvalInfo &Info)
1354 : Info(Info), OldMode(Info.EvalMode) {
1355 Info.EvalMode = EvalInfo::EM_IgnoreSideEffects;
1358 ~IgnoreSideEffectsRAII() { Info.EvalMode = OldMode; }
1363 class SpeculativeEvaluationRAII {
1364 EvalInfo *Info =
nullptr;
1366 unsigned OldSpeculativeEvaluationDepth = 0;
1368 void moveFromAndCancel(SpeculativeEvaluationRAII &&
Other) {
1370 OldStatus =
Other.OldStatus;
1371 OldSpeculativeEvaluationDepth =
Other.OldSpeculativeEvaluationDepth;
1372 Other.Info =
nullptr;
1375 void maybeRestoreState() {
1379 Info->EvalStatus = OldStatus;
1380 Info->SpeculativeEvaluationDepth = OldSpeculativeEvaluationDepth;
1384 SpeculativeEvaluationRAII() =
default;
1386 SpeculativeEvaluationRAII(
1388 : Info(&Info), OldStatus(Info.EvalStatus),
1389 OldSpeculativeEvaluationDepth(Info.SpeculativeEvaluationDepth) {
1390 Info.EvalStatus.Diag = NewDiag;
1391 Info.SpeculativeEvaluationDepth = Info.CallStackDepth + 1;
1394 SpeculativeEvaluationRAII(
const SpeculativeEvaluationRAII &
Other) =
delete;
1395 SpeculativeEvaluationRAII(SpeculativeEvaluationRAII &&
Other) {
1396 moveFromAndCancel(std::move(
Other));
1399 SpeculativeEvaluationRAII &operator=(SpeculativeEvaluationRAII &&
Other) {
1400 maybeRestoreState();
1401 moveFromAndCancel(std::move(
Other));
1405 ~SpeculativeEvaluationRAII() { maybeRestoreState(); }
1410 template<ScopeKind Kind>
1413 unsigned OldStackSize;
1415 ScopeRAII(EvalInfo &Info)
1416 : Info(Info), OldStackSize(Info.CleanupStack.size()) {
1419 Info.CurrentCall->pushTempVersion();
1421 bool destroy(
bool RunDestructors =
true) {
1422 bool OK =
cleanup(Info, RunDestructors, OldStackSize);
1423 OldStackSize = std::numeric_limits<unsigned>::max();
1427 if (OldStackSize != std::numeric_limits<unsigned>::max())
1431 Info.CurrentCall->popTempVersion();
1434 static bool cleanup(EvalInfo &Info,
bool RunDestructors,
1435 unsigned OldStackSize) {
1436 assert(OldStackSize <= Info.CleanupStack.size() &&
1437 "running cleanups out of order?");
1442 for (
unsigned I = Info.CleanupStack.size(); I > OldStackSize; --I) {
1443 if (Info.CleanupStack[I - 1].isDestroyedAtEndOf(Kind)) {
1444 if (!Info.CleanupStack[I - 1].endLifetime(Info, RunDestructors)) {
1452 auto NewEnd = Info.CleanupStack.begin() + OldStackSize;
1453 if (Kind != ScopeKind::Block)
1455 std::remove_if(NewEnd, Info.CleanupStack.end(), [](Cleanup &
C) {
1456 return C.isDestroyedAtEndOf(Kind);
1458 Info.CleanupStack.erase(NewEnd, Info.CleanupStack.end());
1462 typedef ScopeRAII<ScopeKind::Block> BlockScopeRAII;
1463 typedef ScopeRAII<ScopeKind::FullExpression> FullExpressionRAII;
1464 typedef ScopeRAII<ScopeKind::Call> CallScopeRAII;
1467bool SubobjectDesignator::checkSubobject(EvalInfo &Info,
const Expr *
E,
1471 if (isOnePastTheEnd()) {
1472 Info.CCEDiag(
E, diag::note_constexpr_past_end_subobject)
1483void SubobjectDesignator::diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info,
1485 Info.CCEDiag(
E, diag::note_constexpr_unsized_array_indexed);
1490void SubobjectDesignator::diagnosePointerArithmetic(EvalInfo &Info,
1495 if (MostDerivedPathLength == Entries.size() && MostDerivedIsArrayElement)
1496 Info.CCEDiag(
E, diag::note_constexpr_array_index)
1498 <<
static_cast<unsigned>(getMostDerivedArraySize());
1500 Info.CCEDiag(
E, diag::note_constexpr_array_index)
1505CallStackFrame::CallStackFrame(EvalInfo &Info,
SourceRange CallRange,
1510 Index(Info.NextCallIndex++) {
1511 Info.CurrentCall =
this;
1512 ++Info.CallStackDepth;
1515CallStackFrame::~CallStackFrame() {
1516 assert(Info.CurrentCall ==
this &&
"calls retired out of order");
1517 --Info.CallStackDepth;
1518 Info.CurrentCall = Caller;
1543 llvm_unreachable(
"unknown access kind");
1580 llvm_unreachable(
"unknown access kind");
1584 struct ComplexValue {
1592 ComplexValue() : FloatReal(
APFloat::Bogus()), FloatImag(
APFloat::Bogus()) {}
1594 void makeComplexFloat() { IsInt =
false; }
1595 bool isComplexFloat()
const {
return !IsInt; }
1596 APFloat &getComplexFloatReal() {
return FloatReal; }
1597 APFloat &getComplexFloatImag() {
return FloatImag; }
1599 void makeComplexInt() { IsInt =
true; }
1600 bool isComplexInt()
const {
return IsInt; }
1601 APSInt &getComplexIntReal() {
return IntReal; }
1602 APSInt &getComplexIntImag() {
return IntImag; }
1604 void moveInto(
APValue &v)
const {
1605 if (isComplexFloat())
1606 v =
APValue(FloatReal, FloatImag);
1608 v =
APValue(IntReal, IntImag);
1610 void setFrom(
const APValue &v) {
1629 bool InvalidBase : 1;
1631 bool AllowConstexprUnknown =
false;
1634 bool allowConstexprUnknown()
const {
return AllowConstexprUnknown; }
1635 CharUnits &getLValueOffset() {
return Offset; }
1636 const CharUnits &getLValueOffset()
const {
return Offset; }
1637 SubobjectDesignator &getLValueDesignator() {
return Designator; }
1638 const SubobjectDesignator &getLValueDesignator()
const {
return Designator;}
1639 bool isNullPointer()
const {
return IsNullPtr;}
1641 unsigned getLValueCallIndex()
const {
return Base.getCallIndex(); }
1642 unsigned getLValueVersion()
const {
return Base.getVersion(); }
1648 assert(!InvalidBase &&
"APValues can't handle invalid LValue bases");
1652 if (AllowConstexprUnknown)
1653 V.setConstexprUnknown();
1656 assert(
V.isLValue() &&
"Setting LValue from a non-LValue?");
1657 Base =
V.getLValueBase();
1658 Offset =
V.getLValueOffset();
1659 InvalidBase =
false;
1661 IsNullPtr =
V.isNullPointer();
1662 AllowConstexprUnknown =
V.allowConstexprUnknown();
1669 const auto *
E = B.
get<
const Expr *>();
1670 assert((isa<MemberExpr>(
E) || tryUnwrapAllocSizeCall(
E)) &&
1671 "Unexpected type of invalid base");
1677 InvalidBase = BInvalid;
1678 Designator = SubobjectDesignator(getType(B));
1680 AllowConstexprUnknown =
false;
1687 InvalidBase =
false;
1690 AllowConstexprUnknown =
false;
1699 moveInto(Printable);
1706 template <
typename GenDiagType>
1707 bool checkNullPointerDiagnosingWith(
const GenDiagType &GenDiag) {
1719 bool checkNullPointer(EvalInfo &Info,
const Expr *
E,
1721 return checkNullPointerDiagnosingWith([&Info,
E, CSK] {
1722 Info.CCEDiag(
E, diag::note_constexpr_null_subobject) << CSK;
1726 bool checkNullPointerForFoldAccess(EvalInfo &Info,
const Expr *
E,
1728 return checkNullPointerDiagnosingWith([&Info,
E, AK] {
1729 if (AK == AccessKinds::AK_Dereference)
1730 Info.FFDiag(
E, diag::note_constexpr_dereferencing_null);
1732 Info.FFDiag(
E, diag::note_constexpr_access_null) << AK;
1743 void addDecl(EvalInfo &Info,
const Expr *
E,
1748 void addUnsizedArray(EvalInfo &Info,
const Expr *
E,
QualType ElemTy) {
1750 Info.CCEDiag(
E, diag::note_constexpr_unsupported_unsized_array);
1755 assert(getType(
Base).getNonReferenceType()->isPointerType() ||
1756 getType(
Base).getNonReferenceType()->isArrayType());
1757 Designator.FirstEntryIsAnUnsizedArray =
true;
1765 void addComplex(EvalInfo &Info,
const Expr *
E,
QualType EltTy,
bool Imag) {
1769 void addVectorElement(EvalInfo &Info,
const Expr *
E,
QualType EltTy,
1770 uint64_t Size, uint64_t Idx) {
1772 Designator.addVectorElementUnchecked(EltTy, Size, Idx);
1774 void clearIsNullPointer() {
1777 void adjustOffsetAndIndex(EvalInfo &Info,
const Expr *
E,
1787 uint64_t Offset64 = Offset.getQuantity();
1789 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
1794 clearIsNullPointer();
1799 clearIsNullPointer();
1806 : DeclAndIsDerivedMember(
Decl,
false) {}
1811 return DeclAndIsDerivedMember.getPointer();
1814 bool isDerivedMember()
const {
1815 return DeclAndIsDerivedMember.getInt();
1819 return cast<CXXRecordDecl>(
1820 DeclAndIsDerivedMember.getPointer()->getDeclContext());
1827 assert(
V.isMemberPointer());
1828 DeclAndIsDerivedMember.setPointer(
V.getMemberPointerDecl());
1829 DeclAndIsDerivedMember.setInt(
V.isMemberPointerToDerivedMember());
1831 llvm::append_range(
Path,
V.getMemberPointerPath());
1837 llvm::PointerIntPair<const ValueDecl*, 1, bool> DeclAndIsDerivedMember;
1845 assert(!
Path.empty());
1847 if (
Path.size() >= 2)
1851 if (
Expected->getCanonicalDecl() !=
Class->getCanonicalDecl()) {
1867 if (!isDerivedMember()) {
1868 Path.push_back(Derived);
1871 if (!castBack(Derived))
1874 DeclAndIsDerivedMember.setInt(
false);
1882 DeclAndIsDerivedMember.setInt(
true);
1883 if (isDerivedMember()) {
1887 return castBack(
Base);
1892 static bool operator==(
const MemberPtr &LHS,
const MemberPtr &RHS) {
1893 if (!LHS.getDecl() || !RHS.getDecl())
1894 return !LHS.getDecl() && !RHS.getDecl();
1895 if (LHS.getDecl()->getCanonicalDecl() != RHS.getDecl()->getCanonicalDecl())
1897 return LHS.Path == RHS.Path;
1904 bool AllowNonLiteralTypes =
false);
1906 bool InvalidBaseOK =
false);
1908 bool InvalidBaseOK =
false);
1922 std::string *StringResult =
nullptr);
1939 if (Int.isUnsigned() || Int.isMinSignedValue()) {
1940 Int = Int.extend(Int.getBitWidth() + 1);
1941 Int.setIsSigned(
true);
1946template<
typename KeyT>
1948 ScopeKind
Scope, LValue &LV) {
1949 unsigned Version = getTempVersion();
1958 assert(Args.CallIndex == Index &&
"creating parameter in wrong frame");
1964 return createLocal(
Base, PVD, PVD->
getType(), ScopeKind::Call);
1969 assert(
Base.getCallIndex() == Index &&
"lvalue for wrong frame");
1970 unsigned Version =
Base.getVersion();
1971 APValue &Result = Temporaries[MapKeyTy(Key, Version)];
1972 assert(Result.isAbsent() &&
"local created multiple times");
1978 if (Index <= Info.SpeculativeEvaluationDepth) {
1979 if (
T.isDestructedType())
1980 Info.noteSideEffect();
1982 Info.CleanupStack.push_back(Cleanup(&Result,
Base,
T,
Scope));
1989 FFDiag(
E, diag::note_constexpr_heap_alloc_limit_exceeded);
1995 auto Result = HeapAllocs.emplace(std::piecewise_construct,
1996 std::forward_as_tuple(DA), std::tuple<>());
1997 assert(Result.second &&
"reused a heap alloc index?");
1998 Result.first->second.AllocExpr =
E;
1999 return &Result.first->second.Value;
2003void CallStackFrame::describe(raw_ostream &Out)
const {
2004 unsigned ArgIndex = 0;
2006 isa<CXXMethodDecl>(Callee) && !isa<CXXConstructorDecl>(Callee) &&
2007 cast<CXXMethodDecl>(Callee)->isImplicitObjectMemberFunction();
2010 Callee->getNameForDiagnostic(Out, Info.Ctx.getPrintingPolicy(),
2013 if (
This && IsMemberCall) {
2014 if (
const auto *MCE = dyn_cast_if_present<CXXMemberCallExpr>(
CallExpr)) {
2015 const Expr *
Object = MCE->getImplicitObjectArgument();
2016 Object->printPretty(Out,
nullptr, Info.Ctx.getPrintingPolicy(),
2018 if (
Object->getType()->isPointerType())
2022 }
else if (
const auto *OCE =
2023 dyn_cast_if_present<CXXOperatorCallExpr>(
CallExpr)) {
2024 OCE->getArg(0)->printPretty(Out,
nullptr,
2025 Info.Ctx.getPrintingPolicy(),
2030 This->moveInto(Val);
2033 Info.Ctx.getLValueReferenceType(
This->Designator.MostDerivedType));
2036 Callee->getNameForDiagnostic(Out, Info.Ctx.getPrintingPolicy(),
2038 IsMemberCall =
false;
2044 E =
Callee->param_end(); I !=
E; ++I, ++ArgIndex) {
2045 if (ArgIndex > (
unsigned)IsMemberCall)
2049 APValue *
V = Info.getParamSlot(Arguments, Param);
2051 V->printPretty(Out, Info.Ctx, Param->
getType());
2055 if (ArgIndex == 0 && IsMemberCall)
2056 Out <<
"->" << *
Callee <<
'(';
2070 return Info.noteSideEffect();
2076 unsigned Builtin =
E->getBuiltinCallee();
2077 return (
Builtin == Builtin::BI__builtin___CFStringMakeConstantString ||
2078 Builtin == Builtin::BI__builtin___NSStringMakeConstantString ||
2079 Builtin == Builtin::BI__builtin_ptrauth_sign_constant ||
2080 Builtin == Builtin::BI__builtin_function_start);
2084 const auto *BaseExpr =
2085 llvm::dyn_cast_if_present<CallExpr>(LVal.Base.dyn_cast<
const Expr *>());
2100 if (
const VarDecl *VD = dyn_cast<VarDecl>(
D))
2101 return VD->hasGlobalStorage();
2102 if (isa<TemplateParamObjectDecl>(
D))
2107 return isa<FunctionDecl, MSGuidDecl, UnnamedGlobalConstantDecl>(
D);
2117 case Expr::CompoundLiteralExprClass: {
2121 case Expr::MaterializeTemporaryExprClass:
2124 return cast<MaterializeTemporaryExpr>(
E)->getStorageDuration() ==
SD_Static;
2126 case Expr::StringLiteralClass:
2127 case Expr::PredefinedExprClass:
2128 case Expr::ObjCStringLiteralClass:
2129 case Expr::ObjCEncodeExprClass:
2131 case Expr::ObjCBoxedExprClass:
2132 return cast<ObjCBoxedExpr>(
E)->isExpressibleAsConstantInitializer();
2133 case Expr::CallExprClass:
2136 case Expr::AddrLabelExprClass:
2140 case Expr::BlockExprClass:
2141 return !cast<BlockExpr>(
E)->getBlockDecl()->hasCaptures();
2144 case Expr::SourceLocExprClass:
2146 case Expr::ImplicitValueInitExprClass:
2158 return LVal.Base.dyn_cast<
const ValueDecl*>();
2171 const auto *BaseExpr = LVal.Base.dyn_cast<
const Expr *>();
2176 if (
const auto *EE = dyn_cast<ObjCEncodeExpr>(BaseExpr)) {
2177 Info.Ctx.getObjCEncodingForType(EE->getEncodedType(),
2185 const auto *Lit = dyn_cast<StringLiteral>(BaseExpr);
2186 if (
const auto *PE = dyn_cast<PredefinedExpr>(BaseExpr))
2187 Lit = PE->getFunctionName();
2192 AsString.
Bytes = Lit->getBytes();
2193 AsString.
CharWidth = Lit->getCharByteWidth();
2213 const LValue &RHS) {
2222 CharUnits Offset = RHS.Offset - LHS.Offset;
2223 if (Offset.isNegative()) {
2224 if (LHSString.
Bytes.size() < (
size_t)-Offset.getQuantity())
2226 LHSString.
Bytes = LHSString.
Bytes.drop_front(-Offset.getQuantity());
2228 if (RHSString.
Bytes.size() < (
size_t)Offset.getQuantity())
2230 RHSString.
Bytes = RHSString.
Bytes.drop_front(Offset.getQuantity());
2233 bool LHSIsLonger = LHSString.
Bytes.size() > RHSString.
Bytes.size();
2234 StringRef Longer = LHSIsLonger ? LHSString.
Bytes : RHSString.
Bytes;
2235 StringRef Shorter = LHSIsLonger ? RHSString.
Bytes : LHSString.
Bytes;
2236 int ShorterCharWidth = (LHSIsLonger ? RHSString : LHSString).CharWidth;
2241 for (
int NullByte : llvm::seq(ShorterCharWidth)) {
2242 if (Shorter.size() + NullByte >= Longer.size())
2244 if (Longer[Shorter.size() + NullByte])
2250 return Shorter == Longer.take_front(Shorter.size());
2260 if (isa_and_nonnull<VarDecl>(
Decl)) {
2270 if (!A.getLValueBase())
2271 return !B.getLValueBase();
2272 if (!B.getLValueBase())
2275 if (A.getLValueBase().getOpaqueValue() !=
2276 B.getLValueBase().getOpaqueValue())
2279 return A.getLValueCallIndex() == B.getLValueCallIndex() &&
2280 A.getLValueVersion() == B.getLValueVersion();
2284 assert(
Base &&
"no location for a null lvalue");
2290 if (
auto *PVD = dyn_cast_or_null<ParmVarDecl>(VD)) {
2292 for (CallStackFrame *F = Info.CurrentCall; F; F = F->Caller) {
2293 if (F->Arguments.CallIndex ==
Base.getCallIndex() &&
2294 F->Arguments.Version ==
Base.getVersion() && F->Callee &&
2295 Idx < F->Callee->getNumParams()) {
2296 VD = F->Callee->getParamDecl(Idx);
2303 Info.Note(VD->
getLocation(), diag::note_declared_at);
2305 Info.Note(
E->
getExprLoc(), diag::note_constexpr_temporary_here);
2308 if (std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA))
2309 Info.Note((*Alloc)->AllocExpr->getExprLoc(),
2310 diag::note_constexpr_dynamic_alloc_here);
2343 const SubobjectDesignator &
Designator = LVal.getLValueDesignator();
2351 if (isTemplateArgument(Kind)) {
2352 int InvalidBaseKind = -1;
2355 InvalidBaseKind = 0;
2356 else if (isa_and_nonnull<StringLiteral>(BaseE))
2357 InvalidBaseKind = 1;
2358 else if (isa_and_nonnull<MaterializeTemporaryExpr>(BaseE) ||
2359 isa_and_nonnull<LifetimeExtendedTemporaryDecl>(BaseVD))
2360 InvalidBaseKind = 2;
2361 else if (
auto *PE = dyn_cast_or_null<PredefinedExpr>(BaseE)) {
2362 InvalidBaseKind = 3;
2363 Ident = PE->getIdentKindName();
2366 if (InvalidBaseKind != -1) {
2367 Info.FFDiag(
Loc, diag::note_constexpr_invalid_template_arg)
2368 << IsReferenceType << !
Designator.Entries.empty() << InvalidBaseKind
2374 if (
auto *FD = dyn_cast_or_null<FunctionDecl>(BaseVD);
2375 FD && FD->isImmediateFunction()) {
2376 Info.FFDiag(
Loc, diag::note_consteval_address_accessible)
2378 Info.Note(FD->getLocation(), diag::note_declared_at);
2386 if (Info.getLangOpts().CPlusPlus11) {
2387 Info.FFDiag(
Loc, diag::note_constexpr_non_global, 1)
2388 << IsReferenceType << !
Designator.Entries.empty() << !!BaseVD
2390 auto *VarD = dyn_cast_or_null<VarDecl>(BaseVD);
2391 if (VarD && VarD->isConstexpr()) {
2397 Info.Note(VarD->getLocation(), diag::note_constexpr_not_static)
2409 assert((Info.checkingPotentialConstantExpression() ||
2410 LVal.getLValueCallIndex() == 0) &&
2411 "have call index for global lvalue");
2413 if (LVal.allowConstexprUnknown()) {
2415 Info.FFDiag(
Loc, diag::note_constexpr_var_init_non_constant, 1) << BaseVD;
2424 Info.FFDiag(
Loc, diag::note_constexpr_dynamic_alloc)
2425 << IsReferenceType << !
Designator.Entries.empty();
2431 if (
const VarDecl *Var = dyn_cast<const VarDecl>(BaseVD)) {
2433 if (Var->getTLSKind())
2439 if (!isForManglingOnly(Kind) && Var->hasAttr<DLLImportAttr>())
2445 if (Info.getASTContext().getLangOpts().CUDA &&
2446 Info.getASTContext().getLangOpts().CUDAIsDevice &&
2447 Info.getASTContext().CUDAConstantEvalCtx.NoWrongSidedVars) {
2448 if ((!Var->hasAttr<CUDADeviceAttr>() &&
2449 !Var->hasAttr<CUDAConstantAttr>() &&
2450 !Var->getType()->isCUDADeviceBuiltinSurfaceType() &&
2451 !Var->getType()->isCUDADeviceBuiltinTextureType()) ||
2452 Var->hasAttr<HIPManagedAttr>())
2456 if (
const auto *FD = dyn_cast<const FunctionDecl>(BaseVD)) {
2467 if (Info.getLangOpts().CPlusPlus && !isForManglingOnly(Kind) &&
2468 FD->hasAttr<DLLImportAttr>())
2472 }
else if (
const auto *MTE =
2473 dyn_cast_or_null<MaterializeTemporaryExpr>(BaseE)) {
2474 if (CheckedTemps.insert(MTE).second) {
2477 Info.FFDiag(MTE->getExprLoc(),
2478 diag::note_constexpr_unsupported_temporary_nontrivial_dtor)
2483 APValue *
V = MTE->getOrCreateValue(
false);
2484 assert(
V &&
"evasluation result refers to uninitialised temporary");
2486 Info, MTE->getExprLoc(), TempType, *
V, Kind,
2487 nullptr, CheckedTemps))
2494 if (!IsReferenceType)
2506 Info.FFDiag(
Loc, diag::note_constexpr_past_end, 1)
2507 << !
Designator.Entries.empty() << !!BaseVD << BaseVD;
2522 const auto *FD = dyn_cast_or_null<CXXMethodDecl>(
Member);
2525 if (FD->isImmediateFunction()) {
2526 Info.FFDiag(
Loc, diag::note_consteval_address_accessible) << 0;
2527 Info.Note(FD->getLocation(), diag::note_declared_at);
2530 return isForManglingOnly(Kind) || FD->isVirtual() ||
2531 !FD->hasAttr<DLLImportAttr>();
2537 const LValue *
This =
nullptr) {
2539 if (Info.getLangOpts().CPlusPlus23)
2558 if (
This && Info.EvaluatingDecl ==
This->getLValueBase())
2562 if (Info.getLangOpts().CPlusPlus11)
2563 Info.FFDiag(
E, diag::note_constexpr_nonliteral)
2566 Info.FFDiag(
E, diag::note_invalid_subexpr_in_const_expr);
2577 if (SubobjectDecl) {
2578 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
2579 << 1 << SubobjectDecl;
2581 diag::note_constexpr_subobject_declared_here);
2583 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
2592 Type = AT->getValueType();
2597 if (
Value.isArray()) {
2599 for (
unsigned I = 0, N =
Value.getArrayInitializedElts(); I != N; ++I) {
2601 Value.getArrayInitializedElt(I), Kind,
2602 SubobjectDecl, CheckedTemps))
2605 if (!
Value.hasArrayFiller())
2608 Value.getArrayFiller(), Kind, SubobjectDecl,
2611 if (
Value.isUnion() &&
Value.getUnionField()) {
2614 Value.getUnionValue(), Kind,
Value.getUnionField(), CheckedTemps);
2616 if (
Value.isStruct()) {
2618 if (
const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {
2619 unsigned BaseIndex = 0;
2621 const APValue &BaseValue =
Value.getStructBase(BaseIndex);
2624 Info.FFDiag(TypeBeginLoc, diag::note_constexpr_uninitialized_base)
2625 << BS.getType() <<
SourceRange(TypeBeginLoc, BS.getEndLoc());
2635 for (
const auto *I : RD->fields()) {
2636 if (I->isUnnamedBitField())
2640 Value.getStructField(I->getFieldIndex()), Kind,
2646 if (
Value.isLValue() &&
2647 CERK == CheckEvaluationResultKind::ConstantExpression) {
2649 LVal.setFrom(Info.Ctx,
Value);
2654 if (
Value.isMemberPointer() &&
2655 CERK == CheckEvaluationResultKind::ConstantExpression)
2675 nullptr, CheckedTemps);
2684 CheckEvaluationResultKind::FullyInitialized, Info, DiagLoc,
Type,
Value,
2685 ConstantExprKind::Normal,
nullptr, CheckedTemps);
2691 if (!Info.HeapAllocs.empty()) {
2695 Info.CCEDiag(Info.HeapAllocs.begin()->second.AllocExpr,
2696 diag::note_constexpr_memory_leak)
2697 <<
unsigned(Info.HeapAllocs.size() - 1);
2705 if (!
Value.getLValueBase()) {
2707 Result = !
Value.getLValueOffset().isZero();
2725 Result = Val.
getInt().getBoolValue();
2757 llvm_unreachable(
"unknown APValue kind");
2763 assert(
E->
isPRValue() &&
"missing lvalue-to-rvalue conv in bool condition");
2773 Info.CCEDiag(
E, diag::note_constexpr_overflow)
2774 << SrcValue << DestType;
2775 return Info.noteUndefinedBehavior();
2781 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
2785 Result =
APSInt(DestWidth, !DestSigned);
2787 if (
Value.convertToInteger(Result, llvm::APFloat::rmTowardZero, &ignored)
2788 & APFloat::opInvalidOp)
2799 llvm::RoundingMode RM =
2801 if (RM == llvm::RoundingMode::Dynamic)
2802 RM = llvm::RoundingMode::NearestTiesToEven;
2808 APFloat::opStatus St) {
2811 if (Info.InConstantContext)
2815 if ((St & APFloat::opInexact) &&
2819 Info.FFDiag(
E, diag::note_constexpr_dynamic_rounding);
2823 if ((St != APFloat::opOK) &&
2826 FPO.getAllowFEnvAccess())) {
2827 Info.FFDiag(
E, diag::note_constexpr_float_arithmetic_strict);
2831 if ((St & APFloat::opStatus::opInvalidOp) &&
2850 assert((isa<CastExpr>(
E) || isa<CompoundAssignOperator>(
E) ||
2851 isa<ConvertVectorExpr>(
E)) &&
2852 "HandleFloatToFloatCast has been checked with only CastExpr, "
2853 "CompoundAssignOperator and ConvertVectorExpr. Please either validate "
2854 "the new expression or address the root cause of this usage.");
2856 APFloat::opStatus St;
2857 APFloat
Value = Result;
2859 St = Result.convert(Info.Ctx.getFloatTypeSemantics(DestType), RM, &ignored);
2866 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
2872 Result =
Value.getBoolValue();
2879 QualType DestType, APFloat &Result) {
2880 Result = APFloat(Info.Ctx.getFloatTypeSemantics(DestType), 1);
2882 APFloat::opStatus St = Result.convertFromAPInt(
Value,
Value.isSigned(), RM);
2888 assert(FD->
isBitField() &&
"truncateBitfieldValue on non-bitfield");
2890 if (!
Value.isInt()) {
2894 assert(
Value.isLValue() &&
"integral value neither int nor lvalue?");
2900 unsigned OldBitWidth = Int.getBitWidth();
2902 if (NewBitWidth < OldBitWidth)
2903 Int = Int.trunc(NewBitWidth).extend(OldBitWidth);
2910template<
typename Operation>
2913 unsigned BitWidth, Operation Op,
2915 if (LHS.isUnsigned()) {
2916 Result = Op(LHS, RHS);
2920 APSInt Value(Op(LHS.extend(BitWidth), RHS.extend(BitWidth)),
false);
2921 Result =
Value.trunc(LHS.getBitWidth());
2922 if (Result.extend(BitWidth) !=
Value) {
2923 if (Info.checkingForUndefinedBehavior())
2925 diag::warn_integer_constant_overflow)
2926 <<
toString(Result, 10, Result.isSigned(),
false,
2938 bool HandleOverflowResult =
true;
2945 std::multiplies<APSInt>(), Result);
2948 std::plus<APSInt>(), Result);
2951 std::minus<APSInt>(), Result);
2952 case BO_And: Result = LHS & RHS;
return true;
2953 case BO_Xor: Result = LHS ^ RHS;
return true;
2954 case BO_Or: Result = LHS | RHS;
return true;
2958 Info.FFDiag(
E, diag::note_expr_divide_by_zero)
2964 if (RHS.isNegative() && RHS.isAllOnes() && LHS.isSigned() &&
2965 LHS.isMinSignedValue())
2967 Info,
E, -LHS.extend(LHS.getBitWidth() + 1),
E->
getType());
2968 Result = (Opcode == BO_Rem ? LHS % RHS : LHS / RHS);
2969 return HandleOverflowResult;
2971 if (Info.getLangOpts().OpenCL)
2973 RHS &=
APSInt(llvm::APInt(RHS.getBitWidth(),
2974 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2976 else if (RHS.isSigned() && RHS.isNegative()) {
2979 Info.CCEDiag(
E, diag::note_constexpr_negative_shift) << RHS;
2980 if (!Info.noteUndefinedBehavior())
2988 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
2990 Info.CCEDiag(
E, diag::note_constexpr_large_shift)
2991 << RHS <<
E->
getType() << LHS.getBitWidth();
2992 if (!Info.noteUndefinedBehavior())
2994 }
else if (LHS.isSigned() && !Info.getLangOpts().CPlusPlus20) {
2999 if (LHS.isNegative()) {
3000 Info.CCEDiag(
E, diag::note_constexpr_lshift_of_negative) << LHS;
3001 if (!Info.noteUndefinedBehavior())
3003 }
else if (LHS.countl_zero() < SA) {
3004 Info.CCEDiag(
E, diag::note_constexpr_lshift_discards);
3005 if (!Info.noteUndefinedBehavior())
3013 if (Info.getLangOpts().OpenCL)
3015 RHS &=
APSInt(llvm::APInt(RHS.getBitWidth(),
3016 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
3018 else if (RHS.isSigned() && RHS.isNegative()) {
3021 Info.CCEDiag(
E, diag::note_constexpr_negative_shift) << RHS;
3022 if (!Info.noteUndefinedBehavior())
3030 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
3032 Info.CCEDiag(
E, diag::note_constexpr_large_shift)
3033 << RHS <<
E->
getType() << LHS.getBitWidth();
3034 if (!Info.noteUndefinedBehavior())
3042 case BO_LT: Result = LHS < RHS;
return true;
3043 case BO_GT: Result = LHS > RHS;
return true;
3044 case BO_LE: Result = LHS <= RHS;
return true;
3045 case BO_GE: Result = LHS >= RHS;
return true;
3046 case BO_EQ: Result = LHS == RHS;
return true;
3047 case BO_NE: Result = LHS != RHS;
return true;
3049 llvm_unreachable(
"BO_Cmp should be handled elsewhere");
3056 const APFloat &RHS) {
3058 APFloat::opStatus St;
3064 St = LHS.multiply(RHS, RM);
3067 St = LHS.add(RHS, RM);
3070 St = LHS.subtract(RHS, RM);
3076 Info.CCEDiag(
E, diag::note_expr_divide_by_zero);
3077 St = LHS.divide(RHS, RM);
3086 Info.CCEDiag(
E, diag::note_constexpr_float_arithmetic) << LHS.isNaN();
3087 return Info.noteUndefinedBehavior();
3095 const APInt &RHSValue, APInt &Result) {
3096 bool LHS = (LHSValue != 0);
3097 bool RHS = (RHSValue != 0);
3099 if (Opcode == BO_LAnd)
3100 Result = LHS && RHS;
3102 Result = LHS || RHS;
3107 const APFloat &RHSValue, APInt &Result) {
3108 bool LHS = !LHSValue.isZero();
3109 bool RHS = !RHSValue.isZero();
3111 if (Opcode == BO_LAnd)
3112 Result = LHS && RHS;
3114 Result = LHS || RHS;
3120 const APValue &RHSValue, APInt &Result) {
3124 RHSValue.
getInt(), Result);
3130template <
typename APTy>
3133 const APTy &RHSValue, APInt &Result) {
3136 llvm_unreachable(
"unsupported binary operator");
3138 Result = (LHSValue == RHSValue);
3141 Result = (LHSValue != RHSValue);
3144 Result = (LHSValue < RHSValue);
3147 Result = (LHSValue > RHSValue);
3150 Result = (LHSValue <= RHSValue);
3153 Result = (LHSValue >= RHSValue);
3167 const APValue &RHSValue, APInt &Result) {
3171 RHSValue.
getInt(), Result);
3182 assert(Opcode != BO_PtrMemD && Opcode != BO_PtrMemI &&
3183 "Operation not supported on vector types");
3187 QualType EltTy = VT->getElementType();
3194 "A vector result that isn't a vector OR uncalculated LValue");
3200 RHSValue.
getVectorLength() == NumElements &&
"Different vector sizes");
3204 for (
unsigned EltNum = 0; EltNum < NumElements; ++EltNum) {
3209 APSInt EltResult{Info.Ctx.getIntWidth(EltTy),
3219 RHSElt.
getInt(), EltResult);
3225 ResultElements.emplace_back(EltResult);
3230 "Mismatched LHS/RHS/Result Type");
3231 APFloat LHSFloat = LHSElt.
getFloat();
3239 ResultElements.emplace_back(LHSFloat);
3243 LHSValue =
APValue(ResultElements.data(), ResultElements.size());
3251 unsigned TruncatedElements) {
3252 SubobjectDesignator &
D = Result.Designator;
3255 if (TruncatedElements ==
D.Entries.size())
3257 assert(TruncatedElements >=
D.MostDerivedPathLength &&
3258 "not casting to a derived class");
3264 for (
unsigned I = TruncatedElements, N =
D.Entries.size(); I != N; ++I) {
3268 if (isVirtualBaseClass(
D.Entries[I]))
3274 D.Entries.resize(TruncatedElements);
3284 RL = &Info.Ctx.getASTRecordLayout(Derived);
3287 Obj.addDecl(Info,
E,
Base,
false);
3288 Obj.getLValueOffset() += RL->getBaseClassOffset(
Base);
3297 if (!
Base->isVirtual())
3300 SubobjectDesignator &
D = Obj.Designator;
3309 DerivedDecl =
D.MostDerivedType.getNonReferenceType()->getAsCXXRecordDecl();
3315 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(DerivedDecl);
3316 Obj.addDecl(Info,
E, BaseDecl,
true);
3324 PathE =
E->path_end();
3325 PathI != PathE; ++PathI) {
3329 Type = (*PathI)->getType();
3341 llvm_unreachable(
"Class must be derived from the passed in base class!");
3356 RL = &Info.Ctx.getASTRecordLayout(FD->
getParent());
3360 LVal.addDecl(Info,
E, FD);
3361 LVal.adjustOffset(Info.Ctx.toCharUnitsFromBits(RL->getFieldOffset(I)));
3369 for (
const auto *
C : IFD->
chain())
3402 if (SOT == SizeOfType::SizeOf)
3403 Size = Info.Ctx.getTypeSizeInChars(
Type);
3405 Size = Info.Ctx.getTypeInfoDataSizeInChars(
Type).Width;
3422 LVal.adjustOffsetAndIndex(Info,
E, Adjustment, SizeOfPointee);
3428 int64_t Adjustment) {
3430 APSInt::get(Adjustment));
3445 LVal.Offset += SizeOfComponent;
3447 LVal.addComplex(Info,
E, EltTy, Imag);
3453 uint64_t Size, uint64_t Idx) {
3458 LVal.Offset += SizeOfElement * Idx;
3460 LVal.addVectorElement(Info,
E, EltTy, Size, Idx);
3474 const VarDecl *VD, CallStackFrame *Frame,
3475 unsigned Version,
APValue *&Result) {
3478 bool AllowConstexprUnknown =
3483 auto CheckUninitReference = [&](
bool IsLocalVariable) {
3495 if (!AllowConstexprUnknown || IsLocalVariable) {
3496 if (!Info.checkingPotentialConstantExpression())
3497 Info.FFDiag(
E, diag::note_constexpr_use_uninit_reference);
3507 Result = Frame->getTemporary(VD, Version);
3509 return CheckUninitReference(
true);
3511 if (!isa<ParmVarDecl>(VD)) {
3518 "missing value for local variable");
3519 if (Info.checkingPotentialConstantExpression())
3524 diag::note_unimplemented_constexpr_lambda_feature_ast)
3525 <<
"captures not currently allowed";
3532 if (Info.EvaluatingDecl ==
Base) {
3533 Result = Info.EvaluatingDeclValue;
3534 return CheckUninitReference(
false);
3541 if (isa<ParmVarDecl>(VD)) {
3542 if (AllowConstexprUnknown) {
3549 if (!Info.checkingPotentialConstantExpression() ||
3550 !Info.CurrentCall->Callee ||
3552 if (Info.getLangOpts().CPlusPlus11) {
3553 Info.FFDiag(
E, diag::note_constexpr_function_param_value_unknown)
3574 if (!
Init && !AllowConstexprUnknown) {
3577 if (!Info.checkingPotentialConstantExpression()) {
3578 Info.FFDiag(
E, diag::note_constexpr_var_init_unknown, 1)
3589 if (
Init &&
Init->isValueDependent()) {
3596 if (!Info.checkingPotentialConstantExpression()) {
3597 Info.FFDiag(
E, Info.getLangOpts().CPlusPlus11
3598 ? diag::note_constexpr_ltor_non_constexpr
3599 : diag::note_constexpr_ltor_non_integral, 1)
3613 Info.FFDiag(
E, diag::note_constexpr_var_init_non_constant, 1) << VD;
3629 !AllowConstexprUnknown) ||
3630 ((Info.getLangOpts().CPlusPlus || Info.getLangOpts().OpenCL) &&
3633 Info.CCEDiag(
E, diag::note_constexpr_var_init_non_constant, 1) << VD;
3643 Info.FFDiag(
E, diag::note_constexpr_var_init_weak) << VD;
3650 if (!Result && !AllowConstexprUnknown)
3653 return CheckUninitReference(
false);
3664 if (I->getType()->getAsCXXRecordDecl()->getCanonicalDecl() ==
Base)
3668 llvm_unreachable(
"base class missing from derived class's bases list");
3674 assert(!isa<SourceLocExpr>(Lit) &&
3675 "SourceLocExpr should have already been converted to a StringLiteral");
3678 if (
const auto *ObjCEnc = dyn_cast<ObjCEncodeExpr>(Lit)) {
3680 Info.Ctx.getObjCEncodingForType(ObjCEnc->getEncodedType(), Str);
3681 assert(Index <= Str.size() &&
"Index too large");
3682 return APSInt::getUnsigned(Str.c_str()[Index]);
3685 if (
auto PE = dyn_cast<PredefinedExpr>(Lit))
3686 Lit = PE->getFunctionName();
3689 Info.Ctx.getAsConstantArrayType(S->getType());
3690 assert(CAT &&
"string literal isn't an array");
3692 assert(CharType->
isIntegerType() &&
"unexpected character type");
3695 if (Index < S->getLength())
3696 Value = S->getCodeUnit(Index);
3708 AllocType.isNull() ? S->getType() : AllocType);
3709 assert(CAT &&
"string literal isn't an array");
3711 assert(CharType->
isIntegerType() &&
"unexpected character type");
3715 std::min(S->getLength(), Elts), Elts);
3718 if (Result.hasArrayFiller())
3720 for (
unsigned I = 0, N = Result.getArrayInitializedElts(); I != N; ++I) {
3721 Value = S->getCodeUnit(I);
3728 unsigned Size = Array.getArraySize();
3729 assert(Index < Size);
3732 unsigned OldElts = Array.getArrayInitializedElts();
3733 unsigned NewElts = std::max(Index+1, OldElts * 2);
3734 NewElts = std::min(Size, std::max(NewElts, 8u));
3738 for (
unsigned I = 0; I != OldElts; ++I)
3740 for (
unsigned I = OldElts; I != NewElts; ++I)
3744 Array.swap(NewValue);
3765 for (
auto *Field : RD->
fields())
3766 if (!Field->isUnnamedBitField() &&
3770 for (
auto &BaseSpec : RD->
bases())
3788 for (
auto *Field : RD->
fields()) {
3793 if (Field->isMutable() &&
3795 Info.FFDiag(
E, diag::note_constexpr_access_mutable, 1) << AK << Field;
3796 Info.Note(Field->getLocation(), diag::note_declared_at);
3804 for (
auto &BaseSpec : RD->
bases())
3814 bool MutableSubobject =
false) {
3819 switch (Info.IsEvaluatingDecl) {
3820 case EvalInfo::EvaluatingDeclKind::None:
3823 case EvalInfo::EvaluatingDeclKind::Ctor:
3825 if (Info.EvaluatingDecl ==
Base)
3830 if (
auto *BaseE =
Base.dyn_cast<
const Expr *>())
3831 if (
auto *BaseMTE = dyn_cast<MaterializeTemporaryExpr>(BaseE))
3832 return Info.EvaluatingDecl == BaseMTE->getExtendingDecl();
3835 case EvalInfo::EvaluatingDeclKind::Dtor:
3840 if (MutableSubobject ||
Base != Info.EvaluatingDecl)
3849 llvm_unreachable(
"unknown evaluating decl kind");
3854 return Info.CheckArraySize(
3863struct CompleteObject {
3871 CompleteObject() :
Value(nullptr) {}
3875 bool mayAccessMutableMembers(EvalInfo &Info,
AccessKinds AK)
const {
3886 if (!Info.getLangOpts().CPlusPlus14 &&
3887 AK != AccessKinds::AK_IsWithinLifetime)
3892 explicit operator bool()
const {
return !
Type.isNull(); }
3897 bool IsMutable =
false) {
3911template <
typename Sub
objectHandler>
3912static typename SubobjectHandler::result_type
3914 const SubobjectDesignator &Sub, SubobjectHandler &handler) {
3917 return handler.failed();
3918 if (Sub.isOnePastTheEnd() || Sub.isMostDerivedAnUnsizedArray()) {
3919 if (Info.getLangOpts().CPlusPlus11)
3920 Info.FFDiag(
E, Sub.isOnePastTheEnd()
3921 ? diag::note_constexpr_access_past_end
3922 : diag::note_constexpr_access_unsized_array)
3923 << handler.AccessKind;
3926 return handler.failed();
3932 const FieldDecl *VolatileField =
nullptr;
3935 for (
unsigned I = 0, N = Sub.Entries.size(); ; ++I) {
3946 if (!Info.checkingPotentialConstantExpression())
3947 Info.FFDiag(
E, diag::note_constexpr_access_uninit)
3950 return handler.failed();
3958 Info.isEvaluatingCtorDtor(
3959 Obj.Base,
ArrayRef(Sub.Entries.begin(), Sub.Entries.begin() + I)) !=
3960 ConstructionPhase::None) {
3970 if (Info.getLangOpts().CPlusPlus) {
3974 if (VolatileField) {
3977 Decl = VolatileField;
3978 }
else if (
auto *VD = Obj.Base.dyn_cast<
const ValueDecl*>()) {
3980 Loc = VD->getLocation();
3984 if (
auto *
E = Obj.Base.dyn_cast<
const Expr *>())
3987 Info.FFDiag(
E, diag::note_constexpr_access_volatile_obj, 1)
3988 << handler.AccessKind << DiagKind <<
Decl;
3989 Info.Note(
Loc, diag::note_constexpr_volatile_here) << DiagKind;
3991 Info.FFDiag(
E, diag::note_invalid_subexpr_in_const_expr);
3993 return handler.failed();
4001 !Obj.mayAccessMutableMembers(Info, handler.AccessKind) &&
4003 return handler.failed();
4007 if (!handler.found(*O, ObjType))
4019 LastField =
nullptr;
4023 assert(CAT &&
"vla in literal type?");
4024 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4025 if (CAT->
getSize().ule(Index)) {
4028 if (Info.getLangOpts().CPlusPlus11)
4029 Info.FFDiag(
E, diag::note_constexpr_access_past_end)
4030 << handler.AccessKind;
4033 return handler.failed();
4040 else if (!
isRead(handler.AccessKind)) {
4042 return handler.failed();
4050 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4052 if (Info.getLangOpts().CPlusPlus11)
4053 Info.FFDiag(
E, diag::note_constexpr_access_past_end)
4054 << handler.AccessKind;
4057 return handler.failed();
4063 assert(I == N - 1 &&
"extracting subobject of scalar?");
4073 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4074 unsigned NumElements = VT->getNumElements();
4075 if (Index == NumElements) {
4076 if (Info.getLangOpts().CPlusPlus11)
4077 Info.FFDiag(
E, diag::note_constexpr_access_past_end)
4078 << handler.AccessKind;
4081 return handler.failed();
4084 if (Index > NumElements) {
4085 Info.CCEDiag(
E, diag::note_constexpr_array_index)
4086 << Index << 0 << NumElements;
4087 return handler.failed();
4090 ObjType = VT->getElementType();
4091 assert(I == N - 1 &&
"extracting subobject of scalar?");
4093 }
else if (
const FieldDecl *Field = getAsField(Sub.Entries[I])) {
4094 if (Field->isMutable() &&
4095 !Obj.mayAccessMutableMembers(Info, handler.AccessKind)) {
4096 Info.FFDiag(
E, diag::note_constexpr_access_mutable, 1)
4097 << handler.AccessKind << Field;
4098 Info.Note(Field->getLocation(), diag::note_declared_at);
4099 return handler.failed();
4109 if (I == N - 1 && handler.AccessKind ==
AK_Construct) {
4120 Info.FFDiag(
E, diag::note_constexpr_access_inactive_union_member)
4121 << handler.AccessKind << Field << !UnionField << UnionField;
4122 return handler.failed();
4131 if (Field->getType().isVolatileQualified())
4132 VolatileField = Field;
4145struct ExtractSubobjectHandler {
4151 typedef bool result_type;
4152 bool failed() {
return false; }
4172 const CompleteObject &Obj,
4173 const SubobjectDesignator &Sub,
APValue &Result,
4176 ExtractSubobjectHandler Handler = {Info,
E, Result, AK};
4181struct ModifySubobjectHandler {
4186 typedef bool result_type;
4192 Info.FFDiag(
E, diag::note_constexpr_modify_const_type) << QT;
4198 bool failed() {
return false; }
4200 if (!checkConst(SubobjType))
4203 Subobj.
swap(NewVal);
4207 if (!checkConst(SubobjType))
4209 if (!NewVal.
isInt()) {
4218 if (!checkConst(SubobjType))
4226const AccessKinds ModifySubobjectHandler::AccessKind;
4230 const CompleteObject &Obj,
4231 const SubobjectDesignator &Sub,
4233 ModifySubobjectHandler Handler = { Info, NewVal,
E };
4240 const SubobjectDesignator &A,
4241 const SubobjectDesignator &B,
4242 bool &WasArrayIndex) {
4243 unsigned I = 0, N = std::min(A.Entries.size(), B.Entries.size());
4244 for (; I != N; ++I) {
4248 if (A.Entries[I].getAsArrayIndex() != B.Entries[I].getAsArrayIndex()) {
4249 WasArrayIndex =
true;
4257 if (A.Entries[I].getAsBaseOrMember() !=
4258 B.Entries[I].getAsBaseOrMember()) {
4259 WasArrayIndex =
false;
4262 if (
const FieldDecl *FD = getAsField(A.Entries[I]))
4264 ObjType = FD->getType();
4270 WasArrayIndex =
false;
4277 const SubobjectDesignator &A,
4278 const SubobjectDesignator &B) {
4279 if (A.Entries.size() != B.Entries.size())
4282 bool IsArray = A.MostDerivedIsArrayElement;
4283 if (IsArray && A.MostDerivedPathLength != A.Entries.size())
4292 return CommonLength >= A.Entries.size() - IsArray;
4299 if (LVal.InvalidBase) {
4301 return CompleteObject();
4305 if (AK == AccessKinds::AK_Dereference)
4306 Info.FFDiag(
E, diag::note_constexpr_dereferencing_null);
4308 Info.FFDiag(
E, diag::note_constexpr_access_null) << AK;
4309 return CompleteObject();
4312 CallStackFrame *Frame =
nullptr;
4314 if (LVal.getLValueCallIndex()) {
4315 std::tie(Frame, Depth) =
4316 Info.getCallFrameAndDepth(LVal.getLValueCallIndex());
4318 Info.FFDiag(
E, diag::note_constexpr_lifetime_ended, 1)
4319 << AK << LVal.Base.is<
const ValueDecl*>();
4321 return CompleteObject();
4332 if (Info.getLangOpts().CPlusPlus)
4333 Info.FFDiag(
E, diag::note_constexpr_access_volatile_type)
4337 return CompleteObject();
4342 QualType BaseType = getType(LVal.Base);
4344 if (Info.getLangOpts().CPlusPlus14 && LVal.Base == Info.EvaluatingDecl &&
4348 BaseVal = Info.EvaluatingDeclValue;
4351 if (
auto *GD = dyn_cast<MSGuidDecl>(
D)) {
4354 Info.FFDiag(
E, diag::note_constexpr_modify_global);
4355 return CompleteObject();
4359 Info.FFDiag(
E, diag::note_constexpr_unsupported_layout)
4361 return CompleteObject();
4363 return CompleteObject(LVal.Base, &
V, GD->getType());
4367 if (
auto *GCD = dyn_cast<UnnamedGlobalConstantDecl>(
D)) {
4369 Info.FFDiag(
E, diag::note_constexpr_modify_global);
4370 return CompleteObject();
4372 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&GCD->getValue()),
4377 if (
auto *TPO = dyn_cast<TemplateParamObjectDecl>(
D)) {
4379 Info.FFDiag(
E, diag::note_constexpr_modify_global);
4380 return CompleteObject();
4382 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&TPO->getValue()),
4393 const VarDecl *VD = dyn_cast<VarDecl>(
D);
4400 return CompleteObject();
4403 bool IsConstant = BaseType.
isConstant(Info.Ctx);
4404 bool ConstexprVar =
false;
4405 if (
const auto *VD = dyn_cast_if_present<VarDecl>(
4406 Info.EvaluatingDecl.dyn_cast<
const ValueDecl *>()))
4413 if (IsAccess && isa<ParmVarDecl>(VD)) {
4417 }
else if (Info.getLangOpts().CPlusPlus14 &&
4424 Info.FFDiag(
E, diag::note_constexpr_modify_global);
4425 return CompleteObject();
4428 }
else if (Info.getLangOpts().C23 && ConstexprVar) {
4430 return CompleteObject();
4434 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4435 if (Info.getLangOpts().CPlusPlus) {
4436 Info.FFDiag(
E, diag::note_constexpr_ltor_non_const_int, 1) << VD;
4437 Info.Note(VD->
getLocation(), diag::note_declared_at);
4441 return CompleteObject();
4443 }
else if (!IsAccess) {
4444 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4446 Info.checkingPotentialConstantExpression() &&
4449 }
else if (IsConstant) {
4453 if (Info.getLangOpts().CPlusPlus) {
4454 Info.CCEDiag(
E, Info.getLangOpts().CPlusPlus11
4455 ? diag::note_constexpr_ltor_non_constexpr
4456 : diag::note_constexpr_ltor_non_integral, 1)
4458 Info.Note(VD->
getLocation(), diag::note_declared_at);
4464 if (Info.getLangOpts().CPlusPlus) {
4465 Info.FFDiag(
E, Info.getLangOpts().CPlusPlus11
4466 ? diag::note_constexpr_ltor_non_constexpr
4467 : diag::note_constexpr_ltor_non_integral, 1)
4469 Info.Note(VD->
getLocation(), diag::note_declared_at);
4473 return CompleteObject();
4482 return CompleteObject();
4487 if (!Info.checkingPotentialConstantExpression()) {
4488 Info.FFDiag(
E, diag::note_constexpr_access_unknown_variable, 1)
4490 Info.Note(VD->getLocation(), diag::note_declared_at);
4492 return CompleteObject();
4495 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
4497 Info.FFDiag(
E, diag::note_constexpr_access_deleted_object) << AK;
4498 return CompleteObject();
4500 return CompleteObject(LVal.Base, &(*Alloc)->Value,
4501 LVal.Base.getDynamicAllocType());
4510 dyn_cast_or_null<MaterializeTemporaryExpr>(
Base)) {
4511 assert(MTE->getStorageDuration() ==
SD_Static &&
4512 "should have a frame for a non-global materialized temporary");
4539 if (!MTE->isUsableInConstantExpressions(Info.Ctx) &&
4542 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4543 Info.FFDiag(
E, diag::note_constexpr_access_static_temporary, 1) << AK;
4544 Info.Note(MTE->getExprLoc(), diag::note_constexpr_temporary_here);
4545 return CompleteObject();
4548 BaseVal = MTE->getOrCreateValue(
false);
4549 assert(BaseVal &&
"got reference to unevaluated temporary");
4551 dyn_cast_or_null<CompoundLiteralExpr>(
Base)) {
4567 !CLETy.isConstant(Info.Ctx)) {
4569 Info.Note(CLE->getExprLoc(), diag::note_declared_at);
4570 return CompleteObject();
4573 BaseVal = &CLE->getStaticValue();
4576 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4579 Info.FFDiag(
E, diag::note_constexpr_access_unreadable_object)
4582 Info.Ctx.getLValueReferenceType(LValType));
4584 return CompleteObject();
4587 BaseVal = Frame->getTemporary(
Base, LVal.Base.getVersion());
4588 assert(BaseVal &&
"missing value for temporary");
4599 unsigned VisibleDepth = Depth;
4600 if (llvm::isa_and_nonnull<ParmVarDecl>(
4601 LVal.Base.dyn_cast<
const ValueDecl *>()))
4603 if ((Frame && Info.getLangOpts().CPlusPlus14 &&
4604 Info.EvalStatus.HasSideEffects) ||
4605 (
isModification(AK) && VisibleDepth < Info.SpeculativeEvaluationDepth))
4606 return CompleteObject();
4608 return CompleteObject(LVal.getLValueBase(), BaseVal, BaseType);
4627 const LValue &LVal,
APValue &RVal,
4628 bool WantObjectRepresentation =
false) {
4629 if (LVal.Designator.Invalid)
4638 if (
Base && !LVal.getLValueCallIndex() && !
Type.isVolatileQualified()) {
4639 if (isa<StringLiteral>(
Base) || isa<PredefinedExpr>(
Base)) {
4642 assert(LVal.Designator.Entries.size() <= 1 &&
4643 "Can only read characters from string literals");
4644 if (LVal.Designator.Entries.empty()) {
4651 if (LVal.Designator.isOnePastTheEnd()) {
4652 if (Info.getLangOpts().CPlusPlus11)
4653 Info.FFDiag(Conv, diag::note_constexpr_access_past_end) << AK;
4658 uint64_t CharIndex = LVal.Designator.Entries[0].getAsArrayIndex();
4665 return Obj &&
extractSubobject(Info, Conv, Obj, LVal.Designator, RVal, AK);
4671 if (LVal.Designator.Invalid)
4674 if (!Info.getLangOpts().CPlusPlus14) {
4684struct CompoundAssignSubobjectHandler {
4693 typedef bool result_type;
4698 Info.FFDiag(
E, diag::note_constexpr_modify_const_type) << QT;
4704 bool failed() {
return false; }
4708 return found(Subobj.
getInt(), SubobjType);
4710 return found(Subobj.
getFloat(), SubobjType);
4717 return foundPointer(Subobj, SubobjType);
4719 return foundVector(Subobj, SubobjType);
4721 Info.FFDiag(
E, diag::note_constexpr_access_uninit)
4733 if (!checkConst(SubobjType))
4744 if (!checkConst(SubobjType))
4763 Info.Ctx.getLangOpts());
4766 PromotedLHSType, FValue) &&
4776 return checkConst(SubobjType) &&
4783 if (!checkConst(SubobjType))
4791 (Opcode != BO_Add && Opcode != BO_Sub)) {
4797 if (Opcode == BO_Sub)
4801 LVal.setFrom(Info.Ctx, Subobj);
4804 LVal.moveInto(Subobj);
4810const AccessKinds CompoundAssignSubobjectHandler::AccessKind;
4815 const LValue &LVal,
QualType LValType,
4819 if (LVal.Designator.Invalid)
4822 if (!Info.getLangOpts().CPlusPlus14) {
4828 CompoundAssignSubobjectHandler Handler = { Info,
E, PromotedLValType, Opcode,
4830 return Obj &&
findSubobject(Info,
E, Obj, LVal.Designator, Handler);
4834struct IncDecSubobjectHandler {
4840 typedef bool result_type;
4845 Info.FFDiag(
E, diag::note_constexpr_modify_const_type) << QT;
4851 bool failed() {
return false; }
4862 return found(Subobj.
getInt(), SubobjType);
4864 return found(Subobj.
getFloat(), SubobjType);
4874 return foundPointer(Subobj, SubobjType);
4882 if (!checkConst(SubobjType))
4904 bool WasNegative =
Value.isNegative();
4908 if (!WasNegative &&
Value.isNegative() &&
E->canOverflow()) {
4915 if (WasNegative && !
Value.isNegative() &&
E->canOverflow()) {
4916 unsigned BitWidth =
Value.getBitWidth();
4917 APSInt ActualValue(
Value.sext(BitWidth + 1),
false);
4918 ActualValue.setBit(BitWidth);
4925 if (!checkConst(SubobjType))
4932 APFloat::opStatus St;
4934 St =
Value.add(One, RM);
4936 St =
Value.subtract(One, RM);
4940 if (!checkConst(SubobjType))
4952 LVal.setFrom(Info.Ctx, Subobj);
4956 LVal.moveInto(Subobj);
4965 if (LVal.Designator.Invalid)
4968 if (!Info.getLangOpts().CPlusPlus14) {
4975 IncDecSubobjectHandler Handler = {Info, cast<UnaryOperator>(
E), AK, Old};
4976 return Obj &&
findSubobject(Info,
E, Obj, LVal.Designator, Handler);
4982 if (Object->getType()->isPointerType() && Object->isPRValue())
4985 if (Object->isGLValue())
4988 if (Object->getType()->isLiteralType(Info.Ctx))
4991 if (Object->getType()->isRecordType() && Object->isPRValue())
4994 Info.FFDiag(Object, diag::note_constexpr_nonliteral) << Object->getType();
5013 bool IncludeMember =
true) {
5020 if (!MemPtr.getDecl()) {
5026 if (MemPtr.isDerivedMember()) {
5033 if (LV.Designator.MostDerivedPathLength + MemPtr.Path.size() >
5034 LV.Designator.Entries.size()) {
5038 unsigned PathLengthToMember =
5039 LV.Designator.Entries.size() - MemPtr.Path.size();
5040 for (
unsigned I = 0, N = MemPtr.Path.size(); I != N; ++I) {
5042 LV.Designator.Entries[PathLengthToMember + I]);
5059 (PathLengthToMember > LV.Designator.MostDerivedPathLength)
5060 ? getAsBaseClass(LV.Designator.Entries[PathLengthToMember - 1])
5061 : LV.Designator.MostDerivedType->getAsCXXRecordDecl();
5062 const CXXRecordDecl *LastMPDecl = MemPtr.getContainingRecord();
5070 PathLengthToMember))
5072 }
else if (!MemPtr.Path.empty()) {
5074 LV.Designator.Entries.reserve(LV.Designator.Entries.size() +
5075 MemPtr.Path.size() + IncludeMember);
5081 assert(RD &&
"member pointer access on non-class-type expression");
5083 for (
unsigned I = 1, N = MemPtr.Path.size(); I != N; ++I) {
5091 MemPtr.getContainingRecord()))
5096 if (IncludeMember) {
5097 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(MemPtr.getDecl())) {
5101 dyn_cast<IndirectFieldDecl>(MemPtr.getDecl())) {
5105 llvm_unreachable(
"can't construct reference to bound member function");
5109 return MemPtr.getDecl();
5115 bool IncludeMember =
true) {
5119 if (Info.noteFailure()) {
5127 BO->
getRHS(), IncludeMember);
5134 SubobjectDesignator &
D = Result.Designator;
5135 if (
D.Invalid || !Result.checkNullPointer(Info,
E,
CSK_Derived))
5143 if (
D.MostDerivedPathLength +
E->path_size() >
D.Entries.size()) {
5144 Info.CCEDiag(
E, diag::note_constexpr_invalid_downcast)
5145 <<
D.MostDerivedType << TargetQT;
5151 unsigned NewEntriesSize =
D.Entries.size() -
E->path_size();
5154 if (NewEntriesSize ==
D.MostDerivedPathLength)
5155 FinalType =
D.MostDerivedType->getAsCXXRecordDecl();
5157 FinalType = getAsBaseClass(
D.Entries[NewEntriesSize - 1]);
5159 Info.CCEDiag(
E, diag::note_constexpr_invalid_downcast)
5160 <<
D.MostDerivedType << TargetQT;
5174 if (!Result.isAbsent())
5178 if (RD->isInvalidDecl()) {
5182 if (RD->isUnion()) {
5187 std::distance(RD->field_begin(), RD->field_end()));
5191 End = RD->bases_end();
5192 I != End; ++I, ++Index)
5196 for (
const auto *I : RD->fields()) {
5197 if (I->isUnnamedBitField())
5200 I->getType(), Result.getStructField(I->getFieldIndex()));
5208 if (Result.hasArrayFiller())
5220enum EvalStmtResult {
5240 assert(
Init->isGLValue() &&
D->getType()->isReferenceType());
5249 if (!Result.Designator.Invalid && Result.Designator.isOnePastTheEnd()) {
5255 Result.moveInto(Val);
5267 APValue &Val = Info.CurrentCall->createTemporary(VD, VD->
getType(),
5268 ScopeKind::Block, Result);
5273 return Info.noteSideEffect();
5297 bool EvaluateConditionDecl =
false) {
5299 if (
const VarDecl *VD = dyn_cast<VarDecl>(
D))
5303 EvaluateConditionDecl && DD)
5313 if (
auto *VD = BD->getHoldingVar())
5321 if (
auto *DD = dyn_cast_if_present<DecompositionDecl>(VD)) {
5330 if (Info.noteSideEffect())
5332 assert(
E->
containsErrors() &&
"valid value-dependent expression should never "
5333 "reach invalid code path.");
5339 const Expr *Cond,
bool &Result) {
5342 FullExpressionRAII
Scope(Info);
5349 return Scope.destroy();
5362struct TempVersionRAII {
5363 CallStackFrame &Frame;
5365 TempVersionRAII(CallStackFrame &Frame) : Frame(Frame) {
5366 Frame.pushTempVersion();
5369 ~TempVersionRAII() {
5370 Frame.popTempVersion();
5384 BlockScopeRAII
Scope(Info);
5386 EvalStmtResult ESR =
EvaluateStmt(Result, Info, Body, Case);
5387 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5392 return ESR_Succeeded;
5395 return ESR_Continue;
5398 case ESR_CaseNotFound:
5401 llvm_unreachable(
"Invalid EvalStmtResult!");
5407 BlockScopeRAII
Scope(Info);
5414 if (ESR != ESR_Succeeded) {
5415 if (ESR != ESR_Failed && !
Scope.destroy())
5421 FullExpressionRAII CondScope(Info);
5436 if (!CondScope.destroy())
5445 if (isa<DefaultStmt>(SC)) {
5450 const CaseStmt *CS = cast<CaseStmt>(SC);
5461 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5465 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5470 return ESR_Succeeded;
5476 case ESR_CaseNotFound:
5479 Info.FFDiag(
Found->getBeginLoc(),
5480 diag::note_constexpr_stmt_expr_unsupported);
5483 llvm_unreachable(
"Invalid EvalStmtResult!");
5493 Info.CCEDiag(VD->
getLocation(), diag::note_constexpr_static_local)
5503 if (!Info.nextStep(S))
5509 switch (S->getStmtClass()) {
5510 case Stmt::CompoundStmtClass:
5514 case Stmt::LabelStmtClass:
5515 case Stmt::AttributedStmtClass:
5516 case Stmt::DoStmtClass:
5519 case Stmt::CaseStmtClass:
5520 case Stmt::DefaultStmtClass:
5525 case Stmt::IfStmtClass: {
5528 const IfStmt *IS = cast<IfStmt>(S);
5532 BlockScopeRAII
Scope(Info);
5538 if (ESR != ESR_CaseNotFound) {
5539 assert(ESR != ESR_Succeeded);
5550 if (ESR == ESR_Failed)
5552 if (ESR != ESR_CaseNotFound)
5553 return Scope.destroy() ? ESR : ESR_Failed;
5555 return ESR_CaseNotFound;
5558 if (ESR == ESR_Failed)
5560 if (ESR != ESR_CaseNotFound)
5561 return Scope.destroy() ? ESR : ESR_Failed;
5562 return ESR_CaseNotFound;
5565 case Stmt::WhileStmtClass: {
5566 EvalStmtResult ESR =
5568 if (ESR != ESR_Continue)
5573 case Stmt::ForStmtClass: {
5574 const ForStmt *FS = cast<ForStmt>(S);
5575 BlockScopeRAII
Scope(Info);
5579 if (
const Stmt *
Init = FS->getInit()) {
5581 if (ESR != ESR_CaseNotFound) {
5582 assert(ESR != ESR_Succeeded);
5587 EvalStmtResult ESR =
5589 if (ESR != ESR_Continue)
5591 if (
const auto *Inc = FS->getInc()) {
5592 if (Inc->isValueDependent()) {
5596 FullExpressionRAII IncScope(Info);
5604 case Stmt::DeclStmtClass: {
5607 const DeclStmt *DS = cast<DeclStmt>(S);
5608 for (
const auto *
D : DS->
decls()) {
5609 if (
const auto *VD = dyn_cast<VarDecl>(
D)) {
5612 if (VD->hasLocalStorage() && !VD->getInit())
5620 return ESR_CaseNotFound;
5624 return ESR_CaseNotFound;
5628 switch (S->getStmtClass()) {
5630 if (
const Expr *
E = dyn_cast<Expr>(S)) {
5639 FullExpressionRAII
Scope(Info);
5643 return ESR_Succeeded;
5646 Info.FFDiag(S->getBeginLoc()) << S->getSourceRange();
5649 case Stmt::NullStmtClass:
5650 return ESR_Succeeded;
5652 case Stmt::DeclStmtClass: {
5653 const DeclStmt *DS = cast<DeclStmt>(S);
5654 for (
const auto *
D : DS->
decls()) {
5655 const VarDecl *VD = dyn_cast_or_null<VarDecl>(
D);
5659 FullExpressionRAII
Scope(Info);
5661 !Info.noteFailure())
5663 if (!
Scope.destroy())
5666 return ESR_Succeeded;
5669 case Stmt::ReturnStmtClass: {
5670 const Expr *RetExpr = cast<ReturnStmt>(S)->getRetValue();
5671 FullExpressionRAII
Scope(Info);
5680 :
Evaluate(Result.Value, Info, RetExpr)))
5682 return Scope.destroy() ? ESR_Returned : ESR_Failed;
5685 case Stmt::CompoundStmtClass: {
5686 BlockScopeRAII
Scope(Info);
5689 for (
const auto *BI : CS->
body()) {
5690 EvalStmtResult ESR =
EvaluateStmt(Result, Info, BI, Case);
5691 if (ESR == ESR_Succeeded)
5693 else if (ESR != ESR_CaseNotFound) {
5694 if (ESR != ESR_Failed && !
Scope.destroy())
5700 return ESR_CaseNotFound;
5701 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5704 case Stmt::IfStmtClass: {
5705 const IfStmt *IS = cast<IfStmt>(S);
5708 BlockScopeRAII
Scope(Info);
5711 if (ESR != ESR_Succeeded) {
5712 if (ESR != ESR_Failed && !
Scope.destroy())
5722 if (!Info.InConstantContext)
5729 EvalStmtResult ESR =
EvaluateStmt(Result, Info, SubStmt);
5730 if (ESR != ESR_Succeeded) {
5731 if (ESR != ESR_Failed && !
Scope.destroy())
5736 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5739 case Stmt::WhileStmtClass: {
5740 const WhileStmt *WS = cast<WhileStmt>(S);
5742 BlockScopeRAII
Scope(Info);
5751 if (ESR != ESR_Continue) {
5752 if (ESR != ESR_Failed && !
Scope.destroy())
5756 if (!
Scope.destroy())
5759 return ESR_Succeeded;
5762 case Stmt::DoStmtClass: {
5763 const DoStmt *DS = cast<DoStmt>(S);
5767 if (ESR != ESR_Continue)
5776 FullExpressionRAII CondScope(Info);
5778 !CondScope.destroy())
5781 return ESR_Succeeded;
5784 case Stmt::ForStmtClass: {
5785 const ForStmt *FS = cast<ForStmt>(S);
5786 BlockScopeRAII ForScope(Info);
5787 if (FS->getInit()) {
5788 EvalStmtResult ESR =
EvaluateStmt(Result, Info, FS->getInit());
5789 if (ESR != ESR_Succeeded) {
5790 if (ESR != ESR_Failed && !ForScope.destroy())
5796 BlockScopeRAII IterScope(Info);
5797 bool Continue =
true;
5798 if (FS->getCond() && !
EvaluateCond(Info, FS->getConditionVariable(),
5799 FS->getCond(), Continue))
5803 if (!IterScope.destroy())
5809 if (ESR != ESR_Continue) {
5810 if (ESR != ESR_Failed && (!IterScope.destroy() || !ForScope.destroy()))
5815 if (
const auto *Inc = FS->getInc()) {
5816 if (Inc->isValueDependent()) {
5820 FullExpressionRAII IncScope(Info);
5826 if (!IterScope.destroy())
5829 return ForScope.destroy() ? ESR_Succeeded : ESR_Failed;
5832 case Stmt::CXXForRangeStmtClass: {
5834 BlockScopeRAII
Scope(Info);
5837 if (FS->getInit()) {
5838 EvalStmtResult ESR =
EvaluateStmt(Result, Info, FS->getInit());
5839 if (ESR != ESR_Succeeded) {
5840 if (ESR != ESR_Failed && !
Scope.destroy())
5847 EvalStmtResult ESR =
EvaluateStmt(Result, Info, FS->getRangeStmt());
5848 if (ESR != ESR_Succeeded) {
5849 if (ESR != ESR_Failed && !
Scope.destroy())
5856 if (!FS->getBeginStmt() || !FS->getEndStmt() || !FS->getCond())
5861 if (ESR != ESR_Succeeded) {
5862 if (ESR != ESR_Failed && !
Scope.destroy())
5867 if (ESR != ESR_Succeeded) {
5868 if (ESR != ESR_Failed && !
Scope.destroy())
5876 if (FS->getCond()->isValueDependent()) {
5881 bool Continue =
true;
5882 FullExpressionRAII CondExpr(Info);
5890 BlockScopeRAII InnerScope(Info);
5891 ESR =
EvaluateStmt(Result, Info, FS->getLoopVarStmt());
5892 if (ESR != ESR_Succeeded) {
5893 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
5900 if (ESR != ESR_Continue) {
5901 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
5905 if (FS->getInc()->isValueDependent()) {
5914 if (!InnerScope.destroy())
5918 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5921 case Stmt::SwitchStmtClass:
5924 case Stmt::ContinueStmtClass:
5925 return ESR_Continue;
5927 case Stmt::BreakStmtClass:
5930 case Stmt::LabelStmtClass:
5931 return EvaluateStmt(Result, Info, cast<LabelStmt>(S)->getSubStmt(), Case);
5933 case Stmt::AttributedStmtClass: {
5934 const auto *AS = cast<AttributedStmt>(S);
5935 const auto *SS = AS->getSubStmt();
5936 MSConstexprContextRAII ConstexprContext(
5937 *Info.CurrentCall, hasSpecificAttr<MSConstexprAttr>(AS->getAttrs()) &&
5938 isa<ReturnStmt>(SS));
5940 auto LO = Info.getASTContext().getLangOpts();
5941 if (LO.CXXAssumptions && !LO.MSVCCompat) {
5942 for (
auto *
Attr : AS->getAttrs()) {
5943 auto *AA = dyn_cast<CXXAssumeAttr>(
Attr);
5947 auto *Assumption = AA->getAssumption();
5948 if (Assumption->isValueDependent())
5951 if (Assumption->HasSideEffects(Info.getASTContext()))
5958 Info.CCEDiag(Assumption->getExprLoc(),
5959 diag::note_constexpr_assumption_failed);
5968 case Stmt::CaseStmtClass:
5969 case Stmt::DefaultStmtClass:
5970 return EvaluateStmt(Result, Info, cast<SwitchCase>(S)->getSubStmt(), Case);
5971 case Stmt::CXXTryStmtClass:
5973 return EvaluateStmt(Result, Info, cast<CXXTryStmt>(S)->getTryBlock(), Case);
5983 bool IsValueInitialization) {
5990 if (!CD->
isConstexpr() && !IsValueInitialization) {
5991 if (Info.getLangOpts().CPlusPlus11) {
5994 Info.CCEDiag(
Loc, diag::note_constexpr_invalid_function, 1)
5996 Info.Note(CD->
getLocation(), diag::note_declared_at);
5998 Info.CCEDiag(
Loc, diag::note_invalid_subexpr_in_const_expr);
6012 if (Info.checkingPotentialConstantExpression() && !
Definition &&
6020 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6027 if (!Info.Ctx.getLangOpts().CPlusPlus20 && isa<CXXMethodDecl>(
Declaration) &&
6029 Info.CCEDiag(CallLoc, diag::note_constexpr_virtual_call);
6032 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6038 (
Definition->isConstexpr() || (Info.CurrentCall->CanEvalMSConstexpr &&
6048 StringRef Name = DiagDecl->
getName();
6050 Name ==
"__assert_rtn" || Name ==
"__assert_fail" || Name ==
"_wassert";
6052 Info.FFDiag(CallLoc, diag::note_constexpr_assert_failed);
6057 if (Info.getLangOpts().CPlusPlus11) {
6060 auto *CD = dyn_cast<CXXConstructorDecl>(DiagDecl);
6061 if (CD && CD->isInheritingConstructor()) {
6062 auto *Inherited = CD->getInheritedConstructor().getConstructor();
6063 if (!Inherited->isConstexpr())
6064 DiagDecl = CD = Inherited;
6070 if (CD && CD->isInheritingConstructor())
6071 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_inhctor, 1)
6072 << CD->getInheritedConstructor().getConstructor()->
getParent();
6074 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_function, 1)
6076 Info.Note(DiagDecl->
getLocation(), diag::note_declared_at);
6078 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6084struct CheckDynamicTypeHandler {
6086 typedef bool result_type;
6087 bool failed() {
return false; }
6090 bool found(APFloat &
Value,
QualType SubobjType) {
return true; }
6098 if (
This.Designator.Invalid)
6110 if (
This.Designator.isOnePastTheEnd() ||
6111 This.Designator.isMostDerivedAnUnsizedArray()) {
6112 Info.FFDiag(
E,
This.Designator.isOnePastTheEnd()
6113 ? diag::note_constexpr_access_past_end
6114 : diag::note_constexpr_access_unsized_array)
6117 }
else if (Polymorphic) {
6123 Info.Ctx.getLValueReferenceType(
This.Designator.getType(Info.Ctx));
6124 Info.FFDiag(
E, diag::note_constexpr_polymorphic_unknown_dynamic_type)
6131 CheckDynamicTypeHandler Handler{AK};
6154 unsigned PathLength) {
6155 assert(PathLength >=
Designator.MostDerivedPathLength && PathLength <=
6156 Designator.Entries.size() &&
"invalid path length");
6157 return (PathLength ==
Designator.MostDerivedPathLength)
6158 ?
Designator.MostDerivedType->getAsCXXRecordDecl()
6159 : getAsBaseClass(
Designator.Entries[PathLength - 1]);
6172 return std::nullopt;
6174 if (
This.Designator.Invalid)
6175 return std::nullopt;
6184 This.Designator.MostDerivedType->getAsCXXRecordDecl();
6187 return std::nullopt;
6195 for (
unsigned PathLength =
This.Designator.MostDerivedPathLength;
6196 PathLength <=
Path.size(); ++PathLength) {
6197 switch (Info.isEvaluatingCtorDtor(
This.getLValueBase(),
6198 Path.slice(0, PathLength))) {
6199 case ConstructionPhase::Bases:
6200 case ConstructionPhase::DestroyingBases:
6205 case ConstructionPhase::None:
6206 case ConstructionPhase::AfterBases:
6207 case ConstructionPhase::AfterFields:
6208 case ConstructionPhase::Destroying:
6220 return std::nullopt;
6238 unsigned PathLength = DynType->PathLength;
6239 for (; PathLength <=
This.Designator.Entries.size(); ++PathLength) {
6242 Found->getCorrespondingMethodDeclaredInClass(
Class,
false);
6252 if (Callee->isPureVirtual()) {
6253 Info.FFDiag(
E, diag::note_constexpr_pure_virtual_call, 1) << Callee;
6254 Info.Note(Callee->getLocation(), diag::note_declared_at);
6260 if (!Info.Ctx.hasSameUnqualifiedType(Callee->getReturnType(),
6261 Found->getReturnType())) {
6262 CovariantAdjustmentPath.push_back(Callee->getReturnType());
6263 for (
unsigned CovariantPathLength = PathLength + 1;
6264 CovariantPathLength !=
This.Designator.Entries.size();
6265 ++CovariantPathLength) {
6269 Found->getCorrespondingMethodDeclaredInClass(NextClass,
false);
6270 if (Next && !Info.Ctx.hasSameUnqualifiedType(
6271 Next->getReturnType(), CovariantAdjustmentPath.back()))
6272 CovariantAdjustmentPath.push_back(Next->getReturnType());
6274 if (!Info.Ctx.hasSameUnqualifiedType(
Found->getReturnType(),
6275 CovariantAdjustmentPath.back()))
6276 CovariantAdjustmentPath.push_back(
Found->getReturnType());
6292 assert(Result.isLValue() &&
6293 "unexpected kind of APValue for covariant return");
6294 if (Result.isNullPointer())
6298 LVal.setFrom(Info.Ctx, Result);
6301 for (
unsigned I = 1; I !=
Path.size(); ++I) {
6303 assert(OldClass && NewClass &&
"unexpected kind of covariant return");
6304 if (OldClass != NewClass &&
6307 OldClass = NewClass;
6310 LVal.moveInto(Result);
6319 auto *BaseClass = BaseSpec.getType()->getAsCXXRecordDecl();
6321 return BaseSpec.getAccessSpecifier() ==
AS_public;
6323 llvm_unreachable(
"Base is not a direct base of Derived");
6333 SubobjectDesignator &
D = Ptr.Designator;
6345 std::optional<DynamicType> DynType =
6356 const CXXRecordDecl *
C =
E->getTypeAsWritten()->getPointeeCXXRecordDecl();
6357 assert(
C &&
"dynamic_cast target is not void pointer nor class");
6365 Ptr.setNull(Info.Ctx,
E->
getType());
6372 DynType->Type->isDerivedFrom(
C)))
6374 else if (!Paths || Paths->begin() == Paths->end())
6376 else if (Paths->isAmbiguous(CQT))
6379 assert(Paths->front().Access !=
AS_public &&
"why did the cast fail?");
6382 Info.FFDiag(
E, diag::note_constexpr_dynamic_cast_to_reference_failed)
6383 << DiagKind << Ptr.Designator.getType(Info.Ctx)
6384 << Info.Ctx.getCanonicalTagType(DynType->Type)
6392 for (
int PathLength = Ptr.Designator.Entries.size();
6393 PathLength >= (
int)DynType->PathLength; --PathLength) {
6398 if (PathLength > (
int)DynType->PathLength &&
6401 return RuntimeCheckFailed(
nullptr);
6408 if (DynType->Type->isDerivedFrom(
C, Paths) && !Paths.isAmbiguous(CQT) &&
6421 return RuntimeCheckFailed(&Paths);
6425struct StartLifetimeOfUnionMemberHandler {
6427 const Expr *LHSExpr;
6430 bool Failed =
false;
6433 typedef bool result_type;
6434 bool failed() {
return Failed; }
6450 }
else if (DuringInit) {
6454 Info.FFDiag(LHSExpr,
6455 diag::note_constexpr_union_member_change_during_init);
6464 llvm_unreachable(
"wrong value kind for union object");
6467 llvm_unreachable(
"wrong value kind for union object");
6472const AccessKinds StartLifetimeOfUnionMemberHandler::AccessKind;
6479 const Expr *LHSExpr,
6480 const LValue &LHS) {
6481 if (LHS.InvalidBase || LHS.Designator.Invalid)
6487 unsigned PathLength = LHS.Designator.Entries.size();
6488 for (
const Expr *
E = LHSExpr;
E !=
nullptr;) {
6490 if (
auto *ME = dyn_cast<MemberExpr>(
E)) {
6491 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
6494 if (!FD || FD->getType()->isReferenceType())
6498 if (FD->getParent()->isUnion()) {
6503 FD->getType()->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
6504 if (!RD || RD->hasTrivialDefaultConstructor())
6505 UnionPathLengths.push_back({PathLength - 1, FD});
6511 LHS.Designator.Entries[PathLength]
6512 .getAsBaseOrMember().getPointer()));
6516 }
else if (
auto *ASE = dyn_cast<ArraySubscriptExpr>(
E)) {
6518 auto *
Base = ASE->getBase()->IgnoreImplicit();
6519 if (!
Base->getType()->isArrayType())
6525 }
else if (
auto *ICE = dyn_cast<ImplicitCastExpr>(
E)) {
6527 E = ICE->getSubExpr();
6528 if (ICE->getCastKind() == CK_NoOp)
6530 if (ICE->getCastKind() != CK_DerivedToBase &&
6531 ICE->getCastKind() != CK_UncheckedDerivedToBase)
6535 if (Elt->isVirtual()) {
6544 LHS.Designator.Entries[PathLength]
6545 .getAsBaseOrMember().getPointer()));
6555 if (UnionPathLengths.empty())
6560 CompleteObject Obj =
6564 for (std::pair<unsigned, const FieldDecl *> LengthAndField :
6565 llvm::reverse(UnionPathLengths)) {
6567 SubobjectDesignator
D = LHS.Designator;
6568 D.truncate(Info.Ctx, LHS.Base, LengthAndField.first);
6570 bool DuringInit = Info.isEvaluatingCtorDtor(LHS.Base,
D.Entries) ==
6571 ConstructionPhase::AfterBases;
6572 StartLifetimeOfUnionMemberHandler StartLifetime{
6573 Info, LHSExpr, LengthAndField.second, DuringInit};
6582 CallRef
Call, EvalInfo &Info,
bool NonNull =
false,
6583 APValue **EvaluatedArg =
nullptr) {
6590 APValue &
V = PVD ? Info.CurrentCall->createParam(
Call, PVD, LV)
6591 : Info.CurrentCall->createTemporary(Arg, Arg->
getType(),
6592 ScopeKind::Call, LV);
6598 if (
NonNull &&
V.isLValue() &&
V.isNullPointer()) {
6599 Info.CCEDiag(Arg, diag::note_non_null_attribute_failed);
6612 bool RightToLeft =
false,
6613 LValue *ObjectArg =
nullptr) {
6615 llvm::SmallBitVector ForbiddenNullArgs;
6616 if (Callee->hasAttr<NonNullAttr>()) {
6617 ForbiddenNullArgs.resize(Args.size());
6618 for (
const auto *
Attr : Callee->specific_attrs<NonNullAttr>()) {
6619 if (!
Attr->args_size()) {
6620 ForbiddenNullArgs.set();
6623 for (
auto Idx :
Attr->args()) {
6624 unsigned ASTIdx = Idx.getASTIndex();
6625 if (ASTIdx >= Args.size())
6627 ForbiddenNullArgs[ASTIdx] =
true;
6631 for (
unsigned I = 0; I < Args.size(); I++) {
6632 unsigned Idx = RightToLeft ? Args.size() - I - 1 : I;
6634 Idx < Callee->getNumParams() ? Callee->getParamDecl(Idx) :
nullptr;
6635 bool NonNull = !ForbiddenNullArgs.empty() && ForbiddenNullArgs[Idx];
6640 if (!Info.noteFailure())
6645 ObjectArg->setFrom(Info.Ctx, *That);
6654 bool CopyObjectRepresentation) {
6656 CallStackFrame *Frame = Info.CurrentCall;
6657 APValue *RefValue = Info.getParamSlot(Frame->Arguments, Param);
6665 RefLValue.setFrom(Info.Ctx, *RefValue);
6668 CopyObjectRepresentation);
6674 const LValue *ObjectArg,
const Expr *
E,
6676 const Stmt *Body, EvalInfo &Info,
6677 APValue &Result,
const LValue *ResultSlot) {
6678 if (!Info.CheckCallLimit(CallLoc))
6707 ObjectArg->moveInto(Result);
6716 if (!Info.checkingPotentialConstantExpression())
6718 Frame.LambdaThisCaptureField);
6723 if (ESR == ESR_Succeeded) {
6724 if (Callee->getReturnType()->isVoidType())
6726 Info.FFDiag(Callee->getEndLoc(), diag::note_constexpr_no_return);
6728 return ESR == ESR_Returned;
6735 EvalInfo &Info,
APValue &Result) {
6737 if (!Info.CheckCallLimit(CallLoc))
6742 Info.FFDiag(CallLoc, diag::note_constexpr_virtual_base) << RD;
6746 EvalInfo::EvaluatingConstructorRAII EvalObj(
6748 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries},
6760 if ((*I)->getInit()->isValueDependent()) {
6764 FullExpressionRAII InitScope(Info);
6766 !InitScope.destroy())
6789 if (!Result.hasValue()) {
6802 BlockScopeRAII LifetimeExtendedScope(Info);
6805 unsigned BasesSeen = 0;
6815 assert(
Indirect &&
"fields out of order?");
6821 assert(FieldIt != RD->
field_end() &&
"missing field?");
6822 if (!FieldIt->isUnnamedBitField())
6825 Result.getStructField(FieldIt->getFieldIndex()));
6830 LValue Subobject =
This;
6831 LValue SubobjectParent =
This;
6836 if (I->isBaseInitializer()) {
6837 QualType BaseType(I->getBaseClass(), 0);
6841 assert(!BaseIt->
isVirtual() &&
"virtual base for literal type");
6842 assert(Info.Ctx.hasSameUnqualifiedType(BaseIt->
getType(), BaseType) &&
6843 "base class initializers not in expected order");
6849 Value = &Result.getStructBase(BasesSeen++);
6850 }
else if ((FD = I->getMember())) {
6855 Value = &Result.getUnionValue();
6857 SkipToField(FD,
false);
6863 auto IndirectFieldChain = IFD->chain();
6864 for (
auto *
C : IndirectFieldChain) {
6865 FD = cast<FieldDecl>(
C);
6873 (
Value->isUnion() &&
6886 if (
C == IndirectFieldChain.back())
6887 SubobjectParent = Subobject;
6893 if (
C == IndirectFieldChain.front() && !RD->
isUnion())
6894 SkipToField(FD,
true);
6899 llvm_unreachable(
"unknown base initializer kind");
6906 if (
Init->isValueDependent()) {
6910 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &SubobjectParent,
6911 isa<CXXDefaultInitExpr>(
Init));
6912 FullExpressionRAII InitScope(Info);
6918 if (!Info.noteFailure())
6927 if (!Info.noteFailure())
6935 if (I->isBaseInitializer() && BasesSeen == RD->
getNumBases())
6936 EvalObj.finishedConstructingBases();
6941 for (; FieldIt != RD->
field_end(); ++FieldIt) {
6942 if (!FieldIt->isUnnamedBitField())
6945 Result.getStructField(FieldIt->getFieldIndex()));
6949 EvalObj.finishedConstructingFields();
6953 LifetimeExtendedScope.destroy();
6959 EvalInfo &Info,
APValue &Result) {
6960 CallScopeRAII CallScope(Info);
6966 CallScope.destroy();
6978 This.moveInto(Printable);
6980 diag::note_constexpr_destroy_out_of_lifetime)
6981 << Printable.
getAsString(Info.Ctx, Info.Ctx.getLValueReferenceType(
T));
6997 LValue ElemLV =
This;
6998 ElemLV.addArray(Info, &LocE, CAT);
7005 if (Size && Size >
Value.getArrayInitializedElts())
7010 for (Size =
Value.getArraySize(); Size != 0; --Size) {
7011 APValue &Elem =
Value.getArrayInitializedElt(Size - 1);
7024 if (
T.isDestructedType()) {
7026 diag::note_constexpr_unsupported_destruction)
7036 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_virtual_base) << RD;
7061 if (!Info.CheckCallLimit(CallRange.
getBegin()))
7070 CallStackFrame Frame(Info, CallRange,
Definition, &
This,
nullptr,
7075 EvalInfo::EvaluatingDestructorRAII EvalObj(
7077 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries});
7078 if (!EvalObj.DidInsert) {
7085 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_double_destroy);
7105 for (
const FieldDecl *FD : llvm::reverse(Fields)) {
7106 if (FD->isUnnamedBitField())
7109 LValue Subobject =
This;
7113 APValue *SubobjectValue = &
Value.getStructField(FD->getFieldIndex());
7120 EvalObj.startedDestroyingBases();
7127 LValue Subobject =
This;
7132 APValue *SubobjectValue = &
Value.getStructBase(BasesLeft);
7137 assert(BasesLeft == 0 &&
"NumBases was wrong?");
7145struct DestroyObjectHandler {
7151 typedef bool result_type;
7152 bool failed() {
return false; }
7158 Info.FFDiag(
E, diag::note_constexpr_destroy_complex_elem);
7162 Info.FFDiag(
E, diag::note_constexpr_destroy_complex_elem);
7183 if (Info.EvalStatus.HasSideEffects)
7194 if (Info.checkingPotentialConstantExpression() ||
7195 Info.SpeculativeEvaluationDepth)
7199 auto Caller = Info.getStdAllocatorCaller(
"allocate");
7201 Info.FFDiag(
E->
getExprLoc(), Info.getLangOpts().CPlusPlus20
7202 ? diag::note_constexpr_new_untyped
7203 : diag::note_constexpr_new);
7207 QualType ElemType = Caller.ElemType;
7210 diag::note_constexpr_new_not_complete_object_type)
7218 bool IsNothrow =
false;
7219 for (
unsigned I = 1, N =
E->getNumArgs(); I != N; ++I) {
7227 APInt Size, Remainder;
7228 APInt ElemSizeAP(ByteSize.getBitWidth(), ElemSize.
getQuantity());
7229 APInt::udivrem(ByteSize, ElemSizeAP, Size, Remainder);
7230 if (Remainder != 0) {
7232 Info.FFDiag(
E->
getExprLoc(), diag::note_constexpr_operator_new_bad_size)
7233 << ByteSize <<
APSInt(ElemSizeAP,
true) << ElemType;
7237 if (!Info.CheckArraySize(
E->
getBeginLoc(), ByteSize.getActiveBits(),
7238 Size.getZExtValue(), !IsNothrow)) {
7240 Result.setNull(Info.Ctx,
E->
getType());
7246 QualType AllocType = Info.Ctx.getConstantArrayType(
7247 ElemType, Size,
nullptr, ArraySizeModifier::Normal, 0);
7248 APValue *Val = Info.createHeapAlloc(Caller.Call, AllocType, Result);
7250 Result.addArray(Info,
E, cast<ConstantArrayType>(AllocType));
7257 return DD->isVirtual();
7264 return DD->isVirtual() ? DD->getOperatorDelete() :
nullptr;
7275 DynAlloc::Kind DeallocKind) {
7276 auto PointerAsString = [&] {
7277 return Pointer.toString(Info.Ctx, Info.Ctx.VoidPtrTy);
7282 Info.FFDiag(
E, diag::note_constexpr_delete_not_heap_alloc)
7283 << PointerAsString();
7286 return std::nullopt;
7289 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
7291 Info.FFDiag(
E, diag::note_constexpr_double_delete);
7292 return std::nullopt;
7295 if (DeallocKind != (*Alloc)->getKind()) {
7297 Info.FFDiag(
E, diag::note_constexpr_new_delete_mismatch)
7298 << DeallocKind << (*Alloc)->getKind() << AllocType;
7300 return std::nullopt;
7303 bool Subobject =
false;
7304 if (DeallocKind == DynAlloc::New) {
7305 Subobject =
Pointer.Designator.MostDerivedPathLength != 0 ||
7306 Pointer.Designator.isOnePastTheEnd();
7308 Subobject =
Pointer.Designator.Entries.size() != 1 ||
7309 Pointer.Designator.Entries[0].getAsArrayIndex() != 0;
7312 Info.FFDiag(
E, diag::note_constexpr_delete_subobject)
7313 << PointerAsString() <<
Pointer.Designator.isOnePastTheEnd();
7314 return std::nullopt;
7322 if (Info.checkingPotentialConstantExpression() ||
7323 Info.SpeculativeEvaluationDepth)
7327 if (!Info.getStdAllocatorCaller(
"deallocate")) {
7335 for (
unsigned I = 1, N =
E->getNumArgs(); I != N; ++I)
7338 if (
Pointer.Designator.Invalid)
7343 if (
Pointer.isNullPointer()) {
7344 Info.CCEDiag(
E->
getExprLoc(), diag::note_constexpr_deallocate_null);
7360class BitCastBuffer {
7368 static_assert(std::numeric_limits<unsigned char>::digits >= 8,
7369 "Need at least 8 bit unsigned char");
7371 bool TargetIsLittleEndian;
7374 BitCastBuffer(
CharUnits Width,
bool TargetIsLittleEndian)
7375 : Bytes(Width.getQuantity()),
7376 TargetIsLittleEndian(TargetIsLittleEndian) {}
7380 for (
CharUnits I = Offset,
E = Offset + Width; I !=
E; ++I) {
7383 if (!Bytes[I.getQuantity()])
7385 Output.push_back(*Bytes[I.getQuantity()]);
7387 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
7388 std::reverse(Output.begin(), Output.end());
7393 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
7394 std::reverse(Input.begin(), Input.end());
7397 for (
unsigned char Byte : Input) {
7398 assert(!Bytes[Offset.getQuantity() + Index] &&
"overwriting a byte?");
7399 Bytes[Offset.getQuantity() + Index] = Byte;
7404 size_t size() {
return Bytes.size(); }
7409class APValueToBufferConverter {
7411 BitCastBuffer Buffer;
7414 APValueToBufferConverter(EvalInfo &Info,
CharUnits ObjectWidth,
7417 Buffer(ObjectWidth, Info.Ctx.getTargetInfo().isLittleEndian()),
7426 assert((
size_t)Offset.getQuantity() <= Buffer.size());
7439 return visitInt(Val.
getInt(), Ty, Offset);
7441 return visitFloat(Val.
getFloat(), Ty, Offset);
7443 return visitArray(Val, Ty, Offset);
7445 return visitRecord(Val, Ty, Offset);
7447 return visitVector(Val, Ty, Offset);
7451 return visitComplex(Val, Ty, Offset);
7459 diag::note_constexpr_bit_cast_unsupported_type)
7465 llvm_unreachable(
"LValue subobject in bit_cast?");
7467 llvm_unreachable(
"Unhandled APValue::ValueKind");
7475 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
7476 for (
size_t I = 0,
E = CXXRD->getNumBases(); I !=
E; ++I) {
7482 if (!
Base.isStruct())
7492 unsigned FieldIdx = 0;
7494 if (FD->isBitField()) {
7496 diag::note_constexpr_bit_cast_unsupported_bitfield);
7502 assert(FieldOffsetBits % Info.Ctx.getCharWidth() == 0 &&
7503 "only bit-fields can have sub-char alignment");
7505 Info.Ctx.toCharUnitsFromBits(FieldOffsetBits) + Offset;
7525 for (
unsigned I = 0; I != NumInitializedElts; ++I) {
7527 if (!visit(SubObj, CAT->
getElementType(), Offset + I * ElemWidth))
7534 for (
unsigned I = NumInitializedElts; I != ArraySize; ++I) {
7535 if (!visit(Filler, CAT->
getElementType(), Offset + I * ElemWidth))
7546 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
7551 Offset + (0 * EltSizeChars)))
7554 Offset + (1 * EltSizeChars)))
7558 Offset + (0 * EltSizeChars)))
7561 Offset + (1 * EltSizeChars)))
7582 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
7584 llvm::APInt Res = llvm::APInt::getZero(NElts);
7585 for (
unsigned I = 0; I < NElts; ++I) {
7587 assert(EltAsInt.isUnsigned() && EltAsInt.getBitWidth() == 1 &&
7588 "bool vector element must be 1-bit unsigned integer!");
7590 Res.insertBits(EltAsInt, BigEndian ? (NElts - I - 1) : I);
7594 llvm::StoreIntToMemory(Res, &*Bytes.begin(), NElts / 8);
7595 Buffer.writeObject(Offset, Bytes);
7599 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
7600 for (
unsigned I = 0; I < NElts; ++I) {
7601 if (!visit(Val.
getVectorElt(I), EltTy, Offset + I * EltSizeChars))
7610 APSInt AdjustedVal = Val;
7611 unsigned Width = AdjustedVal.getBitWidth();
7613 Width = Info.Ctx.getTypeSize(Ty);
7614 AdjustedVal = AdjustedVal.extend(Width);
7618 llvm::StoreIntToMemory(AdjustedVal, &*Bytes.begin(), Width / 8);
7619 Buffer.writeObject(Offset, Bytes);
7624 APSInt AsInt(Val.bitcastToAPInt());
7625 return visitInt(AsInt, Ty, Offset);
7629 static std::optional<BitCastBuffer>
7632 APValueToBufferConverter Converter(Info, DstSize, BCE);
7634 return std::nullopt;
7635 return Converter.Buffer;
7640class BufferToAPValueConverter {
7642 const BitCastBuffer &Buffer;
7645 BufferToAPValueConverter(EvalInfo &Info,
const BitCastBuffer &Buffer,
7647 : Info(Info), Buffer(Buffer), BCE(BCE) {}
7652 std::nullopt_t unsupportedType(
QualType Ty) {
7654 diag::note_constexpr_bit_cast_unsupported_type)
7656 return std::nullopt;
7659 std::nullopt_t unrepresentableValue(
QualType Ty,
const APSInt &Val) {
7661 diag::note_constexpr_bit_cast_unrepresentable_value)
7663 return std::nullopt;
7667 const EnumType *EnumSugar =
nullptr) {
7681 const llvm::fltSemantics &Semantics =
7682 Info.Ctx.getFloatTypeSemantics(
QualType(
T, 0));
7683 unsigned NumBits = llvm::APFloatBase::getSizeInBits(Semantics);
7684 assert(NumBits % 8 == 0);
7691 if (!Buffer.readObject(Offset,
SizeOf, Bytes)) {
7694 bool IsStdByte = EnumSugar && EnumSugar->isStdByteType();
7698 if (!IsStdByte && !IsUChar) {
7699 QualType DisplayType(EnumSugar ? (
const Type *)EnumSugar :
T, 0);
7701 diag::note_constexpr_bit_cast_indet_dest)
7702 << DisplayType << Info.Ctx.getLangOpts().CharIsSigned;
7703 return std::nullopt;
7709 APSInt Val(
SizeOf.getQuantity() * Info.Ctx.getCharWidth(),
true);
7710 llvm::LoadIntFromMemory(Val, &*Bytes.begin(), Bytes.size());
7715 unsigned IntWidth = Info.Ctx.getIntWidth(
QualType(
T, 0));
7716 if (IntWidth != Val.getBitWidth()) {
7717 APSInt Truncated = Val.trunc(IntWidth);
7718 if (Truncated.extend(Val.getBitWidth()) != Val)
7719 return unrepresentableValue(
QualType(
T, 0), Val);
7727 const llvm::fltSemantics &Semantics =
7728 Info.Ctx.getFloatTypeSemantics(
QualType(
T, 0));
7739 unsigned NumBases = 0;
7740 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
7741 NumBases = CXXRD->getNumBases();
7747 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
7748 for (
size_t I = 0,
E = CXXRD->getNumBases(); I !=
E; ++I) {
7752 std::optional<APValue> SubObj = visitType(
7755 return std::nullopt;
7756 ResultVal.getStructBase(I) = *SubObj;
7761 unsigned FieldIdx = 0;
7765 if (FD->isBitField()) {
7767 diag::note_constexpr_bit_cast_unsupported_bitfield);
7768 return std::nullopt;
7772 assert(FieldOffsetBits % Info.Ctx.getCharWidth() == 0);
7778 std::optional<APValue> SubObj = visitType(FieldTy, FieldOffset);
7780 return std::nullopt;
7781 ResultVal.getStructField(FieldIdx) = *SubObj;
7791 assert(!RepresentationType.
isNull() &&
7792 "enum forward decl should be caught by Sema");
7793 const auto *AsBuiltin =
7797 return visit(AsBuiltin, Offset, Ty);
7805 for (
size_t I = 0; I !=
Size; ++I) {
7806 std::optional<APValue> ElementValue =
7809 return std::nullopt;
7810 ArrayValue.getArrayInitializedElt(I) = std::move(*ElementValue);
7818 CharUnits ElementWidth = Info.Ctx.getTypeSizeInChars(ElementType);
7821 std::optional<APValue> Values[2];
7822 for (
unsigned I = 0; I != 2; ++I) {
7823 Values[I] = visitType(Ty->
getElementType(), Offset + I * ElementWidth);
7825 return std::nullopt;
7829 return APValue(Values[0]->getInt(), Values[1]->getInt());
7830 return APValue(Values[0]->getFloat(), Values[1]->getFloat());
7840 Elts.reserve(NElts);
7850 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
7853 Bytes.reserve(NElts / 8);
7855 return std::nullopt;
7857 APSInt SValInt(NElts,
true);
7858 llvm::LoadIntFromMemory(SValInt, &*Bytes.begin(), Bytes.size());
7860 for (
unsigned I = 0; I < NElts; ++I) {
7862 SValInt.extractBits(1, (BigEndian ? NElts - I - 1 : I) * EltSize);
7869 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
7870 for (
unsigned I = 0; I < NElts; ++I) {
7871 std::optional<APValue> EltValue =
7872 visitType(EltTy, Offset + I * EltSizeChars);
7874 return std::nullopt;
7875 Elts.push_back(std::move(*EltValue));
7879 return APValue(Elts.data(), Elts.size());
7882 std::optional<APValue> visit(
const Type *Ty,
CharUnits Offset) {
7883 return unsupportedType(
QualType(Ty, 0));
7890#define TYPE(Class, Base) \
7892 return visit(cast<Class##Type>(Can.getTypePtr()), Offset);
7893#define ABSTRACT_TYPE(Class, Base)
7894#define NON_CANONICAL_TYPE(Class, Base) \
7896 llvm_unreachable("non-canonical type should be impossible!");
7897#define DEPENDENT_TYPE(Class, Base) \
7900 "dependent types aren't supported in the constant evaluator!");
7901#define NON_CANONICAL_UNLESS_DEPENDENT(Class, Base) \
7903 llvm_unreachable("either dependent or not canonical!");
7904#include "clang/AST/TypeNodes.inc"
7906 llvm_unreachable(
"Unhandled Type::TypeClass");
7911 static std::optional<APValue> convert(EvalInfo &Info, BitCastBuffer &Buffer,
7913 BufferToAPValueConverter Converter(Info, Buffer, BCE);
7921 bool CheckingDest) {
7924 auto diag = [&](
int Reason) {
7926 Info->FFDiag(
Loc, diag::note_constexpr_bit_cast_invalid_type)
7927 << CheckingDest << (Reason == 4) << Reason;
7932 Info->
Note(NoteLoc, diag::note_constexpr_bit_cast_invalid_subtype)
7933 << NoteTy << Construct << Ty;
7947 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(
Record)) {
7949 if (!checkBitCastConstexprEligibilityType(
Loc, BS.
getType(), Info, Ctx,
7954 if (FD->getType()->isReferenceType())
7956 if (!checkBitCastConstexprEligibilityType(
Loc, FD->getType(), Info, Ctx,
7958 return note(0, FD->getType(), FD->getBeginLoc());
7964 Info, Ctx, CheckingDest))
7979 Info->FFDiag(
Loc, diag::note_constexpr_bit_cast_invalid_vector)
7990 Info->FFDiag(
Loc, diag::note_constexpr_bit_cast_unsupported_type)
7999static bool checkBitCastConstexprEligibility(EvalInfo *Info,
8002 bool DestOK = checkBitCastConstexprEligibilityType(
8004 bool SourceOK = DestOK && checkBitCastConstexprEligibilityType(
8010static bool handleRValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
8013 assert(
CHAR_BIT == 8 && Info.Ctx.getTargetInfo().getCharWidth() == 8 &&
8014 "no host or target supports non 8-bit chars");
8016 if (!checkBitCastConstexprEligibility(&Info, Info.Ctx, BCE))
8020 std::optional<BitCastBuffer> Buffer =
8021 APValueToBufferConverter::convert(Info, SourceRValue, BCE);
8026 std::optional<APValue> MaybeDestValue =
8027 BufferToAPValueConverter::convert(Info, *Buffer, BCE);
8028 if (!MaybeDestValue)
8031 DestValue = std::move(*MaybeDestValue);
8035static bool handleLValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
8038 assert(
CHAR_BIT == 8 && Info.Ctx.getTargetInfo().getCharWidth() == 8 &&
8039 "no host or target supports non 8-bit chars");
8041 "LValueToRValueBitcast requires an lvalue operand!");
8043 LValue SourceLValue;
8045 SourceLValue.setFrom(Info.Ctx, SourceValue);
8048 SourceRValue,
true))
8051 return handleRValueToRValueBitCast(Info, DestValue, SourceRValue, BCE);
8054template <
class Derived>
8055class ExprEvaluatorBase
8058 Derived &getDerived() {
return static_cast<Derived&
>(*this); }
8060 return getDerived().Success(
V,
E);
8062 bool DerivedZeroInitialization(
const Expr *
E) {
8063 return getDerived().ZeroInitialization(
E);
8069 template<
typename ConditionalOperator>
8071 assert(Info.checkingPotentialConstantExpression());
8076 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
8077 StmtVisitorTy::Visit(
E->getFalseExpr());
8083 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
8085 StmtVisitorTy::Visit(
E->getTrueExpr());
8090 Error(
E, diag::note_constexpr_conditional_never_const);
8094 template<
typename ConditionalOperator>
8098 if (Info.checkingPotentialConstantExpression() && Info.noteFailure()) {
8099 CheckPotentialConstantConditional(
E);
8102 if (Info.noteFailure()) {
8103 StmtVisitorTy::Visit(
E->getTrueExpr());
8104 StmtVisitorTy::Visit(
E->getFalseExpr());
8109 Expr *EvalExpr = BoolResult ?
E->getTrueExpr() :
E->getFalseExpr();
8110 return StmtVisitorTy::Visit(EvalExpr);
8116 typedef ExprEvaluatorBase ExprEvaluatorBaseTy;
8119 return Info.CCEDiag(
E,
D);
8122 bool ZeroInitialization(
const Expr *
E) {
return Error(
E); }
8124 bool IsConstantEvaluatedBuiltinCall(
const CallExpr *
E) {
8125 unsigned BuiltinOp =
E->getBuiltinCallee();
8126 return BuiltinOp != 0 &&
8127 Info.Ctx.BuiltinInfo.isConstantEvaluated(BuiltinOp);
8131 ExprEvaluatorBase(EvalInfo &Info) : Info(Info) {}
8133 EvalInfo &getEvalInfo() {
return Info; }
8142 return Error(
E, diag::note_invalid_subexpr_in_const_expr);
8145 bool VisitStmt(
const Stmt *) {
8146 llvm_unreachable(
"Expression evaluator should not be called on stmts");
8148 bool VisitExpr(
const Expr *
E) {
8153 const auto It =
E->begin();
8154 return StmtVisitorTy::Visit(*It);
8158 return StmtVisitorTy::Visit(
E->getFunctionName());
8161 if (
E->hasAPValueResult())
8162 return DerivedSuccess(
E->getAPValueResult(),
E);
8164 return StmtVisitorTy::Visit(
E->getSubExpr());
8168 {
return StmtVisitorTy::Visit(
E->getSubExpr()); }
8170 {
return StmtVisitorTy::Visit(
E->getSubExpr()); }
8172 {
return StmtVisitorTy::Visit(
E->getSubExpr()); }
8174 {
return StmtVisitorTy::Visit(
E->getChosenSubExpr()); }
8176 {
return StmtVisitorTy::Visit(
E->getResultExpr()); }
8178 {
return StmtVisitorTy::Visit(
E->getReplacement()); }
8180 TempVersionRAII RAII(*Info.CurrentCall);
8181 SourceLocExprScopeGuard Guard(
E, Info.CurrentCall->CurSourceLocExprScope);
8182 return StmtVisitorTy::Visit(
E->getExpr());
8185 TempVersionRAII RAII(*Info.CurrentCall);
8189 SourceLocExprScopeGuard Guard(
E, Info.CurrentCall->CurSourceLocExprScope);
8190 return StmtVisitorTy::Visit(
E->getExpr());
8194 FullExpressionRAII
Scope(Info);
8195 return StmtVisitorTy::Visit(
E->getSubExpr()) &&
Scope.destroy();
8201 return StmtVisitorTy::Visit(
E->getSubExpr());
8205 CCEDiag(
E, diag::note_constexpr_invalid_cast)
8206 << diag::ConstexprInvalidCastKind::Reinterpret;
8207 return static_cast<Derived*
>(
this)->VisitCastExpr(
E);
8210 if (!Info.Ctx.getLangOpts().CPlusPlus20)
8211 CCEDiag(
E, diag::note_constexpr_invalid_cast)
8212 << diag::ConstexprInvalidCastKind::Dynamic;
8213 return static_cast<Derived*
>(
this)->VisitCastExpr(
E);
8216 return static_cast<Derived*
>(
this)->VisitCastExpr(
E);
8220 switch (
E->getOpcode()) {
8225 VisitIgnoredValue(
E->getLHS());
8226 return StmtVisitorTy::Visit(
E->getRHS());
8236 return DerivedSuccess(Result,
E);
8242 return StmtVisitorTy::Visit(
E->getSemanticForm());
8249 if (!
Evaluate(Info.CurrentCall->createTemporary(
8250 E->getOpaqueValue(),
8251 getStorageType(Info.Ctx,
E->getOpaqueValue()),
8252 ScopeKind::FullExpression, CommonLV),
8253 Info,
E->getCommon()))
8256 return HandleConditionalOperator(
E);
8260 bool IsBcpCall =
false;
8267 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
8274 if (Info.checkingPotentialConstantExpression() && IsBcpCall)
8277 FoldConstant Fold(Info, IsBcpCall);
8278 if (!HandleConditionalOperator(
E)) {
8279 Fold.keepDiagnostics();
8287 if (
APValue *
Value = Info.CurrentCall->getCurrentTemporary(
E);
8289 return DerivedSuccess(*
Value,
E);
8291 const Expr *Source =
E->getSourceExpr();
8295 assert(0 &&
"OpaqueValueExpr recursively refers to itself");
8298 return StmtVisitorTy::Visit(Source);
8302 for (
const Expr *SemE :
E->semantics()) {
8303 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
8307 if (SemE ==
E->getResultExpr())
8312 if (OVE->isUnique())
8316 if (!
Evaluate(Info.CurrentCall->createTemporary(
8317 OVE, getStorageType(Info.Ctx, OVE),
8318 ScopeKind::FullExpression, LV),
8319 Info, OVE->getSourceExpr()))
8321 }
else if (SemE ==
E->getResultExpr()) {
8322 if (!StmtVisitorTy::Visit(SemE))
8334 if (!handleCallExpr(
E, Result,
nullptr))
8336 return DerivedSuccess(Result,
E);
8340 const LValue *ResultSlot) {
8341 CallScopeRAII CallScope(Info);
8347 LValue *
This =
nullptr, ObjectArg;
8348 auto Args =
ArrayRef(
E->getArgs(),
E->getNumArgs());
8349 bool HasQualifier =
false;
8356 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(Callee)) {
8360 Member = dyn_cast<CXXMethodDecl>(ME->getMemberDecl());
8362 return Error(Callee);
8364 HasQualifier = ME->hasQualifier();
8365 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(Callee)) {
8371 Member = dyn_cast<CXXMethodDecl>(
D);
8373 return Error(Callee);
8375 }
else if (
const auto *PDE = dyn_cast<CXXPseudoDestructorExpr>(Callee)) {
8376 if (!Info.getLangOpts().CPlusPlus20)
8377 Info.CCEDiag(PDE, diag::note_constexpr_pseudo_destructor);
8381 return Error(Callee);
8388 if (!CalleeLV.getLValueOffset().isZero())
8389 return Error(Callee);
8390 if (CalleeLV.isNullPointer()) {
8391 Info.FFDiag(Callee, diag::note_constexpr_null_callee)
8395 FD = dyn_cast_or_null<FunctionDecl>(
8396 CalleeLV.getLValueBase().dyn_cast<
const ValueDecl *>());
8398 return Error(Callee);
8401 if (!Info.Ctx.hasSameFunctionTypeIgnoringExceptionSpec(
8408 auto *OCE = dyn_cast<CXXOperatorCallExpr>(
E);
8409 if (OCE && OCE->isAssignmentOp()) {
8410 assert(Args.size() == 2 &&
"wrong number of arguments in assignment");
8411 Call = Info.CurrentCall->createCall(FD);
8412 bool HasThis =
false;
8413 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FD))
8414 HasThis = MD->isImplicitObjectMemberFunction();
8442 if (Info.getLangOpts().CPlusPlus20 && OCE &&
8443 OCE->getOperator() == OO_Equal && MD->
isTrivial() &&
8447 Args = Args.slice(1);
8455 ClosureClass->
captures().empty() &&
8456 "Number of captures must be zero for conversion to function-ptr");
8467 "A generic lambda's static-invoker function must be a "
8468 "template specialization");
8472 void *InsertPos =
nullptr;
8475 assert(CorrespondingCallOpSpecialization &&
8476 "We must always have a function call operator specialization "
8477 "that corresponds to our static invoker specialization");
8478 assert(isa<CXXMethodDecl>(CorrespondingCallOpSpecialization));
8479 FD = CorrespondingCallOpSpecialization;
8487 Ptr.moveInto(Result);
8488 return CallScope.destroy();
8498 Call = Info.CurrentCall->createCall(FD);
8506 auto *NamedMember = dyn_cast<CXXMethodDecl>(FD);
8507 if (NamedMember && NamedMember->isVirtual() && !HasQualifier) {
8510 CovariantAdjustmentPath);
8513 }
else if (NamedMember && NamedMember->isImplicitObjectMemberFunction()) {
8523 if (
auto *DD = dyn_cast<CXXDestructorDecl>(FD)) {
8524 assert(
This &&
"no 'this' pointer for destructor call");
8526 Info.Ctx.getCanonicalTagType(DD->getParent())) &&
8527 CallScope.destroy();
8541 Result, ResultSlot))
8544 if (!CovariantAdjustmentPath.empty() &&
8546 CovariantAdjustmentPath))
8549 return CallScope.destroy();
8553 return StmtVisitorTy::Visit(
E->getInitializer());
8556 if (
E->getNumInits() == 0)
8557 return DerivedZeroInitialization(
E);
8558 if (
E->getNumInits() == 1)
8559 return StmtVisitorTy::Visit(
E->getInit(0));
8563 return DerivedZeroInitialization(
E);
8566 return DerivedZeroInitialization(
E);
8569 return DerivedZeroInitialization(
E);
8574 assert(!Info.Ctx.getLangOpts().CPlusPlus11 &&
8575 "missing temporary materialization conversion");
8576 assert(!
E->isArrow() &&
"missing call to bound member function?");
8584 const FieldDecl *FD = dyn_cast<FieldDecl>(
E->getMemberDecl());
8585 if (!FD)
return Error(
E);
8589 "record / field mismatch");
8600 DerivedSuccess(Result,
E);
8610 E->getEncodedElementAccess(Indices);
8611 if (Indices.size() == 1) {
8617 for (
unsigned I = 0; I < Indices.size(); ++I) {
8620 APValue VecResult(Elts.data(), Indices.size());
8621 return DerivedSuccess(VecResult,
E);
8629 switch (
E->getCastKind()) {
8633 case CK_AtomicToNonAtomic: {
8638 if (!
Evaluate(AtomicVal, Info,
E->getSubExpr()))
8640 return DerivedSuccess(AtomicVal,
E);
8644 case CK_UserDefinedConversion:
8645 return StmtVisitorTy::Visit(
E->getSubExpr());
8647 case CK_LValueToRValue: {
8656 return DerivedSuccess(RVal,
E);
8658 case CK_LValueToRValueBitCast: {
8659 APValue DestValue, SourceValue;
8660 if (!
Evaluate(SourceValue, Info,
E->getSubExpr()))
8662 if (!handleLValueToRValueBitCast(Info, DestValue, SourceValue,
E))
8664 return DerivedSuccess(DestValue,
E);
8667 case CK_AddressSpaceConversion: {
8671 return DerivedSuccess(
Value,
E);
8679 return VisitUnaryPostIncDec(UO);
8682 return VisitUnaryPostIncDec(UO);
8685 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
8695 return DerivedSuccess(RVal, UO);
8708 BlockScopeRAII
Scope(Info);
8713 const Expr *FinalExpr = dyn_cast<Expr>(*BI);
8715 Info.FFDiag((*BI)->getBeginLoc(),
8716 diag::note_constexpr_stmt_expr_unsupported);
8719 return this->Visit(FinalExpr) &&
Scope.destroy();
8725 if (ESR != ESR_Succeeded) {
8729 if (ESR != ESR_Failed)
8730 Info.FFDiag((*BI)->getBeginLoc(),
8731 diag::note_constexpr_stmt_expr_unsupported);
8736 llvm_unreachable(
"Return from function from the loop above.");
8740 return StmtVisitorTy::Visit(
E->getSelectedExpr());
8744 void VisitIgnoredValue(
const Expr *
E) {
8749 void VisitIgnoredBaseExpression(
const Expr *
E) {
8754 VisitIgnoredValue(
E);
8764template<
class Derived>
8765class LValueExprEvaluatorBase
8766 :
public ExprEvaluatorBase<Derived> {
8770 typedef LValueExprEvaluatorBase LValueExprEvaluatorBaseTy;
8771 typedef ExprEvaluatorBase<Derived> ExprEvaluatorBaseTy;
8778 bool evaluatePointer(
const Expr *
E, LValue &Result) {
8783 LValueExprEvaluatorBase(EvalInfo &Info, LValue &Result,
bool InvalidBaseOK)
8784 : ExprEvaluatorBaseTy(Info), Result(Result),
8785 InvalidBaseOK(InvalidBaseOK) {}
8788 Result.setFrom(this->Info.Ctx,
V);
8797 EvalOK = evaluatePointer(
E->getBase(), Result);
8804 EvalOK = this->Visit(
E->getBase());
8810 Result.setInvalid(
E);
8815 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(
E->getMemberDecl())) {
8818 "record / field mismatch");
8839 switch (
E->getOpcode()) {
8841 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
8850 switch (
E->getCastKind()) {
8852 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
8854 case CK_DerivedToBase:
8855 case CK_UncheckedDerivedToBase:
8856 if (!this->Visit(
E->getSubExpr()))
8902class LValueExprEvaluator
8903 :
public LValueExprEvaluatorBase<LValueExprEvaluator> {
8905 LValueExprEvaluator(EvalInfo &Info, LValue &Result,
bool InvalidBaseOK) :
8906 LValueExprEvaluatorBaseTy(Info, Result, InvalidBaseOK) {}
8919 E, 0, Info.getASTContext().getNextStringLiteralVersion()));
8930 return VisitUnaryPreIncDec(UO);
8933 return VisitUnaryPreIncDec(UO);
8939 switch (
E->getCastKind()) {
8941 return LValueExprEvaluatorBaseTy::VisitCastExpr(
E);
8943 case CK_LValueBitCast:
8944 this->CCEDiag(
E, diag::note_constexpr_invalid_cast)
8945 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
8946 << Info.Ctx.getLangOpts().CPlusPlus;
8947 if (!Visit(
E->getSubExpr()))
8949 Result.Designator.setInvalid();
8952 case CK_BaseToDerived:
8953 if (!Visit(
E->getSubExpr()))
8958 if (!Visit(
E->getSubExpr()))
8969 bool LValueToRValueConversion) {
8973 assert(Info.CurrentCall->This ==
nullptr &&
8974 "This should not be set for a static call operator");
8982 if (Self->getType()->isReferenceType()) {
8983 APValue *RefValue = Info.getParamSlot(Info.CurrentCall->Arguments, Self);
8985 Result.setFrom(Info.Ctx, *RefValue);
8987 const ParmVarDecl *VD = Info.CurrentCall->Arguments.getOrigParam(Self);
8988 CallStackFrame *Frame =
8989 Info.getCallFrameAndDepth(Info.CurrentCall->Arguments.CallIndex)
8991 unsigned Version = Info.CurrentCall->Arguments.Version;
8992 Result.set({VD, Frame->Index, Version});
8995 Result = *Info.CurrentCall->This;
9005 if (LValueToRValueConversion) {
9009 Result.setFrom(Info.Ctx, RVal);
9020 bool InvalidBaseOK) {
9024 return LValueExprEvaluator(Info, Result, InvalidBaseOK).Visit(
E);
9027bool LValueExprEvaluator::VisitDeclRefExpr(
const DeclRefExpr *
E) {
9035 E->refersToEnclosingVariableOrCapture()) {
9040 if (Info.checkingPotentialConstantExpression())
9043 if (
auto *FD = Info.CurrentCall->LambdaCaptureFields.lookup(
D)) {
9044 const auto *MD = cast<CXXMethodDecl>(Info.CurrentCall->Callee);
9052 return Success(cast<ValueDecl>(
D));
9053 if (
const VarDecl *VD = dyn_cast<VarDecl>(
D))
9054 return VisitVarDecl(
E, VD);
9056 return Visit(BD->getBinding());
9060bool LValueExprEvaluator::VisitVarDecl(
const Expr *
E,
const VarDecl *VD) {
9061 CallStackFrame *Frame =
nullptr;
9062 unsigned Version = 0;
9070 CallStackFrame *CurrFrame = Info.CurrentCall;
9071 if (CurrFrame->Callee && CurrFrame->Callee->Equals(VD->
getDeclContext())) {
9075 if (
auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
9076 if (CurrFrame->Arguments) {
9077 VD = CurrFrame->Arguments.getOrigParam(PVD);
9079 Info.getCallFrameAndDepth(CurrFrame->Arguments.CallIndex).first;
9080 Version = CurrFrame->Arguments.Version;
9084 Version = CurrFrame->getCurrentTemporaryVersion(VD);
9091 Result.set({VD, Frame->Index, Version});
9097 if (!Info.getLangOpts().CPlusPlus11) {
9098 Info.CCEDiag(
E, diag::note_constexpr_ltor_non_integral, 1)
9100 Info.Note(VD->
getLocation(), diag::note_declared_at);
9109 Result.AllowConstexprUnknown =
true;
9116bool LValueExprEvaluator::VisitCallExpr(
const CallExpr *
E) {
9117 if (!IsConstantEvaluatedBuiltinCall(
E))
9118 return ExprEvaluatorBaseTy::VisitCallExpr(
E);
9120 switch (
E->getBuiltinCallee()) {
9123 case Builtin::BIas_const:
9124 case Builtin::BIforward:
9125 case Builtin::BIforward_like:
9126 case Builtin::BImove:
9127 case Builtin::BImove_if_noexcept:
9128 if (cast<FunctionDecl>(
E->getCalleeDecl())->isConstexpr())
9129 return Visit(
E->getArg(0));
9133 return ExprEvaluatorBaseTy::VisitCallExpr(
E);
9136bool LValueExprEvaluator::VisitMaterializeTemporaryExpr(
9145 for (
const Expr *
E : CommaLHSs)
9154 if (Info.EvalMode == EvalInfo::EM_ConstantFold)
9157 Value =
E->getOrCreateValue(
true);
9161 Value = &Info.CurrentCall->createTemporary(
9162 E, Inner->getType(),
9177 for (
unsigned I = Adjustments.size(); I != 0; ) {
9179 switch (Adjustments[I].Kind) {
9184 Type = Adjustments[I].DerivedToBase.BasePath->getType();
9190 Type = Adjustments[I].Field->getType();
9195 Adjustments[I].Ptr.RHS))
9197 Type = Adjustments[I].Ptr.MPT->getPointeeType();
9207 assert((!Info.getLangOpts().CPlusPlus ||
E->isFileScope()) &&
9208 "lvalue compound literal in c++?");
9212 if (
E->hasStaticStorage()) {
9213 Lit = &
E->getOrCreateStaticValue(Info.Ctx);
9220 assert(!Info.getLangOpts().CPlusPlus);
9221 Lit = &Info.CurrentCall->createTemporary(
E,
E->getInitializer()->
getType(),
9222 ScopeKind::Block, Result);
9234bool LValueExprEvaluator::VisitCXXTypeidExpr(
const CXXTypeidExpr *
E) {
9237 if (!
E->isPotentiallyEvaluated()) {
9238 if (
E->isTypeOperand())
9243 if (!Info.Ctx.getLangOpts().CPlusPlus20) {
9244 Info.CCEDiag(
E, diag::note_constexpr_typeid_polymorphic)
9249 if (!Visit(
E->getExprOperand()))
9252 std::optional<DynamicType> DynType =
9258 Info.Ctx.getCanonicalTagType(DynType->Type).getTypePtr());
9264bool LValueExprEvaluator::VisitCXXUuidofExpr(
const CXXUuidofExpr *
E) {
9268bool LValueExprEvaluator::VisitMemberExpr(
const MemberExpr *
E) {
9270 if (
const VarDecl *VD = dyn_cast<VarDecl>(
E->getMemberDecl())) {
9271 VisitIgnoredBaseExpression(
E->getBase());
9272 return VisitVarDecl(
E, VD);
9276 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(
E->getMemberDecl())) {
9277 if (MD->isStatic()) {
9278 VisitIgnoredBaseExpression(
E->getBase());
9284 return LValueExprEvaluatorBaseTy::VisitMemberExpr(
E);
9287bool LValueExprEvaluator::VisitExtVectorElementExpr(
9292 if (!
Evaluate(Val, Info,
E->getBase())) {
9293 if (!Info.noteFailure())
9299 E->getEncodedElementAccess(Indices);
9301 if (Indices.size() > 1)
9305 Result.setFrom(Info.Ctx, Val);
9311 VT->getNumElements(), Indices[0]);
9326 if (!
Evaluate(Val, Info,
E->getBase())) {
9327 if (!Info.noteFailure())
9333 if (!Info.noteFailure())
9339 Result.setFrom(Info.Ctx, Val);
9341 VT->getNumElements(), Index.getExtValue());
9349 for (
const Expr *SubExpr : {
E->getLHS(),
E->getRHS()}) {
9350 if (SubExpr ==
E->getBase() ? !evaluatePointer(SubExpr, Result)
9352 if (!Info.noteFailure())
9362bool LValueExprEvaluator::VisitUnaryDeref(
const UnaryOperator *
E) {
9363 bool Success = evaluatePointer(
E->getSubExpr(), Result);
9373 Info.noteUndefinedBehavior();
9376bool LValueExprEvaluator::VisitUnaryReal(
const UnaryOperator *
E) {
9377 if (!Visit(
E->getSubExpr()))
9385bool LValueExprEvaluator::VisitUnaryImag(
const UnaryOperator *
E) {
9387 "lvalue __imag__ on scalar?");
9388 if (!Visit(
E->getSubExpr()))
9394bool LValueExprEvaluator::VisitUnaryPreIncDec(
const UnaryOperator *UO) {
9395 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9406bool LValueExprEvaluator::VisitCompoundAssignOperator(
9408 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9416 if (!Info.noteFailure())
9432 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9439 if (!
Evaluate(NewVal, this->Info,
E->getRHS())) {
9440 if (!Info.noteFailure())
9445 if (!this->Visit(
E->getLHS()) || !
Success)
9448 if (Info.getLangOpts().CPlusPlus20 &&
9464 llvm::APInt &Result) {
9465 assert(isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
9466 "Can't get the size of a non alloc_size function");
9467 const auto *
Base = LVal.getLValueBase().get<
const Expr *>();
9469 std::optional<llvm::APInt> Size =
9470 CE->evaluateBytesReturnedByAllocSizeCall(Ctx);
9474 Result = std::move(*Size);
9493 dyn_cast_or_null<VarDecl>(
Base.dyn_cast<
const ValueDecl *>());
9498 if (!
Init ||
Init->getType().isNull())
9502 if (!tryUnwrapAllocSizeCall(
E))
9507 Result.setInvalid(
E);
9510 Result.addUnsizedArray(Info,
E, Pointee);
9515class PointerExprEvaluator
9516 :
public ExprEvaluatorBase<PointerExprEvaluator> {
9525 bool evaluateLValue(
const Expr *
E, LValue &Result) {
9529 bool evaluatePointer(
const Expr *
E, LValue &Result) {
9533 bool visitNonBuiltinCallExpr(
const CallExpr *
E);
9536 PointerExprEvaluator(EvalInfo &info, LValue &Result,
bool InvalidBaseOK)
9537 : ExprEvaluatorBaseTy(info), Result(Result),
9538 InvalidBaseOK(InvalidBaseOK) {}
9541 Result.setFrom(Info.Ctx,
V);
9544 bool ZeroInitialization(
const Expr *
E) {
9545 Result.setNull(Info.Ctx,
E->
getType());
9555 if (
E->isExpressibleAsConstantInitializer())
9557 if (Info.noteFailure())
9564 bool VisitBuiltinCallExpr(
const CallExpr *
E,
unsigned BuiltinOp);
9566 if (!
E->getBlockDecl()->hasCaptures())
9571 auto DiagnoseInvalidUseOfThis = [&] {
9572 if (Info.getLangOpts().CPlusPlus11)
9573 Info.FFDiag(
E, diag::note_constexpr_this) <<
E->isImplicit();
9579 if (Info.checkingPotentialConstantExpression())
9582 bool IsExplicitLambda =
9584 if (!IsExplicitLambda) {
9585 if (!Info.CurrentCall->This) {
9586 DiagnoseInvalidUseOfThis();
9590 Result = *Info.CurrentCall->This;
9598 if (!Info.CurrentCall->LambdaThisCaptureField) {
9599 if (IsExplicitLambda && !Info.CurrentCall->This) {
9600 DiagnoseInvalidUseOfThis();
9607 const auto *MD = cast<CXXMethodDecl>(Info.CurrentCall->Callee);
9609 Info,
E, Result, MD, Info.CurrentCall->LambdaThisCaptureField,
9618 assert(!
E->isIntType() &&
"SourceLocExpr isn't a pointer type?");
9619 APValue LValResult =
E->EvaluateInContext(
9620 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.getDefaultExpr());
9621 Result.setFrom(Info.Ctx, LValResult);
9626 llvm::report_fatal_error(
"Not yet implemented for ExprConstant.cpp");
9631 std::string ResultStr =
E->ComputeName(Info.Ctx);
9634 APInt Size(Info.Ctx.getTypeSize(Info.Ctx.getSizeType()),
9635 ResultStr.size() + 1);
9636 QualType ArrayTy = Info.Ctx.getConstantArrayType(
9637 CharTy, Size,
nullptr, ArraySizeModifier::Normal, 0);
9641 false, ArrayTy,
E->getLocation());
9643 evaluateLValue(SL, Result);
9644 Result.addArray(Info,
E, cast<ConstantArrayType>(ArrayTy));
9653 bool InvalidBaseOK) {
9656 return PointerExprEvaluator(Info, Result, InvalidBaseOK).Visit(
E);
9659bool PointerExprEvaluator::VisitBinaryOperator(
const BinaryOperator *
E) {
9660 if (
E->getOpcode() != BO_Add &&
9661 E->getOpcode() != BO_Sub)
9662 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
9664 const Expr *PExp =
E->getLHS();
9665 const Expr *IExp =
E->getRHS();
9667 std::swap(PExp, IExp);
9669 bool EvalPtrOK = evaluatePointer(PExp, Result);
9670 if (!EvalPtrOK && !Info.noteFailure())
9673 llvm::APSInt Offset;
9677 if (
E->getOpcode() == BO_Sub)
9684bool PointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *
E) {
9685 return evaluateLValue(
E->getSubExpr(), Result);
9693 if (!FnII || !FnII->
isStr(
"current"))
9696 const auto *RD = dyn_cast<RecordDecl>(FD->
getParent());
9704bool PointerExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
9705 const Expr *SubExpr =
E->getSubExpr();
9707 switch (
E->getCastKind()) {
9711 case CK_CPointerToObjCPointerCast:
9712 case CK_BlockPointerToObjCPointerCast:
9713 case CK_AnyPointerToBlockPointerCast:
9714 case CK_AddressSpaceConversion:
9715 if (!Visit(SubExpr))
9721 CCEDiag(
E, diag::note_constexpr_invalid_cast)
9722 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
9723 << Info.Ctx.getLangOpts().CPlusPlus;
9724 Result.Designator.setInvalid();
9732 bool HasValidResult = !Result.InvalidBase && !Result.Designator.Invalid &&
9734 bool VoidPtrCastMaybeOK =
9737 Info.Ctx.hasSimilarType(Result.Designator.getType(Info.Ctx),
9746 if (VoidPtrCastMaybeOK &&
9747 (Info.getStdAllocatorCaller(
"allocate") ||
9749 Info.getLangOpts().CPlusPlus26)) {
9753 Info.getLangOpts().CPlusPlus) {
9755 CCEDiag(
E, diag::note_constexpr_invalid_void_star_cast)
9756 << SubExpr->
getType() << Info.getLangOpts().CPlusPlus26
9757 << Result.Designator.getType(Info.Ctx).getCanonicalType()
9760 CCEDiag(
E, diag::note_constexpr_invalid_cast)
9761 << diag::ConstexprInvalidCastKind::CastFrom
9764 CCEDiag(
E, diag::note_constexpr_invalid_cast)
9765 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
9766 << Info.Ctx.getLangOpts().CPlusPlus;
9767 Result.Designator.setInvalid();
9770 if (
E->getCastKind() == CK_AddressSpaceConversion && Result.IsNullPtr)
9771 ZeroInitialization(
E);
9774 case CK_DerivedToBase:
9775 case CK_UncheckedDerivedToBase:
9776 if (!evaluatePointer(
E->getSubExpr(), Result))
9778 if (!Result.Base && Result.Offset.isZero())
9787 case CK_BaseToDerived:
9788 if (!Visit(
E->getSubExpr()))
9790 if (!Result.Base && Result.Offset.isZero())
9795 if (!Visit(
E->getSubExpr()))
9799 case CK_NullToPointer:
9800 VisitIgnoredValue(
E->getSubExpr());
9801 return ZeroInitialization(
E);
9803 case CK_IntegralToPointer: {
9804 CCEDiag(
E, diag::note_constexpr_invalid_cast)
9805 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
9806 << Info.Ctx.getLangOpts().CPlusPlus;
9812 if (
Value.isInt()) {
9814 uint64_t N =
Value.getInt().extOrTrunc(Size).getZExtValue();
9815 if (N == Info.Ctx.getTargetNullPointerValue(
E->
getType())) {
9816 Result.setNull(Info.Ctx,
E->
getType());
9818 Result.Base = (
Expr *)
nullptr;
9819 Result.InvalidBase =
false;
9821 Result.Designator.setInvalid();
9822 Result.IsNullPtr =
false;
9830 if (!
Value.isLValue())
9834 Result.setFrom(Info.Ctx,
Value);
9839 case CK_ArrayToPointerDecay: {
9841 if (!evaluateLValue(SubExpr, Result))
9845 SubExpr, SubExpr->
getType(), ScopeKind::FullExpression, Result);
9850 auto *AT = Info.Ctx.getAsArrayType(SubExpr->
getType());
9851 if (
auto *CAT = dyn_cast<ConstantArrayType>(AT))
9852 Result.addArray(Info,
E, CAT);
9854 Result.addUnsizedArray(Info,
E, AT->getElementType());
9858 case CK_FunctionToPointerDecay:
9859 return evaluateLValue(SubExpr, Result);
9861 case CK_LValueToRValue: {
9863 if (!evaluateLValue(
E->getSubExpr(), LVal))
9870 return InvalidBaseOK &&
9876 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
9884 T =
T.getNonReferenceType();
9886 if (
T.getQualifiers().hasUnaligned())
9889 const bool AlignOfReturnsPreferred =
9890 Ctx.
getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver7;
9895 if (ExprKind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
9898 else if (ExprKind == UETT_AlignOf)
9901 llvm_unreachable(
"GetAlignOfType on a non-alignment ExprKind");
9918 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(
E))
9927 return Info.Ctx.getDeclAlign(VD);
9928 if (
const auto *
E =
Value.Base.dyn_cast<
const Expr *>())
9936 EvalInfo &Info,
APSInt &Alignment) {
9939 if (Alignment < 0 || !Alignment.isPowerOf2()) {
9940 Info.FFDiag(
E, diag::note_constexpr_invalid_alignment) << Alignment;
9943 unsigned SrcWidth = Info.Ctx.getIntWidth(ForType);
9944 APSInt MaxValue(APInt::getOneBitSet(SrcWidth, SrcWidth - 1));
9945 if (APSInt::compareValues(Alignment, MaxValue) > 0) {
9946 Info.FFDiag(
E, diag::note_constexpr_alignment_too_big)
9947 << MaxValue << ForType << Alignment;
9953 APSInt(Alignment.zextOrTrunc(SrcWidth),
true);
9954 assert(APSInt::compareValues(Alignment, ExtAlignment) == 0 &&
9955 "Alignment should not be changed by ext/trunc");
9956 Alignment = ExtAlignment;
9957 assert(Alignment.getBitWidth() == SrcWidth);
9962bool PointerExprEvaluator::visitNonBuiltinCallExpr(
const CallExpr *
E) {
9963 if (ExprEvaluatorBaseTy::VisitCallExpr(
E))
9966 if (!(InvalidBaseOK &&
E->getCalleeAllocSizeAttr()))
9969 Result.setInvalid(
E);
9971 Result.addUnsizedArray(Info,
E, PointeeTy);
9975bool PointerExprEvaluator::VisitCallExpr(
const CallExpr *
E) {
9976 if (!IsConstantEvaluatedBuiltinCall(
E))
9977 return visitNonBuiltinCallExpr(
E);
9978 return VisitBuiltinCallExpr(
E,
E->getBuiltinCallee());
9987bool PointerExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *
E,
9988 unsigned BuiltinOp) {
9992 switch (BuiltinOp) {
9993 case Builtin::BIaddressof:
9994 case Builtin::BI__addressof:
9995 case Builtin::BI__builtin_addressof:
9996 return evaluateLValue(
E->getArg(0), Result);
9997 case Builtin::BI__builtin_assume_aligned: {
10001 if (!evaluatePointer(
E->getArg(0), Result))
10004 LValue OffsetResult(Result);
10011 if (
E->getNumArgs() > 2) {
10016 int64_t AdditionalOffset = -Offset.getZExtValue();
10021 if (OffsetResult.Base) {
10024 if (BaseAlignment < Align) {
10025 Result.Designator.setInvalid();
10026 CCEDiag(
E->getArg(0), diag::note_constexpr_baa_insufficient_alignment)
10033 if (OffsetResult.Offset.alignTo(Align) != OffsetResult.Offset) {
10034 Result.Designator.setInvalid();
10037 ? CCEDiag(
E->getArg(0),
10038 diag::note_constexpr_baa_insufficient_alignment)
10040 : CCEDiag(
E->getArg(0),
10041 diag::note_constexpr_baa_value_insufficient_alignment))
10042 << OffsetResult.Offset.getQuantity() << Align.
getQuantity();
10048 case Builtin::BI__builtin_align_up:
10049 case Builtin::BI__builtin_align_down: {
10050 if (!evaluatePointer(
E->getArg(0), Result))
10069 assert(Alignment.getBitWidth() <= 64 &&
10070 "Cannot handle > 64-bit address-space");
10071 uint64_t Alignment64 = Alignment.getZExtValue();
10073 BuiltinOp == Builtin::BI__builtin_align_down
10074 ? llvm::alignDown(Result.Offset.getQuantity(), Alignment64)
10075 : llvm::alignTo(Result.Offset.getQuantity(), Alignment64));
10076 Result.adjustOffset(NewOffset - Result.Offset);
10081 Info.FFDiag(
E->getArg(0), diag::note_constexpr_alignment_adjust)
10085 case Builtin::BI__builtin_operator_new:
10087 case Builtin::BI__builtin_launder:
10088 return evaluatePointer(
E->getArg(0), Result);
10089 case Builtin::BIstrchr:
10090 case Builtin::BIwcschr:
10091 case Builtin::BImemchr:
10092 case Builtin::BIwmemchr:
10093 if (Info.getLangOpts().CPlusPlus11)
10094 Info.CCEDiag(
E, diag::note_constexpr_invalid_function)
10096 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
10098 Info.CCEDiag(
E, diag::note_invalid_subexpr_in_const_expr);
10100 case Builtin::BI__builtin_strchr:
10101 case Builtin::BI__builtin_wcschr:
10102 case Builtin::BI__builtin_memchr:
10103 case Builtin::BI__builtin_char_memchr:
10104 case Builtin::BI__builtin_wmemchr: {
10105 if (!Visit(
E->getArg(0)))
10111 if (BuiltinOp != Builtin::BIstrchr &&
10112 BuiltinOp != Builtin::BIwcschr &&
10113 BuiltinOp != Builtin::BI__builtin_strchr &&
10114 BuiltinOp != Builtin::BI__builtin_wcschr) {
10118 MaxLength = N.getZExtValue();
10121 if (MaxLength == 0u)
10122 return ZeroInitialization(
E);
10123 if (!Result.checkNullPointerForFoldAccess(Info,
E,
AK_Read) ||
10124 Result.Designator.Invalid)
10126 QualType CharTy = Result.Designator.getType(Info.Ctx);
10127 bool IsRawByte = BuiltinOp == Builtin::BImemchr ||
10128 BuiltinOp == Builtin::BI__builtin_memchr;
10129 assert(IsRawByte ||
10130 Info.Ctx.hasSameUnqualifiedType(
10134 Info.FFDiag(
E, diag::note_constexpr_ltor_incomplete_type) << CharTy;
10140 Info.FFDiag(
E, diag::note_constexpr_memchr_unsupported)
10141 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp) << CharTy;
10147 bool StopAtNull =
false;
10148 switch (BuiltinOp) {
10149 case Builtin::BIstrchr:
10150 case Builtin::BI__builtin_strchr:
10157 return ZeroInitialization(
E);
10160 case Builtin::BImemchr:
10161 case Builtin::BI__builtin_memchr:
10162 case Builtin::BI__builtin_char_memchr:
10166 DesiredVal = Desired.trunc(Info.Ctx.getCharWidth()).getZExtValue();
10169 case Builtin::BIwcschr:
10170 case Builtin::BI__builtin_wcschr:
10173 case Builtin::BIwmemchr:
10174 case Builtin::BI__builtin_wmemchr:
10176 DesiredVal = Desired.getZExtValue();
10180 for (; MaxLength; --MaxLength) {
10185 if (Char.
getInt().getZExtValue() == DesiredVal)
10187 if (StopAtNull && !Char.
getInt())
10193 return ZeroInitialization(
E);
10196 case Builtin::BImemcpy:
10197 case Builtin::BImemmove:
10198 case Builtin::BIwmemcpy:
10199 case Builtin::BIwmemmove:
10200 if (Info.getLangOpts().CPlusPlus11)
10201 Info.CCEDiag(
E, diag::note_constexpr_invalid_function)
10203 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
10205 Info.CCEDiag(
E, diag::note_invalid_subexpr_in_const_expr);
10207 case Builtin::BI__builtin_memcpy:
10208 case Builtin::BI__builtin_memmove:
10209 case Builtin::BI__builtin_wmemcpy:
10210 case Builtin::BI__builtin_wmemmove: {
10211 bool WChar = BuiltinOp == Builtin::BIwmemcpy ||
10212 BuiltinOp == Builtin::BIwmemmove ||
10213 BuiltinOp == Builtin::BI__builtin_wmemcpy ||
10214 BuiltinOp == Builtin::BI__builtin_wmemmove;
10215 bool Move = BuiltinOp == Builtin::BImemmove ||
10216 BuiltinOp == Builtin::BIwmemmove ||
10217 BuiltinOp == Builtin::BI__builtin_memmove ||
10218 BuiltinOp == Builtin::BI__builtin_wmemmove;
10221 if (!Visit(
E->getArg(0)))
10223 LValue Dest = Result;
10232 assert(!N.isSigned() &&
"memcpy and friends take an unsigned size");
10242 if (!Src.Base || !Dest.Base) {
10244 (!Src.Base ? Src : Dest).moveInto(Val);
10245 Info.FFDiag(
E, diag::note_constexpr_memcpy_null)
10246 <<
Move << WChar << !!Src.Base
10250 if (Src.Designator.Invalid || Dest.Designator.Invalid)
10256 QualType T = Dest.Designator.getType(Info.Ctx);
10257 QualType SrcT = Src.Designator.getType(Info.Ctx);
10258 if (!Info.Ctx.hasSameUnqualifiedType(
T, SrcT)) {
10260 Info.FFDiag(
E, diag::note_constexpr_memcpy_type_pun) <<
Move << SrcT <<
T;
10264 Info.FFDiag(
E, diag::note_constexpr_memcpy_incomplete_type) <<
Move <<
T;
10267 if (!
T.isTriviallyCopyableType(Info.Ctx)) {
10268 Info.FFDiag(
E, diag::note_constexpr_memcpy_nontrivial) <<
Move <<
T;
10273 uint64_t TSize = Info.Ctx.getTypeSizeInChars(
T).getQuantity();
10278 llvm::APInt OrigN = N;
10279 llvm::APInt::udivrem(OrigN, TSize, N, Remainder);
10281 Info.FFDiag(
E, diag::note_constexpr_memcpy_unsupported)
10291 uint64_t RemainingSrcSize = Src.Designator.validIndexAdjustments().second;
10292 uint64_t RemainingDestSize = Dest.Designator.validIndexAdjustments().second;
10293 if (N.ugt(RemainingSrcSize) || N.ugt(RemainingDestSize)) {
10294 Info.FFDiag(
E, diag::note_constexpr_memcpy_unsupported)
10295 <<
Move << WChar << (N.ugt(RemainingSrcSize) ? 1 : 2) <<
T
10299 uint64_t NElems = N.getZExtValue();
10305 uint64_t SrcOffset = Src.getLValueOffset().getQuantity();
10306 uint64_t DestOffset = Dest.getLValueOffset().getQuantity();
10307 if (DestOffset >= SrcOffset && DestOffset - SrcOffset < NBytes) {
10310 Info.FFDiag(
E, diag::note_constexpr_memcpy_overlap) << WChar;
10318 }
else if (!Move && SrcOffset >= DestOffset &&
10319 SrcOffset - DestOffset < NBytes) {
10321 Info.FFDiag(
E, diag::note_constexpr_memcpy_overlap) << WChar;
10356bool PointerExprEvaluator::VisitCXXNewExpr(
const CXXNewExpr *
E) {
10357 if (!Info.getLangOpts().CPlusPlus20)
10358 Info.CCEDiag(
E, diag::note_constexpr_new);
10361 if (Info.SpeculativeEvaluationDepth)
10365 QualType AllocType =
E->getAllocatedType();
10368 bool IsNothrow =
false;
10369 bool IsPlacement =
false;
10371 if (
E->getNumPlacementArgs() == 1 &&
10387 }
else if (OperatorNew->isReservedGlobalPlacementOperator()) {
10388 if (Info.CurrentCall->isStdFunction() || Info.getLangOpts().CPlusPlus26 ||
10389 (Info.CurrentCall->CanEvalMSConstexpr &&
10390 OperatorNew->hasAttr<MSConstexprAttr>())) {
10393 if (Result.Designator.Invalid)
10395 TargetType =
E->getPlacementArg(0)->
getType();
10396 IsPlacement =
true;
10398 Info.FFDiag(
E, diag::note_constexpr_new_placement)
10402 }
else if (
E->getNumPlacementArgs()) {
10403 Info.FFDiag(
E, diag::note_constexpr_new_placement)
10406 }
else if (!OperatorNew
10407 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
10408 Info.FFDiag(
E, diag::note_constexpr_new_non_replaceable)
10409 << isa<CXXMethodDecl>(OperatorNew) << OperatorNew;
10413 const Expr *
Init =
E->getInitializer();
10416 bool ValueInit =
false;
10418 if (std::optional<const Expr *> ArraySize =
E->getArraySize()) {
10419 const Expr *Stripped = *ArraySize;
10420 for (;
auto *ICE = dyn_cast<ImplicitCastExpr>(Stripped);
10421 Stripped = ICE->getSubExpr())
10422 if (ICE->getCastKind() != CK_NoOp &&
10423 ICE->getCastKind() != CK_IntegralCast)
10436 return ZeroInitialization(
E);
10438 Info.FFDiag(*ArraySize, diag::note_constexpr_new_negative)
10439 <<
ArrayBound << (*ArraySize)->getSourceRange();
10445 if (!Info.CheckArraySize(ArraySize.value()->getExprLoc(),
10450 return ZeroInitialization(
E);
10459 }
else if (isa<CXXScalarValueInitExpr>(
Init) ||
10460 isa<ImplicitValueInitExpr>(
Init)) {
10462 }
else if (
auto *CCE = dyn_cast<CXXConstructExpr>(
Init)) {
10463 ResizedArrayCCE = CCE;
10465 auto *CAT = Info.Ctx.getAsConstantArrayType(
Init->getType());
10466 assert(CAT &&
"unexpected type for array initializer");
10470 llvm::APInt InitBound = CAT->
getSize().zext(Bits);
10471 llvm::APInt AllocBound =
ArrayBound.zext(Bits);
10472 if (InitBound.ugt(AllocBound)) {
10474 return ZeroInitialization(
E);
10476 Info.FFDiag(*ArraySize, diag::note_constexpr_new_too_small)
10477 <<
toString(AllocBound, 10,
false)
10479 << (*ArraySize)->getSourceRange();
10485 if (InitBound != AllocBound)
10486 ResizedArrayILE = cast<InitListExpr>(
Init);
10489 AllocType = Info.Ctx.getConstantArrayType(AllocType,
ArrayBound,
nullptr,
10490 ArraySizeModifier::Normal, 0);
10493 "array allocation with non-array new");
10499 struct FindObjectHandler {
10506 typedef bool result_type;
10507 bool failed() {
return false; }
10510 Info.FFDiag(
E, diag::note_constexpr_modify_const_type) << QT;
10516 if (!checkConst(SubobjType))
10520 unsigned SubobjectSize = 1;
10521 unsigned AllocSize = 1;
10522 if (
auto *CAT = dyn_cast<ConstantArrayType>(AllocType))
10524 if (
auto *CAT = dyn_cast<ConstantArrayType>(SubobjType))
10526 if (SubobjectSize < AllocSize ||
10527 !Info.Ctx.hasSimilarType(Info.Ctx.getBaseElementType(SubobjType),
10528 Info.Ctx.getBaseElementType(AllocType))) {
10529 Info.FFDiag(
E, diag::note_constexpr_placement_new_wrong_type)
10530 << SubobjType << AllocType;
10537 Info.FFDiag(
E, diag::note_constexpr_construct_complex_elem);
10541 Info.FFDiag(
E, diag::note_constexpr_construct_complex_elem);
10544 } Handler = {Info,
E, AllocType, AK,
nullptr};
10547 if (!Obj || !
findSubobject(Info,
E, Obj, Result.Designator, Handler))
10550 Val = Handler.Value;
10559 Val = Info.createHeapAlloc(
E, AllocType, Result);
10568 }
else if (ResizedArrayILE) {
10572 }
else if (ResizedArrayCCE) {
10586 Result.addArray(Info,
E, cast<ConstantArrayType>(AT));
10595class MemberPointerExprEvaluator
10596 :
public ExprEvaluatorBase<MemberPointerExprEvaluator> {
10600 Result = MemberPtr(
D);
10605 MemberPointerExprEvaluator(EvalInfo &Info, MemberPtr &Result)
10606 : ExprEvaluatorBaseTy(Info), Result(Result) {}
10612 bool ZeroInitialization(
const Expr *
E) {
10625 return MemberPointerExprEvaluator(Info, Result).Visit(
E);
10628bool MemberPointerExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
10629 switch (
E->getCastKind()) {
10631 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
10633 case CK_NullToMemberPointer:
10634 VisitIgnoredValue(
E->getSubExpr());
10635 return ZeroInitialization(
E);
10637 case CK_BaseToDerivedMemberPointer: {
10638 if (!Visit(
E->getSubExpr()))
10640 if (
E->path_empty())
10645 typedef std::reverse_iterator<CastExpr::path_const_iterator> ReverseIter;
10646 for (ReverseIter PathI(
E->path_end() - 1), PathE(
E->path_begin());
10647 PathI != PathE; ++PathI) {
10648 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
10649 const CXXRecordDecl *Derived = (*PathI)->getType()->getAsCXXRecordDecl();
10650 if (!Result.castToDerived(Derived))
10653 if (!Result.castToDerived(
E->
getType()
10660 case CK_DerivedToBaseMemberPointer:
10661 if (!Visit(
E->getSubExpr()))
10664 PathE =
E->path_end(); PathI != PathE; ++PathI) {
10665 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
10667 if (!Result.castToBase(
Base))
10674bool MemberPointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *
E) {
10677 return Success(cast<DeclRefExpr>(
E->getSubExpr())->getDecl());
10685 class RecordExprEvaluator
10686 :
public ExprEvaluatorBase<RecordExprEvaluator> {
10687 const LValue &
This;
10691 RecordExprEvaluator(EvalInfo &info,
const LValue &
This,
APValue &Result)
10692 : ExprEvaluatorBaseTy(info),
This(
This), Result(Result) {}
10698 bool ZeroInitialization(
const Expr *
E) {
10699 return ZeroInitialization(
E,
E->
getType());
10703 bool VisitCallExpr(
const CallExpr *
E) {
10704 return handleCallExpr(
E, Result, &
This);
10709 return VisitCXXConstructExpr(
E,
E->
getType());
10717 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
10732 assert(!RD->
isUnion() &&
"Expected non-union class type");
10741 unsigned Index = 0;
10743 End = CD->
bases_end(); I != End; ++I, ++Index) {
10745 LValue Subobject =
This;
10749 Result.getStructBase(Index)))
10754 for (
const auto *I : RD->
fields()) {
10756 if (I->isUnnamedBitField() || I->getType()->isReferenceType())
10759 LValue Subobject =
This;
10765 Result.getStructField(I->getFieldIndex()), Info, Subobject, &VIE))
10772bool RecordExprEvaluator::ZeroInitialization(
const Expr *
E,
QualType T) {
10779 while (I != RD->
field_end() && (*I)->isUnnamedBitField())
10786 LValue Subobject =
This;
10791 return EvaluateInPlace(Result.getUnionValue(), Info, Subobject, &VIE);
10794 if (isa<CXXRecordDecl>(RD) && cast<CXXRecordDecl>(RD)->getNumVBases()) {
10795 Info.FFDiag(
E, diag::note_constexpr_virtual_base) << RD;
10802bool RecordExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
10803 switch (
E->getCastKind()) {
10805 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
10807 case CK_ConstructorConversion:
10808 return Visit(
E->getSubExpr());
10810 case CK_DerivedToBase:
10811 case CK_UncheckedDerivedToBase: {
10813 if (!
Evaluate(DerivedObject, Info,
E->getSubExpr()))
10816 return Error(
E->getSubExpr());
10822 PathE =
E->path_end(); PathI != PathE; ++PathI) {
10823 assert(!(*PathI)->isVirtual() &&
"record rvalue with virtual base");
10834bool RecordExprEvaluator::VisitInitListExpr(
const InitListExpr *
E) {
10835 if (
E->isTransparent())
10836 return Visit(
E->getInit(0));
10837 return VisitCXXParenListOrInitListExpr(
E,
E->inits());
10840bool RecordExprEvaluator::VisitCXXParenListOrInitListExpr(
10845 auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
10847 EvalInfo::EvaluatingConstructorRAII EvalObj(
10849 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries},
10850 CXXRD && CXXRD->getNumBases());
10854 if (
auto *ILE = dyn_cast<InitListExpr>(ExprToVisit)) {
10855 Field = ILE->getInitializedFieldInUnion();
10856 }
else if (
auto *PLIE = dyn_cast<CXXParenListInitExpr>(ExprToVisit)) {
10857 Field = PLIE->getInitializedFieldInUnion();
10860 "Expression is neither an init list nor a C++ paren list");
10873 const Expr *InitExpr = Args.empty() ? &VIE : Args[0];
10875 LValue Subobject =
This;
10880 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &
This,
10881 isa<CXXDefaultInitExpr>(InitExpr));
10883 if (
EvaluateInPlace(Result.getUnionValue(), Info, Subobject, InitExpr)) {
10884 if (
Field->isBitField())
10893 if (!Result.hasValue())
10896 unsigned ElementNo = 0;
10900 if (CXXRD && CXXRD->getNumBases()) {
10901 for (
const auto &
Base : CXXRD->bases()) {
10902 assert(ElementNo < Args.size() &&
"missing init for base class");
10903 const Expr *
Init = Args[ElementNo];
10905 LValue Subobject =
This;
10909 APValue &FieldVal = Result.getStructBase(ElementNo);
10911 if (!Info.noteFailure())
10918 EvalObj.finishedConstructingBases();
10922 for (
const auto *Field : RD->
fields()) {
10925 if (
Field->isUnnamedBitField())
10928 LValue Subobject =
This;
10930 bool HaveInit = ElementNo < Args.size();
10935 Subobject, Field, &Layout))
10941 const Expr *
Init = HaveInit ? Args[ElementNo++] : &VIE;
10943 if (
Field->getType()->isIncompleteArrayType()) {
10944 if (
auto *CAT = Info.Ctx.getAsConstantArrayType(
Init->getType())) {
10948 Info.FFDiag(
Init, diag::note_constexpr_unsupported_flexible_array);
10955 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &
This,
10956 isa<CXXDefaultInitExpr>(
Init));
10958 APValue &FieldVal = Result.getStructField(
Field->getFieldIndex());
10959 if (
Field->getType()->isReferenceType()) {
10963 if (!Info.noteFailure())
10968 (
Field->isBitField() &&
10970 if (!Info.noteFailure())
10976 EvalObj.finishedConstructingFields();
10988 bool ZeroInit =
E->requiresZeroInitialization();
10991 return ZeroInitialization(
E,
T);
11003 if (
E->isElidable() && !ZeroInit) {
11009 const Expr *SrcObj =
E->getArg(0);
11011 assert(Info.Ctx.hasSameUnqualifiedType(
E->
getType(), SrcObj->
getType()));
11013 dyn_cast<MaterializeTemporaryExpr>(SrcObj))
11014 return Visit(ME->getSubExpr());
11017 if (ZeroInit && !ZeroInitialization(
E,
T))
11020 auto Args =
ArrayRef(
E->getArgs(),
E->getNumArgs());
11026bool RecordExprEvaluator::VisitCXXInheritedCtorInitExpr(
11028 if (!Info.CurrentCall) {
11029 assert(Info.checkingPotentialConstantExpression());
11048bool RecordExprEvaluator::VisitCXXStdInitializerListExpr(
11051 Info.Ctx.getAsConstantArrayType(
E->getSubExpr()->
getType());
11057 assert(
ArrayType &&
"unexpected type for array initializer");
11064 Array.moveInto(Result.getStructField(0));
11068 assert(Field !=
Record->field_end() &&
11069 Info.Ctx.hasSameType(
Field->getType()->getPointeeType(),
11071 "Expected std::initializer_list first field to be const E *");
11073 assert(Field !=
Record->field_end() &&
11074 "Expected std::initializer_list to have two fields");
11076 if (Info.Ctx.hasSameType(
Field->getType(), Info.Ctx.getSizeType())) {
11081 assert(Info.Ctx.hasSameType(
Field->getType()->getPointeeType(),
11083 "Expected std::initializer_list second field to be const E *");
11088 Array.moveInto(Result.getStructField(1));
11091 assert(++Field ==
Record->field_end() &&
11092 "Expected std::initializer_list to only have two fields");
11097bool RecordExprEvaluator::VisitLambdaExpr(
const LambdaExpr *
E) {
11102 const size_t NumFields =
11105 assert(NumFields == (
size_t)std::distance(
E->capture_init_begin(),
11106 E->capture_init_end()) &&
11107 "The number of lambda capture initializers should equal the number of "
11108 "fields within the closure type");
11113 auto *CaptureInitIt =
E->capture_init_begin();
11115 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(ClosureClass);
11116 for (
const auto *Field : ClosureClass->
fields()) {
11117 assert(CaptureInitIt !=
E->capture_init_end());
11119 Expr *
const CurFieldInit = *CaptureInitIt++;
11126 LValue Subobject =
This;
11131 APValue &FieldVal = Result.getStructField(
Field->getFieldIndex());
11133 if (!Info.keepEvaluatingAfterFailure())
11142 APValue &Result, EvalInfo &Info) {
11145 "can't evaluate expression as a record rvalue");
11146 return RecordExprEvaluator(Info,
This, Result).Visit(
E);
11157class TemporaryExprEvaluator
11158 :
public LValueExprEvaluatorBase<TemporaryExprEvaluator> {
11160 TemporaryExprEvaluator(EvalInfo &Info, LValue &Result) :
11161 LValueExprEvaluatorBaseTy(Info, Result,
false) {}
11164 bool VisitConstructExpr(
const Expr *
E) {
11166 E,
E->
getType(), ScopeKind::FullExpression, Result);
11170 bool VisitCastExpr(
const CastExpr *
E) {
11171 switch (
E->getCastKind()) {
11173 return LValueExprEvaluatorBaseTy::VisitCastExpr(
E);
11175 case CK_ConstructorConversion:
11176 return VisitConstructExpr(
E->getSubExpr());
11180 return VisitConstructExpr(
E);
11183 return VisitConstructExpr(
E);
11185 bool VisitCallExpr(
const CallExpr *
E) {
11186 return VisitConstructExpr(
E);
11189 return VisitConstructExpr(
E);
11192 return VisitConstructExpr(
E);
11201 return TemporaryExprEvaluator(Info, Result).Visit(
E);
11209 class VectorExprEvaluator
11210 :
public ExprEvaluatorBase<VectorExprEvaluator> {
11214 VectorExprEvaluator(EvalInfo &info,
APValue &Result)
11215 : ExprEvaluatorBaseTy(info), Result(Result) {}
11224 assert(
V.isVector());
11228 bool ZeroInitialization(
const Expr *
E);
11231 {
return Visit(
E->getSubExpr()); }
11248 "not a vector prvalue");
11249 return VectorExprEvaluator(Info, Result).Visit(
E);
11253 assert(Val.
isVector() &&
"expected vector APValue");
11257 llvm::APInt Result(NumElts, 0);
11259 for (
unsigned I = 0; I < NumElts; ++I) {
11261 assert(Elt.
isInt() &&
"expected integer element in bool vector");
11263 if (Elt.
getInt().getBoolValue())
11270bool VectorExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
11274 const Expr *SE =
E->getSubExpr();
11277 switch (
E->getCastKind()) {
11278 case CK_VectorSplat: {
11284 Val =
APValue(std::move(IntResult));
11289 Val =
APValue(std::move(FloatResult));
11306 Info.FFDiag(
E, diag::note_constexpr_invalid_cast)
11307 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
11308 << Info.Ctx.getLangOpts().CPlusPlus;
11312 if (!handleRValueToRValueBitCast(Info, Result, SVal,
E))
11317 case CK_HLSLVectorTruncation: {
11322 for (
unsigned I = 0; I < NElts; I++)
11327 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
11332VectorExprEvaluator::VisitInitListExpr(
const InitListExpr *
E) {
11334 unsigned NumInits =
E->getNumInits();
11349 unsigned CountInits = 0, CountElts = 0;
11350 while (CountElts < NumElements) {
11352 if (CountInits < NumInits
11358 for (
unsigned j = 0; j < vlen; j++)
11362 llvm::APSInt sInt(32);
11363 if (CountInits < NumInits) {
11367 sInt = Info.Ctx.MakeIntValue(0, EltTy);
11368 Elements.push_back(
APValue(sInt));
11371 llvm::APFloat f(0.0);
11372 if (CountInits < NumInits) {
11376 f = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy));
11377 Elements.push_back(
APValue(f));
11386VectorExprEvaluator::ZeroInitialization(
const Expr *
E) {
11390 if (EltTy->isIntegerType())
11391 ZeroElement =
APValue(Info.Ctx.MakeIntValue(0, EltTy));
11394 APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy)));
11400bool VectorExprEvaluator::VisitUnaryImag(
const UnaryOperator *
E) {
11401 VisitIgnoredValue(
E->getSubExpr());
11402 return ZeroInitialization(
E);
11405bool VectorExprEvaluator::VisitBinaryOperator(
const BinaryOperator *
E) {
11407 assert(Op != BO_PtrMemD && Op != BO_PtrMemI && Op != BO_Cmp &&
11408 "Operation not supported on vector types");
11410 if (Op == BO_Comma)
11411 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
11413 Expr *LHS =
E->getLHS();
11414 Expr *RHS =
E->getRHS();
11417 "Must both be vector types");
11424 "All operands must be the same size.");
11428 bool LHSOK =
Evaluate(LHSValue, Info, LHS);
11429 if (!LHSOK && !Info.noteFailure())
11431 if (!
Evaluate(RHSValue, Info, RHS) || !LHSOK)
11453 "Vector can only be int or float type");
11461 "Vector operator ~ can only be int");
11462 Elt.
getInt().flipAllBits();
11472 "Vector can only be int or float type");
11478 EltResult.setAllBits();
11480 EltResult.clearAllBits();
11486 return std::nullopt;
11490bool VectorExprEvaluator::VisitUnaryOperator(
const UnaryOperator *
E) {
11491 Expr *SubExpr =
E->getSubExpr();
11496 const QualType ResultEltTy = VD->getElementType();
11500 if (!
Evaluate(SubExprValue, Info, SubExpr))
11513 "Vector length doesn't match type?");
11516 for (
unsigned EltNum = 0; EltNum < VD->getNumElements(); ++EltNum) {
11518 Info.Ctx, ResultEltTy, Op, SubExprValue.
getVectorElt(EltNum));
11521 ResultElements.push_back(*Elt);
11523 return Success(
APValue(ResultElements.data(), ResultElements.size()),
E);
11532 Result =
APValue(APFloat(0.0));
11534 DestTy, Result.getFloat());
11545 Result.getFloat());
11550 DestTy, Result.getInt());
11554 Info.FFDiag(
E, diag::err_convertvector_constexpr_unsupported_vector_cast)
11555 << SourceTy << DestTy;
11559bool VectorExprEvaluator::VisitCallExpr(
const CallExpr *
E) {
11560 if (!IsConstantEvaluatedBuiltinCall(
E))
11561 return ExprEvaluatorBaseTy::VisitCallExpr(
E);
11563 switch (
E->getBuiltinCallee()) {
11566 case Builtin::BI__builtin_elementwise_popcount:
11567 case Builtin::BI__builtin_elementwise_bitreverse: {
11575 ResultElements.reserve(SourceLen);
11577 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11579 switch (
E->getBuiltinCallee()) {
11580 case Builtin::BI__builtin_elementwise_popcount:
11581 ResultElements.push_back(
APValue(
11582 APSInt(
APInt(Info.Ctx.getIntWidth(DestEltTy), Elt.popcount()),
11585 case Builtin::BI__builtin_elementwise_bitreverse:
11586 ResultElements.push_back(
11593 return Success(
APValue(ResultElements.data(), ResultElements.size()),
E);
11595 case Builtin::BI__builtin_elementwise_abs: {
11603 ResultElements.reserve(SourceLen);
11605 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11610 CurrentEle.getInt().
abs(),
11611 DestEltTy->isUnsignedIntegerOrEnumerationType()));
11612 ResultElements.push_back(Val);
11615 return Success(
APValue(ResultElements.data(), ResultElements.size()),
E);
11618 case Builtin::BI__builtin_elementwise_add_sat:
11619 case Builtin::BI__builtin_elementwise_sub_sat:
11620 case clang::X86::BI__builtin_ia32_pmulhuw128:
11621 case clang::X86::BI__builtin_ia32_pmulhuw256:
11622 case clang::X86::BI__builtin_ia32_pmulhuw512:
11623 case clang::X86::BI__builtin_ia32_pmulhw128:
11624 case clang::X86::BI__builtin_ia32_pmulhw256:
11625 case clang::X86::BI__builtin_ia32_pmulhw512:
11626 case clang::X86::BI__builtin_ia32_psllv2di:
11627 case clang::X86::BI__builtin_ia32_psllv4di:
11628 case clang::X86::BI__builtin_ia32_psllv4si:
11629 case clang::X86::BI__builtin_ia32_psllv8si:
11630 case clang::X86::BI__builtin_ia32_psrav4si:
11631 case clang::X86::BI__builtin_ia32_psrav8si:
11632 case clang::X86::BI__builtin_ia32_psrlv2di:
11633 case clang::X86::BI__builtin_ia32_psrlv4di:
11634 case clang::X86::BI__builtin_ia32_psrlv4si:
11635 case clang::X86::BI__builtin_ia32_psrlv8si:
11637 case clang::X86::BI__builtin_ia32_psllwi128:
11638 case clang::X86::BI__builtin_ia32_pslldi128:
11639 case clang::X86::BI__builtin_ia32_psllqi128:
11640 case clang::X86::BI__builtin_ia32_psllwi256:
11641 case clang::X86::BI__builtin_ia32_pslldi256:
11642 case clang::X86::BI__builtin_ia32_psllqi256:
11643 case clang::X86::BI__builtin_ia32_psllwi512:
11644 case clang::X86::BI__builtin_ia32_pslldi512:
11645 case clang::X86::BI__builtin_ia32_psllqi512:
11647 case clang::X86::BI__builtin_ia32_psrlwi128:
11648 case clang::X86::BI__builtin_ia32_psrldi128:
11649 case clang::X86::BI__builtin_ia32_psrlqi128:
11650 case clang::X86::BI__builtin_ia32_psrlwi256:
11651 case clang::X86::BI__builtin_ia32_psrldi256:
11652 case clang::X86::BI__builtin_ia32_psrlqi256:
11653 case clang::X86::BI__builtin_ia32_psrlwi512:
11654 case clang::X86::BI__builtin_ia32_psrldi512:
11655 case clang::X86::BI__builtin_ia32_psrlqi512:
11657 case clang::X86::BI__builtin_ia32_psrawi128:
11658 case clang::X86::BI__builtin_ia32_psradi128:
11659 case clang::X86::BI__builtin_ia32_psraqi128:
11660 case clang::X86::BI__builtin_ia32_psrawi256:
11661 case clang::X86::BI__builtin_ia32_psradi256:
11662 case clang::X86::BI__builtin_ia32_psraqi256:
11663 case clang::X86::BI__builtin_ia32_psrawi512:
11664 case clang::X86::BI__builtin_ia32_psradi512:
11665 case clang::X86::BI__builtin_ia32_psraqi512: {
11667 APValue SourceLHS, SourceRHS;
11676 ResultElements.reserve(SourceLen);
11678 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11681 if (SourceRHS.
isInt()) {
11682 const unsigned LaneBitWidth = LHS.getBitWidth();
11683 const unsigned ShiftAmount = SourceRHS.
getInt().getZExtValue();
11685 switch (
E->getBuiltinCallee()) {
11686 case clang::X86::BI__builtin_ia32_psllwi128:
11687 case clang::X86::BI__builtin_ia32_psllwi256:
11688 case clang::X86::BI__builtin_ia32_psllwi512:
11689 case clang::X86::BI__builtin_ia32_pslldi128:
11690 case clang::X86::BI__builtin_ia32_pslldi256:
11691 case clang::X86::BI__builtin_ia32_pslldi512:
11692 case clang::X86::BI__builtin_ia32_psllqi128:
11693 case clang::X86::BI__builtin_ia32_psllqi256:
11694 case clang::X86::BI__builtin_ia32_psllqi512:
11695 if (ShiftAmount >= LaneBitWidth) {
11696 ResultElements.push_back(
11697 APValue(
APSInt(APInt::getZero(LaneBitWidth), DestUnsigned)));
11699 ResultElements.push_back(
11703 case clang::X86::BI__builtin_ia32_psrlwi128:
11704 case clang::X86::BI__builtin_ia32_psrlwi256:
11705 case clang::X86::BI__builtin_ia32_psrlwi512:
11706 case clang::X86::BI__builtin_ia32_psrldi128:
11707 case clang::X86::BI__builtin_ia32_psrldi256:
11708 case clang::X86::BI__builtin_ia32_psrldi512:
11709 case clang::X86::BI__builtin_ia32_psrlqi128:
11710 case clang::X86::BI__builtin_ia32_psrlqi256:
11711 case clang::X86::BI__builtin_ia32_psrlqi512:
11712 if (ShiftAmount >= LaneBitWidth) {
11713 ResultElements.push_back(
11714 APValue(
APSInt(APInt::getZero(LaneBitWidth), DestUnsigned)));
11716 ResultElements.push_back(
11720 case clang::X86::BI__builtin_ia32_psrawi128:
11721 case clang::X86::BI__builtin_ia32_psrawi256:
11722 case clang::X86::BI__builtin_ia32_psrawi512:
11723 case clang::X86::BI__builtin_ia32_psradi128:
11724 case clang::X86::BI__builtin_ia32_psradi256:
11725 case clang::X86::BI__builtin_ia32_psradi512:
11726 case clang::X86::BI__builtin_ia32_psraqi128:
11727 case clang::X86::BI__builtin_ia32_psraqi256:
11728 case clang::X86::BI__builtin_ia32_psraqi512:
11729 ResultElements.push_back(
11730 APValue(
APSInt(LHS.ashr(std::min(ShiftAmount, LaneBitWidth - 1)),
11734 llvm_unreachable(
"Unexpected builtin callee");
11739 switch (
E->getBuiltinCallee()) {
11740 case Builtin::BI__builtin_elementwise_add_sat:
11741 ResultElements.push_back(
APValue(
11742 APSInt(LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS),
11745 case Builtin::BI__builtin_elementwise_sub_sat:
11746 ResultElements.push_back(
APValue(
11747 APSInt(LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS),
11750 case clang::X86::BI__builtin_ia32_pmulhuw128:
11751 case clang::X86::BI__builtin_ia32_pmulhuw256:
11752 case clang::X86::BI__builtin_ia32_pmulhuw512:
11753 ResultElements.push_back(
APValue(
APSInt(llvm::APIntOps::mulhu(LHS, RHS),
11756 case clang::X86::BI__builtin_ia32_pmulhw128:
11757 case clang::X86::BI__builtin_ia32_pmulhw256:
11758 case clang::X86::BI__builtin_ia32_pmulhw512:
11759 ResultElements.push_back(
APValue(
APSInt(llvm::APIntOps::mulhs(LHS, RHS),
11762 case clang::X86::BI__builtin_ia32_psllv2di:
11763 case clang::X86::BI__builtin_ia32_psllv4di:
11764 case clang::X86::BI__builtin_ia32_psllv4si:
11765 case clang::X86::BI__builtin_ia32_psllv8si:
11766 if (RHS.uge(RHS.getBitWidth())) {
11767 ResultElements.push_back(
11768 APValue(
APSInt(APInt::getZero(RHS.getBitWidth()), DestUnsigned)));
11771 ResultElements.push_back(
11772 APValue(
APSInt(LHS.shl(RHS.getZExtValue()), DestUnsigned)));
11774 case clang::X86::BI__builtin_ia32_psrav4si:
11775 case clang::X86::BI__builtin_ia32_psrav8si:
11776 if (RHS.uge(RHS.getBitWidth())) {
11777 ResultElements.push_back(
11778 APValue(
APSInt(LHS.ashr(RHS.getBitWidth() - 1), DestUnsigned)));
11781 ResultElements.push_back(
11782 APValue(
APSInt(LHS.ashr(RHS.getZExtValue()), DestUnsigned)));
11784 case clang::X86::BI__builtin_ia32_psrlv2di:
11785 case clang::X86::BI__builtin_ia32_psrlv4di:
11786 case clang::X86::BI__builtin_ia32_psrlv4si:
11787 case clang::X86::BI__builtin_ia32_psrlv8si:
11788 if (RHS.uge(RHS.getBitWidth())) {
11789 ResultElements.push_back(
11790 APValue(
APSInt(APInt::getZero(RHS.getBitWidth()), DestUnsigned)));
11793 ResultElements.push_back(
11794 APValue(
APSInt(LHS.lshr(RHS.getZExtValue()), DestUnsigned)));
11799 return Success(
APValue(ResultElements.data(), ResultElements.size()),
E);
11801 case clang::X86::BI__builtin_ia32_pmuldq128:
11802 case clang::X86::BI__builtin_ia32_pmuldq256:
11803 case clang::X86::BI__builtin_ia32_pmuldq512:
11804 case clang::X86::BI__builtin_ia32_pmuludq128:
11805 case clang::X86::BI__builtin_ia32_pmuludq256:
11806 case clang::X86::BI__builtin_ia32_pmuludq512: {
11807 APValue SourceLHS, SourceRHS;
11814 ResultElements.reserve(SourceLen / 2);
11816 for (
unsigned EltNum = 0; EltNum < SourceLen; EltNum += 2) {
11820 switch (
E->getBuiltinCallee()) {
11821 case clang::X86::BI__builtin_ia32_pmuludq128:
11822 case clang::X86::BI__builtin_ia32_pmuludq256:
11823 case clang::X86::BI__builtin_ia32_pmuludq512:
11824 ResultElements.push_back(
11825 APValue(
APSInt(llvm::APIntOps::muluExtended(LHS, RHS),
true)));
11827 case clang::X86::BI__builtin_ia32_pmuldq128:
11828 case clang::X86::BI__builtin_ia32_pmuldq256:
11829 case clang::X86::BI__builtin_ia32_pmuldq512:
11830 ResultElements.push_back(
11831 APValue(
APSInt(llvm::APIntOps::mulsExtended(LHS, RHS),
false)));
11836 return Success(
APValue(ResultElements.data(), ResultElements.size()),
E);
11838 case Builtin::BI__builtin_elementwise_max:
11839 case Builtin::BI__builtin_elementwise_min: {
11840 APValue SourceLHS, SourceRHS;
11852 ResultElements.reserve(SourceLen);
11854 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11857 switch (
E->getBuiltinCallee()) {
11858 case Builtin::BI__builtin_elementwise_max:
11859 ResultElements.push_back(
11863 case Builtin::BI__builtin_elementwise_min:
11864 ResultElements.push_back(
11871 return Success(
APValue(ResultElements.data(), ResultElements.size()),
E);
11873 case X86::BI__builtin_ia32_selectb_128:
11874 case X86::BI__builtin_ia32_selectb_256:
11875 case X86::BI__builtin_ia32_selectb_512:
11876 case X86::BI__builtin_ia32_selectw_128:
11877 case X86::BI__builtin_ia32_selectw_256:
11878 case X86::BI__builtin_ia32_selectw_512:
11879 case X86::BI__builtin_ia32_selectd_128:
11880 case X86::BI__builtin_ia32_selectd_256:
11881 case X86::BI__builtin_ia32_selectd_512:
11882 case X86::BI__builtin_ia32_selectq_128:
11883 case X86::BI__builtin_ia32_selectq_256:
11884 case X86::BI__builtin_ia32_selectq_512:
11885 case X86::BI__builtin_ia32_selectph_128:
11886 case X86::BI__builtin_ia32_selectph_256:
11887 case X86::BI__builtin_ia32_selectph_512:
11888 case X86::BI__builtin_ia32_selectpbf_128:
11889 case X86::BI__builtin_ia32_selectpbf_256:
11890 case X86::BI__builtin_ia32_selectpbf_512:
11891 case X86::BI__builtin_ia32_selectps_128:
11892 case X86::BI__builtin_ia32_selectps_256:
11893 case X86::BI__builtin_ia32_selectps_512:
11894 case X86::BI__builtin_ia32_selectpd_128:
11895 case X86::BI__builtin_ia32_selectpd_256:
11896 case X86::BI__builtin_ia32_selectpd_512: {
11898 APValue SourceMask, SourceLHS, SourceRHS;
11907 ResultElements.reserve(SourceLen);
11909 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11912 ResultElements.push_back(Mask[EltNum] ? LHS : RHS);
11915 return Success(
APValue(ResultElements.data(), ResultElements.size()),
E);
11917 case Builtin::BI__builtin_elementwise_ctlz:
11918 case Builtin::BI__builtin_elementwise_cttz: {
11920 std::optional<APValue> Fallback;
11923 if (
E->getNumArgs() > 1) {
11927 Fallback = FallbackTmp;
11933 ResultElements.reserve(SourceLen);
11935 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11940 Info.FFDiag(
E, diag::note_constexpr_countzeroes_zero)
11941 << (
E->getBuiltinCallee() ==
11942 Builtin::BI__builtin_elementwise_cttz);
11945 ResultElements.push_back(Fallback->getVectorElt(EltNum));
11948 switch (
E->getBuiltinCallee()) {
11949 case Builtin::BI__builtin_elementwise_ctlz:
11950 ResultElements.push_back(
APValue(
11951 APSInt(
APInt(Info.Ctx.getIntWidth(DestEltTy), LHS.countl_zero()),
11954 case Builtin::BI__builtin_elementwise_cttz:
11955 ResultElements.push_back(
APValue(
11956 APSInt(
APInt(Info.Ctx.getIntWidth(DestEltTy), LHS.countr_zero()),
11962 return Success(
APValue(ResultElements.data(), ResultElements.size()),
E);
11965 case Builtin::BI__builtin_elementwise_fma: {
11966 APValue SourceX, SourceY, SourceZ;
11974 ResultElements.reserve(SourceLen);
11976 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11981 (void)Result.fusedMultiplyAdd(Y, Z, RM);
11982 ResultElements.push_back(
APValue(Result));
11984 return Success(
APValue(ResultElements.data(), ResultElements.size()),
E);
12002 ResultElements.reserve(SourceLen);
12003 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12008 ResultElements.push_back(std::move(Elt));
12011 return Success(
APValue(ResultElements.data(), ResultElements.size()),
E);
12016 APValue const &VecVal2,
unsigned EltNum,
12018 unsigned const TotalElementsInInputVector1 = VecVal1.
getVectorLength();
12019 unsigned const TotalElementsInInputVector2 = VecVal2.
getVectorLength();
12021 APSInt IndexVal =
E->getShuffleMaskIdx(EltNum);
12022 int64_t index = IndexVal.getExtValue();
12029 E, diag::err_shufflevector_minus_one_is_undefined_behavior_constexpr)
12035 index >= TotalElementsInInputVector1 + TotalElementsInInputVector2)
12036 llvm_unreachable(
"Out of bounds shuffle index");
12038 if (index >= TotalElementsInInputVector1)
12039 Result = VecVal2.
getVectorElt(index - TotalElementsInInputVector1);
12047 const Expr *Vec1 =
E->getExpr(0);
12051 const Expr *Vec2 =
E->getExpr(1);
12061 ResultElements.reserve(TotalElementsInOutputVector);
12062 for (
unsigned EltNum = 0; EltNum < TotalElementsInOutputVector; ++EltNum) {
12066 ResultElements.push_back(std::move(Elt));
12069 return Success(
APValue(ResultElements.data(), ResultElements.size()),
E);
12077 class ArrayExprEvaluator
12078 :
public ExprEvaluatorBase<ArrayExprEvaluator> {
12079 const LValue &
This;
12083 ArrayExprEvaluator(EvalInfo &Info,
const LValue &
This,
APValue &Result)
12084 : ExprEvaluatorBaseTy(Info),
This(
This), Result(Result) {}
12087 assert(
V.isArray() &&
"expected array");
12092 bool ZeroInitialization(
const Expr *
E) {
12094 Info.Ctx.getAsConstantArrayType(
E->
getType());
12108 if (!Result.hasArrayFiller())
12112 LValue Subobject =
This;
12113 Subobject.addArray(Info,
E, CAT);
12115 return EvaluateInPlace(Result.getArrayFiller(), Info, Subobject, &VIE);
12118 bool VisitCallExpr(
const CallExpr *
E) {
12119 return handleCallExpr(
E, Result, &
This);
12126 const LValue &Subobject,
12134 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
12136 const Expr *ArrayFiller,
12142 APValue &Result, EvalInfo &Info) {
12145 "not an array prvalue");
12146 return ArrayExprEvaluator(Info,
This, Result).Visit(
E);
12154 "not an array prvalue");
12155 return ArrayExprEvaluator(Info,
This, Result)
12156 .VisitInitListExpr(ILE, AllocType);
12165 "not an array prvalue");
12166 return ArrayExprEvaluator(Info,
This, Result)
12167 .VisitCXXConstructExpr(CCE,
This, &Result, AllocType);
12174 if (isa<ImplicitValueInitExpr>(FillerExpr))
12176 if (
const InitListExpr *ILE = dyn_cast<InitListExpr>(FillerExpr)) {
12177 for (
unsigned I = 0,
E = ILE->getNumInits(); I !=
E; ++I) {
12182 if (ILE->hasArrayFiller() &&
12191bool ArrayExprEvaluator::VisitInitListExpr(
const InitListExpr *
E,
12200 if (
E->isStringLiteralInit()) {
12206 return VisitStringLiteral(SL, AllocType);
12210 assert(!
E->isTransparent() &&
12211 "transparent array list initialization is not string literal init?");
12213 return VisitCXXParenListOrInitListExpr(
E,
E->inits(),
E->getArrayFiller(),
12217bool ArrayExprEvaluator::VisitCXXParenListOrInitListExpr(
12225 assert((!Result.isArray() || Result.getArrayInitializedElts() == 0) &&
12226 "zero-initialized array shouldn't have any initialized elts");
12228 if (Result.isArray() && Result.hasArrayFiller())
12229 Filler = Result.getArrayFiller();
12231 unsigned NumEltsToInit = Args.size();
12236 if (NumEltsToInit != NumElts &&
12238 NumEltsToInit = NumElts;
12240 for (
auto *
Init : Args) {
12241 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts()))
12242 NumEltsToInit += EmbedS->getDataElementCount() - 1;
12244 if (NumEltsToInit > NumElts)
12245 NumEltsToInit = NumElts;
12248 LLVM_DEBUG(llvm::dbgs() <<
"The number of elements to initialize: "
12249 << NumEltsToInit <<
".\n");
12256 for (
unsigned I = 0,
E = Result.getArrayInitializedElts(); I !=
E; ++I)
12257 Result.getArrayInitializedElt(I) = Filler;
12258 if (Result.hasArrayFiller())
12259 Result.getArrayFiller() = Filler;
12262 LValue Subobject =
This;
12263 Subobject.addArray(Info, ExprToVisit, CAT);
12264 auto Eval = [&](
const Expr *
Init,
unsigned ArrayIndex) {
12265 if (
Init->isValueDependent())
12268 if (!
EvaluateInPlace(Result.getArrayInitializedElt(ArrayIndex), Info,
12269 Subobject,
Init) ||
12272 if (!Info.noteFailure())
12278 unsigned ArrayIndex = 0;
12281 for (
unsigned Index = 0; Index != NumEltsToInit; ++Index) {
12282 const Expr *
Init = Index < Args.size() ? Args[Index] : ArrayFiller;
12283 if (ArrayIndex >= NumEltsToInit)
12285 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
12287 for (
unsigned I = EmbedS->getStartingElementPos(),
12288 N = EmbedS->getDataElementCount();
12289 I != EmbedS->getStartingElementPos() + N; ++I) {
12292 Result.getArrayInitializedElt(ArrayIndex) =
APValue(
Value);
12296 Init->getFPFeaturesInEffect(Info.Ctx.getLangOpts());
12301 Result.getArrayInitializedElt(ArrayIndex) =
APValue(FValue);
12306 if (!Eval(
Init, ArrayIndex))
12312 if (!Result.hasArrayFiller())
12317 assert(ArrayFiller &&
"no array filler for incomplete init list");
12325 if (
E->getCommonExpr() &&
12326 !
Evaluate(Info.CurrentCall->createTemporary(
12327 E->getCommonExpr(),
12328 getStorageType(Info.Ctx,
E->getCommonExpr()),
12329 ScopeKind::FullExpression, CommonLV),
12330 Info,
E->getCommonExpr()->getSourceExpr()))
12338 LValue Subobject =
This;
12339 Subobject.addArray(Info,
E, CAT);
12342 for (EvalInfo::ArrayInitLoopIndex Index(Info); Index != Elements; ++Index) {
12351 FullExpressionRAII
Scope(Info);
12354 Info, Subobject,
E->getSubExpr()) ||
12357 if (!Info.noteFailure())
12370 return VisitCXXConstructExpr(
E,
This, &Result,
E->
getType());
12374 const LValue &Subobject,
12384 HadZeroInit &&
Value->hasArrayFiller() ?
Value->getArrayFiller()
12388 if (FinalSize == 0)
12393 E->requiresZeroInitialization());
12394 LValue ArrayElt = Subobject;
12395 ArrayElt.addArray(Info,
E, CAT);
12401 for (
const unsigned N : {1u, FinalSize}) {
12402 unsigned OldElts =
Value->getArrayInitializedElts();
12408 for (
unsigned I = 0; I < OldElts; ++I)
12409 NewValue.getArrayInitializedElt(I).swap(
12410 Value->getArrayInitializedElt(I));
12411 Value->swap(NewValue);
12414 for (
unsigned I = OldElts; I < N; ++I)
12415 Value->getArrayInitializedElt(I) = Filler;
12417 if (HasTrivialConstructor && N == FinalSize && FinalSize != 1) {
12420 APValue &FirstResult =
Value->getArrayInitializedElt(0);
12421 for (
unsigned I = OldElts; I < FinalSize; ++I)
12422 Value->getArrayInitializedElt(I) = FirstResult;
12424 for (
unsigned I = OldElts; I < N; ++I) {
12425 if (!VisitCXXConstructExpr(
E, ArrayElt,
12426 &
Value->getArrayInitializedElt(I),
12433 if (Info.EvalStatus.Diag && !Info.EvalStatus.Diag->empty() &&
12434 !Info.keepEvaluatingAfterFailure())
12446 return RecordExprEvaluator(Info, Subobject, *
Value)
12447 .VisitCXXConstructExpr(
E,
Type);
12450bool ArrayExprEvaluator::VisitCXXParenListInitExpr(
12453 "Expression result is not a constant array type");
12455 return VisitCXXParenListOrInitListExpr(
E,
E->getInitExprs(),
12456 E->getArrayFiller());
12468class IntExprEvaluator
12469 :
public ExprEvaluatorBase<IntExprEvaluator> {
12472 IntExprEvaluator(EvalInfo &info,
APValue &result)
12473 : ExprEvaluatorBaseTy(info), Result(result) {}
12477 "Invalid evaluation result.");
12479 "Invalid evaluation result.");
12480 assert(SI.getBitWidth() == Info.Ctx.getIntWidth(
E->
getType()) &&
12481 "Invalid evaluation result.");
12491 "Invalid evaluation result.");
12492 assert(I.getBitWidth() == Info.Ctx.getIntWidth(
E->
getType()) &&
12493 "Invalid evaluation result.");
12495 Result.getInt().setIsUnsigned(
12505 "Invalid evaluation result.");
12520 if (
V.isLValue() ||
V.isAddrLabelDiff() ||
V.isIndeterminate() ||
12521 V.allowConstexprUnknown()) {
12528 bool ZeroInitialization(
const Expr *
E) {
return Success(0,
E); }
12530 friend std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &,
12544 bool CheckReferencedDecl(
const Expr *
E,
const Decl *
D);
12546 if (CheckReferencedDecl(
E,
E->getDecl()))
12549 return ExprEvaluatorBaseTy::VisitDeclRefExpr(
E);
12552 if (CheckReferencedDecl(
E,
E->getMemberDecl())) {
12553 VisitIgnoredBaseExpression(
E->getBase());
12557 return ExprEvaluatorBaseTy::VisitMemberExpr(
E);
12561 bool VisitBuiltinCallExpr(
const CallExpr *
E,
unsigned BuiltinOp);
12578 if (Info.ArrayInitIndex ==
uint64_t(-1)) {
12584 return Success(Info.ArrayInitIndex,
E);
12589 return ZeroInitialization(
E);
12593 if (
E->isStoredAsBoolean())
12595 if (
E->getAPValue().isAbsent())
12597 assert(
E->getAPValue().isInt() &&
"APValue type not supported");
12598 return Success(
E->getAPValue().getInt(),
E);
12627class FixedPointExprEvaluator
12628 :
public ExprEvaluatorBase<FixedPointExprEvaluator> {
12632 FixedPointExprEvaluator(EvalInfo &info,
APValue &result)
12633 : ExprEvaluatorBaseTy(info), Result(result) {}
12637 APFixedPoint(I, Info.Ctx.getFixedPointSemantics(
E->
getType())),
E);
12642 APFixedPoint(
Value, Info.Ctx.getFixedPointSemantics(
E->
getType())),
E);
12651 assert(
V.getWidth() == Info.Ctx.getIntWidth(
E->
getType()) &&
12652 "Invalid evaluation result.");
12657 bool ZeroInitialization(
const Expr *
E) {
12687 return IntExprEvaluator(Info, Result).Visit(
E);
12695 if (!Val.
isInt()) {
12698 Info.FFDiag(
E, diag::note_invalid_subexpr_in_const_expr);
12705bool IntExprEvaluator::VisitSourceLocExpr(
const SourceLocExpr *
E) {
12707 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.getDefaultExpr());
12716 if (!FixedPointExprEvaluator(Info, Val).Visit(
E))
12731 auto FXSema = Info.Ctx.getFixedPointSemantics(
E->
getType());
12735 Result = APFixedPoint(Val, FXSema);
12746bool IntExprEvaluator::CheckReferencedDecl(
const Expr*
E,
const Decl*
D) {
12750 bool SameSign = (ECD->getInitVal().isSigned()
12752 bool SameWidth = (ECD->getInitVal().getBitWidth()
12753 == Info.Ctx.getIntWidth(
E->
getType()));
12754 if (SameSign && SameWidth)
12755 return Success(ECD->getInitVal(),
E);
12759 llvm::APSInt Val = ECD->getInitVal();
12761 Val.setIsSigned(!ECD->getInitVal().isSigned());
12763 Val = Val.extOrTrunc(Info.Ctx.getIntWidth(
E->
getType()));
12779#define TYPE(ID, BASE)
12780#define DEPENDENT_TYPE(ID, BASE) case Type::ID:
12781#define NON_CANONICAL_TYPE(ID, BASE) case Type::ID:
12782#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(ID, BASE) case Type::ID:
12783#include "clang/AST/TypeNodes.inc"
12785 case Type::DeducedTemplateSpecialization:
12786 llvm_unreachable(
"unexpected non-canonical or dependent type");
12788 case Type::Builtin:
12789 switch (cast<BuiltinType>(CanTy)->
getKind()) {
12790#define BUILTIN_TYPE(ID, SINGLETON_ID)
12791#define SIGNED_TYPE(ID, SINGLETON_ID) \
12792 case BuiltinType::ID: return GCCTypeClass::Integer;
12793#define FLOATING_TYPE(ID, SINGLETON_ID) \
12794 case BuiltinType::ID: return GCCTypeClass::RealFloat;
12795#define PLACEHOLDER_TYPE(ID, SINGLETON_ID) \
12796 case BuiltinType::ID: break;
12797#include "clang/AST/BuiltinTypes.def"
12798 case BuiltinType::Void:
12799 return GCCTypeClass::Void;
12801 case BuiltinType::Bool:
12802 return GCCTypeClass::Bool;
12804 case BuiltinType::Char_U:
12805 case BuiltinType::UChar:
12806 case BuiltinType::WChar_U:
12807 case BuiltinType::Char8:
12808 case BuiltinType::Char16:
12809 case BuiltinType::Char32:
12810 case BuiltinType::UShort:
12811 case BuiltinType::UInt:
12812 case BuiltinType::ULong:
12813 case BuiltinType::ULongLong:
12814 case BuiltinType::UInt128:
12815 return GCCTypeClass::Integer;
12817 case BuiltinType::UShortAccum:
12818 case BuiltinType::UAccum:
12819 case BuiltinType::ULongAccum:
12820 case BuiltinType::UShortFract:
12821 case BuiltinType::UFract:
12822 case BuiltinType::ULongFract:
12823 case BuiltinType::SatUShortAccum:
12824 case BuiltinType::SatUAccum:
12825 case BuiltinType::SatULongAccum:
12826 case BuiltinType::SatUShortFract:
12827 case BuiltinType::SatUFract:
12828 case BuiltinType::SatULongFract:
12829 return GCCTypeClass::None;
12831 case BuiltinType::NullPtr:
12833 case BuiltinType::ObjCId:
12834 case BuiltinType::ObjCClass:
12835 case BuiltinType::ObjCSel:
12836#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
12837 case BuiltinType::Id:
12838#include "clang/Basic/OpenCLImageTypes.def"
12839#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
12840 case BuiltinType::Id:
12841#include "clang/Basic/OpenCLExtensionTypes.def"
12842 case BuiltinType::OCLSampler:
12843 case BuiltinType::OCLEvent:
12844 case BuiltinType::OCLClkEvent:
12845 case BuiltinType::OCLQueue:
12846 case BuiltinType::OCLReserveID:
12847#define SVE_TYPE(Name, Id, SingletonId) \
12848 case BuiltinType::Id:
12849#include "clang/Basic/AArch64ACLETypes.def"
12850#define PPC_VECTOR_TYPE(Name, Id, Size) \
12851 case BuiltinType::Id:
12852#include "clang/Basic/PPCTypes.def"
12853#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
12854#include "clang/Basic/RISCVVTypes.def"
12855#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
12856#include "clang/Basic/WebAssemblyReferenceTypes.def"
12857#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
12858#include "clang/Basic/AMDGPUTypes.def"
12859#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
12860#include "clang/Basic/HLSLIntangibleTypes.def"
12861 return GCCTypeClass::None;
12863 case BuiltinType::Dependent:
12864 llvm_unreachable(
"unexpected dependent type");
12866 llvm_unreachable(
"unexpected placeholder type");
12869 return LangOpts.CPlusPlus ? GCCTypeClass::Enum : GCCTypeClass::Integer;
12871 case Type::Pointer:
12872 case Type::ConstantArray:
12873 case Type::VariableArray:
12874 case Type::IncompleteArray:
12875 case Type::FunctionNoProto:
12876 case Type::FunctionProto:
12877 case Type::ArrayParameter:
12878 return GCCTypeClass::Pointer;
12880 case Type::MemberPointer:
12882 ? GCCTypeClass::PointerToDataMember
12883 : GCCTypeClass::PointerToMemberFunction;
12885 case Type::Complex:
12886 return GCCTypeClass::Complex;
12889 return CanTy->
isUnionType() ? GCCTypeClass::Union
12890 : GCCTypeClass::ClassOrStruct;
12898 case Type::ExtVector:
12899 return GCCTypeClass::Vector;
12901 case Type::BlockPointer:
12902 case Type::ConstantMatrix:
12903 case Type::ObjCObject:
12904 case Type::ObjCInterface:
12905 case Type::ObjCObjectPointer:
12907 case Type::HLSLAttributedResource:
12908 case Type::HLSLInlineSpirv:
12911 return GCCTypeClass::None;
12914 return GCCTypeClass::BitInt;
12916 case Type::LValueReference:
12917 case Type::RValueReference:
12918 llvm_unreachable(
"invalid type for expression");
12921 llvm_unreachable(
"unexpected type class");
12930 if (
E->getNumArgs() == 0)
12931 return GCCTypeClass::None;
12946 if (
Base.isNull()) {
12949 }
else if (
const Expr *
E =
Base.dyn_cast<
const Expr *>()) {
12950 if (!isa<StringLiteral>(
E))
12968 SpeculativeEvaluationRAII SpeculativeEval(Info);
12973 FoldConstant Fold(Info,
true);
12996 Fold.keepDiagnostics();
13005 return V.hasValue();
13016 if (
const VarDecl *VD = dyn_cast<VarDecl>(
D))
13019 if (isa<CompoundLiteralExpr>(
E))
13040 const auto *Cast = dyn_cast<CastExpr>(NoParens);
13041 if (Cast ==
nullptr)
13046 auto CastKind = Cast->getCastKind();
13048 CastKind != CK_AddressSpaceConversion)
13051 const auto *SubExpr = Cast->getSubExpr();
13073 assert(!LVal.Designator.Invalid);
13075 auto IsLastOrInvalidFieldDecl = [&Ctx](
const FieldDecl *FD) {
13083 auto &
Base = LVal.getLValueBase();
13084 if (
auto *ME = dyn_cast_or_null<MemberExpr>(
Base.dyn_cast<
const Expr *>())) {
13085 if (
auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
13086 if (!IsLastOrInvalidFieldDecl(FD))
13088 }
else if (
auto *IFD = dyn_cast<IndirectFieldDecl>(ME->getMemberDecl())) {
13089 for (
auto *FD : IFD->chain()) {
13090 if (!IsLastOrInvalidFieldDecl(cast<FieldDecl>(FD)))
13098 if (LVal.Designator.FirstEntryIsAnUnsizedArray) {
13108 for (
unsigned E = LVal.Designator.Entries.size(); I !=
E; ++I) {
13109 const auto &Entry = LVal.Designator.Entries[I];
13115 const auto *CAT = cast<ConstantArrayType>(Ctx.
getAsArrayType(BaseType));
13116 uint64_t Index = Entry.getAsArrayIndex();
13122 uint64_t Index = Entry.getAsArrayIndex();
13125 BaseType = CT->getElementType();
13126 }
else if (
auto *FD = getAsField(Entry)) {
13127 if (!IsLastOrInvalidFieldDecl(FD))
13131 assert(getAsBaseClass(Entry) &&
"Expecting cast to a base class");
13143 if (LVal.Designator.Invalid)
13146 if (!LVal.Designator.Entries.empty())
13147 return LVal.Designator.isMostDerivedAnUnsizedArray();
13149 if (!LVal.InvalidBase)
13154 const auto *
E = LVal.Base.dyn_cast<
const Expr *>();
13155 return !
E || !isa<MemberExpr>(
E);
13161 const SubobjectDesignator &
Designator = LVal.Designator;
13173 auto isFlexibleArrayMember = [&] {
13175 FAMKind StrictFlexArraysLevel =
13178 if (
Designator.isMostDerivedAnUnsizedArray())
13181 if (StrictFlexArraysLevel == FAMKind::Default)
13184 if (
Designator.getMostDerivedArraySize() == 0 &&
13185 StrictFlexArraysLevel != FAMKind::IncompleteOnly)
13188 if (
Designator.getMostDerivedArraySize() == 1 &&
13189 StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete)
13195 return LVal.InvalidBase &&
13197 Designator.MostDerivedIsArrayElement && isFlexibleArrayMember() &&
13205 auto CharUnitsMax = std::numeric_limits<CharUnits::QuantityType>::max();
13206 if (Int.ugt(CharUnitsMax))
13218 if (
const auto *
V = LV.getLValueBase().dyn_cast<
const ValueDecl *>())
13219 if (
const auto *VD = dyn_cast<VarDecl>(
V))
13231 unsigned Type,
const LValue &LVal,
13250 if (!(
Type & 1) || LVal.Designator.Invalid || DetermineForCompleteObject) {
13252 if (
Type == 3 && !DetermineForCompleteObject)
13255 llvm::APInt APEndOffset;
13256 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
13260 if (LVal.InvalidBase)
13264 const bool Ret = CheckedHandleSizeof(BaseTy, EndOffset);
13270 const SubobjectDesignator &
Designator = LVal.Designator;
13282 llvm::APInt APEndOffset;
13283 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
13295 if (!CheckedHandleSizeof(
Designator.MostDerivedType, BytesPerElem))
13301 int64_t ElemsRemaining;
13304 uint64_t ArraySize =
Designator.getMostDerivedArraySize();
13305 uint64_t ArrayIndex =
Designator.Entries.back().getAsArrayIndex();
13306 ElemsRemaining = ArraySize <= ArrayIndex ? 0 : ArraySize - ArrayIndex;
13308 ElemsRemaining =
Designator.isOnePastTheEnd() ? 0 : 1;
13311 EndOffset = LVal.getLValueOffset() + BytesPerElem * ElemsRemaining;
13321 EvalInfo &Info, uint64_t &Size) {
13328 SpeculativeEvaluationRAII SpeculativeEval(Info);
13329 IgnoreSideEffectsRAII Fold(Info);
13337 LVal.setFrom(Info.Ctx, RVal);
13345 if (LVal.getLValueOffset().isNegative()) {
13356 if (EndOffset <= LVal.getLValueOffset())
13359 Size = (EndOffset - LVal.getLValueOffset()).getQuantity();
13363bool IntExprEvaluator::VisitCallExpr(
const CallExpr *
E) {
13364 if (!IsConstantEvaluatedBuiltinCall(
E))
13365 return ExprEvaluatorBaseTy::VisitCallExpr(
E);
13366 return VisitBuiltinCallExpr(
E,
E->getBuiltinCallee());
13382 Info.FFDiag(
E->getArg(0));
13388 assert(SrcInt.getBitWidth() >= Alignment.getBitWidth() &&
13389 "Bit widths must be the same");
13396bool IntExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *
E,
13397 unsigned BuiltinOp) {
13398 switch (BuiltinOp) {
13402 case Builtin::BI__builtin_dynamic_object_size:
13403 case Builtin::BI__builtin_object_size: {
13407 assert(
Type <= 3 &&
"unexpected type");
13418 switch (Info.EvalMode) {
13419 case EvalInfo::EM_ConstantExpression:
13420 case EvalInfo::EM_ConstantFold:
13421 case EvalInfo::EM_IgnoreSideEffects:
13424 case EvalInfo::EM_ConstantExpressionUnevaluated:
13429 llvm_unreachable(
"unexpected EvalMode");
13432 case Builtin::BI__builtin_os_log_format_buffer_size: {
13438 case Builtin::BI__builtin_is_aligned: {
13446 Ptr.setFrom(Info.Ctx, Src);
13452 assert(Alignment.isPowerOf2());
13465 Info.FFDiag(
E->getArg(0), diag::note_constexpr_alignment_compute)
13469 assert(Src.
isInt());
13470 return Success((Src.
getInt() & (Alignment - 1)) == 0 ? 1 : 0,
E);
13472 case Builtin::BI__builtin_align_up: {
13480 APSInt((Src.
getInt() + (Alignment - 1)) & ~(Alignment - 1),
13481 Src.
getInt().isUnsigned());
13482 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
13485 case Builtin::BI__builtin_align_down: {
13494 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
13498 case Builtin::BI__builtin_bitreverse8:
13499 case Builtin::BI__builtin_bitreverse16:
13500 case Builtin::BI__builtin_bitreverse32:
13501 case Builtin::BI__builtin_bitreverse64:
13502 case Builtin::BI__builtin_elementwise_bitreverse: {
13507 return Success(Val.reverseBits(),
E);
13510 case Builtin::BI__builtin_bswap16:
13511 case Builtin::BI__builtin_bswap32:
13512 case Builtin::BI__builtin_bswap64: {
13517 return Success(Val.byteSwap(),
E);
13520 case Builtin::BI__builtin_classify_type:
13523 case Builtin::BI__builtin_clrsb:
13524 case Builtin::BI__builtin_clrsbl:
13525 case Builtin::BI__builtin_clrsbll: {
13530 return Success(Val.getBitWidth() - Val.getSignificantBits(),
E);
13533 case Builtin::BI__builtin_clz:
13534 case Builtin::BI__builtin_clzl:
13535 case Builtin::BI__builtin_clzll:
13536 case Builtin::BI__builtin_clzs:
13537 case Builtin::BI__builtin_clzg:
13538 case Builtin::BI__builtin_elementwise_ctlz:
13539 case Builtin::BI__lzcnt16:
13540 case Builtin::BI__lzcnt:
13541 case Builtin::BI__lzcnt64: {
13552 std::optional<APSInt> Fallback;
13553 if ((BuiltinOp == Builtin::BI__builtin_clzg ||
13554 BuiltinOp == Builtin::BI__builtin_elementwise_ctlz) &&
13555 E->getNumArgs() > 1) {
13559 Fallback = FallbackTemp;
13569 bool ZeroIsUndefined = BuiltinOp != Builtin::BI__lzcnt16 &&
13570 BuiltinOp != Builtin::BI__lzcnt &&
13571 BuiltinOp != Builtin::BI__lzcnt64;
13573 if (BuiltinOp == Builtin::BI__builtin_elementwise_ctlz) {
13574 Info.FFDiag(
E, diag::note_constexpr_countzeroes_zero)
13578 if (ZeroIsUndefined)
13582 return Success(Val.countl_zero(),
E);
13585 case Builtin::BI__builtin_constant_p: {
13586 const Expr *Arg =
E->getArg(0);
13595 Info.FFDiag(
E, diag::note_invalid_subexpr_in_const_expr);
13599 case Builtin::BI__noop:
13603 case Builtin::BI__builtin_is_constant_evaluated: {
13604 const auto *
Callee = Info.CurrentCall->getCallee();
13605 if (Info.InConstantContext && !Info.CheckingPotentialConstantExpression &&
13606 (Info.CallStackDepth == 1 ||
13607 (Info.CallStackDepth == 2 &&
Callee->isInStdNamespace() &&
13608 Callee->getIdentifier() &&
13609 Callee->getIdentifier()->isStr(
"is_constant_evaluated")))) {
13611 if (Info.EvalStatus.Diag)
13612 Info.report((Info.CallStackDepth == 1)
13614 : Info.CurrentCall->getCallRange().getBegin(),
13615 diag::warn_is_constant_evaluated_always_true_constexpr)
13616 << (Info.CallStackDepth == 1 ?
"__builtin_is_constant_evaluated"
13617 :
"std::is_constant_evaluated");
13620 return Success(Info.InConstantContext,
E);
13623 case Builtin::BI__builtin_is_within_lifetime:
13624 if (
auto result = EvaluateBuiltinIsWithinLifetime(*
this,
E))
13628 case Builtin::BI__builtin_ctz:
13629 case Builtin::BI__builtin_ctzl:
13630 case Builtin::BI__builtin_ctzll:
13631 case Builtin::BI__builtin_ctzs:
13632 case Builtin::BI__builtin_ctzg:
13633 case Builtin::BI__builtin_elementwise_cttz: {
13644 std::optional<APSInt> Fallback;
13645 if ((BuiltinOp == Builtin::BI__builtin_ctzg ||
13646 BuiltinOp == Builtin::BI__builtin_elementwise_cttz) &&
13647 E->getNumArgs() > 1) {
13651 Fallback = FallbackTemp;
13658 if (BuiltinOp == Builtin::BI__builtin_elementwise_cttz) {
13659 Info.FFDiag(
E, diag::note_constexpr_countzeroes_zero)
13665 return Success(Val.countr_zero(),
E);
13668 case Builtin::BI__builtin_eh_return_data_regno: {
13670 Operand = Info.Ctx.getTargetInfo().getEHDataRegisterNumber(Operand);
13674 case Builtin::BI__builtin_elementwise_abs: {
13682 case Builtin::BI__builtin_expect:
13683 case Builtin::BI__builtin_expect_with_probability:
13684 return Visit(
E->getArg(0));
13686 case Builtin::BI__builtin_ptrauth_string_discriminator: {
13693 case Builtin::BI__builtin_ffs:
13694 case Builtin::BI__builtin_ffsl:
13695 case Builtin::BI__builtin_ffsll: {
13700 unsigned N = Val.countr_zero();
13701 return Success(N == Val.getBitWidth() ? 0 : N + 1,
E);
13704 case Builtin::BI__builtin_fpclassify: {
13709 switch (Val.getCategory()) {
13710 case APFloat::fcNaN: Arg = 0;
break;
13711 case APFloat::fcInfinity: Arg = 1;
break;
13712 case APFloat::fcNormal: Arg = Val.isDenormal() ? 3 : 2;
break;
13713 case APFloat::fcZero: Arg = 4;
break;
13715 return Visit(
E->getArg(Arg));
13718 case Builtin::BI__builtin_isinf_sign: {
13721 Success(Val.isInfinity() ? (Val.isNegative() ? -1 : 1) : 0,
E);
13724 case Builtin::BI__builtin_isinf: {
13727 Success(Val.isInfinity() ? 1 : 0,
E);
13730 case Builtin::BI__builtin_isfinite: {
13733 Success(Val.isFinite() ? 1 : 0,
E);
13736 case Builtin::BI__builtin_isnan: {
13742 case Builtin::BI__builtin_isnormal: {
13745 Success(Val.isNormal() ? 1 : 0,
E);
13748 case Builtin::BI__builtin_issubnormal: {
13751 Success(Val.isDenormal() ? 1 : 0,
E);
13754 case Builtin::BI__builtin_iszero: {
13760 case Builtin::BI__builtin_signbit:
13761 case Builtin::BI__builtin_signbitf:
13762 case Builtin::BI__builtin_signbitl: {
13765 Success(Val.isNegative() ? 1 : 0,
E);
13768 case Builtin::BI__builtin_isgreater:
13769 case Builtin::BI__builtin_isgreaterequal:
13770 case Builtin::BI__builtin_isless:
13771 case Builtin::BI__builtin_islessequal:
13772 case Builtin::BI__builtin_islessgreater:
13773 case Builtin::BI__builtin_isunordered: {
13782 switch (BuiltinOp) {
13783 case Builtin::BI__builtin_isgreater:
13785 case Builtin::BI__builtin_isgreaterequal:
13787 case Builtin::BI__builtin_isless:
13789 case Builtin::BI__builtin_islessequal:
13791 case Builtin::BI__builtin_islessgreater: {
13792 APFloat::cmpResult cmp = LHS.compare(RHS);
13793 return cmp == APFloat::cmpResult::cmpLessThan ||
13794 cmp == APFloat::cmpResult::cmpGreaterThan;
13796 case Builtin::BI__builtin_isunordered:
13797 return LHS.compare(RHS) == APFloat::cmpResult::cmpUnordered;
13799 llvm_unreachable(
"Unexpected builtin ID: Should be a floating "
13800 "point comparison function");
13808 case Builtin::BI__builtin_issignaling: {
13811 Success(Val.isSignaling() ? 1 : 0,
E);
13814 case Builtin::BI__builtin_isfpclass: {
13818 unsigned Test =
static_cast<llvm::FPClassTest
>(MaskVal.getZExtValue());
13821 Success((Val.classify() & Test) ? 1 : 0,
E);
13824 case Builtin::BI__builtin_parity:
13825 case Builtin::BI__builtin_parityl:
13826 case Builtin::BI__builtin_parityll: {
13831 return Success(Val.popcount() % 2,
E);
13834 case Builtin::BI__builtin_abs:
13835 case Builtin::BI__builtin_labs:
13836 case Builtin::BI__builtin_llabs: {
13840 if (Val ==
APSInt(APInt::getSignedMinValue(Val.getBitWidth()),
13843 if (Val.isNegative())
13848 case Builtin::BI__builtin_popcount:
13849 case Builtin::BI__builtin_popcountl:
13850 case Builtin::BI__builtin_popcountll:
13851 case Builtin::BI__builtin_popcountg:
13852 case Builtin::BI__builtin_elementwise_popcount:
13853 case Builtin::BI__popcnt16:
13854 case Builtin::BI__popcnt:
13855 case Builtin::BI__popcnt64: {
13866 return Success(Val.popcount(),
E);
13869 case Builtin::BI__builtin_rotateleft8:
13870 case Builtin::BI__builtin_rotateleft16:
13871 case Builtin::BI__builtin_rotateleft32:
13872 case Builtin::BI__builtin_rotateleft64:
13873 case Builtin::BI_rotl8:
13874 case Builtin::BI_rotl16:
13875 case Builtin::BI_rotl:
13876 case Builtin::BI_lrotl:
13877 case Builtin::BI_rotl64: {
13883 return Success(Val.rotl(Amt.urem(Val.getBitWidth())),
E);
13886 case Builtin::BI__builtin_rotateright8:
13887 case Builtin::BI__builtin_rotateright16:
13888 case Builtin::BI__builtin_rotateright32:
13889 case Builtin::BI__builtin_rotateright64:
13890 case Builtin::BI_rotr8:
13891 case Builtin::BI_rotr16:
13892 case Builtin::BI_rotr:
13893 case Builtin::BI_lrotr:
13894 case Builtin::BI_rotr64: {
13900 return Success(Val.rotr(Amt.urem(Val.getBitWidth())),
E);
13903 case Builtin::BI__builtin_elementwise_add_sat: {
13909 APInt Result = LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS);
13912 case Builtin::BI__builtin_elementwise_sub_sat: {
13918 APInt Result = LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
13921 case Builtin::BI__builtin_elementwise_max: {
13927 APInt Result = std::max(LHS, RHS);
13930 case Builtin::BI__builtin_elementwise_min: {
13936 APInt Result = std::min(LHS, RHS);
13939 case Builtin::BIstrlen:
13940 case Builtin::BIwcslen:
13942 if (Info.getLangOpts().CPlusPlus11)
13943 Info.CCEDiag(
E, diag::note_constexpr_invalid_function)
13945 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
13947 Info.CCEDiag(
E, diag::note_invalid_subexpr_in_const_expr);
13949 case Builtin::BI__builtin_strlen:
13950 case Builtin::BI__builtin_wcslen: {
13959 case Builtin::BIstrcmp:
13960 case Builtin::BIwcscmp:
13961 case Builtin::BIstrncmp:
13962 case Builtin::BIwcsncmp:
13963 case Builtin::BImemcmp:
13964 case Builtin::BIbcmp:
13965 case Builtin::BIwmemcmp:
13967 if (Info.getLangOpts().CPlusPlus11)
13968 Info.CCEDiag(
E, diag::note_constexpr_invalid_function)
13970 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
13972 Info.CCEDiag(
E, diag::note_invalid_subexpr_in_const_expr);
13974 case Builtin::BI__builtin_strcmp:
13975 case Builtin::BI__builtin_wcscmp:
13976 case Builtin::BI__builtin_strncmp:
13977 case Builtin::BI__builtin_wcsncmp:
13978 case Builtin::BI__builtin_memcmp:
13979 case Builtin::BI__builtin_bcmp:
13980 case Builtin::BI__builtin_wmemcmp: {
13981 LValue String1, String2;
13987 if (BuiltinOp != Builtin::BIstrcmp &&
13988 BuiltinOp != Builtin::BIwcscmp &&
13989 BuiltinOp != Builtin::BI__builtin_strcmp &&
13990 BuiltinOp != Builtin::BI__builtin_wcscmp) {
13994 MaxLength = N.getZExtValue();
13998 if (MaxLength == 0u)
14001 if (!String1.checkNullPointerForFoldAccess(Info,
E,
AK_Read) ||
14002 !String2.checkNullPointerForFoldAccess(Info,
E,
AK_Read) ||
14003 String1.Designator.Invalid || String2.Designator.Invalid)
14006 QualType CharTy1 = String1.Designator.getType(Info.Ctx);
14007 QualType CharTy2 = String2.Designator.getType(Info.Ctx);
14009 bool IsRawByte = BuiltinOp == Builtin::BImemcmp ||
14010 BuiltinOp == Builtin::BIbcmp ||
14011 BuiltinOp == Builtin::BI__builtin_memcmp ||
14012 BuiltinOp == Builtin::BI__builtin_bcmp;
14014 assert(IsRawByte ||
14015 (Info.Ctx.hasSameUnqualifiedType(
14017 Info.Ctx.hasSameUnqualifiedType(CharTy1, CharTy2)));
14024 Info.FFDiag(
E, diag::note_constexpr_memcmp_unsupported)
14025 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp) << CharTy1
14030 const auto &ReadCurElems = [&](
APValue &Char1,
APValue &Char2) {
14033 Char1.
isInt() && Char2.isInt();
14035 const auto &AdvanceElems = [&] {
14041 (BuiltinOp != Builtin::BImemcmp && BuiltinOp != Builtin::BIbcmp &&
14042 BuiltinOp != Builtin::BIwmemcmp &&
14043 BuiltinOp != Builtin::BI__builtin_memcmp &&
14044 BuiltinOp != Builtin::BI__builtin_bcmp &&
14045 BuiltinOp != Builtin::BI__builtin_wmemcmp);
14046 bool IsWide = BuiltinOp == Builtin::BIwcscmp ||
14047 BuiltinOp == Builtin::BIwcsncmp ||
14048 BuiltinOp == Builtin::BIwmemcmp ||
14049 BuiltinOp == Builtin::BI__builtin_wcscmp ||
14050 BuiltinOp == Builtin::BI__builtin_wcsncmp ||
14051 BuiltinOp == Builtin::BI__builtin_wmemcmp;
14053 for (; MaxLength; --MaxLength) {
14055 if (!ReadCurElems(Char1, Char2))
14063 if (StopAtNull && !Char1.
getInt())
14065 assert(!(StopAtNull && !Char2.
getInt()));
14066 if (!AdvanceElems())
14073 case Builtin::BI__atomic_always_lock_free:
14074 case Builtin::BI__atomic_is_lock_free:
14075 case Builtin::BI__c11_atomic_is_lock_free: {
14091 if (
Size.isPowerOfTwo()) {
14093 unsigned InlineWidthBits =
14094 Info.Ctx.getTargetInfo().getMaxAtomicInlineWidth();
14095 if (Size <= Info.Ctx.toCharUnitsFromBits(InlineWidthBits)) {
14096 if (BuiltinOp == Builtin::BI__c11_atomic_is_lock_free ||
14102 const Expr *PtrArg =
E->getArg(1);
14108 IntResult.isAligned(
Size.getAsAlign()))
14112 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(PtrArg)) {
14115 if (ICE->getCastKind() == CK_BitCast)
14116 PtrArg = ICE->getSubExpr();
14122 Info.Ctx.getTypeAlignInChars(PointeeType) >= Size) {
14130 return BuiltinOp == Builtin::BI__atomic_always_lock_free ?
14133 case Builtin::BI__builtin_addcb:
14134 case Builtin::BI__builtin_addcs:
14135 case Builtin::BI__builtin_addc:
14136 case Builtin::BI__builtin_addcl:
14137 case Builtin::BI__builtin_addcll:
14138 case Builtin::BI__builtin_subcb:
14139 case Builtin::BI__builtin_subcs:
14140 case Builtin::BI__builtin_subc:
14141 case Builtin::BI__builtin_subcl:
14142 case Builtin::BI__builtin_subcll: {
14143 LValue CarryOutLValue;
14144 APSInt LHS, RHS, CarryIn, CarryOut, Result;
14155 bool FirstOverflowed =
false;
14156 bool SecondOverflowed =
false;
14157 switch (BuiltinOp) {
14159 llvm_unreachable(
"Invalid value for BuiltinOp");
14160 case Builtin::BI__builtin_addcb:
14161 case Builtin::BI__builtin_addcs:
14162 case Builtin::BI__builtin_addc:
14163 case Builtin::BI__builtin_addcl:
14164 case Builtin::BI__builtin_addcll:
14166 LHS.uadd_ov(RHS, FirstOverflowed).uadd_ov(CarryIn, SecondOverflowed);
14168 case Builtin::BI__builtin_subcb:
14169 case Builtin::BI__builtin_subcs:
14170 case Builtin::BI__builtin_subc:
14171 case Builtin::BI__builtin_subcl:
14172 case Builtin::BI__builtin_subcll:
14174 LHS.usub_ov(RHS, FirstOverflowed).usub_ov(CarryIn, SecondOverflowed);
14180 CarryOut = (
uint64_t)(FirstOverflowed | SecondOverflowed);
14186 case Builtin::BI__builtin_add_overflow:
14187 case Builtin::BI__builtin_sub_overflow:
14188 case Builtin::BI__builtin_mul_overflow:
14189 case Builtin::BI__builtin_sadd_overflow:
14190 case Builtin::BI__builtin_uadd_overflow:
14191 case Builtin::BI__builtin_uaddl_overflow:
14192 case Builtin::BI__builtin_uaddll_overflow:
14193 case Builtin::BI__builtin_usub_overflow:
14194 case Builtin::BI__builtin_usubl_overflow:
14195 case Builtin::BI__builtin_usubll_overflow:
14196 case Builtin::BI__builtin_umul_overflow:
14197 case Builtin::BI__builtin_umull_overflow:
14198 case Builtin::BI__builtin_umulll_overflow:
14199 case Builtin::BI__builtin_saddl_overflow:
14200 case Builtin::BI__builtin_saddll_overflow:
14201 case Builtin::BI__builtin_ssub_overflow:
14202 case Builtin::BI__builtin_ssubl_overflow:
14203 case Builtin::BI__builtin_ssubll_overflow:
14204 case Builtin::BI__builtin_smul_overflow:
14205 case Builtin::BI__builtin_smull_overflow:
14206 case Builtin::BI__builtin_smulll_overflow: {
14207 LValue ResultLValue;
14217 bool DidOverflow =
false;
14220 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
14221 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
14222 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
14223 bool IsSigned = LHS.isSigned() || RHS.isSigned() ||
14225 bool AllSigned = LHS.isSigned() && RHS.isSigned() &&
14227 uint64_t LHSSize = LHS.getBitWidth();
14228 uint64_t RHSSize = RHS.getBitWidth();
14229 uint64_t ResultSize = Info.Ctx.getTypeSize(ResultType);
14230 uint64_t MaxBits = std::max(std::max(LHSSize, RHSSize), ResultSize);
14236 if (IsSigned && !AllSigned)
14239 LHS =
APSInt(LHS.extOrTrunc(MaxBits), !IsSigned);
14240 RHS =
APSInt(RHS.extOrTrunc(MaxBits), !IsSigned);
14241 Result =
APSInt(MaxBits, !IsSigned);
14245 switch (BuiltinOp) {
14247 llvm_unreachable(
"Invalid value for BuiltinOp");
14248 case Builtin::BI__builtin_add_overflow:
14249 case Builtin::BI__builtin_sadd_overflow:
14250 case Builtin::BI__builtin_saddl_overflow:
14251 case Builtin::BI__builtin_saddll_overflow:
14252 case Builtin::BI__builtin_uadd_overflow:
14253 case Builtin::BI__builtin_uaddl_overflow:
14254 case Builtin::BI__builtin_uaddll_overflow:
14255 Result = LHS.isSigned() ? LHS.sadd_ov(RHS, DidOverflow)
14256 : LHS.uadd_ov(RHS, DidOverflow);
14258 case Builtin::BI__builtin_sub_overflow:
14259 case Builtin::BI__builtin_ssub_overflow:
14260 case Builtin::BI__builtin_ssubl_overflow:
14261 case Builtin::BI__builtin_ssubll_overflow:
14262 case Builtin::BI__builtin_usub_overflow:
14263 case Builtin::BI__builtin_usubl_overflow:
14264 case Builtin::BI__builtin_usubll_overflow:
14265 Result = LHS.isSigned() ? LHS.ssub_ov(RHS, DidOverflow)
14266 : LHS.usub_ov(RHS, DidOverflow);
14268 case Builtin::BI__builtin_mul_overflow:
14269 case Builtin::BI__builtin_smul_overflow:
14270 case Builtin::BI__builtin_smull_overflow:
14271 case Builtin::BI__builtin_smulll_overflow:
14272 case Builtin::BI__builtin_umul_overflow:
14273 case Builtin::BI__builtin_umull_overflow:
14274 case Builtin::BI__builtin_umulll_overflow:
14275 Result = LHS.isSigned() ? LHS.smul_ov(RHS, DidOverflow)
14276 : LHS.umul_ov(RHS, DidOverflow);
14282 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
14283 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
14284 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
14290 APSInt Temp = Result.extOrTrunc(Info.Ctx.getTypeSize(ResultType));
14293 if (!APSInt::isSameValue(Temp, Result))
14294 DidOverflow =
true;
14304 case Builtin::BI__builtin_reduce_add:
14305 case Builtin::BI__builtin_reduce_mul:
14306 case Builtin::BI__builtin_reduce_and:
14307 case Builtin::BI__builtin_reduce_or:
14308 case Builtin::BI__builtin_reduce_xor:
14309 case Builtin::BI__builtin_reduce_min:
14310 case Builtin::BI__builtin_reduce_max: {
14317 for (
unsigned EltNum = 1; EltNum < SourceLen; ++EltNum) {
14318 switch (BuiltinOp) {
14321 case Builtin::BI__builtin_reduce_add: {
14324 Reduced.getBitWidth() + 1, std::plus<APSInt>(), Reduced))
14328 case Builtin::BI__builtin_reduce_mul: {
14331 Reduced.getBitWidth() * 2, std::multiplies<APSInt>(), Reduced))
14335 case Builtin::BI__builtin_reduce_and: {
14339 case Builtin::BI__builtin_reduce_or: {
14343 case Builtin::BI__builtin_reduce_xor: {
14347 case Builtin::BI__builtin_reduce_min: {
14351 case Builtin::BI__builtin_reduce_max: {
14361 case clang::X86::BI__builtin_ia32_addcarryx_u32:
14362 case clang::X86::BI__builtin_ia32_addcarryx_u64:
14363 case clang::X86::BI__builtin_ia32_subborrow_u32:
14364 case clang::X86::BI__builtin_ia32_subborrow_u64: {
14365 LValue ResultLValue;
14366 APSInt CarryIn, LHS, RHS;
14374 bool IsAdd = BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u32 ||
14375 BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u64;
14377 unsigned BitWidth = LHS.getBitWidth();
14378 unsigned CarryInBit = CarryIn.ugt(0) ? 1 : 0;
14381 ? (LHS.zext(BitWidth + 1) + (RHS.zext(BitWidth + 1) + CarryInBit))
14382 : (LHS.zext(BitWidth + 1) - (RHS.zext(BitWidth + 1) + CarryInBit));
14384 APInt Result = ExResult.extractBits(BitWidth, 0);
14385 uint64_t CarryOut = ExResult.extractBitsAsZExtValue(1, BitWidth);
14393 case clang::X86::BI__builtin_ia32_bextr_u32:
14394 case clang::X86::BI__builtin_ia32_bextr_u64:
14395 case clang::X86::BI__builtin_ia32_bextri_u32:
14396 case clang::X86::BI__builtin_ia32_bextri_u64: {
14402 unsigned BitWidth = Val.getBitWidth();
14404 uint64_t Length = Idx.extractBitsAsZExtValue(8, 8);
14405 Length = Length > BitWidth ? BitWidth : Length;
14408 if (Length == 0 || Shift >= BitWidth)
14412 Result &= llvm::maskTrailingOnes<uint64_t>(Length);
14416 case clang::X86::BI__builtin_ia32_bzhi_si:
14417 case clang::X86::BI__builtin_ia32_bzhi_di: {
14423 unsigned BitWidth = Val.getBitWidth();
14424 unsigned Index = Idx.extractBitsAsZExtValue(8, 0);
14425 if (Index < BitWidth)
14426 Val.clearHighBits(BitWidth - Index);
14430 case clang::X86::BI__builtin_ia32_lzcnt_u16:
14431 case clang::X86::BI__builtin_ia32_lzcnt_u32:
14432 case clang::X86::BI__builtin_ia32_lzcnt_u64: {
14436 return Success(Val.countLeadingZeros(),
E);
14439 case clang::X86::BI__builtin_ia32_tzcnt_u16:
14440 case clang::X86::BI__builtin_ia32_tzcnt_u32:
14441 case clang::X86::BI__builtin_ia32_tzcnt_u64: {
14445 return Success(Val.countTrailingZeros(),
E);
14448 case clang::X86::BI__builtin_ia32_pdep_si:
14449 case clang::X86::BI__builtin_ia32_pdep_di: {
14455 unsigned BitWidth = Val.getBitWidth();
14456 APInt Result = APInt::getZero(BitWidth);
14457 for (
unsigned I = 0,
P = 0; I != BitWidth; ++I)
14459 Result.setBitVal(I, Val[
P++]);
14463 case clang::X86::BI__builtin_ia32_pext_si:
14464 case clang::X86::BI__builtin_ia32_pext_di: {
14470 unsigned BitWidth = Val.getBitWidth();
14471 APInt Result = APInt::getZero(BitWidth);
14472 for (
unsigned I = 0,
P = 0; I != BitWidth; ++I)
14474 Result.setBitVal(
P++, Val[I]);
14483 const LValue &LV) {
14486 if (!LV.getLValueBase())
14491 if (!LV.getLValueDesignator().Invalid &&
14492 !LV.getLValueDesignator().isOnePastTheEnd())
14497 QualType Ty = getType(LV.getLValueBase());
14502 if (LV.getLValueDesignator().Invalid)
14508 return LV.getLValueOffset() == Size;
14518class DataRecursiveIntBinOpEvaluator {
14519 struct EvalResult {
14521 bool Failed =
false;
14523 EvalResult() =
default;
14525 void swap(EvalResult &RHS) {
14527 Failed = RHS.Failed;
14528 RHS.Failed =
false;
14534 EvalResult LHSResult;
14535 enum { AnyExprKind, BinOpKind, BinOpVisitedLHSKind }
Kind;
14538 Job(Job &&) =
default;
14540 void startSpeculativeEval(EvalInfo &Info) {
14541 SpecEvalRAII = SpeculativeEvaluationRAII(Info);
14545 SpeculativeEvaluationRAII SpecEvalRAII;
14550 IntExprEvaluator &IntEval;
14555 DataRecursiveIntBinOpEvaluator(IntExprEvaluator &IntEval,
APValue &Result)
14556 : IntEval(IntEval), Info(IntEval.getEvalInfo()), FinalResult(Result) { }
14563 return E->getOpcode() == BO_Comma ||
E->isLogicalOp() ||
14571 EvalResult PrevResult;
14572 while (!Queue.empty())
14573 process(PrevResult);
14575 if (PrevResult.Failed)
return false;
14577 FinalResult.
swap(PrevResult.Val);
14583 return IntEval.Success(
Value,
E, Result);
14586 return IntEval.Success(
Value,
E, Result);
14589 return IntEval.Error(
E);
14592 return IntEval.Error(
E,
D);
14596 return Info.CCEDiag(
E,
D);
14600 bool VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *
E,
14601 bool &SuppressRHSDiags);
14603 bool VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
14606 void EvaluateExpr(
const Expr *
E, EvalResult &Result) {
14607 Result.Failed = !
Evaluate(Result.Val, Info,
E);
14612 void process(EvalResult &Result);
14614 void enqueue(
const Expr *
E) {
14616 Queue.resize(Queue.size()+1);
14617 Queue.back().E =
E;
14618 Queue.back().Kind = Job::AnyExprKind;
14624bool DataRecursiveIntBinOpEvaluator::
14626 bool &SuppressRHSDiags) {
14627 if (
E->getOpcode() == BO_Comma) {
14629 if (LHSResult.Failed)
14630 return Info.noteSideEffect();
14634 if (
E->isLogicalOp()) {
14639 if (LHSAsBool == (
E->getOpcode() == BO_LOr)) {
14640 Success(LHSAsBool,
E, LHSResult.Val);
14644 LHSResult.Failed =
true;
14648 if (!Info.noteSideEffect())
14654 SuppressRHSDiags =
true;
14663 if (LHSResult.Failed && !Info.noteFailure())
14674 assert(!LVal.
hasLValuePath() &&
"have designator for integer lvalue");
14676 uint64_t Offset64 = Offset.getQuantity();
14677 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
14679 : Offset64 + Index64);
14682bool DataRecursiveIntBinOpEvaluator::
14683 VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
14685 if (
E->getOpcode() == BO_Comma) {
14686 if (RHSResult.Failed)
14688 Result = RHSResult.Val;
14692 if (
E->isLogicalOp()) {
14693 bool lhsResult, rhsResult;
14699 if (
E->getOpcode() == BO_LOr)
14700 return Success(lhsResult || rhsResult,
E, Result);
14702 return Success(lhsResult && rhsResult,
E, Result);
14708 if (rhsResult == (
E->getOpcode() == BO_LOr))
14709 return Success(rhsResult,
E, Result);
14719 if (LHSResult.Failed || RHSResult.Failed)
14722 const APValue &LHSVal = LHSResult.Val;
14723 const APValue &RHSVal = RHSResult.Val;
14733 if (
E->getOpcode() == BO_Add &&
14747 if (!LHSExpr || !RHSExpr)
14749 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
14750 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
14751 if (!LHSAddrExpr || !RHSAddrExpr)
14757 Result =
APValue(LHSAddrExpr, RHSAddrExpr);
14776void DataRecursiveIntBinOpEvaluator::process(EvalResult &Result) {
14777 Job &job = Queue.back();
14779 switch (job.Kind) {
14780 case Job::AnyExprKind: {
14781 if (
const BinaryOperator *Bop = dyn_cast<BinaryOperator>(job.E)) {
14782 if (shouldEnqueue(Bop)) {
14783 job.Kind = Job::BinOpKind;
14784 enqueue(Bop->getLHS());
14789 EvaluateExpr(job.E, Result);
14794 case Job::BinOpKind: {
14796 bool SuppressRHSDiags =
false;
14797 if (!VisitBinOpLHSOnly(Result, Bop, SuppressRHSDiags)) {
14801 if (SuppressRHSDiags)
14802 job.startSpeculativeEval(Info);
14803 job.LHSResult.swap(Result);
14804 job.Kind = Job::BinOpVisitedLHSKind;
14809 case Job::BinOpVisitedLHSKind: {
14813 Result.Failed = !VisitBinOp(job.LHSResult, RHS, Bop, Result.Val);
14819 llvm_unreachable(
"Invalid Job::Kind!");
14823enum class CmpResult {
14832template <
class SuccessCB,
class AfterCB>
14835 SuccessCB &&
Success, AfterCB &&DoAfter) {
14837 assert(
E->isComparisonOp() &&
"expected comparison operator");
14838 assert((
E->getOpcode() == BO_Cmp ||
14840 "unsupported binary expression evaluation");
14841 auto Error = [&](
const Expr *
E) {
14842 Info.FFDiag(
E, diag::note_invalid_subexpr_in_const_expr);
14846 bool IsRelational =
E->isRelationalOp() ||
E->getOpcode() == BO_Cmp;
14847 bool IsEquality =
E->isEqualityOp();
14856 if (!LHSOK && !Info.noteFailure())
14861 return Success(CmpResult::Less,
E);
14863 return Success(CmpResult::Greater,
E);
14864 return Success(CmpResult::Equal,
E);
14868 APFixedPoint LHSFX(Info.Ctx.getFixedPointSemantics(LHSTy));
14869 APFixedPoint RHSFX(Info.Ctx.getFixedPointSemantics(RHSTy));
14872 if (!LHSOK && !Info.noteFailure())
14877 return Success(CmpResult::Less,
E);
14879 return Success(CmpResult::Greater,
E);
14880 return Success(CmpResult::Equal,
E);
14884 ComplexValue LHS, RHS;
14886 if (
E->isAssignmentOp()) {
14893 LHS.makeComplexFloat();
14894 LHS.FloatImag = APFloat(LHS.FloatReal.getSemantics());
14899 if (!LHSOK && !Info.noteFailure())
14905 RHS.makeComplexFloat();
14906 RHS.FloatImag = APFloat(RHS.FloatReal.getSemantics());
14910 if (LHS.isComplexFloat()) {
14911 APFloat::cmpResult CR_r =
14912 LHS.getComplexFloatReal().compare(RHS.getComplexFloatReal());
14913 APFloat::cmpResult CR_i =
14914 LHS.getComplexFloatImag().compare(RHS.getComplexFloatImag());
14915 bool IsEqual = CR_r == APFloat::cmpEqual && CR_i == APFloat::cmpEqual;
14916 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal,
E);
14918 assert(IsEquality &&
"invalid complex comparison");
14919 bool IsEqual = LHS.getComplexIntReal() == RHS.getComplexIntReal() &&
14920 LHS.getComplexIntImag() == RHS.getComplexIntImag();
14921 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal,
E);
14927 APFloat RHS(0.0), LHS(0.0);
14930 if (!LHSOK && !Info.noteFailure())
14936 assert(
E->isComparisonOp() &&
"Invalid binary operator!");
14937 llvm::APFloatBase::cmpResult APFloatCmpResult = LHS.compare(RHS);
14938 if (!Info.InConstantContext &&
14939 APFloatCmpResult == APFloat::cmpUnordered &&
14942 Info.FFDiag(
E, diag::note_constexpr_float_arithmetic_strict);
14945 auto GetCmpRes = [&]() {
14946 switch (APFloatCmpResult) {
14947 case APFloat::cmpEqual:
14948 return CmpResult::Equal;
14949 case APFloat::cmpLessThan:
14950 return CmpResult::Less;
14951 case APFloat::cmpGreaterThan:
14952 return CmpResult::Greater;
14953 case APFloat::cmpUnordered:
14954 return CmpResult::Unordered;
14956 llvm_unreachable(
"Unrecognised APFloat::cmpResult enum");
14962 LValue LHSValue, RHSValue;
14965 if (!LHSOK && !Info.noteFailure())
14974 auto DiagComparison = [&] (
unsigned DiagID,
bool Reversed =
false) {
14975 std::string LHS = LHSValue.toString(Info.Ctx,
E->getLHS()->
getType());
14976 std::string RHS = RHSValue.toString(Info.Ctx,
E->getRHS()->
getType());
14977 Info.FFDiag(
E, DiagID)
14984 return DiagComparison(
14985 diag::note_constexpr_pointer_comparison_unspecified);
14991 if ((!LHSValue.Base && !LHSValue.Offset.isZero()) ||
14992 (!RHSValue.Base && !RHSValue.Offset.isZero()))
14993 return DiagComparison(diag::note_constexpr_pointer_constant_comparison,
15007 return DiagComparison(diag::note_constexpr_literal_comparison);
15009 return DiagComparison(diag::note_constexpr_opaque_call_comparison,
15014 return DiagComparison(diag::note_constexpr_pointer_weak_comparison,
15018 if (LHSValue.Base && LHSValue.Offset.isZero() &&
15020 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
15022 if (RHSValue.Base && RHSValue.Offset.isZero() &&
15024 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
15030 return DiagComparison(
15031 diag::note_constexpr_pointer_comparison_zero_sized);
15032 if (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown)
15033 return DiagComparison(
15034 diag::note_constexpr_pointer_comparison_unspecified);
15036 return Success(CmpResult::Unequal,
E);
15039 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
15040 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
15042 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
15043 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
15053 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid && IsRelational) {
15054 bool WasArrayIndex;
15056 LHSValue.Base.isNull() ?
QualType()
15058 LHSDesignator, RHSDesignator, WasArrayIndex);
15065 if (!WasArrayIndex && Mismatch < LHSDesignator.Entries.size() &&
15066 Mismatch < RHSDesignator.Entries.size()) {
15067 const FieldDecl *LF = getAsField(LHSDesignator.Entries[Mismatch]);
15068 const FieldDecl *RF = getAsField(RHSDesignator.Entries[Mismatch]);
15070 Info.CCEDiag(
E, diag::note_constexpr_pointer_comparison_base_classes);
15072 Info.CCEDiag(
E, diag::note_constexpr_pointer_comparison_base_field)
15073 << getAsBaseClass(LHSDesignator.Entries[Mismatch])
15076 Info.CCEDiag(
E, diag::note_constexpr_pointer_comparison_base_field)
15077 << getAsBaseClass(RHSDesignator.Entries[Mismatch])
15082 diag::note_constexpr_pointer_comparison_differing_access)
15090 unsigned PtrSize = Info.Ctx.getTypeSize(LHSTy);
15093 assert(PtrSize <= 64 &&
"Unexpected pointer width");
15094 uint64_t Mask = ~0ULL >> (64 - PtrSize);
15095 CompareLHS &= Mask;
15096 CompareRHS &= Mask;
15101 if (!LHSValue.Base.isNull() && IsRelational) {
15105 CharUnits Size = Info.Ctx.getTypeSizeInChars(BaseTy);
15106 uint64_t OffsetLimit = Size.getQuantity();
15107 if (CompareLHS > OffsetLimit || CompareRHS > OffsetLimit)
15111 if (CompareLHS < CompareRHS)
15112 return Success(CmpResult::Less,
E);
15113 if (CompareLHS > CompareRHS)
15114 return Success(CmpResult::Greater,
E);
15115 return Success(CmpResult::Equal,
E);
15119 assert(IsEquality &&
"unexpected member pointer operation");
15122 MemberPtr LHSValue, RHSValue;
15125 if (!LHSOK && !Info.noteFailure())
15133 if (LHSValue.getDecl() && LHSValue.getDecl()->isWeak()) {
15134 Info.FFDiag(
E, diag::note_constexpr_mem_pointer_weak_comparison)
15135 << LHSValue.getDecl();
15138 if (RHSValue.getDecl() && RHSValue.getDecl()->isWeak()) {
15139 Info.FFDiag(
E, diag::note_constexpr_mem_pointer_weak_comparison)
15140 << RHSValue.getDecl();
15147 if (!LHSValue.getDecl() || !RHSValue.getDecl()) {
15148 bool Equal = !LHSValue.getDecl() && !RHSValue.getDecl();
15149 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal,
E);
15154 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(LHSValue.getDecl()))
15155 if (MD->isVirtual())
15156 Info.CCEDiag(
E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
15157 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(RHSValue.getDecl()))
15158 if (MD->isVirtual())
15159 Info.CCEDiag(
E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
15165 bool Equal = LHSValue == RHSValue;
15166 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal,
E);
15170 assert(
E->isComparisonOp() &&
"unexpected nullptr operation");
15171 assert(RHSTy->
isNullPtrType() &&
"missing pointer conversion");
15179 return Success(CmpResult::Equal,
E);
15192 case CmpResult::Unequal:
15193 llvm_unreachable(
"should never produce Unequal for three-way comparison");
15194 case CmpResult::Less:
15195 CCR = ComparisonCategoryResult::Less;
15197 case CmpResult::Equal:
15198 CCR = ComparisonCategoryResult::Equal;
15200 case CmpResult::Greater:
15201 CCR = ComparisonCategoryResult::Greater;
15203 case CmpResult::Unordered:
15204 CCR = ComparisonCategoryResult::Unordered;
15218 ConstantExprKind::Normal);
15221 return ExprEvaluatorBaseTy::VisitBinCmp(
E);
15225bool RecordExprEvaluator::VisitCXXParenListInitExpr(
15227 return VisitCXXParenListOrInitListExpr(
E,
E->getInitExprs());
15233 if (
E->isAssignmentOp()) {
15235 if (!Info.noteFailure())
15239 if (DataRecursiveIntBinOpEvaluator::shouldEnqueue(
E))
15240 return DataRecursiveIntBinOpEvaluator(*
this, Result).Traverse(
E);
15244 "DataRecursiveIntBinOpEvaluator should have handled integral types");
15246 if (
E->isComparisonOp()) {
15250 assert((CR != CmpResult::Unequal ||
E->isEqualityOp()) &&
15251 "should only produce Unequal for equality comparisons");
15252 bool IsEqual = CR == CmpResult::Equal,
15253 IsLess = CR == CmpResult::Less,
15254 IsGreater = CR == CmpResult::Greater;
15255 auto Op =
E->getOpcode();
15258 llvm_unreachable(
"unsupported binary operator");
15261 return Success(IsEqual == (Op == BO_EQ),
E);
15267 return Success(IsEqual || IsLess,
E);
15269 return Success(IsEqual || IsGreater,
E);
15273 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
15281 E->getOpcode() == BO_Sub) {
15282 LValue LHSValue, RHSValue;
15285 if (!LHSOK && !Info.noteFailure())
15294 const Expr *LHSExpr = LHSValue.Base.dyn_cast<
const Expr *>();
15295 const Expr *RHSExpr = RHSValue.Base.dyn_cast<
const Expr *>();
15297 auto DiagArith = [&](
unsigned DiagID) {
15298 std::string LHS = LHSValue.toString(Info.Ctx,
E->getLHS()->
getType());
15299 std::string RHS = RHSValue.toString(Info.Ctx,
E->getRHS()->
getType());
15300 Info.FFDiag(
E, DiagID) << LHS << RHS;
15301 if (LHSExpr && LHSExpr == RHSExpr)
15303 diag::note_constexpr_repeated_literal_eval)
15308 if (!LHSExpr || !RHSExpr)
15309 return DiagArith(diag::note_constexpr_pointer_arith_unspecified);
15312 return DiagArith(diag::note_constexpr_literal_arith);
15314 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
15315 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
15316 if (!LHSAddrExpr || !RHSAddrExpr)
15324 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
15325 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
15327 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
15328 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
15334 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid &&
15337 Info.CCEDiag(
E, diag::note_constexpr_pointer_subtraction_not_same_array);
15349 if (ElementSize.
isZero()) {
15350 Info.FFDiag(
E, diag::note_constexpr_pointer_subtraction_zero_size)
15367 APSInt TrueResult = (LHS - RHS) / ElemSize;
15368 APSInt Result = TrueResult.trunc(Info.Ctx.getIntWidth(
E->
getType()));
15370 if (Result.extend(65) != TrueResult &&
15376 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
15381bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr(
15383 switch(
E->getKind()) {
15384 case UETT_PreferredAlignOf:
15385 case UETT_AlignOf: {
15386 if (
E->isArgumentType())
15394 case UETT_PtrAuthTypeDiscriminator: {
15395 if (
E->getArgumentType()->isDependentType())
15398 Info.Ctx.getPointerAuthTypeDiscriminator(
E->getArgumentType()),
E);
15400 case UETT_VecStep: {
15416 case UETT_DataSizeOf:
15417 case UETT_SizeOf: {
15418 QualType SrcTy =
E->getTypeOfArgument();
15426 E->getKind() == UETT_DataSizeOf ? SizeOfType::DataSizeOf
15427 : SizeOfType::SizeOf)) {
15432 case UETT_OpenMPRequiredSimdAlign:
15433 assert(
E->isArgumentType());
15435 Info.Ctx.toCharUnitsFromBits(
15436 Info.Ctx.getOpenMPDefaultSimdAlign(
E->getArgumentType()))
15439 case UETT_VectorElements: {
15447 if (Info.InConstantContext)
15448 Info.CCEDiag(
E, diag::note_constexpr_non_const_vectorelements)
15453 case UETT_CountOf: {
15459 if (
const auto *CAT =
15469 const auto *VAT = Info.Ctx.getAsVariableArrayType(Ty);
15471 if (VAT->getElementType()->isArrayType()) {
15474 if (!VAT->getSizeExpr()) {
15479 std::optional<APSInt> Res =
15480 VAT->getSizeExpr()->getIntegerConstantExpr(Info.Ctx);
15485 static_cast<unsigned>(Info.Ctx.getTypeSize(Info.Ctx.getSizeType())),
15486 Res->getZExtValue()};
15498 llvm_unreachable(
"unknown expr/type trait");
15501bool IntExprEvaluator::VisitOffsetOfExpr(
const OffsetOfExpr *OOE) {
15507 for (
unsigned i = 0; i != n; ++i) {
15515 const ArrayType *AT = Info.Ctx.getAsArrayType(CurrentType);
15519 CharUnits ElementSize = Info.Ctx.getTypeSizeInChars(CurrentType);
15520 Result += IdxResult.getSExtValue() * ElementSize;
15532 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
15539 llvm_unreachable(
"dependent __builtin_offsetof");
15554 CurrentType = BaseSpec->
getType();
15568bool IntExprEvaluator::VisitUnaryOperator(
const UnaryOperator *
E) {
15569 switch (
E->getOpcode()) {
15577 return Visit(
E->getSubExpr());
15580 return Visit(
E->getSubExpr());
15582 if (!Visit(
E->getSubExpr()))
15584 if (!Result.isInt())
return Error(
E);
15586 if (
Value.isSigned() &&
Value.isMinSignedValue() &&
E->canOverflow()) {
15587 if (Info.checkingForUndefinedBehavior())
15588 Info.Ctx.getDiagnostics().Report(
E->
getExprLoc(),
15589 diag::warn_integer_constant_overflow)
15601 if (!Visit(
E->getSubExpr()))
15603 if (!Result.isInt())
return Error(
E);
15604 return Success(~Result.getInt(),
E);
15617bool IntExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
15618 const Expr *SubExpr =
E->getSubExpr();
15622 switch (
E->getCastKind()) {
15623 case CK_BaseToDerived:
15624 case CK_DerivedToBase:
15625 case CK_UncheckedDerivedToBase:
15628 case CK_ArrayToPointerDecay:
15629 case CK_FunctionToPointerDecay:
15630 case CK_NullToPointer:
15631 case CK_NullToMemberPointer:
15632 case CK_BaseToDerivedMemberPointer:
15633 case CK_DerivedToBaseMemberPointer:
15634 case CK_ReinterpretMemberPointer:
15635 case CK_ConstructorConversion:
15636 case CK_IntegralToPointer:
15638 case CK_VectorSplat:
15639 case CK_IntegralToFloating:
15640 case CK_FloatingCast:
15641 case CK_CPointerToObjCPointerCast:
15642 case CK_BlockPointerToObjCPointerCast:
15643 case CK_AnyPointerToBlockPointerCast:
15644 case CK_ObjCObjectLValueCast:
15645 case CK_FloatingRealToComplex:
15646 case CK_FloatingComplexToReal:
15647 case CK_FloatingComplexCast:
15648 case CK_FloatingComplexToIntegralComplex:
15649 case CK_IntegralRealToComplex:
15650 case CK_IntegralComplexCast:
15651 case CK_IntegralComplexToFloatingComplex:
15652 case CK_BuiltinFnToFnPtr:
15653 case CK_ZeroToOCLOpaqueType:
15654 case CK_NonAtomicToAtomic:
15655 case CK_AddressSpaceConversion:
15656 case CK_IntToOCLSampler:
15657 case CK_FloatingToFixedPoint:
15658 case CK_FixedPointToFloating:
15659 case CK_FixedPointCast:
15660 case CK_IntegralToFixedPoint:
15661 case CK_MatrixCast:
15662 case CK_HLSLAggregateSplatCast:
15663 llvm_unreachable(
"invalid cast kind for integral value");
15667 case CK_LValueBitCast:
15668 case CK_ARCProduceObject:
15669 case CK_ARCConsumeObject:
15670 case CK_ARCReclaimReturnedObject:
15671 case CK_ARCExtendBlockObject:
15672 case CK_CopyAndAutoreleaseBlockObject:
15675 case CK_UserDefinedConversion:
15676 case CK_LValueToRValue:
15677 case CK_AtomicToNonAtomic:
15679 case CK_LValueToRValueBitCast:
15680 case CK_HLSLArrayRValue:
15681 case CK_HLSLElementwiseCast:
15682 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
15684 case CK_MemberPointerToBoolean:
15685 case CK_PointerToBoolean:
15686 case CK_IntegralToBoolean:
15687 case CK_FloatingToBoolean:
15688 case CK_BooleanToSignedIntegral:
15689 case CK_FloatingComplexToBoolean:
15690 case CK_IntegralComplexToBoolean: {
15695 if (BoolResult &&
E->getCastKind() == CK_BooleanToSignedIntegral)
15700 case CK_FixedPointToIntegral: {
15701 APFixedPoint Src(Info.Ctx.getFixedPointSemantics(SrcType));
15705 llvm::APSInt Result = Src.convertToInt(
15706 Info.Ctx.getIntWidth(DestType),
15713 case CK_FixedPointToBoolean: {
15716 if (!
Evaluate(Val, Info, SubExpr))
15721 case CK_IntegralCast: {
15722 if (!Visit(SubExpr))
15725 if (!Result.isInt()) {
15731 if (Result.isAddrLabelDiff())
15732 return Info.Ctx.getTypeSize(DestType) <= Info.Ctx.getTypeSize(SrcType);
15734 return Info.Ctx.getTypeSize(DestType) == Info.Ctx.getTypeSize(SrcType);
15737 if (Info.Ctx.getLangOpts().CPlusPlus && DestType->
isEnumeralType()) {
15749 if (!ED->isFixed()) {
15753 ED->getValueRange(
Max,
Min);
15756 if (ED->getNumNegativeBits() &&
15757 (
Max.slt(Result.getInt().getSExtValue()) ||
15758 Min.sgt(Result.getInt().getSExtValue())))
15759 Info.CCEDiag(
E, diag::note_constexpr_unscoped_enum_out_of_range)
15760 << llvm::toString(Result.getInt(), 10) <<
Min.getSExtValue()
15761 <<
Max.getSExtValue() << ED;
15762 else if (!ED->getNumNegativeBits() &&
15763 Max.ult(Result.getInt().getZExtValue()))
15764 Info.CCEDiag(
E, diag::note_constexpr_unscoped_enum_out_of_range)
15765 << llvm::toString(Result.getInt(), 10) <<
Min.getZExtValue()
15766 <<
Max.getZExtValue() << ED;
15771 Result.getInt()),
E);
15774 case CK_PointerToIntegral: {
15775 CCEDiag(
E, diag::note_constexpr_invalid_cast)
15776 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
15783 if (LV.getLValueBase()) {
15788 if (Info.Ctx.getTypeSize(DestType) != Info.Ctx.getTypeSize(SrcType))
15791 LV.Designator.setInvalid();
15792 LV.moveInto(Result);
15799 if (!
V.toIntegralConstant(AsInt, SrcType, Info.Ctx))
15800 llvm_unreachable(
"Can't cast this!");
15805 case CK_IntegralComplexToReal: {
15809 return Success(
C.getComplexIntReal(),
E);
15812 case CK_FloatingToIntegral: {
15822 case CK_HLSLVectorTruncation: {
15830 llvm_unreachable(
"unknown cast resulting in integral value");
15838 if (!LV.isComplexInt())
15840 return Success(LV.getComplexIntReal(),
E);
15843 return Visit(
E->getSubExpr());
15851 if (!LV.isComplexInt())
15853 return Success(LV.getComplexIntImag(),
E);
15856 VisitIgnoredValue(
E->getSubExpr());
15868bool IntExprEvaluator::VisitConceptSpecializationExpr(
15873bool IntExprEvaluator::VisitRequiresExpr(
const RequiresExpr *
E) {
15877bool FixedPointExprEvaluator::VisitUnaryOperator(
const UnaryOperator *
E) {
15878 switch (
E->getOpcode()) {
15884 return Visit(
E->getSubExpr());
15886 if (!Visit(
E->getSubExpr()))
return false;
15887 if (!Result.isFixedPoint())
15890 APFixedPoint Negated = Result.getFixedPoint().negate(&Overflowed);
15904bool FixedPointExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
15905 const Expr *SubExpr =
E->getSubExpr();
15908 "Expected destination type to be a fixed point type");
15909 auto DestFXSema = Info.Ctx.getFixedPointSemantics(DestType);
15911 switch (
E->getCastKind()) {
15912 case CK_FixedPointCast: {
15913 APFixedPoint Src(Info.Ctx.getFixedPointSemantics(SubExpr->
getType()));
15917 APFixedPoint Result = Src.convert(DestFXSema, &Overflowed);
15919 if (Info.checkingForUndefinedBehavior())
15920 Info.Ctx.getDiagnostics().Report(
E->
getExprLoc(),
15921 diag::warn_fixedpoint_constant_overflow)
15922 << Result.toString() <<
E->
getType();
15928 case CK_IntegralToFixedPoint: {
15934 APFixedPoint IntResult = APFixedPoint::getFromIntValue(
15935 Src, Info.Ctx.getFixedPointSemantics(DestType), &Overflowed);
15938 if (Info.checkingForUndefinedBehavior())
15939 Info.Ctx.getDiagnostics().Report(
E->
getExprLoc(),
15940 diag::warn_fixedpoint_constant_overflow)
15941 << IntResult.toString() <<
E->
getType();
15948 case CK_FloatingToFixedPoint: {
15954 APFixedPoint Result = APFixedPoint::getFromFloatValue(
15955 Src, Info.Ctx.getFixedPointSemantics(DestType), &Overflowed);
15958 if (Info.checkingForUndefinedBehavior())
15959 Info.Ctx.getDiagnostics().Report(
E->
getExprLoc(),
15960 diag::warn_fixedpoint_constant_overflow)
15961 << Result.toString() <<
E->
getType();
15969 case CK_LValueToRValue:
15970 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
15976bool FixedPointExprEvaluator::VisitBinaryOperator(
const BinaryOperator *
E) {
15977 if (
E->isPtrMemOp() ||
E->isAssignmentOp() ||
E->getOpcode() == BO_Comma)
15978 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
15980 const Expr *LHS =
E->getLHS();
15981 const Expr *RHS =
E->getRHS();
15983 Info.Ctx.getFixedPointSemantics(
E->
getType());
15985 APFixedPoint LHSFX(Info.Ctx.getFixedPointSemantics(LHS->
getType()));
15988 APFixedPoint RHSFX(Info.Ctx.getFixedPointSemantics(RHS->
getType()));
15992 bool OpOverflow =
false, ConversionOverflow =
false;
15993 APFixedPoint Result(LHSFX.getSemantics());
15994 switch (
E->getOpcode()) {
15996 Result = LHSFX.
add(RHSFX, &OpOverflow)
15997 .convert(ResultFXSema, &ConversionOverflow);
16001 Result = LHSFX.sub(RHSFX, &OpOverflow)
16002 .convert(ResultFXSema, &ConversionOverflow);
16006 Result = LHSFX.mul(RHSFX, &OpOverflow)
16007 .convert(ResultFXSema, &ConversionOverflow);
16011 if (RHSFX.getValue() == 0) {
16012 Info.FFDiag(
E, diag::note_expr_divide_by_zero);
16015 Result = LHSFX.div(RHSFX, &OpOverflow)
16016 .convert(ResultFXSema, &ConversionOverflow);
16022 llvm::APSInt RHSVal = RHSFX.getValue();
16025 LHSSema.getWidth() - (
unsigned)LHSSema.hasUnsignedPadding();
16026 unsigned Amt = RHSVal.getLimitedValue(ShiftBW - 1);
16030 if (RHSVal.isNegative())
16031 Info.CCEDiag(
E, diag::note_constexpr_negative_shift) << RHSVal;
16032 else if (Amt != RHSVal)
16033 Info.CCEDiag(
E, diag::note_constexpr_large_shift)
16034 << RHSVal <<
E->
getType() << ShiftBW;
16036 if (
E->getOpcode() == BO_Shl)
16037 Result = LHSFX.shl(Amt, &OpOverflow);
16039 Result = LHSFX.shr(Amt, &OpOverflow);
16045 if (OpOverflow || ConversionOverflow) {
16046 if (Info.checkingForUndefinedBehavior())
16047 Info.Ctx.getDiagnostics().Report(
E->
getExprLoc(),
16048 diag::warn_fixedpoint_constant_overflow)
16049 << Result.toString() <<
E->
getType();
16061class FloatExprEvaluator
16062 :
public ExprEvaluatorBase<FloatExprEvaluator> {
16065 FloatExprEvaluator(EvalInfo &info, APFloat &result)
16066 : ExprEvaluatorBaseTy(info), Result(result) {}
16069 Result =
V.getFloat();
16073 bool ZeroInitialization(
const Expr *
E) {
16074 Result = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(
E->
getType()));
16095 return FloatExprEvaluator(Info, Result).Visit(
E);
16102 llvm::APFloat &Result) {
16104 if (!S)
return false;
16111 if (S->getString().empty())
16112 fill = llvm::APInt(32, 0);
16113 else if (S->getString().getAsInteger(0, fill))
16118 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
16120 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
16128 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
16130 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
16136bool FloatExprEvaluator::VisitCallExpr(
const CallExpr *
E) {
16137 if (!IsConstantEvaluatedBuiltinCall(
E))
16138 return ExprEvaluatorBaseTy::VisitCallExpr(
E);
16140 switch (
E->getBuiltinCallee()) {
16144 case Builtin::BI__builtin_huge_val:
16145 case Builtin::BI__builtin_huge_valf:
16146 case Builtin::BI__builtin_huge_vall:
16147 case Builtin::BI__builtin_huge_valf16:
16148 case Builtin::BI__builtin_huge_valf128:
16149 case Builtin::BI__builtin_inf:
16150 case Builtin::BI__builtin_inff:
16151 case Builtin::BI__builtin_infl:
16152 case Builtin::BI__builtin_inff16:
16153 case Builtin::BI__builtin_inff128: {
16154 const llvm::fltSemantics &Sem =
16155 Info.Ctx.getFloatTypeSemantics(
E->
getType());
16156 Result = llvm::APFloat::getInf(Sem);
16160 case Builtin::BI__builtin_nans:
16161 case Builtin::BI__builtin_nansf:
16162 case Builtin::BI__builtin_nansl:
16163 case Builtin::BI__builtin_nansf16:
16164 case Builtin::BI__builtin_nansf128:
16170 case Builtin::BI__builtin_nan:
16171 case Builtin::BI__builtin_nanf:
16172 case Builtin::BI__builtin_nanl:
16173 case Builtin::BI__builtin_nanf16:
16174 case Builtin::BI__builtin_nanf128:
16182 case Builtin::BI__builtin_elementwise_abs:
16183 case Builtin::BI__builtin_fabs:
16184 case Builtin::BI__builtin_fabsf:
16185 case Builtin::BI__builtin_fabsl:
16186 case Builtin::BI__builtin_fabsf128:
16195 if (Result.isNegative())
16196 Result.changeSign();
16199 case Builtin::BI__arithmetic_fence:
16206 case Builtin::BI__builtin_copysign:
16207 case Builtin::BI__builtin_copysignf:
16208 case Builtin::BI__builtin_copysignl:
16209 case Builtin::BI__builtin_copysignf128: {
16214 Result.copySign(RHS);
16218 case Builtin::BI__builtin_fmax:
16219 case Builtin::BI__builtin_fmaxf:
16220 case Builtin::BI__builtin_fmaxl:
16221 case Builtin::BI__builtin_fmaxf16:
16222 case Builtin::BI__builtin_fmaxf128: {
16227 Result = maxnum(Result, RHS);
16231 case Builtin::BI__builtin_fmin:
16232 case Builtin::BI__builtin_fminf:
16233 case Builtin::BI__builtin_fminl:
16234 case Builtin::BI__builtin_fminf16:
16235 case Builtin::BI__builtin_fminf128: {
16240 Result = minnum(Result, RHS);
16244 case Builtin::BI__builtin_fmaximum_num:
16245 case Builtin::BI__builtin_fmaximum_numf:
16246 case Builtin::BI__builtin_fmaximum_numl:
16247 case Builtin::BI__builtin_fmaximum_numf16:
16248 case Builtin::BI__builtin_fmaximum_numf128: {
16253 Result = maximumnum(Result, RHS);
16257 case Builtin::BI__builtin_fminimum_num:
16258 case Builtin::BI__builtin_fminimum_numf:
16259 case Builtin::BI__builtin_fminimum_numl:
16260 case Builtin::BI__builtin_fminimum_numf16:
16261 case Builtin::BI__builtin_fminimum_numf128: {
16266 Result = minimumnum(Result, RHS);
16270 case Builtin::BI__builtin_elementwise_fma: {
16275 APFloat SourceY(0.), SourceZ(0.);
16281 (void)Result.fusedMultiplyAdd(SourceY, SourceZ, RM);
16287bool FloatExprEvaluator::VisitUnaryReal(
const UnaryOperator *
E) {
16292 Result = CV.FloatReal;
16296 return Visit(
E->getSubExpr());
16299bool FloatExprEvaluator::VisitUnaryImag(
const UnaryOperator *
E) {
16304 Result = CV.FloatImag;
16308 VisitIgnoredValue(
E->getSubExpr());
16309 const llvm::fltSemantics &Sem = Info.Ctx.getFloatTypeSemantics(
E->
getType());
16310 Result = llvm::APFloat::getZero(Sem);
16314bool FloatExprEvaluator::VisitUnaryOperator(
const UnaryOperator *
E) {
16315 switch (
E->getOpcode()) {
16316 default:
return Error(
E);
16325 Result.changeSign();
16330bool FloatExprEvaluator::VisitBinaryOperator(
const BinaryOperator *
E) {
16331 if (
E->isPtrMemOp() ||
E->isAssignmentOp() ||
E->getOpcode() == BO_Comma)
16332 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
16336 if (!LHSOK && !Info.noteFailure())
16343 Result =
E->getValue();
16347bool FloatExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
16348 const Expr* SubExpr =
E->getSubExpr();
16350 switch (
E->getCastKind()) {
16352 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
16354 case CK_IntegralToFloating: {
16357 Info.Ctx.getLangOpts());
16363 case CK_FixedPointToFloating: {
16364 APFixedPoint FixResult(Info.Ctx.getFixedPointSemantics(SubExpr->
getType()));
16368 FixResult.convertToFloat(Info.Ctx.getFloatTypeSemantics(
E->
getType()));
16372 case CK_FloatingCast: {
16373 if (!Visit(SubExpr))
16379 case CK_FloatingComplexToReal: {
16383 Result =
V.getComplexFloatReal();
16386 case CK_HLSLVectorTruncation: {
16400class ComplexExprEvaluator
16401 :
public ExprEvaluatorBase<ComplexExprEvaluator> {
16402 ComplexValue &Result;
16405 ComplexExprEvaluator(EvalInfo &info, ComplexValue &Result)
16406 : ExprEvaluatorBaseTy(info), Result(Result) {}
16413 bool ZeroInitialization(
const Expr *
E);
16432 return ComplexExprEvaluator(Info, Result).Visit(
E);
16435bool ComplexExprEvaluator::ZeroInitialization(
const Expr *
E) {
16438 Result.makeComplexFloat();
16439 APFloat Zero = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(ElemTy));
16440 Result.FloatReal =
Zero;
16441 Result.FloatImag =
Zero;
16443 Result.makeComplexInt();
16444 APSInt Zero = Info.Ctx.MakeIntValue(0, ElemTy);
16445 Result.IntReal =
Zero;
16446 Result.IntImag =
Zero;
16452 const Expr* SubExpr =
E->getSubExpr();
16455 Result.makeComplexFloat();
16456 APFloat &Imag = Result.FloatImag;
16460 Result.FloatReal =
APFloat(Imag.getSemantics());
16464 "Unexpected imaginary literal.");
16466 Result.makeComplexInt();
16467 APSInt &Imag = Result.IntImag;
16471 Result.IntReal =
APSInt(Imag.getBitWidth(), !Imag.isSigned());
16476bool ComplexExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
16478 switch (
E->getCastKind()) {
16480 case CK_BaseToDerived:
16481 case CK_DerivedToBase:
16482 case CK_UncheckedDerivedToBase:
16485 case CK_ArrayToPointerDecay:
16486 case CK_FunctionToPointerDecay:
16487 case CK_NullToPointer:
16488 case CK_NullToMemberPointer:
16489 case CK_BaseToDerivedMemberPointer:
16490 case CK_DerivedToBaseMemberPointer:
16491 case CK_MemberPointerToBoolean:
16492 case CK_ReinterpretMemberPointer:
16493 case CK_ConstructorConversion:
16494 case CK_IntegralToPointer:
16495 case CK_PointerToIntegral:
16496 case CK_PointerToBoolean:
16498 case CK_VectorSplat:
16499 case CK_IntegralCast:
16500 case CK_BooleanToSignedIntegral:
16501 case CK_IntegralToBoolean:
16502 case CK_IntegralToFloating:
16503 case CK_FloatingToIntegral:
16504 case CK_FloatingToBoolean:
16505 case CK_FloatingCast:
16506 case CK_CPointerToObjCPointerCast:
16507 case CK_BlockPointerToObjCPointerCast:
16508 case CK_AnyPointerToBlockPointerCast:
16509 case CK_ObjCObjectLValueCast:
16510 case CK_FloatingComplexToReal:
16511 case CK_FloatingComplexToBoolean:
16512 case CK_IntegralComplexToReal:
16513 case CK_IntegralComplexToBoolean:
16514 case CK_ARCProduceObject:
16515 case CK_ARCConsumeObject:
16516 case CK_ARCReclaimReturnedObject:
16517 case CK_ARCExtendBlockObject:
16518 case CK_CopyAndAutoreleaseBlockObject:
16519 case CK_BuiltinFnToFnPtr:
16520 case CK_ZeroToOCLOpaqueType:
16521 case CK_NonAtomicToAtomic:
16522 case CK_AddressSpaceConversion:
16523 case CK_IntToOCLSampler:
16524 case CK_FloatingToFixedPoint:
16525 case CK_FixedPointToFloating:
16526 case CK_FixedPointCast:
16527 case CK_FixedPointToBoolean:
16528 case CK_FixedPointToIntegral:
16529 case CK_IntegralToFixedPoint:
16530 case CK_MatrixCast:
16531 case CK_HLSLVectorTruncation:
16532 case CK_HLSLElementwiseCast:
16533 case CK_HLSLAggregateSplatCast:
16534 llvm_unreachable(
"invalid cast kind for complex value");
16536 case CK_LValueToRValue:
16537 case CK_AtomicToNonAtomic:
16539 case CK_LValueToRValueBitCast:
16540 case CK_HLSLArrayRValue:
16541 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
16544 case CK_LValueBitCast:
16545 case CK_UserDefinedConversion:
16548 case CK_FloatingRealToComplex: {
16549 APFloat &Real = Result.FloatReal;
16553 Result.makeComplexFloat();
16554 Result.FloatImag =
APFloat(Real.getSemantics());
16558 case CK_FloatingComplexCast: {
16559 if (!Visit(
E->getSubExpr()))
16570 case CK_FloatingComplexToIntegralComplex: {
16571 if (!Visit(
E->getSubExpr()))
16577 Result.makeComplexInt();
16579 To, Result.IntReal) &&
16581 To, Result.IntImag);
16584 case CK_IntegralRealToComplex: {
16585 APSInt &Real = Result.IntReal;
16589 Result.makeComplexInt();
16590 Result.IntImag =
APSInt(Real.getBitWidth(), !Real.isSigned());
16594 case CK_IntegralComplexCast: {
16595 if (!Visit(
E->getSubExpr()))
16607 case CK_IntegralComplexToFloatingComplex: {
16608 if (!Visit(
E->getSubExpr()))
16612 Info.Ctx.getLangOpts());
16616 Result.makeComplexFloat();
16618 To, Result.FloatReal) &&
16620 To, Result.FloatImag);
16624 llvm_unreachable(
"unknown cast resulting in complex value");
16628 APFloat &ResR, APFloat &ResI) {
16634 APFloat AC = A *
C;
16635 APFloat BD = B *
D;
16636 APFloat AD = A *
D;
16637 APFloat BC = B *
C;
16640 if (ResR.isNaN() && ResI.isNaN()) {
16641 bool Recalc =
false;
16642 if (A.isInfinity() || B.isInfinity()) {
16643 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
16645 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
16648 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
16650 D = APFloat::copySign(APFloat(
D.getSemantics()),
D);
16653 if (
C.isInfinity() ||
D.isInfinity()) {
16654 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
16656 D = APFloat::copySign(APFloat(
D.getSemantics(),
D.isInfinity() ? 1 : 0),
16659 A = APFloat::copySign(APFloat(A.getSemantics()), A);
16661 B = APFloat::copySign(APFloat(B.getSemantics()), B);
16664 if (!Recalc && (AC.isInfinity() || BD.isInfinity() || AD.isInfinity() ||
16665 BC.isInfinity())) {
16667 A = APFloat::copySign(APFloat(A.getSemantics()), A);
16669 B = APFloat::copySign(APFloat(B.getSemantics()), B);
16671 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
16673 D = APFloat::copySign(APFloat(
D.getSemantics()),
D);
16677 ResR = APFloat::getInf(A.getSemantics()) * (A *
C - B *
D);
16678 ResI = APFloat::getInf(A.getSemantics()) * (A *
D + B *
C);
16684 APFloat &ResR, APFloat &ResI) {
16691 APFloat MaxCD = maxnum(
abs(
C),
abs(
D));
16692 if (MaxCD.isFinite()) {
16693 DenomLogB =
ilogb(MaxCD);
16694 C =
scalbn(
C, -DenomLogB, APFloat::rmNearestTiesToEven);
16695 D =
scalbn(
D, -DenomLogB, APFloat::rmNearestTiesToEven);
16697 APFloat Denom =
C *
C +
D *
D;
16699 scalbn((A *
C + B *
D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
16701 scalbn((B *
C - A *
D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
16702 if (ResR.isNaN() && ResI.isNaN()) {
16703 if (Denom.isPosZero() && (!A.isNaN() || !B.isNaN())) {
16704 ResR = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * A;
16705 ResI = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * B;
16706 }
else if ((A.isInfinity() || B.isInfinity()) &&
C.isFinite() &&
16708 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
16710 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
16712 ResR = APFloat::getInf(ResR.getSemantics()) * (A *
C + B *
D);
16713 ResI = APFloat::getInf(ResI.getSemantics()) * (B *
C - A *
D);
16714 }
else if (MaxCD.isInfinity() && A.isFinite() && B.isFinite()) {
16715 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
16717 D = APFloat::copySign(APFloat(
D.getSemantics(),
D.isInfinity() ? 1 : 0),
16719 ResR = APFloat::getZero(ResR.getSemantics()) * (A *
C + B *
D);
16720 ResI = APFloat::getZero(ResI.getSemantics()) * (B *
C - A *
D);
16725bool ComplexExprEvaluator::VisitBinaryOperator(
const BinaryOperator *
E) {
16726 if (
E->isPtrMemOp() ||
E->isAssignmentOp() ||
E->getOpcode() == BO_Comma)
16727 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
16731 bool LHSReal =
false, RHSReal =
false;
16736 APFloat &Real = Result.FloatReal;
16739 Result.makeComplexFloat();
16740 Result.FloatImag =
APFloat(Real.getSemantics());
16743 LHSOK = Visit(
E->getLHS());
16745 if (!LHSOK && !Info.noteFailure())
16751 APFloat &Real = RHS.FloatReal;
16754 RHS.makeComplexFloat();
16755 RHS.FloatImag =
APFloat(Real.getSemantics());
16759 assert(!(LHSReal && RHSReal) &&
16760 "Cannot have both operands of a complex operation be real.");
16761 switch (
E->getOpcode()) {
16762 default:
return Error(
E);
16764 if (Result.isComplexFloat()) {
16765 Result.getComplexFloatReal().
add(RHS.getComplexFloatReal(),
16766 APFloat::rmNearestTiesToEven);
16768 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
16770 Result.getComplexFloatImag().
add(RHS.getComplexFloatImag(),
16771 APFloat::rmNearestTiesToEven);
16773 Result.getComplexIntReal() += RHS.getComplexIntReal();
16774 Result.getComplexIntImag() += RHS.getComplexIntImag();
16778 if (Result.isComplexFloat()) {
16779 Result.getComplexFloatReal().subtract(RHS.getComplexFloatReal(),
16780 APFloat::rmNearestTiesToEven);
16782 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
16783 Result.getComplexFloatImag().changeSign();
16784 }
else if (!RHSReal) {
16785 Result.getComplexFloatImag().subtract(RHS.getComplexFloatImag(),
16786 APFloat::rmNearestTiesToEven);
16789 Result.getComplexIntReal() -= RHS.getComplexIntReal();
16790 Result.getComplexIntImag() -= RHS.getComplexIntImag();
16794 if (Result.isComplexFloat()) {
16799 ComplexValue LHS = Result;
16800 APFloat &A = LHS.getComplexFloatReal();
16801 APFloat &B = LHS.getComplexFloatImag();
16802 APFloat &
C = RHS.getComplexFloatReal();
16803 APFloat &
D = RHS.getComplexFloatImag();
16804 APFloat &ResR = Result.getComplexFloatReal();
16805 APFloat &ResI = Result.getComplexFloatImag();
16807 assert(!RHSReal &&
"Cannot have two real operands for a complex op!");
16815 }
else if (RHSReal) {
16827 ComplexValue LHS = Result;
16828 Result.getComplexIntReal() =
16829 (LHS.getComplexIntReal() * RHS.getComplexIntReal() -
16830 LHS.getComplexIntImag() * RHS.getComplexIntImag());
16831 Result.getComplexIntImag() =
16832 (LHS.getComplexIntReal() * RHS.getComplexIntImag() +
16833 LHS.getComplexIntImag() * RHS.getComplexIntReal());
16837 if (Result.isComplexFloat()) {
16842 ComplexValue LHS = Result;
16843 APFloat &A = LHS.getComplexFloatReal();
16844 APFloat &B = LHS.getComplexFloatImag();
16845 APFloat &
C = RHS.getComplexFloatReal();
16846 APFloat &
D = RHS.getComplexFloatImag();
16847 APFloat &ResR = Result.getComplexFloatReal();
16848 APFloat &ResI = Result.getComplexFloatImag();
16860 B = APFloat::getZero(A.getSemantics());
16865 ComplexValue LHS = Result;
16866 APSInt Den = RHS.getComplexIntReal() * RHS.getComplexIntReal() +
16867 RHS.getComplexIntImag() * RHS.getComplexIntImag();
16869 return Error(
E, diag::note_expr_divide_by_zero);
16871 Result.getComplexIntReal() =
16872 (LHS.getComplexIntReal() * RHS.getComplexIntReal() +
16873 LHS.getComplexIntImag() * RHS.getComplexIntImag()) / Den;
16874 Result.getComplexIntImag() =
16875 (LHS.getComplexIntImag() * RHS.getComplexIntReal() -
16876 LHS.getComplexIntReal() * RHS.getComplexIntImag()) / Den;
16884bool ComplexExprEvaluator::VisitUnaryOperator(
const UnaryOperator *
E) {
16886 if (!Visit(
E->getSubExpr()))
16889 switch (
E->getOpcode()) {
16898 if (Result.isComplexFloat()) {
16899 Result.getComplexFloatReal().changeSign();
16900 Result.getComplexFloatImag().changeSign();
16903 Result.getComplexIntReal() = -Result.getComplexIntReal();
16904 Result.getComplexIntImag() = -Result.getComplexIntImag();
16908 if (Result.isComplexFloat())
16909 Result.getComplexFloatImag().changeSign();
16911 Result.getComplexIntImag() = -Result.getComplexIntImag();
16916bool ComplexExprEvaluator::VisitInitListExpr(
const InitListExpr *
E) {
16917 if (
E->getNumInits() == 2) {
16919 Result.makeComplexFloat();
16925 Result.makeComplexInt();
16933 return ExprEvaluatorBaseTy::VisitInitListExpr(
E);
16936bool ComplexExprEvaluator::VisitCallExpr(
const CallExpr *
E) {
16937 if (!IsConstantEvaluatedBuiltinCall(
E))
16938 return ExprEvaluatorBaseTy::VisitCallExpr(
E);
16940 switch (
E->getBuiltinCallee()) {
16941 case Builtin::BI__builtin_complex:
16942 Result.makeComplexFloat();
16960class AtomicExprEvaluator :
16961 public ExprEvaluatorBase<AtomicExprEvaluator> {
16962 const LValue *
This;
16965 AtomicExprEvaluator(EvalInfo &Info,
const LValue *
This,
APValue &Result)
16966 : ExprEvaluatorBaseTy(Info),
This(
This), Result(Result) {}
16973 bool ZeroInitialization(
const Expr *
E) {
16982 bool VisitCastExpr(
const CastExpr *
E) {
16983 switch (
E->getCastKind()) {
16985 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
16986 case CK_NullToPointer:
16987 VisitIgnoredValue(
E->getSubExpr());
16988 return ZeroInitialization(
E);
16989 case CK_NonAtomicToAtomic:
16991 :
Evaluate(Result, Info,
E->getSubExpr());
17001 return AtomicExprEvaluator(Info,
This, Result).Visit(
E);
17010class VoidExprEvaluator
17011 :
public ExprEvaluatorBase<VoidExprEvaluator> {
17013 VoidExprEvaluator(EvalInfo &Info) : ExprEvaluatorBaseTy(Info) {}
17017 bool ZeroInitialization(
const Expr *
E) {
return true; }
17019 bool VisitCastExpr(
const CastExpr *
E) {
17020 switch (
E->getCastKind()) {
17022 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
17024 VisitIgnoredValue(
E->getSubExpr());
17029 bool VisitCallExpr(
const CallExpr *
E) {
17030 if (!IsConstantEvaluatedBuiltinCall(
E))
17031 return ExprEvaluatorBaseTy::VisitCallExpr(
E);
17033 switch (
E->getBuiltinCallee()) {
17034 case Builtin::BI__assume:
17035 case Builtin::BI__builtin_assume:
17039 case Builtin::BI__builtin_operator_delete:
17051bool VoidExprEvaluator::VisitCXXDeleteExpr(
const CXXDeleteExpr *
E) {
17053 if (Info.SpeculativeEvaluationDepth)
17057 if (!OperatorDelete
17058 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
17059 Info.FFDiag(
E, diag::note_constexpr_new_non_replaceable)
17060 << isa<CXXMethodDecl>(OperatorDelete) << OperatorDelete;
17064 const Expr *Arg =
E->getArgument();
17069 if (
Pointer.Designator.Invalid)
17073 if (
Pointer.isNullPointer()) {
17077 if (!Info.getLangOpts().CPlusPlus20)
17078 Info.CCEDiag(
E, diag::note_constexpr_new);
17083 Info,
E,
Pointer,
E->isArrayForm() ? DynAlloc::ArrayNew : DynAlloc::New);
17090 if (!
E->isArrayForm() &&
Pointer.Designator.Entries.size() != 0 &&
17092 Info.FFDiag(
E, diag::note_constexpr_delete_base_nonvirt_dtor)
17099 if (!
E->isArrayForm() && !
E->isGlobalDelete()) {
17101 if (VirtualDelete &&
17103 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
17104 Info.FFDiag(
E, diag::note_constexpr_new_non_replaceable)
17105 << isa<CXXMethodDecl>(VirtualDelete) << VirtualDelete;
17111 (*Alloc)->Value, AllocType))
17119 Info.FFDiag(
E, diag::note_constexpr_double_delete);
17129 return VoidExprEvaluator(Info).Visit(
E);
17145 LV.moveInto(Result);
17150 if (!IntExprEvaluator(Info, Result).Visit(
E))
17156 LV.moveInto(Result);
17158 llvm::APFloat F(0.0);
17166 C.moveInto(Result);
17168 if (!FixedPointExprEvaluator(Info, Result).Visit(
E))
return false;
17173 P.moveInto(Result);
17178 Info.CurrentCall->createTemporary(
E,
T, ScopeKind::FullExpression, LV);
17185 Info.CurrentCall->createTemporary(
E,
T, ScopeKind::FullExpression, LV);
17190 if (!Info.getLangOpts().CPlusPlus11)
17191 Info.CCEDiag(
E, diag::note_constexpr_nonliteral)
17196 QualType Unqual =
T.getAtomicUnqualifiedType();
17200 E, Unqual, ScopeKind::FullExpression, LV);
17208 }
else if (Info.getLangOpts().CPlusPlus11) {
17209 Info.FFDiag(
E, diag::note_constexpr_nonliteral) <<
E->
getType();
17212 Info.FFDiag(
E, diag::note_invalid_subexpr_in_const_expr);
17223 const Expr *
E,
bool AllowNonLiteralTypes) {
17244 QualType Unqual =
T.getAtomicUnqualifiedType();
17265 if (Info.EnableNewConstInterp) {
17266 if (!Info.Ctx.getInterpContext().evaluateAsRValue(Info,
E, Result))
17269 ConstantExprKind::Normal);
17278 LV.setFrom(Info.Ctx, Result);
17285 ConstantExprKind::Normal) &&
17293 if (
const auto *L = dyn_cast<IntegerLiteral>(Exp)) {
17295 APValue(
APSInt(L->getValue(), L->getType()->isUnsignedIntegerType()));
17300 if (
const auto *L = dyn_cast<CXXBoolLiteralExpr>(Exp)) {
17306 if (
const auto *FL = dyn_cast<FloatingLiteral>(Exp)) {
17307 Result =
APValue(FL->getValue());
17312 if (
const auto *L = dyn_cast<CharacterLiteral>(Exp)) {
17318 if (
const auto *CE = dyn_cast<ConstantExpr>(Exp)) {
17319 if (CE->hasAPValueResult()) {
17320 APValue APV = CE->getAPValueResult();
17322 Result = std::move(APV);
17398 bool InConstantContext)
const {
17399 assert(!isValueDependent() &&
17400 "Expression evaluator can't be called on a dependent expression.");
17401 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsRValue");
17402 EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
17403 Info.InConstantContext = InConstantContext;
17404 return ::EvaluateAsRValue(
this, Result, Ctx, Info);
17408 bool InConstantContext)
const {
17409 assert(!isValueDependent() &&
17410 "Expression evaluator can't be called on a dependent expression.");
17411 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsBooleanCondition");
17419 bool InConstantContext)
const {
17420 assert(!isValueDependent() &&
17421 "Expression evaluator can't be called on a dependent expression.");
17422 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsInt");
17423 EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
17424 Info.InConstantContext = InConstantContext;
17425 return ::EvaluateAsInt(
this, Result, Ctx, AllowSideEffects, Info);
17430 bool InConstantContext)
const {
17431 assert(!isValueDependent() &&
17432 "Expression evaluator can't be called on a dependent expression.");
17433 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFixedPoint");
17434 EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
17435 Info.InConstantContext = InConstantContext;
17436 return ::EvaluateAsFixedPoint(
this, Result, Ctx, AllowSideEffects, Info);
17441 bool InConstantContext)
const {
17442 assert(!isValueDependent() &&
17443 "Expression evaluator can't be called on a dependent expression.");
17445 if (!getType()->isRealFloatingType())
17448 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFloat");
17460 bool InConstantContext)
const {
17461 assert(!isValueDependent() &&
17462 "Expression evaluator can't be called on a dependent expression.");
17464 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsLValue");
17465 EvalInfo Info(Ctx, Result, EvalInfo::EM_ConstantFold);
17466 Info.InConstantContext = InConstantContext;
17469 if (!
EvaluateLValue(
this, LV, Info) || !Info.discardCleanups() ||
17470 Result.HasSideEffects ||
17473 ConstantExprKind::Normal, CheckedTemps))
17476 LV.moveInto(Result.Val);
17483 bool IsConstantDestruction) {
17484 EvalInfo Info(Ctx, EStatus,
17485 IsConstantDestruction ? EvalInfo::EM_ConstantExpression
17486 : EvalInfo::EM_ConstantFold);
17487 Info.setEvaluatingDecl(
Base, DestroyedValue,
17488 EvalInfo::EvaluatingDeclKind::Dtor);
17489 Info.InConstantContext = IsConstantDestruction;
17498 if (!Info.discardCleanups())
17499 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
17506 assert(!isValueDependent() &&
17507 "Expression evaluator can't be called on a dependent expression.");
17510 Result.Val.hasValue())
17513 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsConstantExpr");
17514 EvalInfo::EvaluationMode EM = EvalInfo::EM_ConstantExpression;
17515 EvalInfo Info(Ctx, Result, EM);
17516 Info.InConstantContext =
true;
17518 if (Info.EnableNewConstInterp) {
17519 if (!Info.Ctx.getInterpContext().evaluate(Info,
this, Result.Val, Kind))
17522 getStorageType(Ctx,
this), Result.Val, Kind);
17527 if (Kind == ConstantExprKind::ClassTemplateArgument)
17535 Info.setEvaluatingDecl(
Base, Result.Val);
17543 FullExpressionRAII
Scope(Info);
17545 Result.HasSideEffects || !
Scope.destroy())
17548 if (!Info.discardCleanups())
17549 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
17559 if (Kind == ConstantExprKind::ClassTemplateArgument &&
17562 Result.HasSideEffects)) {
17574 bool IsConstantInitialization)
const {
17575 assert(!isValueDependent() &&
17576 "Expression evaluator can't be called on a dependent expression.");
17578 llvm::TimeTraceScope TimeScope(
"EvaluateAsInitializer", [&] {
17580 llvm::raw_string_ostream OS(Name);
17586 EStatus.
Diag = &Notes;
17588 EvalInfo Info(Ctx, EStatus,
17589 (IsConstantInitialization &&
17591 ? EvalInfo::EM_ConstantExpression
17592 : EvalInfo::EM_ConstantFold);
17593 Info.setEvaluatingDecl(VD,
Value);
17594 Info.InConstantContext = IsConstantInitialization;
17599 if (Info.EnableNewConstInterp) {
17600 auto &InterpCtx =
const_cast<ASTContext &
>(Ctx).getInterpContext();
17601 if (!InterpCtx.evaluateAsInitializer(Info, VD,
Value))
17605 ConstantExprKind::Normal);
17620 FullExpressionRAII
Scope(Info);
17623 EStatus.HasSideEffects)
17629 Info.performLifetimeExtension();
17631 if (!Info.discardCleanups())
17632 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
17636 ConstantExprKind::Normal) &&
17643 EStatus.
Diag = &Notes;
17647 bool IsConstantDestruction = hasConstantInitialization();
17653 if (getEvaluatedValue() && !getEvaluatedValue()->isAbsent())
17654 DestroyedValue = *getEvaluatedValue();
17659 getType(), getLocation(), EStatus,
17660 IsConstantDestruction) ||
17664 ensureEvaluatedStmt()->HasConstantDestruction =
true;
17671 assert(!isValueDependent() &&
17672 "Expression evaluator can't be called on a dependent expression.");
17681 assert(!isValueDependent() &&
17682 "Expression evaluator can't be called on a dependent expression.");
17684 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstInt");
17687 EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
17688 Info.InConstantContext =
true;
17692 assert(Result &&
"Could not evaluate expression");
17693 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
17695 return EVResult.Val.getInt();
17700 assert(!isValueDependent() &&
17701 "Expression evaluator can't be called on a dependent expression.");
17703 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstIntCheckOverflow");
17706 EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
17707 Info.InConstantContext =
true;
17708 Info.CheckingForUndefinedBehavior =
true;
17712 assert(Result &&
"Could not evaluate expression");
17713 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
17715 return EVResult.Val.getInt();
17719 assert(!isValueDependent() &&
17720 "Expression evaluator can't be called on a dependent expression.");
17722 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateForOverflow");
17726 EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
17727 Info.CheckingForUndefinedBehavior =
true;
17759 IK_ICEIfUnevaluated,
17775static ICEDiag
Worst(ICEDiag A, ICEDiag B) {
return A.Kind >= B.Kind ? A : B; }
17780 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
17782 Info.InConstantContext =
true;
17796#define ABSTRACT_STMT(Node)
17797#define STMT(Node, Base) case Expr::Node##Class:
17798#define EXPR(Node, Base)
17799#include "clang/AST/StmtNodes.inc"
17800 case Expr::PredefinedExprClass:
17801 case Expr::FloatingLiteralClass:
17802 case Expr::ImaginaryLiteralClass:
17803 case Expr::StringLiteralClass:
17804 case Expr::ArraySubscriptExprClass:
17805 case Expr::MatrixSubscriptExprClass:
17806 case Expr::ArraySectionExprClass:
17807 case Expr::OMPArrayShapingExprClass:
17808 case Expr::OMPIteratorExprClass:
17809 case Expr::MemberExprClass:
17810 case Expr::CompoundAssignOperatorClass:
17811 case Expr::CompoundLiteralExprClass:
17812 case Expr::ExtVectorElementExprClass:
17813 case Expr::DesignatedInitExprClass:
17814 case Expr::ArrayInitLoopExprClass:
17815 case Expr::ArrayInitIndexExprClass:
17816 case Expr::NoInitExprClass:
17817 case Expr::DesignatedInitUpdateExprClass:
17818 case Expr::ImplicitValueInitExprClass:
17819 case Expr::ParenListExprClass:
17820 case Expr::VAArgExprClass:
17821 case Expr::AddrLabelExprClass:
17822 case Expr::StmtExprClass:
17823 case Expr::CXXMemberCallExprClass:
17824 case Expr::CUDAKernelCallExprClass:
17825 case Expr::CXXAddrspaceCastExprClass:
17826 case Expr::CXXDynamicCastExprClass:
17827 case Expr::CXXTypeidExprClass:
17828 case Expr::CXXUuidofExprClass:
17829 case Expr::MSPropertyRefExprClass:
17830 case Expr::MSPropertySubscriptExprClass:
17831 case Expr::CXXNullPtrLiteralExprClass:
17832 case Expr::UserDefinedLiteralClass:
17833 case Expr::CXXThisExprClass:
17834 case Expr::CXXThrowExprClass:
17835 case Expr::CXXNewExprClass:
17836 case Expr::CXXDeleteExprClass:
17837 case Expr::CXXPseudoDestructorExprClass:
17838 case Expr::UnresolvedLookupExprClass:
17839 case Expr::RecoveryExprClass:
17840 case Expr::DependentScopeDeclRefExprClass:
17841 case Expr::CXXConstructExprClass:
17842 case Expr::CXXInheritedCtorInitExprClass:
17843 case Expr::CXXStdInitializerListExprClass:
17844 case Expr::CXXBindTemporaryExprClass:
17845 case Expr::ExprWithCleanupsClass:
17846 case Expr::CXXTemporaryObjectExprClass:
17847 case Expr::CXXUnresolvedConstructExprClass:
17848 case Expr::CXXDependentScopeMemberExprClass:
17849 case Expr::UnresolvedMemberExprClass:
17850 case Expr::ObjCStringLiteralClass:
17851 case Expr::ObjCBoxedExprClass:
17852 case Expr::ObjCArrayLiteralClass:
17853 case Expr::ObjCDictionaryLiteralClass:
17854 case Expr::ObjCEncodeExprClass:
17855 case Expr::ObjCMessageExprClass:
17856 case Expr::ObjCSelectorExprClass:
17857 case Expr::ObjCProtocolExprClass:
17858 case Expr::ObjCIvarRefExprClass:
17859 case Expr::ObjCPropertyRefExprClass:
17860 case Expr::ObjCSubscriptRefExprClass:
17861 case Expr::ObjCIsaExprClass:
17862 case Expr::ObjCAvailabilityCheckExprClass:
17863 case Expr::ShuffleVectorExprClass:
17864 case Expr::ConvertVectorExprClass:
17865 case Expr::BlockExprClass:
17866 case Expr::NoStmtClass:
17867 case Expr::OpaqueValueExprClass:
17868 case Expr::PackExpansionExprClass:
17869 case Expr::SubstNonTypeTemplateParmPackExprClass:
17870 case Expr::FunctionParmPackExprClass:
17871 case Expr::AsTypeExprClass:
17872 case Expr::ObjCIndirectCopyRestoreExprClass:
17873 case Expr::MaterializeTemporaryExprClass:
17874 case Expr::PseudoObjectExprClass:
17875 case Expr::AtomicExprClass:
17876 case Expr::LambdaExprClass:
17877 case Expr::CXXFoldExprClass:
17878 case Expr::CoawaitExprClass:
17879 case Expr::DependentCoawaitExprClass:
17880 case Expr::CoyieldExprClass:
17881 case Expr::SYCLUniqueStableNameExprClass:
17882 case Expr::CXXParenListInitExprClass:
17883 case Expr::HLSLOutArgExprClass:
17886 case Expr::InitListExprClass: {
17892 if (cast<InitListExpr>(
E)->getNumInits() == 1)
17893 return CheckICE(cast<InitListExpr>(
E)->getInit(0), Ctx);
17897 case Expr::SizeOfPackExprClass:
17898 case Expr::GNUNullExprClass:
17899 case Expr::SourceLocExprClass:
17900 case Expr::EmbedExprClass:
17901 case Expr::OpenACCAsteriskSizeExprClass:
17904 case Expr::PackIndexingExprClass:
17905 return CheckICE(cast<PackIndexingExpr>(
E)->getSelectedExpr(), Ctx);
17907 case Expr::SubstNonTypeTemplateParmExprClass:
17909 CheckICE(cast<SubstNonTypeTemplateParmExpr>(
E)->getReplacement(), Ctx);
17911 case Expr::ConstantExprClass:
17912 return CheckICE(cast<ConstantExpr>(
E)->getSubExpr(), Ctx);
17914 case Expr::ParenExprClass:
17915 return CheckICE(cast<ParenExpr>(
E)->getSubExpr(), Ctx);
17916 case Expr::GenericSelectionExprClass:
17917 return CheckICE(cast<GenericSelectionExpr>(
E)->getResultExpr(), Ctx);
17918 case Expr::IntegerLiteralClass:
17919 case Expr::FixedPointLiteralClass:
17920 case Expr::CharacterLiteralClass:
17921 case Expr::ObjCBoolLiteralExprClass:
17922 case Expr::CXXBoolLiteralExprClass:
17923 case Expr::CXXScalarValueInitExprClass:
17924 case Expr::TypeTraitExprClass:
17925 case Expr::ConceptSpecializationExprClass:
17926 case Expr::RequiresExprClass:
17927 case Expr::ArrayTypeTraitExprClass:
17928 case Expr::ExpressionTraitExprClass:
17929 case Expr::CXXNoexceptExprClass:
17931 case Expr::CallExprClass:
17932 case Expr::CXXOperatorCallExprClass: {
17936 const CallExpr *CE = cast<CallExpr>(
E);
17941 case Expr::CXXRewrittenBinaryOperatorClass:
17942 return CheckICE(cast<CXXRewrittenBinaryOperator>(
E)->getSemanticForm(),
17944 case Expr::DeclRefExprClass: {
17945 const NamedDecl *
D = cast<DeclRefExpr>(
E)->getDecl();
17946 if (isa<EnumConstantDecl>(
D))
17958 const VarDecl *VD = dyn_cast<VarDecl>(
D);
17965 case Expr::UnaryOperatorClass: {
17988 llvm_unreachable(
"invalid unary operator class");
17990 case Expr::OffsetOfExprClass: {
17999 case Expr::UnaryExprOrTypeTraitExprClass: {
18001 if ((Exp->
getKind() == UETT_SizeOf) &&
18004 if (Exp->
getKind() == UETT_CountOf) {
18011 if (VAT->getElementType()->isArrayType())
18023 case Expr::BinaryOperatorClass: {
18068 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE) {
18071 return ICEDiag(IK_ICEIfUnevaluated,
E->
getBeginLoc());
18072 if (REval.isSigned() && REval.isAllOnes()) {
18074 if (LEval.isMinSignedValue())
18075 return ICEDiag(IK_ICEIfUnevaluated,
E->
getBeginLoc());
18083 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE)
18084 return ICEDiag(IK_ICEIfUnevaluated,
E->
getBeginLoc());
18090 return Worst(LHSResult, RHSResult);
18096 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICEIfUnevaluated) {
18106 return Worst(LHSResult, RHSResult);
18109 llvm_unreachable(
"invalid binary operator kind");
18111 case Expr::ImplicitCastExprClass:
18112 case Expr::CStyleCastExprClass:
18113 case Expr::CXXFunctionalCastExprClass:
18114 case Expr::CXXStaticCastExprClass:
18115 case Expr::CXXReinterpretCastExprClass:
18116 case Expr::CXXConstCastExprClass:
18117 case Expr::ObjCBridgedCastExprClass: {
18118 const Expr *SubExpr = cast<CastExpr>(
E)->getSubExpr();
18119 if (isa<ExplicitCastExpr>(
E)) {
18124 APSInt IgnoredVal(DestWidth, !DestSigned);
18129 if (FL->getValue().convertToInteger(IgnoredVal,
18130 llvm::APFloat::rmTowardZero,
18131 &Ignored) & APFloat::opInvalidOp)
18136 switch (cast<CastExpr>(
E)->getCastKind()) {
18137 case CK_LValueToRValue:
18138 case CK_AtomicToNonAtomic:
18139 case CK_NonAtomicToAtomic:
18141 case CK_IntegralToBoolean:
18142 case CK_IntegralCast:
18148 case Expr::BinaryConditionalOperatorClass: {
18151 if (CommonResult.Kind == IK_NotICE)
return CommonResult;
18153 if (FalseResult.Kind == IK_NotICE)
return FalseResult;
18154 if (CommonResult.Kind == IK_ICEIfUnevaluated)
return CommonResult;
18155 if (FalseResult.Kind == IK_ICEIfUnevaluated &&
18157 return FalseResult;
18159 case Expr::ConditionalOperatorClass: {
18167 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
18170 if (CondResult.Kind == IK_NotICE)
18176 if (TrueResult.Kind == IK_NotICE)
18178 if (FalseResult.Kind == IK_NotICE)
18179 return FalseResult;
18180 if (CondResult.Kind == IK_ICEIfUnevaluated)
18182 if (TrueResult.Kind == IK_ICE && FalseResult.Kind == IK_ICE)
18188 return FalseResult;
18191 case Expr::CXXDefaultArgExprClass:
18192 return CheckICE(cast<CXXDefaultArgExpr>(
E)->getExpr(), Ctx);
18193 case Expr::CXXDefaultInitExprClass:
18194 return CheckICE(cast<CXXDefaultInitExpr>(
E)->getExpr(), Ctx);
18195 case Expr::ChooseExprClass: {
18196 return CheckICE(cast<ChooseExpr>(
E)->getChosenSubExpr(), Ctx);
18198 case Expr::BuiltinBitCastExprClass: {
18199 if (!checkBitCastConstexprEligibility(
nullptr, Ctx, cast<CastExpr>(
E)))
18201 return CheckICE(cast<CastExpr>(
E)->getSubExpr(), Ctx);
18205 llvm_unreachable(
"Invalid StmtClass!");
18211 llvm::APSInt *
Value) {
18219 if (!Result.isInt())
18227 assert(!isValueDependent() &&
18228 "Expression evaluator can't be called on a dependent expression.");
18230 ExprTimeTraceScope TimeScope(
this, Ctx,
"isIntegerConstantExpr");
18236 if (
D.
Kind != IK_ICE)
18241std::optional<llvm::APSInt>
18243 if (isValueDependent()) {
18245 return std::nullopt;
18252 return std::nullopt;
18255 if (!isIntegerConstantExpr(Ctx))
18256 return std::nullopt;
18264 EvalInfo Info(Ctx, Status, EvalInfo::EM_IgnoreSideEffects);
18265 Info.InConstantContext =
true;
18268 llvm_unreachable(
"ICE cannot be evaluated!");
18274 assert(!isValueDependent() &&
18275 "Expression evaluator can't be called on a dependent expression.");
18277 return CheckICE(
this, Ctx).Kind == IK_ICE;
18281 assert(!isValueDependent() &&
18282 "Expression evaluator can't be called on a dependent expression.");
18299 Status.Diag = &Diags;
18300 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
18306 Info.discardCleanups() && !Status.HasSideEffects;
18308 return IsConstExpr && Diags.empty();
18315 assert(!isValueDependent() &&
18316 "Expression evaluator can't be called on a dependent expression.");
18318 llvm::TimeTraceScope TimeScope(
"EvaluateWithSubstitution", [&] {
18320 llvm::raw_string_ostream OS(Name);
18327 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpressionUnevaluated);
18328 Info.InConstantContext =
true;
18331 const LValue *ThisPtr =
nullptr;
18334 auto *MD = dyn_cast<CXXMethodDecl>(Callee);
18335 assert(MD &&
"Don't provide `this` for non-methods.");
18336 assert(MD->isImplicitObjectMemberFunction() &&
18337 "Don't provide `this` for methods without an implicit object.");
18339 if (!
This->isValueDependent() &&
18341 !Info.EvalStatus.HasSideEffects)
18342 ThisPtr = &ThisVal;
18346 Info.EvalStatus.HasSideEffects =
false;
18349 CallRef
Call = Info.CurrentCall->createCall(Callee);
18352 unsigned Idx = I - Args.begin();
18353 if (Idx >= Callee->getNumParams())
18355 const ParmVarDecl *PVD = Callee->getParamDecl(Idx);
18356 if ((*I)->isValueDependent() ||
18358 Info.EvalStatus.HasSideEffects) {
18360 if (
APValue *Slot = Info.getParamSlot(
Call, PVD))
18366 Info.EvalStatus.HasSideEffects =
false;
18371 Info.discardCleanups();
18372 Info.EvalStatus.HasSideEffects =
false;
18375 CallStackFrame Frame(Info, Callee->getLocation(), Callee, ThisPtr,
This,
18378 FullExpressionRAII
Scope(Info);
18380 !Info.EvalStatus.HasSideEffects;
18392 llvm::TimeTraceScope TimeScope(
"isPotentialConstantExpr", [&] {
18394 llvm::raw_string_ostream OS(Name);
18401 Status.Diag = &Diags;
18403 EvalInfo Info(FD->
getASTContext(), Status, EvalInfo::EM_ConstantExpression);
18404 Info.InConstantContext =
true;
18405 Info.CheckingPotentialConstantExpression =
true;
18408 if (Info.EnableNewConstInterp) {
18409 Info.Ctx.getInterpContext().isPotentialConstantExpr(Info, FD);
18410 return Diags.empty();
18421 This.set({&VIE, Info.CurrentCall->Index});
18429 Info.setEvaluatingDecl(
This.getLValueBase(), Scratch);
18435 &VIE, Args, CallRef(), FD->
getBody(), Info, Scratch,
18439 return Diags.empty();
18447 "Expression evaluator can't be called on a dependent expression.");
18450 Status.Diag = &Diags;
18453 EvalInfo::EM_ConstantExpressionUnevaluated);
18454 Info.InConstantContext =
true;
18455 Info.CheckingPotentialConstantExpression =
true;
18457 if (Info.EnableNewConstInterp) {
18458 Info.Ctx.getInterpContext().isPotentialConstantExprUnevaluated(Info,
E, FD);
18459 return Diags.empty();
18464 nullptr, CallRef());
18468 return Diags.empty();
18472 unsigned Type)
const {
18473 if (!getType()->isPointerType())
18477 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantFold);
18482 EvalInfo &Info, std::string *StringResult) {
18494 if (
const StringLiteral *S = dyn_cast_or_null<StringLiteral>(
18495 String.getLValueBase().dyn_cast<
const Expr *>())) {
18496 StringRef Str = S->getBytes();
18497 int64_t Off = String.Offset.getQuantity();
18498 if (Off >= 0 && (uint64_t)Off <= (uint64_t)Str.size() &&
18499 S->getCharByteWidth() == 1 &&
18501 Info.Ctx.hasSameUnqualifiedType(CharTy, Info.Ctx.CharTy)) {
18502 Str = Str.substr(Off);
18504 StringRef::size_type Pos = Str.find(0);
18505 if (Pos != StringRef::npos)
18506 Str = Str.substr(0, Pos);
18508 Result = Str.size();
18510 *StringResult = Str;
18518 for (uint64_t Strlen = 0; ; ++Strlen) {
18526 }
else if (StringResult)
18527 StringResult->push_back(Char.
getInt().getExtValue());
18535 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantFold);
18537 std::string StringResult;
18540 return StringResult;
18544template <
typename T>
18546 const Expr *SizeExpression,
18547 const Expr *PtrExpression,
18550 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
18551 Info.InConstantContext =
true;
18553 if (Info.EnableNewConstInterp)
18554 return Info.Ctx.getInterpContext().evaluateCharRange(Info, SizeExpression,
18555 PtrExpression, Result);
18558 FullExpressionRAII
Scope(Info);
18563 uint64_t Size = SizeValue.getZExtValue();
18566 if constexpr (std::is_same_v<APValue, T>)
18569 if (Size < Result.max_size())
18570 Result.reserve(Size);
18576 for (uint64_t I = 0; I < Size; ++I) {
18582 if constexpr (std::is_same_v<APValue, T>) {
18583 Result.getArrayInitializedElt(I) = std::move(Char);
18587 assert(
C.getBitWidth() <= 8 &&
18588 "string element not representable in char");
18590 Result.push_back(
static_cast<char>(
C.getExtValue()));
18601 const Expr *SizeExpression,
18605 PtrExpression, Ctx, Status);
18609 const Expr *SizeExpression,
18613 PtrExpression, Ctx, Status);
18618 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantFold);
18620 if (Info.EnableNewConstInterp)
18621 return Info.Ctx.getInterpContext().evaluateStrlen(Info,
this, Result);
18627struct IsWithinLifetimeHandler {
18629 static constexpr AccessKinds AccessKind = AccessKinds::AK_IsWithinLifetime;
18630 using result_type = std::optional<bool>;
18631 std::optional<bool> failed() {
return std::nullopt; }
18632 template <
typename T>
18633 std::optional<bool> found(
T &Subobj,
QualType SubobjType) {
18638std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &IEE,
18640 EvalInfo &Info = IEE.Info;
18645 if (!Info.InConstantContext)
18646 return std::nullopt;
18647 assert(
E->getBuiltinCallee() == Builtin::BI__builtin_is_within_lifetime);
18648 const Expr *Arg =
E->getArg(0);
18650 return std::nullopt;
18653 return std::nullopt;
18655 if (Val.allowConstexprUnknown())
18659 bool CalledFromStd =
false;
18660 const auto *
Callee = Info.CurrentCall->getCallee();
18661 if (Callee &&
Callee->isInStdNamespace()) {
18665 Info.CCEDiag(CalledFromStd ? Info.CurrentCall->getCallRange().getBegin()
18667 diag::err_invalid_is_within_lifetime)
18668 << (CalledFromStd ?
"std::is_within_lifetime"
18669 :
"__builtin_is_within_lifetime")
18671 return std::nullopt;
18681 if (Val.isNullPointer() || Val.getLValueBase().isNull())
18683 QualType T = Val.getLValueBase().getType();
18685 "Pointers to functions should have been typed as function pointers "
18686 "which would have been rejected earlier");
18689 if (Val.getLValueDesignator().isOnePastTheEnd())
18691 assert(Val.getLValueDesignator().isValidSubobject() &&
18692 "Unchecked case for valid subobject");
18696 CompleteObject CO =
18700 if (Info.EvaluatingDeclValue && CO.Value == Info.EvaluatingDeclValue)
18705 IsWithinLifetimeHandler handler{Info};
18706 return findSubobject(Info,
E, CO, Val.getLValueDesignator(), handler);
Defines the clang::ASTContext interface.
This file provides some common utility functions for processing Lambda related AST Constructs.
Defines enum values for all the target-independent builtin functions.
static Address castToBase(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy, Address OriginalBaseAddress, llvm::Value *Addr)
enum clang::sema::@1840::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 EvaluateCharRangeAsStringImpl(const Expr *, T &Result, const Expr *SizeExpression, const Expr *PtrExpression, ASTContext &Ctx, Expr::EvalResult &Status)
static bool EvaluateBuiltinStrLen(const Expr *E, uint64_t &Result, EvalInfo &Info, std::string *StringResult=nullptr)
static bool isValidIndeterminateAccess(AccessKinds AK)
Is this kind of access valid on an indeterminate object value?
static bool EvaluateMemberPointer(const Expr *E, MemberPtr &Result, EvalInfo &Info)
static bool hasUnacceptableSideEffect(Expr::EvalStatus &Result, Expr::SideEffectsKind SEK)
static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E, AccessKinds AK, const LValue &LVal, QualType LValType)
Find the complete object to which an LValue refers.
static bool evaluateLValueAsAllocSize(EvalInfo &Info, APValue::LValueBase Base, LValue &Result)
Attempts to evaluate the given LValueBase as the result of a call to a function with the alloc_size a...
static const CXXMethodDecl * HandleVirtualDispatch(EvalInfo &Info, const Expr *E, LValue &This, const CXXMethodDecl *Found, llvm::SmallVectorImpl< QualType > &CovariantAdjustmentPath)
Perform virtual dispatch.
static bool EvaluateVarDecl(EvalInfo &Info, const VarDecl *VD)
static bool CheckEvaluationResult(CheckEvaluationResultKind CERK, EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value, ConstantExprKind Kind, const FieldDecl *SubobjectDecl, CheckedTemporaries &CheckedTemps)
static bool HandleLValueComplexElement(EvalInfo &Info, const Expr *E, LValue &LVal, QualType EltTy, bool Imag)
Update an lvalue to refer to a component of a complex number.
static bool HandleSizeof(EvalInfo &Info, SourceLocation Loc, QualType Type, CharUnits &Size, SizeOfType SOT=SizeOfType::SizeOf)
Get the size of the given type in char units.
static bool HandleConstructorCall(const Expr *E, const LValue &This, CallRef Call, const CXXConstructorDecl *Definition, EvalInfo &Info, APValue &Result)
Evaluate a constructor call.
static 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 llvm::APInt ConvertBoolVectorToInt(const APValue &Val)
static bool isBaseClassPublic(const CXXRecordDecl *Derived, const CXXRecordDecl *Base)
Determine whether Base, which is known to be a direct base class of Derived, is a public base class.
static bool hasVirtualDestructor(QualType T)
static bool HandleOverflow(EvalInfo &Info, const Expr *E, const T &SrcValue, QualType DestType)
static CharUnits getBaseAlignment(EvalInfo &Info, const LValue &Value)
static bool HandleLValueIndirectMember(EvalInfo &Info, const Expr *E, LValue &LVal, const IndirectFieldDecl *IFD)
Update LVal to refer to the given indirect field.
static ICEDiag Worst(ICEDiag A, ICEDiag B)
static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E, const VarDecl *VD, CallStackFrame *Frame, unsigned Version, APValue *&Result)
Try to evaluate the initializer for a variable declaration.
static bool handleDefaultInitValue(QualType T, APValue &Result)
Get the value to use for a default-initialized object of type T.
static bool HandleLValueVectorElement(EvalInfo &Info, const Expr *E, LValue &LVal, QualType EltTy, uint64_t Size, uint64_t Idx)
static void NoteLValueLocation(EvalInfo &Info, APValue::LValueBase Base)
static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc, QualType Type, const LValue &LVal, ConstantExprKind Kind, CheckedTemporaries &CheckedTemps)
Check that this reference or pointer core constant expression is a valid value for an address or refe...
static bool CheckedIntArithmetic(EvalInfo &Info, const Expr *E, const APSInt &LHS, const APSInt &RHS, unsigned BitWidth, Operation Op, APSInt &Result)
Perform the given integer operation, which is known to need at most BitWidth bits,...
static bool EvaluateTemporary(const Expr *E, LValue &Result, EvalInfo &Info)
Evaluate an expression of record type as a temporary.
static bool EvaluateArray(const Expr *E, const LValue &This, APValue &Result, EvalInfo &Info)
static bool truncateBitfieldValue(EvalInfo &Info, const Expr *E, APValue &Value, const FieldDecl *FD)
static bool handleVectorShuffle(EvalInfo &Info, const ShuffleVectorExpr *E, QualType ElemType, APValue const &VecVal1, APValue const &VecVal2, unsigned EltNum, APValue &Result)
static bool handleVectorElementCast(EvalInfo &Info, const FPOptions FPO, const Expr *E, QualType SourceTy, QualType DestTy, APValue const &Original, APValue &Result)
static const ValueDecl * HandleMemberPointerAccess(EvalInfo &Info, QualType LVType, LValue &LV, const Expr *RHS, bool IncludeMember=true)
HandleMemberPointerAccess - Evaluate a member access operation and build an lvalue referring to the r...
static bool HandleBaseToDerivedCast(EvalInfo &Info, const CastExpr *E, LValue &Result)
HandleBaseToDerivedCast - Apply the given base-to-derived cast operation on the provided lvalue,...
static bool EvaluateFloat(const Expr *E, APFloat &Result, EvalInfo &Info)
static bool IsOpaqueConstantCall(const CallExpr *E)
Should this call expression be treated as forming an opaque constant?
static bool CheckMemberPointerConstantExpression(EvalInfo &Info, SourceLocation Loc, QualType Type, const APValue &Value, ConstantExprKind Kind)
Member pointers are constant expressions unless they point to a non-virtual dllimport member function...
static bool EvaluateAsInt(const Expr *E, Expr::EvalResult &ExprResult, const ASTContext &Ctx, Expr::SideEffectsKind AllowSideEffects, EvalInfo &Info)
static bool handleLValueToRValueConversion(EvalInfo &Info, const Expr *Conv, QualType Type, const LValue &LVal, APValue &RVal, bool WantObjectRepresentation=false)
Perform an lvalue-to-rvalue conversion on the given glvalue.
static bool refersToCompleteObject(const LValue &LVal)
Tests to see if the LValue has a user-specified designator (that isn't necessarily valid).
static bool AreElementsOfSameArray(QualType ObjType, const SubobjectDesignator &A, const SubobjectDesignator &B)
Determine whether the given subobject designators refer to elements of the same array object.
static bool EvaluateDecompositionDeclInit(EvalInfo &Info, const DecompositionDecl *DD)
static bool IsWeakLValue(const LValue &Value)
static bool EvaluateArrayNewConstructExpr(EvalInfo &Info, LValue &This, APValue &Result, const CXXConstructExpr *CCE, QualType AllocType)
static bool EvaluateRecord(const Expr *E, const LValue &This, APValue &Result, EvalInfo &Info)
static bool handleAssignment(EvalInfo &Info, const Expr *E, const LValue &LVal, QualType LValType, APValue &Val)
Perform an assignment of Val to LVal. Takes ownership of Val.
static bool CastToDerivedClass(EvalInfo &Info, const Expr *E, LValue &Result, const RecordDecl *TruncatedType, unsigned TruncatedElements)
Cast an lvalue referring to a base subobject to a derived class, by truncating the lvalue's path to t...
static bool EvaluateIgnoredValue(EvalInfo &Info, const Expr *E)
Evaluate an expression to see if it had side-effects, and discard its result.
static void addFlexibleArrayMemberInitSize(EvalInfo &Info, const QualType &T, const LValue &LV, CharUnits &Size)
If we're evaluating the object size of an instance of a struct that contains a flexible array member,...
static bool HandleLValueBasePath(EvalInfo &Info, const CastExpr *E, QualType Type, LValue &Result)
static QualType getSubobjectType(QualType ObjType, QualType SubobjType, bool IsMutable=false)
static bool EvaluateFixedPointOrInteger(const Expr *E, APFixedPoint &Result, EvalInfo &Info)
Evaluate an integer or fixed point expression into an APResult.
static bool HandleIntToFloatCast(EvalInfo &Info, const Expr *E, const FPOptions FPO, QualType SrcType, const APSInt &Value, QualType DestType, APFloat &Result)
static const CXXRecordDecl * getBaseClassType(SubobjectDesignator &Designator, unsigned PathLength)
static bool CastToBaseClass(EvalInfo &Info, const Expr *E, LValue &Result, const CXXRecordDecl *DerivedRD, const CXXRecordDecl *BaseRD)
Cast an lvalue referring to a derived class to a known base subobject.
static bool HandleLValueBase(EvalInfo &Info, const Expr *E, LValue &Obj, const CXXRecordDecl *DerivedDecl, const CXXBaseSpecifier *Base)
static bool HandleConversionToBool(const APValue &Val, bool &Result)
CharUnits GetAlignOfExpr(const ASTContext &Ctx, const Expr *E, UnaryExprOrTypeTrait ExprKind)
static bool isModification(AccessKinds AK)
static bool handleCompareOpForVector(const APValue &LHSValue, BinaryOperatorKind Opcode, const APValue &RHSValue, APInt &Result)
static bool MaybeElementDependentArrayFiller(const Expr *FillerExpr)
static bool EvaluateObjectArgument(EvalInfo &Info, const Expr *Object, LValue &This)
Build an lvalue for the object argument of a member function call.
static bool CheckLiteralType(EvalInfo &Info, const Expr *E, const LValue *This=nullptr)
Check that this core constant expression is of literal type, and if not, produce an appropriate diagn...
static bool EvaluateInteger(const Expr *E, APSInt &Result, EvalInfo &Info)
CheckEvaluationResultKind
static bool isZeroSized(const LValue &Value)
static APSInt extractStringLiteralCharacter(EvalInfo &Info, const Expr *Lit, uint64_t Index)
Extract the value of a character from a string literal.
static bool modifySubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, const SubobjectDesignator &Sub, APValue &NewVal)
Update the designated sub-object of an rvalue to the given value.
static bool EvaluateCPlusPlus11IntegralConstantExpr(const ASTContext &Ctx, const Expr *E, llvm::APSInt *Value)
Evaluate an expression as a C++11 integral constant expression.
static CharUnits GetAlignOfType(const ASTContext &Ctx, QualType T, UnaryExprOrTypeTrait ExprKind)
static bool getBuiltinAlignArguments(const CallExpr *E, EvalInfo &Info, APValue &Val, APSInt &Alignment)
static bool HandleLValueArrayAdjustment(EvalInfo &Info, const Expr *E, LValue &LVal, QualType EltTy, APSInt Adjustment)
Update a pointer value to model pointer arithmetic.
static bool extractSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, const SubobjectDesignator &Sub, APValue &Result, AccessKinds AK=AK_Read)
Extract the designated sub-object of an rvalue.
static bool HandleLValueMember(EvalInfo &Info, const Expr *E, LValue &LVal, const FieldDecl *FD, const ASTRecordLayout *RL=nullptr)
Update LVal to refer to the given field, which must be a member of the type currently described by LV...
static void addOrSubLValueAsInteger(APValue &LVal, const APSInt &Index, bool IsSub)
static bool IsDeclSourceLocationCurrent(const FunctionDecl *FD)
void HandleComplexComplexDiv(APFloat A, APFloat B, APFloat C, APFloat D, APFloat &ResR, APFloat &ResI)
static bool handleTrivialCopy(EvalInfo &Info, const ParmVarDecl *Param, const Expr *E, APValue &Result, bool CopyObjectRepresentation)
Perform a trivial copy from Param, which is the parameter of a copy or move constructor or assignment...
static bool checkFloatingPointResult(EvalInfo &Info, const Expr *E, APFloat::opStatus St)
Check if the given evaluation result is allowed for constant evaluation.
static bool EvaluateBuiltinConstantPForLValue(const APValue &LV)
EvaluateBuiltinConstantPForLValue - Determine the result of __builtin_constant_p when applied to the ...
static bool EvaluateBuiltinConstantP(EvalInfo &Info, const Expr *Arg)
EvaluateBuiltinConstantP - Evaluate __builtin_constant_p as similarly to GCC as we can manage.
static bool checkNonVirtualMemberCallThisPointer(EvalInfo &Info, const Expr *E, const LValue &This, const CXXMethodDecl *NamedMember)
Check that the pointee of the 'this' pointer in a member function call is either within its lifetime ...
static bool CheckConstantExpression(EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value, ConstantExprKind Kind)
Check that this core constant expression value is a valid value for a constant expression.
static bool EvaluateAsBooleanCondition(const Expr *E, bool &Result, EvalInfo &Info)
static std::optional< DynamicType > ComputeDynamicType(EvalInfo &Info, const Expr *E, LValue &This, AccessKinds AK)
Determine the dynamic type of an object.
static bool EvaluateDecl(EvalInfo &Info, const Decl *D, bool EvaluateConditionDecl=false)
static void expandArray(APValue &Array, unsigned Index)
static bool handleLogicalOpForVector(const APInt &LHSValue, BinaryOperatorKind Opcode, const APInt &RHSValue, APInt &Result)
static unsigned FindDesignatorMismatch(QualType ObjType, const SubobjectDesignator &A, const SubobjectDesignator &B, bool &WasArrayIndex)
Find the position where two subobject designators diverge, or equivalently the length of the common i...
static bool isOnePastTheEndOfCompleteObject(const ASTContext &Ctx, const LValue &LV)
Determine whether this is a pointer past the end of the complete object referred to by the lvalue.
static unsigned getBaseIndex(const CXXRecordDecl *Derived, const CXXRecordDecl *Base)
Get the base index of the given base class within an APValue representing the given derived class.
static bool EvaluateFixedPoint(const Expr *E, APFixedPoint &Result, EvalInfo &Info)
Evaluate only a fixed point expression into an APResult.
void HandleComplexComplexMul(APFloat A, APFloat B, APFloat C, APFloat D, APFloat &ResR, APFloat &ResI)
static bool tryEvaluateBuiltinObjectSize(const Expr *E, unsigned Type, EvalInfo &Info, uint64_t &Size)
Tries to evaluate the __builtin_object_size for E.
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 FastEvaluateAsRValue(const Expr *Exp, APValue &Result, const ASTContext &Ctx, bool &IsConst)
static bool HandleCovariantReturnAdjustment(EvalInfo &Info, const Expr *E, APValue &Result, ArrayRef< QualType > Path)
Perform the adjustment from a value returned by a virtual function to a value of the statically expec...
static EvalStmtResult EvaluateSwitch(StmtResult &Result, EvalInfo &Info, const SwitchStmt *SS)
Evaluate a switch statement.
static void expandStringLiteral(EvalInfo &Info, const StringLiteral *S, APValue &Result, QualType AllocType=QualType())
static bool EvaluateArgs(ArrayRef< const Expr * > Args, CallRef Call, EvalInfo &Info, const FunctionDecl *Callee, bool RightToLeft=false, LValue *ObjectArg=nullptr)
Evaluate the arguments to a function call.
static bool EvaluateAtomic(const Expr *E, const LValue *This, APValue &Result, EvalInfo &Info)
static bool getBytesReturnedByAllocSizeCall(const ASTContext &Ctx, const LValue &LVal, llvm::APInt &Result)
Convenience function.
static bool handleIntIntBinOp(EvalInfo &Info, const BinaryOperator *E, const APSInt &LHS, BinaryOperatorKind Opcode, APSInt RHS, APSInt &Result)
Perform the given binary integer operation.
static bool EvaluateInitForDeclOfReferenceType(EvalInfo &Info, const ValueDecl *D, const Expr *Init, LValue &Result, APValue &Val)
Evaluates the initializer of a reference.
static bool checkDynamicType(EvalInfo &Info, const Expr *E, const LValue &This, AccessKinds AK, bool Polymorphic)
Check that we can access the notional vptr of an object / determine its dynamic type.
static bool HandleFloatToIntCast(EvalInfo &Info, const Expr *E, QualType SrcType, const APFloat &Value, QualType DestType, APSInt &Result)
static bool getAlignmentArgument(const Expr *E, QualType ForType, EvalInfo &Info, APSInt &Alignment)
Evaluate the value of the alignment argument to __builtin_align_{up,down}, __builtin_is_aligned and _...
static bool CheckFullyInitialized(EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value)
Check that this evaluated value is fully-initialized and can be loaded by an lvalue-to-rvalue convers...
static SubobjectHandler::result_type findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, const SubobjectDesignator &Sub, SubobjectHandler &handler)
Find the designated sub-object of an rvalue.
static bool determineEndOffset(EvalInfo &Info, SourceLocation ExprLoc, unsigned Type, const LValue &LVal, CharUnits &EndOffset)
Helper for tryEvaluateBuiltinObjectSize – Given an LValue, this will determine how many bytes exist f...
static bool convertUnsignedAPIntToCharUnits(const llvm::APInt &Int, CharUnits &Result)
Converts the given APInt to CharUnits, assuming the APInt is unsigned.
static bool EvaluateCallArg(const ParmVarDecl *PVD, const Expr *Arg, CallRef Call, EvalInfo &Info, bool NonNull=false, APValue **EvaluatedArg=nullptr)
GCCTypeClass EvaluateBuiltinClassifyType(QualType T, const LangOptions &LangOpts)
EvaluateBuiltinClassifyType - Evaluate __builtin_classify_type the same way as GCC.
static bool EvaluateDependentExpr(const Expr *E, EvalInfo &Info)
static bool MaybeEvaluateDeferredVarDeclInit(EvalInfo &Info, const VarDecl *VD)
static APSInt HandleIntToIntCast(EvalInfo &Info, const Expr *E, QualType DestType, QualType SrcType, const APSInt &Value)
static std::optional< APValue > handleVectorUnaryOperator(ASTContext &Ctx, QualType ResultTy, UnaryOperatorKind Op, APValue Elt)
static bool lifetimeStartedInEvaluation(EvalInfo &Info, APValue::LValueBase Base, bool MutableSubobject=false)
static bool isOneByteCharacterType(QualType T)
static bool HandleLambdaCapture(EvalInfo &Info, const Expr *E, LValue &Result, const CXXMethodDecl *MD, const FieldDecl *FD, bool LValueToRValueConversion)
Get an lvalue to a field of a lambda's closure type.
static bool EvaluateCond(EvalInfo &Info, const VarDecl *CondDecl, const Expr *Cond, bool &Result)
Evaluate a condition (either a variable declaration or an expression).
static bool EvaluateAsFixedPoint(const Expr *E, Expr::EvalResult &ExprResult, const ASTContext &Ctx, Expr::SideEffectsKind AllowSideEffects, EvalInfo &Info)
static bool EvaluateAsRValue(EvalInfo &Info, const Expr *E, APValue &Result)
EvaluateAsRValue - Try to evaluate this expression, performing an implicit lvalue-to-rvalue cast if i...
static bool diagnoseMutableFields(EvalInfo &Info, const Expr *E, AccessKinds AK, QualType T)
Diagnose an attempt to read from any unreadable field within the specified type, which might be a cla...
static ICEDiag CheckICE(const Expr *E, const ASTContext &Ctx)
static bool CheckConstexprFunction(EvalInfo &Info, SourceLocation CallLoc, const FunctionDecl *Declaration, const FunctionDecl *Definition, const Stmt *Body)
CheckConstexprFunction - Check that a function can be called in a constant expression.
static bool EvaluateDestruction(const ASTContext &Ctx, APValue::LValueBase Base, APValue DestroyedValue, QualType Type, SourceLocation Loc, Expr::EvalStatus &EStatus, bool IsConstantDestruction)
static EvalStmtResult EvaluateStmt(StmtResult &Result, EvalInfo &Info, const Stmt *S, const SwitchCase *SC=nullptr)
static bool EvaluateArrayNewInitList(EvalInfo &Info, LValue &This, APValue &Result, const InitListExpr *ILE, QualType AllocType)
static bool HasSameBase(const LValue &A, const LValue &B)
static bool CheckLocalVariableDeclaration(EvalInfo &Info, const VarDecl *VD)
static bool HandleLValueDirectBase(EvalInfo &Info, const Expr *E, LValue &Obj, const CXXRecordDecl *Derived, const CXXRecordDecl *Base, const ASTRecordLayout *RL=nullptr)
static bool IsGlobalLValue(APValue::LValueBase B)
static llvm::RoundingMode getActiveRoundingMode(EvalInfo &Info, const Expr *E)
Get rounding mode to use in evaluation of the specified expression.
static QualType getObjectType(APValue::LValueBase B)
Retrieves the "underlying object type" of the given expression, as used by __builtin_object_size.
static bool handleCompareOpForVectorHelper(const APTy &LHSValue, BinaryOperatorKind Opcode, const APTy &RHSValue, APInt &Result)
static bool Evaluate(APValue &Result, EvalInfo &Info, const Expr *E)
static bool isReadByLvalueToRvalueConversion(const CXXRecordDecl *RD)
Determine whether a type would actually be read by an lvalue-to-rvalue conversion.
static void negateAsSigned(APSInt &Int)
Negate an APSInt in place, converting it to a signed form if necessary, and preserving its value (by ...
static bool HandleFunctionCall(SourceLocation CallLoc, const FunctionDecl *Callee, const LValue *ObjectArg, const Expr *E, ArrayRef< const Expr * > Args, CallRef Call, const Stmt *Body, EvalInfo &Info, APValue &Result, const LValue *ResultSlot)
Evaluate a function call.
static bool isUserWritingOffTheEnd(const ASTContext &Ctx, const LValue &LVal)
Attempts to detect a user writing into a piece of memory that's impossible to figure out the size of ...
static bool GetLValueBaseAsString(const EvalInfo &Info, const LValue &LVal, LValueBaseString &AsString)
static bool HandleOperatorDeleteCall(EvalInfo &Info, const CallExpr *E)
static bool EvaluateIntegerOrLValue(const Expr *E, APValue &Result, EvalInfo &Info)
EvaluateIntegerOrLValue - Evaluate an rvalue integral-typed expression, and produce either the intege...
static bool HandleDynamicCast(EvalInfo &Info, const ExplicitCastExpr *E, LValue &Ptr)
Apply the given dynamic cast operation on the provided lvalue.
static bool HandleOperatorNewCall(EvalInfo &Info, const CallExpr *E, LValue &Result)
Perform a call to 'operator new' or to ‘__builtin_operator_new’.
static bool HandleFloatToFloatCast(EvalInfo &Info, const Expr *E, QualType SrcType, QualType DestType, APFloat &Result)
static bool MaybeHandleUnionActiveMemberChange(EvalInfo &Info, const Expr *LHSExpr, const LValue &LHS)
Handle a builtin simple-assignment or a call to a trivial assignment operator whose left-hand side mi...
static bool isFormalAccess(AccessKinds AK)
Is this an access per the C++ definition?
static bool handleCompoundAssignment(EvalInfo &Info, const CompoundAssignOperator *E, const LValue &LVal, QualType LValType, QualType PromotedLValType, BinaryOperatorKind Opcode, const APValue &RVal)
Perform a compound assignment of LVal <op>= RVal.
static bool handleIncDec(EvalInfo &Info, const Expr *E, const LValue &LVal, QualType LValType, bool IsIncrement, APValue *Old)
Perform an increment or decrement on LVal.
static bool EvaluateVoid(const Expr *E, EvalInfo &Info)
static bool HandleDestruction(EvalInfo &Info, const Expr *E, const LValue &This, QualType ThisType)
Perform a destructor or pseudo-destructor call on the given object, which might in general not be a c...
static bool HandleDestructionImpl(EvalInfo &Info, SourceRange CallRange, const LValue &This, APValue &Value, QualType T)
static bool ArePotentiallyOverlappingStringLiterals(const EvalInfo &Info, const LValue &LHS, const LValue &RHS)
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
llvm::MachO::Record Record
Implements a partial diagnostic which may not be emitted.
llvm::DenseMap< Stmt *, Stmt * > MapTy
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
static QualType getPointeeType(const MemRegion *R)
Enumerates target-specific builtins in their own namespaces within namespace clang.
Defines the clang::TypeLoc interface and its subclasses.
C Language Family Type Representation.
__DEVICE__ long long abs(long long __n)
a trap message and trap category.
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
bool allowConstexprUnknown() const
std::string getAsString(const ASTContext &Ctx, QualType Ty) const
bool isFixedPoint() const
@ Indeterminate
This object has an indeterminate value (C++ [basic.indet]).
@ None
There is no such object (it's outside its lifetime).
APSInt & getComplexIntReal()
APFloat & getComplexFloatImag()
APFloat & getComplexFloatReal()
APValue & getStructBase(unsigned i)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
SourceManager & getSourceManager()
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
unsigned getIntWidth(QualType T) const
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
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,...
unsigned getPreferredTypeAlign(QualType T) const
Return the "preferred" alignment of the specified type T for the current target, in bits.
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<=>,...
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
const clang::PrintingPolicy & getPrintingPolicy() const
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
llvm::APSInt MakeIntValue(uint64_t Value, QualType Type) const
Make an APSInt of the appropriate width and signedness for the given Value and integer Type.
const VariableArrayType * getAsVariableArrayType(QualType T) const
const TargetInfo & getTargetInfo() const
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
CanQualType getCanonicalTagType(const TagDecl *TD) const
uint64_t getCharWidth() const
Return the size of the character type, in bits.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
unsigned getFieldCount() const
getFieldCount - Get the number of fields in the layout.
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - Get the offset, in chars, for the given base class.
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...
QualType getFunctionObjectParameterReferenceType() const
Return the type of the object pointed by this.
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
bool isMoveAssignmentOperator() const
Determine whether this is a move assignment operator.
bool isCopyAssignmentOperator() const
Determine whether this is a copy-assignment operator, regardless of whether it was declared implicitl...
bool isLambdaStaticInvoker() const
Determine whether this is a lambda closure type's static member function that is used for the result ...
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)
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()
capture_const_range captures() const
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
CXXMethodDecl * getLambdaCallOperator() const
Retrieve the lambda call operator of the closure type if this is a closure type.
CXXRecordDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
bool isDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is derived from the class Base.
A C++ reinterpret_cast expression (C++ [expr.reinterpret.cast]).
A rewritten comparison expression that was originally written using operator syntax.
An expression "T()" which creates an rvalue of a non-class type T.
Implicit construction of a std::initializer_list<T> object from an array temporary within list-initia...
Represents the this expression in C++.
A C++ typeid expression (C++ [expr.typeid]), which gets the type_info that corresponds to the supplie...
A Microsoft C++ __uuidof expression, which gets the _GUID that corresponds to the supplied type or ex...
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
unsigned getBuiltinCallee() const
getBuiltinCallee - If this is a call to a builtin, return the builtin ID of the callee.
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
bool isAnyOperatorNew() const
A decomposition declaration.
auto flat_bindings() const
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.
EnumDecl * getDefinitionOrSelf() const
QualType getIntegerType() const
Return the integer type this enum decl corresponds to.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
EnumDecl * getOriginalDecl() 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...
bool isIntegerConstantExpr(const ASTContext &Ctx) const
static bool isPotentialConstantExprUnevaluated(Expr *E, const FunctionDecl *FD, SmallVectorImpl< PartialDiagnosticAt > &Diags)
isPotentialConstantExprUnevaluated - Return true if this expression might be usable in a constant exp...
@ SE_AllowSideEffects
Allow any unmodeled side effect.
@ SE_AllowUndefinedBehavior
Allow UB that we can give a value, but not arbitrary unmodeled side effects.
bool isCXX11ConstantExpr(const ASTContext &Ctx, APValue *Result=nullptr) const
isCXX11ConstantExpr - Return true if this expression is a constant expression in C++11.
bool EvaluateCharRangeAsString(std::string &Result, const Expr *SizeExpression, const Expr *PtrExpression, ASTContext &Ctx, EvalResult &Status) const
llvm::APSInt EvaluateKnownConstIntCheckOverflow(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
bool isValueDependent() const
Determines whether the value of this expression depends on.
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.
bool EvaluateAsFloat(llvm::APFloat &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsFloat - Return true if this is a constant which we can fold and convert to a floating point...
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsLValue - Evaluate an expression to see if we can fold it to an lvalue with link time known ...
bool EvaluateAsFixedPoint(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsFixedPoint - Return true if this is a constant which we can fold and convert to a fixed poi...
bool isEvaluatable(const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
isEvaluatable - Call EvaluateAsRValue to see if this expression can be constant folded without side-e...
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language.
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...
bool HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects=true) const
HasSideEffects - This routine returns true for all those expressions which have any effect other than...
bool EvaluateAsConstantExpr(EvalResult &Result, const ASTContext &Ctx, ConstantExprKind Kind=ConstantExprKind::Normal) const
Evaluate an expression that is required to be a constant expression.
std::optional< std::string > tryEvaluateString(ASTContext &Ctx) const
If the current Expr can be evaluated to a pointer to a null-terminated constant string,...
bool EvaluateAsBooleanCondition(bool &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsBooleanCondition - Return true if this is a constant which we can fold and convert to a boo...
bool isTemporaryObject(ASTContext &Ctx, const CXXRecordDecl *TempTy) const
Determine whether the result of this expression is a temporary object of the given class type.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
bool tryEvaluateObjectSize(uint64_t &Result, ASTContext &Ctx, unsigned Type) const
If the current Expr is a pointer, this will try to statically determine the number of bytes available...
bool isCXX98IntegralConstantExpr(const ASTContext &Ctx) const
isCXX98IntegralConstantExpr - Return true if this expression is an integral constant expression in C+...
bool EvaluateWithSubstitution(APValue &Value, ASTContext &Ctx, const FunctionDecl *Callee, ArrayRef< const Expr * > Args, const Expr *This=nullptr) const
EvaluateWithSubstitution - Evaluate an expression as if from the context of a call to the given funct...
bool EvaluateAsInitializer(APValue &Result, const ASTContext &Ctx, const VarDecl *VD, SmallVectorImpl< PartialDiagnosticAt > &Notes, bool IsConstantInitializer) const
EvaluateAsInitializer - Evaluate an expression as if it were the initializer of the given declaration...
void EvaluateForOverflow(const ASTContext &Ctx) const
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 getBitWidthValue() const
Computes the bit width of this field, if this is a bit field.
unsigned getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
FieldDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this field.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
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 hasCXXExplicitFunctionObjectParameter() const
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
ArrayRef< ParmVarDecl * >::const_iterator param_const_iterator
bool isConstexpr() const
Whether this is a (C++11) constexpr function or constexpr constructor.
bool isUsableAsGlobalAllocationFunctionInConstantEvaluation(UnsignedOrNone *AlignmentParam=nullptr, bool *IsNothrow=nullptr) const
Determines whether this function is one of the replaceable global allocation functions described in i...
bool isDefaulted() const
Whether this function is defaulted.
void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override
Appends a human-readable name for this declaration into the given stream.
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.
CXXRecordDecl * getMostRecentCXXRecordDecl() const
Note: this can trigger extra deserialization when external AST sources are used.
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
void printQualifiedName(raw_ostream &OS) const
Returns a human-readable qualified name for this declaration, like A::B::i, for i being member of nam...
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.
This expression type represents an asterisk in an OpenACC Size-Expr, used in the 'tile' and 'gang' cl...
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.
bool isExplicitObjectParameter() const
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 * getOriginalDecl() 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.
static StringLiteral * Create(const ASTContext &Ctx, StringRef Str, StringLiteralKind Kind, bool Pascal, QualType Ty, ArrayRef< SourceLocation > Locs)
This is the "fully general" constructor that allows representation of strings formed from one or more...
uint32_t getCodeUnit(size_t i) const
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
bool isBooleanType() const
bool isFunctionReferenceType() const
bool isMFloat8Type() const
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
bool isPackedVectorBoolType(const ASTContext &ctx) const
bool isLiteralType(const ASTContext &Ctx) const
Return true if this is a literal type (C++11 [basic.types]p10)
bool isIncompleteArrayType() const
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
bool isComplexType() const
isComplexType() does not include complex integers (a GCC extension).
const ArrayType * castAsArrayTypeUnsafe() const
A variant of castAs<> for array type which silently discards qualifiers from the outermost type.
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
bool isIntegralOrUnscopedEnumerationType() const
Determine whether this type is an integral or unscoped enumeration type.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isConstantArrayType() const
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isVoidPointerType() const
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6....
bool isFunctionPointerType() const
bool isPointerType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isEnumeralType() const
bool isVariableArrayType() const
bool isSveVLSBuiltinType() const
Determines if this is a sizeless type supported by the 'arm_sve_vector_bits' type attribute,...
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
bool isExtVectorBoolType() const
bool isMemberDataPointerType() const
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
RecordDecl * castAsRecordDecl() const
bool isAnyComplexType() const
bool isFixedPointType() const
Return true if this is a fixed point type according to ISO/IEC JTC1 SC22 WG14 N1169.
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 isObjectType() const
Determine whether this type is an object type.
EnumDecl * getAsEnumDecl() const
Retrieves the EnumDecl this type refers to.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
bool isFunctionType() const
bool isVectorType() const
bool isRealFloatingType() const
Floating point categories.
bool isFloatingType() const
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
const T * castAsCanonical() const
Return this type's canonical type cast to the specified type.
bool isAnyPointerType() const
TypeClass getTypeClass() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isNullPtrType() const
bool isRecordType() const
bool isSizelessVectorType() const
Returns true for all scalable vector types.
bool hasPointerRepresentation() const
Whether this type is represented natively as a pointer.
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
QualType 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.
Expr * getSizeExpr() const
Represents a GCC generic vector type.
unsigned getNumElements() const
QualType getElementType() const
WhileStmt - This represents a 'while' stmt.
VarDecl * getConditionVariable()
Retrieve the variable declared in this "while" statement, if any.
Base class for stack frames, shared between VM and walker.
Interface for the VM to interact with the AST walker's context.
Defines the clang::TargetInfo interface.
bool computeOSLogBufferLayout(clang::ASTContext &Ctx, const clang::CallExpr *E, OSLogBufferLayout &layout)
static const FunctionDecl * getCallee(const CXXConstructExpr &D)
uint32_t Literal
Literals are represented as positive integers.
bool Call(InterpState &S, CodePtr OpPC, const Function *Func, uint32_t VarArgSize)
bool NE(InterpState &S, CodePtr OpPC)
llvm::FixedPointSemantics FixedPointSemantics
bool Alloc(InterpState &S, CodePtr OpPC, const Descriptor *Desc)
The JSON file list parser is used to communicate input to InstallAPI.
@ NonNull
Values of this type can never be null.
@ Success
Annotation was successful.
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.
@ None
The alignment was not explicit in code.
@ ArrayBound
Array bound in array declarator or new-expression.
@ Class
The "class" keyword introduces the elaborated-type-specifier.
@ 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.
std::string ObjCEncodeStorage
Represents an element in a path from a derived class to a base class.
EvalResult is a struct with detailed info about an evaluated expression.
APValue Val
Val - This is the value the expression can be folded to.
bool isGlobalLValue() const
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)