56#include "llvm/ADT/APFixedPoint.h"
57#include "llvm/ADT/Sequence.h"
58#include "llvm/ADT/SmallBitVector.h"
59#include "llvm/ADT/StringExtras.h"
60#include "llvm/Support/Casting.h"
61#include "llvm/Support/Debug.h"
62#include "llvm/Support/SaveAndRestore.h"
63#include "llvm/Support/SipHash.h"
64#include "llvm/Support/TimeProfiler.h"
65#include "llvm/Support/raw_ostream.h"
70#define DEBUG_TYPE "exprconstant"
73using llvm::APFixedPoint;
77using llvm::FixedPointSemantics;
84 using SourceLocExprScopeGuard =
94 return dyn_cast_or_null<FieldDecl>(
E.getAsBaseOrMember().getPointer());
99 return dyn_cast_or_null<CXXRecordDecl>(
E.getAsBaseOrMember().getPointer());
104 return E.getAsBaseOrMember().getInt();
116 static const AllocSizeAttr *getAllocSizeAttr(
const CallExpr *CE) {
118 return DirectCallee->getAttr<AllocSizeAttr>();
120 return IndirectCallee->getAttr<AllocSizeAttr>();
128 static const CallExpr *tryUnwrapAllocSizeCall(
const Expr *
E) {
136 if (
const auto *FE = dyn_cast<FullExpr>(
E))
139 if (
const auto *Cast = dyn_cast<CastExpr>(
E))
140 E = Cast->getSubExpr()->IgnoreParens();
142 if (
const auto *CE = dyn_cast<CallExpr>(
E))
143 return getAllocSizeAttr(CE) ? CE :
nullptr;
150 const auto *
E =
Base.dyn_cast<
const Expr *>();
159 case ConstantExprKind::Normal:
160 case ConstantExprKind::ClassTemplateArgument:
161 case ConstantExprKind::ImmediateInvocation:
166 case ConstantExprKind::NonClassTemplateArgument:
169 llvm_unreachable(
"unknown ConstantExprKind");
174 case ConstantExprKind::Normal:
175 case ConstantExprKind::ImmediateInvocation:
178 case ConstantExprKind::ClassTemplateArgument:
179 case ConstantExprKind::NonClassTemplateArgument:
182 llvm_unreachable(
"unknown ConstantExprKind");
188 static const uint64_t AssumedSizeForUnsizedArray =
189 std::numeric_limits<uint64_t>::max() / 2;
199 bool &FirstEntryIsUnsizedArray) {
202 assert(!isBaseAnAllocSizeCall(
Base) &&
203 "Unsized arrays shouldn't appear here");
204 unsigned MostDerivedLength = 0;
207 for (
unsigned I = 0, N =
Path.size(); I != N; ++I) {
211 MostDerivedLength = I + 1;
214 if (
auto *CAT = dyn_cast<ConstantArrayType>(AT)) {
215 ArraySize = CAT->getZExtSize();
217 assert(I == 0 &&
"unexpected unsized array designator");
218 FirstEntryIsUnsizedArray =
true;
219 ArraySize = AssumedSizeForUnsizedArray;
225 MostDerivedLength = I + 1;
228 Type = VT->getElementType();
229 ArraySize = VT->getNumElements();
230 MostDerivedLength = I + 1;
233 Type = FD->getType();
235 MostDerivedLength = I + 1;
243 return MostDerivedLength;
247 struct SubobjectDesignator {
251 LLVM_PREFERRED_TYPE(
bool)
252 unsigned Invalid : 1;
255 LLVM_PREFERRED_TYPE(
bool)
256 unsigned IsOnePastTheEnd : 1;
259 LLVM_PREFERRED_TYPE(
bool)
260 unsigned FirstEntryIsAnUnsizedArray : 1;
263 LLVM_PREFERRED_TYPE(
bool)
264 unsigned MostDerivedIsArrayElement : 1;
268 unsigned MostDerivedPathLength : 28;
277 uint64_t MostDerivedArraySize;
286 SubobjectDesignator() : Invalid(
true) {}
289 : Invalid(
false), IsOnePastTheEnd(
false),
290 FirstEntryIsAnUnsizedArray(
false), MostDerivedIsArrayElement(
false),
291 MostDerivedPathLength(0), MostDerivedArraySize(0),
292 MostDerivedType(
T) {}
295 : Invalid(!
V.isLValue() || !
V.hasLValuePath()), IsOnePastTheEnd(
false),
296 FirstEntryIsAnUnsizedArray(
false), MostDerivedIsArrayElement(
false),
297 MostDerivedPathLength(0), MostDerivedArraySize(0) {
298 assert(
V.isLValue() &&
"Non-LValue used to make an LValue designator?");
300 IsOnePastTheEnd =
V.isLValueOnePastTheEnd();
302 Entries.insert(Entries.end(), VEntries.begin(), VEntries.end());
303 if (
V.getLValueBase()) {
304 bool IsArray =
false;
305 bool FirstIsUnsizedArray =
false;
306 MostDerivedPathLength = findMostDerivedSubobject(
307 Ctx,
V.getLValueBase(),
V.getLValuePath(), MostDerivedArraySize,
308 MostDerivedType, IsArray, FirstIsUnsizedArray);
309 MostDerivedIsArrayElement = IsArray;
310 FirstEntryIsAnUnsizedArray = FirstIsUnsizedArray;
316 unsigned NewLength) {
320 assert(
Base &&
"cannot truncate path for null pointer");
321 assert(NewLength <= Entries.size() &&
"not a truncation");
323 if (NewLength == Entries.size())
325 Entries.resize(NewLength);
327 bool IsArray =
false;
328 bool FirstIsUnsizedArray =
false;
329 MostDerivedPathLength = findMostDerivedSubobject(
330 Ctx,
Base, Entries, MostDerivedArraySize, MostDerivedType, IsArray,
331 FirstIsUnsizedArray);
332 MostDerivedIsArrayElement = IsArray;
333 FirstEntryIsAnUnsizedArray = FirstIsUnsizedArray;
343 bool isMostDerivedAnUnsizedArray()
const {
344 assert(!Invalid &&
"Calling this makes no sense on invalid designators");
345 return Entries.size() == 1 && FirstEntryIsAnUnsizedArray;
350 uint64_t getMostDerivedArraySize()
const {
351 assert(!isMostDerivedAnUnsizedArray() &&
"Unsized array has no size");
352 return MostDerivedArraySize;
356 bool isOnePastTheEnd()
const {
360 if (!isMostDerivedAnUnsizedArray() && MostDerivedIsArrayElement &&
361 Entries[MostDerivedPathLength - 1].getAsArrayIndex() ==
362 MostDerivedArraySize)
370 std::pair<uint64_t, uint64_t> validIndexAdjustments() {
371 if (Invalid || isMostDerivedAnUnsizedArray())
377 bool IsArray = MostDerivedPathLength == Entries.size() &&
378 MostDerivedIsArrayElement;
379 uint64_t ArrayIndex = IsArray ? Entries.back().getAsArrayIndex()
380 : (uint64_t)IsOnePastTheEnd;
382 IsArray ? getMostDerivedArraySize() : (uint64_t)1;
383 return {ArrayIndex, ArraySize - ArrayIndex};
387 bool isValidSubobject()
const {
390 return !isOnePastTheEnd();
398 assert(!Invalid &&
"invalid designator has no subobject type");
399 return MostDerivedPathLength == Entries.size()
410 MostDerivedIsArrayElement =
true;
412 MostDerivedPathLength = Entries.size();
416 void addUnsizedArrayUnchecked(
QualType ElemTy) {
419 MostDerivedType = ElemTy;
420 MostDerivedIsArrayElement =
true;
424 MostDerivedArraySize = AssumedSizeForUnsizedArray;
425 MostDerivedPathLength = Entries.size();
429 void addDeclUnchecked(
const Decl *
D,
bool Virtual =
false) {
433 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(
D)) {
434 MostDerivedType = FD->getType();
435 MostDerivedIsArrayElement =
false;
436 MostDerivedArraySize = 0;
437 MostDerivedPathLength = Entries.size();
441 void addComplexUnchecked(
QualType EltTy,
bool Imag) {
446 MostDerivedType = EltTy;
447 MostDerivedIsArrayElement =
true;
448 MostDerivedArraySize = 2;
449 MostDerivedPathLength = Entries.size();
452 void addVectorElementUnchecked(
QualType EltTy, uint64_t Size,
455 MostDerivedType = EltTy;
456 MostDerivedPathLength = Entries.size();
457 MostDerivedArraySize = 0;
458 MostDerivedIsArrayElement =
false;
461 void diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info,
const Expr *
E);
462 void diagnosePointerArithmetic(EvalInfo &Info,
const Expr *
E,
465 void adjustIndex(EvalInfo &Info,
const Expr *
E,
APSInt N) {
466 if (Invalid || !N)
return;
467 uint64_t TruncatedN = N.extOrTrunc(64).getZExtValue();
468 if (isMostDerivedAnUnsizedArray()) {
469 diagnoseUnsizedArrayPointerArithmetic(Info,
E);
474 Entries.back().getAsArrayIndex() + TruncatedN);
481 bool IsArray = MostDerivedPathLength == Entries.size() &&
482 MostDerivedIsArrayElement;
483 uint64_t ArrayIndex = IsArray ? Entries.back().getAsArrayIndex()
484 : (uint64_t)IsOnePastTheEnd;
486 IsArray ? getMostDerivedArraySize() : (uint64_t)1;
488 if (N < -(int64_t)ArrayIndex || N > ArraySize - ArrayIndex) {
491 N = N.extend(std::max<unsigned>(N.getBitWidth() + 1, 65));
492 (llvm::APInt&)N += ArrayIndex;
493 assert(N.ugt(ArraySize) &&
"bounds check failed for in-bounds index");
494 diagnosePointerArithmetic(Info,
E, N);
499 ArrayIndex += TruncatedN;
500 assert(ArrayIndex <= ArraySize &&
501 "bounds check succeeded for out-of-bounds index");
506 IsOnePastTheEnd = (ArrayIndex != 0);
511 enum class ScopeKind {
519 CallRef() : OrigCallee(), CallIndex(0), Version() {}
520 CallRef(
const FunctionDecl *Callee,
unsigned CallIndex,
unsigned Version)
521 : OrigCallee(Callee), CallIndex(CallIndex), Version(Version) {}
523 explicit operator bool()
const {
return OrigCallee; }
549 CallStackFrame *Caller;
571 typedef std::pair<const void *, unsigned> MapKeyTy;
572 typedef std::map<MapKeyTy, APValue>
MapTy;
575 MapTy ConstexprUnknownAPValues;
585 unsigned CurTempVersion = TempVersionStack.back();
587 unsigned getTempVersion()
const {
return TempVersionStack.back(); }
589 void pushTempVersion() {
590 TempVersionStack.push_back(++CurTempVersion);
593 void popTempVersion() {
594 TempVersionStack.pop_back();
598 return {Callee, Index, ++CurTempVersion};
609 llvm::DenseMap<const ValueDecl *, FieldDecl *> LambdaCaptureFields;
610 FieldDecl *LambdaThisCaptureField =
nullptr;
612 CallStackFrame(EvalInfo &Info,
SourceRange CallRange,
618 APValue *getTemporary(
const void *Key,
unsigned Version) {
619 MapKeyTy KV(Key, Version);
620 auto LB = Temporaries.lower_bound(KV);
621 if (LB != Temporaries.end() && LB->first == KV)
627 APValue *getCurrentTemporary(
const void *Key) {
628 auto UB = Temporaries.upper_bound(MapKeyTy(Key,
UINT_MAX));
629 if (UB != Temporaries.begin() && std::prev(UB)->first.first == Key)
630 return &std::prev(UB)->second;
635 unsigned getCurrentTemporaryVersion(
const void *Key)
const {
636 auto UB = Temporaries.upper_bound(MapKeyTy(Key,
UINT_MAX));
637 if (UB != Temporaries.begin() && std::prev(UB)->first.first == Key)
638 return std::prev(UB)->first.second;
646 template<
typename KeyT>
648 ScopeKind
Scope, LValue &LV);
656 void describe(llvm::raw_ostream &OS)
const override;
658 Frame *getCaller()
const override {
return Caller; }
659 SourceRange getCallRange()
const override {
return CallRange; }
660 const FunctionDecl *getCallee()
const override {
return Callee; }
662 bool isStdFunction()
const {
663 for (
const DeclContext *DC = Callee; DC; DC = DC->getParent())
664 if (DC->isStdNamespace())
671 bool CanEvalMSConstexpr =
false;
679 class ThisOverrideRAII {
681 ThisOverrideRAII(CallStackFrame &Frame,
const LValue *NewThis,
bool Enable)
682 : Frame(Frame), OldThis(Frame.This) {
684 Frame.This = NewThis;
686 ~ThisOverrideRAII() {
687 Frame.This = OldThis;
690 CallStackFrame &Frame;
691 const LValue *OldThis;
696 class ExprTimeTraceScope {
698 ExprTimeTraceScope(
const Expr *
E,
const ASTContext &Ctx, StringRef Name)
699 : TimeScope(Name, [
E, &Ctx] {
704 llvm::TimeTraceScope TimeScope;
709 struct MSConstexprContextRAII {
710 CallStackFrame &Frame;
712 explicit MSConstexprContextRAII(CallStackFrame &Frame,
bool Value)
713 : Frame(Frame), OldValue(Frame.CanEvalMSConstexpr) {
714 Frame.CanEvalMSConstexpr =
Value;
717 ~MSConstexprContextRAII() { Frame.CanEvalMSConstexpr = OldValue; }
722 const LValue &This,
QualType ThisType);
730 llvm::PointerIntPair<APValue*, 2, ScopeKind>
Value;
741 bool isDestroyedAtEndOf(ScopeKind K)
const {
742 return (
int)
Value.getInt() >= (
int)K;
744 bool endLifetime(EvalInfo &Info,
bool RunDestructors) {
745 if (RunDestructors) {
748 Loc = VD->getLocation();
757 bool hasSideEffect() {
758 return T.isDestructedType();
763 struct ObjectUnderConstruction {
766 friend bool operator==(
const ObjectUnderConstruction &LHS,
767 const ObjectUnderConstruction &RHS) {
768 return LHS.Base == RHS.Base && LHS.Path == RHS.Path;
770 friend llvm::hash_code
hash_value(
const ObjectUnderConstruction &Obj) {
771 return llvm::hash_combine(Obj.Base, Obj.Path);
774 enum class ConstructionPhase {
785template<>
struct DenseMapInfo<ObjectUnderConstruction> {
786 using Base = DenseMapInfo<APValue::LValueBase>;
788 return {Base::getEmptyKey(), {}}; }
790 return {Base::getTombstoneKey(), {}};
795 static bool isEqual(
const ObjectUnderConstruction &LHS,
796 const ObjectUnderConstruction &RHS) {
810 const Expr *AllocExpr =
nullptr;
821 if (
auto *NE = dyn_cast<CXXNewExpr>(AllocExpr))
822 return NE->isArray() ? ArrayNew : New;
823 assert(isa<CallExpr>(AllocExpr));
828 struct DynAllocOrder {
856 CallStackFrame *CurrentCall;
859 unsigned CallStackDepth;
862 unsigned NextCallIndex;
871 bool EnableNewConstInterp;
875 CallStackFrame BottomFrame;
885 enum class EvaluatingDeclKind {
892 EvaluatingDeclKind IsEvaluatingDecl = EvaluatingDeclKind::None;
899 llvm::DenseMap<ObjectUnderConstruction, ConstructionPhase>
900 ObjectsUnderConstruction;
905 std::map<DynamicAllocLValue, DynAlloc, DynAllocOrder> HeapAllocs;
908 unsigned NumHeapAllocs = 0;
910 struct EvaluatingConstructorRAII {
912 ObjectUnderConstruction
Object;
914 EvaluatingConstructorRAII(EvalInfo &EI, ObjectUnderConstruction Object,
918 EI.ObjectsUnderConstruction
919 .insert({
Object, HasBases ? ConstructionPhase::Bases
920 : ConstructionPhase::AfterBases})
923 void finishedConstructingBases() {
924 EI.ObjectsUnderConstruction[
Object] = ConstructionPhase::AfterBases;
926 void finishedConstructingFields() {
927 EI.ObjectsUnderConstruction[
Object] = ConstructionPhase::AfterFields;
929 ~EvaluatingConstructorRAII() {
930 if (DidInsert) EI.ObjectsUnderConstruction.erase(Object);
934 struct EvaluatingDestructorRAII {
936 ObjectUnderConstruction
Object;
938 EvaluatingDestructorRAII(EvalInfo &EI, ObjectUnderConstruction Object)
940 DidInsert = EI.ObjectsUnderConstruction
941 .insert({
Object, ConstructionPhase::Destroying})
944 void startedDestroyingBases() {
945 EI.ObjectsUnderConstruction[
Object] =
946 ConstructionPhase::DestroyingBases;
948 ~EvaluatingDestructorRAII() {
950 EI.ObjectsUnderConstruction.erase(Object);
957 return ObjectsUnderConstruction.lookup({
Base,
Path});
962 unsigned SpeculativeEvaluationDepth = 0;
970 bool HasActiveDiagnostic;
974 bool HasFoldFailureDiagnostic;
979 bool CheckingPotentialConstantExpression =
false;
987 bool CheckingForUndefinedBehavior =
false;
989 enum EvaluationMode {
992 EM_ConstantExpression,
999 EM_ConstantExpressionUnevaluated,
1007 EM_IgnoreSideEffects,
1012 bool checkingPotentialConstantExpression()
const override {
1013 return CheckingPotentialConstantExpression;
1019 bool checkingForUndefinedBehavior()
const override {
1020 return CheckingForUndefinedBehavior;
1024 : Ctx(const_cast<
ASTContext &>(
C)), EvalStatus(S), CurrentCall(nullptr),
1025 CallStackDepth(0), NextCallIndex(1),
1026 StepsLeft(
C.getLangOpts().ConstexprStepLimit),
1027 EnableNewConstInterp(
C.getLangOpts().EnableNewConstInterp),
1030 nullptr, CallRef()),
1031 EvaluatingDecl((const
ValueDecl *)nullptr),
1032 EvaluatingDeclValue(nullptr), HasActiveDiagnostic(
false),
1033 HasFoldFailureDiagnostic(
false), EvalMode(Mode) {}
1039 ASTContext &getASTContext()
const override {
return Ctx; }
1042 EvaluatingDeclKind EDK = EvaluatingDeclKind::Ctor) {
1043 EvaluatingDecl =
Base;
1044 IsEvaluatingDecl = EDK;
1045 EvaluatingDeclValue = &
Value;
1051 if (checkingPotentialConstantExpression() && CallStackDepth > 1)
1053 if (NextCallIndex == 0) {
1055 FFDiag(
Loc, diag::note_constexpr_call_limit_exceeded);
1058 if (CallStackDepth <= getLangOpts().ConstexprCallDepth)
1060 FFDiag(
Loc, diag::note_constexpr_depth_limit_exceeded)
1061 << getLangOpts().ConstexprCallDepth;
1066 uint64_t ElemCount,
bool Diag) {
1072 ElemCount >
uint64_t(std::numeric_limits<unsigned>::max())) {
1074 FFDiag(
Loc, diag::note_constexpr_new_too_large) << ElemCount;
1084 if (ElemCount > Limit) {
1086 FFDiag(
Loc, diag::note_constexpr_new_exceeds_limits)
1087 << ElemCount << Limit;
1093 std::pair<CallStackFrame *, unsigned>
1094 getCallFrameAndDepth(
unsigned CallIndex) {
1095 assert(CallIndex &&
"no call index in getCallFrameAndDepth");
1098 unsigned Depth = CallStackDepth;
1099 CallStackFrame *Frame = CurrentCall;
1100 while (Frame->Index > CallIndex) {
1101 Frame = Frame->Caller;
1104 if (Frame->Index == CallIndex)
1105 return {Frame, Depth};
1106 return {
nullptr, 0};
1109 bool nextStep(
const Stmt *S) {
1111 FFDiag(S->getBeginLoc(), diag::note_constexpr_step_limit_exceeded);
1121 std::optional<DynAlloc *> Result;
1122 auto It = HeapAllocs.find(DA);
1123 if (It != HeapAllocs.end())
1124 Result = &It->second;
1130 CallStackFrame *Frame = getCallFrameAndDepth(
Call.CallIndex).first;
1131 return Frame ? Frame->getTemporary(
Call.getOrigParam(PVD),
Call.Version)
1136 struct StdAllocatorCaller {
1137 unsigned FrameIndex;
1140 explicit operator bool()
const {
return FrameIndex != 0; };
1143 StdAllocatorCaller getStdAllocatorCaller(StringRef FnName)
const {
1144 for (
const CallStackFrame *
Call = CurrentCall;
Call != &BottomFrame;
1146 const auto *MD = dyn_cast_or_null<CXXMethodDecl>(
Call->Callee);
1150 if (!FnII || !FnII->
isStr(FnName))
1154 dyn_cast<ClassTemplateSpecializationDecl>(MD->getParent());
1160 if (CTSD->isInStdNamespace() && ClassII &&
1161 ClassII->
isStr(
"allocator") && TAL.
size() >= 1 &&
1163 return {
Call->Index, TAL[0].getAsType(),
Call->CallExpr};
1169 void performLifetimeExtension() {
1171 llvm::erase_if(CleanupStack, [](Cleanup &
C) {
1172 return !
C.isDestroyedAtEndOf(ScopeKind::FullExpression);
1179 bool discardCleanups() {
1180 for (Cleanup &
C : CleanupStack) {
1181 if (
C.hasSideEffect() && !noteSideEffect()) {
1182 CleanupStack.clear();
1186 CleanupStack.clear();
1191 interp::Frame *getCurrentFrame()
override {
return CurrentCall; }
1192 const interp::Frame *getBottomFrame()
const override {
return &BottomFrame; }
1194 bool hasActiveDiagnostic()
override {
return HasActiveDiagnostic; }
1195 void setActiveDiagnostic(
bool Flag)
override { HasActiveDiagnostic = Flag; }
1197 void setFoldFailureDiagnostic(
bool Flag)
override {
1198 HasFoldFailureDiagnostic = Flag;
1209 bool hasPriorDiagnostic()
override {
1210 if (!EvalStatus.
Diag->empty()) {
1212 case EM_ConstantFold:
1213 case EM_IgnoreSideEffects:
1214 if (!HasFoldFailureDiagnostic)
1218 case EM_ConstantExpression:
1219 case EM_ConstantExpressionUnevaluated:
1220 setActiveDiagnostic(
false);
1227 unsigned getCallStackDepth()
override {
return CallStackDepth; }
1232 bool keepEvaluatingAfterSideEffect()
const override {
1234 case EM_IgnoreSideEffects:
1237 case EM_ConstantExpression:
1238 case EM_ConstantExpressionUnevaluated:
1239 case EM_ConstantFold:
1242 return checkingPotentialConstantExpression() ||
1243 checkingForUndefinedBehavior();
1245 llvm_unreachable(
"Missed EvalMode case");
1250 bool noteSideEffect()
override {
1252 return keepEvaluatingAfterSideEffect();
1256 bool keepEvaluatingAfterUndefinedBehavior() {
1258 case EM_IgnoreSideEffects:
1259 case EM_ConstantFold:
1262 case EM_ConstantExpression:
1263 case EM_ConstantExpressionUnevaluated:
1264 return checkingForUndefinedBehavior();
1266 llvm_unreachable(
"Missed EvalMode case");
1272 bool noteUndefinedBehavior()
override {
1274 return keepEvaluatingAfterUndefinedBehavior();
1279 bool keepEvaluatingAfterFailure()
const override {
1284 case EM_ConstantExpression:
1285 case EM_ConstantExpressionUnevaluated:
1286 case EM_ConstantFold:
1287 case EM_IgnoreSideEffects:
1288 return checkingPotentialConstantExpression() ||
1289 checkingForUndefinedBehavior();
1291 llvm_unreachable(
"Missed EvalMode case");
1304 [[nodiscard]]
bool noteFailure() {
1312 bool KeepGoing = keepEvaluatingAfterFailure();
1317 class ArrayInitLoopIndex {
1322 ArrayInitLoopIndex(EvalInfo &Info)
1323 : Info(Info), OuterIndex(Info.ArrayInitIndex) {
1324 Info.ArrayInitIndex = 0;
1326 ~ArrayInitLoopIndex() { Info.ArrayInitIndex = OuterIndex; }
1328 operator uint64_t&() {
return Info.ArrayInitIndex; }
1333 struct FoldConstant {
1336 bool HadNoPriorDiags;
1337 EvalInfo::EvaluationMode OldMode;
1339 explicit FoldConstant(EvalInfo &Info,
bool Enabled)
1342 HadNoPriorDiags(Info.EvalStatus.
Diag &&
1343 Info.EvalStatus.
Diag->empty() &&
1344 !Info.EvalStatus.HasSideEffects),
1345 OldMode(Info.EvalMode) {
1347 Info.EvalMode = EvalInfo::EM_ConstantFold;
1349 void keepDiagnostics() { Enabled =
false; }
1351 if (Enabled && HadNoPriorDiags && !Info.EvalStatus.Diag->empty() &&
1352 !Info.EvalStatus.HasSideEffects)
1353 Info.EvalStatus.Diag->clear();
1354 Info.EvalMode = OldMode;
1360 struct IgnoreSideEffectsRAII {
1362 EvalInfo::EvaluationMode OldMode;
1363 explicit IgnoreSideEffectsRAII(EvalInfo &Info)
1364 : Info(Info), OldMode(Info.EvalMode) {
1365 Info.EvalMode = EvalInfo::EM_IgnoreSideEffects;
1368 ~IgnoreSideEffectsRAII() { Info.EvalMode = OldMode; }
1373 class SpeculativeEvaluationRAII {
1374 EvalInfo *Info =
nullptr;
1376 unsigned OldSpeculativeEvaluationDepth = 0;
1378 void moveFromAndCancel(SpeculativeEvaluationRAII &&
Other) {
1380 OldStatus =
Other.OldStatus;
1381 OldSpeculativeEvaluationDepth =
Other.OldSpeculativeEvaluationDepth;
1382 Other.Info =
nullptr;
1385 void maybeRestoreState() {
1389 Info->EvalStatus = OldStatus;
1390 Info->SpeculativeEvaluationDepth = OldSpeculativeEvaluationDepth;
1394 SpeculativeEvaluationRAII() =
default;
1396 SpeculativeEvaluationRAII(
1398 : Info(&Info), OldStatus(Info.EvalStatus),
1399 OldSpeculativeEvaluationDepth(Info.SpeculativeEvaluationDepth) {
1400 Info.EvalStatus.Diag = NewDiag;
1401 Info.SpeculativeEvaluationDepth = Info.CallStackDepth + 1;
1404 SpeculativeEvaluationRAII(
const SpeculativeEvaluationRAII &
Other) =
delete;
1405 SpeculativeEvaluationRAII(SpeculativeEvaluationRAII &&
Other) {
1406 moveFromAndCancel(std::move(
Other));
1409 SpeculativeEvaluationRAII &operator=(SpeculativeEvaluationRAII &&
Other) {
1410 maybeRestoreState();
1411 moveFromAndCancel(std::move(
Other));
1415 ~SpeculativeEvaluationRAII() { maybeRestoreState(); }
1420 template<ScopeKind Kind>
1423 unsigned OldStackSize;
1425 ScopeRAII(EvalInfo &Info)
1426 : Info(Info), OldStackSize(Info.CleanupStack.size()) {
1429 Info.CurrentCall->pushTempVersion();
1431 bool destroy(
bool RunDestructors =
true) {
1432 bool OK =
cleanup(Info, RunDestructors, OldStackSize);
1437 if (OldStackSize != -1U)
1441 Info.CurrentCall->popTempVersion();
1444 static bool cleanup(EvalInfo &Info,
bool RunDestructors,
1445 unsigned OldStackSize) {
1446 assert(OldStackSize <= Info.CleanupStack.size() &&
1447 "running cleanups out of order?");
1452 for (
unsigned I = Info.CleanupStack.size(); I > OldStackSize; --I) {
1453 if (Info.CleanupStack[I - 1].isDestroyedAtEndOf(Kind)) {
1454 if (!Info.CleanupStack[I - 1].endLifetime(Info, RunDestructors)) {
1462 auto NewEnd = Info.CleanupStack.begin() + OldStackSize;
1463 if (Kind != ScopeKind::Block)
1465 std::remove_if(NewEnd, Info.CleanupStack.end(), [](Cleanup &
C) {
1466 return C.isDestroyedAtEndOf(Kind);
1468 Info.CleanupStack.erase(NewEnd, Info.CleanupStack.end());
1472 typedef ScopeRAII<ScopeKind::Block> BlockScopeRAII;
1473 typedef ScopeRAII<ScopeKind::FullExpression> FullExpressionRAII;
1474 typedef ScopeRAII<ScopeKind::Call> CallScopeRAII;
1477bool SubobjectDesignator::checkSubobject(EvalInfo &Info,
const Expr *
E,
1481 if (isOnePastTheEnd()) {
1482 Info.CCEDiag(
E, diag::note_constexpr_past_end_subobject)
1493void SubobjectDesignator::diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info,
1495 Info.CCEDiag(
E, diag::note_constexpr_unsized_array_indexed);
1500void SubobjectDesignator::diagnosePointerArithmetic(EvalInfo &Info,
1505 if (MostDerivedPathLength == Entries.size() && MostDerivedIsArrayElement)
1506 Info.CCEDiag(
E, diag::note_constexpr_array_index)
1508 <<
static_cast<unsigned>(getMostDerivedArraySize());
1510 Info.CCEDiag(
E, diag::note_constexpr_array_index)
1515CallStackFrame::CallStackFrame(EvalInfo &Info,
SourceRange CallRange,
1520 Index(Info.NextCallIndex++) {
1521 Info.CurrentCall =
this;
1522 ++Info.CallStackDepth;
1525CallStackFrame::~CallStackFrame() {
1526 assert(Info.CurrentCall ==
this &&
"calls retired out of order");
1527 --Info.CallStackDepth;
1528 Info.CurrentCall = Caller;
1552 llvm_unreachable(
"unknown access kind");
1588 llvm_unreachable(
"unknown access kind");
1592 struct ComplexValue {
1600 ComplexValue() : FloatReal(
APFloat::Bogus()), FloatImag(
APFloat::Bogus()) {}
1602 void makeComplexFloat() { IsInt =
false; }
1603 bool isComplexFloat()
const {
return !IsInt; }
1604 APFloat &getComplexFloatReal() {
return FloatReal; }
1605 APFloat &getComplexFloatImag() {
return FloatImag; }
1607 void makeComplexInt() { IsInt =
true; }
1608 bool isComplexInt()
const {
return IsInt; }
1609 APSInt &getComplexIntReal() {
return IntReal; }
1610 APSInt &getComplexIntImag() {
return IntImag; }
1613 if (isComplexFloat())
1619 assert(
v.isComplexFloat() ||
v.isComplexInt());
1620 if (
v.isComplexFloat()) {
1622 FloatReal =
v.getComplexFloatReal();
1623 FloatImag =
v.getComplexFloatImag();
1626 IntReal =
v.getComplexIntReal();
1627 IntImag =
v.getComplexIntImag();
1637 bool InvalidBase : 1;
1639 bool AllowConstexprUnknown =
false;
1642 bool allowConstexprUnknown()
const {
return AllowConstexprUnknown; }
1643 CharUnits &getLValueOffset() {
return Offset; }
1644 const CharUnits &getLValueOffset()
const {
return Offset; }
1645 SubobjectDesignator &getLValueDesignator() {
return Designator; }
1646 const SubobjectDesignator &getLValueDesignator()
const {
return Designator;}
1647 bool isNullPointer()
const {
return IsNullPtr;}
1649 unsigned getLValueCallIndex()
const {
return Base.getCallIndex(); }
1650 unsigned getLValueVersion()
const {
return Base.getVersion(); }
1656 assert(!InvalidBase &&
"APValues can't handle invalid LValue bases");
1660 if (AllowConstexprUnknown)
1661 V.setConstexprUnknown();
1664 assert(
V.isLValue() &&
"Setting LValue from a non-LValue?");
1665 Base =
V.getLValueBase();
1666 Offset =
V.getLValueOffset();
1667 InvalidBase =
false;
1669 IsNullPtr =
V.isNullPointer();
1670 AllowConstexprUnknown =
V.allowConstexprUnknown();
1677 const auto *
E = B.
get<
const Expr *>();
1678 assert((isa<MemberExpr>(
E) || tryUnwrapAllocSizeCall(
E)) &&
1679 "Unexpected type of invalid base");
1685 InvalidBase = BInvalid;
1686 Designator = SubobjectDesignator(getType(B));
1688 AllowConstexprUnknown =
false;
1695 InvalidBase =
false;
1698 AllowConstexprUnknown =
false;
1707 moveInto(Printable);
1714 template <
typename GenDiagType>
1715 bool checkNullPointerDiagnosingWith(
const GenDiagType &GenDiag) {
1727 bool checkNullPointer(EvalInfo &Info,
const Expr *
E,
1729 return checkNullPointerDiagnosingWith([&Info,
E, CSK] {
1730 Info.CCEDiag(
E, diag::note_constexpr_null_subobject) << CSK;
1734 bool checkNullPointerForFoldAccess(EvalInfo &Info,
const Expr *
E,
1736 return checkNullPointerDiagnosingWith([&Info,
E, AK] {
1737 Info.FFDiag(
E, diag::note_constexpr_access_null) << AK;
1748 void addDecl(EvalInfo &Info,
const Expr *
E,
1753 void addUnsizedArray(EvalInfo &Info,
const Expr *
E,
QualType ElemTy) {
1755 Info.CCEDiag(
E, diag::note_constexpr_unsupported_unsized_array);
1760 assert(getType(
Base)->isPointerType() || getType(
Base)->isArrayType());
1761 Designator.FirstEntryIsAnUnsizedArray =
true;
1769 void addComplex(EvalInfo &Info,
const Expr *
E,
QualType EltTy,
bool Imag) {
1773 void addVectorElement(EvalInfo &Info,
const Expr *
E,
QualType EltTy,
1774 uint64_t Size, uint64_t Idx) {
1776 Designator.addVectorElementUnchecked(EltTy, Size, Idx);
1778 void clearIsNullPointer() {
1781 void adjustOffsetAndIndex(EvalInfo &Info,
const Expr *
E,
1791 uint64_t Offset64 = Offset.getQuantity();
1793 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
1798 clearIsNullPointer();
1803 clearIsNullPointer();
1810 : DeclAndIsDerivedMember(
Decl,
false) {}
1815 return DeclAndIsDerivedMember.getPointer();
1818 bool isDerivedMember()
const {
1819 return DeclAndIsDerivedMember.getInt();
1823 return cast<CXXRecordDecl>(
1824 DeclAndIsDerivedMember.getPointer()->getDeclContext());
1831 assert(
V.isMemberPointer());
1832 DeclAndIsDerivedMember.setPointer(
V.getMemberPointerDecl());
1833 DeclAndIsDerivedMember.setInt(
V.isMemberPointerToDerivedMember());
1842 llvm::PointerIntPair<const ValueDecl*, 1, bool> DeclAndIsDerivedMember;
1850 assert(!
Path.empty());
1852 if (
Path.size() >= 2)
1856 if (
Expected->getCanonicalDecl() !=
Class->getCanonicalDecl()) {
1872 if (!isDerivedMember()) {
1873 Path.push_back(Derived);
1876 if (!castBack(Derived))
1879 DeclAndIsDerivedMember.setInt(
false);
1887 DeclAndIsDerivedMember.setInt(
true);
1888 if (isDerivedMember()) {
1892 return castBack(
Base);
1897 static bool operator==(
const MemberPtr &LHS,
const MemberPtr &RHS) {
1898 if (!LHS.getDecl() || !RHS.getDecl())
1899 return !LHS.getDecl() && !RHS.getDecl();
1900 if (LHS.getDecl()->getCanonicalDecl() != RHS.getDecl()->getCanonicalDecl())
1902 return LHS.Path == RHS.Path;
1908 const LValue &This,
const Expr *
E,
1909 bool AllowNonLiteralTypes =
false);
1911 bool InvalidBaseOK =
false);
1913 bool InvalidBaseOK =
false);
1927 std::string *StringResult =
nullptr);
1944 if (Int.isUnsigned() || Int.isMinSignedValue()) {
1945 Int = Int.extend(Int.getBitWidth() + 1);
1946 Int.setIsSigned(
true);
1951template<
typename KeyT>
1953 ScopeKind
Scope, LValue &LV) {
1954 unsigned Version = getTempVersion();
1961CallStackFrame::createConstexprUnknownAPValues(
const VarDecl *Key,
1963 APValue &Result = ConstexprUnknownAPValues[MapKeyTy(Key,
Base.getVersion())];
1972 assert(Args.CallIndex == Index &&
"creating parameter in wrong frame");
1978 return createLocal(
Base, PVD, PVD->
getType(), ScopeKind::Call);
1983 assert(
Base.getCallIndex() == Index &&
"lvalue for wrong frame");
1984 unsigned Version =
Base.getVersion();
1985 APValue &Result = Temporaries[MapKeyTy(Key, Version)];
1986 assert(Result.isAbsent() &&
"local created multiple times");
1992 if (Index <= Info.SpeculativeEvaluationDepth) {
1993 if (
T.isDestructedType())
1994 Info.noteSideEffect();
1996 Info.CleanupStack.push_back(Cleanup(&Result,
Base,
T,
Scope));
2003 FFDiag(
E, diag::note_constexpr_heap_alloc_limit_exceeded);
2009 auto Result = HeapAllocs.emplace(std::piecewise_construct,
2010 std::forward_as_tuple(DA), std::tuple<>());
2011 assert(Result.second &&
"reused a heap alloc index?");
2012 Result.first->second.AllocExpr =
E;
2013 return &Result.first->second.Value;
2017void CallStackFrame::describe(raw_ostream &Out)
const {
2018 unsigned ArgIndex = 0;
2020 isa<CXXMethodDecl>(Callee) && !isa<CXXConstructorDecl>(Callee) &&
2021 cast<CXXMethodDecl>(Callee)->isImplicitObjectMemberFunction();
2024 Callee->getNameForDiagnostic(Out, Info.Ctx.getPrintingPolicy(),
2027 if (This && IsMemberCall) {
2028 if (
const auto *MCE = dyn_cast_if_present<CXXMemberCallExpr>(
CallExpr)) {
2029 const Expr *
Object = MCE->getImplicitObjectArgument();
2030 Object->printPretty(Out,
nullptr, Info.Ctx.getPrintingPolicy(),
2032 if (
Object->getType()->isPointerType())
2036 }
else if (
const auto *OCE =
2037 dyn_cast_if_present<CXXOperatorCallExpr>(
CallExpr)) {
2038 OCE->getArg(0)->printPretty(Out,
nullptr,
2039 Info.Ctx.getPrintingPolicy(),
2044 This->moveInto(Val);
2047 Info.Ctx.getLValueReferenceType(
This->Designator.MostDerivedType));
2050 Callee->getNameForDiagnostic(Out, Info.Ctx.getPrintingPolicy(),
2052 IsMemberCall =
false;
2058 E =
Callee->param_end(); I !=
E; ++I, ++ArgIndex) {
2059 if (ArgIndex > (
unsigned)IsMemberCall)
2063 APValue *
V = Info.getParamSlot(Arguments, Param);
2065 V->printPretty(Out, Info.Ctx, Param->
getType());
2069 if (ArgIndex == 0 && IsMemberCall)
2070 Out <<
"->" << *
Callee <<
'(';
2084 return Info.noteSideEffect();
2090 unsigned Builtin =
E->getBuiltinCallee();
2091 return (Builtin == Builtin::BI__builtin___CFStringMakeConstantString ||
2092 Builtin == Builtin::BI__builtin___NSStringMakeConstantString ||
2093 Builtin == Builtin::BI__builtin_ptrauth_sign_constant ||
2094 Builtin == Builtin::BI__builtin_function_start);
2098 const auto *BaseExpr =
2099 llvm::dyn_cast_if_present<CallExpr>(LVal.Base.dyn_cast<
const Expr *>());
2114 if (
const VarDecl *VD = dyn_cast<VarDecl>(
D))
2115 return VD->hasGlobalStorage();
2116 if (isa<TemplateParamObjectDecl>(
D))
2121 return isa<FunctionDecl, MSGuidDecl, UnnamedGlobalConstantDecl>(
D);
2131 case Expr::CompoundLiteralExprClass: {
2135 case Expr::MaterializeTemporaryExprClass:
2138 return cast<MaterializeTemporaryExpr>(
E)->getStorageDuration() ==
SD_Static;
2140 case Expr::StringLiteralClass:
2141 case Expr::PredefinedExprClass:
2142 case Expr::ObjCStringLiteralClass:
2143 case Expr::ObjCEncodeExprClass:
2145 case Expr::ObjCBoxedExprClass:
2146 return cast<ObjCBoxedExpr>(
E)->isExpressibleAsConstantInitializer();
2147 case Expr::CallExprClass:
2150 case Expr::AddrLabelExprClass:
2154 case Expr::BlockExprClass:
2155 return !cast<BlockExpr>(
E)->getBlockDecl()->hasCaptures();
2158 case Expr::SourceLocExprClass:
2160 case Expr::ImplicitValueInitExprClass:
2172 return LVal.Base.dyn_cast<
const ValueDecl*>();
2185 const auto *BaseExpr = LVal.Base.dyn_cast<
const Expr *>();
2190 if (
const auto *EE = dyn_cast<ObjCEncodeExpr>(BaseExpr)) {
2191 Info.Ctx.getObjCEncodingForType(EE->getEncodedType(),
2199 const auto *Lit = dyn_cast<StringLiteral>(BaseExpr);
2200 if (
const auto *PE = dyn_cast<PredefinedExpr>(BaseExpr))
2201 Lit = PE->getFunctionName();
2206 AsString.
Bytes = Lit->getBytes();
2207 AsString.
CharWidth = Lit->getCharByteWidth();
2227 const LValue &RHS) {
2236 CharUnits Offset = RHS.Offset - LHS.Offset;
2237 if (Offset.isNegative())
2238 LHSString.
Bytes = LHSString.
Bytes.drop_front(-Offset.getQuantity());
2240 RHSString.
Bytes = RHSString.
Bytes.drop_front(Offset.getQuantity());
2242 bool LHSIsLonger = LHSString.
Bytes.size() > RHSString.
Bytes.size();
2243 StringRef Longer = LHSIsLonger ? LHSString.
Bytes : RHSString.
Bytes;
2244 StringRef Shorter = LHSIsLonger ? RHSString.
Bytes : LHSString.
Bytes;
2245 int ShorterCharWidth = (LHSIsLonger ? RHSString : LHSString).CharWidth;
2250 for (
int NullByte : llvm::seq(ShorterCharWidth)) {
2251 if (Shorter.size() + NullByte >= Longer.size())
2253 if (Longer[Shorter.size() + NullByte])
2259 return Shorter == Longer.take_front(Shorter.size());
2269 if (isa_and_nonnull<VarDecl>(
Decl)) {
2279 if (!A.getLValueBase())
2280 return !B.getLValueBase();
2281 if (!B.getLValueBase())
2284 if (A.getLValueBase().getOpaqueValue() !=
2285 B.getLValueBase().getOpaqueValue())
2288 return A.getLValueCallIndex() == B.getLValueCallIndex() &&
2289 A.getLValueVersion() == B.getLValueVersion();
2293 assert(
Base &&
"no location for a null lvalue");
2299 if (
auto *PVD = dyn_cast_or_null<ParmVarDecl>(VD)) {
2301 for (CallStackFrame *F = Info.CurrentCall; F; F = F->Caller) {
2302 if (F->Arguments.CallIndex ==
Base.getCallIndex() &&
2303 F->Arguments.Version ==
Base.getVersion() && F->Callee &&
2304 Idx < F->Callee->getNumParams()) {
2305 VD = F->Callee->getParamDecl(Idx);
2312 Info.Note(VD->
getLocation(), diag::note_declared_at);
2314 Info.Note(
E->
getExprLoc(), diag::note_constexpr_temporary_here);
2317 if (std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA))
2318 Info.Note((*Alloc)->AllocExpr->getExprLoc(),
2319 diag::note_constexpr_dynamic_alloc_here);
2352 const SubobjectDesignator &
Designator = LVal.getLValueDesignator();
2360 if (isTemplateArgument(Kind)) {
2361 int InvalidBaseKind = -1;
2364 InvalidBaseKind = 0;
2365 else if (isa_and_nonnull<StringLiteral>(BaseE))
2366 InvalidBaseKind = 1;
2367 else if (isa_and_nonnull<MaterializeTemporaryExpr>(BaseE) ||
2368 isa_and_nonnull<LifetimeExtendedTemporaryDecl>(BaseVD))
2369 InvalidBaseKind = 2;
2370 else if (
auto *PE = dyn_cast_or_null<PredefinedExpr>(BaseE)) {
2371 InvalidBaseKind = 3;
2372 Ident = PE->getIdentKindName();
2375 if (InvalidBaseKind != -1) {
2376 Info.FFDiag(
Loc, diag::note_constexpr_invalid_template_arg)
2377 << IsReferenceType << !
Designator.Entries.empty() << InvalidBaseKind
2383 if (
auto *FD = dyn_cast_or_null<FunctionDecl>(BaseVD);
2384 FD && FD->isImmediateFunction()) {
2385 Info.FFDiag(
Loc, diag::note_consteval_address_accessible)
2387 Info.Note(FD->getLocation(), diag::note_declared_at);
2395 if (Info.getLangOpts().CPlusPlus11) {
2396 Info.FFDiag(
Loc, diag::note_constexpr_non_global, 1)
2397 << IsReferenceType << !
Designator.Entries.empty() << !!BaseVD
2399 auto *VarD = dyn_cast_or_null<VarDecl>(BaseVD);
2400 if (VarD && VarD->isConstexpr()) {
2406 Info.Note(VarD->getLocation(), diag::note_constexpr_not_static)
2418 assert((Info.checkingPotentialConstantExpression() ||
2419 LVal.getLValueCallIndex() == 0) &&
2420 "have call index for global lvalue");
2423 Info.FFDiag(
Loc, diag::note_constexpr_dynamic_alloc)
2424 << IsReferenceType << !
Designator.Entries.empty();
2430 if (
const VarDecl *Var = dyn_cast<const VarDecl>(BaseVD)) {
2432 if (Var->getTLSKind())
2438 if (!isForManglingOnly(Kind) && Var->hasAttr<DLLImportAttr>())
2444 if (Info.getASTContext().getLangOpts().CUDA &&
2445 Info.getASTContext().getLangOpts().CUDAIsDevice &&
2446 Info.getASTContext().CUDAConstantEvalCtx.NoWrongSidedVars) {
2447 if ((!Var->hasAttr<CUDADeviceAttr>() &&
2448 !Var->hasAttr<CUDAConstantAttr>() &&
2449 !Var->getType()->isCUDADeviceBuiltinSurfaceType() &&
2450 !Var->getType()->isCUDADeviceBuiltinTextureType()) ||
2451 Var->hasAttr<HIPManagedAttr>())
2455 if (
const auto *FD = dyn_cast<const FunctionDecl>(BaseVD)) {
2466 if (Info.getLangOpts().CPlusPlus && !isForManglingOnly(Kind) &&
2467 FD->hasAttr<DLLImportAttr>())
2471 }
else if (
const auto *MTE =
2472 dyn_cast_or_null<MaterializeTemporaryExpr>(BaseE)) {
2473 if (CheckedTemps.insert(MTE).second) {
2476 Info.FFDiag(MTE->getExprLoc(),
2477 diag::note_constexpr_unsupported_temporary_nontrivial_dtor)
2482 APValue *
V = MTE->getOrCreateValue(
false);
2483 assert(
V &&
"evasluation result refers to uninitialised temporary");
2485 Info, MTE->getExprLoc(), TempType, *
V, Kind,
2486 nullptr, CheckedTemps))
2493 if (!IsReferenceType)
2505 Info.FFDiag(
Loc, diag::note_constexpr_past_end, 1)
2506 << !
Designator.Entries.empty() << !!BaseVD << BaseVD;
2521 const auto *FD = dyn_cast_or_null<CXXMethodDecl>(
Member);
2524 if (FD->isImmediateFunction()) {
2525 Info.FFDiag(
Loc, diag::note_consteval_address_accessible) << 0;
2526 Info.Note(FD->getLocation(), diag::note_declared_at);
2529 return isForManglingOnly(Kind) || FD->isVirtual() ||
2530 !FD->hasAttr<DLLImportAttr>();
2536 const LValue *This =
nullptr) {
2538 if (Info.getLangOpts().CPlusPlus23)
2557 if (This && Info.EvaluatingDecl == This->getLValueBase())
2561 if (Info.getLangOpts().CPlusPlus11)
2562 Info.FFDiag(
E, diag::note_constexpr_nonliteral)
2565 Info.FFDiag(
E, diag::note_invalid_subexpr_in_const_expr);
2576 if (SubobjectDecl) {
2577 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
2578 << 1 << SubobjectDecl;
2580 diag::note_constexpr_subobject_declared_here);
2582 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
2591 Type = AT->getValueType();
2596 if (
Value.isArray()) {
2598 for (
unsigned I = 0, N =
Value.getArrayInitializedElts(); I != N; ++I) {
2600 Value.getArrayInitializedElt(I), Kind,
2601 SubobjectDecl, CheckedTemps))
2604 if (!
Value.hasArrayFiller())
2607 Value.getArrayFiller(), Kind, SubobjectDecl,
2610 if (
Value.isUnion() &&
Value.getUnionField()) {
2613 Value.getUnionValue(), Kind,
Value.getUnionField(), CheckedTemps);
2615 if (
Value.isStruct()) {
2617 if (
const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {
2618 unsigned BaseIndex = 0;
2620 const APValue &BaseValue =
Value.getStructBase(BaseIndex);
2623 Info.FFDiag(TypeBeginLoc, diag::note_constexpr_uninitialized_base)
2624 << BS.getType() <<
SourceRange(TypeBeginLoc, BS.getEndLoc());
2634 for (
const auto *I : RD->
fields()) {
2635 if (I->isUnnamedBitField())
2639 Value.getStructField(I->getFieldIndex()), Kind,
2645 if (
Value.isLValue() &&
2646 CERK == CheckEvaluationResultKind::ConstantExpression) {
2648 LVal.setFrom(Info.Ctx,
Value);
2653 if (
Value.isMemberPointer() &&
2654 CERK == CheckEvaluationResultKind::ConstantExpression)
2674 nullptr, CheckedTemps);
2683 CheckEvaluationResultKind::FullyInitialized, Info, DiagLoc,
Type,
Value,
2684 ConstantExprKind::Normal,
nullptr, CheckedTemps);
2690 if (!Info.HeapAllocs.empty()) {
2694 Info.CCEDiag(Info.HeapAllocs.begin()->second.AllocExpr,
2695 diag::note_constexpr_memory_leak)
2696 <<
unsigned(Info.HeapAllocs.size() - 1);
2704 if (!
Value.getLValueBase()) {
2706 Result = !
Value.getLValueOffset().isZero();
2724 Result = Val.
getInt().getBoolValue();
2756 llvm_unreachable(
"unknown APValue kind");
2762 assert(
E->
isPRValue() &&
"missing lvalue-to-rvalue conv in bool condition");
2772 Info.CCEDiag(
E, diag::note_constexpr_overflow)
2773 << SrcValue << DestType;
2774 return Info.noteUndefinedBehavior();
2780 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
2784 Result =
APSInt(DestWidth, !DestSigned);
2786 if (
Value.convertToInteger(Result, llvm::APFloat::rmTowardZero, &ignored)
2787 & APFloat::opInvalidOp)
2798 llvm::RoundingMode RM =
2800 if (RM == llvm::RoundingMode::Dynamic)
2801 RM = llvm::RoundingMode::NearestTiesToEven;
2807 APFloat::opStatus St) {
2810 if (Info.InConstantContext)
2814 if ((St & APFloat::opInexact) &&
2818 Info.FFDiag(
E, diag::note_constexpr_dynamic_rounding);
2822 if ((St != APFloat::opOK) &&
2825 FPO.getAllowFEnvAccess())) {
2826 Info.FFDiag(
E, diag::note_constexpr_float_arithmetic_strict);
2830 if ((St & APFloat::opStatus::opInvalidOp) &&
2849 assert((isa<CastExpr>(
E) || isa<CompoundAssignOperator>(
E) ||
2850 isa<ConvertVectorExpr>(
E)) &&
2851 "HandleFloatToFloatCast has been checked with only CastExpr, "
2852 "CompoundAssignOperator and ConvertVectorExpr. Please either validate "
2853 "the new expression or address the root cause of this usage.");
2855 APFloat::opStatus St;
2856 APFloat
Value = Result;
2858 St = Result.convert(Info.Ctx.getFloatTypeSemantics(DestType), RM, &ignored);
2865 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
2871 Result =
Value.getBoolValue();
2878 QualType DestType, APFloat &Result) {
2879 Result = APFloat(Info.Ctx.getFloatTypeSemantics(DestType), 1);
2881 APFloat::opStatus St = Result.convertFromAPInt(
Value,
Value.isSigned(), RM);
2887 assert(FD->
isBitField() &&
"truncateBitfieldValue on non-bitfield");
2889 if (!
Value.isInt()) {
2893 assert(
Value.isLValue() &&
"integral value neither int nor lvalue?");
2899 unsigned OldBitWidth = Int.getBitWidth();
2901 if (NewBitWidth < OldBitWidth)
2902 Int = Int.trunc(NewBitWidth).extend(OldBitWidth);
2909template<
typename Operation>
2912 unsigned BitWidth, Operation Op,
2914 if (LHS.isUnsigned()) {
2915 Result = Op(LHS, RHS);
2919 APSInt Value(Op(LHS.extend(BitWidth), RHS.extend(BitWidth)),
false);
2920 Result =
Value.trunc(LHS.getBitWidth());
2921 if (Result.extend(BitWidth) !=
Value) {
2922 if (Info.checkingForUndefinedBehavior())
2924 diag::warn_integer_constant_overflow)
2925 <<
toString(Result, 10, Result.isSigned(),
false,
2937 bool HandleOverflowResult =
true;
2944 std::multiplies<APSInt>(), Result);
2947 std::plus<APSInt>(), Result);
2950 std::minus<APSInt>(), Result);
2951 case BO_And: Result = LHS & RHS;
return true;
2952 case BO_Xor: Result = LHS ^ RHS;
return true;
2953 case BO_Or: Result = LHS | RHS;
return true;
2957 Info.FFDiag(
E, diag::note_expr_divide_by_zero)
2963 if (RHS.isNegative() && RHS.isAllOnes() && LHS.isSigned() &&
2964 LHS.isMinSignedValue())
2966 Info,
E, -LHS.extend(LHS.getBitWidth() + 1),
E->
getType());
2967 Result = (Opcode == BO_Rem ? LHS % RHS : LHS / RHS);
2968 return HandleOverflowResult;
2970 if (Info.getLangOpts().OpenCL)
2972 RHS &=
APSInt(llvm::APInt(RHS.getBitWidth(),
2973 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2975 else if (RHS.isSigned() && RHS.isNegative()) {
2978 Info.CCEDiag(
E, diag::note_constexpr_negative_shift) << RHS;
2979 if (!Info.noteUndefinedBehavior())
2987 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
2989 Info.CCEDiag(
E, diag::note_constexpr_large_shift)
2990 << RHS <<
E->
getType() << LHS.getBitWidth();
2991 if (!Info.noteUndefinedBehavior())
2993 }
else if (LHS.isSigned() && !Info.getLangOpts().CPlusPlus20) {
2998 if (LHS.isNegative()) {
2999 Info.CCEDiag(
E, diag::note_constexpr_lshift_of_negative) << LHS;
3000 if (!Info.noteUndefinedBehavior())
3002 }
else if (LHS.countl_zero() < SA) {
3003 Info.CCEDiag(
E, diag::note_constexpr_lshift_discards);
3004 if (!Info.noteUndefinedBehavior())
3012 if (Info.getLangOpts().OpenCL)
3014 RHS &=
APSInt(llvm::APInt(RHS.getBitWidth(),
3015 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
3017 else if (RHS.isSigned() && RHS.isNegative()) {
3020 Info.CCEDiag(
E, diag::note_constexpr_negative_shift) << RHS;
3021 if (!Info.noteUndefinedBehavior())
3029 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
3031 Info.CCEDiag(
E, diag::note_constexpr_large_shift)
3032 << RHS <<
E->
getType() << LHS.getBitWidth();
3033 if (!Info.noteUndefinedBehavior())
3041 case BO_LT: Result = LHS < RHS;
return true;
3042 case BO_GT: Result = LHS > RHS;
return true;
3043 case BO_LE: Result = LHS <= RHS;
return true;
3044 case BO_GE: Result = LHS >= RHS;
return true;
3045 case BO_EQ: Result = LHS == RHS;
return true;
3046 case BO_NE: Result = LHS != RHS;
return true;
3048 llvm_unreachable(
"BO_Cmp should be handled elsewhere");
3055 const APFloat &RHS) {
3057 APFloat::opStatus St;
3063 St = LHS.multiply(RHS, RM);
3066 St = LHS.add(RHS, RM);
3069 St = LHS.subtract(RHS, RM);
3075 Info.CCEDiag(
E, diag::note_expr_divide_by_zero);
3076 St = LHS.divide(RHS, RM);
3085 Info.CCEDiag(
E, diag::note_constexpr_float_arithmetic) << LHS.isNaN();
3086 return Info.noteUndefinedBehavior();
3094 const APInt &RHSValue, APInt &Result) {
3095 bool LHS = (LHSValue != 0);
3096 bool RHS = (RHSValue != 0);
3098 if (Opcode == BO_LAnd)
3099 Result = LHS && RHS;
3101 Result = LHS || RHS;
3106 const APFloat &RHSValue, APInt &Result) {
3107 bool LHS = !LHSValue.isZero();
3108 bool RHS = !RHSValue.isZero();
3110 if (Opcode == BO_LAnd)
3111 Result = LHS && RHS;
3113 Result = LHS || RHS;
3119 const APValue &RHSValue, APInt &Result) {
3123 RHSValue.
getInt(), Result);
3129template <
typename APTy>
3132 const APTy &RHSValue, APInt &Result) {
3135 llvm_unreachable(
"unsupported binary operator");
3137 Result = (LHSValue == RHSValue);
3140 Result = (LHSValue != RHSValue);
3143 Result = (LHSValue < RHSValue);
3146 Result = (LHSValue > RHSValue);
3149 Result = (LHSValue <= RHSValue);
3152 Result = (LHSValue >= RHSValue);
3166 const APValue &RHSValue, APInt &Result) {
3170 RHSValue.
getInt(), Result);
3181 assert(Opcode != BO_PtrMemD && Opcode != BO_PtrMemI &&
3182 "Operation not supported on vector types");
3186 QualType EltTy = VT->getElementType();
3193 "A vector result that isn't a vector OR uncalculated LValue");
3199 RHSValue.
getVectorLength() == NumElements &&
"Different vector sizes");
3203 for (
unsigned EltNum = 0; EltNum < NumElements; ++EltNum) {
3208 APSInt EltResult{Info.Ctx.getIntWidth(EltTy),
3218 RHSElt.
getInt(), EltResult);
3224 ResultElements.emplace_back(EltResult);
3229 "Mismatched LHS/RHS/Result Type");
3230 APFloat LHSFloat = LHSElt.
getFloat();
3238 ResultElements.emplace_back(LHSFloat);
3242 LHSValue =
APValue(ResultElements.data(), ResultElements.size());
3250 unsigned TruncatedElements) {
3251 SubobjectDesignator &
D = Result.Designator;
3254 if (TruncatedElements ==
D.Entries.size())
3256 assert(TruncatedElements >=
D.MostDerivedPathLength &&
3257 "not casting to a derived class");
3263 for (
unsigned I = TruncatedElements, N =
D.Entries.size(); I != N; ++I) {
3267 if (isVirtualBaseClass(
D.Entries[I]))
3273 D.Entries.resize(TruncatedElements);
3283 RL = &Info.Ctx.getASTRecordLayout(Derived);
3286 Obj.addDecl(Info,
E,
Base,
false);
3287 Obj.getLValueOffset() += RL->getBaseClassOffset(
Base);
3296 if (!
Base->isVirtual())
3299 SubobjectDesignator &
D = Obj.Designator;
3304 DerivedDecl =
D.MostDerivedType->getAsCXXRecordDecl();
3310 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(DerivedDecl);
3311 Obj.addDecl(Info,
E, BaseDecl,
true);
3319 PathE =
E->path_end();
3320 PathI != PathE; ++PathI) {
3324 Type = (*PathI)->getType();
3336 llvm_unreachable(
"Class must be derived from the passed in base class!");
3351 RL = &Info.Ctx.getASTRecordLayout(FD->
getParent());
3355 LVal.addDecl(Info,
E, FD);
3356 LVal.adjustOffset(Info.Ctx.toCharUnitsFromBits(RL->getFieldOffset(I)));
3364 for (
const auto *
C : IFD->
chain())
3397 if (SOT == SizeOfType::SizeOf)
3398 Size = Info.Ctx.getTypeSizeInChars(
Type);
3400 Size = Info.Ctx.getTypeInfoDataSizeInChars(
Type).Width;
3417 LVal.adjustOffsetAndIndex(Info,
E, Adjustment, SizeOfPointee);
3423 int64_t Adjustment) {
3425 APSInt::get(Adjustment));
3440 LVal.Offset += SizeOfComponent;
3442 LVal.addComplex(Info,
E, EltTy, Imag);
3448 uint64_t Size, uint64_t Idx) {
3453 LVal.Offset += SizeOfElement * Idx;
3455 LVal.addVectorElement(Info,
E, EltTy, Size, Idx);
3469 const VarDecl *VD, CallStackFrame *Frame,
3470 unsigned Version,
APValue *&Result) {
3473 bool AllowConstexprUnknown =
3480 Result = Frame->getTemporary(VD, Version);
3484 if (!isa<ParmVarDecl>(VD)) {
3491 "missing value for local variable");
3492 if (Info.checkingPotentialConstantExpression())
3497 diag::note_unimplemented_constexpr_lambda_feature_ast)
3498 <<
"captures not currently allowed";
3505 if (Info.EvaluatingDecl ==
Base) {
3506 Result = Info.EvaluatingDeclValue;
3514 if (isa<ParmVarDecl>(VD) && !AllowConstexprUnknown) {
3517 if (!Info.checkingPotentialConstantExpression() ||
3518 !Info.CurrentCall->Callee ||
3520 if (Info.getLangOpts().CPlusPlus11) {
3521 Info.FFDiag(
E, diag::note_constexpr_function_param_value_unknown)
3542 if (!
Init && !AllowConstexprUnknown) {
3545 if (!Info.checkingPotentialConstantExpression()) {
3546 Info.FFDiag(
E, diag::note_constexpr_var_init_unknown, 1)
3557 if (
Init &&
Init->isValueDependent()) {
3564 if (!Info.checkingPotentialConstantExpression()) {
3565 Info.FFDiag(
E, Info.getLangOpts().CPlusPlus11
3566 ? diag::note_constexpr_ltor_non_constexpr
3567 : diag::note_constexpr_ltor_non_integral, 1)
3581 if (AllowConstexprUnknown) {
3582 Result = &Info.CurrentCall->createConstexprUnknownAPValues(VD,
Base);
3585 Info.FFDiag(
E, diag::note_constexpr_var_init_non_constant, 1) << VD;
3601 ((Info.getLangOpts().CPlusPlus || Info.getLangOpts().OpenCL) &&
3603 Info.CCEDiag(
E, diag::note_constexpr_var_init_non_constant, 1) << VD;
3610 Info.FFDiag(
E, diag::note_constexpr_var_init_weak) << VD;
3624 if (AllowConstexprUnknown) {
3626 Result = &Info.CurrentCall->createConstexprUnknownAPValues(VD,
Base);
3628 Result->setConstexprUnknown();
3641 if (I->getType()->getAsCXXRecordDecl()->getCanonicalDecl() ==
Base)
3645 llvm_unreachable(
"base class missing from derived class's bases list");
3651 assert(!isa<SourceLocExpr>(Lit) &&
3652 "SourceLocExpr should have already been converted to a StringLiteral");
3655 if (
const auto *ObjCEnc = dyn_cast<ObjCEncodeExpr>(Lit)) {
3657 Info.Ctx.getObjCEncodingForType(ObjCEnc->getEncodedType(), Str);
3658 assert(Index <= Str.size() &&
"Index too large");
3659 return APSInt::getUnsigned(Str.c_str()[Index]);
3662 if (
auto PE = dyn_cast<PredefinedExpr>(Lit))
3663 Lit = PE->getFunctionName();
3666 Info.Ctx.getAsConstantArrayType(S->getType());
3667 assert(CAT &&
"string literal isn't an array");
3669 assert(CharType->
isIntegerType() &&
"unexpected character type");
3672 if (Index < S->getLength())
3673 Value = S->getCodeUnit(Index);
3685 AllocType.isNull() ? S->getType() : AllocType);
3686 assert(CAT &&
"string literal isn't an array");
3688 assert(CharType->
isIntegerType() &&
"unexpected character type");
3692 std::min(S->getLength(), Elts), Elts);
3695 if (Result.hasArrayFiller())
3697 for (
unsigned I = 0, N = Result.getArrayInitializedElts(); I != N; ++I) {
3698 Value = S->getCodeUnit(I);
3705 unsigned Size = Array.getArraySize();
3706 assert(Index < Size);
3709 unsigned OldElts = Array.getArrayInitializedElts();
3710 unsigned NewElts = std::max(Index+1, OldElts * 2);
3711 NewElts = std::min(Size, std::max(NewElts, 8u));
3715 for (
unsigned I = 0; I != OldElts; ++I)
3717 for (
unsigned I = OldElts; I != NewElts; ++I)
3721 Array.swap(NewValue);
3742 for (
auto *Field : RD->
fields())
3743 if (!Field->isUnnamedBitField() &&
3747 for (
auto &BaseSpec : RD->
bases())
3765 for (
auto *Field : RD->
fields()) {
3770 if (Field->isMutable() &&
3772 Info.FFDiag(
E, diag::note_constexpr_access_mutable, 1) << AK << Field;
3773 Info.Note(Field->getLocation(), diag::note_declared_at);
3781 for (
auto &BaseSpec : RD->
bases())
3791 bool MutableSubobject =
false) {
3796 switch (Info.IsEvaluatingDecl) {
3797 case EvalInfo::EvaluatingDeclKind::None:
3800 case EvalInfo::EvaluatingDeclKind::Ctor:
3802 if (Info.EvaluatingDecl ==
Base)
3807 if (
auto *BaseE =
Base.dyn_cast<
const Expr *>())
3808 if (
auto *BaseMTE = dyn_cast<MaterializeTemporaryExpr>(BaseE))
3809 return Info.EvaluatingDecl == BaseMTE->getExtendingDecl();
3812 case EvalInfo::EvaluatingDeclKind::Dtor:
3817 if (MutableSubobject ||
Base != Info.EvaluatingDecl)
3826 llvm_unreachable(
"unknown evaluating decl kind");
3831 return Info.CheckArraySize(
3840struct CompleteObject {
3848 CompleteObject() :
Value(nullptr) {}
3852 bool mayAccessMutableMembers(EvalInfo &Info,
AccessKinds AK)
const {
3863 if (!Info.getLangOpts().CPlusPlus14 &&
3864 AK != AccessKinds::AK_IsWithinLifetime)
3869 explicit operator bool()
const {
return !
Type.isNull(); }
3874 bool IsMutable =
false) {
3888template <
typename Sub
objectHandler>
3889static typename SubobjectHandler::result_type
3891 const SubobjectDesignator &Sub, SubobjectHandler &handler) {
3894 return handler.failed();
3895 if (Sub.isOnePastTheEnd() || Sub.isMostDerivedAnUnsizedArray()) {
3896 if (Info.getLangOpts().CPlusPlus11)
3897 Info.FFDiag(
E, Sub.isOnePastTheEnd()
3898 ? diag::note_constexpr_access_past_end
3899 : diag::note_constexpr_access_unsized_array)
3900 << handler.AccessKind;
3903 return handler.failed();
3909 const FieldDecl *VolatileField =
nullptr;
3917 for (
unsigned I = 0, N = Sub.Entries.size(); ; ++I) {
3928 if (!Info.checkingPotentialConstantExpression())
3929 Info.FFDiag(
E, diag::note_constexpr_access_uninit)
3932 return handler.failed();
3940 Info.isEvaluatingCtorDtor(
3943 ConstructionPhase::None) {
3953 if (Info.getLangOpts().CPlusPlus) {
3957 if (VolatileField) {
3960 Decl = VolatileField;
3961 }
else if (
auto *VD = Obj.Base.dyn_cast<
const ValueDecl*>()) {
3963 Loc = VD->getLocation();
3967 if (
auto *
E = Obj.Base.dyn_cast<
const Expr *>())
3970 Info.FFDiag(
E, diag::note_constexpr_access_volatile_obj, 1)
3971 << handler.AccessKind << DiagKind <<
Decl;
3972 Info.Note(
Loc, diag::note_constexpr_volatile_here) << DiagKind;
3974 Info.FFDiag(
E, diag::note_invalid_subexpr_in_const_expr);
3976 return handler.failed();
3984 !Obj.mayAccessMutableMembers(Info, handler.AccessKind) &&
3986 return handler.failed();
3990 if (!handler.found(*O, ObjType))
4002 LastField =
nullptr;
4006 assert(CAT &&
"vla in literal type?");
4007 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4008 if (CAT->
getSize().ule(Index)) {
4011 if (Info.getLangOpts().CPlusPlus11)
4012 Info.FFDiag(
E, diag::note_constexpr_access_past_end)
4013 << handler.AccessKind;
4016 return handler.failed();
4023 else if (!
isRead(handler.AccessKind)) {
4025 return handler.failed();
4033 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4035 if (Info.getLangOpts().CPlusPlus11)
4036 Info.FFDiag(
E, diag::note_constexpr_access_past_end)
4037 << handler.AccessKind;
4040 return handler.failed();
4046 assert(I == N - 1 &&
"extracting subobject of scalar?");
4056 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4057 unsigned NumElements = VT->getNumElements();
4058 if (Index == NumElements) {
4059 if (Info.getLangOpts().CPlusPlus11)
4060 Info.FFDiag(
E, diag::note_constexpr_access_past_end)
4061 << handler.AccessKind;
4064 return handler.failed();
4067 if (Index > NumElements) {
4068 Info.CCEDiag(
E, diag::note_constexpr_array_index)
4069 << Index << 0 << NumElements;
4070 return handler.failed();
4073 ObjType = VT->getElementType();
4074 assert(I == N - 1 &&
"extracting subobject of scalar?");
4076 }
else if (
const FieldDecl *Field = getAsField(Sub.Entries[I])) {
4077 if (Field->isMutable() &&
4078 !Obj.mayAccessMutableMembers(Info, handler.AccessKind)) {
4079 Info.FFDiag(
E, diag::note_constexpr_access_mutable, 1)
4080 << handler.AccessKind << Field;
4081 Info.Note(Field->getLocation(), diag::note_declared_at);
4082 return handler.failed();
4091 if (I == N - 1 && handler.AccessKind ==
AK_Construct) {
4102 Info.FFDiag(
E, diag::note_constexpr_access_inactive_union_member)
4103 << handler.AccessKind << Field << !UnionField << UnionField;
4104 return handler.failed();
4113 if (Field->getType().isVolatileQualified())
4114 VolatileField = Field;
4127struct ExtractSubobjectHandler {
4133 typedef bool result_type;
4134 bool failed() {
return false; }
4154 const CompleteObject &Obj,
4155 const SubobjectDesignator &Sub,
APValue &Result,
4158 ExtractSubobjectHandler Handler = {Info,
E, Result, AK};
4163struct ModifySubobjectHandler {
4168 typedef bool result_type;
4174 Info.FFDiag(
E, diag::note_constexpr_modify_const_type) << QT;
4180 bool failed() {
return false; }
4182 if (!checkConst(SubobjType))
4185 Subobj.
swap(NewVal);
4189 if (!checkConst(SubobjType))
4191 if (!NewVal.
isInt()) {
4200 if (!checkConst(SubobjType))
4208const AccessKinds ModifySubobjectHandler::AccessKind;
4212 const CompleteObject &Obj,
4213 const SubobjectDesignator &Sub,
4215 ModifySubobjectHandler Handler = { Info, NewVal,
E };
4222 const SubobjectDesignator &A,
4223 const SubobjectDesignator &B,
4224 bool &WasArrayIndex) {
4225 unsigned I = 0, N = std::min(A.Entries.size(), B.Entries.size());
4226 for (; I != N; ++I) {
4230 if (A.Entries[I].getAsArrayIndex() != B.Entries[I].getAsArrayIndex()) {
4231 WasArrayIndex =
true;
4239 if (A.Entries[I].getAsBaseOrMember() !=
4240 B.Entries[I].getAsBaseOrMember()) {
4241 WasArrayIndex =
false;
4244 if (
const FieldDecl *FD = getAsField(A.Entries[I]))
4246 ObjType = FD->getType();
4252 WasArrayIndex =
false;
4259 const SubobjectDesignator &A,
4260 const SubobjectDesignator &B) {
4261 if (A.Entries.size() != B.Entries.size())
4264 bool IsArray = A.MostDerivedIsArrayElement;
4265 if (IsArray && A.MostDerivedPathLength != A.Entries.size())
4274 return CommonLength >= A.Entries.size() - IsArray;
4281 if (LVal.InvalidBase) {
4283 return CompleteObject();
4287 Info.FFDiag(
E, diag::note_constexpr_access_null) << AK;
4288 return CompleteObject();
4291 CallStackFrame *Frame =
nullptr;
4293 if (LVal.getLValueCallIndex()) {
4294 std::tie(Frame, Depth) =
4295 Info.getCallFrameAndDepth(LVal.getLValueCallIndex());
4297 Info.FFDiag(
E, diag::note_constexpr_lifetime_ended, 1)
4298 << AK << LVal.Base.is<
const ValueDecl*>();
4300 return CompleteObject();
4311 if (Info.getLangOpts().CPlusPlus)
4312 Info.FFDiag(
E, diag::note_constexpr_access_volatile_type)
4316 return CompleteObject();
4321 QualType BaseType = getType(LVal.Base);
4323 if (Info.getLangOpts().CPlusPlus14 && LVal.Base == Info.EvaluatingDecl &&
4327 BaseVal = Info.EvaluatingDeclValue;
4330 if (
auto *GD = dyn_cast<MSGuidDecl>(
D)) {
4333 Info.FFDiag(
E, diag::note_constexpr_modify_global);
4334 return CompleteObject();
4338 Info.FFDiag(
E, diag::note_constexpr_unsupported_layout)
4340 return CompleteObject();
4342 return CompleteObject(LVal.Base, &
V, GD->getType());
4346 if (
auto *GCD = dyn_cast<UnnamedGlobalConstantDecl>(
D)) {
4348 Info.FFDiag(
E, diag::note_constexpr_modify_global);
4349 return CompleteObject();
4351 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&GCD->getValue()),
4356 if (
auto *TPO = dyn_cast<TemplateParamObjectDecl>(
D)) {
4358 Info.FFDiag(
E, diag::note_constexpr_modify_global);
4359 return CompleteObject();
4361 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&TPO->getValue()),
4372 const VarDecl *VD = dyn_cast<VarDecl>(
D);
4379 return CompleteObject();
4382 bool IsConstant = BaseType.
isConstant(Info.Ctx);
4383 bool ConstexprVar =
false;
4384 if (
const auto *VD = dyn_cast_if_present<VarDecl>(
4385 Info.EvaluatingDecl.dyn_cast<
const ValueDecl *>()))
4391 if (IsAccess && isa<ParmVarDecl>(VD)) {
4395 }
else if (Info.getLangOpts().CPlusPlus14 &&
4402 Info.FFDiag(
E, diag::note_constexpr_modify_global);
4403 return CompleteObject();
4406 }
else if (Info.getLangOpts().C23 && ConstexprVar) {
4408 return CompleteObject();
4412 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4413 if (Info.getLangOpts().CPlusPlus) {
4414 Info.FFDiag(
E, diag::note_constexpr_ltor_non_const_int, 1) << VD;
4415 Info.Note(VD->
getLocation(), diag::note_declared_at);
4419 return CompleteObject();
4421 }
else if (!IsAccess) {
4422 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4423 }
else if (IsConstant && Info.checkingPotentialConstantExpression() &&
4426 }
else if (IsConstant) {
4430 if (Info.getLangOpts().CPlusPlus) {
4431 Info.CCEDiag(
E, Info.getLangOpts().CPlusPlus11
4432 ? diag::note_constexpr_ltor_non_constexpr
4433 : diag::note_constexpr_ltor_non_integral, 1)
4435 Info.Note(VD->
getLocation(), diag::note_declared_at);
4441 if (Info.getLangOpts().CPlusPlus) {
4442 Info.FFDiag(
E, Info.getLangOpts().CPlusPlus11
4443 ? diag::note_constexpr_ltor_non_constexpr
4444 : diag::note_constexpr_ltor_non_integral, 1)
4446 Info.Note(VD->
getLocation(), diag::note_declared_at);
4450 return CompleteObject();
4455 return CompleteObject();
4457 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
4459 Info.FFDiag(
E, diag::note_constexpr_access_deleted_object) << AK;
4460 return CompleteObject();
4462 return CompleteObject(LVal.Base, &(*Alloc)->Value,
4463 LVal.Base.getDynamicAllocType());
4469 dyn_cast_or_null<MaterializeTemporaryExpr>(
Base)) {
4470 assert(MTE->getStorageDuration() ==
SD_Static &&
4471 "should have a frame for a non-global materialized temporary");
4498 if (!MTE->isUsableInConstantExpressions(Info.Ctx) &&
4501 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4502 Info.FFDiag(
E, diag::note_constexpr_access_static_temporary, 1) << AK;
4503 Info.Note(MTE->getExprLoc(), diag::note_constexpr_temporary_here);
4504 return CompleteObject();
4507 BaseVal = MTE->getOrCreateValue(
false);
4508 assert(BaseVal &&
"got reference to unevaluated temporary");
4511 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4514 Info.FFDiag(
E, diag::note_constexpr_access_unreadable_object)
4517 Info.Ctx.getLValueReferenceType(LValType));
4519 return CompleteObject();
4522 BaseVal = Frame->getTemporary(
Base, LVal.Base.getVersion());
4523 assert(BaseVal &&
"missing value for temporary");
4534 unsigned VisibleDepth = Depth;
4535 if (llvm::isa_and_nonnull<ParmVarDecl>(
4536 LVal.Base.dyn_cast<
const ValueDecl *>()))
4538 if ((Frame && Info.getLangOpts().CPlusPlus14 &&
4539 Info.EvalStatus.HasSideEffects) ||
4540 (
isModification(AK) && VisibleDepth < Info.SpeculativeEvaluationDepth))
4541 return CompleteObject();
4543 return CompleteObject(LVal.getLValueBase(), BaseVal, BaseType);
4562 const LValue &LVal,
APValue &RVal,
4563 bool WantObjectRepresentation =
false) {
4564 if (LVal.Designator.Invalid)
4573 if (
Base && !LVal.getLValueCallIndex() && !
Type.isVolatileQualified()) {
4578 if (
Type.isVolatileQualified()) {
4584 if (!
Evaluate(Lit, Info, CLE->getInitializer()))
4604 Info.Note(CLE->getExprLoc(), diag::note_declared_at);
4609 CompleteObject LitObj(LVal.Base, &Lit,
Base->getType());
4611 }
else if (isa<StringLiteral>(
Base) || isa<PredefinedExpr>(
Base)) {
4614 assert(LVal.Designator.Entries.size() <= 1 &&
4615 "Can only read characters from string literals");
4616 if (LVal.Designator.Entries.empty()) {
4623 if (LVal.Designator.isOnePastTheEnd()) {
4624 if (Info.getLangOpts().CPlusPlus11)
4625 Info.FFDiag(Conv, diag::note_constexpr_access_past_end) << AK;
4630 uint64_t CharIndex = LVal.Designator.Entries[0].getAsArrayIndex();
4637 return Obj &&
extractSubobject(Info, Conv, Obj, LVal.Designator, RVal, AK);
4643 if (LVal.Designator.Invalid)
4646 if (!Info.getLangOpts().CPlusPlus14) {
4656struct CompoundAssignSubobjectHandler {
4665 typedef bool result_type;
4670 Info.FFDiag(
E, diag::note_constexpr_modify_const_type) << QT;
4676 bool failed() {
return false; }
4680 return found(Subobj.
getInt(), SubobjType);
4682 return found(Subobj.
getFloat(), SubobjType);
4689 return foundPointer(Subobj, SubobjType);
4691 return foundVector(Subobj, SubobjType);
4693 Info.FFDiag(
E, diag::note_constexpr_access_uninit)
4705 if (!checkConst(SubobjType))
4716 if (!checkConst(SubobjType))
4735 Info.Ctx.getLangOpts());
4738 PromotedLHSType, FValue) &&
4748 return checkConst(SubobjType) &&
4755 if (!checkConst(SubobjType))
4763 (Opcode != BO_Add && Opcode != BO_Sub)) {
4769 if (Opcode == BO_Sub)
4773 LVal.setFrom(Info.Ctx, Subobj);
4776 LVal.moveInto(Subobj);
4782const AccessKinds CompoundAssignSubobjectHandler::AccessKind;
4787 const LValue &LVal,
QualType LValType,
4791 if (LVal.Designator.Invalid)
4794 if (!Info.getLangOpts().CPlusPlus14) {
4800 CompoundAssignSubobjectHandler Handler = { Info,
E, PromotedLValType, Opcode,
4802 return Obj &&
findSubobject(Info,
E, Obj, LVal.Designator, Handler);
4806struct IncDecSubobjectHandler {
4812 typedef bool result_type;
4817 Info.FFDiag(
E, diag::note_constexpr_modify_const_type) << QT;
4823 bool failed() {
return false; }
4834 return found(Subobj.
getInt(), SubobjType);
4836 return found(Subobj.
getFloat(), SubobjType);
4846 return foundPointer(Subobj, SubobjType);
4854 if (!checkConst(SubobjType))
4876 bool WasNegative =
Value.isNegative();
4880 if (!WasNegative &&
Value.isNegative() &&
E->canOverflow()) {
4887 if (WasNegative && !
Value.isNegative() &&
E->canOverflow()) {
4888 unsigned BitWidth =
Value.getBitWidth();
4889 APSInt ActualValue(
Value.sext(BitWidth + 1),
false);
4890 ActualValue.setBit(BitWidth);
4897 if (!checkConst(SubobjType))
4904 APFloat::opStatus St;
4906 St =
Value.add(One, RM);
4908 St =
Value.subtract(One, RM);
4912 if (!checkConst(SubobjType))
4924 LVal.setFrom(Info.Ctx, Subobj);
4928 LVal.moveInto(Subobj);
4937 if (LVal.Designator.Invalid)
4940 if (!Info.getLangOpts().CPlusPlus14) {
4947 IncDecSubobjectHandler Handler = {Info, cast<UnaryOperator>(
E), AK, Old};
4948 return Obj &&
findSubobject(Info,
E, Obj, LVal.Designator, Handler);
4954 if (Object->getType()->isPointerType() && Object->isPRValue())
4957 if (Object->isGLValue())
4960 if (Object->getType()->isLiteralType(Info.Ctx))
4963 if (Object->getType()->isRecordType() && Object->isPRValue())
4966 Info.FFDiag(Object, diag::note_constexpr_nonliteral) << Object->getType();
4985 bool IncludeMember =
true) {
4992 if (!MemPtr.getDecl()) {
4998 if (MemPtr.isDerivedMember()) {
5002 if (LV.Designator.MostDerivedPathLength + MemPtr.Path.size() >
5003 LV.Designator.Entries.size()) {
5007 unsigned PathLengthToMember =
5008 LV.Designator.Entries.size() - MemPtr.Path.size();
5009 for (
unsigned I = 0, N = MemPtr.Path.size(); I != N; ++I) {
5011 LV.Designator.Entries[PathLengthToMember + I]);
5021 PathLengthToMember))
5023 }
else if (!MemPtr.Path.empty()) {
5025 LV.Designator.Entries.reserve(LV.Designator.Entries.size() +
5026 MemPtr.Path.size() + IncludeMember);
5032 assert(RD &&
"member pointer access on non-class-type expression");
5034 for (
unsigned I = 1, N = MemPtr.Path.size(); I != N; ++I) {
5042 MemPtr.getContainingRecord()))
5047 if (IncludeMember) {
5048 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(MemPtr.getDecl())) {
5052 dyn_cast<IndirectFieldDecl>(MemPtr.getDecl())) {
5056 llvm_unreachable(
"can't construct reference to bound member function");
5060 return MemPtr.getDecl();
5066 bool IncludeMember =
true) {
5070 if (Info.noteFailure()) {
5078 BO->
getRHS(), IncludeMember);
5085 SubobjectDesignator &
D = Result.Designator;
5086 if (
D.Invalid || !Result.checkNullPointer(Info,
E,
CSK_Derived))
5094 if (
D.MostDerivedPathLength +
E->path_size() >
D.Entries.size()) {
5095 Info.CCEDiag(
E, diag::note_constexpr_invalid_downcast)
5096 <<
D.MostDerivedType << TargetQT;
5102 unsigned NewEntriesSize =
D.Entries.size() -
E->path_size();
5105 if (NewEntriesSize ==
D.MostDerivedPathLength)
5106 FinalType =
D.MostDerivedType->getAsCXXRecordDecl();
5108 FinalType = getAsBaseClass(
D.Entries[NewEntriesSize - 1]);
5110 Info.CCEDiag(
E, diag::note_constexpr_invalid_downcast)
5111 <<
D.MostDerivedType << TargetQT;
5125 if (!Result.isAbsent())
5129 if (RD->isInvalidDecl()) {
5133 if (RD->isUnion()) {
5138 std::distance(RD->field_begin(), RD->field_end()));
5142 End = RD->bases_end();
5143 I != End; ++I, ++Index)
5147 for (
const auto *I : RD->fields()) {
5148 if (I->isUnnamedBitField())
5151 I->getType(), Result.getStructField(I->getFieldIndex()));
5159 if (Result.hasArrayFiller())
5171enum EvalStmtResult {
5195 APValue &Val = Info.CurrentCall->createTemporary(VD, VD->
getType(),
5196 ScopeKind::Block, Result);
5201 return Info.noteSideEffect();
5220 if (
const VarDecl *VD = dyn_cast<VarDecl>(
D))
5224 for (
auto *BD : DD->bindings())
5225 if (
auto *VD = BD->getHoldingVar())
5233 if (Info.noteSideEffect())
5235 assert(
E->
containsErrors() &&
"valid value-dependent expression should never "
5236 "reach invalid code path.");
5242 const Expr *Cond,
bool &Result) {
5245 FullExpressionRAII
Scope(Info);
5250 return Scope.destroy();
5263struct TempVersionRAII {
5264 CallStackFrame &Frame;
5266 TempVersionRAII(CallStackFrame &Frame) : Frame(Frame) {
5267 Frame.pushTempVersion();
5270 ~TempVersionRAII() {
5271 Frame.popTempVersion();
5285 BlockScopeRAII
Scope(Info);
5287 EvalStmtResult ESR =
EvaluateStmt(Result, Info, Body, Case);
5288 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5293 return ESR_Succeeded;
5296 return ESR_Continue;
5299 case ESR_CaseNotFound:
5302 llvm_unreachable(
"Invalid EvalStmtResult!");
5308 BlockScopeRAII
Scope(Info);
5315 if (ESR != ESR_Succeeded) {
5316 if (ESR != ESR_Failed && !
Scope.destroy())
5322 FullExpressionRAII CondScope(Info);
5334 if (!CondScope.destroy())
5343 if (isa<DefaultStmt>(SC)) {
5348 const CaseStmt *CS = cast<CaseStmt>(SC);
5359 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5363 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5368 return ESR_Succeeded;
5374 case ESR_CaseNotFound:
5377 Info.FFDiag(
Found->getBeginLoc(),
5378 diag::note_constexpr_stmt_expr_unsupported);
5381 llvm_unreachable(
"Invalid EvalStmtResult!");
5391 Info.CCEDiag(VD->
getLocation(), diag::note_constexpr_static_local)
5401 if (!Info.nextStep(S))
5407 switch (S->getStmtClass()) {
5408 case Stmt::CompoundStmtClass:
5412 case Stmt::LabelStmtClass:
5413 case Stmt::AttributedStmtClass:
5414 case Stmt::DoStmtClass:
5417 case Stmt::CaseStmtClass:
5418 case Stmt::DefaultStmtClass:
5423 case Stmt::IfStmtClass: {
5426 const IfStmt *IS = cast<IfStmt>(S);
5430 BlockScopeRAII
Scope(Info);
5436 if (ESR != ESR_CaseNotFound) {
5437 assert(ESR != ESR_Succeeded);
5448 if (ESR == ESR_Failed)
5450 if (ESR != ESR_CaseNotFound)
5451 return Scope.destroy() ? ESR : ESR_Failed;
5453 return ESR_CaseNotFound;
5456 if (ESR == ESR_Failed)
5458 if (ESR != ESR_CaseNotFound)
5459 return Scope.destroy() ? ESR : ESR_Failed;
5460 return ESR_CaseNotFound;
5463 case Stmt::WhileStmtClass: {
5464 EvalStmtResult ESR =
5466 if (ESR != ESR_Continue)
5471 case Stmt::ForStmtClass: {
5472 const ForStmt *FS = cast<ForStmt>(S);
5473 BlockScopeRAII
Scope(Info);
5477 if (
const Stmt *
Init = FS->getInit()) {
5479 if (ESR != ESR_CaseNotFound) {
5480 assert(ESR != ESR_Succeeded);
5485 EvalStmtResult ESR =
5487 if (ESR != ESR_Continue)
5489 if (
const auto *Inc = FS->getInc()) {
5490 if (Inc->isValueDependent()) {
5494 FullExpressionRAII IncScope(Info);
5502 case Stmt::DeclStmtClass: {
5505 const DeclStmt *DS = cast<DeclStmt>(S);
5506 for (
const auto *
D : DS->
decls()) {
5507 if (
const auto *VD = dyn_cast<VarDecl>(
D)) {
5510 if (VD->hasLocalStorage() && !VD->getInit())
5518 return ESR_CaseNotFound;
5522 return ESR_CaseNotFound;
5526 switch (S->getStmtClass()) {
5528 if (
const Expr *
E = dyn_cast<Expr>(S)) {
5537 FullExpressionRAII
Scope(Info);
5541 return ESR_Succeeded;
5544 Info.FFDiag(S->getBeginLoc()) << S->getSourceRange();
5547 case Stmt::NullStmtClass:
5548 return ESR_Succeeded;
5550 case Stmt::DeclStmtClass: {
5551 const DeclStmt *DS = cast<DeclStmt>(S);
5552 for (
const auto *
D : DS->
decls()) {
5553 const VarDecl *VD = dyn_cast_or_null<VarDecl>(
D);
5557 FullExpressionRAII
Scope(Info);
5560 if (!
Scope.destroy())
5563 return ESR_Succeeded;
5566 case Stmt::ReturnStmtClass: {
5567 const Expr *RetExpr = cast<ReturnStmt>(S)->getRetValue();
5568 FullExpressionRAII
Scope(Info);
5577 :
Evaluate(Result.Value, Info, RetExpr)))
5579 return Scope.destroy() ? ESR_Returned : ESR_Failed;
5582 case Stmt::CompoundStmtClass: {
5583 BlockScopeRAII
Scope(Info);
5586 for (
const auto *BI : CS->
body()) {
5587 EvalStmtResult ESR =
EvaluateStmt(Result, Info, BI, Case);
5588 if (ESR == ESR_Succeeded)
5590 else if (ESR != ESR_CaseNotFound) {
5591 if (ESR != ESR_Failed && !
Scope.destroy())
5597 return ESR_CaseNotFound;
5598 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5601 case Stmt::IfStmtClass: {
5602 const IfStmt *IS = cast<IfStmt>(S);
5605 BlockScopeRAII
Scope(Info);
5608 if (ESR != ESR_Succeeded) {
5609 if (ESR != ESR_Failed && !
Scope.destroy())
5619 if (!Info.InConstantContext)
5626 EvalStmtResult ESR =
EvaluateStmt(Result, Info, SubStmt);
5627 if (ESR != ESR_Succeeded) {
5628 if (ESR != ESR_Failed && !
Scope.destroy())
5633 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5636 case Stmt::WhileStmtClass: {
5637 const WhileStmt *WS = cast<WhileStmt>(S);
5639 BlockScopeRAII
Scope(Info);
5648 if (ESR != ESR_Continue) {
5649 if (ESR != ESR_Failed && !
Scope.destroy())
5653 if (!
Scope.destroy())
5656 return ESR_Succeeded;
5659 case Stmt::DoStmtClass: {
5660 const DoStmt *DS = cast<DoStmt>(S);
5664 if (ESR != ESR_Continue)
5673 FullExpressionRAII CondScope(Info);
5675 !CondScope.destroy())
5678 return ESR_Succeeded;
5681 case Stmt::ForStmtClass: {
5682 const ForStmt *FS = cast<ForStmt>(S);
5683 BlockScopeRAII ForScope(Info);
5684 if (FS->getInit()) {
5685 EvalStmtResult ESR =
EvaluateStmt(Result, Info, FS->getInit());
5686 if (ESR != ESR_Succeeded) {
5687 if (ESR != ESR_Failed && !ForScope.destroy())
5693 BlockScopeRAII IterScope(Info);
5694 bool Continue =
true;
5695 if (FS->getCond() && !
EvaluateCond(Info, FS->getConditionVariable(),
5696 FS->getCond(), Continue))
5702 if (ESR != ESR_Continue) {
5703 if (ESR != ESR_Failed && (!IterScope.destroy() || !ForScope.destroy()))
5708 if (
const auto *Inc = FS->getInc()) {
5709 if (Inc->isValueDependent()) {
5713 FullExpressionRAII IncScope(Info);
5719 if (!IterScope.destroy())
5722 return ForScope.destroy() ? ESR_Succeeded : ESR_Failed;
5725 case Stmt::CXXForRangeStmtClass: {
5727 BlockScopeRAII
Scope(Info);
5730 if (FS->getInit()) {
5731 EvalStmtResult ESR =
EvaluateStmt(Result, Info, FS->getInit());
5732 if (ESR != ESR_Succeeded) {
5733 if (ESR != ESR_Failed && !
Scope.destroy())
5740 EvalStmtResult ESR =
EvaluateStmt(Result, Info, FS->getRangeStmt());
5741 if (ESR != ESR_Succeeded) {
5742 if (ESR != ESR_Failed && !
Scope.destroy())
5749 if (!FS->getBeginStmt() || !FS->getEndStmt() || !FS->getCond())
5754 if (ESR != ESR_Succeeded) {
5755 if (ESR != ESR_Failed && !
Scope.destroy())
5760 if (ESR != ESR_Succeeded) {
5761 if (ESR != ESR_Failed && !
Scope.destroy())
5769 if (FS->getCond()->isValueDependent()) {
5774 bool Continue =
true;
5775 FullExpressionRAII CondExpr(Info);
5783 BlockScopeRAII InnerScope(Info);
5784 ESR =
EvaluateStmt(Result, Info, FS->getLoopVarStmt());
5785 if (ESR != ESR_Succeeded) {
5786 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
5793 if (ESR != ESR_Continue) {
5794 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
5798 if (FS->getInc()->isValueDependent()) {
5807 if (!InnerScope.destroy())
5811 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5814 case Stmt::SwitchStmtClass:
5817 case Stmt::ContinueStmtClass:
5818 return ESR_Continue;
5820 case Stmt::BreakStmtClass:
5823 case Stmt::LabelStmtClass:
5824 return EvaluateStmt(Result, Info, cast<LabelStmt>(S)->getSubStmt(), Case);
5826 case Stmt::AttributedStmtClass: {
5827 const auto *AS = cast<AttributedStmt>(S);
5828 const auto *SS = AS->getSubStmt();
5829 MSConstexprContextRAII ConstexprContext(
5830 *Info.CurrentCall, hasSpecificAttr<MSConstexprAttr>(AS->getAttrs()) &&
5831 isa<ReturnStmt>(SS));
5833 auto LO = Info.getASTContext().getLangOpts();
5834 if (LO.CXXAssumptions && !LO.MSVCCompat) {
5835 for (
auto *
Attr : AS->getAttrs()) {
5836 auto *AA = dyn_cast<CXXAssumeAttr>(
Attr);
5840 auto *Assumption = AA->getAssumption();
5841 if (Assumption->isValueDependent())
5844 if (Assumption->HasSideEffects(Info.getASTContext()))
5851 Info.CCEDiag(Assumption->getExprLoc(),
5852 diag::note_constexpr_assumption_failed);
5861 case Stmt::CaseStmtClass:
5862 case Stmt::DefaultStmtClass:
5863 return EvaluateStmt(Result, Info, cast<SwitchCase>(S)->getSubStmt(), Case);
5864 case Stmt::CXXTryStmtClass:
5866 return EvaluateStmt(Result, Info, cast<CXXTryStmt>(S)->getTryBlock(), Case);
5876 bool IsValueInitialization) {
5883 if (!CD->
isConstexpr() && !IsValueInitialization) {
5884 if (Info.getLangOpts().CPlusPlus11) {
5887 Info.CCEDiag(
Loc, diag::note_constexpr_invalid_function, 1)
5889 Info.Note(CD->
getLocation(), diag::note_declared_at);
5891 Info.CCEDiag(
Loc, diag::note_invalid_subexpr_in_const_expr);
5905 if (Info.checkingPotentialConstantExpression() && !
Definition &&
5913 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
5920 if (!Info.Ctx.getLangOpts().CPlusPlus20 && isa<CXXMethodDecl>(
Declaration) &&
5922 Info.CCEDiag(CallLoc, diag::note_constexpr_virtual_call);
5925 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
5931 (
Definition->isConstexpr() || (Info.CurrentCall->CanEvalMSConstexpr &&
5935 if (Info.getLangOpts().CPlusPlus11) {
5940 auto *CD = dyn_cast<CXXConstructorDecl>(DiagDecl);
5941 if (CD && CD->isInheritingConstructor()) {
5942 auto *Inherited = CD->getInheritedConstructor().getConstructor();
5943 if (!Inherited->isConstexpr())
5944 DiagDecl = CD = Inherited;
5950 if (CD && CD->isInheritingConstructor())
5951 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_inhctor, 1)
5952 << CD->getInheritedConstructor().getConstructor()->
getParent();
5954 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_function, 1)
5956 Info.Note(DiagDecl->
getLocation(), diag::note_declared_at);
5958 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
5964struct CheckDynamicTypeHandler {
5966 typedef bool result_type;
5967 bool failed() {
return false; }
5970 bool found(APFloat &
Value,
QualType SubobjType) {
return true; }
5984 if (This.allowConstexprUnknown())
5987 if (This.Designator.Invalid)
5999 if (This.Designator.isOnePastTheEnd() ||
6000 This.Designator.isMostDerivedAnUnsizedArray()) {
6001 Info.FFDiag(
E, This.Designator.isOnePastTheEnd()
6002 ? diag::note_constexpr_access_past_end
6003 : diag::note_constexpr_access_unsized_array)
6006 }
else if (Polymorphic) {
6012 Info.Ctx.getLValueReferenceType(This.Designator.getType(Info.Ctx));
6013 Info.FFDiag(
E, diag::note_constexpr_polymorphic_unknown_dynamic_type)
6020 CheckDynamicTypeHandler Handler{AK};
6021 return Obj &&
findSubobject(Info,
E, Obj, This.Designator, Handler);
6043 unsigned PathLength) {
6044 assert(PathLength >=
Designator.MostDerivedPathLength && PathLength <=
6045 Designator.Entries.size() &&
"invalid path length");
6046 return (PathLength ==
Designator.MostDerivedPathLength)
6047 ?
Designator.MostDerivedType->getAsCXXRecordDecl()
6048 : getAsBaseClass(
Designator.Entries[PathLength - 1]);
6063 return std::nullopt;
6065 if (This.Designator.Invalid)
6066 return std::nullopt;
6075 This.Designator.MostDerivedType->getAsCXXRecordDecl();
6078 return std::nullopt;
6086 for (
unsigned PathLength = This.Designator.MostDerivedPathLength;
6087 PathLength <=
Path.size(); ++PathLength) {
6088 switch (Info.isEvaluatingCtorDtor(This.getLValueBase(),
6089 Path.slice(0, PathLength))) {
6090 case ConstructionPhase::Bases:
6091 case ConstructionPhase::DestroyingBases:
6096 case ConstructionPhase::None:
6097 case ConstructionPhase::AfterBases:
6098 case ConstructionPhase::AfterFields:
6099 case ConstructionPhase::Destroying:
6111 return std::nullopt;
6129 unsigned PathLength = DynType->PathLength;
6130 for (; PathLength <= This.Designator.Entries.size(); ++PathLength) {
6133 Found->getCorrespondingMethodDeclaredInClass(
Class,
false);
6143 if (Callee->isPureVirtual()) {
6144 Info.FFDiag(
E, diag::note_constexpr_pure_virtual_call, 1) << Callee;
6145 Info.Note(Callee->getLocation(), diag::note_declared_at);
6151 if (!Info.Ctx.hasSameUnqualifiedType(Callee->getReturnType(),
6152 Found->getReturnType())) {
6153 CovariantAdjustmentPath.push_back(Callee->getReturnType());
6154 for (
unsigned CovariantPathLength = PathLength + 1;
6155 CovariantPathLength != This.Designator.Entries.size();
6156 ++CovariantPathLength) {
6160 Found->getCorrespondingMethodDeclaredInClass(NextClass,
false);
6161 if (Next && !Info.Ctx.hasSameUnqualifiedType(
6162 Next->getReturnType(), CovariantAdjustmentPath.back()))
6163 CovariantAdjustmentPath.push_back(Next->getReturnType());
6165 if (!Info.Ctx.hasSameUnqualifiedType(
Found->getReturnType(),
6166 CovariantAdjustmentPath.back()))
6167 CovariantAdjustmentPath.push_back(
Found->getReturnType());
6183 assert(Result.isLValue() &&
6184 "unexpected kind of APValue for covariant return");
6185 if (Result.isNullPointer())
6189 LVal.setFrom(Info.Ctx, Result);
6192 for (
unsigned I = 1; I !=
Path.size(); ++I) {
6194 assert(OldClass && NewClass &&
"unexpected kind of covariant return");
6195 if (OldClass != NewClass &&
6198 OldClass = NewClass;
6201 LVal.moveInto(Result);
6210 auto *BaseClass = BaseSpec.getType()->getAsCXXRecordDecl();
6212 return BaseSpec.getAccessSpecifier() ==
AS_public;
6214 llvm_unreachable(
"Base is not a direct base of Derived");
6224 SubobjectDesignator &
D = Ptr.Designator;
6236 std::optional<DynamicType> DynType =
6247 const CXXRecordDecl *
C =
E->getTypeAsWritten()->getPointeeCXXRecordDecl();
6248 assert(
C &&
"dynamic_cast target is not void pointer nor class");
6249 CanQualType CQT = Info.Ctx.getCanonicalType(Info.Ctx.getRecordType(
C));
6256 Ptr.setNull(Info.Ctx,
E->
getType());
6263 DynType->Type->isDerivedFrom(
C)))
6265 else if (!Paths || Paths->begin() == Paths->end())
6267 else if (Paths->isAmbiguous(CQT))
6270 assert(Paths->front().Access !=
AS_public &&
"why did the cast fail?");
6273 Info.FFDiag(
E, diag::note_constexpr_dynamic_cast_to_reference_failed)
6274 << DiagKind << Ptr.Designator.getType(Info.Ctx)
6275 << Info.Ctx.getRecordType(DynType->Type)
6283 for (
int PathLength = Ptr.Designator.Entries.size();
6284 PathLength >= (
int)DynType->PathLength; --PathLength) {
6289 if (PathLength > (
int)DynType->PathLength &&
6292 return RuntimeCheckFailed(
nullptr);
6299 if (DynType->Type->isDerivedFrom(
C, Paths) && !Paths.isAmbiguous(CQT) &&
6312 return RuntimeCheckFailed(&Paths);
6316struct StartLifetimeOfUnionMemberHandler {
6318 const Expr *LHSExpr;
6321 bool Failed =
false;
6324 typedef bool result_type;
6325 bool failed() {
return Failed; }
6341 }
else if (DuringInit) {
6345 Info.FFDiag(LHSExpr,
6346 diag::note_constexpr_union_member_change_during_init);
6355 llvm_unreachable(
"wrong value kind for union object");
6358 llvm_unreachable(
"wrong value kind for union object");
6363const AccessKinds StartLifetimeOfUnionMemberHandler::AccessKind;
6370 const Expr *LHSExpr,
6371 const LValue &LHS) {
6372 if (LHS.InvalidBase || LHS.Designator.Invalid)
6378 unsigned PathLength = LHS.Designator.Entries.size();
6379 for (
const Expr *
E = LHSExpr;
E !=
nullptr;) {
6381 if (
auto *ME = dyn_cast<MemberExpr>(
E)) {
6382 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
6385 if (!FD || FD->getType()->isReferenceType())
6389 if (FD->getParent()->isUnion()) {
6394 FD->getType()->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
6395 if (!RD || RD->hasTrivialDefaultConstructor())
6396 UnionPathLengths.push_back({PathLength - 1, FD});
6402 LHS.Designator.Entries[PathLength]
6403 .getAsBaseOrMember().getPointer()));
6407 }
else if (
auto *ASE = dyn_cast<ArraySubscriptExpr>(
E)) {
6409 auto *
Base = ASE->getBase()->IgnoreImplicit();
6410 if (!
Base->getType()->isArrayType())
6416 }
else if (
auto *ICE = dyn_cast<ImplicitCastExpr>(
E)) {
6418 E = ICE->getSubExpr();
6419 if (ICE->getCastKind() == CK_NoOp)
6421 if (ICE->getCastKind() != CK_DerivedToBase &&
6422 ICE->getCastKind() != CK_UncheckedDerivedToBase)
6426 if (Elt->isVirtual()) {
6435 LHS.Designator.Entries[PathLength]
6436 .getAsBaseOrMember().getPointer()));
6446 if (UnionPathLengths.empty())
6451 CompleteObject Obj =
6455 for (std::pair<unsigned, const FieldDecl *> LengthAndField :
6456 llvm::reverse(UnionPathLengths)) {
6458 SubobjectDesignator
D = LHS.Designator;
6459 D.truncate(Info.Ctx, LHS.Base, LengthAndField.first);
6461 bool DuringInit = Info.isEvaluatingCtorDtor(LHS.Base,
D.Entries) ==
6462 ConstructionPhase::AfterBases;
6463 StartLifetimeOfUnionMemberHandler StartLifetime{
6464 Info, LHSExpr, LengthAndField.second, DuringInit};
6473 CallRef
Call, EvalInfo &Info,
6481 APValue &
V = PVD ? Info.CurrentCall->createParam(
Call, PVD, LV)
6482 : Info.CurrentCall->createTemporary(Arg, Arg->
getType(),
6483 ScopeKind::Call, LV);
6489 if (
NonNull &&
V.isLValue() &&
V.isNullPointer()) {
6490 Info.CCEDiag(Arg, diag::note_non_null_attribute_failed);
6500 bool RightToLeft =
false) {
6502 llvm::SmallBitVector ForbiddenNullArgs;
6503 if (Callee->hasAttr<NonNullAttr>()) {
6504 ForbiddenNullArgs.resize(Args.size());
6505 for (
const auto *
Attr : Callee->specific_attrs<NonNullAttr>()) {
6506 if (!
Attr->args_size()) {
6507 ForbiddenNullArgs.set();
6510 for (
auto Idx :
Attr->args()) {
6511 unsigned ASTIdx = Idx.getASTIndex();
6512 if (ASTIdx >= Args.size())
6514 ForbiddenNullArgs[ASTIdx] =
true;
6518 for (
unsigned I = 0; I < Args.size(); I++) {
6519 unsigned Idx = RightToLeft ? Args.size() - I - 1 : I;
6521 Idx < Callee->getNumParams() ? Callee->getParamDecl(Idx) :
nullptr;
6522 bool NonNull = !ForbiddenNullArgs.empty() && ForbiddenNullArgs[Idx];
6526 if (!Info.noteFailure())
6538 bool CopyObjectRepresentation) {
6540 CallStackFrame *Frame = Info.CurrentCall;
6541 APValue *RefValue = Info.getParamSlot(Frame->Arguments, Param);
6549 RefLValue.setFrom(Info.Ctx, *RefValue);
6552 CopyObjectRepresentation);
6559 CallRef
Call,
const Stmt *Body, EvalInfo &Info,
6560 APValue &Result,
const LValue *ResultSlot) {
6561 if (!Info.CheckCallLimit(CallLoc))
6586 This->moveInto(Result);
6595 if (!Info.checkingPotentialConstantExpression())
6597 Frame.LambdaThisCaptureField);
6602 if (ESR == ESR_Succeeded) {
6603 if (Callee->getReturnType()->isVoidType())
6605 Info.FFDiag(Callee->getEndLoc(), diag::note_constexpr_no_return);
6607 return ESR == ESR_Returned;
6614 EvalInfo &Info,
APValue &Result) {
6616 if (!Info.CheckCallLimit(CallLoc))
6621 Info.FFDiag(CallLoc, diag::note_constexpr_virtual_base) << RD;
6625 EvalInfo::EvaluatingConstructorRAII EvalObj(
6627 ObjectUnderConstruction{This.getLValueBase(), This.Designator.Entries},
6639 if ((*I)->getInit()->isValueDependent()) {
6643 FullExpressionRAII InitScope(Info);
6645 !InitScope.destroy())
6668 if (!Result.hasValue()) {
6681 BlockScopeRAII LifetimeExtendedScope(Info);
6684 unsigned BasesSeen = 0;
6694 assert(
Indirect &&
"fields out of order?");
6700 assert(FieldIt != RD->
field_end() &&
"missing field?");
6701 if (!FieldIt->isUnnamedBitField())
6704 Result.getStructField(FieldIt->getFieldIndex()));
6709 LValue Subobject = This;
6710 LValue SubobjectParent = This;
6715 if (I->isBaseInitializer()) {
6716 QualType BaseType(I->getBaseClass(), 0);
6720 assert(!BaseIt->
isVirtual() &&
"virtual base for literal type");
6721 assert(Info.Ctx.hasSameUnqualifiedType(BaseIt->
getType(), BaseType) &&
6722 "base class initializers not in expected order");
6728 Value = &Result.getStructBase(BasesSeen++);
6729 }
else if ((FD = I->getMember())) {
6734 Value = &Result.getUnionValue();
6736 SkipToField(FD,
false);
6742 auto IndirectFieldChain = IFD->chain();
6743 for (
auto *
C : IndirectFieldChain) {
6744 FD = cast<FieldDecl>(
C);
6752 (
Value->isUnion() &&
Value->getUnionField() != FD)) {
6764 if (
C == IndirectFieldChain.back())
6765 SubobjectParent = Subobject;
6771 if (
C == IndirectFieldChain.front() && !RD->
isUnion())
6772 SkipToField(FD,
true);
6777 llvm_unreachable(
"unknown base initializer kind");
6784 if (
Init->isValueDependent()) {
6788 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &SubobjectParent,
6789 isa<CXXDefaultInitExpr>(
Init));
6790 FullExpressionRAII InitScope(Info);
6796 if (!Info.noteFailure())
6804 if (I->isBaseInitializer() && BasesSeen == RD->
getNumBases())
6805 EvalObj.finishedConstructingBases();
6810 for (; FieldIt != RD->
field_end(); ++FieldIt) {
6811 if (!FieldIt->isUnnamedBitField())
6814 Result.getStructField(FieldIt->getFieldIndex()));
6818 EvalObj.finishedConstructingFields();
6822 LifetimeExtendedScope.destroy();
6828 EvalInfo &Info,
APValue &Result) {
6829 CallScopeRAII CallScope(Info);
6835 CallScope.destroy();
6847 This.moveInto(Printable);
6849 diag::note_constexpr_destroy_out_of_lifetime)
6850 << Printable.
getAsString(Info.Ctx, Info.Ctx.getLValueReferenceType(
T));
6866 LValue ElemLV = This;
6867 ElemLV.addArray(Info, &LocE, CAT);
6874 if (Size && Size >
Value.getArrayInitializedElts())
6879 for (Size =
Value.getArraySize(); Size != 0; --Size) {
6880 APValue &Elem =
Value.getArrayInitializedElt(Size - 1);
6893 if (
T.isDestructedType()) {
6895 diag::note_constexpr_unsupported_destruction)
6905 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_virtual_base) << RD;
6930 if (!Info.CheckCallLimit(CallRange.
getBegin()))
6939 CallStackFrame Frame(Info, CallRange,
Definition, &This,
nullptr,
6944 EvalInfo::EvaluatingDestructorRAII EvalObj(
6946 ObjectUnderConstruction{This.getLValueBase(), This.Designator.Entries});
6947 if (!EvalObj.DidInsert) {
6954 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_double_destroy);
6974 for (
const FieldDecl *FD : llvm::reverse(Fields)) {
6975 if (FD->isUnnamedBitField())
6978 LValue Subobject = This;
6982 APValue *SubobjectValue = &
Value.getStructField(FD->getFieldIndex());
6989 EvalObj.startedDestroyingBases();
6996 LValue Subobject = This;
7001 APValue *SubobjectValue = &
Value.getStructBase(BasesLeft);
7006 assert(BasesLeft == 0 &&
"NumBases was wrong?");
7014struct DestroyObjectHandler {
7020 typedef bool result_type;
7021 bool failed() {
return false; }
7027 Info.FFDiag(
E, diag::note_constexpr_destroy_complex_elem);
7031 Info.FFDiag(
E, diag::note_constexpr_destroy_complex_elem);
7040 const LValue &This,
QualType ThisType) {
7042 DestroyObjectHandler Handler = {Info,
E, This,
AK_Destroy};
7043 return Obj &&
findSubobject(Info,
E, Obj, This.Designator, Handler);
7052 if (Info.EvalStatus.HasSideEffects)
7063 if (Info.checkingPotentialConstantExpression() ||
7064 Info.SpeculativeEvaluationDepth)
7068 auto Caller = Info.getStdAllocatorCaller(
"allocate");
7070 Info.FFDiag(
E->
getExprLoc(), Info.getLangOpts().CPlusPlus20
7071 ? diag::note_constexpr_new_untyped
7072 : diag::note_constexpr_new);
7076 QualType ElemType = Caller.ElemType;
7079 diag::note_constexpr_new_not_complete_object_type)
7087 bool IsNothrow =
false;
7088 for (
unsigned I = 1, N =
E->getNumArgs(); I != N; ++I) {
7096 APInt Size, Remainder;
7097 APInt ElemSizeAP(ByteSize.getBitWidth(), ElemSize.
getQuantity());
7098 APInt::udivrem(ByteSize, ElemSizeAP, Size, Remainder);
7099 if (Remainder != 0) {
7101 Info.FFDiag(
E->
getExprLoc(), diag::note_constexpr_operator_new_bad_size)
7102 << ByteSize <<
APSInt(ElemSizeAP,
true) << ElemType;
7106 if (!Info.CheckArraySize(
E->
getBeginLoc(), ByteSize.getActiveBits(),
7107 Size.getZExtValue(), !IsNothrow)) {
7109 Result.setNull(Info.Ctx,
E->
getType());
7115 QualType AllocType = Info.Ctx.getConstantArrayType(
7116 ElemType, Size,
nullptr, ArraySizeModifier::Normal, 0);
7117 APValue *Val = Info.createHeapAlloc(Caller.Call, AllocType, Result);
7119 Result.addArray(Info,
E, cast<ConstantArrayType>(AllocType));
7126 return DD->isVirtual();
7133 return DD->isVirtual() ? DD->getOperatorDelete() :
nullptr;
7144 DynAlloc::Kind DeallocKind) {
7145 auto PointerAsString = [&] {
7146 return Pointer.toString(Info.Ctx, Info.Ctx.VoidPtrTy);
7151 Info.FFDiag(
E, diag::note_constexpr_delete_not_heap_alloc)
7152 << PointerAsString();
7155 return std::nullopt;
7158 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
7160 Info.FFDiag(
E, diag::note_constexpr_double_delete);
7161 return std::nullopt;
7164 if (DeallocKind != (*Alloc)->getKind()) {
7166 Info.FFDiag(
E, diag::note_constexpr_new_delete_mismatch)
7167 << DeallocKind << (*Alloc)->getKind() << AllocType;
7169 return std::nullopt;
7172 bool Subobject =
false;
7173 if (DeallocKind == DynAlloc::New) {
7174 Subobject =
Pointer.Designator.MostDerivedPathLength != 0 ||
7175 Pointer.Designator.isOnePastTheEnd();
7177 Subobject =
Pointer.Designator.Entries.size() != 1 ||
7178 Pointer.Designator.Entries[0].getAsArrayIndex() != 0;
7181 Info.FFDiag(
E, diag::note_constexpr_delete_subobject)
7182 << PointerAsString() <<
Pointer.Designator.isOnePastTheEnd();
7183 return std::nullopt;
7191 if (Info.checkingPotentialConstantExpression() ||
7192 Info.SpeculativeEvaluationDepth)
7196 if (!Info.getStdAllocatorCaller(
"deallocate")) {
7204 for (
unsigned I = 1, N =
E->getNumArgs(); I != N; ++I)
7207 if (
Pointer.Designator.Invalid)
7212 if (
Pointer.isNullPointer()) {
7213 Info.CCEDiag(
E->
getExprLoc(), diag::note_constexpr_deallocate_null);
7229class BitCastBuffer {
7237 static_assert(std::numeric_limits<unsigned char>::digits >= 8,
7238 "Need at least 8 bit unsigned char");
7240 bool TargetIsLittleEndian;
7243 BitCastBuffer(
CharUnits Width,
bool TargetIsLittleEndian)
7244 : Bytes(Width.getQuantity()),
7245 TargetIsLittleEndian(TargetIsLittleEndian) {}
7249 for (
CharUnits I = Offset,
E = Offset + Width; I !=
E; ++I) {
7252 if (!Bytes[I.getQuantity()])
7254 Output.push_back(*Bytes[I.getQuantity()]);
7256 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
7257 std::reverse(Output.begin(), Output.end());
7262 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
7263 std::reverse(Input.begin(), Input.end());
7266 for (
unsigned char Byte : Input) {
7267 assert(!Bytes[Offset.getQuantity() + Index] &&
"overwriting a byte?");
7268 Bytes[Offset.getQuantity() + Index] = Byte;
7273 size_t size() {
return Bytes.size(); }
7278class APValueToBufferConverter {
7280 BitCastBuffer Buffer;
7283 APValueToBufferConverter(EvalInfo &Info,
CharUnits ObjectWidth,
7286 Buffer(ObjectWidth, Info.Ctx.getTargetInfo().isLittleEndian()),
7295 assert((
size_t)Offset.getQuantity() <= Buffer.size());
7308 return visitInt(Val.
getInt(), Ty, Offset);
7310 return visitFloat(Val.
getFloat(), Ty, Offset);
7312 return visitArray(Val, Ty, Offset);
7314 return visitRecord(Val, Ty, Offset);
7316 return visitVector(Val, Ty, Offset);
7320 return visitComplex(Val, Ty, Offset);
7328 diag::note_constexpr_bit_cast_unsupported_type)
7334 llvm_unreachable(
"LValue subobject in bit_cast?");
7336 llvm_unreachable(
"Unhandled APValue::ValueKind");
7344 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
7345 for (
size_t I = 0,
E = CXXRD->getNumBases(); I !=
E; ++I) {
7356 unsigned FieldIdx = 0;
7358 if (FD->isBitField()) {
7360 diag::note_constexpr_bit_cast_unsupported_bitfield);
7366 assert(FieldOffsetBits % Info.Ctx.getCharWidth() == 0 &&
7367 "only bit-fields can have sub-char alignment");
7369 Info.Ctx.toCharUnitsFromBits(FieldOffsetBits) + Offset;
7389 for (
unsigned I = 0; I != NumInitializedElts; ++I) {
7391 if (!visit(SubObj, CAT->
getElementType(), Offset + I * ElemWidth))
7398 for (
unsigned I = NumInitializedElts; I != ArraySize; ++I) {
7399 if (!visit(Filler, CAT->
getElementType(), Offset + I * ElemWidth))
7410 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
7415 Offset + (0 * EltSizeChars)))
7418 Offset + (1 * EltSizeChars)))
7422 Offset + (0 * EltSizeChars)))
7425 Offset + (1 * EltSizeChars)))
7446 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
7448 llvm::APInt Res = llvm::APInt::getZero(NElts);
7449 for (
unsigned I = 0; I < NElts; ++I) {
7451 assert(EltAsInt.isUnsigned() && EltAsInt.getBitWidth() == 1 &&
7452 "bool vector element must be 1-bit unsigned integer!");
7454 Res.insertBits(EltAsInt, BigEndian ? (NElts - I - 1) : I);
7458 llvm::StoreIntToMemory(Res, &*Bytes.begin(), NElts / 8);
7459 Buffer.writeObject(Offset, Bytes);
7463 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
7464 for (
unsigned I = 0; I < NElts; ++I) {
7465 if (!visit(Val.
getVectorElt(I), EltTy, Offset + I * EltSizeChars))
7474 APSInt AdjustedVal = Val;
7475 unsigned Width = AdjustedVal.getBitWidth();
7477 Width = Info.Ctx.getTypeSize(Ty);
7478 AdjustedVal = AdjustedVal.extend(Width);
7482 llvm::StoreIntToMemory(AdjustedVal, &*Bytes.begin(), Width / 8);
7483 Buffer.writeObject(Offset, Bytes);
7488 APSInt AsInt(Val.bitcastToAPInt());
7489 return visitInt(AsInt, Ty, Offset);
7493 static std::optional<BitCastBuffer>
7496 APValueToBufferConverter Converter(Info, DstSize, BCE);
7498 return std::nullopt;
7499 return Converter.Buffer;
7504class BufferToAPValueConverter {
7506 const BitCastBuffer &Buffer;
7509 BufferToAPValueConverter(EvalInfo &Info,
const BitCastBuffer &Buffer,
7511 : Info(Info), Buffer(Buffer), BCE(BCE) {}
7516 std::nullopt_t unsupportedType(
QualType Ty) {
7518 diag::note_constexpr_bit_cast_unsupported_type)
7520 return std::nullopt;
7523 std::nullopt_t unrepresentableValue(
QualType Ty,
const APSInt &Val) {
7525 diag::note_constexpr_bit_cast_unrepresentable_value)
7527 return std::nullopt;
7531 const EnumType *EnumSugar =
nullptr) {
7545 const llvm::fltSemantics &Semantics =
7546 Info.Ctx.getFloatTypeSemantics(
QualType(
T, 0));
7547 unsigned NumBits = llvm::APFloatBase::getSizeInBits(Semantics);
7548 assert(NumBits % 8 == 0);
7555 if (!Buffer.readObject(Offset,
SizeOf, Bytes)) {
7558 bool IsStdByte = EnumSugar && EnumSugar->isStdByteType();
7562 if (!IsStdByte && !IsUChar) {
7563 QualType DisplayType(EnumSugar ? (
const Type *)EnumSugar :
T, 0);
7565 diag::note_constexpr_bit_cast_indet_dest)
7566 << DisplayType << Info.Ctx.getLangOpts().CharIsSigned;
7567 return std::nullopt;
7573 APSInt Val(
SizeOf.getQuantity() * Info.Ctx.getCharWidth(),
true);
7574 llvm::LoadIntFromMemory(Val, &*Bytes.begin(), Bytes.size());
7579 unsigned IntWidth = Info.Ctx.getIntWidth(
QualType(
T, 0));
7580 if (IntWidth != Val.getBitWidth()) {
7581 APSInt Truncated = Val.trunc(IntWidth);
7582 if (Truncated.extend(Val.getBitWidth()) != Val)
7583 return unrepresentableValue(
QualType(
T, 0), Val);
7591 const llvm::fltSemantics &Semantics =
7592 Info.Ctx.getFloatTypeSemantics(
QualType(
T, 0));
7603 unsigned NumBases = 0;
7604 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
7605 NumBases = CXXRD->getNumBases();
7611 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
7612 for (
size_t I = 0,
E = CXXRD->getNumBases(); I !=
E; ++I) {
7616 std::optional<APValue> SubObj = visitType(
7619 return std::nullopt;
7620 ResultVal.getStructBase(I) = *SubObj;
7625 unsigned FieldIdx = 0;
7629 if (FD->isBitField()) {
7631 diag::note_constexpr_bit_cast_unsupported_bitfield);
7632 return std::nullopt;
7636 assert(FieldOffsetBits % Info.Ctx.getCharWidth() == 0);
7642 std::optional<APValue> SubObj = visitType(FieldTy, FieldOffset);
7644 return std::nullopt;
7645 ResultVal.getStructField(FieldIdx) = *SubObj;
7654 assert(!RepresentationType.
isNull() &&
7655 "enum forward decl should be caught by Sema");
7656 const auto *AsBuiltin =
7660 return visit(AsBuiltin, Offset, Ty);
7668 for (
size_t I = 0; I !=
Size; ++I) {
7669 std::optional<APValue> ElementValue =
7672 return std::nullopt;
7673 ArrayValue.getArrayInitializedElt(I) = std::move(*ElementValue);
7681 CharUnits ElementWidth = Info.Ctx.getTypeSizeInChars(ElementType);
7684 std::optional<APValue> Values[2];
7685 for (
unsigned I = 0; I != 2; ++I) {
7686 Values[I] = visitType(Ty->
getElementType(), Offset + I * ElementWidth);
7688 return std::nullopt;
7692 return APValue(Values[0]->getInt(), Values[1]->getInt());
7693 return APValue(Values[0]->getFloat(), Values[1]->getFloat());
7703 Elts.reserve(NElts);
7713 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
7716 Bytes.reserve(NElts / 8);
7718 return std::nullopt;
7720 APSInt SValInt(NElts,
true);
7721 llvm::LoadIntFromMemory(SValInt, &*Bytes.begin(), Bytes.size());
7723 for (
unsigned I = 0; I < NElts; ++I) {
7725 SValInt.extractBits(1, (BigEndian ? NElts - I - 1 : I) * EltSize);
7732 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
7733 for (
unsigned I = 0; I < NElts; ++I) {
7734 std::optional<APValue> EltValue =
7735 visitType(EltTy, Offset + I * EltSizeChars);
7737 return std::nullopt;
7738 Elts.push_back(std::move(*EltValue));
7742 return APValue(Elts.data(), Elts.size());
7745 std::optional<APValue> visit(
const Type *Ty,
CharUnits Offset) {
7746 return unsupportedType(
QualType(Ty, 0));
7753#define TYPE(Class, Base) \
7755 return visit(cast<Class##Type>(Can.getTypePtr()), Offset);
7756#define ABSTRACT_TYPE(Class, Base)
7757#define NON_CANONICAL_TYPE(Class, Base) \
7759 llvm_unreachable("non-canonical type should be impossible!");
7760#define DEPENDENT_TYPE(Class, Base) \
7763 "dependent types aren't supported in the constant evaluator!");
7764#define NON_CANONICAL_UNLESS_DEPENDENT(Class, Base) \
7766 llvm_unreachable("either dependent or not canonical!");
7767#include "clang/AST/TypeNodes.inc"
7769 llvm_unreachable(
"Unhandled Type::TypeClass");
7774 static std::optional<APValue> convert(EvalInfo &Info, BitCastBuffer &Buffer,
7776 BufferToAPValueConverter Converter(Info, Buffer, BCE);
7784 bool CheckingDest) {
7787 auto diag = [&](
int Reason) {
7789 Info->FFDiag(
Loc, diag::note_constexpr_bit_cast_invalid_type)
7790 << CheckingDest << (Reason == 4) << Reason;
7795 Info->
Note(NoteLoc, diag::note_constexpr_bit_cast_invalid_subtype)
7796 << NoteTy << Construct << Ty;
7810 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(
Record)) {
7812 if (!checkBitCastConstexprEligibilityType(
Loc, BS.
getType(), Info, Ctx,
7817 if (FD->getType()->isReferenceType())
7819 if (!checkBitCastConstexprEligibilityType(
Loc, FD->getType(), Info, Ctx,
7821 return note(0, FD->getType(), FD->getBeginLoc());
7827 Info, Ctx, CheckingDest))
7840 Info->FFDiag(
Loc, diag::note_constexpr_bit_cast_invalid_vector)
7850 Info->FFDiag(
Loc, diag::note_constexpr_bit_cast_unsupported_type)
7859static bool checkBitCastConstexprEligibility(EvalInfo *Info,
7862 bool DestOK = checkBitCastConstexprEligibilityType(
7864 bool SourceOK = DestOK && checkBitCastConstexprEligibilityType(
7870static bool handleRValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
7873 assert(
CHAR_BIT == 8 && Info.Ctx.getTargetInfo().getCharWidth() == 8 &&
7874 "no host or target supports non 8-bit chars");
7876 if (!checkBitCastConstexprEligibility(&Info, Info.Ctx, BCE))
7880 std::optional<BitCastBuffer> Buffer =
7881 APValueToBufferConverter::convert(Info, SourceRValue, BCE);
7886 std::optional<APValue> MaybeDestValue =
7887 BufferToAPValueConverter::convert(Info, *Buffer, BCE);
7888 if (!MaybeDestValue)
7891 DestValue = std::move(*MaybeDestValue);
7895static bool handleLValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
7898 assert(
CHAR_BIT == 8 && Info.Ctx.getTargetInfo().getCharWidth() == 8 &&
7899 "no host or target supports non 8-bit chars");
7901 "LValueToRValueBitcast requires an lvalue operand!");
7903 LValue SourceLValue;
7905 SourceLValue.setFrom(Info.Ctx, SourceValue);
7908 SourceRValue,
true))
7911 return handleRValueToRValueBitCast(Info, DestValue, SourceRValue, BCE);
7914template <
class Derived>
7915class ExprEvaluatorBase
7918 Derived &getDerived() {
return static_cast<Derived&
>(*this); }
7920 return getDerived().Success(
V,
E);
7922 bool DerivedZeroInitialization(
const Expr *
E) {
7923 return getDerived().ZeroInitialization(
E);
7929 template<
typename ConditionalOperator>
7931 assert(Info.checkingPotentialConstantExpression());
7936 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
7937 StmtVisitorTy::Visit(
E->getFalseExpr());
7943 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
7945 StmtVisitorTy::Visit(
E->getTrueExpr());
7950 Error(
E, diag::note_constexpr_conditional_never_const);
7954 template<
typename ConditionalOperator>
7958 if (Info.checkingPotentialConstantExpression() && Info.noteFailure()) {
7959 CheckPotentialConstantConditional(
E);
7962 if (Info.noteFailure()) {
7963 StmtVisitorTy::Visit(
E->getTrueExpr());
7964 StmtVisitorTy::Visit(
E->getFalseExpr());
7969 Expr *EvalExpr = BoolResult ?
E->getTrueExpr() :
E->getFalseExpr();
7970 return StmtVisitorTy::Visit(EvalExpr);
7976 typedef ExprEvaluatorBase ExprEvaluatorBaseTy;
7979 return Info.CCEDiag(
E,
D);
7982 bool ZeroInitialization(
const Expr *
E) {
return Error(
E); }
7984 bool IsConstantEvaluatedBuiltinCall(
const CallExpr *
E) {
7985 unsigned BuiltinOp =
E->getBuiltinCallee();
7986 return BuiltinOp != 0 &&
7987 Info.Ctx.BuiltinInfo.isConstantEvaluated(BuiltinOp);
7991 ExprEvaluatorBase(EvalInfo &Info) : Info(Info) {}
7993 EvalInfo &getEvalInfo() {
return Info; }
8002 return Error(
E, diag::note_invalid_subexpr_in_const_expr);
8005 bool VisitStmt(
const Stmt *) {
8006 llvm_unreachable(
"Expression evaluator should not be called on stmts");
8008 bool VisitExpr(
const Expr *
E) {
8013 const auto It =
E->begin();
8014 return StmtVisitorTy::Visit(*It);
8018 return StmtVisitorTy::Visit(
E->getFunctionName());
8021 if (
E->hasAPValueResult())
8022 return DerivedSuccess(
E->getAPValueResult(),
E);
8024 return StmtVisitorTy::Visit(
E->getSubExpr());
8028 {
return StmtVisitorTy::Visit(
E->getSubExpr()); }
8030 {
return StmtVisitorTy::Visit(
E->getSubExpr()); }
8032 {
return StmtVisitorTy::Visit(
E->getSubExpr()); }
8034 {
return StmtVisitorTy::Visit(
E->getChosenSubExpr()); }
8036 {
return StmtVisitorTy::Visit(
E->getResultExpr()); }
8038 {
return StmtVisitorTy::Visit(
E->getReplacement()); }
8040 TempVersionRAII RAII(*Info.CurrentCall);
8041 SourceLocExprScopeGuard Guard(
E, Info.CurrentCall->CurSourceLocExprScope);
8042 return StmtVisitorTy::Visit(
E->getExpr());
8045 TempVersionRAII RAII(*Info.CurrentCall);
8049 SourceLocExprScopeGuard Guard(
E, Info.CurrentCall->CurSourceLocExprScope);
8050 return StmtVisitorTy::Visit(
E->getExpr());
8054 FullExpressionRAII
Scope(Info);
8055 return StmtVisitorTy::Visit(
E->getSubExpr()) &&
Scope.destroy();
8061 return StmtVisitorTy::Visit(
E->getSubExpr());
8065 CCEDiag(
E, diag::note_constexpr_invalid_cast) << 0;
8066 return static_cast<Derived*
>(
this)->VisitCastExpr(
E);
8069 if (!Info.Ctx.getLangOpts().CPlusPlus20)
8070 CCEDiag(
E, diag::note_constexpr_invalid_cast) << 1;
8071 return static_cast<Derived*
>(
this)->VisitCastExpr(
E);
8074 return static_cast<Derived*
>(
this)->VisitCastExpr(
E);
8078 switch (
E->getOpcode()) {
8083 VisitIgnoredValue(
E->getLHS());
8084 return StmtVisitorTy::Visit(
E->getRHS());
8094 return DerivedSuccess(Result,
E);
8100 return StmtVisitorTy::Visit(
E->getSemanticForm());
8107 if (!
Evaluate(Info.CurrentCall->createTemporary(
8108 E->getOpaqueValue(),
8109 getStorageType(Info.Ctx,
E->getOpaqueValue()),
8110 ScopeKind::FullExpression, CommonLV),
8111 Info,
E->getCommon()))
8114 return HandleConditionalOperator(
E);
8118 bool IsBcpCall =
false;
8125 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
8132 if (Info.checkingPotentialConstantExpression() && IsBcpCall)
8135 FoldConstant Fold(Info, IsBcpCall);
8136 if (!HandleConditionalOperator(
E)) {
8137 Fold.keepDiagnostics();
8145 if (
APValue *
Value = Info.CurrentCall->getCurrentTemporary(
E);
8147 return DerivedSuccess(*
Value,
E);
8149 const Expr *Source =
E->getSourceExpr();
8153 assert(0 &&
"OpaqueValueExpr recursively refers to itself");
8156 return StmtVisitorTy::Visit(Source);
8160 for (
const Expr *SemE :
E->semantics()) {
8161 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
8165 if (SemE ==
E->getResultExpr())
8170 if (OVE->isUnique())
8174 if (!
Evaluate(Info.CurrentCall->createTemporary(
8175 OVE, getStorageType(Info.Ctx, OVE),
8176 ScopeKind::FullExpression, LV),
8177 Info, OVE->getSourceExpr()))
8179 }
else if (SemE ==
E->getResultExpr()) {
8180 if (!StmtVisitorTy::Visit(SemE))
8192 if (!handleCallExpr(
E, Result,
nullptr))
8194 return DerivedSuccess(Result,
E);
8198 const LValue *ResultSlot) {
8199 CallScopeRAII CallScope(Info);
8205 LValue *
This =
nullptr, ThisVal;
8207 bool HasQualifier =
false;
8214 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(Callee)) {
8218 Member = dyn_cast<CXXMethodDecl>(ME->getMemberDecl());
8220 return Error(Callee);
8222 HasQualifier = ME->hasQualifier();
8223 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(Callee)) {
8229 Member = dyn_cast<CXXMethodDecl>(
D);
8231 return Error(Callee);
8233 }
else if (
const auto *PDE = dyn_cast<CXXPseudoDestructorExpr>(Callee)) {
8234 if (!Info.getLangOpts().CPlusPlus20)
8235 Info.CCEDiag(PDE, diag::note_constexpr_pseudo_destructor);
8239 return Error(Callee);
8246 if (!CalleeLV.getLValueOffset().isZero())
8247 return Error(Callee);
8248 if (CalleeLV.isNullPointer()) {
8249 Info.FFDiag(Callee, diag::note_constexpr_null_callee)
8253 FD = dyn_cast_or_null<FunctionDecl>(
8254 CalleeLV.getLValueBase().dyn_cast<
const ValueDecl *>());
8256 return Error(Callee);
8259 if (!Info.Ctx.hasSameFunctionTypeIgnoringExceptionSpec(
8266 auto *OCE = dyn_cast<CXXOperatorCallExpr>(
E);
8267 if (OCE && OCE->isAssignmentOp()) {
8268 assert(Args.size() == 2 &&
"wrong number of arguments in assignment");
8269 Call = Info.CurrentCall->createCall(FD);
8270 bool HasThis =
false;
8271 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FD))
8272 HasThis = MD->isImplicitObjectMemberFunction();
8300 if (Info.getLangOpts().CPlusPlus20 && OCE &&
8301 OCE->getOperator() == OO_Equal && MD->
isTrivial() &&
8305 Args = Args.slice(1);
8314 "Number of captures must be zero for conversion to function-ptr");
8325 "A generic lambda's static-invoker function must be a "
8326 "template specialization");
8330 void *InsertPos =
nullptr;
8333 assert(CorrespondingCallOpSpecialization &&
8334 "We must always have a function call operator specialization "
8335 "that corresponds to our static invoker specialization");
8336 assert(isa<CXXMethodDecl>(CorrespondingCallOpSpecialization));
8337 FD = CorrespondingCallOpSpecialization;
8346 Ptr.moveInto(Result);
8347 return CallScope.destroy();
8357 Call = Info.CurrentCall->createCall(FD);
8364 auto *NamedMember = dyn_cast<CXXMethodDecl>(FD);
8365 if (NamedMember && NamedMember->isVirtual() && !HasQualifier) {
8368 CovariantAdjustmentPath);
8371 }
else if (NamedMember && NamedMember->isImplicitObjectMemberFunction()) {
8381 if (
auto *DD = dyn_cast<CXXDestructorDecl>(FD)) {
8382 assert(This &&
"no 'this' pointer for destructor call");
8384 Info.Ctx.getRecordType(DD->getParent())) &&
8385 CallScope.destroy();
8393 Body, Info, Result, ResultSlot))
8396 if (!CovariantAdjustmentPath.empty() &&
8398 CovariantAdjustmentPath))
8401 return CallScope.destroy();
8405 return StmtVisitorTy::Visit(
E->getInitializer());
8408 if (
E->getNumInits() == 0)
8409 return DerivedZeroInitialization(
E);
8410 if (
E->getNumInits() == 1)
8411 return StmtVisitorTy::Visit(
E->getInit(0));
8415 return DerivedZeroInitialization(
E);
8418 return DerivedZeroInitialization(
E);
8421 return DerivedZeroInitialization(
E);
8426 assert(!Info.Ctx.getLangOpts().CPlusPlus11 &&
8427 "missing temporary materialization conversion");
8428 assert(!
E->isArrow() &&
"missing call to bound member function?");
8436 const FieldDecl *FD = dyn_cast<FieldDecl>(
E->getMemberDecl());
8437 if (!FD)
return Error(
E);
8451 DerivedSuccess(Result,
E);
8461 E->getEncodedElementAccess(Indices);
8462 if (Indices.size() == 1) {
8468 for (
unsigned I = 0; I < Indices.size(); ++I) {
8471 APValue VecResult(Elts.data(), Indices.size());
8472 return DerivedSuccess(VecResult,
E);
8480 switch (
E->getCastKind()) {
8484 case CK_AtomicToNonAtomic: {
8489 if (!
Evaluate(AtomicVal, Info,
E->getSubExpr()))
8491 return DerivedSuccess(AtomicVal,
E);
8495 case CK_UserDefinedConversion:
8496 return StmtVisitorTy::Visit(
E->getSubExpr());
8498 case CK_LValueToRValue: {
8507 return DerivedSuccess(RVal,
E);
8509 case CK_LValueToRValueBitCast: {
8510 APValue DestValue, SourceValue;
8511 if (!
Evaluate(SourceValue, Info,
E->getSubExpr()))
8513 if (!handleLValueToRValueBitCast(Info, DestValue, SourceValue,
E))
8515 return DerivedSuccess(DestValue,
E);
8518 case CK_AddressSpaceConversion: {
8522 return DerivedSuccess(
Value,
E);
8530 return VisitUnaryPostIncDec(UO);
8533 return VisitUnaryPostIncDec(UO);
8536 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
8546 return DerivedSuccess(RVal, UO);
8559 BlockScopeRAII
Scope(Info);
8564 const Expr *FinalExpr = dyn_cast<Expr>(*BI);
8566 Info.FFDiag((*BI)->getBeginLoc(),
8567 diag::note_constexpr_stmt_expr_unsupported);
8570 return this->Visit(FinalExpr) &&
Scope.destroy();
8576 if (ESR != ESR_Succeeded) {
8580 if (ESR != ESR_Failed)
8581 Info.FFDiag((*BI)->getBeginLoc(),
8582 diag::note_constexpr_stmt_expr_unsupported);
8587 llvm_unreachable(
"Return from function from the loop above.");
8591 return StmtVisitorTy::Visit(
E->getSelectedExpr());
8595 void VisitIgnoredValue(
const Expr *
E) {
8600 void VisitIgnoredBaseExpression(
const Expr *
E) {
8605 VisitIgnoredValue(
E);
8615template<
class Derived>
8616class LValueExprEvaluatorBase
8617 :
public ExprEvaluatorBase<Derived> {
8621 typedef LValueExprEvaluatorBase LValueExprEvaluatorBaseTy;
8622 typedef ExprEvaluatorBase<Derived> ExprEvaluatorBaseTy;
8629 bool evaluatePointer(
const Expr *
E, LValue &Result) {
8634 LValueExprEvaluatorBase(EvalInfo &Info, LValue &Result,
bool InvalidBaseOK)
8635 : ExprEvaluatorBaseTy(Info), Result(Result),
8636 InvalidBaseOK(InvalidBaseOK) {}
8639 Result.setFrom(this->Info.Ctx,
V);
8648 EvalOK = evaluatePointer(
E->getBase(), Result);
8655 EvalOK = this->Visit(
E->getBase());
8661 Result.setInvalid(
E);
8666 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(
E->getMemberDecl())) {
8689 switch (
E->getOpcode()) {
8691 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
8700 switch (
E->getCastKind()) {
8702 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
8704 case CK_DerivedToBase:
8705 case CK_UncheckedDerivedToBase:
8706 if (!this->Visit(
E->getSubExpr()))
8752class LValueExprEvaluator
8753 :
public LValueExprEvaluatorBase<LValueExprEvaluator> {
8755 LValueExprEvaluator(EvalInfo &Info, LValue &Result,
bool InvalidBaseOK) :
8756 LValueExprEvaluatorBaseTy(Info, Result, InvalidBaseOK) {}
8769 E, 0, Info.getASTContext().getNextStringLiteralVersion()));
8780 return VisitUnaryPreIncDec(UO);
8783 return VisitUnaryPreIncDec(UO);
8789 switch (
E->getCastKind()) {
8791 return LValueExprEvaluatorBaseTy::VisitCastExpr(
E);
8793 case CK_LValueBitCast:
8794 this->CCEDiag(
E, diag::note_constexpr_invalid_cast)
8795 << 2 << Info.Ctx.getLangOpts().CPlusPlus;
8796 if (!Visit(
E->getSubExpr()))
8798 Result.Designator.setInvalid();
8801 case CK_BaseToDerived:
8802 if (!Visit(
E->getSubExpr()))
8807 if (!Visit(
E->getSubExpr()))
8818 bool LValueToRValueConversion) {
8822 assert(Info.CurrentCall->This ==
nullptr &&
8823 "This should not be set for a static call operator");
8831 if (Self->getType()->isReferenceType()) {
8832 APValue *RefValue = Info.getParamSlot(Info.CurrentCall->Arguments, Self);
8834 Result.setFrom(Info.Ctx, *RefValue);
8836 const ParmVarDecl *VD = Info.CurrentCall->Arguments.getOrigParam(Self);
8837 CallStackFrame *Frame =
8838 Info.getCallFrameAndDepth(Info.CurrentCall->Arguments.CallIndex)
8840 unsigned Version = Info.CurrentCall->Arguments.Version;
8841 Result.set({VD, Frame->Index, Version});
8844 Result = *Info.CurrentCall->This;
8854 if (LValueToRValueConversion) {
8858 Result.setFrom(Info.Ctx, RVal);
8869 bool InvalidBaseOK) {
8873 return LValueExprEvaluator(Info, Result, InvalidBaseOK).Visit(
E);
8876bool LValueExprEvaluator::VisitDeclRefExpr(
const DeclRefExpr *
E) {
8880 return Success(cast<ValueDecl>(
D));
8881 if (
const VarDecl *VD = dyn_cast<VarDecl>(
D))
8882 return VisitVarDecl(
E, VD);
8884 return Visit(BD->getBinding());
8889bool LValueExprEvaluator::VisitVarDecl(
const Expr *
E,
const VarDecl *VD) {
8892 bool AllowConstexprUnknown =
8899 isa<DeclRefExpr>(
E) &&
8900 cast<DeclRefExpr>(
E)->refersToEnclosingVariableOrCapture()) {
8905 if (Info.checkingPotentialConstantExpression())
8908 if (
auto *FD = Info.CurrentCall->LambdaCaptureFields.lookup(VD)) {
8909 const auto *MD = cast<CXXMethodDecl>(Info.CurrentCall->Callee);
8915 CallStackFrame *Frame =
nullptr;
8916 unsigned Version = 0;
8924 CallStackFrame *CurrFrame = Info.CurrentCall;
8925 if (CurrFrame->Callee && CurrFrame->Callee->Equals(VD->
getDeclContext())) {
8929 if (
auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
8930 if (CurrFrame->Arguments) {
8931 VD = CurrFrame->Arguments.getOrigParam(PVD);
8933 Info.getCallFrameAndDepth(CurrFrame->Arguments.CallIndex).first;
8934 Version = CurrFrame->Arguments.Version;
8938 Version = CurrFrame->getCurrentTemporaryVersion(VD);
8945 Result.set({VD, Frame->Index, Version});
8951 if (!Info.getLangOpts().CPlusPlus11) {
8952 Info.CCEDiag(
E, diag::note_constexpr_ltor_non_integral, 1)
8954 Info.Note(VD->
getLocation(), diag::note_declared_at);
8960 if (!
V->hasValue()) {
8966 if (!Info.checkingPotentialConstantExpression() && !AllowConstexprUnknown)
8967 Info.FFDiag(
E, diag::note_constexpr_use_uninit_reference);
8973 Result.set({VD, Frame->Index, Version});
8984bool LValueExprEvaluator::VisitCallExpr(
const CallExpr *
E) {
8985 if (!IsConstantEvaluatedBuiltinCall(
E))
8986 return ExprEvaluatorBaseTy::VisitCallExpr(
E);
8988 switch (
E->getBuiltinCallee()) {
8991 case Builtin::BIas_const:
8992 case Builtin::BIforward:
8993 case Builtin::BIforward_like:
8994 case Builtin::BImove:
8995 case Builtin::BImove_if_noexcept:
8996 if (cast<FunctionDecl>(
E->getCalleeDecl())->isConstexpr())
8997 return Visit(
E->getArg(0));
9001 return ExprEvaluatorBaseTy::VisitCallExpr(
E);
9004bool LValueExprEvaluator::VisitMaterializeTemporaryExpr(
9013 for (
const Expr *
E : CommaLHSs)
9022 if (Info.EvalMode == EvalInfo::EM_ConstantFold)
9025 Value =
E->getOrCreateValue(
true);
9029 Value = &Info.CurrentCall->createTemporary(
9030 E, Inner->getType(),
9045 for (
unsigned I = Adjustments.size(); I != 0; ) {
9047 switch (Adjustments[I].Kind) {
9052 Type = Adjustments[I].DerivedToBase.BasePath->getType();
9058 Type = Adjustments[I].Field->getType();
9063 Adjustments[I].Ptr.RHS))
9065 Type = Adjustments[I].Ptr.MPT->getPointeeType();
9075 assert((!Info.getLangOpts().CPlusPlus ||
E->isFileScope()) &&
9076 "lvalue compound literal in c++?");
9082bool LValueExprEvaluator::VisitCXXTypeidExpr(
const CXXTypeidExpr *
E) {
9085 if (!
E->isPotentiallyEvaluated()) {
9086 if (
E->isTypeOperand())
9091 if (!Info.Ctx.getLangOpts().CPlusPlus20) {
9092 Info.CCEDiag(
E, diag::note_constexpr_typeid_polymorphic)
9097 if (!Visit(
E->getExprOperand()))
9100 std::optional<DynamicType> DynType =
9106 TypeInfoLValue(Info.Ctx.getRecordType(DynType->Type).getTypePtr());
9112bool LValueExprEvaluator::VisitCXXUuidofExpr(
const CXXUuidofExpr *
E) {
9116bool LValueExprEvaluator::VisitMemberExpr(
const MemberExpr *
E) {
9118 if (
const VarDecl *VD = dyn_cast<VarDecl>(
E->getMemberDecl())) {
9119 VisitIgnoredBaseExpression(
E->getBase());
9120 return VisitVarDecl(
E, VD);
9124 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(
E->getMemberDecl())) {
9125 if (MD->isStatic()) {
9126 VisitIgnoredBaseExpression(
E->getBase());
9132 return LValueExprEvaluatorBaseTy::VisitMemberExpr(
E);
9135bool LValueExprEvaluator::VisitExtVectorElementExpr(
9140 if (!
Evaluate(Val, Info,
E->getBase())) {
9141 if (!Info.noteFailure())
9147 E->getEncodedElementAccess(Indices);
9149 if (Indices.size() > 1)
9153 Result.setFrom(Info.Ctx, Val);
9156 VT->getNumElements(), Indices[0]);
9171 if (!
Evaluate(Val, Info,
E->getBase())) {
9172 if (!Info.noteFailure())
9178 if (!Info.noteFailure())
9184 Result.setFrom(Info.Ctx, Val);
9186 VT->getNumElements(), Index.getExtValue());
9194 for (
const Expr *SubExpr : {
E->getLHS(),
E->getRHS()}) {
9195 if (SubExpr ==
E->getBase() ? !evaluatePointer(SubExpr, Result)
9197 if (!Info.noteFailure())
9207bool LValueExprEvaluator::VisitUnaryDeref(
const UnaryOperator *
E) {
9208 return evaluatePointer(
E->getSubExpr(), Result);
9211bool LValueExprEvaluator::VisitUnaryReal(
const UnaryOperator *
E) {
9212 if (!Visit(
E->getSubExpr()))
9220bool LValueExprEvaluator::VisitUnaryImag(
const UnaryOperator *
E) {
9222 "lvalue __imag__ on scalar?");
9223 if (!Visit(
E->getSubExpr()))
9229bool LValueExprEvaluator::VisitUnaryPreIncDec(
const UnaryOperator *UO) {
9230 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9241bool LValueExprEvaluator::VisitCompoundAssignOperator(
9243 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9251 if (!Info.noteFailure())
9267 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9274 if (!
Evaluate(NewVal, this->Info,
E->getRHS())) {
9275 if (!Info.noteFailure())
9280 if (!this->Visit(
E->getLHS()) || !
Success)
9283 if (Info.getLangOpts().CPlusPlus20 &&
9303 llvm::APInt &Result) {
9304 const AllocSizeAttr *AllocSize = getAllocSizeAttr(
Call);
9306 assert(AllocSize && AllocSize->getElemSizeParam().isValid());
9307 unsigned SizeArgNo = AllocSize->getElemSizeParam().getASTIndex();
9309 if (
Call->getNumArgs() <= SizeArgNo)
9312 auto EvaluateAsSizeT = [&](
const Expr *
E,
APSInt &Into) {
9317 if (Into.isNegative() || !Into.isIntN(BitsInSizeT))
9319 Into = Into.zext(BitsInSizeT);
9324 if (!EvaluateAsSizeT(
Call->getArg(SizeArgNo), SizeOfElem))
9327 if (!AllocSize->getNumElemsParam().isValid()) {
9328 Result = std::move(SizeOfElem);
9333 unsigned NumArgNo = AllocSize->getNumElemsParam().getASTIndex();
9334 if (!EvaluateAsSizeT(
Call->getArg(NumArgNo), NumberOfElems))
9338 llvm::APInt BytesAvailable = SizeOfElem.umul_ov(NumberOfElems, Overflow);
9342 Result = std::move(BytesAvailable);
9350 llvm::APInt &Result) {
9351 assert(isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
9352 "Can't get the size of a non alloc_size function");
9353 const auto *
Base = LVal.getLValueBase().get<
const Expr *>();
9373 dyn_cast_or_null<VarDecl>(
Base.dyn_cast<
const ValueDecl *>());
9378 if (!
Init ||
Init->getType().isNull())
9382 if (!tryUnwrapAllocSizeCall(
E))
9387 Result.setInvalid(
E);
9390 Result.addUnsizedArray(Info,
E, Pointee);
9395class PointerExprEvaluator
9396 :
public ExprEvaluatorBase<PointerExprEvaluator> {
9405 bool evaluateLValue(
const Expr *
E, LValue &Result) {
9409 bool evaluatePointer(
const Expr *
E, LValue &Result) {
9413 bool visitNonBuiltinCallExpr(
const CallExpr *
E);
9416 PointerExprEvaluator(EvalInfo &info, LValue &Result,
bool InvalidBaseOK)
9417 : ExprEvaluatorBaseTy(info), Result(Result),
9418 InvalidBaseOK(InvalidBaseOK) {}
9421 Result.setFrom(Info.Ctx,
V);
9424 bool ZeroInitialization(
const Expr *
E) {
9425 Result.setNull(Info.Ctx,
E->
getType());
9435 if (
E->isExpressibleAsConstantInitializer())
9437 if (Info.noteFailure())
9444 bool VisitBuiltinCallExpr(
const CallExpr *
E,
unsigned BuiltinOp);
9446 if (!
E->getBlockDecl()->hasCaptures())
9451 auto DiagnoseInvalidUseOfThis = [&] {
9452 if (Info.getLangOpts().CPlusPlus11)
9453 Info.FFDiag(
E, diag::note_constexpr_this) <<
E->isImplicit();
9459 if (Info.checkingPotentialConstantExpression())
9462 bool IsExplicitLambda =
9464 if (!IsExplicitLambda) {
9465 if (!Info.CurrentCall->This) {
9466 DiagnoseInvalidUseOfThis();
9470 Result = *Info.CurrentCall->This;
9478 if (!Info.CurrentCall->LambdaThisCaptureField) {
9479 if (IsExplicitLambda && !Info.CurrentCall->This) {
9480 DiagnoseInvalidUseOfThis();
9487 const auto *MD = cast<CXXMethodDecl>(Info.CurrentCall->Callee);
9489 Info,
E, Result, MD, Info.CurrentCall->LambdaThisCaptureField,
9498 assert(!
E->isIntType() &&
"SourceLocExpr isn't a pointer type?");
9499 APValue LValResult =
E->EvaluateInContext(
9500 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.getDefaultExpr());
9501 Result.setFrom(Info.Ctx, LValResult);
9506 llvm::report_fatal_error(
"Not yet implemented for ExprConstant.cpp");
9511 std::string ResultStr =
E->ComputeName(Info.Ctx);
9514 APInt Size(Info.Ctx.getTypeSize(Info.Ctx.getSizeType()),
9515 ResultStr.size() + 1);
9516 QualType ArrayTy = Info.Ctx.getConstantArrayType(
9517 CharTy, Size,
nullptr, ArraySizeModifier::Normal, 0);
9521 false, ArrayTy,
E->getLocation());
9523 evaluateLValue(SL, Result);
9524 Result.addArray(Info,
E, cast<ConstantArrayType>(ArrayTy));
9533 bool InvalidBaseOK) {
9536 return PointerExprEvaluator(Info, Result, InvalidBaseOK).Visit(
E);
9539bool PointerExprEvaluator::VisitBinaryOperator(
const BinaryOperator *
E) {
9540 if (
E->getOpcode() != BO_Add &&
9541 E->getOpcode() != BO_Sub)
9542 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
9544 const Expr *PExp =
E->getLHS();
9545 const Expr *IExp =
E->getRHS();
9547 std::swap(PExp, IExp);
9549 bool EvalPtrOK = evaluatePointer(PExp, Result);
9550 if (!EvalPtrOK && !Info.noteFailure())
9553 llvm::APSInt Offset;
9557 if (
E->getOpcode() == BO_Sub)
9564bool PointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *
E) {
9565 return evaluateLValue(
E->getSubExpr(), Result);
9573 if (!FnII || !FnII->
isStr(
"current"))
9576 const auto *RD = dyn_cast<RecordDecl>(FD->
getParent());
9584bool PointerExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
9585 const Expr *SubExpr =
E->getSubExpr();
9587 switch (
E->getCastKind()) {
9591 case CK_CPointerToObjCPointerCast:
9592 case CK_BlockPointerToObjCPointerCast:
9593 case CK_AnyPointerToBlockPointerCast:
9594 case CK_AddressSpaceConversion:
9595 if (!Visit(SubExpr))
9603 bool HasValidResult = !Result.InvalidBase && !Result.Designator.Invalid &&
9605 bool VoidPtrCastMaybeOK =
9608 Info.Ctx.hasSimilarType(Result.Designator.getType(Info.Ctx),
9617 if (VoidPtrCastMaybeOK &&
9618 (Info.getStdAllocatorCaller(
"allocate") ||
9620 Info.getLangOpts().CPlusPlus26)) {
9624 Info.getLangOpts().CPlusPlus) {
9626 CCEDiag(
E, diag::note_constexpr_invalid_void_star_cast)
9627 << SubExpr->
getType() << Info.getLangOpts().CPlusPlus26
9628 << Result.Designator.getType(Info.Ctx).getCanonicalType()
9631 CCEDiag(
E, diag::note_constexpr_invalid_cast)
9634 CCEDiag(
E, diag::note_constexpr_invalid_cast)
9635 << 2 << Info.Ctx.getLangOpts().CPlusPlus;
9636 Result.Designator.setInvalid();
9639 if (
E->getCastKind() == CK_AddressSpaceConversion && Result.IsNullPtr)
9640 ZeroInitialization(
E);
9643 case CK_DerivedToBase:
9644 case CK_UncheckedDerivedToBase:
9645 if (!evaluatePointer(
E->getSubExpr(), Result))
9647 if (!Result.Base && Result.Offset.isZero())
9656 case CK_BaseToDerived:
9657 if (!Visit(
E->getSubExpr()))
9659 if (!Result.Base && Result.Offset.isZero())
9664 if (!Visit(
E->getSubExpr()))
9668 case CK_NullToPointer:
9669 VisitIgnoredValue(
E->getSubExpr());
9670 return ZeroInitialization(
E);
9672 case CK_IntegralToPointer: {
9673 CCEDiag(
E, diag::note_constexpr_invalid_cast)
9674 << 2 << Info.Ctx.getLangOpts().CPlusPlus;
9680 if (
Value.isInt()) {
9682 uint64_t N =
Value.getInt().extOrTrunc(Size).getZExtValue();
9683 Result.Base = (
Expr*)
nullptr;
9684 Result.InvalidBase =
false;
9686 Result.Designator.setInvalid();
9687 Result.IsNullPtr =
false;
9694 if (!
Value.isLValue())
9698 Result.setFrom(Info.Ctx,
Value);
9703 case CK_ArrayToPointerDecay: {
9705 if (!evaluateLValue(SubExpr, Result))
9709 SubExpr, SubExpr->
getType(), ScopeKind::FullExpression, Result);
9714 auto *AT = Info.Ctx.getAsArrayType(SubExpr->
getType());
9715 if (
auto *CAT = dyn_cast<ConstantArrayType>(AT))
9716 Result.addArray(Info,
E, CAT);
9718 Result.addUnsizedArray(Info,
E, AT->getElementType());
9722 case CK_FunctionToPointerDecay:
9723 return evaluateLValue(SubExpr, Result);
9725 case CK_LValueToRValue: {
9727 if (!evaluateLValue(
E->getSubExpr(), LVal))
9734 return InvalidBaseOK &&
9740 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
9748 T =
T.getNonReferenceType();
9750 if (
T.getQualifiers().hasUnaligned())
9753 const bool AlignOfReturnsPreferred =
9754 Ctx.
getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver7;
9759 if (ExprKind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
9762 else if (ExprKind == UETT_AlignOf)
9765 llvm_unreachable(
"GetAlignOfType on a non-alignment ExprKind");
9782 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(
E))
9791 return Info.Ctx.getDeclAlign(VD);
9792 if (
const auto *
E =
Value.Base.dyn_cast<
const Expr *>())
9800 EvalInfo &Info,
APSInt &Alignment) {
9803 if (Alignment < 0 || !Alignment.isPowerOf2()) {
9804 Info.FFDiag(
E, diag::note_constexpr_invalid_alignment) << Alignment;
9807 unsigned SrcWidth = Info.Ctx.getIntWidth(ForType);
9808 APSInt MaxValue(APInt::getOneBitSet(SrcWidth, SrcWidth - 1));
9809 if (APSInt::compareValues(Alignment, MaxValue) > 0) {
9810 Info.FFDiag(
E, diag::note_constexpr_alignment_too_big)
9811 << MaxValue << ForType << Alignment;
9817 APSInt(Alignment.zextOrTrunc(SrcWidth),
true);
9818 assert(APSInt::compareValues(Alignment, ExtAlignment) == 0 &&
9819 "Alignment should not be changed by ext/trunc");
9820 Alignment = ExtAlignment;
9821 assert(Alignment.getBitWidth() == SrcWidth);
9826bool PointerExprEvaluator::visitNonBuiltinCallExpr(
const CallExpr *
E) {
9827 if (ExprEvaluatorBaseTy::VisitCallExpr(
E))
9830 if (!(InvalidBaseOK && getAllocSizeAttr(
E)))
9833 Result.setInvalid(
E);
9835 Result.addUnsizedArray(Info,
E, PointeeTy);
9839bool PointerExprEvaluator::VisitCallExpr(
const CallExpr *
E) {
9840 if (!IsConstantEvaluatedBuiltinCall(
E))
9841 return visitNonBuiltinCallExpr(
E);
9842 return VisitBuiltinCallExpr(
E,
E->getBuiltinCallee());
9851bool PointerExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *
E,
9852 unsigned BuiltinOp) {
9856 switch (BuiltinOp) {
9857 case Builtin::BIaddressof:
9858 case Builtin::BI__addressof:
9859 case Builtin::BI__builtin_addressof:
9860 return evaluateLValue(
E->getArg(0), Result);
9861 case Builtin::BI__builtin_assume_aligned: {
9865 if (!evaluatePointer(
E->getArg(0), Result))
9868 LValue OffsetResult(Result);
9875 if (
E->getNumArgs() > 2) {
9880 int64_t AdditionalOffset = -Offset.getZExtValue();
9885 if (OffsetResult.Base) {
9888 if (BaseAlignment < Align) {
9889 Result.Designator.setInvalid();
9890 CCEDiag(
E->getArg(0), diag::note_constexpr_baa_insufficient_alignment)
9897 if (OffsetResult.Offset.alignTo(Align) != OffsetResult.Offset) {
9898 Result.Designator.setInvalid();
9901 ? CCEDiag(
E->getArg(0),
9902 diag::note_constexpr_baa_insufficient_alignment)
9904 : CCEDiag(
E->getArg(0),
9905 diag::note_constexpr_baa_value_insufficient_alignment))
9906 << OffsetResult.Offset.getQuantity() << Align.
getQuantity();
9912 case Builtin::BI__builtin_align_up:
9913 case Builtin::BI__builtin_align_down: {
9914 if (!evaluatePointer(
E->getArg(0), Result))
9933 assert(Alignment.getBitWidth() <= 64 &&
9934 "Cannot handle > 64-bit address-space");
9935 uint64_t Alignment64 = Alignment.getZExtValue();
9937 BuiltinOp == Builtin::BI__builtin_align_down
9938 ? llvm::alignDown(Result.Offset.getQuantity(), Alignment64)
9939 : llvm::alignTo(Result.Offset.getQuantity(), Alignment64));
9940 Result.adjustOffset(NewOffset - Result.Offset);
9945 Info.FFDiag(
E->getArg(0), diag::note_constexpr_alignment_adjust)
9949 case Builtin::BI__builtin_operator_new:
9951 case Builtin::BI__builtin_launder:
9952 return evaluatePointer(
E->getArg(0), Result);
9953 case Builtin::BIstrchr:
9954 case Builtin::BIwcschr:
9955 case Builtin::BImemchr:
9956 case Builtin::BIwmemchr:
9957 if (Info.getLangOpts().CPlusPlus11)
9958 Info.CCEDiag(
E, diag::note_constexpr_invalid_function)
9960 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
9962 Info.CCEDiag(
E, diag::note_invalid_subexpr_in_const_expr);
9964 case Builtin::BI__builtin_strchr:
9965 case Builtin::BI__builtin_wcschr:
9966 case Builtin::BI__builtin_memchr:
9967 case Builtin::BI__builtin_char_memchr:
9968 case Builtin::BI__builtin_wmemchr: {
9969 if (!Visit(
E->getArg(0)))
9975 if (BuiltinOp != Builtin::BIstrchr &&
9976 BuiltinOp != Builtin::BIwcschr &&
9977 BuiltinOp != Builtin::BI__builtin_strchr &&
9978 BuiltinOp != Builtin::BI__builtin_wcschr) {
9982 MaxLength = N.getZExtValue();
9985 if (MaxLength == 0u)
9986 return ZeroInitialization(
E);
9987 if (!Result.checkNullPointerForFoldAccess(Info,
E,
AK_Read) ||
9988 Result.Designator.Invalid)
9990 QualType CharTy = Result.Designator.getType(Info.Ctx);
9991 bool IsRawByte = BuiltinOp == Builtin::BImemchr ||
9992 BuiltinOp == Builtin::BI__builtin_memchr;
9994 Info.Ctx.hasSameUnqualifiedType(
9998 Info.FFDiag(
E, diag::note_constexpr_ltor_incomplete_type) << CharTy;
10004 Info.FFDiag(
E, diag::note_constexpr_memchr_unsupported)
10005 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp) << CharTy;
10011 bool StopAtNull =
false;
10012 switch (BuiltinOp) {
10013 case Builtin::BIstrchr:
10014 case Builtin::BI__builtin_strchr:
10021 return ZeroInitialization(
E);
10024 case Builtin::BImemchr:
10025 case Builtin::BI__builtin_memchr:
10026 case Builtin::BI__builtin_char_memchr:
10030 DesiredVal = Desired.trunc(Info.Ctx.getCharWidth()).getZExtValue();
10033 case Builtin::BIwcschr:
10034 case Builtin::BI__builtin_wcschr:
10037 case Builtin::BIwmemchr:
10038 case Builtin::BI__builtin_wmemchr:
10040 DesiredVal = Desired.getZExtValue();
10044 for (; MaxLength; --MaxLength) {
10049 if (Char.
getInt().getZExtValue() == DesiredVal)
10051 if (StopAtNull && !Char.
getInt())
10057 return ZeroInitialization(
E);
10060 case Builtin::BImemcpy:
10061 case Builtin::BImemmove:
10062 case Builtin::BIwmemcpy:
10063 case Builtin::BIwmemmove:
10064 if (Info.getLangOpts().CPlusPlus11)
10065 Info.CCEDiag(
E, diag::note_constexpr_invalid_function)
10067 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
10069 Info.CCEDiag(
E, diag::note_invalid_subexpr_in_const_expr);
10071 case Builtin::BI__builtin_memcpy:
10072 case Builtin::BI__builtin_memmove:
10073 case Builtin::BI__builtin_wmemcpy:
10074 case Builtin::BI__builtin_wmemmove: {
10075 bool WChar = BuiltinOp == Builtin::BIwmemcpy ||
10076 BuiltinOp == Builtin::BIwmemmove ||
10077 BuiltinOp == Builtin::BI__builtin_wmemcpy ||
10078 BuiltinOp == Builtin::BI__builtin_wmemmove;
10079 bool Move = BuiltinOp == Builtin::BImemmove ||
10080 BuiltinOp == Builtin::BIwmemmove ||
10081 BuiltinOp == Builtin::BI__builtin_memmove ||
10082 BuiltinOp == Builtin::BI__builtin_wmemmove;
10085 if (!Visit(
E->getArg(0)))
10087 LValue Dest = Result;
10096 assert(!N.isSigned() &&
"memcpy and friends take an unsigned size");
10106 if (!Src.Base || !Dest.Base) {
10108 (!Src.Base ? Src : Dest).moveInto(Val);
10109 Info.FFDiag(
E, diag::note_constexpr_memcpy_null)
10110 <<
Move << WChar << !!Src.Base
10114 if (Src.Designator.Invalid || Dest.Designator.Invalid)
10120 QualType T = Dest.Designator.getType(Info.Ctx);
10121 QualType SrcT = Src.Designator.getType(Info.Ctx);
10122 if (!Info.Ctx.hasSameUnqualifiedType(
T, SrcT)) {
10124 Info.FFDiag(
E, diag::note_constexpr_memcpy_type_pun) <<
Move << SrcT <<
T;
10128 Info.FFDiag(
E, diag::note_constexpr_memcpy_incomplete_type) <<
Move <<
T;
10131 if (!
T.isTriviallyCopyableType(Info.Ctx)) {
10132 Info.FFDiag(
E, diag::note_constexpr_memcpy_nontrivial) <<
Move <<
T;
10137 uint64_t TSize = Info.Ctx.getTypeSizeInChars(
T).getQuantity();
10142 llvm::APInt OrigN = N;
10143 llvm::APInt::udivrem(OrigN, TSize, N, Remainder);
10145 Info.FFDiag(
E, diag::note_constexpr_memcpy_unsupported)
10155 uint64_t RemainingSrcSize = Src.Designator.validIndexAdjustments().second;
10156 uint64_t RemainingDestSize = Dest.Designator.validIndexAdjustments().second;
10157 if (N.ugt(RemainingSrcSize) || N.ugt(RemainingDestSize)) {
10158 Info.FFDiag(
E, diag::note_constexpr_memcpy_unsupported)
10159 <<
Move << WChar << (N.ugt(RemainingSrcSize) ? 1 : 2) <<
T
10163 uint64_t NElems = N.getZExtValue();
10169 uint64_t SrcOffset = Src.getLValueOffset().getQuantity();
10170 uint64_t DestOffset = Dest.getLValueOffset().getQuantity();
10171 if (DestOffset >= SrcOffset && DestOffset - SrcOffset < NBytes) {
10174 Info.FFDiag(
E, diag::note_constexpr_memcpy_overlap) << WChar;
10182 }
else if (!Move && SrcOffset >= DestOffset &&
10183 SrcOffset - DestOffset < NBytes) {
10185 Info.FFDiag(
E, diag::note_constexpr_memcpy_overlap) << WChar;
10220bool PointerExprEvaluator::VisitCXXNewExpr(
const CXXNewExpr *
E) {
10221 if (!Info.getLangOpts().CPlusPlus20)
10222 Info.CCEDiag(
E, diag::note_constexpr_new);
10225 if (Info.SpeculativeEvaluationDepth)
10229 QualType AllocType =
E->getAllocatedType();
10232 bool IsNothrow =
false;
10233 bool IsPlacement =
false;
10235 if (
E->getNumPlacementArgs() == 1 &&
10251 }
else if (OperatorNew->isReservedGlobalPlacementOperator()) {
10252 if (Info.CurrentCall->isStdFunction() || Info.getLangOpts().CPlusPlus26 ||
10253 (Info.CurrentCall->CanEvalMSConstexpr &&
10254 OperatorNew->hasAttr<MSConstexprAttr>())) {
10257 if (Result.Designator.Invalid)
10259 TargetType =
E->getPlacementArg(0)->
getType();
10260 IsPlacement =
true;
10262 Info.FFDiag(
E, diag::note_constexpr_new_placement)
10266 }
else if (
E->getNumPlacementArgs()) {
10267 Info.FFDiag(
E, diag::note_constexpr_new_placement)
10270 }
else if (!OperatorNew->isReplaceableGlobalAllocationFunction()) {
10271 Info.FFDiag(
E, diag::note_constexpr_new_non_replaceable)
10272 << isa<CXXMethodDecl>(OperatorNew) << OperatorNew;
10276 const Expr *
Init =
E->getInitializer();
10279 bool ValueInit =
false;
10281 if (std::optional<const Expr *> ArraySize =
E->getArraySize()) {
10282 const Expr *Stripped = *ArraySize;
10283 for (;
auto *ICE = dyn_cast<ImplicitCastExpr>(Stripped);
10284 Stripped = ICE->getSubExpr())
10285 if (ICE->getCastKind() != CK_NoOp &&
10286 ICE->getCastKind() != CK_IntegralCast)
10289 llvm::APSInt ArrayBound;
10297 if (ArrayBound.isSigned() && ArrayBound.isNegative()) {
10299 return ZeroInitialization(
E);
10301 Info.FFDiag(*ArraySize, diag::note_constexpr_new_negative)
10302 << ArrayBound << (*ArraySize)->getSourceRange();
10308 if (!Info.CheckArraySize(ArraySize.value()->getExprLoc(),
10310 Info.Ctx, AllocType, ArrayBound),
10311 ArrayBound.getZExtValue(), !IsNothrow)) {
10313 return ZeroInitialization(
E);
10322 }
else if (isa<CXXScalarValueInitExpr>(
Init) ||
10323 isa<ImplicitValueInitExpr>(
Init)) {
10325 }
else if (
auto *CCE = dyn_cast<CXXConstructExpr>(
Init)) {
10326 ResizedArrayCCE = CCE;
10328 auto *CAT = Info.Ctx.getAsConstantArrayType(
Init->getType());
10329 assert(CAT &&
"unexpected type for array initializer");
10333 llvm::APInt InitBound = CAT->
getSize().zext(Bits);
10334 llvm::APInt AllocBound = ArrayBound.zext(Bits);
10335 if (InitBound.ugt(AllocBound)) {
10337 return ZeroInitialization(
E);
10339 Info.FFDiag(*ArraySize, diag::note_constexpr_new_too_small)
10340 <<
toString(AllocBound, 10,
false)
10342 << (*ArraySize)->getSourceRange();
10348 if (InitBound != AllocBound)
10349 ResizedArrayILE = cast<InitListExpr>(
Init);
10352 AllocType = Info.Ctx.getConstantArrayType(AllocType, ArrayBound,
nullptr,
10353 ArraySizeModifier::Normal, 0);
10356 "array allocation with non-array new");
10362 struct FindObjectHandler {
10369 typedef bool result_type;
10370 bool failed() {
return false; }
10374 unsigned SubobjectSize = 1;
10375 unsigned AllocSize = 1;
10376 if (
auto *CAT = dyn_cast<ConstantArrayType>(AllocType))
10378 if (
auto *CAT = dyn_cast<ConstantArrayType>(SubobjType))
10380 if (SubobjectSize < AllocSize ||
10381 !Info.Ctx.hasSimilarType(Info.Ctx.getBaseElementType(SubobjType),
10382 Info.Ctx.getBaseElementType(AllocType))) {
10383 Info.FFDiag(
E, diag::note_constexpr_placement_new_wrong_type)
10384 << SubobjType << AllocType;
10391 Info.FFDiag(
E, diag::note_constexpr_construct_complex_elem);
10395 Info.FFDiag(
E, diag::note_constexpr_construct_complex_elem);
10398 } Handler = {Info,
E, AllocType, AK,
nullptr};
10401 if (!Obj || !
findSubobject(Info,
E, Obj, Result.Designator, Handler))
10404 Val = Handler.Value;
10413 Val = Info.createHeapAlloc(
E, AllocType, Result);
10422 }
else if (ResizedArrayILE) {
10426 }
else if (ResizedArrayCCE) {
10440 Result.addArray(Info,
E, cast<ConstantArrayType>(AT));
10449class MemberPointerExprEvaluator
10450 :
public ExprEvaluatorBase<MemberPointerExprEvaluator> {
10454 Result = MemberPtr(
D);
10459 MemberPointerExprEvaluator(EvalInfo &Info, MemberPtr &Result)
10460 : ExprEvaluatorBaseTy(Info), Result(Result) {}
10466 bool ZeroInitialization(
const Expr *
E) {
10479 return MemberPointerExprEvaluator(Info, Result).Visit(
E);
10482bool MemberPointerExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
10483 switch (
E->getCastKind()) {
10485 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
10487 case CK_NullToMemberPointer:
10488 VisitIgnoredValue(
E->getSubExpr());
10489 return ZeroInitialization(
E);
10491 case CK_BaseToDerivedMemberPointer: {
10492 if (!Visit(
E->getSubExpr()))
10494 if (
E->path_empty())
10499 typedef std::reverse_iterator<CastExpr::path_const_iterator> ReverseIter;
10500 for (ReverseIter PathI(
E->path_end() - 1), PathE(
E->path_begin());
10501 PathI != PathE; ++PathI) {
10502 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
10503 const CXXRecordDecl *Derived = (*PathI)->getType()->getAsCXXRecordDecl();
10504 if (!Result.castToDerived(Derived))
10513 case CK_DerivedToBaseMemberPointer:
10514 if (!Visit(
E->getSubExpr()))
10517 PathE =
E->path_end(); PathI != PathE; ++PathI) {
10518 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
10520 if (!Result.castToBase(
Base))
10527bool MemberPointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *
E) {
10530 return Success(cast<DeclRefExpr>(
E->getSubExpr())->getDecl());
10538 class RecordExprEvaluator
10539 :
public ExprEvaluatorBase<RecordExprEvaluator> {
10540 const LValue &
This;
10544 RecordExprEvaluator(EvalInfo &info,
const LValue &This,
APValue &Result)
10545 : ExprEvaluatorBaseTy(info),
This(
This), Result(Result) {}
10551 bool ZeroInitialization(
const Expr *
E) {
10552 return ZeroInitialization(
E,
E->
getType());
10556 bool VisitCallExpr(
const CallExpr *
E) {
10557 return handleCallExpr(
E, Result, &This);
10562 return VisitCXXConstructExpr(
E,
E->
getType());
10570 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
10584 const LValue &This,
APValue &Result) {
10585 assert(!RD->
isUnion() &&
"Expected non-union class type");
10594 unsigned Index = 0;
10596 End = CD->
bases_end(); I != End; ++I, ++Index) {
10598 LValue Subobject = This;
10602 Result.getStructBase(Index)))
10607 for (
const auto *I : RD->
fields()) {
10609 if (I->isUnnamedBitField() || I->getType()->isReferenceType())
10612 LValue Subobject = This;
10618 Result.getStructField(I->getFieldIndex()), Info, Subobject, &VIE))
10625bool RecordExprEvaluator::ZeroInitialization(
const Expr *
E,
QualType T) {
10632 while (I != RD->
field_end() && (*I)->isUnnamedBitField())
10639 LValue Subobject =
This;
10644 return EvaluateInPlace(Result.getUnionValue(), Info, Subobject, &VIE);
10647 if (isa<CXXRecordDecl>(RD) && cast<CXXRecordDecl>(RD)->getNumVBases()) {
10648 Info.FFDiag(
E, diag::note_constexpr_virtual_base) << RD;
10655bool RecordExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
10656 switch (
E->getCastKind()) {
10658 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
10660 case CK_ConstructorConversion:
10661 return Visit(
E->getSubExpr());
10663 case CK_DerivedToBase:
10664 case CK_UncheckedDerivedToBase: {
10666 if (!
Evaluate(DerivedObject, Info,
E->getSubExpr()))
10669 return Error(
E->getSubExpr());
10675 PathE =
E->path_end(); PathI != PathE; ++PathI) {
10676 assert(!(*PathI)->isVirtual() &&
"record rvalue with virtual base");
10687bool RecordExprEvaluator::VisitInitListExpr(
const InitListExpr *
E) {
10688 if (
E->isTransparent())
10689 return Visit(
E->getInit(0));
10690 return VisitCXXParenListOrInitListExpr(
E,
E->inits());
10693bool RecordExprEvaluator::VisitCXXParenListOrInitListExpr(
10699 auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
10701 EvalInfo::EvaluatingConstructorRAII EvalObj(
10703 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries},
10704 CXXRD && CXXRD->getNumBases());
10708 if (
auto *ILE = dyn_cast<InitListExpr>(ExprToVisit)) {
10709 Field = ILE->getInitializedFieldInUnion();
10710 }
else if (
auto *PLIE = dyn_cast<CXXParenListInitExpr>(ExprToVisit)) {
10711 Field = PLIE->getInitializedFieldInUnion();
10714 "Expression is neither an init list nor a C++ paren list");
10727 const Expr *InitExpr = Args.empty() ? &VIE : Args[0];
10729 LValue Subobject =
This;
10734 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
10735 isa<CXXDefaultInitExpr>(InitExpr));
10737 if (
EvaluateInPlace(Result.getUnionValue(), Info, Subobject, InitExpr)) {
10738 if (
Field->isBitField())
10747 if (!Result.hasValue())
10750 unsigned ElementNo = 0;
10754 if (CXXRD && CXXRD->getNumBases()) {
10755 for (
const auto &
Base : CXXRD->bases()) {
10756 assert(ElementNo < Args.size() &&
"missing init for base class");
10757 const Expr *
Init = Args[ElementNo];
10759 LValue Subobject =
This;
10763 APValue &FieldVal = Result.getStructBase(ElementNo);
10765 if (!Info.noteFailure())
10772 EvalObj.finishedConstructingBases();
10776 for (
const auto *Field : RD->
fields()) {
10779 if (
Field->isUnnamedBitField())
10782 LValue Subobject =
This;
10784 bool HaveInit = ElementNo < Args.size();
10789 Subobject, Field, &Layout))
10795 const Expr *
Init = HaveInit ? Args[ElementNo++] : &VIE;
10797 if (
Field->getType()->isIncompleteArrayType()) {
10798 if (
auto *CAT = Info.Ctx.getAsConstantArrayType(
Init->getType())) {
10802 Info.FFDiag(
Init, diag::note_constexpr_unsupported_flexible_array);
10809 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
10810 isa<CXXDefaultInitExpr>(
Init));
10812 APValue &FieldVal = Result.getStructField(
Field->getFieldIndex());
10815 FieldVal, Field))) {
10816 if (!Info.noteFailure())
10822 EvalObj.finishedConstructingFields();
10834 bool ZeroInit =
E->requiresZeroInitialization();
10837 if (Result.hasValue())
10841 return ZeroInitialization(
E,
T);
10853 if (
E->isElidable() && !ZeroInit) {
10859 const Expr *SrcObj =
E->getArg(0);
10861 assert(Info.Ctx.hasSameUnqualifiedType(
E->
getType(), SrcObj->
getType()));
10863 dyn_cast<MaterializeTemporaryExpr>(SrcObj))
10864 return Visit(ME->getSubExpr());
10867 if (ZeroInit && !ZeroInitialization(
E,
T))
10876bool RecordExprEvaluator::VisitCXXInheritedCtorInitExpr(
10878 if (!Info.CurrentCall) {
10879 assert(Info.checkingPotentialConstantExpression());
10898bool RecordExprEvaluator::VisitCXXStdInitializerListExpr(
10901 Info.Ctx.getAsConstantArrayType(
E->getSubExpr()->
getType());
10907 assert(
ArrayType &&
"unexpected type for array initializer");
10914 Array.moveInto(Result.getStructField(0));
10918 assert(Field !=
Record->field_end() &&
10919 Info.Ctx.hasSameType(
Field->getType()->getPointeeType(),
10921 "Expected std::initializer_list first field to be const E *");
10923 assert(Field !=
Record->field_end() &&
10924 "Expected std::initializer_list to have two fields");
10926 if (Info.Ctx.hasSameType(
Field->getType(), Info.Ctx.getSizeType())) {
10931 assert(Info.Ctx.hasSameType(
Field->getType()->getPointeeType(),
10933 "Expected std::initializer_list second field to be const E *");
10938 Array.moveInto(Result.getStructField(1));
10941 assert(++Field ==
Record->field_end() &&
10942 "Expected std::initializer_list to only have two fields");
10947bool RecordExprEvaluator::VisitLambdaExpr(
const LambdaExpr *
E) {
10952 const size_t NumFields =
10955 assert(NumFields == (
size_t)std::distance(
E->capture_init_begin(),
10956 E->capture_init_end()) &&
10957 "The number of lambda capture initializers should equal the number of "
10958 "fields within the closure type");
10963 auto *CaptureInitIt =
E->capture_init_begin();
10965 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(ClosureClass);
10966 for (
const auto *Field : ClosureClass->
fields()) {
10967 assert(CaptureInitIt !=
E->capture_init_end());
10969 Expr *
const CurFieldInit = *CaptureInitIt++;
10976 LValue Subobject =
This;
10981 APValue &FieldVal = Result.getStructField(
Field->getFieldIndex());
10983 if (!Info.keepEvaluatingAfterFailure())
10992 APValue &Result, EvalInfo &Info) {
10995 "can't evaluate expression as a record rvalue");
10996 return RecordExprEvaluator(Info, This, Result).Visit(
E);
11007class TemporaryExprEvaluator
11008 :
public LValueExprEvaluatorBase<TemporaryExprEvaluator> {
11010 TemporaryExprEvaluator(EvalInfo &Info, LValue &Result) :
11011 LValueExprEvaluatorBaseTy(Info, Result,
false) {}
11014 bool VisitConstructExpr(
const Expr *
E) {
11016 E,
E->
getType(), ScopeKind::FullExpression, Result);
11020 bool VisitCastExpr(
const CastExpr *
E) {
11021 switch (
E->getCastKind()) {
11023 return LValueExprEvaluatorBaseTy::VisitCastExpr(
E);
11025 case CK_ConstructorConversion:
11026 return VisitConstructExpr(
E->getSubExpr());
11030 return VisitConstructExpr(
E);
11033 return VisitConstructExpr(
E);
11035 bool VisitCallExpr(
const CallExpr *
E) {
11036 return VisitConstructExpr(
E);
11039 return VisitConstructExpr(
E);
11042 return VisitConstructExpr(
E);
11051 return TemporaryExprEvaluator(Info, Result).Visit(
E);
11059 class VectorExprEvaluator
11060 :
public ExprEvaluatorBase<VectorExprEvaluator> {
11064 VectorExprEvaluator(EvalInfo &info,
APValue &Result)
11065 : ExprEvaluatorBaseTy(info), Result(Result) {}
11074 assert(
V.isVector());
11078 bool ZeroInitialization(
const Expr *
E);
11081 {
return Visit(
E->getSubExpr()); }
11098 "not a vector prvalue");
11099 return VectorExprEvaluator(Info, Result).Visit(
E);
11102bool VectorExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
11106 const Expr *SE =
E->getSubExpr();
11109 switch (
E->getCastKind()) {
11110 case CK_VectorSplat: {
11116 Val =
APValue(std::move(IntResult));
11121 Val =
APValue(std::move(FloatResult));
11138 Info.FFDiag(
E, diag::note_constexpr_invalid_cast)
11139 << 2 << Info.Ctx.getLangOpts().CPlusPlus;
11143 if (!handleRValueToRValueBitCast(Info, Result, SVal,
E))
11148 case CK_HLSLVectorTruncation: {
11153 for (
unsigned I = 0; I < NElts; I++)
11158 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
11163VectorExprEvaluator::VisitInitListExpr(
const InitListExpr *
E) {
11165 unsigned NumInits =
E->getNumInits();
11175 unsigned CountInits = 0, CountElts = 0;
11176 while (CountElts < NumElements) {
11178 if (CountInits < NumInits
11183 unsigned vlen =
v.getVectorLength();
11184 for (
unsigned j = 0; j < vlen; j++)
11185 Elements.push_back(
v.getVectorElt(j));
11188 llvm::APSInt sInt(32);
11189 if (CountInits < NumInits) {
11193 sInt = Info.Ctx.MakeIntValue(0, EltTy);
11194 Elements.push_back(
APValue(sInt));
11197 llvm::APFloat f(0.0);
11198 if (CountInits < NumInits) {
11202 f = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy));
11203 Elements.push_back(
APValue(f));
11212VectorExprEvaluator::ZeroInitialization(
const Expr *
E) {
11216 if (EltTy->isIntegerType())
11217 ZeroElement =
APValue(Info.Ctx.MakeIntValue(0, EltTy));
11220 APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy)));
11226bool VectorExprEvaluator::VisitUnaryImag(
const UnaryOperator *
E) {
11227 VisitIgnoredValue(
E->getSubExpr());
11228 return ZeroInitialization(
E);
11231bool VectorExprEvaluator::VisitBinaryOperator(
const BinaryOperator *
E) {
11233 assert(Op != BO_PtrMemD && Op != BO_PtrMemI && Op != BO_Cmp &&
11234 "Operation not supported on vector types");
11236 if (Op == BO_Comma)
11237 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
11239 Expr *LHS =
E->getLHS();
11240 Expr *RHS =
E->getRHS();
11243 "Must both be vector types");
11250 "All operands must be the same size.");
11254 bool LHSOK =
Evaluate(LHSValue, Info, LHS);
11255 if (!LHSOK && !Info.noteFailure())
11257 if (!
Evaluate(RHSValue, Info, RHS) || !LHSOK)
11279 "Vector can only be int or float type");
11287 "Vector operator ~ can only be int");
11288 Elt.
getInt().flipAllBits();
11298 "Vector can only be int or float type");
11304 EltResult.setAllBits();
11306 EltResult.clearAllBits();
11312 return std::nullopt;
11316bool VectorExprEvaluator::VisitUnaryOperator(
const UnaryOperator *
E) {
11317 Expr *SubExpr =
E->getSubExpr();
11322 const QualType ResultEltTy = VD->getElementType();
11326 if (!
Evaluate(SubExprValue, Info, SubExpr))
11339 "Vector length doesn't match type?");
11342 for (
unsigned EltNum = 0; EltNum < VD->getNumElements(); ++EltNum) {
11344 Info.Ctx, ResultEltTy, Op, SubExprValue.
getVectorElt(EltNum));
11347 ResultElements.push_back(*Elt);
11349 return Success(
APValue(ResultElements.data(), ResultElements.size()),
E);
11358 Result =
APValue(APFloat(0.0));
11360 DestTy, Result.getFloat());
11371 Result.getFloat());
11376 DestTy, Result.getInt());
11380 Info.FFDiag(
E, diag::err_convertvector_constexpr_unsupported_vector_cast)
11381 << SourceTy << DestTy;
11385bool VectorExprEvaluator::VisitCallExpr(
const CallExpr *
E) {
11386 if (!IsConstantEvaluatedBuiltinCall(
E))
11387 return ExprEvaluatorBaseTy::VisitCallExpr(
E);
11389 switch (
E->getBuiltinCallee()) {
11392 case Builtin::BI__builtin_elementwise_popcount:
11393 case Builtin::BI__builtin_elementwise_bitreverse: {
11401 ResultElements.reserve(SourceLen);
11403 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11405 switch (
E->getBuiltinCallee()) {
11406 case Builtin::BI__builtin_elementwise_popcount:
11407 ResultElements.push_back(
APValue(
11408 APSInt(
APInt(Info.Ctx.getIntWidth(DestEltTy), Elt.popcount()),
11411 case Builtin::BI__builtin_elementwise_bitreverse:
11412 ResultElements.push_back(
11419 return Success(
APValue(ResultElements.data(), ResultElements.size()),
E);
11421 case Builtin::BI__builtin_elementwise_add_sat:
11422 case Builtin::BI__builtin_elementwise_sub_sat: {
11423 APValue SourceLHS, SourceRHS;
11431 ResultElements.reserve(SourceLen);
11433 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11436 switch (
E->getBuiltinCallee()) {
11437 case Builtin::BI__builtin_elementwise_add_sat:
11438 ResultElements.push_back(
APValue(
11439 APSInt(LHS.isSigned() ? LHS.sadd_sat(RHS) : RHS.uadd_sat(RHS),
11442 case Builtin::BI__builtin_elementwise_sub_sat:
11443 ResultElements.push_back(
APValue(
11444 APSInt(LHS.isSigned() ? LHS.ssub_sat(RHS) : RHS.usub_sat(RHS),
11450 return Success(
APValue(ResultElements.data(), ResultElements.size()),
E);
11468 ResultElements.reserve(SourceLen);
11469 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11474 ResultElements.push_back(std::move(Elt));
11477 return Success(
APValue(ResultElements.data(), ResultElements.size()),
E);
11482 APValue const &VecVal2,
unsigned EltNum,
11484 unsigned const TotalElementsInInputVector1 = VecVal1.
getVectorLength();
11485 unsigned const TotalElementsInInputVector2 = VecVal2.
getVectorLength();
11487 APSInt IndexVal =
E->getShuffleMaskIdx(Info.Ctx, EltNum);
11488 int64_t index = IndexVal.getExtValue();
11495 E, diag::err_shufflevector_minus_one_is_undefined_behavior_constexpr)
11501 index >= TotalElementsInInputVector1 + TotalElementsInInputVector2)
11502 llvm_unreachable(
"Out of bounds shuffle index");
11504 if (index >= TotalElementsInInputVector1)
11505 Result = VecVal2.
getVectorElt(index - TotalElementsInInputVector1);
11513 const Expr *Vec1 =
E->getExpr(0);
11517 const Expr *Vec2 =
E->getExpr(1);
11527 ResultElements.reserve(TotalElementsInOutputVector);
11528 for (
unsigned EltNum = 0; EltNum < TotalElementsInOutputVector; ++EltNum) {
11532 ResultElements.push_back(std::move(Elt));
11535 return Success(
APValue(ResultElements.data(), ResultElements.size()),
E);
11543 class ArrayExprEvaluator
11544 :
public ExprEvaluatorBase<ArrayExprEvaluator> {
11545 const LValue &
This;
11549 ArrayExprEvaluator(EvalInfo &Info,
const LValue &This,
APValue &Result)
11550 : ExprEvaluatorBaseTy(Info),
This(
This), Result(Result) {}
11553 assert(
V.isArray() &&
"expected array");
11558 bool ZeroInitialization(
const Expr *
E) {
11560 Info.Ctx.getAsConstantArrayType(
E->
getType());
11574 if (!Result.hasArrayFiller())
11578 LValue Subobject =
This;
11579 Subobject.addArray(Info,
E, CAT);
11581 return EvaluateInPlace(Result.getArrayFiller(), Info, Subobject, &VIE);
11584 bool VisitCallExpr(
const CallExpr *
E) {
11585 return handleCallExpr(
E, Result, &This);
11592 const LValue &Subobject,
11600 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
11602 const Expr *ArrayFiller,
11608 APValue &Result, EvalInfo &Info) {
11611 "not an array prvalue");
11612 return ArrayExprEvaluator(Info, This, Result).Visit(
E);
11620 "not an array prvalue");
11621 return ArrayExprEvaluator(Info, This, Result)
11622 .VisitInitListExpr(ILE, AllocType);
11631 "not an array prvalue");
11632 return ArrayExprEvaluator(Info, This, Result)
11633 .VisitCXXConstructExpr(CCE, This, &Result, AllocType);
11640 if (isa<ImplicitValueInitExpr>(FillerExpr))
11642 if (
const InitListExpr *ILE = dyn_cast<InitListExpr>(FillerExpr)) {
11643 for (
unsigned I = 0,
E = ILE->getNumInits(); I !=
E; ++I) {
11648 if (ILE->hasArrayFiller() &&
11657bool ArrayExprEvaluator::VisitInitListExpr(
const InitListExpr *
E,
11666 if (
E->isStringLiteralInit()) {
11672 return VisitStringLiteral(SL, AllocType);
11676 assert(!
E->isTransparent() &&
11677 "transparent array list initialization is not string literal init?");
11679 return VisitCXXParenListOrInitListExpr(
E,
E->inits(),
E->getArrayFiller(),
11683bool ArrayExprEvaluator::VisitCXXParenListOrInitListExpr(
11691 assert((!Result.isArray() || Result.getArrayInitializedElts() == 0) &&
11692 "zero-initialized array shouldn't have any initialized elts");
11694 if (Result.isArray() && Result.hasArrayFiller())
11695 Filler = Result.getArrayFiller();
11697 unsigned NumEltsToInit = Args.size();
11702 if (NumEltsToInit != NumElts &&
11704 NumEltsToInit = NumElts;
11706 for (
auto *
Init : Args) {
11707 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts()))
11708 NumEltsToInit += EmbedS->getDataElementCount() - 1;
11710 if (NumEltsToInit > NumElts)
11711 NumEltsToInit = NumElts;
11714 LLVM_DEBUG(llvm::dbgs() <<
"The number of elements to initialize: "
11715 << NumEltsToInit <<
".\n");
11722 for (
unsigned I = 0,
E = Result.getArrayInitializedElts(); I !=
E; ++I)
11723 Result.getArrayInitializedElt(I) = Filler;
11724 if (Result.hasArrayFiller())
11725 Result.getArrayFiller() = Filler;
11728 LValue Subobject =
This;
11729 Subobject.addArray(Info, ExprToVisit, CAT);
11730 auto Eval = [&](
const Expr *
Init,
unsigned ArrayIndex) {
11731 if (
Init->isValueDependent())
11734 if (!
EvaluateInPlace(Result.getArrayInitializedElt(ArrayIndex), Info,
11735 Subobject,
Init) ||
11738 if (!Info.noteFailure())
11744 unsigned ArrayIndex = 0;
11747 for (
unsigned Index = 0; Index != NumEltsToInit; ++Index) {
11748 const Expr *
Init = Index < Args.size() ? Args[Index] : ArrayFiller;
11749 if (ArrayIndex >= NumEltsToInit)
11751 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
11753 for (
unsigned I = EmbedS->getStartingElementPos(),
11754 N = EmbedS->getDataElementCount();
11755 I != EmbedS->getStartingElementPos() + N; ++I) {
11758 Result.getArrayInitializedElt(ArrayIndex) =
APValue(
Value);
11762 Init->getFPFeaturesInEffect(Info.Ctx.getLangOpts());
11767 Result.getArrayInitializedElt(ArrayIndex) =
APValue(FValue);
11772 if (!Eval(
Init, ArrayIndex))
11778 if (!Result.hasArrayFiller())
11783 assert(ArrayFiller &&
"no array filler for incomplete init list");
11791 if (
E->getCommonExpr() &&
11792 !
Evaluate(Info.CurrentCall->createTemporary(
11793 E->getCommonExpr(),
11794 getStorageType(Info.Ctx,
E->getCommonExpr()),
11795 ScopeKind::FullExpression, CommonLV),
11796 Info,
E->getCommonExpr()->getSourceExpr()))
11804 LValue Subobject =
This;
11805 Subobject.addArray(Info,
E, CAT);
11808 for (EvalInfo::ArrayInitLoopIndex Index(Info); Index != Elements; ++Index) {
11817 FullExpressionRAII
Scope(Info);
11820 Info, Subobject,
E->getSubExpr()) ||
11823 if (!Info.noteFailure())
11836 return VisitCXXConstructExpr(
E, This, &Result,
E->
getType());
11840 const LValue &Subobject,
11850 HadZeroInit &&
Value->hasArrayFiller() ?
Value->getArrayFiller()
11854 if (FinalSize == 0)
11859 E->requiresZeroInitialization());
11860 LValue ArrayElt = Subobject;
11861 ArrayElt.addArray(Info,
E, CAT);
11867 for (
const unsigned N : {1u, FinalSize}) {
11868 unsigned OldElts =
Value->getArrayInitializedElts();
11874 for (
unsigned I = 0; I < OldElts; ++I)
11875 NewValue.getArrayInitializedElt(I).swap(
11876 Value->getArrayInitializedElt(I));
11877 Value->swap(NewValue);
11880 for (
unsigned I = OldElts; I < N; ++I)
11881 Value->getArrayInitializedElt(I) = Filler;
11883 if (HasTrivialConstructor && N == FinalSize && FinalSize != 1) {
11886 APValue &FirstResult =
Value->getArrayInitializedElt(0);
11887 for (
unsigned I = OldElts; I < FinalSize; ++I)
11888 Value->getArrayInitializedElt(I) = FirstResult;
11890 for (
unsigned I = OldElts; I < N; ++I) {
11891 if (!VisitCXXConstructExpr(
E, ArrayElt,
11892 &
Value->getArrayInitializedElt(I),
11899 if (Info.EvalStatus.Diag && !Info.EvalStatus.Diag->empty() &&
11900 !Info.keepEvaluatingAfterFailure())
11912 return RecordExprEvaluator(Info, Subobject, *
Value)
11913 .VisitCXXConstructExpr(
E,
Type);
11916bool ArrayExprEvaluator::VisitCXXParenListInitExpr(
11919 "Expression result is not a constant array type");
11921 return VisitCXXParenListOrInitListExpr(
E,
E->getInitExprs(),
11922 E->getArrayFiller());
11934class IntExprEvaluator
11935 :
public ExprEvaluatorBase<IntExprEvaluator> {
11938 IntExprEvaluator(EvalInfo &info,
APValue &result)
11939 : ExprEvaluatorBaseTy(info), Result(result) {}
11943 "Invalid evaluation result.");
11945 "Invalid evaluation result.");
11946 assert(SI.getBitWidth() == Info.Ctx.getIntWidth(
E->
getType()) &&
11947 "Invalid evaluation result.");
11957 "Invalid evaluation result.");
11958 assert(I.getBitWidth() == Info.Ctx.getIntWidth(
E->
getType()) &&
11959 "Invalid evaluation result.");
11961 Result.getInt().setIsUnsigned(
11971 "Invalid evaluation result.");
11986 if (
V.isLValue() ||
V.isAddrLabelDiff() ||
V.isIndeterminate() ||
11987 V.allowConstexprUnknown()) {
11994 bool ZeroInitialization(
const Expr *
E) {
return Success(0,
E); }
11996 friend std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &,
12010 bool CheckReferencedDecl(
const Expr *
E,
const Decl *
D);
12012 if (CheckReferencedDecl(
E,
E->getDecl()))
12015 return ExprEvaluatorBaseTy::VisitDeclRefExpr(
E);
12018 if (CheckReferencedDecl(
E,
E->getMemberDecl())) {
12019 VisitIgnoredBaseExpression(
E->getBase());
12023 return ExprEvaluatorBaseTy::VisitMemberExpr(
E);
12027 bool VisitBuiltinCallExpr(
const CallExpr *
E,
unsigned BuiltinOp);
12044 if (Info.ArrayInitIndex ==
uint64_t(-1)) {
12050 return Success(Info.ArrayInitIndex,
E);
12055 return ZeroInitialization(
E);
12088class FixedPointExprEvaluator
12089 :
public ExprEvaluatorBase<FixedPointExprEvaluator> {
12093 FixedPointExprEvaluator(EvalInfo &info,
APValue &result)
12094 : ExprEvaluatorBaseTy(info), Result(result) {}
12098 APFixedPoint(I, Info.Ctx.getFixedPointSemantics(
E->
getType())),
E);
12103 APFixedPoint(
Value, Info.Ctx.getFixedPointSemantics(
E->
getType())),
E);
12112 assert(
V.getWidth() == Info.Ctx.getIntWidth(
E->
getType()) &&
12113 "Invalid evaluation result.");
12118 bool ZeroInitialization(
const Expr *
E) {
12148 return IntExprEvaluator(Info, Result).Visit(
E);
12156 if (!Val.
isInt()) {
12159 Info.FFDiag(
E, diag::note_invalid_subexpr_in_const_expr);
12166bool IntExprEvaluator::VisitSourceLocExpr(
const SourceLocExpr *
E) {
12168 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.getDefaultExpr());
12177 if (!FixedPointExprEvaluator(Info, Val).Visit(
E))
12192 auto FXSema = Info.Ctx.getFixedPointSemantics(
E->
getType());
12196 Result = APFixedPoint(Val, FXSema);
12207bool IntExprEvaluator::CheckReferencedDecl(
const Expr*
E,
const Decl*
D) {
12211 bool SameSign = (ECD->getInitVal().isSigned()
12213 bool SameWidth = (ECD->getInitVal().getBitWidth()
12214 == Info.Ctx.getIntWidth(
E->
getType()));
12215 if (SameSign && SameWidth)
12216 return Success(ECD->getInitVal(),
E);
12220 llvm::APSInt Val = ECD->getInitVal();
12222 Val.setIsSigned(!ECD->getInitVal().isSigned());
12224 Val = Val.extOrTrunc(Info.Ctx.getIntWidth(
E->
getType()));
12240#define TYPE(ID, BASE)
12241#define DEPENDENT_TYPE(ID, BASE) case Type::ID:
12242#define NON_CANONICAL_TYPE(ID, BASE) case Type::ID:
12243#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(ID, BASE) case Type::ID:
12244#include "clang/AST/TypeNodes.inc"
12246 case Type::DeducedTemplateSpecialization:
12247 llvm_unreachable(
"unexpected non-canonical or dependent type");
12249 case Type::Builtin:
12250 switch (cast<BuiltinType>(CanTy)->
getKind()) {
12251#define BUILTIN_TYPE(ID, SINGLETON_ID)
12252#define SIGNED_TYPE(ID, SINGLETON_ID) \
12253 case BuiltinType::ID: return GCCTypeClass::Integer;
12254#define FLOATING_TYPE(ID, SINGLETON_ID) \
12255 case BuiltinType::ID: return GCCTypeClass::RealFloat;
12256#define PLACEHOLDER_TYPE(ID, SINGLETON_ID) \
12257 case BuiltinType::ID: break;
12258#include "clang/AST/BuiltinTypes.def"
12259 case BuiltinType::Void:
12260 return GCCTypeClass::Void;
12262 case BuiltinType::Bool:
12263 return GCCTypeClass::Bool;
12265 case BuiltinType::Char_U:
12266 case BuiltinType::UChar:
12267 case BuiltinType::WChar_U:
12268 case BuiltinType::Char8:
12269 case BuiltinType::Char16:
12270 case BuiltinType::Char32:
12271 case BuiltinType::UShort:
12272 case BuiltinType::UInt:
12273 case BuiltinType::ULong:
12274 case BuiltinType::ULongLong:
12275 case BuiltinType::UInt128:
12276 return GCCTypeClass::Integer;
12278 case BuiltinType::UShortAccum:
12279 case BuiltinType::UAccum:
12280 case BuiltinType::ULongAccum:
12281 case BuiltinType::UShortFract:
12282 case BuiltinType::UFract:
12283 case BuiltinType::ULongFract:
12284 case BuiltinType::SatUShortAccum:
12285 case BuiltinType::SatUAccum:
12286 case BuiltinType::SatULongAccum:
12287 case BuiltinType::SatUShortFract:
12288 case BuiltinType::SatUFract:
12289 case BuiltinType::SatULongFract:
12290 return GCCTypeClass::None;
12292 case BuiltinType::NullPtr:
12294 case BuiltinType::ObjCId:
12295 case BuiltinType::ObjCClass:
12296 case BuiltinType::ObjCSel:
12297#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
12298 case BuiltinType::Id:
12299#include "clang/Basic/OpenCLImageTypes.def"
12300#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
12301 case BuiltinType::Id:
12302#include "clang/Basic/OpenCLExtensionTypes.def"
12303 case BuiltinType::OCLSampler:
12304 case BuiltinType::OCLEvent:
12305 case BuiltinType::OCLClkEvent:
12306 case BuiltinType::OCLQueue:
12307 case BuiltinType::OCLReserveID:
12308#define SVE_TYPE(Name, Id, SingletonId) \
12309 case BuiltinType::Id:
12310#include "clang/Basic/AArch64SVEACLETypes.def"
12311#define PPC_VECTOR_TYPE(Name, Id, Size) \
12312 case BuiltinType::Id:
12313#include "clang/Basic/PPCTypes.def"
12314#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
12315#include "clang/Basic/RISCVVTypes.def"
12316#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
12317#include "clang/Basic/WebAssemblyReferenceTypes.def"
12318#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
12319#include "clang/Basic/AMDGPUTypes.def"
12320#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
12321#include "clang/Basic/HLSLIntangibleTypes.def"
12322 return GCCTypeClass::None;
12324 case BuiltinType::Dependent:
12325 llvm_unreachable(
"unexpected dependent type");
12327 llvm_unreachable(
"unexpected placeholder type");
12330 return LangOpts.CPlusPlus ? GCCTypeClass::Enum : GCCTypeClass::Integer;
12332 case Type::Pointer:
12333 case Type::ConstantArray:
12334 case Type::VariableArray:
12335 case Type::IncompleteArray:
12336 case Type::FunctionNoProto:
12337 case Type::FunctionProto:
12338 case Type::ArrayParameter:
12339 return GCCTypeClass::Pointer;
12341 case Type::MemberPointer:
12343 ? GCCTypeClass::PointerToDataMember
12344 : GCCTypeClass::PointerToMemberFunction;
12346 case Type::Complex:
12347 return GCCTypeClass::Complex;
12350 return CanTy->
isUnionType() ? GCCTypeClass::Union
12351 : GCCTypeClass::ClassOrStruct;
12359 case Type::ExtVector:
12360 return GCCTypeClass::Vector;
12362 case Type::BlockPointer:
12363 case Type::ConstantMatrix:
12364 case Type::ObjCObject:
12365 case Type::ObjCInterface:
12366 case Type::ObjCObjectPointer:
12368 case Type::HLSLAttributedResource:
12371 return GCCTypeClass::None;
12374 return GCCTypeClass::BitInt;
12376 case Type::LValueReference:
12377 case Type::RValueReference:
12378 llvm_unreachable(
"invalid type for expression");
12381 llvm_unreachable(
"unexpected type class");
12390 if (
E->getNumArgs() == 0)
12391 return GCCTypeClass::None;
12406 if (
Base.isNull()) {
12409 }
else if (
const Expr *
E =
Base.dyn_cast<
const Expr *>()) {
12410 if (!isa<StringLiteral>(
E))
12428 SpeculativeEvaluationRAII SpeculativeEval(Info);
12433 FoldConstant Fold(Info,
true);
12456 Fold.keepDiagnostics();
12465 return V.hasValue();
12476 if (
const VarDecl *VD = dyn_cast<VarDecl>(
D))
12479 if (isa<CompoundLiteralExpr>(
E))
12500 const auto *Cast = dyn_cast<CastExpr>(NoParens);
12501 if (Cast ==
nullptr)
12506 auto CastKind = Cast->getCastKind();
12508 CastKind != CK_AddressSpaceConversion)
12511 const auto *SubExpr = Cast->getSubExpr();
12533 assert(!LVal.Designator.Invalid);
12535 auto IsLastOrInvalidFieldDecl = [&Ctx](
const FieldDecl *FD,
bool &
Invalid) {
12544 auto &
Base = LVal.getLValueBase();
12545 if (
auto *ME = dyn_cast_or_null<MemberExpr>(
Base.dyn_cast<
const Expr *>())) {
12546 if (
auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
12548 if (!IsLastOrInvalidFieldDecl(FD,
Invalid))
12550 }
else if (
auto *IFD = dyn_cast<IndirectFieldDecl>(ME->getMemberDecl())) {
12551 for (
auto *FD : IFD->chain()) {
12553 if (!IsLastOrInvalidFieldDecl(cast<FieldDecl>(FD),
Invalid))
12561 if (LVal.Designator.FirstEntryIsAnUnsizedArray) {
12571 for (
unsigned E = LVal.Designator.Entries.size(); I !=
E; ++I) {
12572 const auto &Entry = LVal.Designator.Entries[I];
12578 const auto *CAT = cast<ConstantArrayType>(Ctx.
getAsArrayType(BaseType));
12579 uint64_t Index = Entry.getAsArrayIndex();
12585 uint64_t Index = Entry.getAsArrayIndex();
12588 BaseType = CT->getElementType();
12589 }
else if (
auto *FD = getAsField(Entry)) {
12591 if (!IsLastOrInvalidFieldDecl(FD,
Invalid))
12595 assert(getAsBaseClass(Entry) &&
"Expecting cast to a base class");
12607 if (LVal.Designator.Invalid)
12610 if (!LVal.Designator.Entries.empty())
12611 return LVal.Designator.isMostDerivedAnUnsizedArray();
12613 if (!LVal.InvalidBase)
12618 const auto *
E = LVal.Base.dyn_cast<
const Expr *>();
12619 return !
E || !isa<MemberExpr>(
E);
12625 const SubobjectDesignator &
Designator = LVal.Designator;
12637 auto isFlexibleArrayMember = [&] {
12639 FAMKind StrictFlexArraysLevel =
12642 if (
Designator.isMostDerivedAnUnsizedArray())
12645 if (StrictFlexArraysLevel == FAMKind::Default)
12648 if (
Designator.getMostDerivedArraySize() == 0 &&
12649 StrictFlexArraysLevel != FAMKind::IncompleteOnly)
12652 if (
Designator.getMostDerivedArraySize() == 1 &&
12653 StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete)
12659 return LVal.InvalidBase &&
12661 Designator.MostDerivedIsArrayElement && isFlexibleArrayMember() &&
12669 auto CharUnitsMax = std::numeric_limits<CharUnits::QuantityType>::max();
12670 if (Int.ugt(CharUnitsMax))
12682 if (
const auto *
V = LV.getLValueBase().dyn_cast<
const ValueDecl *>())
12683 if (
const auto *VD = dyn_cast<VarDecl>(
V))
12695 unsigned Type,
const LValue &LVal,
12712 if (!(
Type & 1) || LVal.Designator.Invalid || DetermineForCompleteObject) {
12714 if (
Type == 3 && !DetermineForCompleteObject)
12717 llvm::APInt APEndOffset;
12718 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
12722 if (LVal.InvalidBase)
12726 const bool Ret = CheckedHandleSizeof(BaseTy, EndOffset);
12732 const SubobjectDesignator &
Designator = LVal.Designator;
12744 llvm::APInt APEndOffset;
12745 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
12757 if (!CheckedHandleSizeof(
Designator.MostDerivedType, BytesPerElem))
12763 int64_t ElemsRemaining;
12766 uint64_t ArraySize =
Designator.getMostDerivedArraySize();
12767 uint64_t ArrayIndex =
Designator.Entries.back().getAsArrayIndex();
12768 ElemsRemaining = ArraySize <= ArrayIndex ? 0 : ArraySize - ArrayIndex;
12770 ElemsRemaining =
Designator.isOnePastTheEnd() ? 0 : 1;
12773 EndOffset = LVal.getLValueOffset() + BytesPerElem * ElemsRemaining;
12783 EvalInfo &Info, uint64_t &Size) {
12790 SpeculativeEvaluationRAII SpeculativeEval(Info);
12791 IgnoreSideEffectsRAII Fold(Info);
12799 LVal.setFrom(Info.Ctx, RVal);
12807 if (LVal.getLValueOffset().isNegative()) {
12818 if (EndOffset <= LVal.getLValueOffset())
12821 Size = (EndOffset - LVal.getLValueOffset()).getQuantity();
12825bool IntExprEvaluator::VisitCallExpr(
const CallExpr *
E) {
12826 if (!IsConstantEvaluatedBuiltinCall(
E))
12827 return ExprEvaluatorBaseTy::VisitCallExpr(
E);
12828 return VisitBuiltinCallExpr(
E,
E->getBuiltinCallee());
12844 Info.FFDiag(
E->getArg(0));
12850 assert(SrcInt.getBitWidth() >= Alignment.getBitWidth() &&
12851 "Bit widths must be the same");
12858bool IntExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *
E,
12859 unsigned BuiltinOp) {
12860 switch (BuiltinOp) {
12864 case Builtin::BI__builtin_dynamic_object_size:
12865 case Builtin::BI__builtin_object_size: {
12869 assert(
Type <= 3 &&
"unexpected type");
12880 switch (Info.EvalMode) {
12881 case EvalInfo::EM_ConstantExpression:
12882 case EvalInfo::EM_ConstantFold:
12883 case EvalInfo::EM_IgnoreSideEffects:
12886 case EvalInfo::EM_ConstantExpressionUnevaluated:
12891 llvm_unreachable(
"unexpected EvalMode");
12894 case Builtin::BI__builtin_os_log_format_buffer_size: {
12900 case Builtin::BI__builtin_is_aligned: {
12908 Ptr.setFrom(Info.Ctx, Src);
12914 assert(Alignment.isPowerOf2());
12927 Info.FFDiag(
E->getArg(0), diag::note_constexpr_alignment_compute)
12931 assert(Src.
isInt());
12932 return Success((Src.
getInt() & (Alignment - 1)) == 0 ? 1 : 0,
E);
12934 case Builtin::BI__builtin_align_up: {
12942 APSInt((Src.
getInt() + (Alignment - 1)) & ~(Alignment - 1),
12943 Src.
getInt().isUnsigned());
12944 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
12947 case Builtin::BI__builtin_align_down: {
12956 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
12960 case Builtin::BI__builtin_bitreverse8:
12961 case Builtin::BI__builtin_bitreverse16:
12962 case Builtin::BI__builtin_bitreverse32:
12963 case Builtin::BI__builtin_bitreverse64:
12964 case Builtin::BI__builtin_elementwise_bitreverse: {
12969 return Success(Val.reverseBits(),
E);
12972 case Builtin::BI__builtin_bswap16:
12973 case Builtin::BI__builtin_bswap32:
12974 case Builtin::BI__builtin_bswap64: {
12979 return Success(Val.byteSwap(),
E);
12982 case Builtin::BI__builtin_classify_type:
12985 case Builtin::BI__builtin_clrsb:
12986 case Builtin::BI__builtin_clrsbl:
12987 case Builtin::BI__builtin_clrsbll: {
12992 return Success(Val.getBitWidth() - Val.getSignificantBits(),
E);
12995 case Builtin::BI__builtin_clz:
12996 case Builtin::BI__builtin_clzl:
12997 case Builtin::BI__builtin_clzll:
12998 case Builtin::BI__builtin_clzs:
12999 case Builtin::BI__builtin_clzg:
13000 case Builtin::BI__lzcnt16:
13001 case Builtin::BI__lzcnt:
13002 case Builtin::BI__lzcnt64: {
13007 std::optional<APSInt> Fallback;
13008 if (BuiltinOp == Builtin::BI__builtin_clzg &&
E->getNumArgs() > 1) {
13012 Fallback = FallbackTemp;
13022 bool ZeroIsUndefined = BuiltinOp != Builtin::BI__lzcnt16 &&
13023 BuiltinOp != Builtin::BI__lzcnt &&
13024 BuiltinOp != Builtin::BI__lzcnt64;
13026 if (ZeroIsUndefined)
13030 return Success(Val.countl_zero(),
E);
13033 case Builtin::BI__builtin_constant_p: {
13034 const Expr *Arg =
E->getArg(0);
13043 Info.FFDiag(
E, diag::note_invalid_subexpr_in_const_expr);
13047 case Builtin::BI__noop:
13051 case Builtin::BI__builtin_is_constant_evaluated: {
13052 const auto *
Callee = Info.CurrentCall->getCallee();
13053 if (Info.InConstantContext && !Info.CheckingPotentialConstantExpression &&
13054 (Info.CallStackDepth == 1 ||
13055 (Info.CallStackDepth == 2 &&
Callee->isInStdNamespace() &&
13056 Callee->getIdentifier() &&
13057 Callee->getIdentifier()->isStr(
"is_constant_evaluated")))) {
13059 if (Info.EvalStatus.Diag)
13060 Info.report((Info.CallStackDepth == 1)
13062 : Info.CurrentCall->getCallRange().getBegin(),
13063 diag::warn_is_constant_evaluated_always_true_constexpr)
13064 << (Info.CallStackDepth == 1 ?
"__builtin_is_constant_evaluated"
13065 :
"std::is_constant_evaluated");
13068 return Success(Info.InConstantContext,
E);
13071 case Builtin::BI__builtin_is_within_lifetime:
13072 if (
auto result = EvaluateBuiltinIsWithinLifetime(*
this,
E))
13076 case Builtin::BI__builtin_ctz:
13077 case Builtin::BI__builtin_ctzl:
13078 case Builtin::BI__builtin_ctzll:
13079 case Builtin::BI__builtin_ctzs:
13080 case Builtin::BI__builtin_ctzg: {
13085 std::optional<APSInt> Fallback;
13086 if (BuiltinOp == Builtin::BI__builtin_ctzg &&
E->getNumArgs() > 1) {
13090 Fallback = FallbackTemp;
13100 return Success(Val.countr_zero(),
E);
13103 case Builtin::BI__builtin_eh_return_data_regno: {
13105 Operand = Info.Ctx.getTargetInfo().getEHDataRegisterNumber(Operand);
13109 case Builtin::BI__builtin_expect:
13110 case Builtin::BI__builtin_expect_with_probability:
13111 return Visit(
E->getArg(0));
13113 case Builtin::BI__builtin_ptrauth_string_discriminator: {
13120 case Builtin::BI__builtin_ffs:
13121 case Builtin::BI__builtin_ffsl:
13122 case Builtin::BI__builtin_ffsll: {
13127 unsigned N = Val.countr_zero();
13128 return Success(N == Val.getBitWidth() ? 0 : N + 1,
E);
13131 case Builtin::BI__builtin_fpclassify: {
13136 switch (Val.getCategory()) {
13137 case APFloat::fcNaN: Arg = 0;
break;
13138 case APFloat::fcInfinity: Arg = 1;
break;
13139 case APFloat::fcNormal: Arg = Val.isDenormal() ? 3 : 2;
break;
13140 case APFloat::fcZero: Arg = 4;
break;
13142 return Visit(
E->getArg(Arg));
13145 case Builtin::BI__builtin_isinf_sign: {
13148 Success(Val.isInfinity() ? (Val.isNegative() ? -1 : 1) : 0,
E);
13151 case Builtin::BI__builtin_isinf: {
13154 Success(Val.isInfinity() ? 1 : 0,
E);
13157 case Builtin::BI__builtin_isfinite: {
13160 Success(Val.isFinite() ? 1 : 0,
E);
13163 case Builtin::BI__builtin_isnan: {
13169 case Builtin::BI__builtin_isnormal: {
13172 Success(Val.isNormal() ? 1 : 0,
E);
13175 case Builtin::BI__builtin_issubnormal: {
13178 Success(Val.isDenormal() ? 1 : 0,
E);
13181 case Builtin::BI__builtin_iszero: {
13187 case Builtin::BI__builtin_signbit:
13188 case Builtin::BI__builtin_signbitf:
13189 case Builtin::BI__builtin_signbitl: {
13192 Success(Val.isNegative() ? 1 : 0,
E);
13195 case Builtin::BI__builtin_isgreater:
13196 case Builtin::BI__builtin_isgreaterequal:
13197 case Builtin::BI__builtin_isless:
13198 case Builtin::BI__builtin_islessequal:
13199 case Builtin::BI__builtin_islessgreater:
13200 case Builtin::BI__builtin_isunordered: {
13209 switch (BuiltinOp) {
13210 case Builtin::BI__builtin_isgreater:
13212 case Builtin::BI__builtin_isgreaterequal:
13214 case Builtin::BI__builtin_isless:
13216 case Builtin::BI__builtin_islessequal:
13218 case Builtin::BI__builtin_islessgreater: {
13219 APFloat::cmpResult cmp = LHS.compare(RHS);
13220 return cmp == APFloat::cmpResult::cmpLessThan ||
13221 cmp == APFloat::cmpResult::cmpGreaterThan;
13223 case Builtin::BI__builtin_isunordered:
13224 return LHS.compare(RHS) == APFloat::cmpResult::cmpUnordered;
13226 llvm_unreachable(
"Unexpected builtin ID: Should be a floating "
13227 "point comparison function");
13235 case Builtin::BI__builtin_issignaling: {
13238 Success(Val.isSignaling() ? 1 : 0,
E);
13241 case Builtin::BI__builtin_isfpclass: {
13245 unsigned Test =
static_cast<llvm::FPClassTest
>(MaskVal.getZExtValue());
13248 Success((Val.classify() & Test) ? 1 : 0,
E);
13251 case Builtin::BI__builtin_parity:
13252 case Builtin::BI__builtin_parityl:
13253 case Builtin::BI__builtin_parityll: {
13258 return Success(Val.popcount() % 2,
E);
13261 case Builtin::BI__builtin_abs:
13262 case Builtin::BI__builtin_labs:
13263 case Builtin::BI__builtin_llabs: {
13267 if (Val ==
APSInt(APInt::getSignedMinValue(Val.getBitWidth()),
13270 if (Val.isNegative())
13275 case Builtin::BI__builtin_popcount:
13276 case Builtin::BI__builtin_popcountl:
13277 case Builtin::BI__builtin_popcountll:
13278 case Builtin::BI__builtin_popcountg:
13279 case Builtin::BI__builtin_elementwise_popcount:
13280 case Builtin::BI__popcnt16:
13281 case Builtin::BI__popcnt:
13282 case Builtin::BI__popcnt64: {
13287 return Success(Val.popcount(),
E);
13290 case Builtin::BI__builtin_rotateleft8:
13291 case Builtin::BI__builtin_rotateleft16:
13292 case Builtin::BI__builtin_rotateleft32:
13293 case Builtin::BI__builtin_rotateleft64:
13294 case Builtin::BI_rotl8:
13295 case Builtin::BI_rotl16:
13296 case Builtin::BI_rotl:
13297 case Builtin::BI_lrotl:
13298 case Builtin::BI_rotl64: {
13304 return Success(Val.rotl(Amt.urem(Val.getBitWidth())),
E);
13307 case Builtin::BI__builtin_rotateright8:
13308 case Builtin::BI__builtin_rotateright16:
13309 case Builtin::BI__builtin_rotateright32:
13310 case Builtin::BI__builtin_rotateright64:
13311 case Builtin::BI_rotr8:
13312 case Builtin::BI_rotr16:
13313 case Builtin::BI_rotr:
13314 case Builtin::BI_lrotr:
13315 case Builtin::BI_rotr64: {
13321 return Success(Val.rotr(Amt.urem(Val.getBitWidth())),
E);
13324 case Builtin::BI__builtin_elementwise_add_sat: {
13330 APInt Result = LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS);
13333 case Builtin::BI__builtin_elementwise_sub_sat: {
13339 APInt Result = LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
13343 case Builtin::BIstrlen:
13344 case Builtin::BIwcslen:
13346 if (Info.getLangOpts().CPlusPlus11)
13347 Info.CCEDiag(
E, diag::note_constexpr_invalid_function)
13349 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
13351 Info.CCEDiag(
E, diag::note_invalid_subexpr_in_const_expr);
13353 case Builtin::BI__builtin_strlen:
13354 case Builtin::BI__builtin_wcslen: {
13363 case Builtin::BIstrcmp:
13364 case Builtin::BIwcscmp:
13365 case Builtin::BIstrncmp:
13366 case Builtin::BIwcsncmp:
13367 case Builtin::BImemcmp:
13368 case Builtin::BIbcmp:
13369 case Builtin::BIwmemcmp:
13371 if (Info.getLangOpts().CPlusPlus11)
13372 Info.CCEDiag(
E, diag::note_constexpr_invalid_function)
13374 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
13376 Info.CCEDiag(
E, diag::note_invalid_subexpr_in_const_expr);
13378 case Builtin::BI__builtin_strcmp:
13379 case Builtin::BI__builtin_wcscmp:
13380 case Builtin::BI__builtin_strncmp:
13381 case Builtin::BI__builtin_wcsncmp:
13382 case Builtin::BI__builtin_memcmp:
13383 case Builtin::BI__builtin_bcmp:
13384 case Builtin::BI__builtin_wmemcmp: {
13385 LValue String1, String2;
13391 if (BuiltinOp != Builtin::BIstrcmp &&
13392 BuiltinOp != Builtin::BIwcscmp &&
13393 BuiltinOp != Builtin::BI__builtin_strcmp &&
13394 BuiltinOp != Builtin::BI__builtin_wcscmp) {
13398 MaxLength = N.getZExtValue();
13402 if (MaxLength == 0u)
13405 if (!String1.checkNullPointerForFoldAccess(Info,
E,
AK_Read) ||
13406 !String2.checkNullPointerForFoldAccess(Info,
E,
AK_Read) ||
13407 String1.Designator.Invalid || String2.Designator.Invalid)
13410 QualType CharTy1 = String1.Designator.getType(Info.Ctx);
13411 QualType CharTy2 = String2.Designator.getType(Info.Ctx);
13413 bool IsRawByte = BuiltinOp == Builtin::BImemcmp ||
13414 BuiltinOp == Builtin::BIbcmp ||
13415 BuiltinOp == Builtin::BI__builtin_memcmp ||
13416 BuiltinOp == Builtin::BI__builtin_bcmp;
13418 assert(IsRawByte ||
13419 (Info.Ctx.hasSameUnqualifiedType(
13421 Info.Ctx.hasSameUnqualifiedType(CharTy1, CharTy2)));
13428 Info.FFDiag(
E, diag::note_constexpr_memcmp_unsupported)
13429 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp) << CharTy1
13434 const auto &ReadCurElems = [&](
APValue &Char1,
APValue &Char2) {
13437 Char1.
isInt() && Char2.isInt();
13439 const auto &AdvanceElems = [&] {
13445 (BuiltinOp != Builtin::BImemcmp && BuiltinOp != Builtin::BIbcmp &&
13446 BuiltinOp != Builtin::BIwmemcmp &&
13447 BuiltinOp != Builtin::BI__builtin_memcmp &&
13448 BuiltinOp != Builtin::BI__builtin_bcmp &&
13449 BuiltinOp != Builtin::BI__builtin_wmemcmp);
13450 bool IsWide = BuiltinOp == Builtin::BIwcscmp ||
13451 BuiltinOp == Builtin::BIwcsncmp ||
13452 BuiltinOp == Builtin::BIwmemcmp ||
13453 BuiltinOp == Builtin::BI__builtin_wcscmp ||
13454 BuiltinOp == Builtin::BI__builtin_wcsncmp ||
13455 BuiltinOp == Builtin::BI__builtin_wmemcmp;
13457 for (; MaxLength; --MaxLength) {
13459 if (!ReadCurElems(Char1, Char2))
13467 if (StopAtNull && !Char1.
getInt())
13469 assert(!(StopAtNull && !Char2.
getInt()));
13470 if (!AdvanceElems())
13477 case Builtin::BI__atomic_always_lock_free:
13478 case Builtin::BI__atomic_is_lock_free:
13479 case Builtin::BI__c11_atomic_is_lock_free: {
13495 if (
Size.isPowerOfTwo()) {
13497 unsigned InlineWidthBits =
13498 Info.Ctx.getTargetInfo().getMaxAtomicInlineWidth();
13499 if (Size <= Info.Ctx.toCharUnitsFromBits(InlineWidthBits)) {
13500 if (BuiltinOp == Builtin::BI__c11_atomic_is_lock_free ||
13506 const Expr *PtrArg =
E->getArg(1);
13512 IntResult.isAligned(
Size.getAsAlign()))
13516 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(PtrArg)) {
13519 if (ICE->getCastKind() == CK_BitCast)
13520 PtrArg = ICE->getSubExpr();
13526 Info.Ctx.getTypeAlignInChars(PointeeType) >= Size) {
13534 return BuiltinOp == Builtin::BI__atomic_always_lock_free ?
13537 case Builtin::BI__builtin_addcb:
13538 case Builtin::BI__builtin_addcs:
13539 case Builtin::BI__builtin_addc:
13540 case Builtin::BI__builtin_addcl:
13541 case Builtin::BI__builtin_addcll:
13542 case Builtin::BI__builtin_subcb:
13543 case Builtin::BI__builtin_subcs:
13544 case Builtin::BI__builtin_subc:
13545 case Builtin::BI__builtin_subcl:
13546 case Builtin::BI__builtin_subcll: {
13547 LValue CarryOutLValue;
13548 APSInt LHS, RHS, CarryIn, CarryOut, Result;
13559 bool FirstOverflowed =
false;
13560 bool SecondOverflowed =
false;
13561 switch (BuiltinOp) {
13563 llvm_unreachable(
"Invalid value for BuiltinOp");
13564 case Builtin::BI__builtin_addcb:
13565 case Builtin::BI__builtin_addcs:
13566 case Builtin::BI__builtin_addc:
13567 case Builtin::BI__builtin_addcl:
13568 case Builtin::BI__builtin_addcll:
13570 LHS.uadd_ov(RHS, FirstOverflowed).uadd_ov(CarryIn, SecondOverflowed);
13572 case Builtin::BI__builtin_subcb:
13573 case Builtin::BI__builtin_subcs:
13574 case Builtin::BI__builtin_subc:
13575 case Builtin::BI__builtin_subcl:
13576 case Builtin::BI__builtin_subcll:
13578 LHS.usub_ov(RHS, FirstOverflowed).usub_ov(CarryIn, SecondOverflowed);
13584 CarryOut = (
uint64_t)(FirstOverflowed | SecondOverflowed);
13590 case Builtin::BI__builtin_add_overflow:
13591 case Builtin::BI__builtin_sub_overflow:
13592 case Builtin::BI__builtin_mul_overflow:
13593 case Builtin::BI__builtin_sadd_overflow:
13594 case Builtin::BI__builtin_uadd_overflow:
13595 case Builtin::BI__builtin_uaddl_overflow:
13596 case Builtin::BI__builtin_uaddll_overflow:
13597 case Builtin::BI__builtin_usub_overflow:
13598 case Builtin::BI__builtin_usubl_overflow:
13599 case Builtin::BI__builtin_usubll_overflow:
13600 case Builtin::BI__builtin_umul_overflow:
13601 case Builtin::BI__builtin_umull_overflow:
13602 case Builtin::BI__builtin_umulll_overflow:
13603 case Builtin::BI__builtin_saddl_overflow:
13604 case Builtin::BI__builtin_saddll_overflow:
13605 case Builtin::BI__builtin_ssub_overflow:
13606 case Builtin::BI__builtin_ssubl_overflow:
13607 case Builtin::BI__builtin_ssubll_overflow:
13608 case Builtin::BI__builtin_smul_overflow:
13609 case Builtin::BI__builtin_smull_overflow:
13610 case Builtin::BI__builtin_smulll_overflow: {
13611 LValue ResultLValue;
13621 bool DidOverflow =
false;
13624 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
13625 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
13626 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
13627 bool IsSigned = LHS.isSigned() || RHS.isSigned() ||
13629 bool AllSigned = LHS.isSigned() && RHS.isSigned() &&
13631 uint64_t LHSSize = LHS.getBitWidth();
13632 uint64_t RHSSize = RHS.getBitWidth();
13633 uint64_t ResultSize = Info.Ctx.getTypeSize(ResultType);
13634 uint64_t MaxBits = std::max(std::max(LHSSize, RHSSize), ResultSize);
13640 if (IsSigned && !AllSigned)
13643 LHS =
APSInt(LHS.extOrTrunc(MaxBits), !IsSigned);
13644 RHS =
APSInt(RHS.extOrTrunc(MaxBits), !IsSigned);
13645 Result =
APSInt(MaxBits, !IsSigned);
13649 switch (BuiltinOp) {
13651 llvm_unreachable(
"Invalid value for BuiltinOp");
13652 case Builtin::BI__builtin_add_overflow:
13653 case Builtin::BI__builtin_sadd_overflow:
13654 case Builtin::BI__builtin_saddl_overflow:
13655 case Builtin::BI__builtin_saddll_overflow:
13656 case Builtin::BI__builtin_uadd_overflow:
13657 case Builtin::BI__builtin_uaddl_overflow:
13658 case Builtin::BI__builtin_uaddll_overflow:
13659 Result = LHS.isSigned() ? LHS.sadd_ov(RHS, DidOverflow)
13660 : LHS.uadd_ov(RHS, DidOverflow);
13662 case Builtin::BI__builtin_sub_overflow:
13663 case Builtin::BI__builtin_ssub_overflow:
13664 case Builtin::BI__builtin_ssubl_overflow:
13665 case Builtin::BI__builtin_ssubll_overflow:
13666 case Builtin::BI__builtin_usub_overflow:
13667 case Builtin::BI__builtin_usubl_overflow:
13668 case Builtin::BI__builtin_usubll_overflow:
13669 Result = LHS.isSigned() ? LHS.ssub_ov(RHS, DidOverflow)
13670 : LHS.usub_ov(RHS, DidOverflow);
13672 case Builtin::BI__builtin_mul_overflow:
13673 case Builtin::BI__builtin_smul_overflow:
13674 case Builtin::BI__builtin_smull_overflow:
13675 case Builtin::BI__builtin_smulll_overflow:
13676 case Builtin::BI__builtin_umul_overflow:
13677 case Builtin::BI__builtin_umull_overflow:
13678 case Builtin::BI__builtin_umulll_overflow:
13679 Result = LHS.isSigned() ? LHS.smul_ov(RHS, DidOverflow)
13680 : LHS.umul_ov(RHS, DidOverflow);
13686 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
13687 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
13688 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
13694 APSInt Temp = Result.extOrTrunc(Info.Ctx.getTypeSize(ResultType));
13697 if (!APSInt::isSameValue(Temp, Result))
13698 DidOverflow =
true;
13708 case Builtin::BI__builtin_reduce_add:
13709 case Builtin::BI__builtin_reduce_mul:
13710 case Builtin::BI__builtin_reduce_and:
13711 case Builtin::BI__builtin_reduce_or:
13712 case Builtin::BI__builtin_reduce_xor:
13713 case Builtin::BI__builtin_reduce_min:
13714 case Builtin::BI__builtin_reduce_max: {
13721 for (
unsigned EltNum = 1; EltNum < SourceLen; ++EltNum) {
13722 switch (BuiltinOp) {
13725 case Builtin::BI__builtin_reduce_add: {
13728 Reduced.getBitWidth() + 1, std::plus<APSInt>(), Reduced))
13732 case Builtin::BI__builtin_reduce_mul: {
13735 Reduced.getBitWidth() * 2, std::multiplies<APSInt>(), Reduced))
13739 case Builtin::BI__builtin_reduce_and: {
13743 case Builtin::BI__builtin_reduce_or: {
13747 case Builtin::BI__builtin_reduce_xor: {
13751 case Builtin::BI__builtin_reduce_min: {
13755 case Builtin::BI__builtin_reduce_max: {
13765 case clang::X86::BI__builtin_ia32_addcarryx_u32:
13766 case clang::X86::BI__builtin_ia32_addcarryx_u64:
13767 case clang::X86::BI__builtin_ia32_subborrow_u32:
13768 case clang::X86::BI__builtin_ia32_subborrow_u64: {
13769 LValue ResultLValue;
13770 APSInt CarryIn, LHS, RHS;
13778 bool IsAdd = BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u32 ||
13779 BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u64;
13781 unsigned BitWidth = LHS.getBitWidth();
13782 unsigned CarryInBit = CarryIn.ugt(0) ? 1 : 0;
13785 ? (LHS.zext(BitWidth + 1) + (RHS.zext(BitWidth + 1) + CarryInBit))
13786 : (LHS.zext(BitWidth + 1) - (RHS.zext(BitWidth + 1) + CarryInBit));
13788 APInt Result = ExResult.extractBits(BitWidth, 0);
13789 uint64_t CarryOut = ExResult.extractBitsAsZExtValue(1, BitWidth);
13797 case clang::X86::BI__builtin_ia32_bextr_u32:
13798 case clang::X86::BI__builtin_ia32_bextr_u64:
13799 case clang::X86::BI__builtin_ia32_bextri_u32:
13800 case clang::X86::BI__builtin_ia32_bextri_u64: {
13806 unsigned BitWidth = Val.getBitWidth();
13808 uint64_t Length = Idx.extractBitsAsZExtValue(8, 8);
13809 Length = Length > BitWidth ? BitWidth : Length;
13812 if (Length == 0 || Shift >= BitWidth)
13816 Result &= llvm::maskTrailingOnes<uint64_t>(Length);
13820 case clang::X86::BI__builtin_ia32_bzhi_si:
13821 case clang::X86::BI__builtin_ia32_bzhi_di: {
13827 unsigned BitWidth = Val.getBitWidth();
13828 unsigned Index = Idx.extractBitsAsZExtValue(8, 0);
13829 if (Index < BitWidth)
13830 Val.clearHighBits(BitWidth - Index);
13834 case clang::X86::BI__builtin_ia32_lzcnt_u16:
13835 case clang::X86::BI__builtin_ia32_lzcnt_u32:
13836 case clang::X86::BI__builtin_ia32_lzcnt_u64: {
13840 return Success(Val.countLeadingZeros(),
E);
13843 case clang::X86::BI__builtin_ia32_tzcnt_u16:
13844 case clang::X86::BI__builtin_ia32_tzcnt_u32:
13845 case clang::X86::BI__builtin_ia32_tzcnt_u64: {
13849 return Success(Val.countTrailingZeros(),
E);
13852 case clang::X86::BI__builtin_ia32_pdep_si:
13853 case clang::X86::BI__builtin_ia32_pdep_di: {
13859 unsigned BitWidth = Val.getBitWidth();
13860 APInt Result = APInt::getZero(BitWidth);
13861 for (
unsigned I = 0,
P = 0; I != BitWidth; ++I)
13863 Result.setBitVal(I, Val[
P++]);
13867 case clang::X86::BI__builtin_ia32_pext_si:
13868 case clang::X86::BI__builtin_ia32_pext_di: {
13874 unsigned BitWidth = Val.getBitWidth();
13875 APInt Result = APInt::getZero(BitWidth);
13876 for (
unsigned I = 0,
P = 0; I != BitWidth; ++I)
13878 Result.setBitVal(
P++, Val[I]);
13887 const LValue &LV) {
13890 if (!LV.getLValueBase())
13895 if (!LV.getLValueDesignator().Invalid &&
13896 !LV.getLValueDesignator().isOnePastTheEnd())
13901 QualType Ty = getType(LV.getLValueBase());
13906 if (LV.getLValueDesignator().Invalid)
13912 return LV.getLValueOffset() == Size;
13922class DataRecursiveIntBinOpEvaluator {
13923 struct EvalResult {
13925 bool Failed =
false;
13927 EvalResult() =
default;
13929 void swap(EvalResult &RHS) {
13931 Failed = RHS.Failed;
13932 RHS.Failed =
false;
13938 EvalResult LHSResult;
13939 enum { AnyExprKind, BinOpKind, BinOpVisitedLHSKind }
Kind;
13942 Job(Job &&) =
default;
13944 void startSpeculativeEval(EvalInfo &Info) {
13945 SpecEvalRAII = SpeculativeEvaluationRAII(Info);
13949 SpeculativeEvaluationRAII SpecEvalRAII;
13954 IntExprEvaluator &IntEval;
13959 DataRecursiveIntBinOpEvaluator(IntExprEvaluator &IntEval,
APValue &Result)
13960 : IntEval(IntEval), Info(IntEval.getEvalInfo()), FinalResult(Result) { }
13967 return E->getOpcode() == BO_Comma ||
E->isLogicalOp() ||
13975 EvalResult PrevResult;
13976 while (!Queue.empty())
13977 process(PrevResult);
13979 if (PrevResult.Failed)
return false;
13981 FinalResult.
swap(PrevResult.Val);
13987 return IntEval.Success(
Value,
E, Result);
13990 return IntEval.Success(
Value,
E, Result);
13993 return IntEval.Error(
E);
13996 return IntEval.Error(
E,
D);
14000 return Info.CCEDiag(
E,
D);
14004 bool VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *
E,
14005 bool &SuppressRHSDiags);
14007 bool VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
14010 void EvaluateExpr(
const Expr *
E, EvalResult &Result) {
14011 Result.Failed = !
Evaluate(Result.Val, Info,
E);
14016 void process(EvalResult &Result);
14018 void enqueue(
const Expr *
E) {
14020 Queue.resize(Queue.size()+1);
14021 Queue.back().E =
E;
14022 Queue.back().Kind = Job::AnyExprKind;
14028bool DataRecursiveIntBinOpEvaluator::
14030 bool &SuppressRHSDiags) {
14031 if (
E->getOpcode() == BO_Comma) {
14033 if (LHSResult.Failed)
14034 return Info.noteSideEffect();
14038 if (
E->isLogicalOp()) {
14043 if (LHSAsBool == (
E->getOpcode() == BO_LOr)) {
14044 Success(LHSAsBool,
E, LHSResult.Val);
14048 LHSResult.Failed =
true;
14052 if (!Info.noteSideEffect())
14058 SuppressRHSDiags =
true;
14067 if (LHSResult.Failed && !Info.noteFailure())
14078 assert(!LVal.
hasLValuePath() &&
"have designator for integer lvalue");
14080 uint64_t Offset64 = Offset.getQuantity();
14081 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
14083 : Offset64 + Index64);
14086bool DataRecursiveIntBinOpEvaluator::
14087 VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
14089 if (
E->getOpcode() == BO_Comma) {
14090 if (RHSResult.Failed)
14092 Result = RHSResult.Val;
14096 if (
E->isLogicalOp()) {
14097 bool lhsResult, rhsResult;
14103 if (
E->getOpcode() == BO_LOr)
14104 return Success(lhsResult || rhsResult,
E, Result);
14106 return Success(lhsResult && rhsResult,
E, Result);
14112 if (rhsResult == (
E->getOpcode() == BO_LOr))
14113 return Success(rhsResult,
E, Result);
14123 if (LHSResult.Failed || RHSResult.Failed)
14126 const APValue &LHSVal = LHSResult.Val;
14127 const APValue &RHSVal = RHSResult.Val;
14137 if (
E->getOpcode() == BO_Add &&
14151 if (!LHSExpr || !RHSExpr)
14153 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
14154 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
14155 if (!LHSAddrExpr || !RHSAddrExpr)
14161 Result =
APValue(LHSAddrExpr, RHSAddrExpr);
14180void DataRecursiveIntBinOpEvaluator::process(EvalResult &Result) {
14181 Job &job = Queue.back();
14183 switch (job.Kind) {
14184 case Job::AnyExprKind: {
14185 if (
const BinaryOperator *Bop = dyn_cast<BinaryOperator>(job.E)) {
14186 if (shouldEnqueue(Bop)) {
14187 job.Kind = Job::BinOpKind;
14188 enqueue(Bop->getLHS());
14193 EvaluateExpr(job.E, Result);
14198 case Job::BinOpKind: {
14200 bool SuppressRHSDiags =
false;
14201 if (!VisitBinOpLHSOnly(Result, Bop, SuppressRHSDiags)) {
14205 if (SuppressRHSDiags)
14206 job.startSpeculativeEval(Info);
14207 job.LHSResult.swap(Result);
14208 job.Kind = Job::BinOpVisitedLHSKind;
14213 case Job::BinOpVisitedLHSKind: {
14217 Result.Failed = !VisitBinOp(job.LHSResult, RHS, Bop, Result.Val);
14223 llvm_unreachable(
"Invalid Job::Kind!");
14227enum class CmpResult {
14236template <
class SuccessCB,
class AfterCB>
14239 SuccessCB &&
Success, AfterCB &&DoAfter) {
14241 assert(
E->isComparisonOp() &&
"expected comparison operator");
14242 assert((
E->getOpcode() == BO_Cmp ||
14244 "unsupported binary expression evaluation");
14245 auto Error = [&](
const Expr *
E) {
14246 Info.FFDiag(
E, diag::note_invalid_subexpr_in_const_expr);
14250 bool IsRelational =
E->isRelationalOp() ||
E->getOpcode() == BO_Cmp;
14251 bool IsEquality =
E->isEqualityOp();
14260 if (!LHSOK && !Info.noteFailure())
14265 return Success(CmpResult::Less,
E);
14267 return Success(CmpResult::Greater,
E);
14268 return Success(CmpResult::Equal,
E);
14272 APFixedPoint LHSFX(Info.Ctx.getFixedPointSemantics(LHSTy));
14273 APFixedPoint RHSFX(Info.Ctx.getFixedPointSemantics(RHSTy));
14276 if (!LHSOK && !Info.noteFailure())
14281 return Success(CmpResult::Less,
E);
14283 return Success(CmpResult::Greater,
E);
14284 return Success(CmpResult::Equal,
E);
14288 ComplexValue LHS, RHS;
14290 if (
E->isAssignmentOp()) {
14297 LHS.makeComplexFloat();
14298 LHS.FloatImag = APFloat(LHS.FloatReal.getSemantics());
14303 if (!LHSOK && !Info.noteFailure())
14309 RHS.makeComplexFloat();
14310 RHS.FloatImag = APFloat(RHS.FloatReal.getSemantics());
14314 if (LHS.isComplexFloat()) {
14315 APFloat::cmpResult CR_r =
14316 LHS.getComplexFloatReal().compare(RHS.getComplexFloatReal());
14317 APFloat::cmpResult CR_i =
14318 LHS.getComplexFloatImag().compare(RHS.getComplexFloatImag());
14319 bool IsEqual = CR_r == APFloat::cmpEqual && CR_i == APFloat::cmpEqual;
14320 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal,
E);
14322 assert(IsEquality &&
"invalid complex comparison");
14323 bool IsEqual = LHS.getComplexIntReal() == RHS.getComplexIntReal() &&
14324 LHS.getComplexIntImag() == RHS.getComplexIntImag();
14325 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal,
E);
14331 APFloat RHS(0.0), LHS(0.0);
14334 if (!LHSOK && !Info.noteFailure())
14340 assert(
E->isComparisonOp() &&
"Invalid binary operator!");
14341 llvm::APFloatBase::cmpResult APFloatCmpResult = LHS.compare(RHS);
14342 if (!Info.InConstantContext &&
14343 APFloatCmpResult == APFloat::cmpUnordered &&
14346 Info.FFDiag(
E, diag::note_constexpr_float_arithmetic_strict);
14349 auto GetCmpRes = [&]() {
14350 switch (APFloatCmpResult) {
14351 case APFloat::cmpEqual:
14352 return CmpResult::Equal;
14353 case APFloat::cmpLessThan:
14354 return CmpResult::Less;
14355 case APFloat::cmpGreaterThan:
14356 return CmpResult::Greater;
14357 case APFloat::cmpUnordered:
14358 return CmpResult::Unordered;
14360 llvm_unreachable(
"Unrecognised APFloat::cmpResult enum");
14366 LValue LHSValue, RHSValue;
14369 if (!LHSOK && !Info.noteFailure())
14378 (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown))
14384 auto DiagComparison = [&] (
unsigned DiagID,
bool Reversed =
false) {
14385 std::string LHS = LHSValue.toString(Info.Ctx,
E->getLHS()->
getType());
14386 std::string RHS = RHSValue.toString(Info.Ctx,
E->getRHS()->
getType());
14387 Info.FFDiag(
E, DiagID)
14394 return DiagComparison(
14395 diag::note_constexpr_pointer_comparison_unspecified);
14401 if ((!LHSValue.Base && !LHSValue.Offset.isZero()) ||
14402 (!RHSValue.Base && !RHSValue.Offset.isZero()))
14403 return DiagComparison(diag::note_constexpr_pointer_constant_comparison,
14417 return DiagComparison(diag::note_constexpr_literal_comparison);
14419 return DiagComparison(diag::note_constexpr_opaque_call_comparison,
14424 return DiagComparison(diag::note_constexpr_pointer_weak_comparison,
14428 if (LHSValue.Base && LHSValue.Offset.isZero() &&
14430 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
14432 if (RHSValue.Base && RHSValue.Offset.isZero() &&
14434 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
14440 return DiagComparison(
14441 diag::note_constexpr_pointer_comparison_zero_sized);
14442 return Success(CmpResult::Unequal,
E);
14445 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
14446 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
14448 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
14449 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
14459 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid && IsRelational) {
14460 bool WasArrayIndex;
14462 getType(LHSValue.Base), LHSDesignator, RHSDesignator, WasArrayIndex);
14469 if (!WasArrayIndex && Mismatch < LHSDesignator.Entries.size() &&
14470 Mismatch < RHSDesignator.Entries.size()) {
14471 const FieldDecl *LF = getAsField(LHSDesignator.Entries[Mismatch]);
14472 const FieldDecl *RF = getAsField(RHSDesignator.Entries[Mismatch]);
14474 Info.CCEDiag(
E, diag::note_constexpr_pointer_comparison_base_classes);
14476 Info.CCEDiag(
E, diag::note_constexpr_pointer_comparison_base_field)
14477 << getAsBaseClass(LHSDesignator.Entries[Mismatch])
14480 Info.CCEDiag(
E, diag::note_constexpr_pointer_comparison_base_field)
14481 << getAsBaseClass(RHSDesignator.Entries[Mismatch])
14486 diag::note_constexpr_pointer_comparison_differing_access)
14494 unsigned PtrSize = Info.Ctx.getTypeSize(LHSTy);
14497 assert(PtrSize <= 64 &&
"Unexpected pointer width");
14498 uint64_t Mask = ~0ULL >> (64 - PtrSize);
14499 CompareLHS &= Mask;
14500 CompareRHS &= Mask;
14505 if (!LHSValue.Base.isNull() && IsRelational) {
14506 QualType BaseTy = getType(LHSValue.Base);
14509 CharUnits Size = Info.Ctx.getTypeSizeInChars(BaseTy);
14510 uint64_t OffsetLimit = Size.getQuantity();
14511 if (CompareLHS > OffsetLimit || CompareRHS > OffsetLimit)
14515 if (CompareLHS < CompareRHS)
14516 return Success(CmpResult::Less,
E);
14517 if (CompareLHS > CompareRHS)
14518 return Success(CmpResult::Greater,
E);
14519 return Success(CmpResult::Equal,
E);
14523 assert(IsEquality &&
"unexpected member pointer operation");
14526 MemberPtr LHSValue, RHSValue;
14529 if (!LHSOK && !Info.noteFailure())
14537 if (LHSValue.getDecl() && LHSValue.getDecl()->isWeak()) {
14538 Info.FFDiag(
E, diag::note_constexpr_mem_pointer_weak_comparison)
14539 << LHSValue.getDecl();
14542 if (RHSValue.getDecl() && RHSValue.getDecl()->isWeak()) {
14543 Info.FFDiag(
E, diag::note_constexpr_mem_pointer_weak_comparison)
14544 << RHSValue.getDecl();
14551 if (!LHSValue.getDecl() || !RHSValue.getDecl()) {
14552 bool Equal = !LHSValue.getDecl() && !RHSValue.getDecl();
14553 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal,
E);
14558 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(LHSValue.getDecl()))
14559 if (MD->isVirtual())
14560 Info.CCEDiag(
E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
14561 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(RHSValue.getDecl()))
14562 if (MD->isVirtual())
14563 Info.CCEDiag(
E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
14569 bool Equal = LHSValue == RHSValue;
14570 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal,
E);
14574 assert(
E->isComparisonOp() &&
"unexpected nullptr operation");
14575 assert(RHSTy->
isNullPtrType() &&
"missing pointer conversion");
14583 return Success(CmpResult::Equal,
E);
14596 case CmpResult::Unequal:
14597 llvm_unreachable(
"should never produce Unequal for three-way comparison");
14598 case CmpResult::Less:
14599 CCR = ComparisonCategoryResult::Less;
14601 case CmpResult::Equal:
14602 CCR = ComparisonCategoryResult::Equal;
14604 case CmpResult::Greater:
14605 CCR = ComparisonCategoryResult::Greater;
14607 case CmpResult::Unordered:
14608 CCR = ComparisonCategoryResult::Unordered;
14622 ConstantExprKind::Normal);
14625 return ExprEvaluatorBaseTy::VisitBinCmp(
E);
14629bool RecordExprEvaluator::VisitCXXParenListInitExpr(
14631 return VisitCXXParenListOrInitListExpr(
E,
E->getInitExprs());
14637 if (
E->isAssignmentOp()) {
14639 if (!Info.noteFailure())
14643 if (DataRecursiveIntBinOpEvaluator::shouldEnqueue(
E))
14644 return DataRecursiveIntBinOpEvaluator(*
this, Result).Traverse(
E);
14648 "DataRecursiveIntBinOpEvaluator should have handled integral types");
14650 if (
E->isComparisonOp()) {
14654 assert((CR != CmpResult::Unequal ||
E->isEqualityOp()) &&
14655 "should only produce Unequal for equality comparisons");
14656 bool IsEqual = CR == CmpResult::Equal,
14657 IsLess = CR == CmpResult::Less,
14658 IsGreater = CR == CmpResult::Greater;
14659 auto Op =
E->getOpcode();
14662 llvm_unreachable(
"unsupported binary operator");
14665 return Success(IsEqual == (Op == BO_EQ),
E);
14671 return Success(IsEqual || IsLess,
E);
14673 return Success(IsEqual || IsGreater,
E);
14677 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
14685 E->getOpcode() == BO_Sub) {
14686 LValue LHSValue, RHSValue;
14689 if (!LHSOK && !Info.noteFailure())
14699 if (!LHSValue.Offset.isZero() || !RHSValue.Offset.isZero())
14701 const Expr *LHSExpr = LHSValue.Base.dyn_cast<
const Expr *>();
14702 const Expr *RHSExpr = RHSValue.Base.dyn_cast<
const Expr *>();
14704 auto DiagArith = [&](
unsigned DiagID) {
14705 std::string LHS = LHSValue.toString(Info.Ctx,
E->getLHS()->
getType());
14706 std::string RHS = RHSValue.toString(Info.Ctx,
E->getRHS()->
getType());
14707 Info.FFDiag(
E, DiagID) << LHS << RHS;
14708 if (LHSExpr && LHSExpr == RHSExpr)
14710 diag::note_constexpr_repeated_literal_eval)
14715 if (!LHSExpr || !RHSExpr)
14716 return DiagArith(diag::note_constexpr_pointer_arith_unspecified);
14719 return DiagArith(diag::note_constexpr_literal_arith);
14721 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
14722 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
14723 if (!LHSAddrExpr || !RHSAddrExpr)
14731 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
14732 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
14734 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
14735 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
14741 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid &&
14744 Info.CCEDiag(
E, diag::note_constexpr_pointer_subtraction_not_same_array);
14756 if (ElementSize.
isZero()) {
14757 Info.FFDiag(
E, diag::note_constexpr_pointer_subtraction_zero_size)
14774 APSInt TrueResult = (LHS - RHS) / ElemSize;
14775 APSInt Result = TrueResult.trunc(Info.Ctx.getIntWidth(
E->
getType()));
14777 if (Result.extend(65) != TrueResult &&
14783 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
14788bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr(
14790 switch(
E->getKind()) {
14791 case UETT_PreferredAlignOf:
14792 case UETT_AlignOf: {
14793 if (
E->isArgumentType())
14801 case UETT_PtrAuthTypeDiscriminator: {
14802 if (
E->getArgumentType()->isDependentType())
14805 Info.Ctx.getPointerAuthTypeDiscriminator(
E->getArgumentType()),
E);
14807 case UETT_VecStep: {
14823 case UETT_DataSizeOf:
14824 case UETT_SizeOf: {
14825 QualType SrcTy =
E->getTypeOfArgument();
14833 E->getKind() == UETT_DataSizeOf ? SizeOfType::DataSizeOf
14834 : SizeOfType::SizeOf)) {
14839 case UETT_OpenMPRequiredSimdAlign:
14840 assert(
E->isArgumentType());
14842 Info.Ctx.toCharUnitsFromBits(
14843 Info.Ctx.getOpenMPDefaultSimdAlign(
E->getArgumentType()))
14846 case UETT_VectorElements: {
14854 if (Info.InConstantContext)
14855 Info.CCEDiag(
E, diag::note_constexpr_non_const_vectorelements)
14862 llvm_unreachable(
"unknown expr/type trait");
14865bool IntExprEvaluator::VisitOffsetOfExpr(
const OffsetOfExpr *OOE) {
14871 for (
unsigned i = 0; i != n; ++i) {
14879 const ArrayType *AT = Info.Ctx.getAsArrayType(CurrentType);
14883 CharUnits ElementSize = Info.Ctx.getTypeSizeInChars(CurrentType);
14884 Result += IdxResult.getSExtValue() * ElementSize;
14897 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
14904 llvm_unreachable(
"dependent __builtin_offsetof");
14920 CurrentType = BaseSpec->
getType();
14934bool IntExprEvaluator::VisitUnaryOperator(
const UnaryOperator *
E) {
14935 switch (
E->getOpcode()) {
14943 return Visit(
E->getSubExpr());
14946 return Visit(
E->getSubExpr());
14948 if (!Visit(
E->getSubExpr()))
14950 if (!Result.isInt())
return Error(
E);
14952 if (
Value.isSigned() &&
Value.isMinSignedValue() &&
E->canOverflow()) {
14953 if (Info.checkingForUndefinedBehavior())
14954 Info.Ctx.getDiagnostics().Report(
E->
getExprLoc(),
14955 diag::warn_integer_constant_overflow)
14967 if (!Visit(
E->getSubExpr()))
14969 if (!Result.isInt())
return Error(
E);
14970 return Success(~Result.getInt(),
E);
14983bool IntExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
14984 const Expr *SubExpr =
E->getSubExpr();
14988 switch (
E->getCastKind()) {
14989 case CK_BaseToDerived:
14990 case CK_DerivedToBase:
14991 case CK_UncheckedDerivedToBase:
14994 case CK_ArrayToPointerDecay:
14995 case CK_FunctionToPointerDecay:
14996 case CK_NullToPointer:
14997 case CK_NullToMemberPointer:
14998 case CK_BaseToDerivedMemberPointer:
14999 case CK_DerivedToBaseMemberPointer:
15000 case CK_ReinterpretMemberPointer:
15001 case CK_ConstructorConversion:
15002 case CK_IntegralToPointer:
15004 case CK_VectorSplat:
15005 case CK_IntegralToFloating:
15006 case CK_FloatingCast:
15007 case CK_CPointerToObjCPointerCast:
15008 case CK_BlockPointerToObjCPointerCast:
15009 case CK_AnyPointerToBlockPointerCast:
15010 case CK_ObjCObjectLValueCast:
15011 case CK_FloatingRealToComplex:
15012 case CK_FloatingComplexToReal:
15013 case CK_FloatingComplexCast:
15014 case CK_FloatingComplexToIntegralComplex:
15015 case CK_IntegralRealToComplex:
15016 case CK_IntegralComplexCast:
15017 case CK_IntegralComplexToFloatingComplex:
15018 case CK_BuiltinFnToFnPtr:
15019 case CK_ZeroToOCLOpaqueType:
15020 case CK_NonAtomicToAtomic:
15021 case CK_AddressSpaceConversion:
15022 case CK_IntToOCLSampler:
15023 case CK_FloatingToFixedPoint:
15024 case CK_FixedPointToFloating:
15025 case CK_FixedPointCast:
15026 case CK_IntegralToFixedPoint:
15027 case CK_MatrixCast:
15028 llvm_unreachable(
"invalid cast kind for integral value");
15032 case CK_LValueBitCast:
15033 case CK_ARCProduceObject:
15034 case CK_ARCConsumeObject:
15035 case CK_ARCReclaimReturnedObject:
15036 case CK_ARCExtendBlockObject:
15037 case CK_CopyAndAutoreleaseBlockObject:
15040 case CK_UserDefinedConversion:
15041 case CK_LValueToRValue:
15042 case CK_AtomicToNonAtomic:
15044 case CK_LValueToRValueBitCast:
15045 case CK_HLSLArrayRValue:
15046 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
15048 case CK_MemberPointerToBoolean:
15049 case CK_PointerToBoolean:
15050 case CK_IntegralToBoolean:
15051 case CK_FloatingToBoolean:
15052 case CK_BooleanToSignedIntegral:
15053 case CK_FloatingComplexToBoolean:
15054 case CK_IntegralComplexToBoolean: {
15059 if (BoolResult &&
E->getCastKind() == CK_BooleanToSignedIntegral)
15064 case CK_FixedPointToIntegral: {
15065 APFixedPoint Src(Info.Ctx.getFixedPointSemantics(SrcType));
15069 llvm::APSInt Result = Src.convertToInt(
15070 Info.Ctx.getIntWidth(DestType),
15077 case CK_FixedPointToBoolean: {
15080 if (!
Evaluate(Val, Info, SubExpr))
15085 case CK_IntegralCast: {
15086 if (!Visit(SubExpr))
15089 if (!Result.isInt()) {
15095 if (Result.isAddrLabelDiff())
15096 return Info.Ctx.getTypeSize(DestType) <= Info.Ctx.getTypeSize(SrcType);
15098 return Info.Ctx.getTypeSize(DestType) == Info.Ctx.getTypeSize(SrcType);
15101 if (Info.Ctx.getLangOpts().CPlusPlus && Info.InConstantContext &&
15102 Info.EvalMode == EvalInfo::EM_ConstantExpression &&
15105 bool ConstexprVar =
true;
15112 if (
const auto *VD = dyn_cast_or_null<VarDecl>(
15113 Info.EvaluatingDecl.dyn_cast<
const ValueDecl *>()))
15136 (
Max.slt(Result.getInt().getSExtValue()) ||
15137 Min.sgt(Result.getInt().getSExtValue())))
15138 Info.CCEDiag(
E, diag::note_constexpr_unscoped_enum_out_of_range)
15139 << llvm::toString(Result.getInt(), 10) <<
Min.getSExtValue()
15140 <<
Max.getSExtValue() << ED;
15142 Max.ult(Result.getInt().getZExtValue()))
15143 Info.CCEDiag(
E, diag::note_constexpr_unscoped_enum_out_of_range)
15144 << llvm::toString(Result.getInt(), 10) <<
Min.getZExtValue()
15145 <<
Max.getZExtValue() << ED;
15150 Result.getInt()),
E);
15153 case CK_PointerToIntegral: {
15154 CCEDiag(
E, diag::note_constexpr_invalid_cast)
15161 if (LV.getLValueBase()) {
15166 if (Info.Ctx.getTypeSize(DestType) != Info.Ctx.getTypeSize(SrcType))
15169 LV.Designator.setInvalid();
15170 LV.moveInto(Result);
15177 if (!
V.toIntegralConstant(AsInt, SrcType, Info.Ctx))
15178 llvm_unreachable(
"Can't cast this!");
15183 case CK_IntegralComplexToReal: {
15187 return Success(
C.getComplexIntReal(),
E);
15190 case CK_FloatingToIntegral: {
15200 case CK_HLSLVectorTruncation: {
15208 llvm_unreachable(
"unknown cast resulting in integral value");
15216 if (!LV.isComplexInt())
15218 return Success(LV.getComplexIntReal(),
E);
15221 return Visit(
E->getSubExpr());
15229 if (!LV.isComplexInt())
15231 return Success(LV.getComplexIntImag(),
E);
15234 VisitIgnoredValue(
E->getSubExpr());
15246bool IntExprEvaluator::VisitConceptSpecializationExpr(
15251bool IntExprEvaluator::VisitRequiresExpr(
const RequiresExpr *
E) {
15255bool FixedPointExprEvaluator::VisitUnaryOperator(
const UnaryOperator *
E) {
15256 switch (
E->getOpcode()) {
15262 return Visit(
E->getSubExpr());
15264 if (!Visit(
E->getSubExpr()))
return false;
15265 if (!Result.isFixedPoint())
15268 APFixedPoint Negated = Result.getFixedPoint().negate(&Overflowed);
15282bool FixedPointExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
15283 const Expr *SubExpr =
E->getSubExpr();
15286 "Expected destination type to be a fixed point type");
15287 auto DestFXSema = Info.Ctx.getFixedPointSemantics(DestType);
15289 switch (
E->getCastKind()) {
15290 case CK_FixedPointCast: {
15291 APFixedPoint Src(Info.Ctx.getFixedPointSemantics(SubExpr->
getType()));
15295 APFixedPoint Result = Src.convert(DestFXSema, &Overflowed);
15297 if (Info.checkingForUndefinedBehavior())
15298 Info.Ctx.getDiagnostics().Report(
E->
getExprLoc(),
15299 diag::warn_fixedpoint_constant_overflow)
15300 << Result.toString() <<
E->
getType();
15306 case CK_IntegralToFixedPoint: {
15312 APFixedPoint IntResult = APFixedPoint::getFromIntValue(
15313 Src, Info.Ctx.getFixedPointSemantics(DestType), &Overflowed);
15316 if (Info.checkingForUndefinedBehavior())
15317 Info.Ctx.getDiagnostics().Report(
E->
getExprLoc(),
15318 diag::warn_fixedpoint_constant_overflow)
15319 << IntResult.toString() <<
E->
getType();
15326 case CK_FloatingToFixedPoint: {
15332 APFixedPoint Result = APFixedPoint::getFromFloatValue(
15333 Src, Info.Ctx.getFixedPointSemantics(DestType), &Overflowed);
15336 if (Info.checkingForUndefinedBehavior())
15337 Info.Ctx.getDiagnostics().Report(
E->
getExprLoc(),
15338 diag::warn_fixedpoint_constant_overflow)
15339 << Result.toString() <<
E->
getType();
15347 case CK_LValueToRValue:
15348 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
15354bool FixedPointExprEvaluator::VisitBinaryOperator(
const BinaryOperator *
E) {
15355 if (
E->isPtrMemOp() ||
E->isAssignmentOp() ||
E->getOpcode() == BO_Comma)
15356 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
15358 const Expr *LHS =
E->getLHS();
15359 const Expr *RHS =
E->getRHS();
15361 Info.Ctx.getFixedPointSemantics(
E->
getType());
15363 APFixedPoint LHSFX(Info.Ctx.getFixedPointSemantics(LHS->
getType()));
15366 APFixedPoint RHSFX(Info.Ctx.getFixedPointSemantics(RHS->
getType()));
15370 bool OpOverflow =
false, ConversionOverflow =
false;
15371 APFixedPoint Result(LHSFX.getSemantics());
15372 switch (
E->getOpcode()) {
15374 Result = LHSFX.
add(RHSFX, &OpOverflow)
15375 .convert(ResultFXSema, &ConversionOverflow);
15379 Result = LHSFX.sub(RHSFX, &OpOverflow)
15380 .convert(ResultFXSema, &ConversionOverflow);
15384 Result = LHSFX.mul(RHSFX, &OpOverflow)
15385 .convert(ResultFXSema, &ConversionOverflow);
15389 if (RHSFX.getValue() == 0) {
15390 Info.FFDiag(
E, diag::note_expr_divide_by_zero);
15393 Result = LHSFX.div(RHSFX, &OpOverflow)
15394 .convert(ResultFXSema, &ConversionOverflow);
15400 llvm::APSInt RHSVal = RHSFX.getValue();
15403 LHSSema.getWidth() - (
unsigned)LHSSema.hasUnsignedPadding();
15404 unsigned Amt = RHSVal.getLimitedValue(ShiftBW - 1);
15408 if (RHSVal.isNegative())
15409 Info.CCEDiag(
E, diag::note_constexpr_negative_shift) << RHSVal;
15410 else if (Amt != RHSVal)
15411 Info.CCEDiag(
E, diag::note_constexpr_large_shift)
15412 << RHSVal <<
E->
getType() << ShiftBW;
15414 if (
E->getOpcode() == BO_Shl)
15415 Result = LHSFX.shl(Amt, &OpOverflow);
15417 Result = LHSFX.shr(Amt, &OpOverflow);
15423 if (OpOverflow || ConversionOverflow) {
15424 if (Info.checkingForUndefinedBehavior())
15425 Info.Ctx.getDiagnostics().Report(
E->
getExprLoc(),
15426 diag::warn_fixedpoint_constant_overflow)
15427 << Result.toString() <<
E->
getType();
15439class FloatExprEvaluator
15440 :
public ExprEvaluatorBase<FloatExprEvaluator> {
15443 FloatExprEvaluator(EvalInfo &info, APFloat &result)
15444 : ExprEvaluatorBaseTy(info), Result(result) {}
15447 Result =
V.getFloat();
15451 bool ZeroInitialization(
const Expr *
E) {
15452 Result = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(
E->
getType()));
15473 return FloatExprEvaluator(Info, Result).Visit(
E);
15480 llvm::APFloat &Result) {
15482 if (!S)
return false;
15489 if (S->getString().empty())
15490 fill = llvm::APInt(32, 0);
15491 else if (S->getString().getAsInteger(0, fill))
15496 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
15498 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
15506 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
15508 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
15514bool FloatExprEvaluator::VisitCallExpr(
const CallExpr *
E) {
15515 if (!IsConstantEvaluatedBuiltinCall(
E))
15516 return ExprEvaluatorBaseTy::VisitCallExpr(
E);
15518 switch (
E->getBuiltinCallee()) {
15522 case Builtin::BI__builtin_huge_val:
15523 case Builtin::BI__builtin_huge_valf:
15524 case Builtin::BI__builtin_huge_vall:
15525 case Builtin::BI__builtin_huge_valf16:
15526 case Builtin::BI__builtin_huge_valf128:
15527 case Builtin::BI__builtin_inf:
15528 case Builtin::BI__builtin_inff:
15529 case Builtin::BI__builtin_infl:
15530 case Builtin::BI__builtin_inff16:
15531 case Builtin::BI__builtin_inff128: {
15532 const llvm::fltSemantics &Sem =
15533 Info.Ctx.getFloatTypeSemantics(
E->
getType());
15534 Result = llvm::APFloat::getInf(Sem);
15538 case Builtin::BI__builtin_nans:
15539 case Builtin::BI__builtin_nansf:
15540 case Builtin::BI__builtin_nansl:
15541 case Builtin::BI__builtin_nansf16:
15542 case Builtin::BI__builtin_nansf128:
15548 case Builtin::BI__builtin_nan:
15549 case Builtin::BI__builtin_nanf:
15550 case Builtin::BI__builtin_nanl:
15551 case Builtin::BI__builtin_nanf16:
15552 case Builtin::BI__builtin_nanf128:
15560 case Builtin::BI__builtin_fabs:
15561 case Builtin::BI__builtin_fabsf:
15562 case Builtin::BI__builtin_fabsl:
15563 case Builtin::BI__builtin_fabsf128:
15572 if (Result.isNegative())
15573 Result.changeSign();
15576 case Builtin::BI__arithmetic_fence:
15583 case Builtin::BI__builtin_copysign:
15584 case Builtin::BI__builtin_copysignf:
15585 case Builtin::BI__builtin_copysignl:
15586 case Builtin::BI__builtin_copysignf128: {
15591 Result.copySign(RHS);
15595 case Builtin::BI__builtin_fmax:
15596 case Builtin::BI__builtin_fmaxf:
15597 case Builtin::BI__builtin_fmaxl:
15598 case Builtin::BI__builtin_fmaxf16:
15599 case Builtin::BI__builtin_fmaxf128: {
15606 if (Result.isZero() && RHS.isZero() && Result.isNegative())
15608 else if (Result.isNaN() || RHS > Result)
15613 case Builtin::BI__builtin_fmin:
15614 case Builtin::BI__builtin_fminf:
15615 case Builtin::BI__builtin_fminl:
15616 case Builtin::BI__builtin_fminf16:
15617 case Builtin::BI__builtin_fminf128: {
15624 if (Result.isZero() && RHS.isZero() && RHS.isNegative())
15626 else if (Result.isNaN() || RHS < Result)
15631 case Builtin::BI__builtin_fmaximum_num:
15632 case Builtin::BI__builtin_fmaximum_numf:
15633 case Builtin::BI__builtin_fmaximum_numl:
15634 case Builtin::BI__builtin_fmaximum_numf16:
15635 case Builtin::BI__builtin_fmaximum_numf128: {
15640 Result = maximumnum(Result, RHS);
15644 case Builtin::BI__builtin_fminimum_num:
15645 case Builtin::BI__builtin_fminimum_numf:
15646 case Builtin::BI__builtin_fminimum_numl:
15647 case Builtin::BI__builtin_fminimum_numf16:
15648 case Builtin::BI__builtin_fminimum_numf128: {
15653 Result = minimumnum(Result, RHS);
15659bool FloatExprEvaluator::VisitUnaryReal(
const UnaryOperator *
E) {
15664 Result = CV.FloatReal;
15668 return Visit(
E->getSubExpr());
15671bool FloatExprEvaluator::VisitUnaryImag(
const UnaryOperator *
E) {
15676 Result = CV.FloatImag;
15680 VisitIgnoredValue(
E->getSubExpr());
15681 const llvm::fltSemantics &Sem = Info.Ctx.getFloatTypeSemantics(
E->
getType());
15682 Result = llvm::APFloat::getZero(Sem);
15686bool FloatExprEvaluator::VisitUnaryOperator(
const UnaryOperator *
E) {
15687 switch (
E->getOpcode()) {
15688 default:
return Error(
E);
15697 Result.changeSign();
15702bool FloatExprEvaluator::VisitBinaryOperator(
const BinaryOperator *
E) {
15703 if (
E->isPtrMemOp() ||
E->isAssignmentOp() ||
E->getOpcode() == BO_Comma)
15704 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
15708 if (!LHSOK && !Info.noteFailure())
15715 Result =
E->getValue();
15719bool FloatExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
15720 const Expr* SubExpr =
E->getSubExpr();
15722 switch (
E->getCastKind()) {
15724 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
15726 case CK_IntegralToFloating: {
15729 Info.Ctx.getLangOpts());
15735 case CK_FixedPointToFloating: {
15736 APFixedPoint FixResult(Info.Ctx.getFixedPointSemantics(SubExpr->
getType()));
15740 FixResult.convertToFloat(Info.Ctx.getFloatTypeSemantics(
E->
getType()));
15744 case CK_FloatingCast: {
15745 if (!Visit(SubExpr))
15751 case CK_FloatingComplexToReal: {
15755 Result =
V.getComplexFloatReal();
15758 case CK_HLSLVectorTruncation: {
15772class ComplexExprEvaluator
15773 :
public ExprEvaluatorBase<ComplexExprEvaluator> {
15774 ComplexValue &Result;
15777 ComplexExprEvaluator(EvalInfo &info, ComplexValue &Result)
15778 : ExprEvaluatorBaseTy(info), Result(Result) {}
15785 bool ZeroInitialization(
const Expr *
E);
15804 return ComplexExprEvaluator(Info, Result).Visit(
E);
15807bool ComplexExprEvaluator::ZeroInitialization(
const Expr *
E) {
15810 Result.makeComplexFloat();
15811 APFloat Zero = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(ElemTy));
15812 Result.FloatReal =
Zero;
15813 Result.FloatImag =
Zero;
15815 Result.makeComplexInt();
15816 APSInt Zero = Info.Ctx.MakeIntValue(0, ElemTy);
15817 Result.IntReal =
Zero;
15818 Result.IntImag =
Zero;
15824 const Expr* SubExpr =
E->getSubExpr();
15827 Result.makeComplexFloat();
15828 APFloat &Imag = Result.FloatImag;
15832 Result.FloatReal =
APFloat(Imag.getSemantics());
15836 "Unexpected imaginary literal.");
15838 Result.makeComplexInt();
15839 APSInt &Imag = Result.IntImag;
15843 Result.IntReal =
APSInt(Imag.getBitWidth(), !Imag.isSigned());
15848bool ComplexExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
15850 switch (
E->getCastKind()) {
15852 case CK_BaseToDerived:
15853 case CK_DerivedToBase:
15854 case CK_UncheckedDerivedToBase:
15857 case CK_ArrayToPointerDecay:
15858 case CK_FunctionToPointerDecay:
15859 case CK_NullToPointer:
15860 case CK_NullToMemberPointer:
15861 case CK_BaseToDerivedMemberPointer:
15862 case CK_DerivedToBaseMemberPointer:
15863 case CK_MemberPointerToBoolean:
15864 case CK_ReinterpretMemberPointer:
15865 case CK_ConstructorConversion:
15866 case CK_IntegralToPointer:
15867 case CK_PointerToIntegral:
15868 case CK_PointerToBoolean:
15870 case CK_VectorSplat:
15871 case CK_IntegralCast:
15872 case CK_BooleanToSignedIntegral:
15873 case CK_IntegralToBoolean:
15874 case CK_IntegralToFloating:
15875 case CK_FloatingToIntegral:
15876 case CK_FloatingToBoolean:
15877 case CK_FloatingCast:
15878 case CK_CPointerToObjCPointerCast:
15879 case CK_BlockPointerToObjCPointerCast:
15880 case CK_AnyPointerToBlockPointerCast:
15881 case CK_ObjCObjectLValueCast:
15882 case CK_FloatingComplexToReal:
15883 case CK_FloatingComplexToBoolean:
15884 case CK_IntegralComplexToReal:
15885 case CK_IntegralComplexToBoolean:
15886 case CK_ARCProduceObject:
15887 case CK_ARCConsumeObject:
15888 case CK_ARCReclaimReturnedObject:
15889 case CK_ARCExtendBlockObject:
15890 case CK_CopyAndAutoreleaseBlockObject:
15891 case CK_BuiltinFnToFnPtr:
15892 case CK_ZeroToOCLOpaqueType:
15893 case CK_NonAtomicToAtomic:
15894 case CK_AddressSpaceConversion:
15895 case CK_IntToOCLSampler:
15896 case CK_FloatingToFixedPoint:
15897 case CK_FixedPointToFloating:
15898 case CK_FixedPointCast:
15899 case CK_FixedPointToBoolean:
15900 case CK_FixedPointToIntegral:
15901 case CK_IntegralToFixedPoint:
15902 case CK_MatrixCast:
15903 case CK_HLSLVectorTruncation:
15904 llvm_unreachable(
"invalid cast kind for complex value");
15906 case CK_LValueToRValue:
15907 case CK_AtomicToNonAtomic:
15909 case CK_LValueToRValueBitCast:
15910 case CK_HLSLArrayRValue:
15911 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
15914 case CK_LValueBitCast:
15915 case CK_UserDefinedConversion:
15918 case CK_FloatingRealToComplex: {
15919 APFloat &Real = Result.FloatReal;
15923 Result.makeComplexFloat();
15924 Result.FloatImag =
APFloat(Real.getSemantics());
15928 case CK_FloatingComplexCast: {
15929 if (!Visit(
E->getSubExpr()))
15940 case CK_FloatingComplexToIntegralComplex: {
15941 if (!Visit(
E->getSubExpr()))
15947 Result.makeComplexInt();
15949 To, Result.IntReal) &&
15951 To, Result.IntImag);
15954 case CK_IntegralRealToComplex: {
15955 APSInt &Real = Result.IntReal;
15959 Result.makeComplexInt();
15960 Result.IntImag =
APSInt(Real.getBitWidth(), !Real.isSigned());
15964 case CK_IntegralComplexCast: {
15965 if (!Visit(
E->getSubExpr()))
15977 case CK_IntegralComplexToFloatingComplex: {
15978 if (!Visit(
E->getSubExpr()))
15982 Info.Ctx.getLangOpts());
15986 Result.makeComplexFloat();
15988 To, Result.FloatReal) &&
15990 To, Result.FloatImag);
15994 llvm_unreachable(
"unknown cast resulting in complex value");
15998 APFloat &ResR, APFloat &ResI) {
16004 APFloat AC = A *
C;
16005 APFloat BD = B *
D;
16006 APFloat AD = A *
D;
16007 APFloat BC = B *
C;
16010 if (ResR.isNaN() && ResI.isNaN()) {
16011 bool Recalc =
false;
16012 if (A.isInfinity() || B.isInfinity()) {
16013 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
16015 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
16018 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
16020 D = APFloat::copySign(APFloat(
D.getSemantics()),
D);
16023 if (
C.isInfinity() ||
D.isInfinity()) {
16024 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
16026 D = APFloat::copySign(APFloat(
D.getSemantics(),
D.isInfinity() ? 1 : 0),
16029 A = APFloat::copySign(APFloat(A.getSemantics()), A);
16031 B = APFloat::copySign(APFloat(B.getSemantics()), B);
16034 if (!Recalc && (AC.isInfinity() || BD.isInfinity() || AD.isInfinity() ||
16035 BC.isInfinity())) {
16037 A = APFloat::copySign(APFloat(A.getSemantics()), A);
16039 B = APFloat::copySign(APFloat(B.getSemantics()), B);
16041 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
16043 D = APFloat::copySign(APFloat(
D.getSemantics()),
D);
16047 ResR = APFloat::getInf(A.getSemantics()) * (A *
C - B *
D);
16048 ResI = APFloat::getInf(A.getSemantics()) * (A *
D + B *
C);
16054 APFloat &ResR, APFloat &ResI) {
16061 APFloat MaxCD = maxnum(
abs(
C),
abs(
D));
16062 if (MaxCD.isFinite()) {
16063 DenomLogB =
ilogb(MaxCD);
16064 C =
scalbn(
C, -DenomLogB, APFloat::rmNearestTiesToEven);
16065 D =
scalbn(
D, -DenomLogB, APFloat::rmNearestTiesToEven);
16067 APFloat Denom =
C *
C +
D *
D;
16069 scalbn((A *
C + B *
D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
16071 scalbn((B *
C - A *
D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
16072 if (ResR.isNaN() && ResI.isNaN()) {
16073 if (Denom.isPosZero() && (!A.isNaN() || !B.isNaN())) {
16074 ResR = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * A;
16075 ResI = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * B;
16076 }
else if ((A.isInfinity() || B.isInfinity()) &&
C.isFinite() &&
16078 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
16080 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
16082 ResR = APFloat::getInf(ResR.getSemantics()) * (A *
C + B *
D);
16083 ResI = APFloat::getInf(ResI.getSemantics()) * (B *
C - A *
D);
16084 }
else if (MaxCD.isInfinity() && A.isFinite() && B.isFinite()) {
16085 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
16087 D = APFloat::copySign(APFloat(
D.getSemantics(),
D.isInfinity() ? 1 : 0),
16089 ResR = APFloat::getZero(ResR.getSemantics()) * (A *
C + B *
D);
16090 ResI = APFloat::getZero(ResI.getSemantics()) * (B *
C - A *
D);
16095bool ComplexExprEvaluator::VisitBinaryOperator(
const BinaryOperator *
E) {
16096 if (
E->isPtrMemOp() ||
E->isAssignmentOp() ||
E->getOpcode() == BO_Comma)
16097 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
16101 bool LHSReal =
false, RHSReal =
false;
16106 APFloat &Real = Result.FloatReal;
16109 Result.makeComplexFloat();
16110 Result.FloatImag =
APFloat(Real.getSemantics());
16113 LHSOK = Visit(
E->getLHS());
16115 if (!LHSOK && !Info.noteFailure())
16121 APFloat &Real = RHS.FloatReal;
16124 RHS.makeComplexFloat();
16125 RHS.FloatImag =
APFloat(Real.getSemantics());
16129 assert(!(LHSReal && RHSReal) &&
16130 "Cannot have both operands of a complex operation be real.");
16131 switch (
E->getOpcode()) {
16132 default:
return Error(
E);
16134 if (Result.isComplexFloat()) {
16135 Result.getComplexFloatReal().
add(RHS.getComplexFloatReal(),
16136 APFloat::rmNearestTiesToEven);
16138 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
16140 Result.getComplexFloatImag().
add(RHS.getComplexFloatImag(),
16141 APFloat::rmNearestTiesToEven);
16143 Result.getComplexIntReal() += RHS.getComplexIntReal();
16144 Result.getComplexIntImag() += RHS.getComplexIntImag();
16148 if (Result.isComplexFloat()) {
16149 Result.getComplexFloatReal().subtract(RHS.getComplexFloatReal(),
16150 APFloat::rmNearestTiesToEven);
16152 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
16153 Result.getComplexFloatImag().changeSign();
16154 }
else if (!RHSReal) {
16155 Result.getComplexFloatImag().subtract(RHS.getComplexFloatImag(),
16156 APFloat::rmNearestTiesToEven);
16159 Result.getComplexIntReal() -= RHS.getComplexIntReal();
16160 Result.getComplexIntImag() -= RHS.getComplexIntImag();
16164 if (Result.isComplexFloat()) {
16169 ComplexValue LHS = Result;
16170 APFloat &A = LHS.getComplexFloatReal();
16171 APFloat &B = LHS.getComplexFloatImag();
16172 APFloat &
C = RHS.getComplexFloatReal();
16173 APFloat &
D = RHS.getComplexFloatImag();
16174 APFloat &ResR = Result.getComplexFloatReal();
16175 APFloat &ResI = Result.getComplexFloatImag();
16177 assert(!RHSReal &&
"Cannot have two real operands for a complex op!");
16185 }
else if (RHSReal) {
16197 ComplexValue LHS = Result;
16198 Result.getComplexIntReal() =
16199 (LHS.getComplexIntReal() * RHS.getComplexIntReal() -
16200 LHS.getComplexIntImag() * RHS.getComplexIntImag());
16201 Result.getComplexIntImag() =
16202 (LHS.getComplexIntReal() * RHS.getComplexIntImag() +
16203 LHS.getComplexIntImag() * RHS.getComplexIntReal());
16207 if (Result.isComplexFloat()) {
16212 ComplexValue LHS = Result;
16213 APFloat &A = LHS.getComplexFloatReal();
16214 APFloat &B = LHS.getComplexFloatImag();
16215 APFloat &
C = RHS.getComplexFloatReal();
16216 APFloat &
D = RHS.getComplexFloatImag();
16217 APFloat &ResR = Result.getComplexFloatReal();
16218 APFloat &ResI = Result.getComplexFloatImag();
16230 B = APFloat::getZero(A.getSemantics());
16235 ComplexValue LHS = Result;
16236 APSInt Den = RHS.getComplexIntReal() * RHS.getComplexIntReal() +
16237 RHS.getComplexIntImag() * RHS.getComplexIntImag();
16239 return Error(
E, diag::note_expr_divide_by_zero);
16241 Result.getComplexIntReal() =
16242 (LHS.getComplexIntReal() * RHS.getComplexIntReal() +
16243 LHS.getComplexIntImag() * RHS.getComplexIntImag()) / Den;
16244 Result.getComplexIntImag() =
16245 (LHS.getComplexIntImag() * RHS.getComplexIntReal() -
16246 LHS.getComplexIntReal() * RHS.getComplexIntImag()) / Den;
16254bool ComplexExprEvaluator::VisitUnaryOperator(
const UnaryOperator *
E) {
16256 if (!Visit(
E->getSubExpr()))
16259 switch (
E->getOpcode()) {
16268 if (Result.isComplexFloat()) {
16269 Result.getComplexFloatReal().changeSign();
16270 Result.getComplexFloatImag().changeSign();
16273 Result.getComplexIntReal() = -Result.getComplexIntReal();
16274 Result.getComplexIntImag() = -Result.getComplexIntImag();
16278 if (Result.isComplexFloat())
16279 Result.getComplexFloatImag().changeSign();
16281 Result.getComplexIntImag() = -Result.getComplexIntImag();
16286bool ComplexExprEvaluator::VisitInitListExpr(
const InitListExpr *
E) {
16287 if (
E->getNumInits() == 2) {
16289 Result.makeComplexFloat();
16295 Result.makeComplexInt();
16303 return ExprEvaluatorBaseTy::VisitInitListExpr(
E);
16306bool ComplexExprEvaluator::VisitCallExpr(
const CallExpr *
E) {
16307 if (!IsConstantEvaluatedBuiltinCall(
E))
16308 return ExprEvaluatorBaseTy::VisitCallExpr(
E);
16310 switch (
E->getBuiltinCallee()) {
16311 case Builtin::BI__builtin_complex:
16312 Result.makeComplexFloat();
16330class AtomicExprEvaluator :
16331 public ExprEvaluatorBase<AtomicExprEvaluator> {
16332 const LValue *
This;
16335 AtomicExprEvaluator(EvalInfo &Info,
const LValue *This,
APValue &Result)
16336 : ExprEvaluatorBaseTy(Info),
This(
This), Result(Result) {}
16343 bool ZeroInitialization(
const Expr *
E) {
16352 bool VisitCastExpr(
const CastExpr *
E) {
16353 switch (
E->getCastKind()) {
16355 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
16356 case CK_NullToPointer:
16357 VisitIgnoredValue(
E->getSubExpr());
16358 return ZeroInitialization(
E);
16359 case CK_NonAtomicToAtomic:
16361 :
Evaluate(Result, Info,
E->getSubExpr());
16371 return AtomicExprEvaluator(Info, This, Result).Visit(
E);
16380class VoidExprEvaluator
16381 :
public ExprEvaluatorBase<VoidExprEvaluator> {
16383 VoidExprEvaluator(EvalInfo &Info) : ExprEvaluatorBaseTy(Info) {}
16387 bool ZeroInitialization(
const Expr *
E) {
return true; }
16389 bool VisitCastExpr(
const CastExpr *
E) {
16390 switch (
E->getCastKind()) {
16392 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
16394 VisitIgnoredValue(
E->getSubExpr());
16399 bool VisitCallExpr(
const CallExpr *
E) {
16400 if (!IsConstantEvaluatedBuiltinCall(
E))
16401 return ExprEvaluatorBaseTy::VisitCallExpr(
E);
16403 switch (
E->getBuiltinCallee()) {
16404 case Builtin::BI__assume:
16405 case Builtin::BI__builtin_assume:
16409 case Builtin::BI__builtin_operator_delete:
16421bool VoidExprEvaluator::VisitCXXDeleteExpr(
const CXXDeleteExpr *
E) {
16423 if (Info.SpeculativeEvaluationDepth)
16427 if (!OperatorDelete->isReplaceableGlobalAllocationFunction()) {
16428 Info.FFDiag(
E, diag::note_constexpr_new_non_replaceable)
16429 << isa<CXXMethodDecl>(OperatorDelete) << OperatorDelete;
16433 const Expr *Arg =
E->getArgument();
16438 if (
Pointer.Designator.Invalid)
16442 if (
Pointer.isNullPointer()) {
16446 if (!Info.getLangOpts().CPlusPlus20)
16447 Info.CCEDiag(
E, diag::note_constexpr_new);
16452 Info,
E,
Pointer,
E->isArrayForm() ? DynAlloc::ArrayNew : DynAlloc::New);
16459 if (!
E->isArrayForm() &&
Pointer.Designator.Entries.size() != 0 &&
16461 Info.FFDiag(
E, diag::note_constexpr_delete_base_nonvirt_dtor)
16468 if (!
E->isArrayForm() && !
E->isGlobalDelete()) {
16470 if (VirtualDelete &&
16472 Info.FFDiag(
E, diag::note_constexpr_new_non_replaceable)
16473 << isa<CXXMethodDecl>(VirtualDelete) << VirtualDelete;
16479 (*Alloc)->Value, AllocType))
16487 Info.FFDiag(
E, diag::note_constexpr_double_delete);
16497 return VoidExprEvaluator(Info).Visit(
E);
16513 LV.moveInto(Result);
16518 if (!IntExprEvaluator(Info, Result).Visit(
E))
16524 LV.moveInto(Result);
16526 llvm::APFloat F(0.0);
16534 C.moveInto(Result);
16536 if (!FixedPointExprEvaluator(Info, Result).Visit(
E))
return false;
16541 P.moveInto(Result);
16546 Info.CurrentCall->createTemporary(
E,
T, ScopeKind::FullExpression, LV);
16553 Info.CurrentCall->createTemporary(
E,
T, ScopeKind::FullExpression, LV);
16558 if (!Info.getLangOpts().CPlusPlus11)
16559 Info.CCEDiag(
E, diag::note_constexpr_nonliteral)
16564 QualType Unqual =
T.getAtomicUnqualifiedType();
16568 E, Unqual, ScopeKind::FullExpression, LV);
16576 }
else if (Info.getLangOpts().CPlusPlus11) {
16577 Info.FFDiag(
E, diag::note_constexpr_nonliteral) <<
E->
getType();
16580 Info.FFDiag(
E, diag::note_invalid_subexpr_in_const_expr);
16591 const Expr *
E,
bool AllowNonLiteralTypes) {
16606 QualType Unqual =
T.getAtomicUnqualifiedType();
16627 if (Info.EnableNewConstInterp) {
16628 if (!Info.Ctx.getInterpContext().evaluateAsRValue(Info,
E, Result))
16631 ConstantExprKind::Normal);
16640 LV.setFrom(Info.Ctx, Result);
16647 ConstantExprKind::Normal) &&
16655 if (
const auto *L = dyn_cast<IntegerLiteral>(Exp)) {
16657 L->getType()->isUnsignedIntegerType()));
16662 if (
const auto *L = dyn_cast<CXXBoolLiteralExpr>(Exp)) {
16668 if (
const auto *FL = dyn_cast<FloatingLiteral>(Exp)) {
16669 Result.Val =
APValue(FL->getValue());
16674 if (
const auto *L = dyn_cast<CharacterLiteral>(Exp)) {
16680 if (
const auto *CE = dyn_cast<ConstantExpr>(Exp)) {
16681 if (CE->hasAPValueResult()) {
16682 APValue APV = CE->getAPValueResult();
16684 Result.Val = std::move(APV);
16760 bool InConstantContext)
const {
16761 assert(!isValueDependent() &&
16762 "Expression evaluator can't be called on a dependent expression.");
16763 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsRValue");
16764 EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
16765 Info.InConstantContext = InConstantContext;
16766 return ::EvaluateAsRValue(
this, Result, Ctx, Info);
16770 bool InConstantContext)
const {
16771 assert(!isValueDependent() &&
16772 "Expression evaluator can't be called on a dependent expression.");
16773 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsBooleanCondition");
16781 bool InConstantContext)
const {
16782 assert(!isValueDependent() &&
16783 "Expression evaluator can't be called on a dependent expression.");
16784 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsInt");
16785 EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
16786 Info.InConstantContext = InConstantContext;
16787 return ::EvaluateAsInt(
this, Result, Ctx, AllowSideEffects, Info);
16792 bool InConstantContext)
const {
16793 assert(!isValueDependent() &&
16794 "Expression evaluator can't be called on a dependent expression.");
16795 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFixedPoint");
16796 EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
16797 Info.InConstantContext = InConstantContext;
16798 return ::EvaluateAsFixedPoint(
this, Result, Ctx, AllowSideEffects, Info);
16803 bool InConstantContext)
const {
16804 assert(!isValueDependent() &&
16805 "Expression evaluator can't be called on a dependent expression.");
16807 if (!getType()->isRealFloatingType())
16810 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFloat");
16822 bool InConstantContext)
const {
16823 assert(!isValueDependent() &&
16824 "Expression evaluator can't be called on a dependent expression.");
16826 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsLValue");
16827 EvalInfo Info(Ctx, Result, EvalInfo::EM_ConstantFold);
16828 Info.InConstantContext = InConstantContext;
16831 if (!
EvaluateLValue(
this, LV, Info) || !Info.discardCleanups() ||
16832 Result.HasSideEffects ||
16835 ConstantExprKind::Normal, CheckedTemps))
16838 LV.moveInto(Result.Val);
16845 bool IsConstantDestruction) {
16846 EvalInfo Info(Ctx, EStatus,
16847 IsConstantDestruction ? EvalInfo::EM_ConstantExpression
16848 : EvalInfo::EM_ConstantFold);
16849 Info.setEvaluatingDecl(
Base, DestroyedValue,
16850 EvalInfo::EvaluatingDeclKind::Dtor);
16851 Info.InConstantContext = IsConstantDestruction;
16860 if (!Info.discardCleanups())
16861 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
16868 assert(!isValueDependent() &&
16869 "Expression evaluator can't be called on a dependent expression.");
16874 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsConstantExpr");
16875 EvalInfo::EvaluationMode EM = EvalInfo::EM_ConstantExpression;
16876 EvalInfo Info(Ctx, Result, EM);
16877 Info.InConstantContext =
true;
16879 if (Info.EnableNewConstInterp) {
16880 if (!Info.Ctx.getInterpContext().evaluate(Info,
this, Result.Val, Kind))
16883 getStorageType(Ctx,
this), Result.Val, Kind);
16888 if (Kind == ConstantExprKind::ClassTemplateArgument)
16896 Info.setEvaluatingDecl(
Base, Result.Val);
16898 if (Info.EnableNewConstInterp) {
16899 if (!Info.Ctx.getInterpContext().evaluateAsRValue(Info,
this, Result.Val))
16908 FullExpressionRAII
Scope(Info);
16910 Result.HasSideEffects || !
Scope.destroy())
16913 if (!Info.discardCleanups())
16914 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
16925 if (Kind == ConstantExprKind::ClassTemplateArgument &&
16928 Result.HasSideEffects)) {
16940 bool IsConstantInitialization)
const {
16941 assert(!isValueDependent() &&
16942 "Expression evaluator can't be called on a dependent expression.");
16944 llvm::TimeTraceScope TimeScope(
"EvaluateAsInitializer", [&] {
16946 llvm::raw_string_ostream OS(Name);
16952 EStatus.
Diag = &Notes;
16954 EvalInfo Info(Ctx, EStatus,
16955 (IsConstantInitialization &&
16957 ? EvalInfo::EM_ConstantExpression
16958 : EvalInfo::EM_ConstantFold);
16959 Info.setEvaluatingDecl(VD,
Value);
16960 Info.InConstantContext = IsConstantInitialization;
16965 if (Info.EnableNewConstInterp) {
16966 auto &InterpCtx =
const_cast<ASTContext &
>(Ctx).getInterpContext();
16967 if (!InterpCtx.evaluateAsInitializer(Info, VD,
Value))
16971 ConstantExprKind::Normal);
16986 FullExpressionRAII
Scope(Info);
16989 EStatus.HasSideEffects)
16995 Info.performLifetimeExtension();
16997 if (!Info.discardCleanups())
16998 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
17002 ConstantExprKind::Normal) &&
17009 EStatus.
Diag = &Notes;
17013 bool IsConstantDestruction = hasConstantInitialization();
17019 if (getEvaluatedValue() && !getEvaluatedValue()->isAbsent())
17020 DestroyedValue = *getEvaluatedValue();
17025 getType(), getLocation(), EStatus,
17026 IsConstantDestruction) ||
17030 ensureEvaluatedStmt()->HasConstantDestruction =
true;
17037 assert(!isValueDependent() &&
17038 "Expression evaluator can't be called on a dependent expression.");
17047 assert(!isValueDependent() &&
17048 "Expression evaluator can't be called on a dependent expression.");
17050 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstInt");
17053 EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
17054 Info.InConstantContext =
true;
17058 assert(Result &&
"Could not evaluate expression");
17059 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
17061 return EVResult.Val.getInt();
17066 assert(!isValueDependent() &&
17067 "Expression evaluator can't be called on a dependent expression.");
17069 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstIntCheckOverflow");
17072 EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
17073 Info.InConstantContext =
true;
17074 Info.CheckingForUndefinedBehavior =
true;
17078 assert(Result &&
"Could not evaluate expression");
17079 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
17081 return EVResult.Val.getInt();
17085 assert(!isValueDependent() &&
17086 "Expression evaluator can't be called on a dependent expression.");
17088 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateForOverflow");
17092 EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
17093 Info.CheckingForUndefinedBehavior =
true;
17126 IK_ICEIfUnevaluated,
17142static ICEDiag
Worst(ICEDiag A, ICEDiag B) {
return A.Kind >= B.Kind ? A : B; }
17147 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
17149 Info.InConstantContext =
true;
17163#define ABSTRACT_STMT(Node)
17164#define STMT(Node, Base) case Expr::Node##Class:
17165#define EXPR(Node, Base)
17166#include "clang/AST/StmtNodes.inc"
17167 case Expr::PredefinedExprClass:
17168 case Expr::FloatingLiteralClass:
17169 case Expr::ImaginaryLiteralClass:
17170 case Expr::StringLiteralClass:
17171 case Expr::ArraySubscriptExprClass:
17172 case Expr::MatrixSubscriptExprClass:
17173 case Expr::ArraySectionExprClass:
17174 case Expr::OMPArrayShapingExprClass:
17175 case Expr::OMPIteratorExprClass:
17176 case Expr::MemberExprClass:
17177 case Expr::CompoundAssignOperatorClass:
17178 case Expr::CompoundLiteralExprClass:
17179 case Expr::ExtVectorElementExprClass:
17180 case Expr::DesignatedInitExprClass:
17181 case Expr::ArrayInitLoopExprClass:
17182 case Expr::ArrayInitIndexExprClass:
17183 case Expr::NoInitExprClass:
17184 case Expr::DesignatedInitUpdateExprClass:
17185 case Expr::ImplicitValueInitExprClass:
17186 case Expr::ParenListExprClass:
17187 case Expr::VAArgExprClass:
17188 case Expr::AddrLabelExprClass:
17189 case Expr::StmtExprClass:
17190 case Expr::CXXMemberCallExprClass:
17191 case Expr::CUDAKernelCallExprClass:
17192 case Expr::CXXAddrspaceCastExprClass:
17193 case Expr::CXXDynamicCastExprClass:
17194 case Expr::CXXTypeidExprClass:
17195 case Expr::CXXUuidofExprClass:
17196 case Expr::MSPropertyRefExprClass:
17197 case Expr::MSPropertySubscriptExprClass:
17198 case Expr::CXXNullPtrLiteralExprClass:
17199 case Expr::UserDefinedLiteralClass:
17200 case Expr::CXXThisExprClass:
17201 case Expr::CXXThrowExprClass:
17202 case Expr::CXXNewExprClass:
17203 case Expr::CXXDeleteExprClass:
17204 case Expr::CXXPseudoDestructorExprClass:
17205 case Expr::UnresolvedLookupExprClass:
17206 case Expr::TypoExprClass:
17207 case Expr::RecoveryExprClass:
17208 case Expr::DependentScopeDeclRefExprClass:
17209 case Expr::CXXConstructExprClass:
17210 case Expr::CXXInheritedCtorInitExprClass:
17211 case Expr::CXXStdInitializerListExprClass:
17212 case Expr::CXXBindTemporaryExprClass:
17213 case Expr::ExprWithCleanupsClass:
17214 case Expr::CXXTemporaryObjectExprClass:
17215 case Expr::CXXUnresolvedConstructExprClass:
17216 case Expr::CXXDependentScopeMemberExprClass:
17217 case Expr::UnresolvedMemberExprClass:
17218 case Expr::ObjCStringLiteralClass:
17219 case Expr::ObjCBoxedExprClass:
17220 case Expr::ObjCArrayLiteralClass:
17221 case Expr::ObjCDictionaryLiteralClass:
17222 case Expr::ObjCEncodeExprClass:
17223 case Expr::ObjCMessageExprClass:
17224 case Expr::ObjCSelectorExprClass:
17225 case Expr::ObjCProtocolExprClass:
17226 case Expr::ObjCIvarRefExprClass:
17227 case Expr::ObjCPropertyRefExprClass:
17228 case Expr::ObjCSubscriptRefExprClass:
17229 case Expr::ObjCIsaExprClass:
17230 case Expr::ObjCAvailabilityCheckExprClass:
17231 case Expr::ShuffleVectorExprClass:
17232 case Expr::ConvertVectorExprClass:
17233 case Expr::BlockExprClass:
17234 case Expr::NoStmtClass:
17235 case Expr::OpaqueValueExprClass:
17236 case Expr::PackExpansionExprClass:
17237 case Expr::SubstNonTypeTemplateParmPackExprClass:
17238 case Expr::FunctionParmPackExprClass:
17239 case Expr::AsTypeExprClass:
17240 case Expr::ObjCIndirectCopyRestoreExprClass:
17241 case Expr::MaterializeTemporaryExprClass:
17242 case Expr::PseudoObjectExprClass:
17243 case Expr::AtomicExprClass:
17244 case Expr::LambdaExprClass:
17245 case Expr::CXXFoldExprClass:
17246 case Expr::CoawaitExprClass:
17247 case Expr::DependentCoawaitExprClass:
17248 case Expr::CoyieldExprClass:
17249 case Expr::SYCLUniqueStableNameExprClass:
17250 case Expr::CXXParenListInitExprClass:
17251 case Expr::HLSLOutArgExprClass:
17254 case Expr::InitListExprClass: {
17260 if (cast<InitListExpr>(
E)->getNumInits() == 1)
17261 return CheckICE(cast<InitListExpr>(
E)->getInit(0), Ctx);
17265 case Expr::SizeOfPackExprClass:
17266 case Expr::GNUNullExprClass:
17267 case Expr::SourceLocExprClass:
17268 case Expr::EmbedExprClass:
17269 case Expr::OpenACCAsteriskSizeExprClass:
17272 case Expr::PackIndexingExprClass:
17273 return CheckICE(cast<PackIndexingExpr>(
E)->getSelectedExpr(), Ctx);
17275 case Expr::SubstNonTypeTemplateParmExprClass:
17277 CheckICE(cast<SubstNonTypeTemplateParmExpr>(
E)->getReplacement(), Ctx);
17279 case Expr::ConstantExprClass:
17280 return CheckICE(cast<ConstantExpr>(
E)->getSubExpr(), Ctx);
17282 case Expr::ParenExprClass:
17283 return CheckICE(cast<ParenExpr>(
E)->getSubExpr(), Ctx);
17284 case Expr::GenericSelectionExprClass:
17285 return CheckICE(cast<GenericSelectionExpr>(
E)->getResultExpr(), Ctx);
17286 case Expr::IntegerLiteralClass:
17287 case Expr::FixedPointLiteralClass:
17288 case Expr::CharacterLiteralClass:
17289 case Expr::ObjCBoolLiteralExprClass:
17290 case Expr::CXXBoolLiteralExprClass:
17291 case Expr::CXXScalarValueInitExprClass:
17292 case Expr::TypeTraitExprClass:
17293 case Expr::ConceptSpecializationExprClass:
17294 case Expr::RequiresExprClass:
17295 case Expr::ArrayTypeTraitExprClass:
17296 case Expr::ExpressionTraitExprClass:
17297 case Expr::CXXNoexceptExprClass:
17299 case Expr::CallExprClass:
17300 case Expr::CXXOperatorCallExprClass: {
17304 const CallExpr *CE = cast<CallExpr>(
E);
17309 case Expr::CXXRewrittenBinaryOperatorClass:
17310 return CheckICE(cast<CXXRewrittenBinaryOperator>(
E)->getSemanticForm(),
17312 case Expr::DeclRefExprClass: {
17313 const NamedDecl *
D = cast<DeclRefExpr>(
E)->getDecl();
17314 if (isa<EnumConstantDecl>(
D))
17326 const VarDecl *VD = dyn_cast<VarDecl>(
D);
17333 case Expr::UnaryOperatorClass: {
17356 llvm_unreachable(
"invalid unary operator class");
17358 case Expr::OffsetOfExprClass: {
17367 case Expr::UnaryExprOrTypeTraitExprClass: {
17369 if ((Exp->
getKind() == UETT_SizeOf) &&
17374 case Expr::BinaryOperatorClass: {
17419 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE) {
17422 return ICEDiag(IK_ICEIfUnevaluated,
E->
getBeginLoc());
17423 if (REval.isSigned() && REval.isAllOnes()) {
17425 if (LEval.isMinSignedValue())
17426 return ICEDiag(IK_ICEIfUnevaluated,
E->
getBeginLoc());
17434 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE)
17435 return ICEDiag(IK_ICEIfUnevaluated,
E->
getBeginLoc());
17441 return Worst(LHSResult, RHSResult);
17447 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICEIfUnevaluated) {
17457 return Worst(LHSResult, RHSResult);
17460 llvm_unreachable(
"invalid binary operator kind");
17462 case Expr::ImplicitCastExprClass:
17463 case Expr::CStyleCastExprClass:
17464 case Expr::CXXFunctionalCastExprClass:
17465 case Expr::CXXStaticCastExprClass:
17466 case Expr::CXXReinterpretCastExprClass:
17467 case Expr::CXXConstCastExprClass:
17468 case Expr::ObjCBridgedCastExprClass: {
17469 const Expr *SubExpr = cast<CastExpr>(
E)->getSubExpr();
17470 if (isa<ExplicitCastExpr>(
E)) {
17475 APSInt IgnoredVal(DestWidth, !DestSigned);
17480 if (FL->getValue().convertToInteger(IgnoredVal,
17481 llvm::APFloat::rmTowardZero,
17482 &Ignored) & APFloat::opInvalidOp)
17487 switch (cast<CastExpr>(
E)->getCastKind()) {
17488 case CK_LValueToRValue:
17489 case CK_AtomicToNonAtomic:
17490 case CK_NonAtomicToAtomic:
17492 case CK_IntegralToBoolean:
17493 case CK_IntegralCast:
17499 case Expr::BinaryConditionalOperatorClass: {
17502 if (CommonResult.Kind == IK_NotICE)
return CommonResult;
17504 if (FalseResult.Kind == IK_NotICE)
return FalseResult;
17505 if (CommonResult.Kind == IK_ICEIfUnevaluated)
return CommonResult;
17506 if (FalseResult.Kind == IK_ICEIfUnevaluated &&
17508 return FalseResult;
17510 case Expr::ConditionalOperatorClass: {
17518 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
17521 if (CondResult.Kind == IK_NotICE)
17527 if (TrueResult.Kind == IK_NotICE)
17529 if (FalseResult.Kind == IK_NotICE)
17530 return FalseResult;
17531 if (CondResult.Kind == IK_ICEIfUnevaluated)
17533 if (TrueResult.Kind == IK_ICE && FalseResult.Kind == IK_ICE)
17539 return FalseResult;
17542 case Expr::CXXDefaultArgExprClass:
17543 return CheckICE(cast<CXXDefaultArgExpr>(
E)->getExpr(), Ctx);
17544 case Expr::CXXDefaultInitExprClass:
17545 return CheckICE(cast<CXXDefaultInitExpr>(
E)->getExpr(), Ctx);
17546 case Expr::ChooseExprClass: {
17547 return CheckICE(cast<ChooseExpr>(
E)->getChosenSubExpr(), Ctx);
17549 case Expr::BuiltinBitCastExprClass: {
17550 if (!checkBitCastConstexprEligibility(
nullptr, Ctx, cast<CastExpr>(
E)))
17552 return CheckICE(cast<CastExpr>(
E)->getSubExpr(), Ctx);
17556 llvm_unreachable(
"Invalid StmtClass!");
17562 llvm::APSInt *
Value,
17573 if (!Result.isInt()) {
17584 assert(!isValueDependent() &&
17585 "Expression evaluator can't be called on a dependent expression.");
17587 ExprTimeTraceScope TimeScope(
this, Ctx,
"isIntegerConstantExpr");
17593 if (
D.
Kind != IK_ICE) {
17600std::optional<llvm::APSInt>
17602 if (isValueDependent()) {
17604 return std::nullopt;
17612 return std::nullopt;
17615 if (!isIntegerConstantExpr(Ctx,
Loc))
17616 return std::nullopt;
17624 EvalInfo Info(Ctx, Status, EvalInfo::EM_IgnoreSideEffects);
17625 Info.InConstantContext =
true;
17628 llvm_unreachable(
"ICE cannot be evaluated!");
17634 assert(!isValueDependent() &&
17635 "Expression evaluator can't be called on a dependent expression.");
17637 return CheckICE(
this, Ctx).Kind == IK_ICE;
17642 assert(!isValueDependent() &&
17643 "Expression evaluator can't be called on a dependent expression.");
17652 Status.Diag = &Diags;
17653 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
17660 Info.discardCleanups() && !Status.HasSideEffects;
17662 if (!Diags.empty()) {
17663 IsConstExpr =
false;
17664 if (
Loc) *
Loc = Diags[0].first;
17665 }
else if (!IsConstExpr) {
17667 if (
Loc) *
Loc = getExprLoc();
17670 return IsConstExpr;
17676 const Expr *This)
const {
17677 assert(!isValueDependent() &&
17678 "Expression evaluator can't be called on a dependent expression.");
17680 llvm::TimeTraceScope TimeScope(
"EvaluateWithSubstitution", [&] {
17682 llvm::raw_string_ostream OS(Name);
17689 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpressionUnevaluated);
17690 Info.InConstantContext =
true;
17693 const LValue *ThisPtr =
nullptr;
17696 auto *MD = dyn_cast<CXXMethodDecl>(Callee);
17697 assert(MD &&
"Don't provide `this` for non-methods.");
17698 assert(MD->isImplicitObjectMemberFunction() &&
17699 "Don't provide `this` for methods without an implicit object.");
17701 if (!This->isValueDependent() &&
17703 !Info.EvalStatus.HasSideEffects)
17704 ThisPtr = &ThisVal;
17708 Info.EvalStatus.HasSideEffects =
false;
17711 CallRef
Call = Info.CurrentCall->createCall(Callee);
17714 unsigned Idx = I - Args.begin();
17715 if (Idx >= Callee->getNumParams())
17717 const ParmVarDecl *PVD = Callee->getParamDecl(Idx);
17718 if ((*I)->isValueDependent() ||
17720 Info.EvalStatus.HasSideEffects) {
17722 if (
APValue *Slot = Info.getParamSlot(
Call, PVD))
17728 Info.EvalStatus.HasSideEffects =
false;
17733 Info.discardCleanups();
17734 Info.EvalStatus.HasSideEffects =
false;
17737 CallStackFrame Frame(Info, Callee->getLocation(), Callee, ThisPtr, This,
17740 FullExpressionRAII
Scope(Info);
17742 !Info.EvalStatus.HasSideEffects;
17754 llvm::TimeTraceScope TimeScope(
"isPotentialConstantExpr", [&] {
17756 llvm::raw_string_ostream OS(Name);
17763 Status.Diag = &Diags;
17765 EvalInfo Info(FD->
getASTContext(), Status, EvalInfo::EM_ConstantExpression);
17766 Info.InConstantContext =
true;
17767 Info.CheckingPotentialConstantExpression =
true;
17770 if (Info.EnableNewConstInterp) {
17771 Info.Ctx.getInterpContext().isPotentialConstantExpr(Info, FD);
17772 return Diags.empty();
17782 This.set({&VIE, Info.CurrentCall->Index});
17790 Info.setEvaluatingDecl(This.getLValueBase(), Scratch);
17796 &VIE, Args, CallRef(), FD->
getBody(), Info, Scratch,
17800 return Diags.empty();
17808 "Expression evaluator can't be called on a dependent expression.");
17811 Status.Diag = &Diags;
17814 EvalInfo::EM_ConstantExpressionUnevaluated);
17815 Info.InConstantContext =
true;
17816 Info.CheckingPotentialConstantExpression =
true;
17820 nullptr, CallRef());
17824 return Diags.empty();
17828 unsigned Type)
const {
17829 if (!getType()->isPointerType())
17833 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantFold);
17838 EvalInfo &Info, std::string *StringResult) {
17850 if (
const StringLiteral *S = dyn_cast_or_null<StringLiteral>(
17851 String.getLValueBase().dyn_cast<
const Expr *>())) {
17852 StringRef Str = S->getBytes();
17853 int64_t Off = String.Offset.getQuantity();
17854 if (Off >= 0 && (uint64_t)Off <= (uint64_t)Str.size() &&
17855 S->getCharByteWidth() == 1 &&
17857 Info.Ctx.hasSameUnqualifiedType(CharTy, Info.Ctx.CharTy)) {
17858 Str = Str.substr(Off);
17860 StringRef::size_type Pos = Str.find(0);
17861 if (Pos != StringRef::npos)
17862 Str = Str.substr(0, Pos);
17864 Result = Str.size();
17866 *StringResult = Str;
17874 for (uint64_t Strlen = 0; ; ++Strlen) {
17882 }
else if (StringResult)
17883 StringResult->push_back(Char.
getInt().getExtValue());
17891 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantFold);
17893 std::string StringResult;
17896 return StringResult;
17901 const Expr *SizeExpression,
17905 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
17906 Info.InConstantContext =
true;
17908 FullExpressionRAII
Scope(Info);
17913 uint64_t Size = SizeValue.getZExtValue();
17919 for (uint64_t I = 0; I < Size; ++I) {
17926 Result.push_back(
static_cast<char>(
C.getExtValue()));
17930 if (!
Scope.destroy())
17941 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantFold);
17946struct IsWithinLifetimeHandler {
17948 static constexpr AccessKinds AccessKind = AccessKinds::AK_IsWithinLifetime;
17949 using result_type = std::optional<bool>;
17950 std::optional<bool> failed() {
return std::nullopt; }
17951 template <
typename T>
17952 std::optional<bool> found(
T &Subobj,
QualType SubobjType) {
17957std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &IEE,
17959 EvalInfo &Info = IEE.Info;
17964 if (!Info.InConstantContext)
17965 return std::nullopt;
17966 assert(
E->getBuiltinCallee() == Builtin::BI__builtin_is_within_lifetime);
17967 const Expr *Arg =
E->getArg(0);
17969 return std::nullopt;
17972 return std::nullopt;
17974 if (Val.allowConstexprUnknown())
17978 bool CalledFromStd =
false;
17979 const auto *
Callee = Info.CurrentCall->getCallee();
17980 if (Callee &&
Callee->isInStdNamespace()) {
17984 Info.CCEDiag(CalledFromStd ? Info.CurrentCall->getCallRange().getBegin()
17986 diag::err_invalid_is_within_lifetime)
17987 << (CalledFromStd ?
"std::is_within_lifetime"
17988 :
"__builtin_is_within_lifetime")
17990 return std::nullopt;
18000 if (Val.isNullPointer() || Val.getLValueBase().isNull())
18002 QualType T = Val.getLValueBase().getType();
18004 "Pointers to functions should have been typed as function pointers "
18005 "which would have been rejected earlier");
18008 if (Val.getLValueDesignator().isOnePastTheEnd())
18010 assert(Val.getLValueDesignator().isValidSubobject() &&
18011 "Unchecked case for valid subobject");
18015 CompleteObject CO =
18019 if (Info.EvaluatingDeclValue && CO.Value == Info.EvaluatingDeclValue)
18024 IsWithinLifetimeHandler handler{Info};
18025 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::@1727::IndirectLocalPathEntry::EntryKind Kind
static Decl::Kind getKind(const Decl *D)
GCCTypeClass
Values returned by __builtin_classify_type, chosen to match the values produced by GCC's builtin.
static bool isRead(AccessKinds AK)
static bool EvaluateBuiltinStrLen(const Expr *E, uint64_t &Result, EvalInfo &Info, std::string *StringResult=nullptr)
static bool isValidIndeterminateAccess(AccessKinds AK)
Is this kind of axcess valid on an indeterminate object value?
static bool EvaluateMemberPointer(const Expr *E, MemberPtr &Result, EvalInfo &Info)
static bool hasUnacceptableSideEffect(Expr::EvalStatus &Result, Expr::SideEffectsKind SEK)
static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E, AccessKinds AK, const LValue &LVal, QualType LValType)
Find the complete object to which an LValue refers.
static bool evaluateLValueAsAllocSize(EvalInfo &Info, APValue::LValueBase Base, LValue &Result)
Attempts to evaluate the given LValueBase as the result of a call to a function with the alloc_size a...
static const CXXMethodDecl * HandleVirtualDispatch(EvalInfo &Info, const Expr *E, LValue &This, const CXXMethodDecl *Found, llvm::SmallVectorImpl< QualType > &CovariantAdjustmentPath)
Perform virtual dispatch.
static bool EvaluateVarDecl(EvalInfo &Info, const VarDecl *VD)
static bool CheckEvaluationResult(CheckEvaluationResultKind CERK, EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value, ConstantExprKind Kind, const FieldDecl *SubobjectDecl, CheckedTemporaries &CheckedTemps)
static bool HandleLValueComplexElement(EvalInfo &Info, const Expr *E, LValue &LVal, QualType EltTy, bool Imag)
Update an lvalue to refer to a component of a complex number.
static bool HandleSizeof(EvalInfo &Info, SourceLocation Loc, QualType Type, CharUnits &Size, SizeOfType SOT=SizeOfType::SizeOf)
Get the size of the given type in char units.
static bool FastEvaluateAsRValue(const Expr *Exp, Expr::EvalResult &Result, const ASTContext &Ctx, bool &IsConst)
static bool HandleConstructorCall(const Expr *E, const LValue &This, CallRef Call, const CXXConstructorDecl *Definition, EvalInfo &Info, APValue &Result)
Evaluate a constructor call.
static EvalStmtResult EvaluateLoopBody(StmtResult &Result, EvalInfo &Info, const Stmt *Body, const SwitchCase *Case=nullptr)
Evaluate the body of a loop, and translate the result as appropriate.
static bool EvaluatePointer(const Expr *E, LValue &Result, EvalInfo &Info, bool InvalidBaseOK=false)
static bool CheckTrivialDefaultConstructor(EvalInfo &Info, SourceLocation Loc, const CXXConstructorDecl *CD, bool IsValueInitialization)
CheckTrivialDefaultConstructor - Check whether a constructor is a trivial default constructor.
static bool EvaluateVector(const Expr *E, APValue &Result, EvalInfo &Info)
static const ValueDecl * GetLValueBaseDecl(const LValue &LVal)
static bool TryEvaluateBuiltinNaN(const ASTContext &Context, QualType ResultTy, const Expr *Arg, bool SNaN, llvm::APFloat &Result)
static const Expr * ignorePointerCastsAndParens(const Expr *E)
A more selective version of E->IgnoreParenCasts for tryEvaluateBuiltinObjectSize.
static bool isAnyAccess(AccessKinds AK)
static bool EvaluateComparisonBinaryOperator(EvalInfo &Info, const BinaryOperator *E, SuccessCB &&Success, AfterCB &&DoAfter)
static bool HandleClassZeroInitialization(EvalInfo &Info, const Expr *E, const RecordDecl *RD, const LValue &This, APValue &Result)
Perform zero-initialization on an object of non-union class type.
static bool EvaluateComplex(const Expr *E, ComplexValue &Res, EvalInfo &Info)
static bool CheckMemoryLeaks(EvalInfo &Info)
Enforce C++2a [expr.const]/4.17, which disallows new-expressions unless "the allocated storage is dea...
static ICEDiag CheckEvalInICE(const Expr *E, const ASTContext &Ctx)
static bool HandleFunctionCall(SourceLocation CallLoc, const FunctionDecl *Callee, const LValue *This, const Expr *E, ArrayRef< const Expr * > Args, CallRef Call, const Stmt *Body, EvalInfo &Info, APValue &Result, const LValue *ResultSlot)
Evaluate a function call.
static bool isBaseClassPublic(const CXXRecordDecl *Derived, const CXXRecordDecl *Base)
Determine whether Base, which is known to be a direct base class of Derived, is a public base class.
static bool hasVirtualDestructor(QualType T)
static bool HandleOverflow(EvalInfo &Info, const Expr *E, const T &SrcValue, QualType DestType)
static CharUnits getBaseAlignment(EvalInfo &Info, const LValue &Value)
static bool HandleLValueIndirectMember(EvalInfo &Info, const Expr *E, LValue &LVal, const IndirectFieldDecl *IFD)
Update LVal to refer to the given indirect field.
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 IsWeakLValue(const LValue &Value)
static bool EvaluateArrayNewConstructExpr(EvalInfo &Info, LValue &This, APValue &Result, const CXXConstructExpr *CCE, QualType AllocType)
static bool EvaluateRecord(const Expr *E, const LValue &This, APValue &Result, EvalInfo &Info)
static bool handleAssignment(EvalInfo &Info, const Expr *E, const LValue &LVal, QualType LValType, APValue &Val)
Perform an assignment of Val to LVal. Takes ownership of Val.
static bool CastToDerivedClass(EvalInfo &Info, const Expr *E, LValue &Result, const RecordDecl *TruncatedType, unsigned TruncatedElements)
Cast an lvalue referring to a base subobject to a derived class, by truncating the lvalue's path to t...
static bool EvaluateIgnoredValue(EvalInfo &Info, const Expr *E)
Evaluate an expression to see if it had side-effects, and discard its result.
static void addFlexibleArrayMemberInitSize(EvalInfo &Info, const QualType &T, const LValue &LV, CharUnits &Size)
If we're evaluating the object size of an instance of a struct that contains a flexible array member,...
static bool HandleLValueBasePath(EvalInfo &Info, const CastExpr *E, QualType Type, LValue &Result)
static bool EvaluateArgs(ArrayRef< const Expr * > Args, CallRef Call, EvalInfo &Info, const FunctionDecl *Callee, bool RightToLeft=false)
Evaluate the arguments to a function call.
static QualType getSubobjectType(QualType ObjType, QualType SubobjType, bool IsMutable=false)
static bool EvaluateFixedPointOrInteger(const Expr *E, APFixedPoint &Result, EvalInfo &Info)
Evaluate an integer or fixed point expression into an APResult.
static bool HandleIntToFloatCast(EvalInfo &Info, const Expr *E, const FPOptions FPO, QualType SrcType, const APSInt &Value, QualType DestType, APFloat &Result)
static const CXXRecordDecl * getBaseClassType(SubobjectDesignator &Designator, unsigned PathLength)
static bool CastToBaseClass(EvalInfo &Info, const Expr *E, LValue &Result, const CXXRecordDecl *DerivedRD, const CXXRecordDecl *BaseRD)
Cast an lvalue referring to a derived class to a known base subobject.
static bool HandleLValueBase(EvalInfo &Info, const Expr *E, LValue &Obj, const CXXRecordDecl *DerivedDecl, const CXXBaseSpecifier *Base)
static bool HandleConversionToBool(const APValue &Val, bool &Result)
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 getBytesReturnedByAllocSizeCall(const ASTContext &Ctx, const CallExpr *Call, llvm::APInt &Result)
Attempts to compute the number of bytes available at the pointer returned by a function with the allo...
static bool EvaluateInteger(const Expr *E, APSInt &Result, EvalInfo &Info)
CheckEvaluationResultKind
static bool isZeroSized(const LValue &Value)
static APSInt extractStringLiteralCharacter(EvalInfo &Info, const Expr *Lit, uint64_t Index)
Extract the value of a character from a string literal.
static bool modifySubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, const SubobjectDesignator &Sub, APValue &NewVal)
Update the designated sub-object of an rvalue to the given value.
static 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 void expandArray(APValue &Array, unsigned Index)
static bool handleLogicalOpForVector(const APInt &LHSValue, BinaryOperatorKind Opcode, const APInt &RHSValue, APInt &Result)
static unsigned FindDesignatorMismatch(QualType ObjType, const SubobjectDesignator &A, const SubobjectDesignator &B, bool &WasArrayIndex)
Find the position where two subobject designators diverge, or equivalently the length of the common i...
static bool isOnePastTheEndOfCompleteObject(const ASTContext &Ctx, const LValue &LV)
Determine whether this is a pointer past the end of the complete object referred to by the lvalue.
static bool EvaluateCPlusPlus11IntegralConstantExpr(const ASTContext &Ctx, const Expr *E, llvm::APSInt *Value, SourceLocation *Loc)
Evaluate an expression as a C++11 integral constant expression.
static unsigned getBaseIndex(const CXXRecordDecl *Derived, const CXXRecordDecl *Base)
Get the base index of the given base class within an APValue representing the given derived class.
static bool EvaluateFixedPoint(const Expr *E, APFixedPoint &Result, EvalInfo &Info)
Evaluate only a fixed point expression into an APResult.
void HandleComplexComplexMul(APFloat A, APFloat B, APFloat C, APFloat D, APFloat &ResR, APFloat &ResI)
static bool tryEvaluateBuiltinObjectSize(const Expr *E, unsigned Type, EvalInfo &Info, uint64_t &Size)
Tries to evaluate the __builtin_object_size for E.
static bool EvalPointerValueAsBool(const APValue &Value, bool &Result)
static bool handleVectorVectorBinOp(EvalInfo &Info, const BinaryOperator *E, BinaryOperatorKind Opcode, APValue &LHSValue, const APValue &RHSValue)
static const FunctionDecl * getVirtualOperatorDelete(QualType T)
static bool isDesignatorAtObjectEnd(const ASTContext &Ctx, const LValue &LVal)
Checks to see if the given LValue's Designator is at the end of the LValue's record layout.
static bool CheckArraySize(EvalInfo &Info, const ConstantArrayType *CAT, SourceLocation CallLoc={})
static bool EvaluateInPlace(APValue &Result, EvalInfo &Info, const LValue &This, const Expr *E, bool AllowNonLiteralTypes=false)
EvaluateInPlace - Evaluate an expression in-place in an APValue.
static bool handleFloatFloatBinOp(EvalInfo &Info, const BinaryOperator *E, APFloat &LHS, BinaryOperatorKind Opcode, const APFloat &RHS)
Perform the given binary floating-point operation, in-place, on LHS.
static std::optional< DynAlloc * > CheckDeleteKind(EvalInfo &Info, const Expr *E, const LValue &Pointer, DynAlloc::Kind DeallocKind)
Check that the given object is a suitable pointer to a heap allocation that still exists and is of th...
static bool EvaluateLValue(const Expr *E, LValue &Result, EvalInfo &Info, bool InvalidBaseOK=false)
Evaluate an expression as an lvalue.
static bool EvaluateCallArg(const ParmVarDecl *PVD, const Expr *Arg, CallRef Call, EvalInfo &Info, bool NonNull=false)
static bool HandleCovariantReturnAdjustment(EvalInfo &Info, const Expr *E, APValue &Result, ArrayRef< QualType > Path)
Perform the adjustment from a value returned by a virtual function to a value of the statically expec...
static EvalStmtResult EvaluateSwitch(StmtResult &Result, EvalInfo &Info, const SwitchStmt *SS)
Evaluate a switch statement.
static void expandStringLiteral(EvalInfo &Info, const StringLiteral *S, APValue &Result, QualType AllocType=QualType())
static bool EvaluateAtomic(const Expr *E, const LValue *This, APValue &Result, EvalInfo &Info)
static bool handleIntIntBinOp(EvalInfo &Info, const BinaryOperator *E, const APSInt &LHS, BinaryOperatorKind Opcode, APSInt RHS, APSInt &Result)
Perform the given binary integer operation.
static bool checkDynamicType(EvalInfo &Info, const Expr *E, const LValue &This, AccessKinds AK, bool Polymorphic)
Check that we can access the notional vptr of an object / determine its dynamic type.
static bool HandleFloatToIntCast(EvalInfo &Info, const Expr *E, QualType SrcType, const APFloat &Value, QualType DestType, APSInt &Result)
static bool getAlignmentArgument(const Expr *E, QualType ForType, EvalInfo &Info, APSInt &Alignment)
Evaluate the value of the alignment argument to __builtin_align_{up,down}, __builtin_is_aligned and _...
static bool CheckFullyInitialized(EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value)
Check that this evaluated value is fully-initialized and can be loaded by an lvalue-to-rvalue convers...
static 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.
GCCTypeClass EvaluateBuiltinClassifyType(QualType T, const LangOptions &LangOpts)
EvaluateBuiltinClassifyType - Evaluate __builtin_classify_type the same way as GCC.
static bool EvaluateDependentExpr(const Expr *E, EvalInfo &Info)
static APSInt HandleIntToIntCast(EvalInfo &Info, const Expr *E, QualType DestType, QualType SrcType, const APSInt &Value)
static std::optional< APValue > handleVectorUnaryOperator(ASTContext &Ctx, QualType ResultTy, UnaryOperatorKind Op, APValue Elt)
static bool lifetimeStartedInEvaluation(EvalInfo &Info, APValue::LValueBase Base, bool MutableSubobject=false)
static bool isOneByteCharacterType(QualType T)
static bool HandleLambdaCapture(EvalInfo &Info, const Expr *E, LValue &Result, const CXXMethodDecl *MD, const FieldDecl *FD, bool LValueToRValueConversion)
Get an lvalue to a field of a lambda's closure type.
static bool EvaluateCond(EvalInfo &Info, const VarDecl *CondDecl, const Expr *Cond, bool &Result)
Evaluate a condition (either a variable declaration or an expression).
static bool EvaluateAsFixedPoint(const Expr *E, Expr::EvalResult &ExprResult, const ASTContext &Ctx, Expr::SideEffectsKind AllowSideEffects, EvalInfo &Info)
static bool EvaluateAsRValue(EvalInfo &Info, const Expr *E, APValue &Result)
EvaluateAsRValue - Try to evaluate this expression, performing an implicit lvalue-to-rvalue cast if i...
static bool diagnoseMutableFields(EvalInfo &Info, const Expr *E, AccessKinds AK, QualType T)
Diagnose an attempt to read from any unreadable field within the specified type, which might be a cla...
static ICEDiag CheckICE(const Expr *E, const ASTContext &Ctx)
static bool CheckConstexprFunction(EvalInfo &Info, SourceLocation CallLoc, const FunctionDecl *Declaration, const FunctionDecl *Definition, const Stmt *Body)
CheckConstexprFunction - Check that a function can be called in a constant expression.
static bool EvaluateDestruction(const ASTContext &Ctx, APValue::LValueBase Base, APValue DestroyedValue, QualType Type, SourceLocation Loc, Expr::EvalStatus &EStatus, bool IsConstantDestruction)
static bool EvaluateDecl(EvalInfo &Info, const Decl *D)
static EvalStmtResult EvaluateStmt(StmtResult &Result, EvalInfo &Info, const Stmt *S, const SwitchCase *SC=nullptr)
static bool EvaluateArrayNewInitList(EvalInfo &Info, LValue &This, APValue &Result, const InitListExpr *ILE, QualType AllocType)
static bool HasSameBase(const LValue &A, const LValue &B)
static bool CheckLocalVariableDeclaration(EvalInfo &Info, const VarDecl *VD)
static bool HandleLValueDirectBase(EvalInfo &Info, const Expr *E, LValue &Obj, const CXXRecordDecl *Derived, const CXXRecordDecl *Base, const ASTRecordLayout *RL=nullptr)
static bool IsGlobalLValue(APValue::LValueBase B)
static llvm::RoundingMode getActiveRoundingMode(EvalInfo &Info, const Expr *E)
Get rounding mode to use in evaluation of the specified expression.
static QualType getObjectType(APValue::LValueBase B)
Retrieves the "underlying object type" of the given expression, as used by __builtin_object_size.
static bool handleCompareOpForVectorHelper(const APTy &LHSValue, BinaryOperatorKind Opcode, const APTy &RHSValue, APInt &Result)
static bool Evaluate(APValue &Result, EvalInfo &Info, const Expr *E)
static bool isReadByLvalueToRvalueConversion(const CXXRecordDecl *RD)
Determine whether a type would actually be read by an lvalue-to-rvalue conversion.
static void negateAsSigned(APSInt &Int)
Negate an APSInt in place, converting it to a signed form if necessary, and preserving its value (by ...
static bool isUserWritingOffTheEnd(const ASTContext &Ctx, const LValue &LVal)
Attempts to detect a user writing into a piece of memory that's impossible to figure out the size of ...
static bool 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.
__DEVICE__ long long abs(long long __n)
QualType getDynamicAllocType() const
QualType getTypeInfoType() const
static LValueBase getTypeInfo(TypeInfoLValue LV, QualType TypeInfo)
static LValueBase getDynamicAlloc(DynamicAllocLValue LV, QualType Type)
A non-discriminated union of a base, field, or array index.
static LValuePathEntry ArrayIndex(uint64_t Index)
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
bool hasArrayFiller() const
const LValueBase getLValueBase() const
APValue & getArrayInitializedElt(unsigned I)
void swap(APValue &RHS)
Swaps the contents of this and the given APValue.
APValue & getStructField(unsigned i)
const FieldDecl * getUnionField() const
APSInt & getComplexIntImag()
bool isComplexInt() const
llvm::PointerIntPair< const Decl *, 1, bool > BaseOrMemberType
A FieldDecl or CXXRecordDecl, along with a flag indicating whether we mean a virtual or non-virtual b...
ValueKind getKind() const
unsigned getArrayInitializedElts() const
static APValue IndeterminateValue()
APFixedPoint & getFixedPoint()
bool hasLValuePath() const
const ValueDecl * getMemberPointerDecl() const
APValue & getUnionValue()
CharUnits & getLValueOffset()
void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const
bool isComplexFloat() const
APValue & getVectorElt(unsigned I)
APValue & getArrayFiller()
unsigned getVectorLength() const
void setUnion(const FieldDecl *Field, const APValue &Value)
bool isIndeterminate() const
unsigned getArraySize() const
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.
QualType getRecordType(const RecordDecl *Decl) const
uint64_t getTargetNullPointerValue(QualType QT) const
Get target-dependent integer value for null pointer which is used for constant folding.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
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<=>,...
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
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 TargetInfo & getTargetInfo() const
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
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...
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
QualType getThisType() const
Return the type of the this pointer.
bool isMoveAssignmentOperator() const
Determine whether this is a move assignment operator.
bool isCopyAssignmentOperator() const
Determine whether this is a copy-assignment operator, regardless of whether it was declared implicitl...
bool isLambdaStaticInvoker() const
Determine whether this is a lambda closure type's static member function that is used for the result ...
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).
The null pointer literal (C++11 [lex.nullptr])
Represents a list-initialization with parenthesis.
Represents a C++ struct/union/class.
bool hasMutableFields() const
Determine whether this class, or any of its class subobjects, contains a mutable field.
bool isGenericLambda() const
Determine whether this class describes a generic lambda function object (i.e.
base_class_iterator bases_end()
bool hasTrivialDestructor() const
Determine whether this class has a trivial destructor (C++ [class.dtor]p3)
capture_const_iterator captures_end() const
void getCaptureFields(llvm::DenseMap< const ValueDecl *, FieldDecl * > &Captures, FieldDecl *&ThisCapture) const
For a closure type, retrieve the mapping from captured variables and this to the non-static data memb...
unsigned getNumBases() const
Retrieves the number of base classes of this class.
base_class_iterator bases_begin()
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
capture_const_iterator captures_begin() const
CXXMethodDecl * getLambdaCallOperator() const
Retrieve the lambda call operator of the closure type if this is a closure type.
CXXRecordDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
bool isDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is derived from the class Base.
A C++ reinterpret_cast expression (C++ [expr.reinterpret.cast]).
A rewritten comparison expression that was originally written using operator syntax.
An expression "T()" which creates an rvalue of a non-class type T.
Implicit construction of a std::initializer_list<T> object from an array temporary within list-initia...
Represents the this expression in C++.
A C++ typeid expression (C++ [expr.typeid]), which gets the type_info that corresponds to the supplie...
A Microsoft C++ __uuidof expression, which gets the _GUID that corresponds to the supplied type or ex...
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
unsigned getBuiltinCallee() const
getBuiltinCallee - If this is a call to a builtin, return the builtin ID of the callee.
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
CaseStmt - Represent a case statement.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
const CXXBaseSpecifier *const * path_const_iterator
CharUnits - This is an opaque type for sizes expressed in character units.
bool isPowerOfTwo() const
isPowerOfTwo - Test whether the quantity is a power of two.
CharUnits alignmentAtOffset(CharUnits offset) const
Given that this is a non-zero alignment value, what is the alignment at the given offset?
bool isZero() const
isZero - Test whether the quantity equals zero.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
const ComparisonCategoryInfo & getInfoForType(QualType Ty) const
Return the comparison category information as specified by getCategoryForType(Ty).
const ValueInfo * getValueInfo(ComparisonCategoryResult ValueKind) const
ComparisonCategoryResult makeWeakResult(ComparisonCategoryResult Res) const
Converts the specified result kind into the correct result kind for this category.
Complex values, per C99 6.2.5p11.
QualType getElementType() const
CompoundAssignOperator - For compound assignments (e.g.
QualType getComputationLHSType() const
CompoundLiteralExpr - [C99 6.5.2.5].
CompoundStmt - This represents a group of statements like { stmt stmt }.
Stmt *const * const_body_iterator
body_iterator body_begin()
Represents the specialization of a concept - evaluates to a prvalue of type bool.
ConditionalOperator - The ?: ternary operator.
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
Expr * getCond() const
getCond - Return the expression representing the condition for the ?: operator.
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
Represents the canonical version of C arrays with a specified constant size.
unsigned getSizeBitWidth() const
Return the bit width of the size type.
static unsigned getNumAddressingBits(const ASTContext &Context, QualType ElementType, const llvm::APInt &NumElements)
Determine the number of bits required to address a member of.
static unsigned getMaxSizeBits(const ASTContext &Context)
Determine the maximum number of active bits that an array's size can require, which limits the maximu...
uint64_t getLimitedSize() const
Return the size zero-extended to uint64_t or UINT64_MAX if the value is larger than UINT64_MAX.
bool isZeroSize() const
Return true if the size is zero.
const Expr * getSizeExpr() const
Return a pointer to the size expression.
llvm::APInt getSize() const
Return the constant array size as an APInt.
uint64_t getZExtSize() const
Return the size zero-extended as a uint64_t.
ConstantExpr - An expression that occurs in a constant context and optionally the result of evaluatin...
ConvertVectorExpr - Clang builtin function __builtin_convertvector This AST node provides support for...
Represents the current source location and context used to determine the value of the source location...
specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext,...
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
A reference to a declared variable, function, enum, etc.
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Decl - This represents one declaration (or definition), e.g.
bool isInStdNamespace() const
ASTContext & getASTContext() const LLVM_READONLY
Kind
Lists the kind of concrete classes of Decl.
bool isInvalidDecl() const
SourceLocation getLocation() const
DeclContext * getDeclContext()
AccessSpecifier getAccess() const
OverloadedOperatorKind getCXXOverloadedOperator() const
If this name is the name of an overloadable operator in C++ (e.g., operator+), retrieve the kind of o...
A decomposition declaration.
Designator - A designator in a C99 designated initializer.
DoStmt - This represents a 'do/while' stmt.
Symbolic representation of a dynamic allocation.
static unsigned getMaxIndex()
Represents a reference to #emded data.
An instance of this object exists for each enum constant that is defined.
unsigned getNumNegativeBits() const
Returns the width in bits required to store all the negative enumerators of this enum.
bool isFixed() const
Returns true if this is an Objective-C, C++11, or Microsoft-style enumeration with a fixed underlying...
QualType getIntegerType() const
Return the integer type this enum decl corresponds to.
void getValueRange(llvm::APInt &Max, llvm::APInt &Min) const
Calculates the [Min,Max) values the enum can store based on the NumPositiveBits and NumNegativeBits.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
EnumDecl * getDecl() const
ExplicitCastExpr - An explicit cast written in the source code.
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
This represents one expression.
const Expr * skipRValueSubobjectAdjustments(SmallVectorImpl< const Expr * > &CommaLHS, SmallVectorImpl< SubobjectAdjustment > &Adjustments) const
Walk outwards from an expression we want to bind a reference to and find the expression whose lifetim...
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
static bool isPotentialConstantExpr(const FunctionDecl *FD, SmallVectorImpl< PartialDiagnosticAt > &Diags)
isPotentialConstantExpr - Return true if this function's definition might be usable in a constant exp...
static bool isPotentialConstantExprUnevaluated(Expr *E, const FunctionDecl *FD, SmallVectorImpl< PartialDiagnosticAt > &Diags)
isPotentialConstantExprUnevaluated - Return true if this expression might be usable in a constant exp...
@ SE_AllowSideEffects
Allow any unmodeled side effect.
@ SE_AllowUndefinedBehavior
Allow UB that we can give a value, but not arbitrary unmodeled side effects.
bool EvaluateCharRangeAsString(std::string &Result, const Expr *SizeExpression, const Expr *PtrExpression, ASTContext &Ctx, EvalResult &Status) const
llvm::APSInt EvaluateKnownConstIntCheckOverflow(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
bool isValueDependent() const
Determines whether the value of this expression depends on.
bool tryEvaluateStrLen(uint64_t &Result, ASTContext &Ctx) const
If the current Expr is a pointer, this will try to statically determine the strlen of the string poin...
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Returns the set of floating point options that apply to this expression.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
bool containsErrors() const
Whether this expression contains subexpressions which had errors, e.g.
bool EvaluateAsFloat(llvm::APFloat &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsFloat - Return true if this is a constant which we can fold and convert to a floating point...
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsLValue - Evaluate an expression to see if we can fold it to an lvalue with link time known ...
bool EvaluateAsFixedPoint(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsFixedPoint - Return true if this is a constant which we can fold and convert to a fixed poi...
bool isEvaluatable(const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
isEvaluatable - Call EvaluateAsRValue to see if this expression can be constant folded without side-e...
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language.
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...
bool HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects=true) const
HasSideEffects - This routine returns true for all those expressions which have any effect other than...
bool EvaluateAsConstantExpr(EvalResult &Result, const ASTContext &Ctx, ConstantExprKind Kind=ConstantExprKind::Normal) const
Evaluate an expression that is required to be a constant expression.
std::optional< std::string > tryEvaluateString(ASTContext &Ctx) const
If the current Expr can be evaluated to a pointer to a null-terminated constant string,...
bool isIntegerConstantExpr(const ASTContext &Ctx, SourceLocation *Loc=nullptr) const
bool EvaluateAsBooleanCondition(bool &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsBooleanCondition - Return true if this is a constant which we can fold and convert to a boo...
bool isTemporaryObject(ASTContext &Ctx, const CXXRecordDecl *TempTy) const
Determine whether the result of this expression is a temporary object of the given class type.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx, SourceLocation *Loc=nullptr) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
bool tryEvaluateObjectSize(uint64_t &Result, ASTContext &Ctx, unsigned Type) const
If the current Expr is a pointer, this will try to statically determine the number of bytes available...
bool isCXX98IntegralConstantExpr(const ASTContext &Ctx) const
isCXX98IntegralConstantExpr - Return true if this expression is an integral constant expression in C+...
bool EvaluateWithSubstitution(APValue &Value, ASTContext &Ctx, const FunctionDecl *Callee, ArrayRef< const Expr * > Args, const Expr *This=nullptr) const
EvaluateWithSubstitution - Evaluate an expression as if from the context of a call to the given funct...
bool EvaluateAsInitializer(APValue &Result, const ASTContext &Ctx, const VarDecl *VD, SmallVectorImpl< PartialDiagnosticAt > &Notes, bool IsConstantInitializer) const
EvaluateAsInitializer - Evaluate an expression as if it were the initializer of the given declaration...
void EvaluateForOverflow(const ASTContext &Ctx) const
bool isCXX11ConstantExpr(const ASTContext &Ctx, APValue *Result=nullptr, SourceLocation *Loc=nullptr) const
isCXX11ConstantExpr - Return true if this expression is a constant expression in C++11.
An expression trait intrinsic.
ExtVectorElementExpr - This represents access to specific elements of a vector, and may occur on the ...
bool isFPConstrained() const
LangOptions::FPExceptionModeKind getExceptionMode() const
RoundingMode getRoundingMode() const
Represents a member of a struct/union/class.
bool isBitField() const
Determines whether this field is a bitfield.
unsigned 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 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 isReplaceableGlobalAllocationFunction(std::optional< unsigned > *AlignmentParam=nullptr, bool *IsNothrow=nullptr) const
Determines whether this function is one of the replaceable global allocation functions: void *operato...
bool isDefaulted() const
Whether this function is defaulted.
void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override
Appends a human-readable name for this declaration into the given stream.
Declaration of a template function.
FunctionDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
GNUNullExpr - Implements the GNU __null extension, which is a name for a null pointer constant that h...
Represents a C11 generic selection.
One of these records is kept for each identifier that is lexed.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
IfStmt - This represents an if/then/else.
bool isNonNegatedConsteval() const
VarDecl * getConditionVariable()
Retrieve the variable declared in this "if" statement, if any.
ImaginaryLiteral - We support imaginary integer and floating point literals, like "1....
Represents an implicitly-generated value initialization of an object of a given type.
Represents a field injected from an anonymous union/struct into the parent scope.
ArrayRef< NamedDecl * > chain() const
Describes an C or C++ initializer list.
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
StrictFlexArraysLevelKind
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
A pointer to member type per C++ 8.3.3 - Pointers to members.
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
void printQualifiedName(raw_ostream &OS) const
Returns a human-readable qualified name for this declaration, like A::B::i, for i being member of nam...
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
ObjCBoxedExpr - used for generalized expression boxing.
ObjCEncodeExpr, used for @encode in Objective-C.
ObjCStringLiteral, used for Objective-C string literals i.e.
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type,...
Expr * getIndexExpr(unsigned Idx)
const OffsetOfNode & getComponent(unsigned Idx) const
TypeSourceInfo * getTypeSourceInfo() const
unsigned getNumComponents() const
Helper class for OffsetOfExpr.
unsigned getArrayExprIndex() const
For an array element node, returns the index into the array of expressions.
FieldDecl * getField() const
For a field offsetof node, returns the field.
@ Array
An index into an array.
@ Identifier
A field in a dependent type, known only by its name.
@ Base
An implicit indirection through a C++ base class, when the field found is in a base class.
Kind getKind() const
Determine what kind of offsetof node this is.
CXXBaseSpecifier * getBase() const
For a base class node, returns the base specifier.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
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.
PointerType - C99 6.7.5.1 - Pointer Declarators.
[C99 6.4.2.2] - A predefined identifier such as func.
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
QualType withConst() const
void addConst()
Add the const type qualifier to this QualType.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
bool isConstant(const ASTContext &Ctx) const
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
void removeLocalVolatile()
QualType withCVRQualifiers(unsigned CVR) const
void addVolatile()
Add the volatile type qualifier to this QualType.
bool isConstQualified() const
Determine whether this type is const-qualified.
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after.
unsigned getCVRQualifiers() const
Retrieve the set of CVR (const-volatile-restrict) qualifiers applied to this type.
Represents a struct/union/class.
bool hasFlexibleArrayMember() const
field_iterator field_end() const
field_range fields() const
bool isAnonymousStructOrUnion() const
Whether this is an anonymous struct or union.
field_iterator field_begin() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
RecordDecl * getDecl() const
Base for LValueReferenceType and RValueReferenceType.
C++2a [expr.prim.req]: A requires-expression provides a concise way to express requirements on templa...
Scope - A scope is a transient data structure that is used while parsing the program.
ShuffleVectorExpr - clang-specific builtin-in function __builtin_shufflevector.
Represents an expression that computes the length of a parameter pack.
Represents a function call to one of __builtin_LINE(), __builtin_COLUMN(), __builtin_FUNCTION(),...
Encodes a location in the source.
A trivial tuple used to represent a source range.
SourceLocation getBegin() const
StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
Stmt - This represents one statement.
StmtClass getStmtClass() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
SourceLocation getBeginLoc() const LLVM_READONLY
StringLiteral - This represents a string literal expression, e.g.
uint32_t getCodeUnit(size_t i) const
static StringLiteral * Create(const ASTContext &Ctx, StringRef Str, StringLiteralKind Kind, bool Pascal, QualType Ty, const SourceLocation *Loc, unsigned NumConcatenated)
This is the "fully general" constructor that allows representation of strings formed from multiple co...
Represents a reference to a non-type template parameter that has been substituted with a template arg...
const SwitchCase * getNextSwitchCase() const
SwitchStmt - This represents a 'switch' stmt.
VarDecl * getConditionVariable()
Retrieve the variable declared in this "switch" statement, if any.
SwitchCase * getSwitchCaseList()
TagDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
virtual bool isNan2008() const
Returns true if NaN encoding is IEEE 754-2008.
A template argument list.
unsigned size() const
Retrieve the number of template arguments in this template argument list.
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
@ Type
The template argument is a type.
A template parameter object.
Symbolic representation of typeid(T) for some type T.
QualType getType() const
Return the type wrapped by this type source info.
A type trait used in the implementation of various C++11 and Library TR1 trait templates.
The base class of the type hierarchy.
bool isStructureType() const
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isBooleanType() const
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
bool isLiteralType(const ASTContext &Ctx) const
Return true if this is a literal type (C++11 [basic.types]p10)
bool isIncompleteArrayType() const
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
bool isComplexType() const
isComplexType() does not include complex integers (a GCC extension).
const ArrayType * castAsArrayTypeUnsafe() const
A variant of castAs<> for array type which silently discards qualifiers from the outermost type.
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
bool isIntegralOrUnscopedEnumerationType() const
Determine whether this type is an integral or unscoped enumeration type.
bool isConstantArrayType() const
bool isVoidPointerType() const
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6....
bool isFunctionPointerType() const
bool isPointerType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isEnumeralType() const
bool isVariableArrayType() const
bool isSveVLSBuiltinType() const
Determines if this is a sizeless type supported by the 'arm_sve_vector_bits' type attribute,...
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
bool isExtVectorBoolType() const
bool isMemberDataPointerType() const
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
bool isAnyComplexType() const
bool isFixedPointType() const
Return true if this is a fixed point type according to ISO/IEC JTC1 SC22 WG14 N1169.
const RecordType * getAsStructureType() const
const Type * getBaseElementTypeUnsafe() const
Get the base element type of this type, potentially discarding type qualifiers.
bool isMemberPointerType() const
bool isAtomicType() const
bool isComplexIntegerType() const
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isObjectType() const
Determine whether this type is an object type.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
bool isFunctionType() const
bool isVectorType() const
bool isRealFloatingType() const
Floating point categories.
bool isFloatingType() const
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
bool isAnyPointerType() const
TypeClass getTypeClass() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isNullPtrType() const
bool isRecordType() const
bool isSizelessVectorType() const
Returns true for all scalable vector types.
bool hasPointerRepresentation() const
Whether this type is represented natively as a pointer.
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
QualType getTypeOfArgument() const
Gets the argument type, or the type of the argument expression, whichever is appropriate.
UnaryExprOrTypeTrait getKind() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Expr * getSubExpr() const
static bool isIncrementOp(Opcode Op)
An artificial decl, representing a global anonymous constant value which is uniquified by value withi...
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
bool isWeak() const
Determine whether this symbol is weakly-imported, or declared with the weak or weak-ref attr.
Represents a variable declaration or definition.
bool isConstexpr() const
Whether this variable is (C++11) constexpr.
bool hasICEInitializer(const ASTContext &Context) const
Determine whether the initializer of this variable is an integer constant expression.
bool isInitCapture() const
Whether this variable is the implicit variable for a lambda init-capture.
APValue * evaluateValue() const
Attempt to evaluate the value of the initializer attached to this declaration, and produce notes expl...
CharUnits getFlexibleArrayInitChars(const ASTContext &Ctx) const
If hasFlexibleArrayInit is true, compute the number of additional bytes necessary to store those elem...
bool hasConstantInitialization() const
Determine whether this variable has constant initialization.
VarDecl * getDefinition(ASTContext &)
Get the real (not just tentative) definition for this declaration.
bool mightBeUsableInConstantExpressions(const ASTContext &C) const
Determine whether this variable's value might be usable in a constant expression, according to the re...
bool evaluateDestruction(SmallVectorImpl< PartialDiagnosticAt > &Notes) const
Evaluate the destruction of this variable to determine if it constitutes constant destruction.
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
ThreadStorageClassSpecifier getTSCSpec() const
const Expr * getInit() const
APValue * getEvaluatedValue() const
Return the already-evaluated value of this variable's initializer, or NULL if the value is not yet kn...
bool hasLocalStorage() const
Returns true if a variable with function scope is a non-static local variable.
DefinitionKind hasDefinition(ASTContext &) const
Check whether this variable is defined in this translation unit.
bool isLocalVarDecl() const
Returns true for local variable declarations other than parameters.
bool isUsableInConstantExpressions(const ASTContext &C) const
Determine whether this variable's value can be used in a constant expression, according to the releva...
const Expr * getAnyInitializer() const
Get the initializer for this variable, no matter which declaration it is attached to.
Represents a GCC generic vector type.
unsigned getNumElements() const
QualType getElementType() const
WhileStmt - This represents a 'while' stmt.
VarDecl * getConditionVariable()
Retrieve the variable declared in this "while" statement, if any.
Base class for stack frames, shared between VM and walker.
Interface for the VM to interact with the AST walker's context.
Defines the clang::TargetInfo interface.
bool computeOSLogBufferLayout(clang::ASTContext &Ctx, const clang::CallExpr *E, OSLogBufferLayout &layout)
uint32_t Literal
Literals are represented as positive integers.
bool Call(InterpState &S, CodePtr OpPC, const Function *Func, uint32_t VarArgSize)
bool NE(InterpState &S, CodePtr OpPC)
llvm::FixedPointSemantics FixedPointSemantics
bool This(InterpState &S, CodePtr OpPC)
bool Zero(InterpState &S, CodePtr OpPC)
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.
bool operator==(const CallGraphNode::CallRecord &LHS, const CallGraphNode::CallRecord &RHS)
bool isLambdaCallWithExplicitObjectParameter(const DeclContext *DC)
UnaryExprOrTypeTrait
Names for the "expression or type" traits.
ComparisonCategoryResult
An enumeration representing the possible results of a three-way comparison.
CheckSubobjectKind
The order of this enum is important for diagnostics.
@ SD_Static
Static storage duration.
@ SD_FullExpression
Full-expression storage duration (for temporaries).
bool isLambdaCallOperator(const CXXMethodDecl *MD)
AccessKinds
Kinds of access we can perform on an object, for diagnostics.
@ AK_ReadObjectRepresentation
ActionResult< Expr * > ExprResult
CastKind
CastKind - The kind of operation required for a conversion.
llvm::hash_code hash_value(const CustomizableOptional< T > &O)
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
const FunctionProtoType * T
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs.
@ Success
Template argument deduction was successful.
@ None
The alignment was not explicit in code.
@ Class
The "class" keyword introduces the elaborated-type-specifier.
@ Other
Other implicit parameter.
Diagnostic wrappers for TextAPI types for error reporting.
hash_code hash_value(const clang::tooling::dependencies::ModuleID &ID)
unsigned PathLength
The corresponding path length in the lvalue.
const CXXRecordDecl * Type
The dynamic class type of the object.
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)