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;
1139 explicit operator bool()
const {
return FrameIndex != 0; };
1142 StdAllocatorCaller getStdAllocatorCaller(StringRef FnName)
const {
1143 for (
const CallStackFrame *
Call = CurrentCall;
Call != &BottomFrame;
1145 const auto *MD = dyn_cast_or_null<CXXMethodDecl>(
Call->Callee);
1149 if (!FnII || !FnII->
isStr(FnName))
1153 dyn_cast<ClassTemplateSpecializationDecl>(MD->getParent());
1159 if (CTSD->isInStdNamespace() && ClassII &&
1160 ClassII->
isStr(
"allocator") && TAL.
size() >= 1 &&
1162 return {
Call->Index, TAL[0].getAsType()};
1168 void performLifetimeExtension() {
1170 llvm::erase_if(CleanupStack, [](Cleanup &
C) {
1171 return !
C.isDestroyedAtEndOf(ScopeKind::FullExpression);
1178 bool discardCleanups() {
1179 for (Cleanup &
C : CleanupStack) {
1180 if (
C.hasSideEffect() && !noteSideEffect()) {
1181 CleanupStack.clear();
1185 CleanupStack.clear();
1190 interp::Frame *getCurrentFrame()
override {
return CurrentCall; }
1191 const interp::Frame *getBottomFrame()
const override {
return &BottomFrame; }
1193 bool hasActiveDiagnostic()
override {
return HasActiveDiagnostic; }
1194 void setActiveDiagnostic(
bool Flag)
override { HasActiveDiagnostic = Flag; }
1196 void setFoldFailureDiagnostic(
bool Flag)
override {
1197 HasFoldFailureDiagnostic = Flag;
1208 bool hasPriorDiagnostic()
override {
1209 if (!EvalStatus.
Diag->empty()) {
1211 case EM_ConstantFold:
1212 case EM_IgnoreSideEffects:
1213 if (!HasFoldFailureDiagnostic)
1217 case EM_ConstantExpression:
1218 case EM_ConstantExpressionUnevaluated:
1219 setActiveDiagnostic(
false);
1226 unsigned getCallStackDepth()
override {
return CallStackDepth; }
1231 bool keepEvaluatingAfterSideEffect()
const override {
1233 case EM_IgnoreSideEffects:
1236 case EM_ConstantExpression:
1237 case EM_ConstantExpressionUnevaluated:
1238 case EM_ConstantFold:
1241 return checkingPotentialConstantExpression() ||
1242 checkingForUndefinedBehavior();
1244 llvm_unreachable(
"Missed EvalMode case");
1249 bool noteSideEffect()
override {
1251 return keepEvaluatingAfterSideEffect();
1255 bool keepEvaluatingAfterUndefinedBehavior() {
1257 case EM_IgnoreSideEffects:
1258 case EM_ConstantFold:
1261 case EM_ConstantExpression:
1262 case EM_ConstantExpressionUnevaluated:
1263 return checkingForUndefinedBehavior();
1265 llvm_unreachable(
"Missed EvalMode case");
1271 bool noteUndefinedBehavior()
override {
1273 return keepEvaluatingAfterUndefinedBehavior();
1278 bool keepEvaluatingAfterFailure()
const override {
1283 case EM_ConstantExpression:
1284 case EM_ConstantExpressionUnevaluated:
1285 case EM_ConstantFold:
1286 case EM_IgnoreSideEffects:
1287 return checkingPotentialConstantExpression() ||
1288 checkingForUndefinedBehavior();
1290 llvm_unreachable(
"Missed EvalMode case");
1303 [[nodiscard]]
bool noteFailure() {
1311 bool KeepGoing = keepEvaluatingAfterFailure();
1316 class ArrayInitLoopIndex {
1321 ArrayInitLoopIndex(EvalInfo &Info)
1322 : Info(Info), OuterIndex(Info.ArrayInitIndex) {
1323 Info.ArrayInitIndex = 0;
1325 ~ArrayInitLoopIndex() { Info.ArrayInitIndex = OuterIndex; }
1327 operator uint64_t&() {
return Info.ArrayInitIndex; }
1332 struct FoldConstant {
1335 bool HadNoPriorDiags;
1336 EvalInfo::EvaluationMode OldMode;
1338 explicit FoldConstant(EvalInfo &Info,
bool Enabled)
1341 HadNoPriorDiags(Info.EvalStatus.
Diag &&
1342 Info.EvalStatus.
Diag->empty() &&
1343 !Info.EvalStatus.HasSideEffects),
1344 OldMode(Info.EvalMode) {
1346 Info.EvalMode = EvalInfo::EM_ConstantFold;
1348 void keepDiagnostics() { Enabled =
false; }
1350 if (Enabled && HadNoPriorDiags && !Info.EvalStatus.Diag->empty() &&
1351 !Info.EvalStatus.HasSideEffects)
1352 Info.EvalStatus.Diag->clear();
1353 Info.EvalMode = OldMode;
1359 struct IgnoreSideEffectsRAII {
1361 EvalInfo::EvaluationMode OldMode;
1362 explicit IgnoreSideEffectsRAII(EvalInfo &Info)
1363 : Info(Info), OldMode(Info.EvalMode) {
1364 Info.EvalMode = EvalInfo::EM_IgnoreSideEffects;
1367 ~IgnoreSideEffectsRAII() { Info.EvalMode = OldMode; }
1372 class SpeculativeEvaluationRAII {
1373 EvalInfo *Info =
nullptr;
1375 unsigned OldSpeculativeEvaluationDepth = 0;
1377 void moveFromAndCancel(SpeculativeEvaluationRAII &&
Other) {
1379 OldStatus =
Other.OldStatus;
1380 OldSpeculativeEvaluationDepth =
Other.OldSpeculativeEvaluationDepth;
1381 Other.Info =
nullptr;
1384 void maybeRestoreState() {
1388 Info->EvalStatus = OldStatus;
1389 Info->SpeculativeEvaluationDepth = OldSpeculativeEvaluationDepth;
1393 SpeculativeEvaluationRAII() =
default;
1395 SpeculativeEvaluationRAII(
1397 : Info(&Info), OldStatus(Info.EvalStatus),
1398 OldSpeculativeEvaluationDepth(Info.SpeculativeEvaluationDepth) {
1399 Info.EvalStatus.Diag = NewDiag;
1400 Info.SpeculativeEvaluationDepth = Info.CallStackDepth + 1;
1403 SpeculativeEvaluationRAII(
const SpeculativeEvaluationRAII &
Other) =
delete;
1404 SpeculativeEvaluationRAII(SpeculativeEvaluationRAII &&
Other) {
1405 moveFromAndCancel(std::move(
Other));
1408 SpeculativeEvaluationRAII &operator=(SpeculativeEvaluationRAII &&
Other) {
1409 maybeRestoreState();
1410 moveFromAndCancel(std::move(
Other));
1414 ~SpeculativeEvaluationRAII() { maybeRestoreState(); }
1419 template<ScopeKind Kind>
1422 unsigned OldStackSize;
1424 ScopeRAII(EvalInfo &Info)
1425 : Info(Info), OldStackSize(Info.CleanupStack.size()) {
1428 Info.CurrentCall->pushTempVersion();
1430 bool destroy(
bool RunDestructors =
true) {
1431 bool OK =
cleanup(Info, RunDestructors, OldStackSize);
1436 if (OldStackSize != -1U)
1440 Info.CurrentCall->popTempVersion();
1443 static bool cleanup(EvalInfo &Info,
bool RunDestructors,
1444 unsigned OldStackSize) {
1445 assert(OldStackSize <= Info.CleanupStack.size() &&
1446 "running cleanups out of order?");
1451 for (
unsigned I = Info.CleanupStack.size(); I > OldStackSize; --I) {
1452 if (Info.CleanupStack[I - 1].isDestroyedAtEndOf(Kind)) {
1453 if (!Info.CleanupStack[I - 1].endLifetime(Info, RunDestructors)) {
1461 auto NewEnd = Info.CleanupStack.begin() + OldStackSize;
1462 if (Kind != ScopeKind::Block)
1464 std::remove_if(NewEnd, Info.CleanupStack.end(), [](Cleanup &
C) {
1465 return C.isDestroyedAtEndOf(Kind);
1467 Info.CleanupStack.erase(NewEnd, Info.CleanupStack.end());
1471 typedef ScopeRAII<ScopeKind::Block> BlockScopeRAII;
1472 typedef ScopeRAII<ScopeKind::FullExpression> FullExpressionRAII;
1473 typedef ScopeRAII<ScopeKind::Call> CallScopeRAII;
1476bool SubobjectDesignator::checkSubobject(EvalInfo &Info,
const Expr *
E,
1480 if (isOnePastTheEnd()) {
1481 Info.CCEDiag(
E, diag::note_constexpr_past_end_subobject)
1492void SubobjectDesignator::diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info,
1494 Info.CCEDiag(
E, diag::note_constexpr_unsized_array_indexed);
1499void SubobjectDesignator::diagnosePointerArithmetic(EvalInfo &Info,
1504 if (MostDerivedPathLength == Entries.size() && MostDerivedIsArrayElement)
1505 Info.CCEDiag(
E, diag::note_constexpr_array_index)
1507 <<
static_cast<unsigned>(getMostDerivedArraySize());
1509 Info.CCEDiag(
E, diag::note_constexpr_array_index)
1514CallStackFrame::CallStackFrame(EvalInfo &Info,
SourceRange CallRange,
1519 Index(Info.NextCallIndex++) {
1520 Info.CurrentCall =
this;
1521 ++Info.CallStackDepth;
1524CallStackFrame::~CallStackFrame() {
1525 assert(Info.CurrentCall ==
this &&
"calls retired out of order");
1526 --Info.CallStackDepth;
1527 Info.CurrentCall = Caller;
1551 llvm_unreachable(
"unknown access kind");
1587 llvm_unreachable(
"unknown access kind");
1591 struct ComplexValue {
1599 ComplexValue() : FloatReal(
APFloat::Bogus()), FloatImag(
APFloat::Bogus()) {}
1601 void makeComplexFloat() { IsInt =
false; }
1602 bool isComplexFloat()
const {
return !IsInt; }
1603 APFloat &getComplexFloatReal() {
return FloatReal; }
1604 APFloat &getComplexFloatImag() {
return FloatImag; }
1606 void makeComplexInt() { IsInt =
true; }
1607 bool isComplexInt()
const {
return IsInt; }
1608 APSInt &getComplexIntReal() {
return IntReal; }
1609 APSInt &getComplexIntImag() {
return IntImag; }
1612 if (isComplexFloat())
1618 assert(
v.isComplexFloat() ||
v.isComplexInt());
1619 if (
v.isComplexFloat()) {
1621 FloatReal =
v.getComplexFloatReal();
1622 FloatImag =
v.getComplexFloatImag();
1625 IntReal =
v.getComplexIntReal();
1626 IntImag =
v.getComplexIntImag();
1636 bool InvalidBase : 1;
1638 bool AllowConstexprUnknown =
false;
1641 bool allowConstexprUnknown()
const {
return AllowConstexprUnknown; }
1642 CharUnits &getLValueOffset() {
return Offset; }
1643 const CharUnits &getLValueOffset()
const {
return Offset; }
1644 SubobjectDesignator &getLValueDesignator() {
return Designator; }
1645 const SubobjectDesignator &getLValueDesignator()
const {
return Designator;}
1646 bool isNullPointer()
const {
return IsNullPtr;}
1648 unsigned getLValueCallIndex()
const {
return Base.getCallIndex(); }
1649 unsigned getLValueVersion()
const {
return Base.getVersion(); }
1655 assert(!InvalidBase &&
"APValues can't handle invalid LValue bases");
1659 if (AllowConstexprUnknown)
1660 V.setConstexprUnknown();
1663 assert(
V.isLValue() &&
"Setting LValue from a non-LValue?");
1664 Base =
V.getLValueBase();
1665 Offset =
V.getLValueOffset();
1666 InvalidBase =
false;
1668 IsNullPtr =
V.isNullPointer();
1669 AllowConstexprUnknown =
V.allowConstexprUnknown();
1676 const auto *
E = B.
get<
const Expr *>();
1677 assert((isa<MemberExpr>(
E) || tryUnwrapAllocSizeCall(
E)) &&
1678 "Unexpected type of invalid base");
1684 InvalidBase = BInvalid;
1685 Designator = SubobjectDesignator(getType(B));
1687 AllowConstexprUnknown =
false;
1694 InvalidBase =
false;
1697 AllowConstexprUnknown =
false;
1706 moveInto(Printable);
1713 template <
typename GenDiagType>
1714 bool checkNullPointerDiagnosingWith(
const GenDiagType &GenDiag) {
1726 bool checkNullPointer(EvalInfo &Info,
const Expr *
E,
1728 return checkNullPointerDiagnosingWith([&Info,
E, CSK] {
1729 Info.CCEDiag(
E, diag::note_constexpr_null_subobject) << CSK;
1733 bool checkNullPointerForFoldAccess(EvalInfo &Info,
const Expr *
E,
1735 return checkNullPointerDiagnosingWith([&Info,
E, AK] {
1736 Info.FFDiag(
E, diag::note_constexpr_access_null) << AK;
1747 void addDecl(EvalInfo &Info,
const Expr *
E,
1752 void addUnsizedArray(EvalInfo &Info,
const Expr *
E,
QualType ElemTy) {
1754 Info.CCEDiag(
E, diag::note_constexpr_unsupported_unsized_array);
1759 assert(getType(
Base)->isPointerType() || getType(
Base)->isArrayType());
1760 Designator.FirstEntryIsAnUnsizedArray =
true;
1768 void addComplex(EvalInfo &Info,
const Expr *
E,
QualType EltTy,
bool Imag) {
1772 void addVectorElement(EvalInfo &Info,
const Expr *
E,
QualType EltTy,
1773 uint64_t Size, uint64_t Idx) {
1775 Designator.addVectorElementUnchecked(EltTy, Size, Idx);
1777 void clearIsNullPointer() {
1780 void adjustOffsetAndIndex(EvalInfo &Info,
const Expr *
E,
1790 uint64_t Offset64 = Offset.getQuantity();
1792 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
1797 clearIsNullPointer();
1802 clearIsNullPointer();
1809 : DeclAndIsDerivedMember(
Decl,
false) {}
1814 return DeclAndIsDerivedMember.getPointer();
1817 bool isDerivedMember()
const {
1818 return DeclAndIsDerivedMember.getInt();
1822 return cast<CXXRecordDecl>(
1823 DeclAndIsDerivedMember.getPointer()->getDeclContext());
1830 assert(
V.isMemberPointer());
1831 DeclAndIsDerivedMember.setPointer(
V.getMemberPointerDecl());
1832 DeclAndIsDerivedMember.setInt(
V.isMemberPointerToDerivedMember());
1841 llvm::PointerIntPair<const ValueDecl*, 1, bool> DeclAndIsDerivedMember;
1849 assert(!
Path.empty());
1851 if (
Path.size() >= 2)
1855 if (
Expected->getCanonicalDecl() !=
Class->getCanonicalDecl()) {
1871 if (!isDerivedMember()) {
1872 Path.push_back(Derived);
1875 if (!castBack(Derived))
1878 DeclAndIsDerivedMember.setInt(
false);
1886 DeclAndIsDerivedMember.setInt(
true);
1887 if (isDerivedMember()) {
1891 return castBack(
Base);
1896 static bool operator==(
const MemberPtr &LHS,
const MemberPtr &RHS) {
1897 if (!LHS.getDecl() || !RHS.getDecl())
1898 return !LHS.getDecl() && !RHS.getDecl();
1899 if (LHS.getDecl()->getCanonicalDecl() != RHS.getDecl()->getCanonicalDecl())
1901 return LHS.Path == RHS.Path;
1907 const LValue &This,
const Expr *
E,
1908 bool AllowNonLiteralTypes =
false);
1910 bool InvalidBaseOK =
false);
1912 bool InvalidBaseOK =
false);
1926 std::string *StringResult =
nullptr);
1943 if (Int.isUnsigned() || Int.isMinSignedValue()) {
1944 Int = Int.extend(Int.getBitWidth() + 1);
1945 Int.setIsSigned(
true);
1950template<
typename KeyT>
1952 ScopeKind
Scope, LValue &LV) {
1953 unsigned Version = getTempVersion();
1960CallStackFrame::createConstexprUnknownAPValues(
const VarDecl *Key,
1962 APValue &Result = ConstexprUnknownAPValues[MapKeyTy(Key,
Base.getVersion())];
1971 assert(Args.CallIndex == Index &&
"creating parameter in wrong frame");
1977 return createLocal(
Base, PVD, PVD->
getType(), ScopeKind::Call);
1982 assert(
Base.getCallIndex() == Index &&
"lvalue for wrong frame");
1983 unsigned Version =
Base.getVersion();
1984 APValue &Result = Temporaries[MapKeyTy(Key, Version)];
1985 assert(Result.isAbsent() &&
"local created multiple times");
1991 if (Index <= Info.SpeculativeEvaluationDepth) {
1992 if (
T.isDestructedType())
1993 Info.noteSideEffect();
1995 Info.CleanupStack.push_back(Cleanup(&Result,
Base,
T,
Scope));
2002 FFDiag(
E, diag::note_constexpr_heap_alloc_limit_exceeded);
2008 auto Result = HeapAllocs.emplace(std::piecewise_construct,
2009 std::forward_as_tuple(DA), std::tuple<>());
2010 assert(Result.second &&
"reused a heap alloc index?");
2011 Result.first->second.AllocExpr =
E;
2012 return &Result.first->second.Value;
2016void CallStackFrame::describe(raw_ostream &Out)
const {
2017 unsigned ArgIndex = 0;
2019 isa<CXXMethodDecl>(Callee) && !isa<CXXConstructorDecl>(Callee) &&
2020 cast<CXXMethodDecl>(Callee)->isImplicitObjectMemberFunction();
2023 Callee->getNameForDiagnostic(Out, Info.Ctx.getPrintingPolicy(),
2026 if (This && IsMemberCall) {
2027 if (
const auto *MCE = dyn_cast_if_present<CXXMemberCallExpr>(
CallExpr)) {
2028 const Expr *
Object = MCE->getImplicitObjectArgument();
2029 Object->printPretty(Out,
nullptr, Info.Ctx.getPrintingPolicy(),
2031 if (
Object->getType()->isPointerType())
2035 }
else if (
const auto *OCE =
2036 dyn_cast_if_present<CXXOperatorCallExpr>(
CallExpr)) {
2037 OCE->getArg(0)->printPretty(Out,
nullptr,
2038 Info.Ctx.getPrintingPolicy(),
2043 This->moveInto(Val);
2046 Info.Ctx.getLValueReferenceType(
This->Designator.MostDerivedType));
2049 Callee->getNameForDiagnostic(Out, Info.Ctx.getPrintingPolicy(),
2051 IsMemberCall =
false;
2057 E =
Callee->param_end(); I !=
E; ++I, ++ArgIndex) {
2058 if (ArgIndex > (
unsigned)IsMemberCall)
2062 APValue *
V = Info.getParamSlot(Arguments, Param);
2064 V->printPretty(Out, Info.Ctx, Param->
getType());
2068 if (ArgIndex == 0 && IsMemberCall)
2069 Out <<
"->" << *
Callee <<
'(';
2083 return Info.noteSideEffect();
2089 unsigned Builtin =
E->getBuiltinCallee();
2090 return (Builtin == Builtin::BI__builtin___CFStringMakeConstantString ||
2091 Builtin == Builtin::BI__builtin___NSStringMakeConstantString ||
2092 Builtin == Builtin::BI__builtin_ptrauth_sign_constant ||
2093 Builtin == Builtin::BI__builtin_function_start);
2097 const auto *BaseExpr =
2098 llvm::dyn_cast_if_present<CallExpr>(LVal.Base.dyn_cast<
const Expr *>());
2113 if (
const VarDecl *VD = dyn_cast<VarDecl>(
D))
2114 return VD->hasGlobalStorage();
2115 if (isa<TemplateParamObjectDecl>(
D))
2120 return isa<FunctionDecl, MSGuidDecl, UnnamedGlobalConstantDecl>(
D);
2130 case Expr::CompoundLiteralExprClass: {
2134 case Expr::MaterializeTemporaryExprClass:
2137 return cast<MaterializeTemporaryExpr>(
E)->getStorageDuration() ==
SD_Static;
2139 case Expr::StringLiteralClass:
2140 case Expr::PredefinedExprClass:
2141 case Expr::ObjCStringLiteralClass:
2142 case Expr::ObjCEncodeExprClass:
2144 case Expr::ObjCBoxedExprClass:
2145 return cast<ObjCBoxedExpr>(
E)->isExpressibleAsConstantInitializer();
2146 case Expr::CallExprClass:
2149 case Expr::AddrLabelExprClass:
2153 case Expr::BlockExprClass:
2154 return !cast<BlockExpr>(
E)->getBlockDecl()->hasCaptures();
2157 case Expr::SourceLocExprClass:
2159 case Expr::ImplicitValueInitExprClass:
2171 return LVal.Base.dyn_cast<
const ValueDecl*>();
2184 const auto *BaseExpr = LVal.Base.dyn_cast<
const Expr *>();
2189 if (
const auto *EE = dyn_cast<ObjCEncodeExpr>(BaseExpr)) {
2190 Info.Ctx.getObjCEncodingForType(EE->getEncodedType(),
2198 const auto *Lit = dyn_cast<StringLiteral>(BaseExpr);
2199 if (
const auto *PE = dyn_cast<PredefinedExpr>(BaseExpr))
2200 Lit = PE->getFunctionName();
2205 AsString.
Bytes = Lit->getBytes();
2206 AsString.
CharWidth = Lit->getCharByteWidth();
2226 const LValue &RHS) {
2235 CharUnits Offset = RHS.Offset - LHS.Offset;
2236 if (Offset.isNegative())
2237 LHSString.
Bytes = LHSString.
Bytes.drop_front(-Offset.getQuantity());
2239 RHSString.
Bytes = RHSString.
Bytes.drop_front(Offset.getQuantity());
2241 bool LHSIsLonger = LHSString.
Bytes.size() > RHSString.
Bytes.size();
2242 StringRef Longer = LHSIsLonger ? LHSString.
Bytes : RHSString.
Bytes;
2243 StringRef Shorter = LHSIsLonger ? RHSString.
Bytes : LHSString.
Bytes;
2244 int ShorterCharWidth = (LHSIsLonger ? RHSString : LHSString).CharWidth;
2249 for (
int NullByte : llvm::seq(ShorterCharWidth)) {
2250 if (Shorter.size() + NullByte >= Longer.size())
2252 if (Longer[Shorter.size() + NullByte])
2258 return Shorter == Longer.take_front(Shorter.size());
2268 if (isa_and_nonnull<VarDecl>(
Decl)) {
2278 if (!A.getLValueBase())
2279 return !B.getLValueBase();
2280 if (!B.getLValueBase())
2283 if (A.getLValueBase().getOpaqueValue() !=
2284 B.getLValueBase().getOpaqueValue())
2287 return A.getLValueCallIndex() == B.getLValueCallIndex() &&
2288 A.getLValueVersion() == B.getLValueVersion();
2292 assert(
Base &&
"no location for a null lvalue");
2298 if (
auto *PVD = dyn_cast_or_null<ParmVarDecl>(VD)) {
2300 for (CallStackFrame *F = Info.CurrentCall; F; F = F->Caller) {
2301 if (F->Arguments.CallIndex ==
Base.getCallIndex() &&
2302 F->Arguments.Version ==
Base.getVersion() && F->Callee &&
2303 Idx < F->Callee->getNumParams()) {
2304 VD = F->Callee->getParamDecl(Idx);
2311 Info.Note(VD->
getLocation(), diag::note_declared_at);
2313 Info.Note(
E->
getExprLoc(), diag::note_constexpr_temporary_here);
2316 if (std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA))
2317 Info.Note((*Alloc)->AllocExpr->getExprLoc(),
2318 diag::note_constexpr_dynamic_alloc_here);
2351 const SubobjectDesignator &
Designator = LVal.getLValueDesignator();
2359 if (isTemplateArgument(Kind)) {
2360 int InvalidBaseKind = -1;
2363 InvalidBaseKind = 0;
2364 else if (isa_and_nonnull<StringLiteral>(BaseE))
2365 InvalidBaseKind = 1;
2366 else if (isa_and_nonnull<MaterializeTemporaryExpr>(BaseE) ||
2367 isa_and_nonnull<LifetimeExtendedTemporaryDecl>(BaseVD))
2368 InvalidBaseKind = 2;
2369 else if (
auto *PE = dyn_cast_or_null<PredefinedExpr>(BaseE)) {
2370 InvalidBaseKind = 3;
2371 Ident = PE->getIdentKindName();
2374 if (InvalidBaseKind != -1) {
2375 Info.FFDiag(
Loc, diag::note_constexpr_invalid_template_arg)
2376 << IsReferenceType << !
Designator.Entries.empty() << InvalidBaseKind
2382 if (
auto *FD = dyn_cast_or_null<FunctionDecl>(BaseVD);
2383 FD && FD->isImmediateFunction()) {
2384 Info.FFDiag(
Loc, diag::note_consteval_address_accessible)
2386 Info.Note(FD->getLocation(), diag::note_declared_at);
2394 if (Info.getLangOpts().CPlusPlus11) {
2395 Info.FFDiag(
Loc, diag::note_constexpr_non_global, 1)
2396 << IsReferenceType << !
Designator.Entries.empty() << !!BaseVD
2398 auto *VarD = dyn_cast_or_null<VarDecl>(BaseVD);
2399 if (VarD && VarD->isConstexpr()) {
2405 Info.Note(VarD->getLocation(), diag::note_constexpr_not_static)
2417 assert((Info.checkingPotentialConstantExpression() ||
2418 LVal.getLValueCallIndex() == 0) &&
2419 "have call index for global lvalue");
2422 Info.FFDiag(
Loc, diag::note_constexpr_dynamic_alloc)
2423 << IsReferenceType << !
Designator.Entries.empty();
2429 if (
const VarDecl *Var = dyn_cast<const VarDecl>(BaseVD)) {
2431 if (Var->getTLSKind())
2437 if (!isForManglingOnly(Kind) && Var->hasAttr<DLLImportAttr>())
2443 if (Info.getASTContext().getLangOpts().CUDA &&
2444 Info.getASTContext().getLangOpts().CUDAIsDevice &&
2445 Info.getASTContext().CUDAConstantEvalCtx.NoWrongSidedVars) {
2446 if ((!Var->hasAttr<CUDADeviceAttr>() &&
2447 !Var->hasAttr<CUDAConstantAttr>() &&
2448 !Var->getType()->isCUDADeviceBuiltinSurfaceType() &&
2449 !Var->getType()->isCUDADeviceBuiltinTextureType()) ||
2450 Var->hasAttr<HIPManagedAttr>())
2454 if (
const auto *FD = dyn_cast<const FunctionDecl>(BaseVD)) {
2465 if (Info.getLangOpts().CPlusPlus && !isForManglingOnly(Kind) &&
2466 FD->hasAttr<DLLImportAttr>())
2470 }
else if (
const auto *MTE =
2471 dyn_cast_or_null<MaterializeTemporaryExpr>(BaseE)) {
2472 if (CheckedTemps.insert(MTE).second) {
2475 Info.FFDiag(MTE->getExprLoc(),
2476 diag::note_constexpr_unsupported_temporary_nontrivial_dtor)
2481 APValue *
V = MTE->getOrCreateValue(
false);
2482 assert(
V &&
"evasluation result refers to uninitialised temporary");
2484 Info, MTE->getExprLoc(), TempType, *
V, Kind,
2485 nullptr, CheckedTemps))
2492 if (!IsReferenceType)
2504 Info.FFDiag(
Loc, diag::note_constexpr_past_end, 1)
2505 << !
Designator.Entries.empty() << !!BaseVD << BaseVD;
2520 const auto *FD = dyn_cast_or_null<CXXMethodDecl>(
Member);
2523 if (FD->isImmediateFunction()) {
2524 Info.FFDiag(
Loc, diag::note_consteval_address_accessible) << 0;
2525 Info.Note(FD->getLocation(), diag::note_declared_at);
2528 return isForManglingOnly(Kind) || FD->isVirtual() ||
2529 !FD->hasAttr<DLLImportAttr>();
2535 const LValue *This =
nullptr) {
2537 if (Info.getLangOpts().CPlusPlus23)
2556 if (This && Info.EvaluatingDecl == This->getLValueBase())
2560 if (Info.getLangOpts().CPlusPlus11)
2561 Info.FFDiag(
E, diag::note_constexpr_nonliteral)
2564 Info.FFDiag(
E, diag::note_invalid_subexpr_in_const_expr);
2575 if (SubobjectDecl) {
2576 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
2577 << 1 << SubobjectDecl;
2579 diag::note_constexpr_subobject_declared_here);
2581 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
2590 Type = AT->getValueType();
2595 if (
Value.isArray()) {
2597 for (
unsigned I = 0, N =
Value.getArrayInitializedElts(); I != N; ++I) {
2599 Value.getArrayInitializedElt(I), Kind,
2600 SubobjectDecl, CheckedTemps))
2603 if (!
Value.hasArrayFiller())
2606 Value.getArrayFiller(), Kind, SubobjectDecl,
2609 if (
Value.isUnion() &&
Value.getUnionField()) {
2612 Value.getUnionValue(), Kind,
Value.getUnionField(), CheckedTemps);
2614 if (
Value.isStruct()) {
2616 if (
const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {
2617 unsigned BaseIndex = 0;
2619 const APValue &BaseValue =
Value.getStructBase(BaseIndex);
2622 Info.FFDiag(TypeBeginLoc, diag::note_constexpr_uninitialized_base)
2623 << BS.getType() <<
SourceRange(TypeBeginLoc, BS.getEndLoc());
2633 for (
const auto *I : RD->
fields()) {
2634 if (I->isUnnamedBitField())
2638 Value.getStructField(I->getFieldIndex()), Kind,
2644 if (
Value.isLValue() &&
2645 CERK == CheckEvaluationResultKind::ConstantExpression) {
2647 LVal.setFrom(Info.Ctx,
Value);
2652 if (
Value.isMemberPointer() &&
2653 CERK == CheckEvaluationResultKind::ConstantExpression)
2673 nullptr, CheckedTemps);
2682 CheckEvaluationResultKind::FullyInitialized, Info, DiagLoc,
Type,
Value,
2683 ConstantExprKind::Normal,
nullptr, CheckedTemps);
2689 if (!Info.HeapAllocs.empty()) {
2693 Info.CCEDiag(Info.HeapAllocs.begin()->second.AllocExpr,
2694 diag::note_constexpr_memory_leak)
2695 <<
unsigned(Info.HeapAllocs.size() - 1);
2703 if (!
Value.getLValueBase()) {
2705 Result = !
Value.getLValueOffset().isZero();
2723 Result = Val.
getInt().getBoolValue();
2755 llvm_unreachable(
"unknown APValue kind");
2761 assert(
E->
isPRValue() &&
"missing lvalue-to-rvalue conv in bool condition");
2771 Info.CCEDiag(
E, diag::note_constexpr_overflow)
2772 << SrcValue << DestType;
2773 return Info.noteUndefinedBehavior();
2779 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
2783 Result =
APSInt(DestWidth, !DestSigned);
2785 if (
Value.convertToInteger(Result, llvm::APFloat::rmTowardZero, &ignored)
2786 & APFloat::opInvalidOp)
2797 llvm::RoundingMode RM =
2799 if (RM == llvm::RoundingMode::Dynamic)
2800 RM = llvm::RoundingMode::NearestTiesToEven;
2806 APFloat::opStatus St) {
2809 if (Info.InConstantContext)
2813 if ((St & APFloat::opInexact) &&
2817 Info.FFDiag(
E, diag::note_constexpr_dynamic_rounding);
2821 if ((St != APFloat::opOK) &&
2824 FPO.getAllowFEnvAccess())) {
2825 Info.FFDiag(
E, diag::note_constexpr_float_arithmetic_strict);
2829 if ((St & APFloat::opStatus::opInvalidOp) &&
2848 assert((isa<CastExpr>(
E) || isa<CompoundAssignOperator>(
E) ||
2849 isa<ConvertVectorExpr>(
E)) &&
2850 "HandleFloatToFloatCast has been checked with only CastExpr, "
2851 "CompoundAssignOperator and ConvertVectorExpr. Please either validate "
2852 "the new expression or address the root cause of this usage.");
2854 APFloat::opStatus St;
2855 APFloat
Value = Result;
2857 St = Result.convert(Info.Ctx.getFloatTypeSemantics(DestType), RM, &ignored);
2864 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
2870 Result =
Value.getBoolValue();
2877 QualType DestType, APFloat &Result) {
2878 Result = APFloat(Info.Ctx.getFloatTypeSemantics(DestType), 1);
2880 APFloat::opStatus St = Result.convertFromAPInt(
Value,
Value.isSigned(), RM);
2886 assert(FD->
isBitField() &&
"truncateBitfieldValue on non-bitfield");
2888 if (!
Value.isInt()) {
2892 assert(
Value.isLValue() &&
"integral value neither int nor lvalue?");
2898 unsigned OldBitWidth = Int.getBitWidth();
2900 if (NewBitWidth < OldBitWidth)
2901 Int = Int.trunc(NewBitWidth).extend(OldBitWidth);
2908template<
typename Operation>
2911 unsigned BitWidth, Operation Op,
2913 if (LHS.isUnsigned()) {
2914 Result = Op(LHS, RHS);
2918 APSInt Value(Op(LHS.extend(BitWidth), RHS.extend(BitWidth)),
false);
2919 Result =
Value.trunc(LHS.getBitWidth());
2920 if (Result.extend(BitWidth) !=
Value) {
2921 if (Info.checkingForUndefinedBehavior())
2923 diag::warn_integer_constant_overflow)
2924 <<
toString(Result, 10, Result.isSigned(),
false,
2936 bool HandleOverflowResult =
true;
2943 std::multiplies<APSInt>(), Result);
2946 std::plus<APSInt>(), Result);
2949 std::minus<APSInt>(), Result);
2950 case BO_And: Result = LHS & RHS;
return true;
2951 case BO_Xor: Result = LHS ^ RHS;
return true;
2952 case BO_Or: Result = LHS | RHS;
return true;
2956 Info.FFDiag(
E, diag::note_expr_divide_by_zero)
2962 if (RHS.isNegative() && RHS.isAllOnes() && LHS.isSigned() &&
2963 LHS.isMinSignedValue())
2965 Info,
E, -LHS.extend(LHS.getBitWidth() + 1),
E->
getType());
2966 Result = (Opcode == BO_Rem ? LHS % RHS : LHS / RHS);
2967 return HandleOverflowResult;
2969 if (Info.getLangOpts().OpenCL)
2971 RHS &=
APSInt(llvm::APInt(RHS.getBitWidth(),
2972 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2974 else if (RHS.isSigned() && RHS.isNegative()) {
2977 Info.CCEDiag(
E, diag::note_constexpr_negative_shift) << RHS;
2978 if (!Info.noteUndefinedBehavior())
2986 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
2988 Info.CCEDiag(
E, diag::note_constexpr_large_shift)
2989 << RHS <<
E->
getType() << LHS.getBitWidth();
2990 if (!Info.noteUndefinedBehavior())
2992 }
else if (LHS.isSigned() && !Info.getLangOpts().CPlusPlus20) {
2997 if (LHS.isNegative()) {
2998 Info.CCEDiag(
E, diag::note_constexpr_lshift_of_negative) << LHS;
2999 if (!Info.noteUndefinedBehavior())
3001 }
else if (LHS.countl_zero() < SA) {
3002 Info.CCEDiag(
E, diag::note_constexpr_lshift_discards);
3003 if (!Info.noteUndefinedBehavior())
3011 if (Info.getLangOpts().OpenCL)
3013 RHS &=
APSInt(llvm::APInt(RHS.getBitWidth(),
3014 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
3016 else if (RHS.isSigned() && RHS.isNegative()) {
3019 Info.CCEDiag(
E, diag::note_constexpr_negative_shift) << RHS;
3020 if (!Info.noteUndefinedBehavior())
3028 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
3030 Info.CCEDiag(
E, diag::note_constexpr_large_shift)
3031 << RHS <<
E->
getType() << LHS.getBitWidth();
3032 if (!Info.noteUndefinedBehavior())
3040 case BO_LT: Result = LHS < RHS;
return true;
3041 case BO_GT: Result = LHS > RHS;
return true;
3042 case BO_LE: Result = LHS <= RHS;
return true;
3043 case BO_GE: Result = LHS >= RHS;
return true;
3044 case BO_EQ: Result = LHS == RHS;
return true;
3045 case BO_NE: Result = LHS != RHS;
return true;
3047 llvm_unreachable(
"BO_Cmp should be handled elsewhere");
3054 const APFloat &RHS) {
3056 APFloat::opStatus St;
3062 St = LHS.multiply(RHS, RM);
3065 St = LHS.add(RHS, RM);
3068 St = LHS.subtract(RHS, RM);
3074 Info.CCEDiag(
E, diag::note_expr_divide_by_zero);
3075 St = LHS.divide(RHS, RM);
3084 Info.CCEDiag(
E, diag::note_constexpr_float_arithmetic) << LHS.isNaN();
3085 return Info.noteUndefinedBehavior();
3093 const APInt &RHSValue, APInt &Result) {
3094 bool LHS = (LHSValue != 0);
3095 bool RHS = (RHSValue != 0);
3097 if (Opcode == BO_LAnd)
3098 Result = LHS && RHS;
3100 Result = LHS || RHS;
3105 const APFloat &RHSValue, APInt &Result) {
3106 bool LHS = !LHSValue.isZero();
3107 bool RHS = !RHSValue.isZero();
3109 if (Opcode == BO_LAnd)
3110 Result = LHS && RHS;
3112 Result = LHS || RHS;
3118 const APValue &RHSValue, APInt &Result) {
3122 RHSValue.
getInt(), Result);
3128template <
typename APTy>
3131 const APTy &RHSValue, APInt &Result) {
3134 llvm_unreachable(
"unsupported binary operator");
3136 Result = (LHSValue == RHSValue);
3139 Result = (LHSValue != RHSValue);
3142 Result = (LHSValue < RHSValue);
3145 Result = (LHSValue > RHSValue);
3148 Result = (LHSValue <= RHSValue);
3151 Result = (LHSValue >= RHSValue);
3165 const APValue &RHSValue, APInt &Result) {
3169 RHSValue.
getInt(), Result);
3180 assert(Opcode != BO_PtrMemD && Opcode != BO_PtrMemI &&
3181 "Operation not supported on vector types");
3185 QualType EltTy = VT->getElementType();
3192 "A vector result that isn't a vector OR uncalculated LValue");
3198 RHSValue.
getVectorLength() == NumElements &&
"Different vector sizes");
3202 for (
unsigned EltNum = 0; EltNum < NumElements; ++EltNum) {
3207 APSInt EltResult{Info.Ctx.getIntWidth(EltTy),
3217 RHSElt.
getInt(), EltResult);
3223 ResultElements.emplace_back(EltResult);
3228 "Mismatched LHS/RHS/Result Type");
3229 APFloat LHSFloat = LHSElt.
getFloat();
3237 ResultElements.emplace_back(LHSFloat);
3241 LHSValue =
APValue(ResultElements.data(), ResultElements.size());
3249 unsigned TruncatedElements) {
3250 SubobjectDesignator &
D = Result.Designator;
3253 if (TruncatedElements ==
D.Entries.size())
3255 assert(TruncatedElements >=
D.MostDerivedPathLength &&
3256 "not casting to a derived class");
3262 for (
unsigned I = TruncatedElements, N =
D.Entries.size(); I != N; ++I) {
3266 if (isVirtualBaseClass(
D.Entries[I]))
3272 D.Entries.resize(TruncatedElements);
3282 RL = &Info.Ctx.getASTRecordLayout(Derived);
3285 Obj.addDecl(Info,
E,
Base,
false);
3286 Obj.getLValueOffset() += RL->getBaseClassOffset(
Base);
3295 if (!
Base->isVirtual())
3298 SubobjectDesignator &
D = Obj.Designator;
3303 DerivedDecl =
D.MostDerivedType->getAsCXXRecordDecl();
3309 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(DerivedDecl);
3310 Obj.addDecl(Info,
E, BaseDecl,
true);
3318 PathE =
E->path_end();
3319 PathI != PathE; ++PathI) {
3323 Type = (*PathI)->getType();
3335 llvm_unreachable(
"Class must be derived from the passed in base class!");
3350 RL = &Info.Ctx.getASTRecordLayout(FD->
getParent());
3354 LVal.addDecl(Info,
E, FD);
3355 LVal.adjustOffset(Info.Ctx.toCharUnitsFromBits(RL->getFieldOffset(I)));
3363 for (
const auto *
C : IFD->
chain())
3396 if (SOT == SizeOfType::SizeOf)
3397 Size = Info.Ctx.getTypeSizeInChars(
Type);
3399 Size = Info.Ctx.getTypeInfoDataSizeInChars(
Type).Width;
3416 LVal.adjustOffsetAndIndex(Info,
E, Adjustment, SizeOfPointee);
3422 int64_t Adjustment) {
3424 APSInt::get(Adjustment));
3439 LVal.Offset += SizeOfComponent;
3441 LVal.addComplex(Info,
E, EltTy, Imag);
3447 uint64_t Size, uint64_t Idx) {
3452 LVal.Offset += SizeOfElement * Idx;
3454 LVal.addVectorElement(Info,
E, EltTy, Size, Idx);
3468 const VarDecl *VD, CallStackFrame *Frame,
3469 unsigned Version,
APValue *&Result) {
3472 bool AllowConstexprUnknown =
3479 Result = Frame->getTemporary(VD, Version);
3483 if (!isa<ParmVarDecl>(VD)) {
3490 "missing value for local variable");
3491 if (Info.checkingPotentialConstantExpression())
3496 diag::note_unimplemented_constexpr_lambda_feature_ast)
3497 <<
"captures not currently allowed";
3504 if (Info.EvaluatingDecl ==
Base) {
3505 Result = Info.EvaluatingDeclValue;
3513 if (isa<ParmVarDecl>(VD) && !AllowConstexprUnknown) {
3516 if (!Info.checkingPotentialConstantExpression() ||
3517 !Info.CurrentCall->Callee ||
3519 if (Info.getLangOpts().CPlusPlus11) {
3520 Info.FFDiag(
E, diag::note_constexpr_function_param_value_unknown)
3541 if (!
Init && !AllowConstexprUnknown) {
3544 if (!Info.checkingPotentialConstantExpression()) {
3545 Info.FFDiag(
E, diag::note_constexpr_var_init_unknown, 1)
3556 if (
Init &&
Init->isValueDependent()) {
3563 if (!Info.checkingPotentialConstantExpression()) {
3564 Info.FFDiag(
E, Info.getLangOpts().CPlusPlus11
3565 ? diag::note_constexpr_ltor_non_constexpr
3566 : diag::note_constexpr_ltor_non_integral, 1)
3580 if (AllowConstexprUnknown) {
3581 Result = &Info.CurrentCall->createConstexprUnknownAPValues(VD,
Base);
3584 Info.FFDiag(
E, diag::note_constexpr_var_init_non_constant, 1) << VD;
3600 ((Info.getLangOpts().CPlusPlus || Info.getLangOpts().OpenCL) &&
3602 Info.CCEDiag(
E, diag::note_constexpr_var_init_non_constant, 1) << VD;
3609 Info.FFDiag(
E, diag::note_constexpr_var_init_weak) << VD;
3623 if (AllowConstexprUnknown) {
3625 Result = &Info.CurrentCall->createConstexprUnknownAPValues(VD,
Base);
3627 Result->setConstexprUnknown();
3640 if (I->getType()->getAsCXXRecordDecl()->getCanonicalDecl() ==
Base)
3644 llvm_unreachable(
"base class missing from derived class's bases list");
3650 assert(!isa<SourceLocExpr>(Lit) &&
3651 "SourceLocExpr should have already been converted to a StringLiteral");
3654 if (
const auto *ObjCEnc = dyn_cast<ObjCEncodeExpr>(Lit)) {
3656 Info.Ctx.getObjCEncodingForType(ObjCEnc->getEncodedType(), Str);
3657 assert(Index <= Str.size() &&
"Index too large");
3658 return APSInt::getUnsigned(Str.c_str()[Index]);
3661 if (
auto PE = dyn_cast<PredefinedExpr>(Lit))
3662 Lit = PE->getFunctionName();
3665 Info.Ctx.getAsConstantArrayType(S->getType());
3666 assert(CAT &&
"string literal isn't an array");
3668 assert(CharType->
isIntegerType() &&
"unexpected character type");
3671 if (Index < S->getLength())
3672 Value = S->getCodeUnit(Index);
3684 AllocType.isNull() ? S->getType() : AllocType);
3685 assert(CAT &&
"string literal isn't an array");
3687 assert(CharType->
isIntegerType() &&
"unexpected character type");
3691 std::min(S->getLength(), Elts), Elts);
3694 if (Result.hasArrayFiller())
3696 for (
unsigned I = 0, N = Result.getArrayInitializedElts(); I != N; ++I) {
3697 Value = S->getCodeUnit(I);
3704 unsigned Size = Array.getArraySize();
3705 assert(Index < Size);
3708 unsigned OldElts = Array.getArrayInitializedElts();
3709 unsigned NewElts = std::max(Index+1, OldElts * 2);
3710 NewElts = std::min(Size, std::max(NewElts, 8u));
3714 for (
unsigned I = 0; I != OldElts; ++I)
3716 for (
unsigned I = OldElts; I != NewElts; ++I)
3720 Array.swap(NewValue);
3741 for (
auto *Field : RD->
fields())
3742 if (!Field->isUnnamedBitField() &&
3746 for (
auto &BaseSpec : RD->
bases())
3764 for (
auto *Field : RD->
fields()) {
3769 if (Field->isMutable() &&
3771 Info.FFDiag(
E, diag::note_constexpr_access_mutable, 1) << AK << Field;
3772 Info.Note(Field->getLocation(), diag::note_declared_at);
3780 for (
auto &BaseSpec : RD->
bases())
3790 bool MutableSubobject =
false) {
3795 switch (Info.IsEvaluatingDecl) {
3796 case EvalInfo::EvaluatingDeclKind::None:
3799 case EvalInfo::EvaluatingDeclKind::Ctor:
3801 if (Info.EvaluatingDecl ==
Base)
3806 if (
auto *BaseE =
Base.dyn_cast<
const Expr *>())
3807 if (
auto *BaseMTE = dyn_cast<MaterializeTemporaryExpr>(BaseE))
3808 return Info.EvaluatingDecl == BaseMTE->getExtendingDecl();
3811 case EvalInfo::EvaluatingDeclKind::Dtor:
3816 if (MutableSubobject ||
Base != Info.EvaluatingDecl)
3825 llvm_unreachable(
"unknown evaluating decl kind");
3830 return Info.CheckArraySize(
3839struct CompleteObject {
3847 CompleteObject() :
Value(nullptr) {}
3851 bool mayAccessMutableMembers(EvalInfo &Info,
AccessKinds AK)
const {
3862 if (!Info.getLangOpts().CPlusPlus14 &&
3863 AK != AccessKinds::AK_IsWithinLifetime)
3868 explicit operator bool()
const {
return !
Type.isNull(); }
3873 bool IsMutable =
false) {
3887template <
typename Sub
objectHandler>
3888static typename SubobjectHandler::result_type
3890 const SubobjectDesignator &Sub, SubobjectHandler &handler) {
3893 return handler.failed();
3894 if (Sub.isOnePastTheEnd() || Sub.isMostDerivedAnUnsizedArray()) {
3895 if (Info.getLangOpts().CPlusPlus11)
3896 Info.FFDiag(
E, Sub.isOnePastTheEnd()
3897 ? diag::note_constexpr_access_past_end
3898 : diag::note_constexpr_access_unsized_array)
3899 << handler.AccessKind;
3902 return handler.failed();
3908 const FieldDecl *VolatileField =
nullptr;
3916 for (
unsigned I = 0, N = Sub.Entries.size(); ; ++I) {
3927 if (!Info.checkingPotentialConstantExpression())
3928 Info.FFDiag(
E, diag::note_constexpr_access_uninit)
3931 return handler.failed();
3939 Info.isEvaluatingCtorDtor(
3942 ConstructionPhase::None) {
3952 if (Info.getLangOpts().CPlusPlus) {
3956 if (VolatileField) {
3959 Decl = VolatileField;
3960 }
else if (
auto *VD = Obj.Base.dyn_cast<
const ValueDecl*>()) {
3962 Loc = VD->getLocation();
3966 if (
auto *
E = Obj.Base.dyn_cast<
const Expr *>())
3969 Info.FFDiag(
E, diag::note_constexpr_access_volatile_obj, 1)
3970 << handler.AccessKind << DiagKind <<
Decl;
3971 Info.Note(
Loc, diag::note_constexpr_volatile_here) << DiagKind;
3973 Info.FFDiag(
E, diag::note_invalid_subexpr_in_const_expr);
3975 return handler.failed();
3983 !Obj.mayAccessMutableMembers(Info, handler.AccessKind) &&
3985 return handler.failed();
3989 if (!handler.found(*O, ObjType))
4001 LastField =
nullptr;
4005 assert(CAT &&
"vla in literal type?");
4006 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4007 if (CAT->
getSize().ule(Index)) {
4010 if (Info.getLangOpts().CPlusPlus11)
4011 Info.FFDiag(
E, diag::note_constexpr_access_past_end)
4012 << handler.AccessKind;
4015 return handler.failed();
4022 else if (!
isRead(handler.AccessKind)) {
4024 return handler.failed();
4032 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4034 if (Info.getLangOpts().CPlusPlus11)
4035 Info.FFDiag(
E, diag::note_constexpr_access_past_end)
4036 << handler.AccessKind;
4039 return handler.failed();
4045 assert(I == N - 1 &&
"extracting subobject of scalar?");
4055 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4056 unsigned NumElements = VT->getNumElements();
4057 if (Index == NumElements) {
4058 if (Info.getLangOpts().CPlusPlus11)
4059 Info.FFDiag(
E, diag::note_constexpr_access_past_end)
4060 << handler.AccessKind;
4063 return handler.failed();
4066 if (Index > NumElements) {
4067 Info.CCEDiag(
E, diag::note_constexpr_array_index)
4068 << Index << 0 << NumElements;
4069 return handler.failed();
4072 ObjType = VT->getElementType();
4073 assert(I == N - 1 &&
"extracting subobject of scalar?");
4075 }
else if (
const FieldDecl *Field = getAsField(Sub.Entries[I])) {
4076 if (Field->isMutable() &&
4077 !Obj.mayAccessMutableMembers(Info, handler.AccessKind)) {
4078 Info.FFDiag(
E, diag::note_constexpr_access_mutable, 1)
4079 << handler.AccessKind << Field;
4080 Info.Note(Field->getLocation(), diag::note_declared_at);
4081 return handler.failed();
4090 if (I == N - 1 && handler.AccessKind ==
AK_Construct) {
4101 Info.FFDiag(
E, diag::note_constexpr_access_inactive_union_member)
4102 << handler.AccessKind << Field << !UnionField << UnionField;
4103 return handler.failed();
4112 if (Field->getType().isVolatileQualified())
4113 VolatileField = Field;
4126struct ExtractSubobjectHandler {
4132 typedef bool result_type;
4133 bool failed() {
return false; }
4153 const CompleteObject &Obj,
4154 const SubobjectDesignator &Sub,
APValue &Result,
4157 ExtractSubobjectHandler Handler = {Info,
E, Result, AK};
4162struct ModifySubobjectHandler {
4167 typedef bool result_type;
4173 Info.FFDiag(
E, diag::note_constexpr_modify_const_type) << QT;
4179 bool failed() {
return false; }
4181 if (!checkConst(SubobjType))
4184 Subobj.
swap(NewVal);
4188 if (!checkConst(SubobjType))
4190 if (!NewVal.
isInt()) {
4199 if (!checkConst(SubobjType))
4207const AccessKinds ModifySubobjectHandler::AccessKind;
4211 const CompleteObject &Obj,
4212 const SubobjectDesignator &Sub,
4214 ModifySubobjectHandler Handler = { Info, NewVal,
E };
4221 const SubobjectDesignator &A,
4222 const SubobjectDesignator &B,
4223 bool &WasArrayIndex) {
4224 unsigned I = 0, N = std::min(A.Entries.size(), B.Entries.size());
4225 for (; I != N; ++I) {
4229 if (A.Entries[I].getAsArrayIndex() != B.Entries[I].getAsArrayIndex()) {
4230 WasArrayIndex =
true;
4238 if (A.Entries[I].getAsBaseOrMember() !=
4239 B.Entries[I].getAsBaseOrMember()) {
4240 WasArrayIndex =
false;
4243 if (
const FieldDecl *FD = getAsField(A.Entries[I]))
4245 ObjType = FD->getType();
4251 WasArrayIndex =
false;
4258 const SubobjectDesignator &A,
4259 const SubobjectDesignator &B) {
4260 if (A.Entries.size() != B.Entries.size())
4263 bool IsArray = A.MostDerivedIsArrayElement;
4264 if (IsArray && A.MostDerivedPathLength != A.Entries.size())
4273 return CommonLength >= A.Entries.size() - IsArray;
4280 if (LVal.InvalidBase) {
4282 return CompleteObject();
4286 Info.FFDiag(
E, diag::note_constexpr_access_null) << AK;
4287 return CompleteObject();
4290 CallStackFrame *Frame =
nullptr;
4292 if (LVal.getLValueCallIndex()) {
4293 std::tie(Frame, Depth) =
4294 Info.getCallFrameAndDepth(LVal.getLValueCallIndex());
4296 Info.FFDiag(
E, diag::note_constexpr_lifetime_ended, 1)
4297 << AK << LVal.Base.is<
const ValueDecl*>();
4299 return CompleteObject();
4310 if (Info.getLangOpts().CPlusPlus)
4311 Info.FFDiag(
E, diag::note_constexpr_access_volatile_type)
4315 return CompleteObject();
4320 QualType BaseType = getType(LVal.Base);
4322 if (Info.getLangOpts().CPlusPlus14 && LVal.Base == Info.EvaluatingDecl &&
4326 BaseVal = Info.EvaluatingDeclValue;
4329 if (
auto *GD = dyn_cast<MSGuidDecl>(
D)) {
4332 Info.FFDiag(
E, diag::note_constexpr_modify_global);
4333 return CompleteObject();
4337 Info.FFDiag(
E, diag::note_constexpr_unsupported_layout)
4339 return CompleteObject();
4341 return CompleteObject(LVal.Base, &
V, GD->getType());
4345 if (
auto *GCD = dyn_cast<UnnamedGlobalConstantDecl>(
D)) {
4347 Info.FFDiag(
E, diag::note_constexpr_modify_global);
4348 return CompleteObject();
4350 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&GCD->getValue()),
4355 if (
auto *TPO = dyn_cast<TemplateParamObjectDecl>(
D)) {
4357 Info.FFDiag(
E, diag::note_constexpr_modify_global);
4358 return CompleteObject();
4360 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&TPO->getValue()),
4371 const VarDecl *VD = dyn_cast<VarDecl>(
D);
4378 return CompleteObject();
4381 bool IsConstant = BaseType.
isConstant(Info.Ctx);
4382 bool ConstexprVar =
false;
4383 if (
const auto *VD = dyn_cast_if_present<VarDecl>(
4384 Info.EvaluatingDecl.dyn_cast<
const ValueDecl *>()))
4390 if (IsAccess && isa<ParmVarDecl>(VD)) {
4394 }
else if (Info.getLangOpts().CPlusPlus14 &&
4401 Info.FFDiag(
E, diag::note_constexpr_modify_global);
4402 return CompleteObject();
4405 }
else if (Info.getLangOpts().C23 && ConstexprVar) {
4407 return CompleteObject();
4411 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4412 if (Info.getLangOpts().CPlusPlus) {
4413 Info.FFDiag(
E, diag::note_constexpr_ltor_non_const_int, 1) << VD;
4414 Info.Note(VD->
getLocation(), diag::note_declared_at);
4418 return CompleteObject();
4420 }
else if (!IsAccess) {
4421 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4422 }
else if (IsConstant && Info.checkingPotentialConstantExpression() &&
4425 }
else if (IsConstant) {
4429 if (Info.getLangOpts().CPlusPlus) {
4430 Info.CCEDiag(
E, Info.getLangOpts().CPlusPlus11
4431 ? diag::note_constexpr_ltor_non_constexpr
4432 : diag::note_constexpr_ltor_non_integral, 1)
4434 Info.Note(VD->
getLocation(), diag::note_declared_at);
4440 if (Info.getLangOpts().CPlusPlus) {
4441 Info.FFDiag(
E, Info.getLangOpts().CPlusPlus11
4442 ? diag::note_constexpr_ltor_non_constexpr
4443 : diag::note_constexpr_ltor_non_integral, 1)
4445 Info.Note(VD->
getLocation(), diag::note_declared_at);
4449 return CompleteObject();
4454 return CompleteObject();
4456 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
4458 Info.FFDiag(
E, diag::note_constexpr_access_deleted_object) << AK;
4459 return CompleteObject();
4461 return CompleteObject(LVal.Base, &(*Alloc)->Value,
4462 LVal.Base.getDynamicAllocType());
4468 dyn_cast_or_null<MaterializeTemporaryExpr>(
Base)) {
4469 assert(MTE->getStorageDuration() ==
SD_Static &&
4470 "should have a frame for a non-global materialized temporary");
4497 if (!MTE->isUsableInConstantExpressions(Info.Ctx) &&
4500 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4501 Info.FFDiag(
E, diag::note_constexpr_access_static_temporary, 1) << AK;
4502 Info.Note(MTE->getExprLoc(), diag::note_constexpr_temporary_here);
4503 return CompleteObject();
4506 BaseVal = MTE->getOrCreateValue(
false);
4507 assert(BaseVal &&
"got reference to unevaluated temporary");
4510 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4513 Info.FFDiag(
E, diag::note_constexpr_access_unreadable_object)
4516 Info.Ctx.getLValueReferenceType(LValType));
4518 return CompleteObject();
4521 BaseVal = Frame->getTemporary(
Base, LVal.Base.getVersion());
4522 assert(BaseVal &&
"missing value for temporary");
4533 unsigned VisibleDepth = Depth;
4534 if (llvm::isa_and_nonnull<ParmVarDecl>(
4535 LVal.Base.dyn_cast<
const ValueDecl *>()))
4537 if ((Frame && Info.getLangOpts().CPlusPlus14 &&
4538 Info.EvalStatus.HasSideEffects) ||
4539 (
isModification(AK) && VisibleDepth < Info.SpeculativeEvaluationDepth))
4540 return CompleteObject();
4542 return CompleteObject(LVal.getLValueBase(), BaseVal, BaseType);
4561 const LValue &LVal,
APValue &RVal,
4562 bool WantObjectRepresentation =
false) {
4563 if (LVal.Designator.Invalid)
4572 if (
Base && !LVal.getLValueCallIndex() && !
Type.isVolatileQualified()) {
4577 if (
Type.isVolatileQualified()) {
4583 if (!
Evaluate(Lit, Info, CLE->getInitializer()))
4603 Info.Note(CLE->getExprLoc(), diag::note_declared_at);
4608 CompleteObject LitObj(LVal.Base, &Lit,
Base->getType());
4610 }
else if (isa<StringLiteral>(
Base) || isa<PredefinedExpr>(
Base)) {
4613 assert(LVal.Designator.Entries.size() <= 1 &&
4614 "Can only read characters from string literals");
4615 if (LVal.Designator.Entries.empty()) {
4622 if (LVal.Designator.isOnePastTheEnd()) {
4623 if (Info.getLangOpts().CPlusPlus11)
4624 Info.FFDiag(Conv, diag::note_constexpr_access_past_end) << AK;
4629 uint64_t CharIndex = LVal.Designator.Entries[0].getAsArrayIndex();
4636 return Obj &&
extractSubobject(Info, Conv, Obj, LVal.Designator, RVal, AK);
4642 if (LVal.Designator.Invalid)
4645 if (!Info.getLangOpts().CPlusPlus14) {
4655struct CompoundAssignSubobjectHandler {
4664 typedef bool result_type;
4669 Info.FFDiag(
E, diag::note_constexpr_modify_const_type) << QT;
4675 bool failed() {
return false; }
4679 return found(Subobj.
getInt(), SubobjType);
4681 return found(Subobj.
getFloat(), SubobjType);
4688 return foundPointer(Subobj, SubobjType);
4690 return foundVector(Subobj, SubobjType);
4692 Info.FFDiag(
E, diag::note_constexpr_access_uninit)
4704 if (!checkConst(SubobjType))
4715 if (!checkConst(SubobjType))
4734 Info.Ctx.getLangOpts());
4737 PromotedLHSType, FValue) &&
4747 return checkConst(SubobjType) &&
4754 if (!checkConst(SubobjType))
4762 (Opcode != BO_Add && Opcode != BO_Sub)) {
4768 if (Opcode == BO_Sub)
4772 LVal.setFrom(Info.Ctx, Subobj);
4775 LVal.moveInto(Subobj);
4781const AccessKinds CompoundAssignSubobjectHandler::AccessKind;
4786 const LValue &LVal,
QualType LValType,
4790 if (LVal.Designator.Invalid)
4793 if (!Info.getLangOpts().CPlusPlus14) {
4799 CompoundAssignSubobjectHandler Handler = { Info,
E, PromotedLValType, Opcode,
4801 return Obj &&
findSubobject(Info,
E, Obj, LVal.Designator, Handler);
4805struct IncDecSubobjectHandler {
4811 typedef bool result_type;
4816 Info.FFDiag(
E, diag::note_constexpr_modify_const_type) << QT;
4822 bool failed() {
return false; }
4833 return found(Subobj.
getInt(), SubobjType);
4835 return found(Subobj.
getFloat(), SubobjType);
4845 return foundPointer(Subobj, SubobjType);
4853 if (!checkConst(SubobjType))
4875 bool WasNegative =
Value.isNegative();
4879 if (!WasNegative &&
Value.isNegative() &&
E->canOverflow()) {
4886 if (WasNegative && !
Value.isNegative() &&
E->canOverflow()) {
4887 unsigned BitWidth =
Value.getBitWidth();
4888 APSInt ActualValue(
Value.sext(BitWidth + 1),
false);
4889 ActualValue.setBit(BitWidth);
4896 if (!checkConst(SubobjType))
4903 APFloat::opStatus St;
4905 St =
Value.add(One, RM);
4907 St =
Value.subtract(One, RM);
4911 if (!checkConst(SubobjType))
4923 LVal.setFrom(Info.Ctx, Subobj);
4927 LVal.moveInto(Subobj);
4936 if (LVal.Designator.Invalid)
4939 if (!Info.getLangOpts().CPlusPlus14) {
4946 IncDecSubobjectHandler Handler = {Info, cast<UnaryOperator>(
E), AK, Old};
4947 return Obj &&
findSubobject(Info,
E, Obj, LVal.Designator, Handler);
4953 if (Object->getType()->isPointerType() && Object->isPRValue())
4956 if (Object->isGLValue())
4959 if (Object->getType()->isLiteralType(Info.Ctx))
4962 if (Object->getType()->isRecordType() && Object->isPRValue())
4965 Info.FFDiag(Object, diag::note_constexpr_nonliteral) << Object->getType();
4984 bool IncludeMember =
true) {
4991 if (!MemPtr.getDecl()) {
4997 if (MemPtr.isDerivedMember()) {
5001 if (LV.Designator.MostDerivedPathLength + MemPtr.Path.size() >
5002 LV.Designator.Entries.size()) {
5006 unsigned PathLengthToMember =
5007 LV.Designator.Entries.size() - MemPtr.Path.size();
5008 for (
unsigned I = 0, N = MemPtr.Path.size(); I != N; ++I) {
5010 LV.Designator.Entries[PathLengthToMember + I]);
5020 PathLengthToMember))
5022 }
else if (!MemPtr.Path.empty()) {
5024 LV.Designator.Entries.reserve(LV.Designator.Entries.size() +
5025 MemPtr.Path.size() + IncludeMember);
5031 assert(RD &&
"member pointer access on non-class-type expression");
5033 for (
unsigned I = 1, N = MemPtr.Path.size(); I != N; ++I) {
5041 MemPtr.getContainingRecord()))
5046 if (IncludeMember) {
5047 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(MemPtr.getDecl())) {
5051 dyn_cast<IndirectFieldDecl>(MemPtr.getDecl())) {
5055 llvm_unreachable(
"can't construct reference to bound member function");
5059 return MemPtr.getDecl();
5065 bool IncludeMember =
true) {
5069 if (Info.noteFailure()) {
5077 BO->
getRHS(), IncludeMember);
5084 SubobjectDesignator &
D = Result.Designator;
5085 if (
D.Invalid || !Result.checkNullPointer(Info,
E,
CSK_Derived))
5093 if (
D.MostDerivedPathLength +
E->path_size() >
D.Entries.size()) {
5094 Info.CCEDiag(
E, diag::note_constexpr_invalid_downcast)
5095 <<
D.MostDerivedType << TargetQT;
5101 unsigned NewEntriesSize =
D.Entries.size() -
E->path_size();
5104 if (NewEntriesSize ==
D.MostDerivedPathLength)
5105 FinalType =
D.MostDerivedType->getAsCXXRecordDecl();
5107 FinalType = getAsBaseClass(
D.Entries[NewEntriesSize - 1]);
5109 Info.CCEDiag(
E, diag::note_constexpr_invalid_downcast)
5110 <<
D.MostDerivedType << TargetQT;
5124 if (!Result.isAbsent())
5128 if (RD->isInvalidDecl()) {
5132 if (RD->isUnion()) {
5137 std::distance(RD->field_begin(), RD->field_end()));
5141 End = RD->bases_end();
5142 I != End; ++I, ++Index)
5146 for (
const auto *I : RD->fields()) {
5147 if (I->isUnnamedBitField())
5150 I->getType(), Result.getStructField(I->getFieldIndex()));
5158 if (Result.hasArrayFiller())
5170enum EvalStmtResult {
5194 APValue &Val = Info.CurrentCall->createTemporary(VD, VD->
getType(),
5195 ScopeKind::Block, Result);
5200 return Info.noteSideEffect();
5219 if (
const VarDecl *VD = dyn_cast<VarDecl>(
D))
5223 for (
auto *BD : DD->bindings())
5224 if (
auto *VD = BD->getHoldingVar())
5232 if (Info.noteSideEffect())
5234 assert(
E->
containsErrors() &&
"valid value-dependent expression should never "
5235 "reach invalid code path.");
5241 const Expr *Cond,
bool &Result) {
5244 FullExpressionRAII
Scope(Info);
5249 return Scope.destroy();
5262struct TempVersionRAII {
5263 CallStackFrame &Frame;
5265 TempVersionRAII(CallStackFrame &Frame) : Frame(Frame) {
5266 Frame.pushTempVersion();
5269 ~TempVersionRAII() {
5270 Frame.popTempVersion();
5284 BlockScopeRAII
Scope(Info);
5286 EvalStmtResult ESR =
EvaluateStmt(Result, Info, Body, Case);
5287 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5292 return ESR_Succeeded;
5295 return ESR_Continue;
5298 case ESR_CaseNotFound:
5301 llvm_unreachable(
"Invalid EvalStmtResult!");
5307 BlockScopeRAII
Scope(Info);
5314 if (ESR != ESR_Succeeded) {
5315 if (ESR != ESR_Failed && !
Scope.destroy())
5321 FullExpressionRAII CondScope(Info);
5333 if (!CondScope.destroy())
5342 if (isa<DefaultStmt>(SC)) {
5347 const CaseStmt *CS = cast<CaseStmt>(SC);
5358 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5362 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5367 return ESR_Succeeded;
5373 case ESR_CaseNotFound:
5376 Info.FFDiag(
Found->getBeginLoc(),
5377 diag::note_constexpr_stmt_expr_unsupported);
5380 llvm_unreachable(
"Invalid EvalStmtResult!");
5390 Info.CCEDiag(VD->
getLocation(), diag::note_constexpr_static_local)
5400 if (!Info.nextStep(S))
5406 switch (S->getStmtClass()) {
5407 case Stmt::CompoundStmtClass:
5411 case Stmt::LabelStmtClass:
5412 case Stmt::AttributedStmtClass:
5413 case Stmt::DoStmtClass:
5416 case Stmt::CaseStmtClass:
5417 case Stmt::DefaultStmtClass:
5422 case Stmt::IfStmtClass: {
5425 const IfStmt *IS = cast<IfStmt>(S);
5429 BlockScopeRAII
Scope(Info);
5435 if (ESR != ESR_CaseNotFound) {
5436 assert(ESR != ESR_Succeeded);
5447 if (ESR == ESR_Failed)
5449 if (ESR != ESR_CaseNotFound)
5450 return Scope.destroy() ? ESR : ESR_Failed;
5452 return ESR_CaseNotFound;
5455 if (ESR == ESR_Failed)
5457 if (ESR != ESR_CaseNotFound)
5458 return Scope.destroy() ? ESR : ESR_Failed;
5459 return ESR_CaseNotFound;
5462 case Stmt::WhileStmtClass: {
5463 EvalStmtResult ESR =
5465 if (ESR != ESR_Continue)
5470 case Stmt::ForStmtClass: {
5471 const ForStmt *FS = cast<ForStmt>(S);
5472 BlockScopeRAII
Scope(Info);
5476 if (
const Stmt *
Init = FS->getInit()) {
5478 if (ESR != ESR_CaseNotFound) {
5479 assert(ESR != ESR_Succeeded);
5484 EvalStmtResult ESR =
5486 if (ESR != ESR_Continue)
5488 if (
const auto *Inc = FS->getInc()) {
5489 if (Inc->isValueDependent()) {
5493 FullExpressionRAII IncScope(Info);
5501 case Stmt::DeclStmtClass: {
5504 const DeclStmt *DS = cast<DeclStmt>(S);
5505 for (
const auto *
D : DS->
decls()) {
5506 if (
const auto *VD = dyn_cast<VarDecl>(
D)) {
5509 if (VD->hasLocalStorage() && !VD->getInit())
5517 return ESR_CaseNotFound;
5521 return ESR_CaseNotFound;
5525 switch (S->getStmtClass()) {
5527 if (
const Expr *
E = dyn_cast<Expr>(S)) {
5536 FullExpressionRAII
Scope(Info);
5540 return ESR_Succeeded;
5543 Info.FFDiag(S->getBeginLoc()) << S->getSourceRange();
5546 case Stmt::NullStmtClass:
5547 return ESR_Succeeded;
5549 case Stmt::DeclStmtClass: {
5550 const DeclStmt *DS = cast<DeclStmt>(S);
5551 for (
const auto *
D : DS->
decls()) {
5552 const VarDecl *VD = dyn_cast_or_null<VarDecl>(
D);
5556 FullExpressionRAII
Scope(Info);
5559 if (!
Scope.destroy())
5562 return ESR_Succeeded;
5565 case Stmt::ReturnStmtClass: {
5566 const Expr *RetExpr = cast<ReturnStmt>(S)->getRetValue();
5567 FullExpressionRAII
Scope(Info);
5576 :
Evaluate(Result.Value, Info, RetExpr)))
5578 return Scope.destroy() ? ESR_Returned : ESR_Failed;
5581 case Stmt::CompoundStmtClass: {
5582 BlockScopeRAII
Scope(Info);
5585 for (
const auto *BI : CS->
body()) {
5586 EvalStmtResult ESR =
EvaluateStmt(Result, Info, BI, Case);
5587 if (ESR == ESR_Succeeded)
5589 else if (ESR != ESR_CaseNotFound) {
5590 if (ESR != ESR_Failed && !
Scope.destroy())
5596 return ESR_CaseNotFound;
5597 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5600 case Stmt::IfStmtClass: {
5601 const IfStmt *IS = cast<IfStmt>(S);
5604 BlockScopeRAII
Scope(Info);
5607 if (ESR != ESR_Succeeded) {
5608 if (ESR != ESR_Failed && !
Scope.destroy())
5618 if (!Info.InConstantContext)
5625 EvalStmtResult ESR =
EvaluateStmt(Result, Info, SubStmt);
5626 if (ESR != ESR_Succeeded) {
5627 if (ESR != ESR_Failed && !
Scope.destroy())
5632 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5635 case Stmt::WhileStmtClass: {
5636 const WhileStmt *WS = cast<WhileStmt>(S);
5638 BlockScopeRAII
Scope(Info);
5647 if (ESR != ESR_Continue) {
5648 if (ESR != ESR_Failed && !
Scope.destroy())
5652 if (!
Scope.destroy())
5655 return ESR_Succeeded;
5658 case Stmt::DoStmtClass: {
5659 const DoStmt *DS = cast<DoStmt>(S);
5663 if (ESR != ESR_Continue)
5672 FullExpressionRAII CondScope(Info);
5674 !CondScope.destroy())
5677 return ESR_Succeeded;
5680 case Stmt::ForStmtClass: {
5681 const ForStmt *FS = cast<ForStmt>(S);
5682 BlockScopeRAII ForScope(Info);
5683 if (FS->getInit()) {
5684 EvalStmtResult ESR =
EvaluateStmt(Result, Info, FS->getInit());
5685 if (ESR != ESR_Succeeded) {
5686 if (ESR != ESR_Failed && !ForScope.destroy())
5692 BlockScopeRAII IterScope(Info);
5693 bool Continue =
true;
5694 if (FS->getCond() && !
EvaluateCond(Info, FS->getConditionVariable(),
5695 FS->getCond(), Continue))
5701 if (ESR != ESR_Continue) {
5702 if (ESR != ESR_Failed && (!IterScope.destroy() || !ForScope.destroy()))
5707 if (
const auto *Inc = FS->getInc()) {
5708 if (Inc->isValueDependent()) {
5712 FullExpressionRAII IncScope(Info);
5718 if (!IterScope.destroy())
5721 return ForScope.destroy() ? ESR_Succeeded : ESR_Failed;
5724 case Stmt::CXXForRangeStmtClass: {
5726 BlockScopeRAII
Scope(Info);
5729 if (FS->getInit()) {
5730 EvalStmtResult ESR =
EvaluateStmt(Result, Info, FS->getInit());
5731 if (ESR != ESR_Succeeded) {
5732 if (ESR != ESR_Failed && !
Scope.destroy())
5739 EvalStmtResult ESR =
EvaluateStmt(Result, Info, FS->getRangeStmt());
5740 if (ESR != ESR_Succeeded) {
5741 if (ESR != ESR_Failed && !
Scope.destroy())
5748 if (!FS->getBeginStmt() || !FS->getEndStmt() || !FS->getCond())
5753 if (ESR != ESR_Succeeded) {
5754 if (ESR != ESR_Failed && !
Scope.destroy())
5759 if (ESR != ESR_Succeeded) {
5760 if (ESR != ESR_Failed && !
Scope.destroy())
5768 if (FS->getCond()->isValueDependent()) {
5773 bool Continue =
true;
5774 FullExpressionRAII CondExpr(Info);
5782 BlockScopeRAII InnerScope(Info);
5783 ESR =
EvaluateStmt(Result, Info, FS->getLoopVarStmt());
5784 if (ESR != ESR_Succeeded) {
5785 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
5792 if (ESR != ESR_Continue) {
5793 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
5797 if (FS->getInc()->isValueDependent()) {
5806 if (!InnerScope.destroy())
5810 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5813 case Stmt::SwitchStmtClass:
5816 case Stmt::ContinueStmtClass:
5817 return ESR_Continue;
5819 case Stmt::BreakStmtClass:
5822 case Stmt::LabelStmtClass:
5823 return EvaluateStmt(Result, Info, cast<LabelStmt>(S)->getSubStmt(), Case);
5825 case Stmt::AttributedStmtClass: {
5826 const auto *AS = cast<AttributedStmt>(S);
5827 const auto *SS = AS->getSubStmt();
5828 MSConstexprContextRAII ConstexprContext(
5829 *Info.CurrentCall, hasSpecificAttr<MSConstexprAttr>(AS->getAttrs()) &&
5830 isa<ReturnStmt>(SS));
5832 auto LO = Info.getASTContext().getLangOpts();
5833 if (LO.CXXAssumptions && !LO.MSVCCompat) {
5834 for (
auto *
Attr : AS->getAttrs()) {
5835 auto *AA = dyn_cast<CXXAssumeAttr>(
Attr);
5839 auto *Assumption = AA->getAssumption();
5840 if (Assumption->isValueDependent())
5843 if (Assumption->HasSideEffects(Info.getASTContext()))
5850 Info.CCEDiag(Assumption->getExprLoc(),
5851 diag::note_constexpr_assumption_failed);
5860 case Stmt::CaseStmtClass:
5861 case Stmt::DefaultStmtClass:
5862 return EvaluateStmt(Result, Info, cast<SwitchCase>(S)->getSubStmt(), Case);
5863 case Stmt::CXXTryStmtClass:
5865 return EvaluateStmt(Result, Info, cast<CXXTryStmt>(S)->getTryBlock(), Case);
5875 bool IsValueInitialization) {
5882 if (!CD->
isConstexpr() && !IsValueInitialization) {
5883 if (Info.getLangOpts().CPlusPlus11) {
5886 Info.CCEDiag(
Loc, diag::note_constexpr_invalid_function, 1)
5888 Info.Note(CD->
getLocation(), diag::note_declared_at);
5890 Info.CCEDiag(
Loc, diag::note_invalid_subexpr_in_const_expr);
5904 if (Info.checkingPotentialConstantExpression() && !
Definition &&
5912 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
5919 if (!Info.Ctx.getLangOpts().CPlusPlus20 && isa<CXXMethodDecl>(
Declaration) &&
5921 Info.CCEDiag(CallLoc, diag::note_constexpr_virtual_call);
5924 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
5930 (
Definition->isConstexpr() || (Info.CurrentCall->CanEvalMSConstexpr &&
5934 if (Info.getLangOpts().CPlusPlus11) {
5939 auto *CD = dyn_cast<CXXConstructorDecl>(DiagDecl);
5940 if (CD && CD->isInheritingConstructor()) {
5941 auto *Inherited = CD->getInheritedConstructor().getConstructor();
5942 if (!Inherited->isConstexpr())
5943 DiagDecl = CD = Inherited;
5949 if (CD && CD->isInheritingConstructor())
5950 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_inhctor, 1)
5951 << CD->getInheritedConstructor().getConstructor()->
getParent();
5953 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_function, 1)
5955 Info.Note(DiagDecl->
getLocation(), diag::note_declared_at);
5957 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
5963struct CheckDynamicTypeHandler {
5965 typedef bool result_type;
5966 bool failed() {
return false; }
5969 bool found(APFloat &
Value,
QualType SubobjType) {
return true; }
5983 if (This.allowConstexprUnknown())
5986 if (This.Designator.Invalid)
5998 if (This.Designator.isOnePastTheEnd() ||
5999 This.Designator.isMostDerivedAnUnsizedArray()) {
6000 Info.FFDiag(
E, This.Designator.isOnePastTheEnd()
6001 ? diag::note_constexpr_access_past_end
6002 : diag::note_constexpr_access_unsized_array)
6005 }
else if (Polymorphic) {
6011 Info.Ctx.getLValueReferenceType(This.Designator.getType(Info.Ctx));
6012 Info.FFDiag(
E, diag::note_constexpr_polymorphic_unknown_dynamic_type)
6019 CheckDynamicTypeHandler Handler{AK};
6020 return Obj &&
findSubobject(Info,
E, Obj, This.Designator, Handler);
6042 unsigned PathLength) {
6043 assert(PathLength >=
Designator.MostDerivedPathLength && PathLength <=
6044 Designator.Entries.size() &&
"invalid path length");
6045 return (PathLength ==
Designator.MostDerivedPathLength)
6046 ?
Designator.MostDerivedType->getAsCXXRecordDecl()
6047 : getAsBaseClass(
Designator.Entries[PathLength - 1]);
6062 return std::nullopt;
6064 if (This.Designator.Invalid)
6065 return std::nullopt;
6074 This.Designator.MostDerivedType->getAsCXXRecordDecl();
6077 return std::nullopt;
6085 for (
unsigned PathLength = This.Designator.MostDerivedPathLength;
6086 PathLength <=
Path.size(); ++PathLength) {
6087 switch (Info.isEvaluatingCtorDtor(This.getLValueBase(),
6088 Path.slice(0, PathLength))) {
6089 case ConstructionPhase::Bases:
6090 case ConstructionPhase::DestroyingBases:
6095 case ConstructionPhase::None:
6096 case ConstructionPhase::AfterBases:
6097 case ConstructionPhase::AfterFields:
6098 case ConstructionPhase::Destroying:
6110 return std::nullopt;
6128 unsigned PathLength = DynType->PathLength;
6129 for (; PathLength <= This.Designator.Entries.size(); ++PathLength) {
6132 Found->getCorrespondingMethodDeclaredInClass(
Class,
false);
6142 if (Callee->isPureVirtual()) {
6143 Info.FFDiag(
E, diag::note_constexpr_pure_virtual_call, 1) << Callee;
6144 Info.Note(Callee->getLocation(), diag::note_declared_at);
6150 if (!Info.Ctx.hasSameUnqualifiedType(Callee->getReturnType(),
6151 Found->getReturnType())) {
6152 CovariantAdjustmentPath.push_back(Callee->getReturnType());
6153 for (
unsigned CovariantPathLength = PathLength + 1;
6154 CovariantPathLength != This.Designator.Entries.size();
6155 ++CovariantPathLength) {
6159 Found->getCorrespondingMethodDeclaredInClass(NextClass,
false);
6160 if (Next && !Info.Ctx.hasSameUnqualifiedType(
6161 Next->getReturnType(), CovariantAdjustmentPath.back()))
6162 CovariantAdjustmentPath.push_back(Next->getReturnType());
6164 if (!Info.Ctx.hasSameUnqualifiedType(
Found->getReturnType(),
6165 CovariantAdjustmentPath.back()))
6166 CovariantAdjustmentPath.push_back(
Found->getReturnType());
6182 assert(Result.isLValue() &&
6183 "unexpected kind of APValue for covariant return");
6184 if (Result.isNullPointer())
6188 LVal.setFrom(Info.Ctx, Result);
6191 for (
unsigned I = 1; I !=
Path.size(); ++I) {
6193 assert(OldClass && NewClass &&
"unexpected kind of covariant return");
6194 if (OldClass != NewClass &&
6197 OldClass = NewClass;
6200 LVal.moveInto(Result);
6209 auto *BaseClass = BaseSpec.getType()->getAsCXXRecordDecl();
6211 return BaseSpec.getAccessSpecifier() ==
AS_public;
6213 llvm_unreachable(
"Base is not a direct base of Derived");
6223 SubobjectDesignator &
D = Ptr.Designator;
6235 std::optional<DynamicType> DynType =
6246 const CXXRecordDecl *
C =
E->getTypeAsWritten()->getPointeeCXXRecordDecl();
6247 assert(
C &&
"dynamic_cast target is not void pointer nor class");
6248 CanQualType CQT = Info.Ctx.getCanonicalType(Info.Ctx.getRecordType(
C));
6255 Ptr.setNull(Info.Ctx,
E->
getType());
6262 DynType->Type->isDerivedFrom(
C)))
6264 else if (!Paths || Paths->begin() == Paths->end())
6266 else if (Paths->isAmbiguous(CQT))
6269 assert(Paths->front().Access !=
AS_public &&
"why did the cast fail?");
6272 Info.FFDiag(
E, diag::note_constexpr_dynamic_cast_to_reference_failed)
6273 << DiagKind << Ptr.Designator.getType(Info.Ctx)
6274 << Info.Ctx.getRecordType(DynType->Type)
6282 for (
int PathLength = Ptr.Designator.Entries.size();
6283 PathLength >= (
int)DynType->PathLength; --PathLength) {
6288 if (PathLength > (
int)DynType->PathLength &&
6291 return RuntimeCheckFailed(
nullptr);
6298 if (DynType->Type->isDerivedFrom(
C, Paths) && !Paths.isAmbiguous(CQT) &&
6311 return RuntimeCheckFailed(&Paths);
6315struct StartLifetimeOfUnionMemberHandler {
6317 const Expr *LHSExpr;
6320 bool Failed =
false;
6323 typedef bool result_type;
6324 bool failed() {
return Failed; }
6340 }
else if (DuringInit) {
6344 Info.FFDiag(LHSExpr,
6345 diag::note_constexpr_union_member_change_during_init);
6354 llvm_unreachable(
"wrong value kind for union object");
6357 llvm_unreachable(
"wrong value kind for union object");
6362const AccessKinds StartLifetimeOfUnionMemberHandler::AccessKind;
6369 const Expr *LHSExpr,
6370 const LValue &LHS) {
6371 if (LHS.InvalidBase || LHS.Designator.Invalid)
6377 unsigned PathLength = LHS.Designator.Entries.size();
6378 for (
const Expr *
E = LHSExpr;
E !=
nullptr;) {
6380 if (
auto *ME = dyn_cast<MemberExpr>(
E)) {
6381 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
6384 if (!FD || FD->getType()->isReferenceType())
6388 if (FD->getParent()->isUnion()) {
6393 FD->getType()->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
6394 if (!RD || RD->hasTrivialDefaultConstructor())
6395 UnionPathLengths.push_back({PathLength - 1, FD});
6401 LHS.Designator.Entries[PathLength]
6402 .getAsBaseOrMember().getPointer()));
6406 }
else if (
auto *ASE = dyn_cast<ArraySubscriptExpr>(
E)) {
6408 auto *
Base = ASE->getBase()->IgnoreImplicit();
6409 if (!
Base->getType()->isArrayType())
6415 }
else if (
auto *ICE = dyn_cast<ImplicitCastExpr>(
E)) {
6417 E = ICE->getSubExpr();
6418 if (ICE->getCastKind() == CK_NoOp)
6420 if (ICE->getCastKind() != CK_DerivedToBase &&
6421 ICE->getCastKind() != CK_UncheckedDerivedToBase)
6425 if (Elt->isVirtual()) {
6434 LHS.Designator.Entries[PathLength]
6435 .getAsBaseOrMember().getPointer()));
6445 if (UnionPathLengths.empty())
6450 CompleteObject Obj =
6454 for (std::pair<unsigned, const FieldDecl *> LengthAndField :
6455 llvm::reverse(UnionPathLengths)) {
6457 SubobjectDesignator
D = LHS.Designator;
6458 D.truncate(Info.Ctx, LHS.Base, LengthAndField.first);
6460 bool DuringInit = Info.isEvaluatingCtorDtor(LHS.Base,
D.Entries) ==
6461 ConstructionPhase::AfterBases;
6462 StartLifetimeOfUnionMemberHandler StartLifetime{
6463 Info, LHSExpr, LengthAndField.second, DuringInit};
6472 CallRef
Call, EvalInfo &Info,
6480 APValue &
V = PVD ? Info.CurrentCall->createParam(
Call, PVD, LV)
6481 : Info.CurrentCall->createTemporary(Arg, Arg->
getType(),
6482 ScopeKind::Call, LV);
6488 if (
NonNull &&
V.isLValue() &&
V.isNullPointer()) {
6489 Info.CCEDiag(Arg, diag::note_non_null_attribute_failed);
6499 bool RightToLeft =
false) {
6501 llvm::SmallBitVector ForbiddenNullArgs;
6502 if (Callee->hasAttr<NonNullAttr>()) {
6503 ForbiddenNullArgs.resize(Args.size());
6504 for (
const auto *
Attr : Callee->specific_attrs<NonNullAttr>()) {
6505 if (!
Attr->args_size()) {
6506 ForbiddenNullArgs.set();
6509 for (
auto Idx :
Attr->args()) {
6510 unsigned ASTIdx = Idx.getASTIndex();
6511 if (ASTIdx >= Args.size())
6513 ForbiddenNullArgs[ASTIdx] =
true;
6517 for (
unsigned I = 0; I < Args.size(); I++) {
6518 unsigned Idx = RightToLeft ? Args.size() - I - 1 : I;
6520 Idx < Callee->getNumParams() ? Callee->getParamDecl(Idx) :
nullptr;
6521 bool NonNull = !ForbiddenNullArgs.empty() && ForbiddenNullArgs[Idx];
6525 if (!Info.noteFailure())
6537 bool CopyObjectRepresentation) {
6539 CallStackFrame *Frame = Info.CurrentCall;
6540 APValue *RefValue = Info.getParamSlot(Frame->Arguments, Param);
6548 RefLValue.setFrom(Info.Ctx, *RefValue);
6551 CopyObjectRepresentation);
6558 CallRef
Call,
const Stmt *Body, EvalInfo &Info,
6559 APValue &Result,
const LValue *ResultSlot) {
6560 if (!Info.CheckCallLimit(CallLoc))
6585 This->moveInto(Result);
6594 if (!Info.checkingPotentialConstantExpression())
6596 Frame.LambdaThisCaptureField);
6601 if (ESR == ESR_Succeeded) {
6602 if (Callee->getReturnType()->isVoidType())
6604 Info.FFDiag(Callee->getEndLoc(), diag::note_constexpr_no_return);
6606 return ESR == ESR_Returned;
6613 EvalInfo &Info,
APValue &Result) {
6615 if (!Info.CheckCallLimit(CallLoc))
6620 Info.FFDiag(CallLoc, diag::note_constexpr_virtual_base) << RD;
6624 EvalInfo::EvaluatingConstructorRAII EvalObj(
6626 ObjectUnderConstruction{This.getLValueBase(), This.Designator.Entries},
6638 if ((*I)->getInit()->isValueDependent()) {
6642 FullExpressionRAII InitScope(Info);
6644 !InitScope.destroy())
6667 if (!Result.hasValue()) {
6680 BlockScopeRAII LifetimeExtendedScope(Info);
6683 unsigned BasesSeen = 0;
6693 assert(
Indirect &&
"fields out of order?");
6699 assert(FieldIt != RD->
field_end() &&
"missing field?");
6700 if (!FieldIt->isUnnamedBitField())
6703 Result.getStructField(FieldIt->getFieldIndex()));
6708 LValue Subobject = This;
6709 LValue SubobjectParent = This;
6714 if (I->isBaseInitializer()) {
6715 QualType BaseType(I->getBaseClass(), 0);
6719 assert(!BaseIt->
isVirtual() &&
"virtual base for literal type");
6720 assert(Info.Ctx.hasSameUnqualifiedType(BaseIt->
getType(), BaseType) &&
6721 "base class initializers not in expected order");
6727 Value = &Result.getStructBase(BasesSeen++);
6728 }
else if ((FD = I->getMember())) {
6733 Value = &Result.getUnionValue();
6735 SkipToField(FD,
false);
6741 auto IndirectFieldChain = IFD->chain();
6742 for (
auto *
C : IndirectFieldChain) {
6743 FD = cast<FieldDecl>(
C);
6751 (
Value->isUnion() &&
Value->getUnionField() != FD)) {
6763 if (
C == IndirectFieldChain.back())
6764 SubobjectParent = Subobject;
6770 if (
C == IndirectFieldChain.front() && !RD->
isUnion())
6771 SkipToField(FD,
true);
6776 llvm_unreachable(
"unknown base initializer kind");
6783 if (
Init->isValueDependent()) {
6787 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &SubobjectParent,
6788 isa<CXXDefaultInitExpr>(
Init));
6789 FullExpressionRAII InitScope(Info);
6795 if (!Info.noteFailure())
6803 if (I->isBaseInitializer() && BasesSeen == RD->
getNumBases())
6804 EvalObj.finishedConstructingBases();
6809 for (; FieldIt != RD->
field_end(); ++FieldIt) {
6810 if (!FieldIt->isUnnamedBitField())
6813 Result.getStructField(FieldIt->getFieldIndex()));
6817 EvalObj.finishedConstructingFields();
6821 LifetimeExtendedScope.destroy();
6827 EvalInfo &Info,
APValue &Result) {
6828 CallScopeRAII CallScope(Info);
6834 CallScope.destroy();
6846 This.moveInto(Printable);
6848 diag::note_constexpr_destroy_out_of_lifetime)
6849 << Printable.
getAsString(Info.Ctx, Info.Ctx.getLValueReferenceType(
T));
6865 LValue ElemLV = This;
6866 ElemLV.addArray(Info, &LocE, CAT);
6873 if (Size && Size >
Value.getArrayInitializedElts())
6878 for (Size =
Value.getArraySize(); Size != 0; --Size) {
6879 APValue &Elem =
Value.getArrayInitializedElt(Size - 1);
6892 if (
T.isDestructedType()) {
6894 diag::note_constexpr_unsupported_destruction)
6904 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_virtual_base) << RD;
6929 if (!Info.CheckCallLimit(CallRange.
getBegin()))
6938 CallStackFrame Frame(Info, CallRange,
Definition, &This,
nullptr,
6943 EvalInfo::EvaluatingDestructorRAII EvalObj(
6945 ObjectUnderConstruction{This.getLValueBase(), This.Designator.Entries});
6946 if (!EvalObj.DidInsert) {
6953 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_double_destroy);
6973 for (
const FieldDecl *FD : llvm::reverse(Fields)) {
6974 if (FD->isUnnamedBitField())
6977 LValue Subobject = This;
6981 APValue *SubobjectValue = &
Value.getStructField(FD->getFieldIndex());
6988 EvalObj.startedDestroyingBases();
6995 LValue Subobject = This;
7000 APValue *SubobjectValue = &
Value.getStructBase(BasesLeft);
7005 assert(BasesLeft == 0 &&
"NumBases was wrong?");
7013struct DestroyObjectHandler {
7019 typedef bool result_type;
7020 bool failed() {
return false; }
7026 Info.FFDiag(
E, diag::note_constexpr_destroy_complex_elem);
7030 Info.FFDiag(
E, diag::note_constexpr_destroy_complex_elem);
7039 const LValue &This,
QualType ThisType) {
7041 DestroyObjectHandler Handler = {Info,
E, This,
AK_Destroy};
7042 return Obj &&
findSubobject(Info,
E, Obj, This.Designator, Handler);
7051 if (Info.EvalStatus.HasSideEffects)
7062 if (Info.checkingPotentialConstantExpression() ||
7063 Info.SpeculativeEvaluationDepth)
7067 auto Caller = Info.getStdAllocatorCaller(
"allocate");
7069 Info.FFDiag(
E->
getExprLoc(), Info.getLangOpts().CPlusPlus20
7070 ? diag::note_constexpr_new_untyped
7071 : diag::note_constexpr_new);
7075 QualType ElemType = Caller.ElemType;
7078 diag::note_constexpr_new_not_complete_object_type)
7086 bool IsNothrow =
false;
7087 for (
unsigned I = 1, N =
E->getNumArgs(); I != N; ++I) {
7095 APInt Size, Remainder;
7096 APInt ElemSizeAP(ByteSize.getBitWidth(), ElemSize.
getQuantity());
7097 APInt::udivrem(ByteSize, ElemSizeAP, Size, Remainder);
7098 if (Remainder != 0) {
7100 Info.FFDiag(
E->
getExprLoc(), diag::note_constexpr_operator_new_bad_size)
7101 << ByteSize <<
APSInt(ElemSizeAP,
true) << ElemType;
7105 if (!Info.CheckArraySize(
E->
getBeginLoc(), ByteSize.getActiveBits(),
7106 Size.getZExtValue(), !IsNothrow)) {
7108 Result.setNull(Info.Ctx,
E->
getType());
7114 QualType AllocType = Info.Ctx.getConstantArrayType(
7115 ElemType, Size,
nullptr, ArraySizeModifier::Normal, 0);
7116 APValue *Val = Info.createHeapAlloc(
E, AllocType, Result);
7118 Result.addArray(Info,
E, cast<ConstantArrayType>(AllocType));
7125 return DD->isVirtual();
7132 return DD->isVirtual() ? DD->getOperatorDelete() :
nullptr;
7143 DynAlloc::Kind DeallocKind) {
7144 auto PointerAsString = [&] {
7145 return Pointer.toString(Info.Ctx, Info.Ctx.VoidPtrTy);
7150 Info.FFDiag(
E, diag::note_constexpr_delete_not_heap_alloc)
7151 << PointerAsString();
7154 return std::nullopt;
7157 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
7159 Info.FFDiag(
E, diag::note_constexpr_double_delete);
7160 return std::nullopt;
7163 if (DeallocKind != (*Alloc)->getKind()) {
7165 Info.FFDiag(
E, diag::note_constexpr_new_delete_mismatch)
7166 << DeallocKind << (*Alloc)->getKind() << AllocType;
7168 return std::nullopt;
7171 bool Subobject =
false;
7172 if (DeallocKind == DynAlloc::New) {
7173 Subobject =
Pointer.Designator.MostDerivedPathLength != 0 ||
7174 Pointer.Designator.isOnePastTheEnd();
7176 Subobject =
Pointer.Designator.Entries.size() != 1 ||
7177 Pointer.Designator.Entries[0].getAsArrayIndex() != 0;
7180 Info.FFDiag(
E, diag::note_constexpr_delete_subobject)
7181 << PointerAsString() <<
Pointer.Designator.isOnePastTheEnd();
7182 return std::nullopt;
7190 if (Info.checkingPotentialConstantExpression() ||
7191 Info.SpeculativeEvaluationDepth)
7195 if (!Info.getStdAllocatorCaller(
"deallocate")) {
7203 for (
unsigned I = 1, N =
E->getNumArgs(); I != N; ++I)
7206 if (
Pointer.Designator.Invalid)
7211 if (
Pointer.isNullPointer()) {
7212 Info.CCEDiag(
E->
getExprLoc(), diag::note_constexpr_deallocate_null);
7228class BitCastBuffer {
7236 static_assert(std::numeric_limits<unsigned char>::digits >= 8,
7237 "Need at least 8 bit unsigned char");
7239 bool TargetIsLittleEndian;
7242 BitCastBuffer(
CharUnits Width,
bool TargetIsLittleEndian)
7243 : Bytes(Width.getQuantity()),
7244 TargetIsLittleEndian(TargetIsLittleEndian) {}
7248 for (
CharUnits I = Offset,
E = Offset + Width; I !=
E; ++I) {
7251 if (!Bytes[I.getQuantity()])
7253 Output.push_back(*Bytes[I.getQuantity()]);
7255 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
7256 std::reverse(Output.begin(), Output.end());
7261 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
7262 std::reverse(Input.begin(), Input.end());
7265 for (
unsigned char Byte : Input) {
7266 assert(!Bytes[Offset.getQuantity() + Index] &&
"overwriting a byte?");
7267 Bytes[Offset.getQuantity() + Index] = Byte;
7272 size_t size() {
return Bytes.size(); }
7277class APValueToBufferConverter {
7279 BitCastBuffer Buffer;
7282 APValueToBufferConverter(EvalInfo &Info,
CharUnits ObjectWidth,
7285 Buffer(ObjectWidth, Info.Ctx.getTargetInfo().isLittleEndian()),
7294 assert((
size_t)Offset.getQuantity() <= Buffer.size());
7307 return visitInt(Val.
getInt(), Ty, Offset);
7309 return visitFloat(Val.
getFloat(), Ty, Offset);
7311 return visitArray(Val, Ty, Offset);
7313 return visitRecord(Val, Ty, Offset);
7315 return visitVector(Val, Ty, Offset);
7319 return visitComplex(Val, Ty, Offset);
7327 diag::note_constexpr_bit_cast_unsupported_type)
7333 llvm_unreachable(
"LValue subobject in bit_cast?");
7335 llvm_unreachable(
"Unhandled APValue::ValueKind");
7343 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
7344 for (
size_t I = 0,
E = CXXRD->getNumBases(); I !=
E; ++I) {
7355 unsigned FieldIdx = 0;
7357 if (FD->isBitField()) {
7359 diag::note_constexpr_bit_cast_unsupported_bitfield);
7365 assert(FieldOffsetBits % Info.Ctx.getCharWidth() == 0 &&
7366 "only bit-fields can have sub-char alignment");
7368 Info.Ctx.toCharUnitsFromBits(FieldOffsetBits) + Offset;
7388 for (
unsigned I = 0; I != NumInitializedElts; ++I) {
7390 if (!visit(SubObj, CAT->
getElementType(), Offset + I * ElemWidth))
7397 for (
unsigned I = NumInitializedElts; I != ArraySize; ++I) {
7398 if (!visit(Filler, CAT->
getElementType(), Offset + I * ElemWidth))
7409 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
7414 Offset + (0 * EltSizeChars)))
7417 Offset + (1 * EltSizeChars)))
7421 Offset + (0 * EltSizeChars)))
7424 Offset + (1 * EltSizeChars)))
7445 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
7447 llvm::APInt Res = llvm::APInt::getZero(NElts);
7448 for (
unsigned I = 0; I < NElts; ++I) {
7450 assert(EltAsInt.isUnsigned() && EltAsInt.getBitWidth() == 1 &&
7451 "bool vector element must be 1-bit unsigned integer!");
7453 Res.insertBits(EltAsInt, BigEndian ? (NElts - I - 1) : I);
7457 llvm::StoreIntToMemory(Res, &*Bytes.begin(), NElts / 8);
7458 Buffer.writeObject(Offset, Bytes);
7462 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
7463 for (
unsigned I = 0; I < NElts; ++I) {
7464 if (!visit(Val.
getVectorElt(I), EltTy, Offset + I * EltSizeChars))
7473 APSInt AdjustedVal = Val;
7474 unsigned Width = AdjustedVal.getBitWidth();
7476 Width = Info.Ctx.getTypeSize(Ty);
7477 AdjustedVal = AdjustedVal.extend(Width);
7481 llvm::StoreIntToMemory(AdjustedVal, &*Bytes.begin(), Width / 8);
7482 Buffer.writeObject(Offset, Bytes);
7487 APSInt AsInt(Val.bitcastToAPInt());
7488 return visitInt(AsInt, Ty, Offset);
7492 static std::optional<BitCastBuffer>
7495 APValueToBufferConverter Converter(Info, DstSize, BCE);
7497 return std::nullopt;
7498 return Converter.Buffer;
7503class BufferToAPValueConverter {
7505 const BitCastBuffer &Buffer;
7508 BufferToAPValueConverter(EvalInfo &Info,
const BitCastBuffer &Buffer,
7510 : Info(Info), Buffer(Buffer), BCE(BCE) {}
7515 std::nullopt_t unsupportedType(
QualType Ty) {
7517 diag::note_constexpr_bit_cast_unsupported_type)
7519 return std::nullopt;
7522 std::nullopt_t unrepresentableValue(
QualType Ty,
const APSInt &Val) {
7524 diag::note_constexpr_bit_cast_unrepresentable_value)
7526 return std::nullopt;
7530 const EnumType *EnumSugar =
nullptr) {
7544 const llvm::fltSemantics &Semantics =
7545 Info.Ctx.getFloatTypeSemantics(
QualType(
T, 0));
7546 unsigned NumBits = llvm::APFloatBase::getSizeInBits(Semantics);
7547 assert(NumBits % 8 == 0);
7554 if (!Buffer.readObject(Offset,
SizeOf, Bytes)) {
7557 bool IsStdByte = EnumSugar && EnumSugar->isStdByteType();
7561 if (!IsStdByte && !IsUChar) {
7562 QualType DisplayType(EnumSugar ? (
const Type *)EnumSugar :
T, 0);
7564 diag::note_constexpr_bit_cast_indet_dest)
7565 << DisplayType << Info.Ctx.getLangOpts().CharIsSigned;
7566 return std::nullopt;
7572 APSInt Val(
SizeOf.getQuantity() * Info.Ctx.getCharWidth(),
true);
7573 llvm::LoadIntFromMemory(Val, &*Bytes.begin(), Bytes.size());
7578 unsigned IntWidth = Info.Ctx.getIntWidth(
QualType(
T, 0));
7579 if (IntWidth != Val.getBitWidth()) {
7580 APSInt Truncated = Val.trunc(IntWidth);
7581 if (Truncated.extend(Val.getBitWidth()) != Val)
7582 return unrepresentableValue(
QualType(
T, 0), Val);
7590 const llvm::fltSemantics &Semantics =
7591 Info.Ctx.getFloatTypeSemantics(
QualType(
T, 0));
7602 unsigned NumBases = 0;
7603 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
7604 NumBases = CXXRD->getNumBases();
7610 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
7611 for (
size_t I = 0,
E = CXXRD->getNumBases(); I !=
E; ++I) {
7615 std::optional<APValue> SubObj = visitType(
7618 return std::nullopt;
7619 ResultVal.getStructBase(I) = *SubObj;
7624 unsigned FieldIdx = 0;
7628 if (FD->isBitField()) {
7630 diag::note_constexpr_bit_cast_unsupported_bitfield);
7631 return std::nullopt;
7635 assert(FieldOffsetBits % Info.Ctx.getCharWidth() == 0);
7641 std::optional<APValue> SubObj = visitType(FieldTy, FieldOffset);
7643 return std::nullopt;
7644 ResultVal.getStructField(FieldIdx) = *SubObj;
7653 assert(!RepresentationType.
isNull() &&
7654 "enum forward decl should be caught by Sema");
7655 const auto *AsBuiltin =
7659 return visit(AsBuiltin, Offset, Ty);
7667 for (
size_t I = 0; I !=
Size; ++I) {
7668 std::optional<APValue> ElementValue =
7671 return std::nullopt;
7672 ArrayValue.getArrayInitializedElt(I) = std::move(*ElementValue);
7680 CharUnits ElementWidth = Info.Ctx.getTypeSizeInChars(ElementType);
7683 std::optional<APValue> Values[2];
7684 for (
unsigned I = 0; I != 2; ++I) {
7685 Values[I] = visitType(Ty->
getElementType(), Offset + I * ElementWidth);
7687 return std::nullopt;
7691 return APValue(Values[0]->getInt(), Values[1]->getInt());
7692 return APValue(Values[0]->getFloat(), Values[1]->getFloat());
7702 Elts.reserve(NElts);
7712 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
7715 Bytes.reserve(NElts / 8);
7717 return std::nullopt;
7719 APSInt SValInt(NElts,
true);
7720 llvm::LoadIntFromMemory(SValInt, &*Bytes.begin(), Bytes.size());
7722 for (
unsigned I = 0; I < NElts; ++I) {
7724 SValInt.extractBits(1, (BigEndian ? NElts - I - 1 : I) * EltSize);
7731 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
7732 for (
unsigned I = 0; I < NElts; ++I) {
7733 std::optional<APValue> EltValue =
7734 visitType(EltTy, Offset + I * EltSizeChars);
7736 return std::nullopt;
7737 Elts.push_back(std::move(*EltValue));
7741 return APValue(Elts.data(), Elts.size());
7744 std::optional<APValue> visit(
const Type *Ty,
CharUnits Offset) {
7745 return unsupportedType(
QualType(Ty, 0));
7752#define TYPE(Class, Base) \
7754 return visit(cast<Class##Type>(Can.getTypePtr()), Offset);
7755#define ABSTRACT_TYPE(Class, Base)
7756#define NON_CANONICAL_TYPE(Class, Base) \
7758 llvm_unreachable("non-canonical type should be impossible!");
7759#define DEPENDENT_TYPE(Class, Base) \
7762 "dependent types aren't supported in the constant evaluator!");
7763#define NON_CANONICAL_UNLESS_DEPENDENT(Class, Base) \
7765 llvm_unreachable("either dependent or not canonical!");
7766#include "clang/AST/TypeNodes.inc"
7768 llvm_unreachable(
"Unhandled Type::TypeClass");
7773 static std::optional<APValue> convert(EvalInfo &Info, BitCastBuffer &Buffer,
7775 BufferToAPValueConverter Converter(Info, Buffer, BCE);
7783 bool CheckingDest) {
7786 auto diag = [&](
int Reason) {
7788 Info->FFDiag(
Loc, diag::note_constexpr_bit_cast_invalid_type)
7789 << CheckingDest << (Reason == 4) << Reason;
7794 Info->
Note(NoteLoc, diag::note_constexpr_bit_cast_invalid_subtype)
7795 << NoteTy << Construct << Ty;
7809 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(
Record)) {
7811 if (!checkBitCastConstexprEligibilityType(
Loc, BS.
getType(), Info, Ctx,
7816 if (FD->getType()->isReferenceType())
7818 if (!checkBitCastConstexprEligibilityType(
Loc, FD->getType(), Info, Ctx,
7820 return note(0, FD->getType(), FD->getBeginLoc());
7826 Info, Ctx, CheckingDest))
7839 Info->FFDiag(
Loc, diag::note_constexpr_bit_cast_invalid_vector)
7849 Info->FFDiag(
Loc, diag::note_constexpr_bit_cast_unsupported_type)
7858static bool checkBitCastConstexprEligibility(EvalInfo *Info,
7861 bool DestOK = checkBitCastConstexprEligibilityType(
7863 bool SourceOK = DestOK && checkBitCastConstexprEligibilityType(
7869static bool handleRValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
7872 assert(
CHAR_BIT == 8 && Info.Ctx.getTargetInfo().getCharWidth() == 8 &&
7873 "no host or target supports non 8-bit chars");
7875 if (!checkBitCastConstexprEligibility(&Info, Info.Ctx, BCE))
7879 std::optional<BitCastBuffer> Buffer =
7880 APValueToBufferConverter::convert(Info, SourceRValue, BCE);
7885 std::optional<APValue> MaybeDestValue =
7886 BufferToAPValueConverter::convert(Info, *Buffer, BCE);
7887 if (!MaybeDestValue)
7890 DestValue = std::move(*MaybeDestValue);
7894static bool handleLValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
7897 assert(
CHAR_BIT == 8 && Info.Ctx.getTargetInfo().getCharWidth() == 8 &&
7898 "no host or target supports non 8-bit chars");
7900 "LValueToRValueBitcast requires an lvalue operand!");
7902 LValue SourceLValue;
7904 SourceLValue.setFrom(Info.Ctx, SourceValue);
7907 SourceRValue,
true))
7910 return handleRValueToRValueBitCast(Info, DestValue, SourceRValue, BCE);
7913template <
class Derived>
7914class ExprEvaluatorBase
7917 Derived &getDerived() {
return static_cast<Derived&
>(*this); }
7919 return getDerived().Success(
V,
E);
7921 bool DerivedZeroInitialization(
const Expr *
E) {
7922 return getDerived().ZeroInitialization(
E);
7928 template<
typename ConditionalOperator>
7930 assert(Info.checkingPotentialConstantExpression());
7935 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
7936 StmtVisitorTy::Visit(
E->getFalseExpr());
7942 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
7944 StmtVisitorTy::Visit(
E->getTrueExpr());
7949 Error(
E, diag::note_constexpr_conditional_never_const);
7953 template<
typename ConditionalOperator>
7957 if (Info.checkingPotentialConstantExpression() && Info.noteFailure()) {
7958 CheckPotentialConstantConditional(
E);
7961 if (Info.noteFailure()) {
7962 StmtVisitorTy::Visit(
E->getTrueExpr());
7963 StmtVisitorTy::Visit(
E->getFalseExpr());
7968 Expr *EvalExpr = BoolResult ?
E->getTrueExpr() :
E->getFalseExpr();
7969 return StmtVisitorTy::Visit(EvalExpr);
7975 typedef ExprEvaluatorBase ExprEvaluatorBaseTy;
7978 return Info.CCEDiag(
E,
D);
7981 bool ZeroInitialization(
const Expr *
E) {
return Error(
E); }
7983 bool IsConstantEvaluatedBuiltinCall(
const CallExpr *
E) {
7984 unsigned BuiltinOp =
E->getBuiltinCallee();
7985 return BuiltinOp != 0 &&
7986 Info.Ctx.BuiltinInfo.isConstantEvaluated(BuiltinOp);
7990 ExprEvaluatorBase(EvalInfo &Info) : Info(Info) {}
7992 EvalInfo &getEvalInfo() {
return Info; }
8001 return Error(
E, diag::note_invalid_subexpr_in_const_expr);
8004 bool VisitStmt(
const Stmt *) {
8005 llvm_unreachable(
"Expression evaluator should not be called on stmts");
8007 bool VisitExpr(
const Expr *
E) {
8012 const auto It =
E->begin();
8013 return StmtVisitorTy::Visit(*It);
8017 return StmtVisitorTy::Visit(
E->getFunctionName());
8020 if (
E->hasAPValueResult())
8021 return DerivedSuccess(
E->getAPValueResult(),
E);
8023 return StmtVisitorTy::Visit(
E->getSubExpr());
8027 {
return StmtVisitorTy::Visit(
E->getSubExpr()); }
8029 {
return StmtVisitorTy::Visit(
E->getSubExpr()); }
8031 {
return StmtVisitorTy::Visit(
E->getSubExpr()); }
8033 {
return StmtVisitorTy::Visit(
E->getChosenSubExpr()); }
8035 {
return StmtVisitorTy::Visit(
E->getResultExpr()); }
8037 {
return StmtVisitorTy::Visit(
E->getReplacement()); }
8039 TempVersionRAII RAII(*Info.CurrentCall);
8040 SourceLocExprScopeGuard Guard(
E, Info.CurrentCall->CurSourceLocExprScope);
8041 return StmtVisitorTy::Visit(
E->getExpr());
8044 TempVersionRAII RAII(*Info.CurrentCall);
8048 SourceLocExprScopeGuard Guard(
E, Info.CurrentCall->CurSourceLocExprScope);
8049 return StmtVisitorTy::Visit(
E->getExpr());
8053 FullExpressionRAII
Scope(Info);
8054 return StmtVisitorTy::Visit(
E->getSubExpr()) &&
Scope.destroy();
8060 return StmtVisitorTy::Visit(
E->getSubExpr());
8064 CCEDiag(
E, diag::note_constexpr_invalid_cast) << 0;
8065 return static_cast<Derived*
>(
this)->VisitCastExpr(
E);
8068 if (!Info.Ctx.getLangOpts().CPlusPlus20)
8069 CCEDiag(
E, diag::note_constexpr_invalid_cast) << 1;
8070 return static_cast<Derived*
>(
this)->VisitCastExpr(
E);
8073 return static_cast<Derived*
>(
this)->VisitCastExpr(
E);
8077 switch (
E->getOpcode()) {
8082 VisitIgnoredValue(
E->getLHS());
8083 return StmtVisitorTy::Visit(
E->getRHS());
8093 return DerivedSuccess(Result,
E);
8099 return StmtVisitorTy::Visit(
E->getSemanticForm());
8106 if (!
Evaluate(Info.CurrentCall->createTemporary(
8107 E->getOpaqueValue(),
8108 getStorageType(Info.Ctx,
E->getOpaqueValue()),
8109 ScopeKind::FullExpression, CommonLV),
8110 Info,
E->getCommon()))
8113 return HandleConditionalOperator(
E);
8117 bool IsBcpCall =
false;
8124 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
8131 if (Info.checkingPotentialConstantExpression() && IsBcpCall)
8134 FoldConstant Fold(Info, IsBcpCall);
8135 if (!HandleConditionalOperator(
E)) {
8136 Fold.keepDiagnostics();
8144 if (
APValue *
Value = Info.CurrentCall->getCurrentTemporary(
E);
8146 return DerivedSuccess(*
Value,
E);
8148 const Expr *Source =
E->getSourceExpr();
8152 assert(0 &&
"OpaqueValueExpr recursively refers to itself");
8155 return StmtVisitorTy::Visit(Source);
8159 for (
const Expr *SemE :
E->semantics()) {
8160 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
8164 if (SemE ==
E->getResultExpr())
8169 if (OVE->isUnique())
8173 if (!
Evaluate(Info.CurrentCall->createTemporary(
8174 OVE, getStorageType(Info.Ctx, OVE),
8175 ScopeKind::FullExpression, LV),
8176 Info, OVE->getSourceExpr()))
8178 }
else if (SemE ==
E->getResultExpr()) {
8179 if (!StmtVisitorTy::Visit(SemE))
8191 if (!handleCallExpr(
E, Result,
nullptr))
8193 return DerivedSuccess(Result,
E);
8197 const LValue *ResultSlot) {
8198 CallScopeRAII CallScope(Info);
8204 LValue *
This =
nullptr, ThisVal;
8206 bool HasQualifier =
false;
8213 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(Callee)) {
8217 Member = dyn_cast<CXXMethodDecl>(ME->getMemberDecl());
8219 return Error(Callee);
8221 HasQualifier = ME->hasQualifier();
8222 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(Callee)) {
8228 Member = dyn_cast<CXXMethodDecl>(
D);
8230 return Error(Callee);
8232 }
else if (
const auto *PDE = dyn_cast<CXXPseudoDestructorExpr>(Callee)) {
8233 if (!Info.getLangOpts().CPlusPlus20)
8234 Info.CCEDiag(PDE, diag::note_constexpr_pseudo_destructor);
8238 return Error(Callee);
8245 if (!CalleeLV.getLValueOffset().isZero())
8246 return Error(Callee);
8247 if (CalleeLV.isNullPointer()) {
8248 Info.FFDiag(Callee, diag::note_constexpr_null_callee)
8252 FD = dyn_cast_or_null<FunctionDecl>(
8253 CalleeLV.getLValueBase().dyn_cast<
const ValueDecl *>());
8255 return Error(Callee);
8258 if (!Info.Ctx.hasSameFunctionTypeIgnoringExceptionSpec(
8265 auto *OCE = dyn_cast<CXXOperatorCallExpr>(
E);
8266 if (OCE && OCE->isAssignmentOp()) {
8267 assert(Args.size() == 2 &&
"wrong number of arguments in assignment");
8268 Call = Info.CurrentCall->createCall(FD);
8269 bool HasThis =
false;
8270 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FD))
8271 HasThis = MD->isImplicitObjectMemberFunction();
8299 if (Info.getLangOpts().CPlusPlus20 && OCE &&
8300 OCE->getOperator() == OO_Equal && MD->
isTrivial() &&
8304 Args = Args.slice(1);
8313 "Number of captures must be zero for conversion to function-ptr");
8324 "A generic lambda's static-invoker function must be a "
8325 "template specialization");
8329 void *InsertPos =
nullptr;
8332 assert(CorrespondingCallOpSpecialization &&
8333 "We must always have a function call operator specialization "
8334 "that corresponds to our static invoker specialization");
8335 assert(isa<CXXMethodDecl>(CorrespondingCallOpSpecialization));
8336 FD = CorrespondingCallOpSpecialization;
8345 Ptr.moveInto(Result);
8346 return CallScope.destroy();
8356 Call = Info.CurrentCall->createCall(FD);
8363 auto *NamedMember = dyn_cast<CXXMethodDecl>(FD);
8364 if (NamedMember && NamedMember->isVirtual() && !HasQualifier) {
8367 CovariantAdjustmentPath);
8370 }
else if (NamedMember && NamedMember->isImplicitObjectMemberFunction()) {
8380 if (
auto *DD = dyn_cast<CXXDestructorDecl>(FD)) {
8381 assert(This &&
"no 'this' pointer for destructor call");
8383 Info.Ctx.getRecordType(DD->getParent())) &&
8384 CallScope.destroy();
8392 Body, Info, Result, ResultSlot))
8395 if (!CovariantAdjustmentPath.empty() &&
8397 CovariantAdjustmentPath))
8400 return CallScope.destroy();
8404 return StmtVisitorTy::Visit(
E->getInitializer());
8407 if (
E->getNumInits() == 0)
8408 return DerivedZeroInitialization(
E);
8409 if (
E->getNumInits() == 1)
8410 return StmtVisitorTy::Visit(
E->getInit(0));
8414 return DerivedZeroInitialization(
E);
8417 return DerivedZeroInitialization(
E);
8420 return DerivedZeroInitialization(
E);
8425 assert(!Info.Ctx.getLangOpts().CPlusPlus11 &&
8426 "missing temporary materialization conversion");
8427 assert(!
E->isArrow() &&
"missing call to bound member function?");
8435 const FieldDecl *FD = dyn_cast<FieldDecl>(
E->getMemberDecl());
8436 if (!FD)
return Error(
E);
8450 DerivedSuccess(Result,
E);
8460 E->getEncodedElementAccess(Indices);
8461 if (Indices.size() == 1) {
8467 for (
unsigned I = 0; I < Indices.size(); ++I) {
8470 APValue VecResult(Elts.data(), Indices.size());
8471 return DerivedSuccess(VecResult,
E);
8479 switch (
E->getCastKind()) {
8483 case CK_AtomicToNonAtomic: {
8488 if (!
Evaluate(AtomicVal, Info,
E->getSubExpr()))
8490 return DerivedSuccess(AtomicVal,
E);
8494 case CK_UserDefinedConversion:
8495 return StmtVisitorTy::Visit(
E->getSubExpr());
8497 case CK_LValueToRValue: {
8506 return DerivedSuccess(RVal,
E);
8508 case CK_LValueToRValueBitCast: {
8509 APValue DestValue, SourceValue;
8510 if (!
Evaluate(SourceValue, Info,
E->getSubExpr()))
8512 if (!handleLValueToRValueBitCast(Info, DestValue, SourceValue,
E))
8514 return DerivedSuccess(DestValue,
E);
8517 case CK_AddressSpaceConversion: {
8521 return DerivedSuccess(
Value,
E);
8529 return VisitUnaryPostIncDec(UO);
8532 return VisitUnaryPostIncDec(UO);
8535 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
8545 return DerivedSuccess(RVal, UO);
8558 BlockScopeRAII
Scope(Info);
8563 const Expr *FinalExpr = dyn_cast<Expr>(*BI);
8565 Info.FFDiag((*BI)->getBeginLoc(),
8566 diag::note_constexpr_stmt_expr_unsupported);
8569 return this->Visit(FinalExpr) &&
Scope.destroy();
8575 if (ESR != ESR_Succeeded) {
8579 if (ESR != ESR_Failed)
8580 Info.FFDiag((*BI)->getBeginLoc(),
8581 diag::note_constexpr_stmt_expr_unsupported);
8586 llvm_unreachable(
"Return from function from the loop above.");
8590 return StmtVisitorTy::Visit(
E->getSelectedExpr());
8594 void VisitIgnoredValue(
const Expr *
E) {
8599 void VisitIgnoredBaseExpression(
const Expr *
E) {
8604 VisitIgnoredValue(
E);
8614template<
class Derived>
8615class LValueExprEvaluatorBase
8616 :
public ExprEvaluatorBase<Derived> {
8620 typedef LValueExprEvaluatorBase LValueExprEvaluatorBaseTy;
8621 typedef ExprEvaluatorBase<Derived> ExprEvaluatorBaseTy;
8628 bool evaluatePointer(
const Expr *
E, LValue &Result) {
8633 LValueExprEvaluatorBase(EvalInfo &Info, LValue &Result,
bool InvalidBaseOK)
8634 : ExprEvaluatorBaseTy(Info), Result(Result),
8635 InvalidBaseOK(InvalidBaseOK) {}
8638 Result.setFrom(this->Info.Ctx,
V);
8647 EvalOK = evaluatePointer(
E->getBase(), Result);
8654 EvalOK = this->Visit(
E->getBase());
8660 Result.setInvalid(
E);
8665 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(
E->getMemberDecl())) {
8688 switch (
E->getOpcode()) {
8690 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
8699 switch (
E->getCastKind()) {
8701 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
8703 case CK_DerivedToBase:
8704 case CK_UncheckedDerivedToBase:
8705 if (!this->Visit(
E->getSubExpr()))
8751class LValueExprEvaluator
8752 :
public LValueExprEvaluatorBase<LValueExprEvaluator> {
8754 LValueExprEvaluator(EvalInfo &Info, LValue &Result,
bool InvalidBaseOK) :
8755 LValueExprEvaluatorBaseTy(Info, Result, InvalidBaseOK) {}
8768 E, 0, Info.getASTContext().getNextStringLiteralVersion()));
8779 return VisitUnaryPreIncDec(UO);
8782 return VisitUnaryPreIncDec(UO);
8788 switch (
E->getCastKind()) {
8790 return LValueExprEvaluatorBaseTy::VisitCastExpr(
E);
8792 case CK_LValueBitCast:
8793 this->CCEDiag(
E, diag::note_constexpr_invalid_cast)
8794 << 2 << Info.Ctx.getLangOpts().CPlusPlus;
8795 if (!Visit(
E->getSubExpr()))
8797 Result.Designator.setInvalid();
8800 case CK_BaseToDerived:
8801 if (!Visit(
E->getSubExpr()))
8806 if (!Visit(
E->getSubExpr()))
8817 bool LValueToRValueConversion) {
8821 assert(Info.CurrentCall->This ==
nullptr &&
8822 "This should not be set for a static call operator");
8830 if (Self->getType()->isReferenceType()) {
8831 APValue *RefValue = Info.getParamSlot(Info.CurrentCall->Arguments, Self);
8833 Result.setFrom(Info.Ctx, *RefValue);
8835 const ParmVarDecl *VD = Info.CurrentCall->Arguments.getOrigParam(Self);
8836 CallStackFrame *Frame =
8837 Info.getCallFrameAndDepth(Info.CurrentCall->Arguments.CallIndex)
8839 unsigned Version = Info.CurrentCall->Arguments.Version;
8840 Result.set({VD, Frame->Index, Version});
8843 Result = *Info.CurrentCall->This;
8853 if (LValueToRValueConversion) {
8857 Result.setFrom(Info.Ctx, RVal);
8868 bool InvalidBaseOK) {
8872 return LValueExprEvaluator(Info, Result, InvalidBaseOK).Visit(
E);
8875bool LValueExprEvaluator::VisitDeclRefExpr(
const DeclRefExpr *
E) {
8879 return Success(cast<ValueDecl>(
D));
8880 if (
const VarDecl *VD = dyn_cast<VarDecl>(
D))
8881 return VisitVarDecl(
E, VD);
8883 return Visit(BD->getBinding());
8888bool LValueExprEvaluator::VisitVarDecl(
const Expr *
E,
const VarDecl *VD) {
8891 bool AllowConstexprUnknown =
8898 isa<DeclRefExpr>(
E) &&
8899 cast<DeclRefExpr>(
E)->refersToEnclosingVariableOrCapture()) {
8904 if (Info.checkingPotentialConstantExpression())
8907 if (
auto *FD = Info.CurrentCall->LambdaCaptureFields.lookup(VD)) {
8908 const auto *MD = cast<CXXMethodDecl>(Info.CurrentCall->Callee);
8914 CallStackFrame *Frame =
nullptr;
8915 unsigned Version = 0;
8923 CallStackFrame *CurrFrame = Info.CurrentCall;
8924 if (CurrFrame->Callee && CurrFrame->Callee->Equals(VD->
getDeclContext())) {
8928 if (
auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
8929 if (CurrFrame->Arguments) {
8930 VD = CurrFrame->Arguments.getOrigParam(PVD);
8932 Info.getCallFrameAndDepth(CurrFrame->Arguments.CallIndex).first;
8933 Version = CurrFrame->Arguments.Version;
8937 Version = CurrFrame->getCurrentTemporaryVersion(VD);
8944 Result.set({VD, Frame->Index, Version});
8950 if (!Info.getLangOpts().CPlusPlus11) {
8951 Info.CCEDiag(
E, diag::note_constexpr_ltor_non_integral, 1)
8953 Info.Note(VD->
getLocation(), diag::note_declared_at);
8959 if (!
V->hasValue()) {
8965 if (!Info.checkingPotentialConstantExpression() && !AllowConstexprUnknown)
8966 Info.FFDiag(
E, diag::note_constexpr_use_uninit_reference);
8972 Result.set({VD, Frame->Index, Version});
8983bool LValueExprEvaluator::VisitCallExpr(
const CallExpr *
E) {
8984 if (!IsConstantEvaluatedBuiltinCall(
E))
8985 return ExprEvaluatorBaseTy::VisitCallExpr(
E);
8987 switch (
E->getBuiltinCallee()) {
8990 case Builtin::BIas_const:
8991 case Builtin::BIforward:
8992 case Builtin::BIforward_like:
8993 case Builtin::BImove:
8994 case Builtin::BImove_if_noexcept:
8995 if (cast<FunctionDecl>(
E->getCalleeDecl())->isConstexpr())
8996 return Visit(
E->getArg(0));
9000 return ExprEvaluatorBaseTy::VisitCallExpr(
E);
9003bool LValueExprEvaluator::VisitMaterializeTemporaryExpr(
9012 for (
const Expr *
E : CommaLHSs)
9021 if (Info.EvalMode == EvalInfo::EM_ConstantFold)
9024 Value =
E->getOrCreateValue(
true);
9028 Value = &Info.CurrentCall->createTemporary(
9029 E, Inner->getType(),
9044 for (
unsigned I = Adjustments.size(); I != 0; ) {
9046 switch (Adjustments[I].Kind) {
9051 Type = Adjustments[I].DerivedToBase.BasePath->getType();
9057 Type = Adjustments[I].Field->getType();
9062 Adjustments[I].Ptr.RHS))
9064 Type = Adjustments[I].Ptr.MPT->getPointeeType();
9074 assert((!Info.getLangOpts().CPlusPlus ||
E->isFileScope()) &&
9075 "lvalue compound literal in c++?");
9081bool LValueExprEvaluator::VisitCXXTypeidExpr(
const CXXTypeidExpr *
E) {
9084 if (!
E->isPotentiallyEvaluated()) {
9085 if (
E->isTypeOperand())
9090 if (!Info.Ctx.getLangOpts().CPlusPlus20) {
9091 Info.CCEDiag(
E, diag::note_constexpr_typeid_polymorphic)
9096 if (!Visit(
E->getExprOperand()))
9099 std::optional<DynamicType> DynType =
9105 TypeInfoLValue(Info.Ctx.getRecordType(DynType->Type).getTypePtr());
9111bool LValueExprEvaluator::VisitCXXUuidofExpr(
const CXXUuidofExpr *
E) {
9115bool LValueExprEvaluator::VisitMemberExpr(
const MemberExpr *
E) {
9117 if (
const VarDecl *VD = dyn_cast<VarDecl>(
E->getMemberDecl())) {
9118 VisitIgnoredBaseExpression(
E->getBase());
9119 return VisitVarDecl(
E, VD);
9123 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(
E->getMemberDecl())) {
9124 if (MD->isStatic()) {
9125 VisitIgnoredBaseExpression(
E->getBase());
9131 return LValueExprEvaluatorBaseTy::VisitMemberExpr(
E);
9134bool LValueExprEvaluator::VisitExtVectorElementExpr(
9139 if (!
Evaluate(Val, Info,
E->getBase())) {
9140 if (!Info.noteFailure())
9146 E->getEncodedElementAccess(Indices);
9148 if (Indices.size() > 1)
9152 Result.setFrom(Info.Ctx, Val);
9155 VT->getNumElements(), Indices[0]);
9170 if (!
Evaluate(Val, Info,
E->getBase())) {
9171 if (!Info.noteFailure())
9177 if (!Info.noteFailure())
9183 Result.setFrom(Info.Ctx, Val);
9185 VT->getNumElements(), Index.getExtValue());
9193 for (
const Expr *SubExpr : {
E->getLHS(),
E->getRHS()}) {
9194 if (SubExpr ==
E->getBase() ? !evaluatePointer(SubExpr, Result)
9196 if (!Info.noteFailure())
9206bool LValueExprEvaluator::VisitUnaryDeref(
const UnaryOperator *
E) {
9207 return evaluatePointer(
E->getSubExpr(), Result);
9210bool LValueExprEvaluator::VisitUnaryReal(
const UnaryOperator *
E) {
9211 if (!Visit(
E->getSubExpr()))
9219bool LValueExprEvaluator::VisitUnaryImag(
const UnaryOperator *
E) {
9221 "lvalue __imag__ on scalar?");
9222 if (!Visit(
E->getSubExpr()))
9228bool LValueExprEvaluator::VisitUnaryPreIncDec(
const UnaryOperator *UO) {
9229 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9240bool LValueExprEvaluator::VisitCompoundAssignOperator(
9242 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9250 if (!Info.noteFailure())
9266 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9273 if (!
Evaluate(NewVal, this->Info,
E->getRHS())) {
9274 if (!Info.noteFailure())
9279 if (!this->Visit(
E->getLHS()) || !
Success)
9282 if (Info.getLangOpts().CPlusPlus20 &&
9302 llvm::APInt &Result) {
9303 const AllocSizeAttr *AllocSize = getAllocSizeAttr(
Call);
9305 assert(AllocSize && AllocSize->getElemSizeParam().isValid());
9306 unsigned SizeArgNo = AllocSize->getElemSizeParam().getASTIndex();
9308 if (
Call->getNumArgs() <= SizeArgNo)
9311 auto EvaluateAsSizeT = [&](
const Expr *
E,
APSInt &Into) {
9316 if (Into.isNegative() || !Into.isIntN(BitsInSizeT))
9318 Into = Into.zext(BitsInSizeT);
9323 if (!EvaluateAsSizeT(
Call->getArg(SizeArgNo), SizeOfElem))
9326 if (!AllocSize->getNumElemsParam().isValid()) {
9327 Result = std::move(SizeOfElem);
9332 unsigned NumArgNo = AllocSize->getNumElemsParam().getASTIndex();
9333 if (!EvaluateAsSizeT(
Call->getArg(NumArgNo), NumberOfElems))
9337 llvm::APInt BytesAvailable = SizeOfElem.umul_ov(NumberOfElems, Overflow);
9341 Result = std::move(BytesAvailable);
9349 llvm::APInt &Result) {
9350 assert(isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
9351 "Can't get the size of a non alloc_size function");
9352 const auto *
Base = LVal.getLValueBase().get<
const Expr *>();
9372 dyn_cast_or_null<VarDecl>(
Base.dyn_cast<
const ValueDecl *>());
9377 if (!
Init ||
Init->getType().isNull())
9381 if (!tryUnwrapAllocSizeCall(
E))
9386 Result.setInvalid(
E);
9389 Result.addUnsizedArray(Info,
E, Pointee);
9394class PointerExprEvaluator
9395 :
public ExprEvaluatorBase<PointerExprEvaluator> {
9404 bool evaluateLValue(
const Expr *
E, LValue &Result) {
9408 bool evaluatePointer(
const Expr *
E, LValue &Result) {
9412 bool visitNonBuiltinCallExpr(
const CallExpr *
E);
9415 PointerExprEvaluator(EvalInfo &info, LValue &Result,
bool InvalidBaseOK)
9416 : ExprEvaluatorBaseTy(info), Result(Result),
9417 InvalidBaseOK(InvalidBaseOK) {}
9420 Result.setFrom(Info.Ctx,
V);
9423 bool ZeroInitialization(
const Expr *
E) {
9424 Result.setNull(Info.Ctx,
E->
getType());
9434 if (
E->isExpressibleAsConstantInitializer())
9436 if (Info.noteFailure())
9443 bool VisitBuiltinCallExpr(
const CallExpr *
E,
unsigned BuiltinOp);
9445 if (!
E->getBlockDecl()->hasCaptures())
9450 auto DiagnoseInvalidUseOfThis = [&] {
9451 if (Info.getLangOpts().CPlusPlus11)
9452 Info.FFDiag(
E, diag::note_constexpr_this) <<
E->isImplicit();
9458 if (Info.checkingPotentialConstantExpression())
9461 bool IsExplicitLambda =
9463 if (!IsExplicitLambda) {
9464 if (!Info.CurrentCall->This) {
9465 DiagnoseInvalidUseOfThis();
9469 Result = *Info.CurrentCall->This;
9477 if (!Info.CurrentCall->LambdaThisCaptureField) {
9478 if (IsExplicitLambda && !Info.CurrentCall->This) {
9479 DiagnoseInvalidUseOfThis();
9486 const auto *MD = cast<CXXMethodDecl>(Info.CurrentCall->Callee);
9488 Info,
E, Result, MD, Info.CurrentCall->LambdaThisCaptureField,
9497 assert(!
E->isIntType() &&
"SourceLocExpr isn't a pointer type?");
9498 APValue LValResult =
E->EvaluateInContext(
9499 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.getDefaultExpr());
9500 Result.setFrom(Info.Ctx, LValResult);
9505 llvm::report_fatal_error(
"Not yet implemented for ExprConstant.cpp");
9510 std::string ResultStr =
E->ComputeName(Info.Ctx);
9513 APInt Size(Info.Ctx.getTypeSize(Info.Ctx.getSizeType()),
9514 ResultStr.size() + 1);
9515 QualType ArrayTy = Info.Ctx.getConstantArrayType(
9516 CharTy, Size,
nullptr, ArraySizeModifier::Normal, 0);
9520 false, ArrayTy,
E->getLocation());
9522 evaluateLValue(SL, Result);
9523 Result.addArray(Info,
E, cast<ConstantArrayType>(ArrayTy));
9532 bool InvalidBaseOK) {
9535 return PointerExprEvaluator(Info, Result, InvalidBaseOK).Visit(
E);
9538bool PointerExprEvaluator::VisitBinaryOperator(
const BinaryOperator *
E) {
9539 if (
E->getOpcode() != BO_Add &&
9540 E->getOpcode() != BO_Sub)
9541 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
9543 const Expr *PExp =
E->getLHS();
9544 const Expr *IExp =
E->getRHS();
9546 std::swap(PExp, IExp);
9548 bool EvalPtrOK = evaluatePointer(PExp, Result);
9549 if (!EvalPtrOK && !Info.noteFailure())
9552 llvm::APSInt Offset;
9556 if (
E->getOpcode() == BO_Sub)
9563bool PointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *
E) {
9564 return evaluateLValue(
E->getSubExpr(), Result);
9572 if (!FnII || !FnII->
isStr(
"current"))
9575 const auto *RD = dyn_cast<RecordDecl>(FD->
getParent());
9583bool PointerExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
9584 const Expr *SubExpr =
E->getSubExpr();
9586 switch (
E->getCastKind()) {
9590 case CK_CPointerToObjCPointerCast:
9591 case CK_BlockPointerToObjCPointerCast:
9592 case CK_AnyPointerToBlockPointerCast:
9593 case CK_AddressSpaceConversion:
9594 if (!Visit(SubExpr))
9602 bool HasValidResult = !Result.InvalidBase && !Result.Designator.Invalid &&
9604 bool VoidPtrCastMaybeOK =
9607 Info.Ctx.hasSimilarType(Result.Designator.getType(Info.Ctx),
9616 if (VoidPtrCastMaybeOK &&
9617 (Info.getStdAllocatorCaller(
"allocate") ||
9619 Info.getLangOpts().CPlusPlus26)) {
9623 Info.getLangOpts().CPlusPlus) {
9625 CCEDiag(
E, diag::note_constexpr_invalid_void_star_cast)
9626 << SubExpr->
getType() << Info.getLangOpts().CPlusPlus26
9627 << Result.Designator.getType(Info.Ctx).getCanonicalType()
9630 CCEDiag(
E, diag::note_constexpr_invalid_cast)
9633 CCEDiag(
E, diag::note_constexpr_invalid_cast)
9634 << 2 << Info.Ctx.getLangOpts().CPlusPlus;
9635 Result.Designator.setInvalid();
9638 if (
E->getCastKind() == CK_AddressSpaceConversion && Result.IsNullPtr)
9639 ZeroInitialization(
E);
9642 case CK_DerivedToBase:
9643 case CK_UncheckedDerivedToBase:
9644 if (!evaluatePointer(
E->getSubExpr(), Result))
9646 if (!Result.Base && Result.Offset.isZero())
9655 case CK_BaseToDerived:
9656 if (!Visit(
E->getSubExpr()))
9658 if (!Result.Base && Result.Offset.isZero())
9663 if (!Visit(
E->getSubExpr()))
9667 case CK_NullToPointer:
9668 VisitIgnoredValue(
E->getSubExpr());
9669 return ZeroInitialization(
E);
9671 case CK_IntegralToPointer: {
9672 CCEDiag(
E, diag::note_constexpr_invalid_cast)
9673 << 2 << Info.Ctx.getLangOpts().CPlusPlus;
9679 if (
Value.isInt()) {
9681 uint64_t N =
Value.getInt().extOrTrunc(Size).getZExtValue();
9682 Result.Base = (
Expr*)
nullptr;
9683 Result.InvalidBase =
false;
9685 Result.Designator.setInvalid();
9686 Result.IsNullPtr =
false;
9693 if (!
Value.isLValue())
9697 Result.setFrom(Info.Ctx,
Value);
9702 case CK_ArrayToPointerDecay: {
9704 if (!evaluateLValue(SubExpr, Result))
9708 SubExpr, SubExpr->
getType(), ScopeKind::FullExpression, Result);
9713 auto *AT = Info.Ctx.getAsArrayType(SubExpr->
getType());
9714 if (
auto *CAT = dyn_cast<ConstantArrayType>(AT))
9715 Result.addArray(Info,
E, CAT);
9717 Result.addUnsizedArray(Info,
E, AT->getElementType());
9721 case CK_FunctionToPointerDecay:
9722 return evaluateLValue(SubExpr, Result);
9724 case CK_LValueToRValue: {
9726 if (!evaluateLValue(
E->getSubExpr(), LVal))
9733 return InvalidBaseOK &&
9739 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
9747 T =
T.getNonReferenceType();
9749 if (
T.getQualifiers().hasUnaligned())
9752 const bool AlignOfReturnsPreferred =
9753 Ctx.
getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver7;
9758 if (ExprKind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
9761 else if (ExprKind == UETT_AlignOf)
9764 llvm_unreachable(
"GetAlignOfType on a non-alignment ExprKind");
9781 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(
E))
9790 return Info.Ctx.getDeclAlign(VD);
9791 if (
const auto *
E =
Value.Base.dyn_cast<
const Expr *>())
9799 EvalInfo &Info,
APSInt &Alignment) {
9802 if (Alignment < 0 || !Alignment.isPowerOf2()) {
9803 Info.FFDiag(
E, diag::note_constexpr_invalid_alignment) << Alignment;
9806 unsigned SrcWidth = Info.Ctx.getIntWidth(ForType);
9807 APSInt MaxValue(APInt::getOneBitSet(SrcWidth, SrcWidth - 1));
9808 if (APSInt::compareValues(Alignment, MaxValue) > 0) {
9809 Info.FFDiag(
E, diag::note_constexpr_alignment_too_big)
9810 << MaxValue << ForType << Alignment;
9816 APSInt(Alignment.zextOrTrunc(SrcWidth),
true);
9817 assert(APSInt::compareValues(Alignment, ExtAlignment) == 0 &&
9818 "Alignment should not be changed by ext/trunc");
9819 Alignment = ExtAlignment;
9820 assert(Alignment.getBitWidth() == SrcWidth);
9825bool PointerExprEvaluator::visitNonBuiltinCallExpr(
const CallExpr *
E) {
9826 if (ExprEvaluatorBaseTy::VisitCallExpr(
E))
9829 if (!(InvalidBaseOK && getAllocSizeAttr(
E)))
9832 Result.setInvalid(
E);
9834 Result.addUnsizedArray(Info,
E, PointeeTy);
9838bool PointerExprEvaluator::VisitCallExpr(
const CallExpr *
E) {
9839 if (!IsConstantEvaluatedBuiltinCall(
E))
9840 return visitNonBuiltinCallExpr(
E);
9841 return VisitBuiltinCallExpr(
E,
E->getBuiltinCallee());
9850bool PointerExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *
E,
9851 unsigned BuiltinOp) {
9855 switch (BuiltinOp) {
9856 case Builtin::BIaddressof:
9857 case Builtin::BI__addressof:
9858 case Builtin::BI__builtin_addressof:
9859 return evaluateLValue(
E->getArg(0), Result);
9860 case Builtin::BI__builtin_assume_aligned: {
9864 if (!evaluatePointer(
E->getArg(0), Result))
9867 LValue OffsetResult(Result);
9874 if (
E->getNumArgs() > 2) {
9879 int64_t AdditionalOffset = -Offset.getZExtValue();
9884 if (OffsetResult.Base) {
9887 if (BaseAlignment < Align) {
9888 Result.Designator.setInvalid();
9889 CCEDiag(
E->getArg(0), diag::note_constexpr_baa_insufficient_alignment)
9896 if (OffsetResult.Offset.alignTo(Align) != OffsetResult.Offset) {
9897 Result.Designator.setInvalid();
9900 ? CCEDiag(
E->getArg(0),
9901 diag::note_constexpr_baa_insufficient_alignment)
9903 : CCEDiag(
E->getArg(0),
9904 diag::note_constexpr_baa_value_insufficient_alignment))
9905 << OffsetResult.Offset.getQuantity() << Align.
getQuantity();
9911 case Builtin::BI__builtin_align_up:
9912 case Builtin::BI__builtin_align_down: {
9913 if (!evaluatePointer(
E->getArg(0), Result))
9932 assert(Alignment.getBitWidth() <= 64 &&
9933 "Cannot handle > 64-bit address-space");
9934 uint64_t Alignment64 = Alignment.getZExtValue();
9936 BuiltinOp == Builtin::BI__builtin_align_down
9937 ? llvm::alignDown(Result.Offset.getQuantity(), Alignment64)
9938 : llvm::alignTo(Result.Offset.getQuantity(), Alignment64));
9939 Result.adjustOffset(NewOffset - Result.Offset);
9944 Info.FFDiag(
E->getArg(0), diag::note_constexpr_alignment_adjust)
9948 case Builtin::BI__builtin_operator_new:
9950 case Builtin::BI__builtin_launder:
9951 return evaluatePointer(
E->getArg(0), Result);
9952 case Builtin::BIstrchr:
9953 case Builtin::BIwcschr:
9954 case Builtin::BImemchr:
9955 case Builtin::BIwmemchr:
9956 if (Info.getLangOpts().CPlusPlus11)
9957 Info.CCEDiag(
E, diag::note_constexpr_invalid_function)
9959 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
9961 Info.CCEDiag(
E, diag::note_invalid_subexpr_in_const_expr);
9963 case Builtin::BI__builtin_strchr:
9964 case Builtin::BI__builtin_wcschr:
9965 case Builtin::BI__builtin_memchr:
9966 case Builtin::BI__builtin_char_memchr:
9967 case Builtin::BI__builtin_wmemchr: {
9968 if (!Visit(
E->getArg(0)))
9974 if (BuiltinOp != Builtin::BIstrchr &&
9975 BuiltinOp != Builtin::BIwcschr &&
9976 BuiltinOp != Builtin::BI__builtin_strchr &&
9977 BuiltinOp != Builtin::BI__builtin_wcschr) {
9981 MaxLength = N.getZExtValue();
9984 if (MaxLength == 0u)
9985 return ZeroInitialization(
E);
9986 if (!Result.checkNullPointerForFoldAccess(Info,
E,
AK_Read) ||
9987 Result.Designator.Invalid)
9989 QualType CharTy = Result.Designator.getType(Info.Ctx);
9990 bool IsRawByte = BuiltinOp == Builtin::BImemchr ||
9991 BuiltinOp == Builtin::BI__builtin_memchr;
9993 Info.Ctx.hasSameUnqualifiedType(
9997 Info.FFDiag(
E, diag::note_constexpr_ltor_incomplete_type) << CharTy;
10003 Info.FFDiag(
E, diag::note_constexpr_memchr_unsupported)
10004 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp) << CharTy;
10010 bool StopAtNull =
false;
10011 switch (BuiltinOp) {
10012 case Builtin::BIstrchr:
10013 case Builtin::BI__builtin_strchr:
10020 return ZeroInitialization(
E);
10023 case Builtin::BImemchr:
10024 case Builtin::BI__builtin_memchr:
10025 case Builtin::BI__builtin_char_memchr:
10029 DesiredVal = Desired.trunc(Info.Ctx.getCharWidth()).getZExtValue();
10032 case Builtin::BIwcschr:
10033 case Builtin::BI__builtin_wcschr:
10036 case Builtin::BIwmemchr:
10037 case Builtin::BI__builtin_wmemchr:
10039 DesiredVal = Desired.getZExtValue();
10043 for (; MaxLength; --MaxLength) {
10048 if (Char.
getInt().getZExtValue() == DesiredVal)
10050 if (StopAtNull && !Char.
getInt())
10056 return ZeroInitialization(
E);
10059 case Builtin::BImemcpy:
10060 case Builtin::BImemmove:
10061 case Builtin::BIwmemcpy:
10062 case Builtin::BIwmemmove:
10063 if (Info.getLangOpts().CPlusPlus11)
10064 Info.CCEDiag(
E, diag::note_constexpr_invalid_function)
10066 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
10068 Info.CCEDiag(
E, diag::note_invalid_subexpr_in_const_expr);
10070 case Builtin::BI__builtin_memcpy:
10071 case Builtin::BI__builtin_memmove:
10072 case Builtin::BI__builtin_wmemcpy:
10073 case Builtin::BI__builtin_wmemmove: {
10074 bool WChar = BuiltinOp == Builtin::BIwmemcpy ||
10075 BuiltinOp == Builtin::BIwmemmove ||
10076 BuiltinOp == Builtin::BI__builtin_wmemcpy ||
10077 BuiltinOp == Builtin::BI__builtin_wmemmove;
10078 bool Move = BuiltinOp == Builtin::BImemmove ||
10079 BuiltinOp == Builtin::BIwmemmove ||
10080 BuiltinOp == Builtin::BI__builtin_memmove ||
10081 BuiltinOp == Builtin::BI__builtin_wmemmove;
10084 if (!Visit(
E->getArg(0)))
10086 LValue Dest = Result;
10095 assert(!N.isSigned() &&
"memcpy and friends take an unsigned size");
10105 if (!Src.Base || !Dest.Base) {
10107 (!Src.Base ? Src : Dest).moveInto(Val);
10108 Info.FFDiag(
E, diag::note_constexpr_memcpy_null)
10109 <<
Move << WChar << !!Src.Base
10113 if (Src.Designator.Invalid || Dest.Designator.Invalid)
10119 QualType T = Dest.Designator.getType(Info.Ctx);
10120 QualType SrcT = Src.Designator.getType(Info.Ctx);
10121 if (!Info.Ctx.hasSameUnqualifiedType(
T, SrcT)) {
10123 Info.FFDiag(
E, diag::note_constexpr_memcpy_type_pun) <<
Move << SrcT <<
T;
10127 Info.FFDiag(
E, diag::note_constexpr_memcpy_incomplete_type) <<
Move <<
T;
10130 if (!
T.isTriviallyCopyableType(Info.Ctx)) {
10131 Info.FFDiag(
E, diag::note_constexpr_memcpy_nontrivial) <<
Move <<
T;
10136 uint64_t TSize = Info.Ctx.getTypeSizeInChars(
T).getQuantity();
10141 llvm::APInt OrigN = N;
10142 llvm::APInt::udivrem(OrigN, TSize, N, Remainder);
10144 Info.FFDiag(
E, diag::note_constexpr_memcpy_unsupported)
10154 uint64_t RemainingSrcSize = Src.Designator.validIndexAdjustments().second;
10155 uint64_t RemainingDestSize = Dest.Designator.validIndexAdjustments().second;
10156 if (N.ugt(RemainingSrcSize) || N.ugt(RemainingDestSize)) {
10157 Info.FFDiag(
E, diag::note_constexpr_memcpy_unsupported)
10158 <<
Move << WChar << (N.ugt(RemainingSrcSize) ? 1 : 2) <<
T
10162 uint64_t NElems = N.getZExtValue();
10168 uint64_t SrcOffset = Src.getLValueOffset().getQuantity();
10169 uint64_t DestOffset = Dest.getLValueOffset().getQuantity();
10170 if (DestOffset >= SrcOffset && DestOffset - SrcOffset < NBytes) {
10173 Info.FFDiag(
E, diag::note_constexpr_memcpy_overlap) << WChar;
10181 }
else if (!Move && SrcOffset >= DestOffset &&
10182 SrcOffset - DestOffset < NBytes) {
10184 Info.FFDiag(
E, diag::note_constexpr_memcpy_overlap) << WChar;
10219bool PointerExprEvaluator::VisitCXXNewExpr(
const CXXNewExpr *
E) {
10220 if (!Info.getLangOpts().CPlusPlus20)
10221 Info.CCEDiag(
E, diag::note_constexpr_new);
10224 if (Info.SpeculativeEvaluationDepth)
10228 QualType AllocType =
E->getAllocatedType();
10231 bool IsNothrow =
false;
10232 bool IsPlacement =
false;
10234 if (
E->getNumPlacementArgs() == 1 &&
10250 }
else if (OperatorNew->isReservedGlobalPlacementOperator()) {
10251 if (Info.CurrentCall->isStdFunction() || Info.getLangOpts().CPlusPlus26 ||
10252 (Info.CurrentCall->CanEvalMSConstexpr &&
10253 OperatorNew->hasAttr<MSConstexprAttr>())) {
10256 if (Result.Designator.Invalid)
10258 TargetType =
E->getPlacementArg(0)->
getType();
10259 IsPlacement =
true;
10261 Info.FFDiag(
E, diag::note_constexpr_new_placement)
10265 }
else if (
E->getNumPlacementArgs()) {
10266 Info.FFDiag(
E, diag::note_constexpr_new_placement)
10269 }
else if (!OperatorNew->isReplaceableGlobalAllocationFunction()) {
10270 Info.FFDiag(
E, diag::note_constexpr_new_non_replaceable)
10271 << isa<CXXMethodDecl>(OperatorNew) << OperatorNew;
10275 const Expr *
Init =
E->getInitializer();
10278 bool ValueInit =
false;
10280 if (std::optional<const Expr *> ArraySize =
E->getArraySize()) {
10281 const Expr *Stripped = *ArraySize;
10282 for (;
auto *ICE = dyn_cast<ImplicitCastExpr>(Stripped);
10283 Stripped = ICE->getSubExpr())
10284 if (ICE->getCastKind() != CK_NoOp &&
10285 ICE->getCastKind() != CK_IntegralCast)
10288 llvm::APSInt ArrayBound;
10296 if (ArrayBound.isSigned() && ArrayBound.isNegative()) {
10298 return ZeroInitialization(
E);
10300 Info.FFDiag(*ArraySize, diag::note_constexpr_new_negative)
10301 << ArrayBound << (*ArraySize)->getSourceRange();
10307 if (!Info.CheckArraySize(ArraySize.value()->getExprLoc(),
10309 Info.Ctx, AllocType, ArrayBound),
10310 ArrayBound.getZExtValue(), !IsNothrow)) {
10312 return ZeroInitialization(
E);
10321 }
else if (isa<CXXScalarValueInitExpr>(
Init) ||
10322 isa<ImplicitValueInitExpr>(
Init)) {
10324 }
else if (
auto *CCE = dyn_cast<CXXConstructExpr>(
Init)) {
10325 ResizedArrayCCE = CCE;
10327 auto *CAT = Info.Ctx.getAsConstantArrayType(
Init->getType());
10328 assert(CAT &&
"unexpected type for array initializer");
10332 llvm::APInt InitBound = CAT->
getSize().zext(Bits);
10333 llvm::APInt AllocBound = ArrayBound.zext(Bits);
10334 if (InitBound.ugt(AllocBound)) {
10336 return ZeroInitialization(
E);
10338 Info.FFDiag(*ArraySize, diag::note_constexpr_new_too_small)
10339 <<
toString(AllocBound, 10,
false)
10341 << (*ArraySize)->getSourceRange();
10347 if (InitBound != AllocBound)
10348 ResizedArrayILE = cast<InitListExpr>(
Init);
10351 AllocType = Info.Ctx.getConstantArrayType(AllocType, ArrayBound,
nullptr,
10352 ArraySizeModifier::Normal, 0);
10355 "array allocation with non-array new");
10361 struct FindObjectHandler {
10368 typedef bool result_type;
10369 bool failed() {
return false; }
10373 unsigned SubobjectSize = 1;
10374 unsigned AllocSize = 1;
10375 if (
auto *CAT = dyn_cast<ConstantArrayType>(AllocType))
10377 if (
auto *CAT = dyn_cast<ConstantArrayType>(SubobjType))
10379 if (SubobjectSize < AllocSize ||
10380 !Info.Ctx.hasSimilarType(Info.Ctx.getBaseElementType(SubobjType),
10381 Info.Ctx.getBaseElementType(AllocType))) {
10382 Info.FFDiag(
E, diag::note_constexpr_placement_new_wrong_type)
10383 << SubobjType << AllocType;
10390 Info.FFDiag(
E, diag::note_constexpr_construct_complex_elem);
10394 Info.FFDiag(
E, diag::note_constexpr_construct_complex_elem);
10397 } Handler = {Info,
E, AllocType, AK,
nullptr};
10400 if (!Obj || !
findSubobject(Info,
E, Obj, Result.Designator, Handler))
10403 Val = Handler.Value;
10412 Val = Info.createHeapAlloc(
E, AllocType, Result);
10421 }
else if (ResizedArrayILE) {
10425 }
else if (ResizedArrayCCE) {
10439 Result.addArray(Info,
E, cast<ConstantArrayType>(AT));
10448class MemberPointerExprEvaluator
10449 :
public ExprEvaluatorBase<MemberPointerExprEvaluator> {
10453 Result = MemberPtr(
D);
10458 MemberPointerExprEvaluator(EvalInfo &Info, MemberPtr &Result)
10459 : ExprEvaluatorBaseTy(Info), Result(Result) {}
10465 bool ZeroInitialization(
const Expr *
E) {
10478 return MemberPointerExprEvaluator(Info, Result).Visit(
E);
10481bool MemberPointerExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
10482 switch (
E->getCastKind()) {
10484 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
10486 case CK_NullToMemberPointer:
10487 VisitIgnoredValue(
E->getSubExpr());
10488 return ZeroInitialization(
E);
10490 case CK_BaseToDerivedMemberPointer: {
10491 if (!Visit(
E->getSubExpr()))
10493 if (
E->path_empty())
10498 typedef std::reverse_iterator<CastExpr::path_const_iterator> ReverseIter;
10499 for (ReverseIter PathI(
E->path_end() - 1), PathE(
E->path_begin());
10500 PathI != PathE; ++PathI) {
10501 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
10502 const CXXRecordDecl *Derived = (*PathI)->getType()->getAsCXXRecordDecl();
10503 if (!Result.castToDerived(Derived))
10512 case CK_DerivedToBaseMemberPointer:
10513 if (!Visit(
E->getSubExpr()))
10516 PathE =
E->path_end(); PathI != PathE; ++PathI) {
10517 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
10519 if (!Result.castToBase(
Base))
10526bool MemberPointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *
E) {
10529 return Success(cast<DeclRefExpr>(
E->getSubExpr())->getDecl());
10537 class RecordExprEvaluator
10538 :
public ExprEvaluatorBase<RecordExprEvaluator> {
10539 const LValue &
This;
10543 RecordExprEvaluator(EvalInfo &info,
const LValue &This,
APValue &Result)
10544 : ExprEvaluatorBaseTy(info),
This(
This), Result(Result) {}
10550 bool ZeroInitialization(
const Expr *
E) {
10551 return ZeroInitialization(
E,
E->
getType());
10555 bool VisitCallExpr(
const CallExpr *
E) {
10556 return handleCallExpr(
E, Result, &This);
10561 return VisitCXXConstructExpr(
E,
E->
getType());
10569 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
10583 const LValue &This,
APValue &Result) {
10584 assert(!RD->
isUnion() &&
"Expected non-union class type");
10593 unsigned Index = 0;
10595 End = CD->
bases_end(); I != End; ++I, ++Index) {
10597 LValue Subobject = This;
10601 Result.getStructBase(Index)))
10606 for (
const auto *I : RD->
fields()) {
10608 if (I->isUnnamedBitField() || I->getType()->isReferenceType())
10611 LValue Subobject = This;
10617 Result.getStructField(I->getFieldIndex()), Info, Subobject, &VIE))
10624bool RecordExprEvaluator::ZeroInitialization(
const Expr *
E,
QualType T) {
10631 while (I != RD->
field_end() && (*I)->isUnnamedBitField())
10638 LValue Subobject =
This;
10643 return EvaluateInPlace(Result.getUnionValue(), Info, Subobject, &VIE);
10646 if (isa<CXXRecordDecl>(RD) && cast<CXXRecordDecl>(RD)->getNumVBases()) {
10647 Info.FFDiag(
E, diag::note_constexpr_virtual_base) << RD;
10654bool RecordExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
10655 switch (
E->getCastKind()) {
10657 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
10659 case CK_ConstructorConversion:
10660 return Visit(
E->getSubExpr());
10662 case CK_DerivedToBase:
10663 case CK_UncheckedDerivedToBase: {
10665 if (!
Evaluate(DerivedObject, Info,
E->getSubExpr()))
10668 return Error(
E->getSubExpr());
10674 PathE =
E->path_end(); PathI != PathE; ++PathI) {
10675 assert(!(*PathI)->isVirtual() &&
"record rvalue with virtual base");
10686bool RecordExprEvaluator::VisitInitListExpr(
const InitListExpr *
E) {
10687 if (
E->isTransparent())
10688 return Visit(
E->getInit(0));
10689 return VisitCXXParenListOrInitListExpr(
E,
E->inits());
10692bool RecordExprEvaluator::VisitCXXParenListOrInitListExpr(
10698 auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
10700 EvalInfo::EvaluatingConstructorRAII EvalObj(
10702 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries},
10703 CXXRD && CXXRD->getNumBases());
10707 if (
auto *ILE = dyn_cast<InitListExpr>(ExprToVisit)) {
10708 Field = ILE->getInitializedFieldInUnion();
10709 }
else if (
auto *PLIE = dyn_cast<CXXParenListInitExpr>(ExprToVisit)) {
10710 Field = PLIE->getInitializedFieldInUnion();
10713 "Expression is neither an init list nor a C++ paren list");
10726 const Expr *InitExpr = Args.empty() ? &VIE : Args[0];
10728 LValue Subobject =
This;
10733 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
10734 isa<CXXDefaultInitExpr>(InitExpr));
10736 if (
EvaluateInPlace(Result.getUnionValue(), Info, Subobject, InitExpr)) {
10737 if (
Field->isBitField())
10746 if (!Result.hasValue())
10749 unsigned ElementNo = 0;
10753 if (CXXRD && CXXRD->getNumBases()) {
10754 for (
const auto &
Base : CXXRD->bases()) {
10755 assert(ElementNo < Args.size() &&
"missing init for base class");
10756 const Expr *
Init = Args[ElementNo];
10758 LValue Subobject =
This;
10762 APValue &FieldVal = Result.getStructBase(ElementNo);
10764 if (!Info.noteFailure())
10771 EvalObj.finishedConstructingBases();
10775 for (
const auto *Field : RD->
fields()) {
10778 if (
Field->isUnnamedBitField())
10781 LValue Subobject =
This;
10783 bool HaveInit = ElementNo < Args.size();
10788 Subobject, Field, &Layout))
10794 const Expr *
Init = HaveInit ? Args[ElementNo++] : &VIE;
10796 if (
Field->getType()->isIncompleteArrayType()) {
10797 if (
auto *CAT = Info.Ctx.getAsConstantArrayType(
Init->getType())) {
10801 Info.FFDiag(
Init, diag::note_constexpr_unsupported_flexible_array);
10808 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
10809 isa<CXXDefaultInitExpr>(
Init));
10811 APValue &FieldVal = Result.getStructField(
Field->getFieldIndex());
10814 FieldVal, Field))) {
10815 if (!Info.noteFailure())
10821 EvalObj.finishedConstructingFields();
10833 bool ZeroInit =
E->requiresZeroInitialization();
10836 if (Result.hasValue())
10840 return ZeroInitialization(
E,
T);
10852 if (
E->isElidable() && !ZeroInit) {
10858 const Expr *SrcObj =
E->getArg(0);
10860 assert(Info.Ctx.hasSameUnqualifiedType(
E->
getType(), SrcObj->
getType()));
10862 dyn_cast<MaterializeTemporaryExpr>(SrcObj))
10863 return Visit(ME->getSubExpr());
10866 if (ZeroInit && !ZeroInitialization(
E,
T))
10875bool RecordExprEvaluator::VisitCXXInheritedCtorInitExpr(
10877 if (!Info.CurrentCall) {
10878 assert(Info.checkingPotentialConstantExpression());
10897bool RecordExprEvaluator::VisitCXXStdInitializerListExpr(
10900 Info.Ctx.getAsConstantArrayType(
E->getSubExpr()->
getType());
10906 assert(
ArrayType &&
"unexpected type for array initializer");
10913 Array.moveInto(Result.getStructField(0));
10917 assert(Field !=
Record->field_end() &&
10918 Info.Ctx.hasSameType(
Field->getType()->getPointeeType(),
10920 "Expected std::initializer_list first field to be const E *");
10922 assert(Field !=
Record->field_end() &&
10923 "Expected std::initializer_list to have two fields");
10925 if (Info.Ctx.hasSameType(
Field->getType(), Info.Ctx.getSizeType())) {
10930 assert(Info.Ctx.hasSameType(
Field->getType()->getPointeeType(),
10932 "Expected std::initializer_list second field to be const E *");
10937 Array.moveInto(Result.getStructField(1));
10940 assert(++Field ==
Record->field_end() &&
10941 "Expected std::initializer_list to only have two fields");
10946bool RecordExprEvaluator::VisitLambdaExpr(
const LambdaExpr *
E) {
10951 const size_t NumFields =
10954 assert(NumFields == (
size_t)std::distance(
E->capture_init_begin(),
10955 E->capture_init_end()) &&
10956 "The number of lambda capture initializers should equal the number of "
10957 "fields within the closure type");
10962 auto *CaptureInitIt =
E->capture_init_begin();
10964 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(ClosureClass);
10965 for (
const auto *Field : ClosureClass->
fields()) {
10966 assert(CaptureInitIt !=
E->capture_init_end());
10968 Expr *
const CurFieldInit = *CaptureInitIt++;
10975 LValue Subobject =
This;
10980 APValue &FieldVal = Result.getStructField(
Field->getFieldIndex());
10982 if (!Info.keepEvaluatingAfterFailure())
10991 APValue &Result, EvalInfo &Info) {
10994 "can't evaluate expression as a record rvalue");
10995 return RecordExprEvaluator(Info, This, Result).Visit(
E);
11006class TemporaryExprEvaluator
11007 :
public LValueExprEvaluatorBase<TemporaryExprEvaluator> {
11009 TemporaryExprEvaluator(EvalInfo &Info, LValue &Result) :
11010 LValueExprEvaluatorBaseTy(Info, Result,
false) {}
11013 bool VisitConstructExpr(
const Expr *
E) {
11015 E,
E->
getType(), ScopeKind::FullExpression, Result);
11019 bool VisitCastExpr(
const CastExpr *
E) {
11020 switch (
E->getCastKind()) {
11022 return LValueExprEvaluatorBaseTy::VisitCastExpr(
E);
11024 case CK_ConstructorConversion:
11025 return VisitConstructExpr(
E->getSubExpr());
11029 return VisitConstructExpr(
E);
11032 return VisitConstructExpr(
E);
11034 bool VisitCallExpr(
const CallExpr *
E) {
11035 return VisitConstructExpr(
E);
11038 return VisitConstructExpr(
E);
11041 return VisitConstructExpr(
E);
11050 return TemporaryExprEvaluator(Info, Result).Visit(
E);
11058 class VectorExprEvaluator
11059 :
public ExprEvaluatorBase<VectorExprEvaluator> {
11063 VectorExprEvaluator(EvalInfo &info,
APValue &Result)
11064 : ExprEvaluatorBaseTy(info), Result(Result) {}
11073 assert(
V.isVector());
11077 bool ZeroInitialization(
const Expr *
E);
11080 {
return Visit(
E->getSubExpr()); }
11097 "not a vector prvalue");
11098 return VectorExprEvaluator(Info, Result).Visit(
E);
11101bool VectorExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
11105 const Expr *SE =
E->getSubExpr();
11108 switch (
E->getCastKind()) {
11109 case CK_VectorSplat: {
11115 Val =
APValue(std::move(IntResult));
11120 Val =
APValue(std::move(FloatResult));
11137 Info.FFDiag(
E, diag::note_constexpr_invalid_cast)
11138 << 2 << Info.Ctx.getLangOpts().CPlusPlus;
11142 if (!handleRValueToRValueBitCast(Info, Result, SVal,
E))
11147 case CK_HLSLVectorTruncation: {
11152 for (
unsigned I = 0; I < NElts; I++)
11157 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
11162VectorExprEvaluator::VisitInitListExpr(
const InitListExpr *
E) {
11164 unsigned NumInits =
E->getNumInits();
11174 unsigned CountInits = 0, CountElts = 0;
11175 while (CountElts < NumElements) {
11177 if (CountInits < NumInits
11182 unsigned vlen =
v.getVectorLength();
11183 for (
unsigned j = 0; j < vlen; j++)
11184 Elements.push_back(
v.getVectorElt(j));
11187 llvm::APSInt sInt(32);
11188 if (CountInits < NumInits) {
11192 sInt = Info.Ctx.MakeIntValue(0, EltTy);
11193 Elements.push_back(
APValue(sInt));
11196 llvm::APFloat f(0.0);
11197 if (CountInits < NumInits) {
11201 f = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy));
11202 Elements.push_back(
APValue(f));
11211VectorExprEvaluator::ZeroInitialization(
const Expr *
E) {
11215 if (EltTy->isIntegerType())
11216 ZeroElement =
APValue(Info.Ctx.MakeIntValue(0, EltTy));
11219 APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy)));
11225bool VectorExprEvaluator::VisitUnaryImag(
const UnaryOperator *
E) {
11226 VisitIgnoredValue(
E->getSubExpr());
11227 return ZeroInitialization(
E);
11230bool VectorExprEvaluator::VisitBinaryOperator(
const BinaryOperator *
E) {
11232 assert(Op != BO_PtrMemD && Op != BO_PtrMemI && Op != BO_Cmp &&
11233 "Operation not supported on vector types");
11235 if (Op == BO_Comma)
11236 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
11238 Expr *LHS =
E->getLHS();
11239 Expr *RHS =
E->getRHS();
11242 "Must both be vector types");
11249 "All operands must be the same size.");
11253 bool LHSOK =
Evaluate(LHSValue, Info, LHS);
11254 if (!LHSOK && !Info.noteFailure())
11256 if (!
Evaluate(RHSValue, Info, RHS) || !LHSOK)
11278 "Vector can only be int or float type");
11286 "Vector operator ~ can only be int");
11287 Elt.
getInt().flipAllBits();
11297 "Vector can only be int or float type");
11303 EltResult.setAllBits();
11305 EltResult.clearAllBits();
11311 return std::nullopt;
11315bool VectorExprEvaluator::VisitUnaryOperator(
const UnaryOperator *
E) {
11316 Expr *SubExpr =
E->getSubExpr();
11321 const QualType ResultEltTy = VD->getElementType();
11325 if (!
Evaluate(SubExprValue, Info, SubExpr))
11338 "Vector length doesn't match type?");
11341 for (
unsigned EltNum = 0; EltNum < VD->getNumElements(); ++EltNum) {
11343 Info.Ctx, ResultEltTy, Op, SubExprValue.
getVectorElt(EltNum));
11346 ResultElements.push_back(*Elt);
11348 return Success(
APValue(ResultElements.data(), ResultElements.size()),
E);
11357 Result =
APValue(APFloat(0.0));
11359 DestTy, Result.getFloat());
11370 Result.getFloat());
11375 DestTy, Result.getInt());
11379 Info.FFDiag(
E, diag::err_convertvector_constexpr_unsupported_vector_cast)
11380 << SourceTy << DestTy;
11384bool VectorExprEvaluator::VisitCallExpr(
const CallExpr *
E) {
11385 if (!IsConstantEvaluatedBuiltinCall(
E))
11386 return ExprEvaluatorBaseTy::VisitCallExpr(
E);
11388 switch (
E->getBuiltinCallee()) {
11391 case Builtin::BI__builtin_elementwise_popcount:
11392 case Builtin::BI__builtin_elementwise_bitreverse: {
11400 ResultElements.reserve(SourceLen);
11402 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11404 switch (
E->getBuiltinCallee()) {
11405 case Builtin::BI__builtin_elementwise_popcount:
11406 ResultElements.push_back(
APValue(
11407 APSInt(
APInt(Info.Ctx.getIntWidth(DestEltTy), Elt.popcount()),
11410 case Builtin::BI__builtin_elementwise_bitreverse:
11411 ResultElements.push_back(
11418 return Success(
APValue(ResultElements.data(), ResultElements.size()),
E);
11420 case Builtin::BI__builtin_elementwise_add_sat:
11421 case Builtin::BI__builtin_elementwise_sub_sat: {
11422 APValue SourceLHS, SourceRHS;
11430 ResultElements.reserve(SourceLen);
11432 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11435 switch (
E->getBuiltinCallee()) {
11436 case Builtin::BI__builtin_elementwise_add_sat:
11437 ResultElements.push_back(
APValue(
11438 APSInt(LHS.isSigned() ? LHS.sadd_sat(RHS) : RHS.uadd_sat(RHS),
11441 case Builtin::BI__builtin_elementwise_sub_sat:
11442 ResultElements.push_back(
APValue(
11443 APSInt(LHS.isSigned() ? LHS.ssub_sat(RHS) : RHS.usub_sat(RHS),
11449 return Success(
APValue(ResultElements.data(), ResultElements.size()),
E);
11467 ResultElements.reserve(SourceLen);
11468 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11473 ResultElements.push_back(std::move(Elt));
11476 return Success(
APValue(ResultElements.data(), ResultElements.size()),
E);
11481 APValue const &VecVal2,
unsigned EltNum,
11483 unsigned const TotalElementsInInputVector1 = VecVal1.
getVectorLength();
11484 unsigned const TotalElementsInInputVector2 = VecVal2.
getVectorLength();
11486 APSInt IndexVal =
E->getShuffleMaskIdx(Info.Ctx, EltNum);
11487 int64_t index = IndexVal.getExtValue();
11494 E, diag::err_shufflevector_minus_one_is_undefined_behavior_constexpr)
11500 index >= TotalElementsInInputVector1 + TotalElementsInInputVector2)
11501 llvm_unreachable(
"Out of bounds shuffle index");
11503 if (index >= TotalElementsInInputVector1)
11504 Result = VecVal2.
getVectorElt(index - TotalElementsInInputVector1);
11512 const Expr *Vec1 =
E->getExpr(0);
11516 const Expr *Vec2 =
E->getExpr(1);
11526 ResultElements.reserve(TotalElementsInOutputVector);
11527 for (
unsigned EltNum = 0; EltNum < TotalElementsInOutputVector; ++EltNum) {
11531 ResultElements.push_back(std::move(Elt));
11534 return Success(
APValue(ResultElements.data(), ResultElements.size()),
E);
11542 class ArrayExprEvaluator
11543 :
public ExprEvaluatorBase<ArrayExprEvaluator> {
11544 const LValue &
This;
11548 ArrayExprEvaluator(EvalInfo &Info,
const LValue &This,
APValue &Result)
11549 : ExprEvaluatorBaseTy(Info),
This(
This), Result(Result) {}
11552 assert(
V.isArray() &&
"expected array");
11557 bool ZeroInitialization(
const Expr *
E) {
11559 Info.Ctx.getAsConstantArrayType(
E->
getType());
11573 if (!Result.hasArrayFiller())
11577 LValue Subobject =
This;
11578 Subobject.addArray(Info,
E, CAT);
11580 return EvaluateInPlace(Result.getArrayFiller(), Info, Subobject, &VIE);
11583 bool VisitCallExpr(
const CallExpr *
E) {
11584 return handleCallExpr(
E, Result, &This);
11591 const LValue &Subobject,
11599 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
11601 const Expr *ArrayFiller,
11607 APValue &Result, EvalInfo &Info) {
11610 "not an array prvalue");
11611 return ArrayExprEvaluator(Info, This, Result).Visit(
E);
11619 "not an array prvalue");
11620 return ArrayExprEvaluator(Info, This, Result)
11621 .VisitInitListExpr(ILE, AllocType);
11630 "not an array prvalue");
11631 return ArrayExprEvaluator(Info, This, Result)
11632 .VisitCXXConstructExpr(CCE, This, &Result, AllocType);
11639 if (isa<ImplicitValueInitExpr>(FillerExpr))
11641 if (
const InitListExpr *ILE = dyn_cast<InitListExpr>(FillerExpr)) {
11642 for (
unsigned I = 0,
E = ILE->getNumInits(); I !=
E; ++I) {
11647 if (ILE->hasArrayFiller() &&
11656bool ArrayExprEvaluator::VisitInitListExpr(
const InitListExpr *
E,
11665 if (
E->isStringLiteralInit()) {
11671 return VisitStringLiteral(SL, AllocType);
11675 assert(!
E->isTransparent() &&
11676 "transparent array list initialization is not string literal init?");
11678 return VisitCXXParenListOrInitListExpr(
E,
E->inits(),
E->getArrayFiller(),
11682bool ArrayExprEvaluator::VisitCXXParenListOrInitListExpr(
11690 assert((!Result.isArray() || Result.getArrayInitializedElts() == 0) &&
11691 "zero-initialized array shouldn't have any initialized elts");
11693 if (Result.isArray() && Result.hasArrayFiller())
11694 Filler = Result.getArrayFiller();
11696 unsigned NumEltsToInit = Args.size();
11701 if (NumEltsToInit != NumElts &&
11703 NumEltsToInit = NumElts;
11705 for (
auto *
Init : Args) {
11706 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts()))
11707 NumEltsToInit += EmbedS->getDataElementCount() - 1;
11709 if (NumEltsToInit > NumElts)
11710 NumEltsToInit = NumElts;
11713 LLVM_DEBUG(llvm::dbgs() <<
"The number of elements to initialize: "
11714 << NumEltsToInit <<
".\n");
11721 for (
unsigned I = 0,
E = Result.getArrayInitializedElts(); I !=
E; ++I)
11722 Result.getArrayInitializedElt(I) = Filler;
11723 if (Result.hasArrayFiller())
11724 Result.getArrayFiller() = Filler;
11727 LValue Subobject =
This;
11728 Subobject.addArray(Info, ExprToVisit, CAT);
11729 auto Eval = [&](
const Expr *
Init,
unsigned ArrayIndex) {
11730 if (
Init->isValueDependent())
11733 if (!
EvaluateInPlace(Result.getArrayInitializedElt(ArrayIndex), Info,
11734 Subobject,
Init) ||
11737 if (!Info.noteFailure())
11743 unsigned ArrayIndex = 0;
11746 for (
unsigned Index = 0; Index != NumEltsToInit; ++Index) {
11747 const Expr *
Init = Index < Args.size() ? Args[Index] : ArrayFiller;
11748 if (ArrayIndex >= NumEltsToInit)
11750 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
11752 for (
unsigned I = EmbedS->getStartingElementPos(),
11753 N = EmbedS->getDataElementCount();
11754 I != EmbedS->getStartingElementPos() + N; ++I) {
11757 Result.getArrayInitializedElt(ArrayIndex) =
APValue(
Value);
11761 Init->getFPFeaturesInEffect(Info.Ctx.getLangOpts());
11766 Result.getArrayInitializedElt(ArrayIndex) =
APValue(FValue);
11771 if (!Eval(
Init, ArrayIndex))
11777 if (!Result.hasArrayFiller())
11782 assert(ArrayFiller &&
"no array filler for incomplete init list");
11790 if (
E->getCommonExpr() &&
11791 !
Evaluate(Info.CurrentCall->createTemporary(
11792 E->getCommonExpr(),
11793 getStorageType(Info.Ctx,
E->getCommonExpr()),
11794 ScopeKind::FullExpression, CommonLV),
11795 Info,
E->getCommonExpr()->getSourceExpr()))
11803 LValue Subobject =
This;
11804 Subobject.addArray(Info,
E, CAT);
11807 for (EvalInfo::ArrayInitLoopIndex Index(Info); Index != Elements; ++Index) {
11816 FullExpressionRAII
Scope(Info);
11819 Info, Subobject,
E->getSubExpr()) ||
11822 if (!Info.noteFailure())
11835 return VisitCXXConstructExpr(
E, This, &Result,
E->
getType());
11839 const LValue &Subobject,
11849 HadZeroInit &&
Value->hasArrayFiller() ?
Value->getArrayFiller()
11853 if (FinalSize == 0)
11858 E->requiresZeroInitialization());
11859 LValue ArrayElt = Subobject;
11860 ArrayElt.addArray(Info,
E, CAT);
11866 for (
const unsigned N : {1u, FinalSize}) {
11867 unsigned OldElts =
Value->getArrayInitializedElts();
11873 for (
unsigned I = 0; I < OldElts; ++I)
11874 NewValue.getArrayInitializedElt(I).swap(
11875 Value->getArrayInitializedElt(I));
11876 Value->swap(NewValue);
11879 for (
unsigned I = OldElts; I < N; ++I)
11880 Value->getArrayInitializedElt(I) = Filler;
11882 if (HasTrivialConstructor && N == FinalSize && FinalSize != 1) {
11885 APValue &FirstResult =
Value->getArrayInitializedElt(0);
11886 for (
unsigned I = OldElts; I < FinalSize; ++I)
11887 Value->getArrayInitializedElt(I) = FirstResult;
11889 for (
unsigned I = OldElts; I < N; ++I) {
11890 if (!VisitCXXConstructExpr(
E, ArrayElt,
11891 &
Value->getArrayInitializedElt(I),
11898 if (Info.EvalStatus.Diag && !Info.EvalStatus.Diag->empty() &&
11899 !Info.keepEvaluatingAfterFailure())
11911 return RecordExprEvaluator(Info, Subobject, *
Value)
11912 .VisitCXXConstructExpr(
E,
Type);
11915bool ArrayExprEvaluator::VisitCXXParenListInitExpr(
11918 "Expression result is not a constant array type");
11920 return VisitCXXParenListOrInitListExpr(
E,
E->getInitExprs(),
11921 E->getArrayFiller());
11933class IntExprEvaluator
11934 :
public ExprEvaluatorBase<IntExprEvaluator> {
11937 IntExprEvaluator(EvalInfo &info,
APValue &result)
11938 : ExprEvaluatorBaseTy(info), Result(result) {}
11942 "Invalid evaluation result.");
11944 "Invalid evaluation result.");
11945 assert(SI.getBitWidth() == Info.Ctx.getIntWidth(
E->
getType()) &&
11946 "Invalid evaluation result.");
11956 "Invalid evaluation result.");
11957 assert(I.getBitWidth() == Info.Ctx.getIntWidth(
E->
getType()) &&
11958 "Invalid evaluation result.");
11960 Result.getInt().setIsUnsigned(
11970 "Invalid evaluation result.");
11985 if (
V.isLValue() ||
V.isAddrLabelDiff() ||
V.isIndeterminate() ||
11986 V.allowConstexprUnknown()) {
11993 bool ZeroInitialization(
const Expr *
E) {
return Success(0,
E); }
11995 friend std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &,
12009 bool CheckReferencedDecl(
const Expr *
E,
const Decl *
D);
12011 if (CheckReferencedDecl(
E,
E->getDecl()))
12014 return ExprEvaluatorBaseTy::VisitDeclRefExpr(
E);
12017 if (CheckReferencedDecl(
E,
E->getMemberDecl())) {
12018 VisitIgnoredBaseExpression(
E->getBase());
12022 return ExprEvaluatorBaseTy::VisitMemberExpr(
E);
12026 bool VisitBuiltinCallExpr(
const CallExpr *
E,
unsigned BuiltinOp);
12043 if (Info.ArrayInitIndex ==
uint64_t(-1)) {
12049 return Success(Info.ArrayInitIndex,
E);
12054 return ZeroInitialization(
E);
12087class FixedPointExprEvaluator
12088 :
public ExprEvaluatorBase<FixedPointExprEvaluator> {
12092 FixedPointExprEvaluator(EvalInfo &info,
APValue &result)
12093 : ExprEvaluatorBaseTy(info), Result(result) {}
12097 APFixedPoint(I, Info.Ctx.getFixedPointSemantics(
E->
getType())),
E);
12102 APFixedPoint(
Value, Info.Ctx.getFixedPointSemantics(
E->
getType())),
E);
12111 assert(
V.getWidth() == Info.Ctx.getIntWidth(
E->
getType()) &&
12112 "Invalid evaluation result.");
12117 bool ZeroInitialization(
const Expr *
E) {
12147 return IntExprEvaluator(Info, Result).Visit(
E);
12155 if (!Val.
isInt()) {
12158 Info.FFDiag(
E, diag::note_invalid_subexpr_in_const_expr);
12165bool IntExprEvaluator::VisitSourceLocExpr(
const SourceLocExpr *
E) {
12167 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.getDefaultExpr());
12176 if (!FixedPointExprEvaluator(Info, Val).Visit(
E))
12191 auto FXSema = Info.Ctx.getFixedPointSemantics(
E->
getType());
12195 Result = APFixedPoint(Val, FXSema);
12206bool IntExprEvaluator::CheckReferencedDecl(
const Expr*
E,
const Decl*
D) {
12210 bool SameSign = (ECD->getInitVal().isSigned()
12212 bool SameWidth = (ECD->getInitVal().getBitWidth()
12213 == Info.Ctx.getIntWidth(
E->
getType()));
12214 if (SameSign && SameWidth)
12215 return Success(ECD->getInitVal(),
E);
12219 llvm::APSInt Val = ECD->getInitVal();
12221 Val.setIsSigned(!ECD->getInitVal().isSigned());
12223 Val = Val.extOrTrunc(Info.Ctx.getIntWidth(
E->
getType()));
12239#define TYPE(ID, BASE)
12240#define DEPENDENT_TYPE(ID, BASE) case Type::ID:
12241#define NON_CANONICAL_TYPE(ID, BASE) case Type::ID:
12242#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(ID, BASE) case Type::ID:
12243#include "clang/AST/TypeNodes.inc"
12245 case Type::DeducedTemplateSpecialization:
12246 llvm_unreachable(
"unexpected non-canonical or dependent type");
12248 case Type::Builtin:
12249 switch (cast<BuiltinType>(CanTy)->
getKind()) {
12250#define BUILTIN_TYPE(ID, SINGLETON_ID)
12251#define SIGNED_TYPE(ID, SINGLETON_ID) \
12252 case BuiltinType::ID: return GCCTypeClass::Integer;
12253#define FLOATING_TYPE(ID, SINGLETON_ID) \
12254 case BuiltinType::ID: return GCCTypeClass::RealFloat;
12255#define PLACEHOLDER_TYPE(ID, SINGLETON_ID) \
12256 case BuiltinType::ID: break;
12257#include "clang/AST/BuiltinTypes.def"
12258 case BuiltinType::Void:
12259 return GCCTypeClass::Void;
12261 case BuiltinType::Bool:
12262 return GCCTypeClass::Bool;
12264 case BuiltinType::Char_U:
12265 case BuiltinType::UChar:
12266 case BuiltinType::WChar_U:
12267 case BuiltinType::Char8:
12268 case BuiltinType::Char16:
12269 case BuiltinType::Char32:
12270 case BuiltinType::UShort:
12271 case BuiltinType::UInt:
12272 case BuiltinType::ULong:
12273 case BuiltinType::ULongLong:
12274 case BuiltinType::UInt128:
12275 return GCCTypeClass::Integer;
12277 case BuiltinType::UShortAccum:
12278 case BuiltinType::UAccum:
12279 case BuiltinType::ULongAccum:
12280 case BuiltinType::UShortFract:
12281 case BuiltinType::UFract:
12282 case BuiltinType::ULongFract:
12283 case BuiltinType::SatUShortAccum:
12284 case BuiltinType::SatUAccum:
12285 case BuiltinType::SatULongAccum:
12286 case BuiltinType::SatUShortFract:
12287 case BuiltinType::SatUFract:
12288 case BuiltinType::SatULongFract:
12289 return GCCTypeClass::None;
12291 case BuiltinType::NullPtr:
12293 case BuiltinType::ObjCId:
12294 case BuiltinType::ObjCClass:
12295 case BuiltinType::ObjCSel:
12296#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
12297 case BuiltinType::Id:
12298#include "clang/Basic/OpenCLImageTypes.def"
12299#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
12300 case BuiltinType::Id:
12301#include "clang/Basic/OpenCLExtensionTypes.def"
12302 case BuiltinType::OCLSampler:
12303 case BuiltinType::OCLEvent:
12304 case BuiltinType::OCLClkEvent:
12305 case BuiltinType::OCLQueue:
12306 case BuiltinType::OCLReserveID:
12307#define SVE_TYPE(Name, Id, SingletonId) \
12308 case BuiltinType::Id:
12309#include "clang/Basic/AArch64SVEACLETypes.def"
12310#define PPC_VECTOR_TYPE(Name, Id, Size) \
12311 case BuiltinType::Id:
12312#include "clang/Basic/PPCTypes.def"
12313#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
12314#include "clang/Basic/RISCVVTypes.def"
12315#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
12316#include "clang/Basic/WebAssemblyReferenceTypes.def"
12317#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
12318#include "clang/Basic/AMDGPUTypes.def"
12319#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
12320#include "clang/Basic/HLSLIntangibleTypes.def"
12321 return GCCTypeClass::None;
12323 case BuiltinType::Dependent:
12324 llvm_unreachable(
"unexpected dependent type");
12326 llvm_unreachable(
"unexpected placeholder type");
12329 return LangOpts.CPlusPlus ? GCCTypeClass::Enum : GCCTypeClass::Integer;
12331 case Type::Pointer:
12332 case Type::ConstantArray:
12333 case Type::VariableArray:
12334 case Type::IncompleteArray:
12335 case Type::FunctionNoProto:
12336 case Type::FunctionProto:
12337 case Type::ArrayParameter:
12338 return GCCTypeClass::Pointer;
12340 case Type::MemberPointer:
12342 ? GCCTypeClass::PointerToDataMember
12343 : GCCTypeClass::PointerToMemberFunction;
12345 case Type::Complex:
12346 return GCCTypeClass::Complex;
12349 return CanTy->
isUnionType() ? GCCTypeClass::Union
12350 : GCCTypeClass::ClassOrStruct;
12358 case Type::ExtVector:
12359 return GCCTypeClass::Vector;
12361 case Type::BlockPointer:
12362 case Type::ConstantMatrix:
12363 case Type::ObjCObject:
12364 case Type::ObjCInterface:
12365 case Type::ObjCObjectPointer:
12367 case Type::HLSLAttributedResource:
12370 return GCCTypeClass::None;
12373 return GCCTypeClass::BitInt;
12375 case Type::LValueReference:
12376 case Type::RValueReference:
12377 llvm_unreachable(
"invalid type for expression");
12380 llvm_unreachable(
"unexpected type class");
12389 if (
E->getNumArgs() == 0)
12390 return GCCTypeClass::None;
12405 if (
Base.isNull()) {
12408 }
else if (
const Expr *
E =
Base.dyn_cast<
const Expr *>()) {
12409 if (!isa<StringLiteral>(
E))
12427 SpeculativeEvaluationRAII SpeculativeEval(Info);
12432 FoldConstant Fold(Info,
true);
12455 Fold.keepDiagnostics();
12464 return V.hasValue();
12475 if (
const VarDecl *VD = dyn_cast<VarDecl>(
D))
12478 if (isa<CompoundLiteralExpr>(
E))
12499 const auto *Cast = dyn_cast<CastExpr>(NoParens);
12500 if (Cast ==
nullptr)
12505 auto CastKind = Cast->getCastKind();
12507 CastKind != CK_AddressSpaceConversion)
12510 const auto *SubExpr = Cast->getSubExpr();
12532 assert(!LVal.Designator.Invalid);
12534 auto IsLastOrInvalidFieldDecl = [&Ctx](
const FieldDecl *FD,
bool &
Invalid) {
12543 auto &
Base = LVal.getLValueBase();
12544 if (
auto *ME = dyn_cast_or_null<MemberExpr>(
Base.dyn_cast<
const Expr *>())) {
12545 if (
auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
12547 if (!IsLastOrInvalidFieldDecl(FD,
Invalid))
12549 }
else if (
auto *IFD = dyn_cast<IndirectFieldDecl>(ME->getMemberDecl())) {
12550 for (
auto *FD : IFD->chain()) {
12552 if (!IsLastOrInvalidFieldDecl(cast<FieldDecl>(FD),
Invalid))
12560 if (LVal.Designator.FirstEntryIsAnUnsizedArray) {
12570 for (
unsigned E = LVal.Designator.Entries.size(); I !=
E; ++I) {
12571 const auto &Entry = LVal.Designator.Entries[I];
12577 const auto *CAT = cast<ConstantArrayType>(Ctx.
getAsArrayType(BaseType));
12578 uint64_t Index = Entry.getAsArrayIndex();
12584 uint64_t Index = Entry.getAsArrayIndex();
12587 BaseType = CT->getElementType();
12588 }
else if (
auto *FD = getAsField(Entry)) {
12590 if (!IsLastOrInvalidFieldDecl(FD,
Invalid))
12594 assert(getAsBaseClass(Entry) &&
"Expecting cast to a base class");
12606 if (LVal.Designator.Invalid)
12609 if (!LVal.Designator.Entries.empty())
12610 return LVal.Designator.isMostDerivedAnUnsizedArray();
12612 if (!LVal.InvalidBase)
12617 const auto *
E = LVal.Base.dyn_cast<
const Expr *>();
12618 return !
E || !isa<MemberExpr>(
E);
12624 const SubobjectDesignator &
Designator = LVal.Designator;
12636 auto isFlexibleArrayMember = [&] {
12638 FAMKind StrictFlexArraysLevel =
12641 if (
Designator.isMostDerivedAnUnsizedArray())
12644 if (StrictFlexArraysLevel == FAMKind::Default)
12647 if (
Designator.getMostDerivedArraySize() == 0 &&
12648 StrictFlexArraysLevel != FAMKind::IncompleteOnly)
12651 if (
Designator.getMostDerivedArraySize() == 1 &&
12652 StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete)
12658 return LVal.InvalidBase &&
12660 Designator.MostDerivedIsArrayElement && isFlexibleArrayMember() &&
12668 auto CharUnitsMax = std::numeric_limits<CharUnits::QuantityType>::max();
12669 if (Int.ugt(CharUnitsMax))
12681 if (
const auto *
V = LV.getLValueBase().dyn_cast<
const ValueDecl *>())
12682 if (
const auto *VD = dyn_cast<VarDecl>(
V))
12694 unsigned Type,
const LValue &LVal,
12711 if (!(
Type & 1) || LVal.Designator.Invalid || DetermineForCompleteObject) {
12713 if (
Type == 3 && !DetermineForCompleteObject)
12716 llvm::APInt APEndOffset;
12717 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
12721 if (LVal.InvalidBase)
12725 const bool Ret = CheckedHandleSizeof(BaseTy, EndOffset);
12731 const SubobjectDesignator &
Designator = LVal.Designator;
12743 llvm::APInt APEndOffset;
12744 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
12756 if (!CheckedHandleSizeof(
Designator.MostDerivedType, BytesPerElem))
12762 int64_t ElemsRemaining;
12765 uint64_t ArraySize =
Designator.getMostDerivedArraySize();
12766 uint64_t ArrayIndex =
Designator.Entries.back().getAsArrayIndex();
12767 ElemsRemaining = ArraySize <= ArrayIndex ? 0 : ArraySize - ArrayIndex;
12769 ElemsRemaining =
Designator.isOnePastTheEnd() ? 0 : 1;
12772 EndOffset = LVal.getLValueOffset() + BytesPerElem * ElemsRemaining;
12782 EvalInfo &Info, uint64_t &Size) {
12789 SpeculativeEvaluationRAII SpeculativeEval(Info);
12790 IgnoreSideEffectsRAII Fold(Info);
12798 LVal.setFrom(Info.Ctx, RVal);
12806 if (LVal.getLValueOffset().isNegative()) {
12817 if (EndOffset <= LVal.getLValueOffset())
12820 Size = (EndOffset - LVal.getLValueOffset()).getQuantity();
12824bool IntExprEvaluator::VisitCallExpr(
const CallExpr *
E) {
12825 if (!IsConstantEvaluatedBuiltinCall(
E))
12826 return ExprEvaluatorBaseTy::VisitCallExpr(
E);
12827 return VisitBuiltinCallExpr(
E,
E->getBuiltinCallee());
12843 Info.FFDiag(
E->getArg(0));
12849 assert(SrcInt.getBitWidth() >= Alignment.getBitWidth() &&
12850 "Bit widths must be the same");
12857bool IntExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *
E,
12858 unsigned BuiltinOp) {
12859 switch (BuiltinOp) {
12863 case Builtin::BI__builtin_dynamic_object_size:
12864 case Builtin::BI__builtin_object_size: {
12868 assert(
Type <= 3 &&
"unexpected type");
12879 switch (Info.EvalMode) {
12880 case EvalInfo::EM_ConstantExpression:
12881 case EvalInfo::EM_ConstantFold:
12882 case EvalInfo::EM_IgnoreSideEffects:
12885 case EvalInfo::EM_ConstantExpressionUnevaluated:
12890 llvm_unreachable(
"unexpected EvalMode");
12893 case Builtin::BI__builtin_os_log_format_buffer_size: {
12899 case Builtin::BI__builtin_is_aligned: {
12907 Ptr.setFrom(Info.Ctx, Src);
12913 assert(Alignment.isPowerOf2());
12926 Info.FFDiag(
E->getArg(0), diag::note_constexpr_alignment_compute)
12930 assert(Src.
isInt());
12931 return Success((Src.
getInt() & (Alignment - 1)) == 0 ? 1 : 0,
E);
12933 case Builtin::BI__builtin_align_up: {
12941 APSInt((Src.
getInt() + (Alignment - 1)) & ~(Alignment - 1),
12942 Src.
getInt().isUnsigned());
12943 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
12946 case Builtin::BI__builtin_align_down: {
12955 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
12959 case Builtin::BI__builtin_bitreverse8:
12960 case Builtin::BI__builtin_bitreverse16:
12961 case Builtin::BI__builtin_bitreverse32:
12962 case Builtin::BI__builtin_bitreverse64:
12963 case Builtin::BI__builtin_elementwise_bitreverse: {
12968 return Success(Val.reverseBits(),
E);
12971 case Builtin::BI__builtin_bswap16:
12972 case Builtin::BI__builtin_bswap32:
12973 case Builtin::BI__builtin_bswap64: {
12978 return Success(Val.byteSwap(),
E);
12981 case Builtin::BI__builtin_classify_type:
12984 case Builtin::BI__builtin_clrsb:
12985 case Builtin::BI__builtin_clrsbl:
12986 case Builtin::BI__builtin_clrsbll: {
12991 return Success(Val.getBitWidth() - Val.getSignificantBits(),
E);
12994 case Builtin::BI__builtin_clz:
12995 case Builtin::BI__builtin_clzl:
12996 case Builtin::BI__builtin_clzll:
12997 case Builtin::BI__builtin_clzs:
12998 case Builtin::BI__builtin_clzg:
12999 case Builtin::BI__lzcnt16:
13000 case Builtin::BI__lzcnt:
13001 case Builtin::BI__lzcnt64: {
13006 std::optional<APSInt> Fallback;
13007 if (BuiltinOp == Builtin::BI__builtin_clzg &&
E->getNumArgs() > 1) {
13011 Fallback = FallbackTemp;
13021 bool ZeroIsUndefined = BuiltinOp != Builtin::BI__lzcnt16 &&
13022 BuiltinOp != Builtin::BI__lzcnt &&
13023 BuiltinOp != Builtin::BI__lzcnt64;
13025 if (ZeroIsUndefined)
13029 return Success(Val.countl_zero(),
E);
13032 case Builtin::BI__builtin_constant_p: {
13033 const Expr *Arg =
E->getArg(0);
13042 Info.FFDiag(
E, diag::note_invalid_subexpr_in_const_expr);
13046 case Builtin::BI__noop:
13050 case Builtin::BI__builtin_is_constant_evaluated: {
13051 const auto *
Callee = Info.CurrentCall->getCallee();
13052 if (Info.InConstantContext && !Info.CheckingPotentialConstantExpression &&
13053 (Info.CallStackDepth == 1 ||
13054 (Info.CallStackDepth == 2 &&
Callee->isInStdNamespace() &&
13055 Callee->getIdentifier() &&
13056 Callee->getIdentifier()->isStr(
"is_constant_evaluated")))) {
13058 if (Info.EvalStatus.Diag)
13059 Info.report((Info.CallStackDepth == 1)
13061 : Info.CurrentCall->getCallRange().getBegin(),
13062 diag::warn_is_constant_evaluated_always_true_constexpr)
13063 << (Info.CallStackDepth == 1 ?
"__builtin_is_constant_evaluated"
13064 :
"std::is_constant_evaluated");
13067 return Success(Info.InConstantContext,
E);
13070 case Builtin::BI__builtin_is_within_lifetime:
13071 if (
auto result = EvaluateBuiltinIsWithinLifetime(*
this,
E))
13075 case Builtin::BI__builtin_ctz:
13076 case Builtin::BI__builtin_ctzl:
13077 case Builtin::BI__builtin_ctzll:
13078 case Builtin::BI__builtin_ctzs:
13079 case Builtin::BI__builtin_ctzg: {
13084 std::optional<APSInt> Fallback;
13085 if (BuiltinOp == Builtin::BI__builtin_ctzg &&
E->getNumArgs() > 1) {
13089 Fallback = FallbackTemp;
13099 return Success(Val.countr_zero(),
E);
13102 case Builtin::BI__builtin_eh_return_data_regno: {
13104 Operand = Info.Ctx.getTargetInfo().getEHDataRegisterNumber(Operand);
13108 case Builtin::BI__builtin_expect:
13109 case Builtin::BI__builtin_expect_with_probability:
13110 return Visit(
E->getArg(0));
13112 case Builtin::BI__builtin_ptrauth_string_discriminator: {
13119 case Builtin::BI__builtin_ffs:
13120 case Builtin::BI__builtin_ffsl:
13121 case Builtin::BI__builtin_ffsll: {
13126 unsigned N = Val.countr_zero();
13127 return Success(N == Val.getBitWidth() ? 0 : N + 1,
E);
13130 case Builtin::BI__builtin_fpclassify: {
13135 switch (Val.getCategory()) {
13136 case APFloat::fcNaN: Arg = 0;
break;
13137 case APFloat::fcInfinity: Arg = 1;
break;
13138 case APFloat::fcNormal: Arg = Val.isDenormal() ? 3 : 2;
break;
13139 case APFloat::fcZero: Arg = 4;
break;
13141 return Visit(
E->getArg(Arg));
13144 case Builtin::BI__builtin_isinf_sign: {
13147 Success(Val.isInfinity() ? (Val.isNegative() ? -1 : 1) : 0,
E);
13150 case Builtin::BI__builtin_isinf: {
13153 Success(Val.isInfinity() ? 1 : 0,
E);
13156 case Builtin::BI__builtin_isfinite: {
13159 Success(Val.isFinite() ? 1 : 0,
E);
13162 case Builtin::BI__builtin_isnan: {
13168 case Builtin::BI__builtin_isnormal: {
13171 Success(Val.isNormal() ? 1 : 0,
E);
13174 case Builtin::BI__builtin_issubnormal: {
13177 Success(Val.isDenormal() ? 1 : 0,
E);
13180 case Builtin::BI__builtin_iszero: {
13186 case Builtin::BI__builtin_signbit:
13187 case Builtin::BI__builtin_signbitf:
13188 case Builtin::BI__builtin_signbitl: {
13191 Success(Val.isNegative() ? 1 : 0,
E);
13194 case Builtin::BI__builtin_isgreater:
13195 case Builtin::BI__builtin_isgreaterequal:
13196 case Builtin::BI__builtin_isless:
13197 case Builtin::BI__builtin_islessequal:
13198 case Builtin::BI__builtin_islessgreater:
13199 case Builtin::BI__builtin_isunordered: {
13208 switch (BuiltinOp) {
13209 case Builtin::BI__builtin_isgreater:
13211 case Builtin::BI__builtin_isgreaterequal:
13213 case Builtin::BI__builtin_isless:
13215 case Builtin::BI__builtin_islessequal:
13217 case Builtin::BI__builtin_islessgreater: {
13218 APFloat::cmpResult cmp = LHS.compare(RHS);
13219 return cmp == APFloat::cmpResult::cmpLessThan ||
13220 cmp == APFloat::cmpResult::cmpGreaterThan;
13222 case Builtin::BI__builtin_isunordered:
13223 return LHS.compare(RHS) == APFloat::cmpResult::cmpUnordered;
13225 llvm_unreachable(
"Unexpected builtin ID: Should be a floating "
13226 "point comparison function");
13234 case Builtin::BI__builtin_issignaling: {
13237 Success(Val.isSignaling() ? 1 : 0,
E);
13240 case Builtin::BI__builtin_isfpclass: {
13244 unsigned Test =
static_cast<llvm::FPClassTest
>(MaskVal.getZExtValue());
13247 Success((Val.classify() & Test) ? 1 : 0,
E);
13250 case Builtin::BI__builtin_parity:
13251 case Builtin::BI__builtin_parityl:
13252 case Builtin::BI__builtin_parityll: {
13257 return Success(Val.popcount() % 2,
E);
13260 case Builtin::BI__builtin_abs:
13261 case Builtin::BI__builtin_labs:
13262 case Builtin::BI__builtin_llabs: {
13266 if (Val ==
APSInt(APInt::getSignedMinValue(Val.getBitWidth()),
13269 if (Val.isNegative())
13274 case Builtin::BI__builtin_popcount:
13275 case Builtin::BI__builtin_popcountl:
13276 case Builtin::BI__builtin_popcountll:
13277 case Builtin::BI__builtin_popcountg:
13278 case Builtin::BI__builtin_elementwise_popcount:
13279 case Builtin::BI__popcnt16:
13280 case Builtin::BI__popcnt:
13281 case Builtin::BI__popcnt64: {
13286 return Success(Val.popcount(),
E);
13289 case Builtin::BI__builtin_rotateleft8:
13290 case Builtin::BI__builtin_rotateleft16:
13291 case Builtin::BI__builtin_rotateleft32:
13292 case Builtin::BI__builtin_rotateleft64:
13293 case Builtin::BI_rotl8:
13294 case Builtin::BI_rotl16:
13295 case Builtin::BI_rotl:
13296 case Builtin::BI_lrotl:
13297 case Builtin::BI_rotl64: {
13303 return Success(Val.rotl(Amt.urem(Val.getBitWidth())),
E);
13306 case Builtin::BI__builtin_rotateright8:
13307 case Builtin::BI__builtin_rotateright16:
13308 case Builtin::BI__builtin_rotateright32:
13309 case Builtin::BI__builtin_rotateright64:
13310 case Builtin::BI_rotr8:
13311 case Builtin::BI_rotr16:
13312 case Builtin::BI_rotr:
13313 case Builtin::BI_lrotr:
13314 case Builtin::BI_rotr64: {
13320 return Success(Val.rotr(Amt.urem(Val.getBitWidth())),
E);
13323 case Builtin::BI__builtin_elementwise_add_sat: {
13329 APInt Result = LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS);
13332 case Builtin::BI__builtin_elementwise_sub_sat: {
13338 APInt Result = LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
13342 case Builtin::BIstrlen:
13343 case Builtin::BIwcslen:
13345 if (Info.getLangOpts().CPlusPlus11)
13346 Info.CCEDiag(
E, diag::note_constexpr_invalid_function)
13348 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
13350 Info.CCEDiag(
E, diag::note_invalid_subexpr_in_const_expr);
13352 case Builtin::BI__builtin_strlen:
13353 case Builtin::BI__builtin_wcslen: {
13362 case Builtin::BIstrcmp:
13363 case Builtin::BIwcscmp:
13364 case Builtin::BIstrncmp:
13365 case Builtin::BIwcsncmp:
13366 case Builtin::BImemcmp:
13367 case Builtin::BIbcmp:
13368 case Builtin::BIwmemcmp:
13370 if (Info.getLangOpts().CPlusPlus11)
13371 Info.CCEDiag(
E, diag::note_constexpr_invalid_function)
13373 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
13375 Info.CCEDiag(
E, diag::note_invalid_subexpr_in_const_expr);
13377 case Builtin::BI__builtin_strcmp:
13378 case Builtin::BI__builtin_wcscmp:
13379 case Builtin::BI__builtin_strncmp:
13380 case Builtin::BI__builtin_wcsncmp:
13381 case Builtin::BI__builtin_memcmp:
13382 case Builtin::BI__builtin_bcmp:
13383 case Builtin::BI__builtin_wmemcmp: {
13384 LValue String1, String2;
13390 if (BuiltinOp != Builtin::BIstrcmp &&
13391 BuiltinOp != Builtin::BIwcscmp &&
13392 BuiltinOp != Builtin::BI__builtin_strcmp &&
13393 BuiltinOp != Builtin::BI__builtin_wcscmp) {
13397 MaxLength = N.getZExtValue();
13401 if (MaxLength == 0u)
13404 if (!String1.checkNullPointerForFoldAccess(Info,
E,
AK_Read) ||
13405 !String2.checkNullPointerForFoldAccess(Info,
E,
AK_Read) ||
13406 String1.Designator.Invalid || String2.Designator.Invalid)
13409 QualType CharTy1 = String1.Designator.getType(Info.Ctx);
13410 QualType CharTy2 = String2.Designator.getType(Info.Ctx);
13412 bool IsRawByte = BuiltinOp == Builtin::BImemcmp ||
13413 BuiltinOp == Builtin::BIbcmp ||
13414 BuiltinOp == Builtin::BI__builtin_memcmp ||
13415 BuiltinOp == Builtin::BI__builtin_bcmp;
13417 assert(IsRawByte ||
13418 (Info.Ctx.hasSameUnqualifiedType(
13420 Info.Ctx.hasSameUnqualifiedType(CharTy1, CharTy2)));
13427 Info.FFDiag(
E, diag::note_constexpr_memcmp_unsupported)
13428 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp) << CharTy1
13433 const auto &ReadCurElems = [&](
APValue &Char1,
APValue &Char2) {
13436 Char1.
isInt() && Char2.isInt();
13438 const auto &AdvanceElems = [&] {
13444 (BuiltinOp != Builtin::BImemcmp && BuiltinOp != Builtin::BIbcmp &&
13445 BuiltinOp != Builtin::BIwmemcmp &&
13446 BuiltinOp != Builtin::BI__builtin_memcmp &&
13447 BuiltinOp != Builtin::BI__builtin_bcmp &&
13448 BuiltinOp != Builtin::BI__builtin_wmemcmp);
13449 bool IsWide = BuiltinOp == Builtin::BIwcscmp ||
13450 BuiltinOp == Builtin::BIwcsncmp ||
13451 BuiltinOp == Builtin::BIwmemcmp ||
13452 BuiltinOp == Builtin::BI__builtin_wcscmp ||
13453 BuiltinOp == Builtin::BI__builtin_wcsncmp ||
13454 BuiltinOp == Builtin::BI__builtin_wmemcmp;
13456 for (; MaxLength; --MaxLength) {
13458 if (!ReadCurElems(Char1, Char2))
13466 if (StopAtNull && !Char1.
getInt())
13468 assert(!(StopAtNull && !Char2.
getInt()));
13469 if (!AdvanceElems())
13476 case Builtin::BI__atomic_always_lock_free:
13477 case Builtin::BI__atomic_is_lock_free:
13478 case Builtin::BI__c11_atomic_is_lock_free: {
13494 if (
Size.isPowerOfTwo()) {
13496 unsigned InlineWidthBits =
13497 Info.Ctx.getTargetInfo().getMaxAtomicInlineWidth();
13498 if (Size <= Info.Ctx.toCharUnitsFromBits(InlineWidthBits)) {
13499 if (BuiltinOp == Builtin::BI__c11_atomic_is_lock_free ||
13505 const Expr *PtrArg =
E->getArg(1);
13511 IntResult.isAligned(
Size.getAsAlign()))
13515 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(PtrArg)) {
13518 if (ICE->getCastKind() == CK_BitCast)
13519 PtrArg = ICE->getSubExpr();
13525 Info.Ctx.getTypeAlignInChars(PointeeType) >= Size) {
13533 return BuiltinOp == Builtin::BI__atomic_always_lock_free ?
13536 case Builtin::BI__builtin_addcb:
13537 case Builtin::BI__builtin_addcs:
13538 case Builtin::BI__builtin_addc:
13539 case Builtin::BI__builtin_addcl:
13540 case Builtin::BI__builtin_addcll:
13541 case Builtin::BI__builtin_subcb:
13542 case Builtin::BI__builtin_subcs:
13543 case Builtin::BI__builtin_subc:
13544 case Builtin::BI__builtin_subcl:
13545 case Builtin::BI__builtin_subcll: {
13546 LValue CarryOutLValue;
13547 APSInt LHS, RHS, CarryIn, CarryOut, Result;
13558 bool FirstOverflowed =
false;
13559 bool SecondOverflowed =
false;
13560 switch (BuiltinOp) {
13562 llvm_unreachable(
"Invalid value for BuiltinOp");
13563 case Builtin::BI__builtin_addcb:
13564 case Builtin::BI__builtin_addcs:
13565 case Builtin::BI__builtin_addc:
13566 case Builtin::BI__builtin_addcl:
13567 case Builtin::BI__builtin_addcll:
13569 LHS.uadd_ov(RHS, FirstOverflowed).uadd_ov(CarryIn, SecondOverflowed);
13571 case Builtin::BI__builtin_subcb:
13572 case Builtin::BI__builtin_subcs:
13573 case Builtin::BI__builtin_subc:
13574 case Builtin::BI__builtin_subcl:
13575 case Builtin::BI__builtin_subcll:
13577 LHS.usub_ov(RHS, FirstOverflowed).usub_ov(CarryIn, SecondOverflowed);
13583 CarryOut = (
uint64_t)(FirstOverflowed | SecondOverflowed);
13589 case Builtin::BI__builtin_add_overflow:
13590 case Builtin::BI__builtin_sub_overflow:
13591 case Builtin::BI__builtin_mul_overflow:
13592 case Builtin::BI__builtin_sadd_overflow:
13593 case Builtin::BI__builtin_uadd_overflow:
13594 case Builtin::BI__builtin_uaddl_overflow:
13595 case Builtin::BI__builtin_uaddll_overflow:
13596 case Builtin::BI__builtin_usub_overflow:
13597 case Builtin::BI__builtin_usubl_overflow:
13598 case Builtin::BI__builtin_usubll_overflow:
13599 case Builtin::BI__builtin_umul_overflow:
13600 case Builtin::BI__builtin_umull_overflow:
13601 case Builtin::BI__builtin_umulll_overflow:
13602 case Builtin::BI__builtin_saddl_overflow:
13603 case Builtin::BI__builtin_saddll_overflow:
13604 case Builtin::BI__builtin_ssub_overflow:
13605 case Builtin::BI__builtin_ssubl_overflow:
13606 case Builtin::BI__builtin_ssubll_overflow:
13607 case Builtin::BI__builtin_smul_overflow:
13608 case Builtin::BI__builtin_smull_overflow:
13609 case Builtin::BI__builtin_smulll_overflow: {
13610 LValue ResultLValue;
13620 bool DidOverflow =
false;
13623 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
13624 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
13625 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
13626 bool IsSigned = LHS.isSigned() || RHS.isSigned() ||
13628 bool AllSigned = LHS.isSigned() && RHS.isSigned() &&
13630 uint64_t LHSSize = LHS.getBitWidth();
13631 uint64_t RHSSize = RHS.getBitWidth();
13632 uint64_t ResultSize = Info.Ctx.getTypeSize(ResultType);
13633 uint64_t MaxBits = std::max(std::max(LHSSize, RHSSize), ResultSize);
13639 if (IsSigned && !AllSigned)
13642 LHS =
APSInt(LHS.extOrTrunc(MaxBits), !IsSigned);
13643 RHS =
APSInt(RHS.extOrTrunc(MaxBits), !IsSigned);
13644 Result =
APSInt(MaxBits, !IsSigned);
13648 switch (BuiltinOp) {
13650 llvm_unreachable(
"Invalid value for BuiltinOp");
13651 case Builtin::BI__builtin_add_overflow:
13652 case Builtin::BI__builtin_sadd_overflow:
13653 case Builtin::BI__builtin_saddl_overflow:
13654 case Builtin::BI__builtin_saddll_overflow:
13655 case Builtin::BI__builtin_uadd_overflow:
13656 case Builtin::BI__builtin_uaddl_overflow:
13657 case Builtin::BI__builtin_uaddll_overflow:
13658 Result = LHS.isSigned() ? LHS.sadd_ov(RHS, DidOverflow)
13659 : LHS.uadd_ov(RHS, DidOverflow);
13661 case Builtin::BI__builtin_sub_overflow:
13662 case Builtin::BI__builtin_ssub_overflow:
13663 case Builtin::BI__builtin_ssubl_overflow:
13664 case Builtin::BI__builtin_ssubll_overflow:
13665 case Builtin::BI__builtin_usub_overflow:
13666 case Builtin::BI__builtin_usubl_overflow:
13667 case Builtin::BI__builtin_usubll_overflow:
13668 Result = LHS.isSigned() ? LHS.ssub_ov(RHS, DidOverflow)
13669 : LHS.usub_ov(RHS, DidOverflow);
13671 case Builtin::BI__builtin_mul_overflow:
13672 case Builtin::BI__builtin_smul_overflow:
13673 case Builtin::BI__builtin_smull_overflow:
13674 case Builtin::BI__builtin_smulll_overflow:
13675 case Builtin::BI__builtin_umul_overflow:
13676 case Builtin::BI__builtin_umull_overflow:
13677 case Builtin::BI__builtin_umulll_overflow:
13678 Result = LHS.isSigned() ? LHS.smul_ov(RHS, DidOverflow)
13679 : LHS.umul_ov(RHS, DidOverflow);
13685 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
13686 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
13687 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
13693 APSInt Temp = Result.extOrTrunc(Info.Ctx.getTypeSize(ResultType));
13696 if (!APSInt::isSameValue(Temp, Result))
13697 DidOverflow =
true;
13707 case Builtin::BI__builtin_reduce_add:
13708 case Builtin::BI__builtin_reduce_mul:
13709 case Builtin::BI__builtin_reduce_and:
13710 case Builtin::BI__builtin_reduce_or:
13711 case Builtin::BI__builtin_reduce_xor:
13712 case Builtin::BI__builtin_reduce_min:
13713 case Builtin::BI__builtin_reduce_max: {
13720 for (
unsigned EltNum = 1; EltNum < SourceLen; ++EltNum) {
13721 switch (BuiltinOp) {
13724 case Builtin::BI__builtin_reduce_add: {
13727 Reduced.getBitWidth() + 1, std::plus<APSInt>(), Reduced))
13731 case Builtin::BI__builtin_reduce_mul: {
13734 Reduced.getBitWidth() * 2, std::multiplies<APSInt>(), Reduced))
13738 case Builtin::BI__builtin_reduce_and: {
13742 case Builtin::BI__builtin_reduce_or: {
13746 case Builtin::BI__builtin_reduce_xor: {
13750 case Builtin::BI__builtin_reduce_min: {
13754 case Builtin::BI__builtin_reduce_max: {
13764 case clang::X86::BI__builtin_ia32_addcarryx_u32:
13765 case clang::X86::BI__builtin_ia32_addcarryx_u64:
13766 case clang::X86::BI__builtin_ia32_subborrow_u32:
13767 case clang::X86::BI__builtin_ia32_subborrow_u64: {
13768 LValue ResultLValue;
13769 APSInt CarryIn, LHS, RHS;
13777 bool IsAdd = BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u32 ||
13778 BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u64;
13780 unsigned BitWidth = LHS.getBitWidth();
13781 unsigned CarryInBit = CarryIn.ugt(0) ? 1 : 0;
13784 ? (LHS.zext(BitWidth + 1) + (RHS.zext(BitWidth + 1) + CarryInBit))
13785 : (LHS.zext(BitWidth + 1) - (RHS.zext(BitWidth + 1) + CarryInBit));
13787 APInt Result = ExResult.extractBits(BitWidth, 0);
13788 uint64_t CarryOut = ExResult.extractBitsAsZExtValue(1, BitWidth);
13796 case clang::X86::BI__builtin_ia32_bextr_u32:
13797 case clang::X86::BI__builtin_ia32_bextr_u64:
13798 case clang::X86::BI__builtin_ia32_bextri_u32:
13799 case clang::X86::BI__builtin_ia32_bextri_u64: {
13805 unsigned BitWidth = Val.getBitWidth();
13807 uint64_t Length = Idx.extractBitsAsZExtValue(8, 8);
13808 Length = Length > BitWidth ? BitWidth : Length;
13811 if (Length == 0 || Shift >= BitWidth)
13815 Result &= llvm::maskTrailingOnes<uint64_t>(Length);
13819 case clang::X86::BI__builtin_ia32_bzhi_si:
13820 case clang::X86::BI__builtin_ia32_bzhi_di: {
13826 unsigned BitWidth = Val.getBitWidth();
13827 unsigned Index = Idx.extractBitsAsZExtValue(8, 0);
13828 if (Index < BitWidth)
13829 Val.clearHighBits(BitWidth - Index);
13833 case clang::X86::BI__builtin_ia32_lzcnt_u16:
13834 case clang::X86::BI__builtin_ia32_lzcnt_u32:
13835 case clang::X86::BI__builtin_ia32_lzcnt_u64: {
13839 return Success(Val.countLeadingZeros(),
E);
13842 case clang::X86::BI__builtin_ia32_tzcnt_u16:
13843 case clang::X86::BI__builtin_ia32_tzcnt_u32:
13844 case clang::X86::BI__builtin_ia32_tzcnt_u64: {
13848 return Success(Val.countTrailingZeros(),
E);
13851 case clang::X86::BI__builtin_ia32_pdep_si:
13852 case clang::X86::BI__builtin_ia32_pdep_di: {
13858 unsigned BitWidth = Val.getBitWidth();
13859 APInt Result = APInt::getZero(BitWidth);
13860 for (
unsigned I = 0,
P = 0; I != BitWidth; ++I)
13862 Result.setBitVal(I, Val[
P++]);
13866 case clang::X86::BI__builtin_ia32_pext_si:
13867 case clang::X86::BI__builtin_ia32_pext_di: {
13873 unsigned BitWidth = Val.getBitWidth();
13874 APInt Result = APInt::getZero(BitWidth);
13875 for (
unsigned I = 0,
P = 0; I != BitWidth; ++I)
13877 Result.setBitVal(
P++, Val[I]);
13886 const LValue &LV) {
13889 if (!LV.getLValueBase())
13894 if (!LV.getLValueDesignator().Invalid &&
13895 !LV.getLValueDesignator().isOnePastTheEnd())
13900 QualType Ty = getType(LV.getLValueBase());
13905 if (LV.getLValueDesignator().Invalid)
13911 return LV.getLValueOffset() == Size;
13921class DataRecursiveIntBinOpEvaluator {
13922 struct EvalResult {
13924 bool Failed =
false;
13926 EvalResult() =
default;
13928 void swap(EvalResult &RHS) {
13930 Failed = RHS.Failed;
13931 RHS.Failed =
false;
13937 EvalResult LHSResult;
13938 enum { AnyExprKind, BinOpKind, BinOpVisitedLHSKind }
Kind;
13941 Job(Job &&) =
default;
13943 void startSpeculativeEval(EvalInfo &Info) {
13944 SpecEvalRAII = SpeculativeEvaluationRAII(Info);
13948 SpeculativeEvaluationRAII SpecEvalRAII;
13953 IntExprEvaluator &IntEval;
13958 DataRecursiveIntBinOpEvaluator(IntExprEvaluator &IntEval,
APValue &Result)
13959 : IntEval(IntEval), Info(IntEval.getEvalInfo()), FinalResult(Result) { }
13966 return E->getOpcode() == BO_Comma ||
E->isLogicalOp() ||
13974 EvalResult PrevResult;
13975 while (!Queue.empty())
13976 process(PrevResult);
13978 if (PrevResult.Failed)
return false;
13980 FinalResult.
swap(PrevResult.Val);
13986 return IntEval.Success(
Value,
E, Result);
13989 return IntEval.Success(
Value,
E, Result);
13992 return IntEval.Error(
E);
13995 return IntEval.Error(
E,
D);
13999 return Info.CCEDiag(
E,
D);
14003 bool VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *
E,
14004 bool &SuppressRHSDiags);
14006 bool VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
14009 void EvaluateExpr(
const Expr *
E, EvalResult &Result) {
14010 Result.Failed = !
Evaluate(Result.Val, Info,
E);
14015 void process(EvalResult &Result);
14017 void enqueue(
const Expr *
E) {
14019 Queue.resize(Queue.size()+1);
14020 Queue.back().E =
E;
14021 Queue.back().Kind = Job::AnyExprKind;
14027bool DataRecursiveIntBinOpEvaluator::
14029 bool &SuppressRHSDiags) {
14030 if (
E->getOpcode() == BO_Comma) {
14032 if (LHSResult.Failed)
14033 return Info.noteSideEffect();
14037 if (
E->isLogicalOp()) {
14042 if (LHSAsBool == (
E->getOpcode() == BO_LOr)) {
14043 Success(LHSAsBool,
E, LHSResult.Val);
14047 LHSResult.Failed =
true;
14051 if (!Info.noteSideEffect())
14057 SuppressRHSDiags =
true;
14066 if (LHSResult.Failed && !Info.noteFailure())
14077 assert(!LVal.
hasLValuePath() &&
"have designator for integer lvalue");
14079 uint64_t Offset64 = Offset.getQuantity();
14080 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
14082 : Offset64 + Index64);
14085bool DataRecursiveIntBinOpEvaluator::
14086 VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
14088 if (
E->getOpcode() == BO_Comma) {
14089 if (RHSResult.Failed)
14091 Result = RHSResult.Val;
14095 if (
E->isLogicalOp()) {
14096 bool lhsResult, rhsResult;
14102 if (
E->getOpcode() == BO_LOr)
14103 return Success(lhsResult || rhsResult,
E, Result);
14105 return Success(lhsResult && rhsResult,
E, Result);
14111 if (rhsResult == (
E->getOpcode() == BO_LOr))
14112 return Success(rhsResult,
E, Result);
14122 if (LHSResult.Failed || RHSResult.Failed)
14125 const APValue &LHSVal = LHSResult.Val;
14126 const APValue &RHSVal = RHSResult.Val;
14136 if (
E->getOpcode() == BO_Add &&
14150 if (!LHSExpr || !RHSExpr)
14152 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
14153 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
14154 if (!LHSAddrExpr || !RHSAddrExpr)
14160 Result =
APValue(LHSAddrExpr, RHSAddrExpr);
14179void DataRecursiveIntBinOpEvaluator::process(EvalResult &Result) {
14180 Job &job = Queue.back();
14182 switch (job.Kind) {
14183 case Job::AnyExprKind: {
14184 if (
const BinaryOperator *Bop = dyn_cast<BinaryOperator>(job.E)) {
14185 if (shouldEnqueue(Bop)) {
14186 job.Kind = Job::BinOpKind;
14187 enqueue(Bop->getLHS());
14192 EvaluateExpr(job.E, Result);
14197 case Job::BinOpKind: {
14199 bool SuppressRHSDiags =
false;
14200 if (!VisitBinOpLHSOnly(Result, Bop, SuppressRHSDiags)) {
14204 if (SuppressRHSDiags)
14205 job.startSpeculativeEval(Info);
14206 job.LHSResult.swap(Result);
14207 job.Kind = Job::BinOpVisitedLHSKind;
14212 case Job::BinOpVisitedLHSKind: {
14216 Result.Failed = !VisitBinOp(job.LHSResult, RHS, Bop, Result.Val);
14222 llvm_unreachable(
"Invalid Job::Kind!");
14226enum class CmpResult {
14235template <
class SuccessCB,
class AfterCB>
14238 SuccessCB &&
Success, AfterCB &&DoAfter) {
14240 assert(
E->isComparisonOp() &&
"expected comparison operator");
14241 assert((
E->getOpcode() == BO_Cmp ||
14243 "unsupported binary expression evaluation");
14244 auto Error = [&](
const Expr *
E) {
14245 Info.FFDiag(
E, diag::note_invalid_subexpr_in_const_expr);
14249 bool IsRelational =
E->isRelationalOp() ||
E->getOpcode() == BO_Cmp;
14250 bool IsEquality =
E->isEqualityOp();
14259 if (!LHSOK && !Info.noteFailure())
14264 return Success(CmpResult::Less,
E);
14266 return Success(CmpResult::Greater,
E);
14267 return Success(CmpResult::Equal,
E);
14271 APFixedPoint LHSFX(Info.Ctx.getFixedPointSemantics(LHSTy));
14272 APFixedPoint RHSFX(Info.Ctx.getFixedPointSemantics(RHSTy));
14275 if (!LHSOK && !Info.noteFailure())
14280 return Success(CmpResult::Less,
E);
14282 return Success(CmpResult::Greater,
E);
14283 return Success(CmpResult::Equal,
E);
14287 ComplexValue LHS, RHS;
14289 if (
E->isAssignmentOp()) {
14296 LHS.makeComplexFloat();
14297 LHS.FloatImag = APFloat(LHS.FloatReal.getSemantics());
14302 if (!LHSOK && !Info.noteFailure())
14308 RHS.makeComplexFloat();
14309 RHS.FloatImag = APFloat(RHS.FloatReal.getSemantics());
14313 if (LHS.isComplexFloat()) {
14314 APFloat::cmpResult CR_r =
14315 LHS.getComplexFloatReal().compare(RHS.getComplexFloatReal());
14316 APFloat::cmpResult CR_i =
14317 LHS.getComplexFloatImag().compare(RHS.getComplexFloatImag());
14318 bool IsEqual = CR_r == APFloat::cmpEqual && CR_i == APFloat::cmpEqual;
14319 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal,
E);
14321 assert(IsEquality &&
"invalid complex comparison");
14322 bool IsEqual = LHS.getComplexIntReal() == RHS.getComplexIntReal() &&
14323 LHS.getComplexIntImag() == RHS.getComplexIntImag();
14324 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal,
E);
14330 APFloat RHS(0.0), LHS(0.0);
14333 if (!LHSOK && !Info.noteFailure())
14339 assert(
E->isComparisonOp() &&
"Invalid binary operator!");
14340 llvm::APFloatBase::cmpResult APFloatCmpResult = LHS.compare(RHS);
14341 if (!Info.InConstantContext &&
14342 APFloatCmpResult == APFloat::cmpUnordered &&
14345 Info.FFDiag(
E, diag::note_constexpr_float_arithmetic_strict);
14348 auto GetCmpRes = [&]() {
14349 switch (APFloatCmpResult) {
14350 case APFloat::cmpEqual:
14351 return CmpResult::Equal;
14352 case APFloat::cmpLessThan:
14353 return CmpResult::Less;
14354 case APFloat::cmpGreaterThan:
14355 return CmpResult::Greater;
14356 case APFloat::cmpUnordered:
14357 return CmpResult::Unordered;
14359 llvm_unreachable(
"Unrecognised APFloat::cmpResult enum");
14365 LValue LHSValue, RHSValue;
14368 if (!LHSOK && !Info.noteFailure())
14377 (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown))
14383 auto DiagComparison = [&] (
unsigned DiagID,
bool Reversed =
false) {
14384 std::string LHS = LHSValue.toString(Info.Ctx,
E->getLHS()->
getType());
14385 std::string RHS = RHSValue.toString(Info.Ctx,
E->getRHS()->
getType());
14386 Info.FFDiag(
E, DiagID)
14393 return DiagComparison(
14394 diag::note_constexpr_pointer_comparison_unspecified);
14400 if ((!LHSValue.Base && !LHSValue.Offset.isZero()) ||
14401 (!RHSValue.Base && !RHSValue.Offset.isZero()))
14402 return DiagComparison(diag::note_constexpr_pointer_constant_comparison,
14416 return DiagComparison(diag::note_constexpr_literal_comparison);
14418 return DiagComparison(diag::note_constexpr_opaque_call_comparison,
14423 return DiagComparison(diag::note_constexpr_pointer_weak_comparison,
14427 if (LHSValue.Base && LHSValue.Offset.isZero() &&
14429 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
14431 if (RHSValue.Base && RHSValue.Offset.isZero() &&
14433 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
14439 return DiagComparison(
14440 diag::note_constexpr_pointer_comparison_zero_sized);
14441 return Success(CmpResult::Unequal,
E);
14444 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
14445 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
14447 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
14448 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
14458 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid && IsRelational) {
14459 bool WasArrayIndex;
14461 getType(LHSValue.Base), LHSDesignator, RHSDesignator, WasArrayIndex);
14468 if (!WasArrayIndex && Mismatch < LHSDesignator.Entries.size() &&
14469 Mismatch < RHSDesignator.Entries.size()) {
14470 const FieldDecl *LF = getAsField(LHSDesignator.Entries[Mismatch]);
14471 const FieldDecl *RF = getAsField(RHSDesignator.Entries[Mismatch]);
14473 Info.CCEDiag(
E, diag::note_constexpr_pointer_comparison_base_classes);
14475 Info.CCEDiag(
E, diag::note_constexpr_pointer_comparison_base_field)
14476 << getAsBaseClass(LHSDesignator.Entries[Mismatch])
14479 Info.CCEDiag(
E, diag::note_constexpr_pointer_comparison_base_field)
14480 << getAsBaseClass(RHSDesignator.Entries[Mismatch])
14485 diag::note_constexpr_pointer_comparison_differing_access)
14493 unsigned PtrSize = Info.Ctx.getTypeSize(LHSTy);
14496 assert(PtrSize <= 64 &&
"Unexpected pointer width");
14497 uint64_t Mask = ~0ULL >> (64 - PtrSize);
14498 CompareLHS &= Mask;
14499 CompareRHS &= Mask;
14504 if (!LHSValue.Base.isNull() && IsRelational) {
14505 QualType BaseTy = getType(LHSValue.Base);
14508 CharUnits Size = Info.Ctx.getTypeSizeInChars(BaseTy);
14509 uint64_t OffsetLimit = Size.getQuantity();
14510 if (CompareLHS > OffsetLimit || CompareRHS > OffsetLimit)
14514 if (CompareLHS < CompareRHS)
14515 return Success(CmpResult::Less,
E);
14516 if (CompareLHS > CompareRHS)
14517 return Success(CmpResult::Greater,
E);
14518 return Success(CmpResult::Equal,
E);
14522 assert(IsEquality &&
"unexpected member pointer operation");
14525 MemberPtr LHSValue, RHSValue;
14528 if (!LHSOK && !Info.noteFailure())
14536 if (LHSValue.getDecl() && LHSValue.getDecl()->isWeak()) {
14537 Info.FFDiag(
E, diag::note_constexpr_mem_pointer_weak_comparison)
14538 << LHSValue.getDecl();
14541 if (RHSValue.getDecl() && RHSValue.getDecl()->isWeak()) {
14542 Info.FFDiag(
E, diag::note_constexpr_mem_pointer_weak_comparison)
14543 << RHSValue.getDecl();
14550 if (!LHSValue.getDecl() || !RHSValue.getDecl()) {
14551 bool Equal = !LHSValue.getDecl() && !RHSValue.getDecl();
14552 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal,
E);
14557 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(LHSValue.getDecl()))
14558 if (MD->isVirtual())
14559 Info.CCEDiag(
E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
14560 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(RHSValue.getDecl()))
14561 if (MD->isVirtual())
14562 Info.CCEDiag(
E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
14568 bool Equal = LHSValue == RHSValue;
14569 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal,
E);
14573 assert(
E->isComparisonOp() &&
"unexpected nullptr operation");
14574 assert(RHSTy->
isNullPtrType() &&
"missing pointer conversion");
14582 return Success(CmpResult::Equal,
E);
14595 case CmpResult::Unequal:
14596 llvm_unreachable(
"should never produce Unequal for three-way comparison");
14597 case CmpResult::Less:
14598 CCR = ComparisonCategoryResult::Less;
14600 case CmpResult::Equal:
14601 CCR = ComparisonCategoryResult::Equal;
14603 case CmpResult::Greater:
14604 CCR = ComparisonCategoryResult::Greater;
14606 case CmpResult::Unordered:
14607 CCR = ComparisonCategoryResult::Unordered;
14621 ConstantExprKind::Normal);
14624 return ExprEvaluatorBaseTy::VisitBinCmp(
E);
14628bool RecordExprEvaluator::VisitCXXParenListInitExpr(
14630 return VisitCXXParenListOrInitListExpr(
E,
E->getInitExprs());
14636 if (
E->isAssignmentOp()) {
14638 if (!Info.noteFailure())
14642 if (DataRecursiveIntBinOpEvaluator::shouldEnqueue(
E))
14643 return DataRecursiveIntBinOpEvaluator(*
this, Result).Traverse(
E);
14647 "DataRecursiveIntBinOpEvaluator should have handled integral types");
14649 if (
E->isComparisonOp()) {
14653 assert((CR != CmpResult::Unequal ||
E->isEqualityOp()) &&
14654 "should only produce Unequal for equality comparisons");
14655 bool IsEqual = CR == CmpResult::Equal,
14656 IsLess = CR == CmpResult::Less,
14657 IsGreater = CR == CmpResult::Greater;
14658 auto Op =
E->getOpcode();
14661 llvm_unreachable(
"unsupported binary operator");
14664 return Success(IsEqual == (Op == BO_EQ),
E);
14670 return Success(IsEqual || IsLess,
E);
14672 return Success(IsEqual || IsGreater,
E);
14676 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
14684 E->getOpcode() == BO_Sub) {
14685 LValue LHSValue, RHSValue;
14688 if (!LHSOK && !Info.noteFailure())
14698 if (!LHSValue.Offset.isZero() || !RHSValue.Offset.isZero())
14700 const Expr *LHSExpr = LHSValue.Base.dyn_cast<
const Expr *>();
14701 const Expr *RHSExpr = RHSValue.Base.dyn_cast<
const Expr *>();
14703 auto DiagArith = [&](
unsigned DiagID) {
14704 std::string LHS = LHSValue.toString(Info.Ctx,
E->getLHS()->
getType());
14705 std::string RHS = RHSValue.toString(Info.Ctx,
E->getRHS()->
getType());
14706 Info.FFDiag(
E, DiagID) << LHS << RHS;
14707 if (LHSExpr && LHSExpr == RHSExpr)
14709 diag::note_constexpr_repeated_literal_eval)
14714 if (!LHSExpr || !RHSExpr)
14715 return DiagArith(diag::note_constexpr_pointer_arith_unspecified);
14718 return DiagArith(diag::note_constexpr_literal_arith);
14720 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
14721 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
14722 if (!LHSAddrExpr || !RHSAddrExpr)
14730 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
14731 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
14733 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
14734 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
14740 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid &&
14743 Info.CCEDiag(
E, diag::note_constexpr_pointer_subtraction_not_same_array);
14755 if (ElementSize.
isZero()) {
14756 Info.FFDiag(
E, diag::note_constexpr_pointer_subtraction_zero_size)
14773 APSInt TrueResult = (LHS - RHS) / ElemSize;
14774 APSInt Result = TrueResult.trunc(Info.Ctx.getIntWidth(
E->
getType()));
14776 if (Result.extend(65) != TrueResult &&
14782 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
14787bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr(
14789 switch(
E->getKind()) {
14790 case UETT_PreferredAlignOf:
14791 case UETT_AlignOf: {
14792 if (
E->isArgumentType())
14800 case UETT_PtrAuthTypeDiscriminator: {
14801 if (
E->getArgumentType()->isDependentType())
14804 Info.Ctx.getPointerAuthTypeDiscriminator(
E->getArgumentType()),
E);
14806 case UETT_VecStep: {
14822 case UETT_DataSizeOf:
14823 case UETT_SizeOf: {
14824 QualType SrcTy =
E->getTypeOfArgument();
14832 E->getKind() == UETT_DataSizeOf ? SizeOfType::DataSizeOf
14833 : SizeOfType::SizeOf)) {
14838 case UETT_OpenMPRequiredSimdAlign:
14839 assert(
E->isArgumentType());
14841 Info.Ctx.toCharUnitsFromBits(
14842 Info.Ctx.getOpenMPDefaultSimdAlign(
E->getArgumentType()))
14845 case UETT_VectorElements: {
14853 if (Info.InConstantContext)
14854 Info.CCEDiag(
E, diag::note_constexpr_non_const_vectorelements)
14861 llvm_unreachable(
"unknown expr/type trait");
14864bool IntExprEvaluator::VisitOffsetOfExpr(
const OffsetOfExpr *OOE) {
14870 for (
unsigned i = 0; i != n; ++i) {
14878 const ArrayType *AT = Info.Ctx.getAsArrayType(CurrentType);
14882 CharUnits ElementSize = Info.Ctx.getTypeSizeInChars(CurrentType);
14883 Result += IdxResult.getSExtValue() * ElementSize;
14896 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
14903 llvm_unreachable(
"dependent __builtin_offsetof");
14919 CurrentType = BaseSpec->
getType();
14933bool IntExprEvaluator::VisitUnaryOperator(
const UnaryOperator *
E) {
14934 switch (
E->getOpcode()) {
14942 return Visit(
E->getSubExpr());
14945 return Visit(
E->getSubExpr());
14947 if (!Visit(
E->getSubExpr()))
14949 if (!Result.isInt())
return Error(
E);
14951 if (
Value.isSigned() &&
Value.isMinSignedValue() &&
E->canOverflow()) {
14952 if (Info.checkingForUndefinedBehavior())
14953 Info.Ctx.getDiagnostics().Report(
E->
getExprLoc(),
14954 diag::warn_integer_constant_overflow)
14966 if (!Visit(
E->getSubExpr()))
14968 if (!Result.isInt())
return Error(
E);
14969 return Success(~Result.getInt(),
E);
14982bool IntExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
14983 const Expr *SubExpr =
E->getSubExpr();
14987 switch (
E->getCastKind()) {
14988 case CK_BaseToDerived:
14989 case CK_DerivedToBase:
14990 case CK_UncheckedDerivedToBase:
14993 case CK_ArrayToPointerDecay:
14994 case CK_FunctionToPointerDecay:
14995 case CK_NullToPointer:
14996 case CK_NullToMemberPointer:
14997 case CK_BaseToDerivedMemberPointer:
14998 case CK_DerivedToBaseMemberPointer:
14999 case CK_ReinterpretMemberPointer:
15000 case CK_ConstructorConversion:
15001 case CK_IntegralToPointer:
15003 case CK_VectorSplat:
15004 case CK_IntegralToFloating:
15005 case CK_FloatingCast:
15006 case CK_CPointerToObjCPointerCast:
15007 case CK_BlockPointerToObjCPointerCast:
15008 case CK_AnyPointerToBlockPointerCast:
15009 case CK_ObjCObjectLValueCast:
15010 case CK_FloatingRealToComplex:
15011 case CK_FloatingComplexToReal:
15012 case CK_FloatingComplexCast:
15013 case CK_FloatingComplexToIntegralComplex:
15014 case CK_IntegralRealToComplex:
15015 case CK_IntegralComplexCast:
15016 case CK_IntegralComplexToFloatingComplex:
15017 case CK_BuiltinFnToFnPtr:
15018 case CK_ZeroToOCLOpaqueType:
15019 case CK_NonAtomicToAtomic:
15020 case CK_AddressSpaceConversion:
15021 case CK_IntToOCLSampler:
15022 case CK_FloatingToFixedPoint:
15023 case CK_FixedPointToFloating:
15024 case CK_FixedPointCast:
15025 case CK_IntegralToFixedPoint:
15026 case CK_MatrixCast:
15027 llvm_unreachable(
"invalid cast kind for integral value");
15031 case CK_LValueBitCast:
15032 case CK_ARCProduceObject:
15033 case CK_ARCConsumeObject:
15034 case CK_ARCReclaimReturnedObject:
15035 case CK_ARCExtendBlockObject:
15036 case CK_CopyAndAutoreleaseBlockObject:
15039 case CK_UserDefinedConversion:
15040 case CK_LValueToRValue:
15041 case CK_AtomicToNonAtomic:
15043 case CK_LValueToRValueBitCast:
15044 case CK_HLSLArrayRValue:
15045 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
15047 case CK_MemberPointerToBoolean:
15048 case CK_PointerToBoolean:
15049 case CK_IntegralToBoolean:
15050 case CK_FloatingToBoolean:
15051 case CK_BooleanToSignedIntegral:
15052 case CK_FloatingComplexToBoolean:
15053 case CK_IntegralComplexToBoolean: {
15058 if (BoolResult &&
E->getCastKind() == CK_BooleanToSignedIntegral)
15063 case CK_FixedPointToIntegral: {
15064 APFixedPoint Src(Info.Ctx.getFixedPointSemantics(SrcType));
15068 llvm::APSInt Result = Src.convertToInt(
15069 Info.Ctx.getIntWidth(DestType),
15076 case CK_FixedPointToBoolean: {
15079 if (!
Evaluate(Val, Info, SubExpr))
15084 case CK_IntegralCast: {
15085 if (!Visit(SubExpr))
15088 if (!Result.isInt()) {
15094 if (Result.isAddrLabelDiff())
15095 return Info.Ctx.getTypeSize(DestType) <= Info.Ctx.getTypeSize(SrcType);
15097 return Info.Ctx.getTypeSize(DestType) == Info.Ctx.getTypeSize(SrcType);
15100 if (Info.Ctx.getLangOpts().CPlusPlus && Info.InConstantContext &&
15101 Info.EvalMode == EvalInfo::EM_ConstantExpression &&
15104 bool ConstexprVar =
true;
15111 if (
const auto *VD = dyn_cast_or_null<VarDecl>(
15112 Info.EvaluatingDecl.dyn_cast<
const ValueDecl *>()))
15135 (
Max.slt(Result.getInt().getSExtValue()) ||
15136 Min.sgt(Result.getInt().getSExtValue())))
15137 Info.CCEDiag(
E, diag::note_constexpr_unscoped_enum_out_of_range)
15138 << llvm::toString(Result.getInt(), 10) <<
Min.getSExtValue()
15139 <<
Max.getSExtValue() << ED;
15141 Max.ult(Result.getInt().getZExtValue()))
15142 Info.CCEDiag(
E, diag::note_constexpr_unscoped_enum_out_of_range)
15143 << llvm::toString(Result.getInt(), 10) <<
Min.getZExtValue()
15144 <<
Max.getZExtValue() << ED;
15149 Result.getInt()),
E);
15152 case CK_PointerToIntegral: {
15153 CCEDiag(
E, diag::note_constexpr_invalid_cast)
15160 if (LV.getLValueBase()) {
15165 if (Info.Ctx.getTypeSize(DestType) != Info.Ctx.getTypeSize(SrcType))
15168 LV.Designator.setInvalid();
15169 LV.moveInto(Result);
15176 if (!
V.toIntegralConstant(AsInt, SrcType, Info.Ctx))
15177 llvm_unreachable(
"Can't cast this!");
15182 case CK_IntegralComplexToReal: {
15186 return Success(
C.getComplexIntReal(),
E);
15189 case CK_FloatingToIntegral: {
15199 case CK_HLSLVectorTruncation: {
15207 llvm_unreachable(
"unknown cast resulting in integral value");
15215 if (!LV.isComplexInt())
15217 return Success(LV.getComplexIntReal(),
E);
15220 return Visit(
E->getSubExpr());
15228 if (!LV.isComplexInt())
15230 return Success(LV.getComplexIntImag(),
E);
15233 VisitIgnoredValue(
E->getSubExpr());
15245bool IntExprEvaluator::VisitConceptSpecializationExpr(
15250bool IntExprEvaluator::VisitRequiresExpr(
const RequiresExpr *
E) {
15254bool FixedPointExprEvaluator::VisitUnaryOperator(
const UnaryOperator *
E) {
15255 switch (
E->getOpcode()) {
15261 return Visit(
E->getSubExpr());
15263 if (!Visit(
E->getSubExpr()))
return false;
15264 if (!Result.isFixedPoint())
15267 APFixedPoint Negated = Result.getFixedPoint().negate(&Overflowed);
15281bool FixedPointExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
15282 const Expr *SubExpr =
E->getSubExpr();
15285 "Expected destination type to be a fixed point type");
15286 auto DestFXSema = Info.Ctx.getFixedPointSemantics(DestType);
15288 switch (
E->getCastKind()) {
15289 case CK_FixedPointCast: {
15290 APFixedPoint Src(Info.Ctx.getFixedPointSemantics(SubExpr->
getType()));
15294 APFixedPoint Result = Src.convert(DestFXSema, &Overflowed);
15296 if (Info.checkingForUndefinedBehavior())
15297 Info.Ctx.getDiagnostics().Report(
E->
getExprLoc(),
15298 diag::warn_fixedpoint_constant_overflow)
15299 << Result.toString() <<
E->
getType();
15305 case CK_IntegralToFixedPoint: {
15311 APFixedPoint IntResult = APFixedPoint::getFromIntValue(
15312 Src, Info.Ctx.getFixedPointSemantics(DestType), &Overflowed);
15315 if (Info.checkingForUndefinedBehavior())
15316 Info.Ctx.getDiagnostics().Report(
E->
getExprLoc(),
15317 diag::warn_fixedpoint_constant_overflow)
15318 << IntResult.toString() <<
E->
getType();
15325 case CK_FloatingToFixedPoint: {
15331 APFixedPoint Result = APFixedPoint::getFromFloatValue(
15332 Src, Info.Ctx.getFixedPointSemantics(DestType), &Overflowed);
15335 if (Info.checkingForUndefinedBehavior())
15336 Info.Ctx.getDiagnostics().Report(
E->
getExprLoc(),
15337 diag::warn_fixedpoint_constant_overflow)
15338 << Result.toString() <<
E->
getType();
15346 case CK_LValueToRValue:
15347 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
15353bool FixedPointExprEvaluator::VisitBinaryOperator(
const BinaryOperator *
E) {
15354 if (
E->isPtrMemOp() ||
E->isAssignmentOp() ||
E->getOpcode() == BO_Comma)
15355 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
15357 const Expr *LHS =
E->getLHS();
15358 const Expr *RHS =
E->getRHS();
15360 Info.Ctx.getFixedPointSemantics(
E->
getType());
15362 APFixedPoint LHSFX(Info.Ctx.getFixedPointSemantics(LHS->
getType()));
15365 APFixedPoint RHSFX(Info.Ctx.getFixedPointSemantics(RHS->
getType()));
15369 bool OpOverflow =
false, ConversionOverflow =
false;
15370 APFixedPoint Result(LHSFX.getSemantics());
15371 switch (
E->getOpcode()) {
15373 Result = LHSFX.
add(RHSFX, &OpOverflow)
15374 .convert(ResultFXSema, &ConversionOverflow);
15378 Result = LHSFX.sub(RHSFX, &OpOverflow)
15379 .convert(ResultFXSema, &ConversionOverflow);
15383 Result = LHSFX.mul(RHSFX, &OpOverflow)
15384 .convert(ResultFXSema, &ConversionOverflow);
15388 if (RHSFX.getValue() == 0) {
15389 Info.FFDiag(
E, diag::note_expr_divide_by_zero);
15392 Result = LHSFX.div(RHSFX, &OpOverflow)
15393 .convert(ResultFXSema, &ConversionOverflow);
15399 llvm::APSInt RHSVal = RHSFX.getValue();
15402 LHSSema.getWidth() - (
unsigned)LHSSema.hasUnsignedPadding();
15403 unsigned Amt = RHSVal.getLimitedValue(ShiftBW - 1);
15407 if (RHSVal.isNegative())
15408 Info.CCEDiag(
E, diag::note_constexpr_negative_shift) << RHSVal;
15409 else if (Amt != RHSVal)
15410 Info.CCEDiag(
E, diag::note_constexpr_large_shift)
15411 << RHSVal <<
E->
getType() << ShiftBW;
15413 if (
E->getOpcode() == BO_Shl)
15414 Result = LHSFX.shl(Amt, &OpOverflow);
15416 Result = LHSFX.shr(Amt, &OpOverflow);
15422 if (OpOverflow || ConversionOverflow) {
15423 if (Info.checkingForUndefinedBehavior())
15424 Info.Ctx.getDiagnostics().Report(
E->
getExprLoc(),
15425 diag::warn_fixedpoint_constant_overflow)
15426 << Result.toString() <<
E->
getType();
15438class FloatExprEvaluator
15439 :
public ExprEvaluatorBase<FloatExprEvaluator> {
15442 FloatExprEvaluator(EvalInfo &info, APFloat &result)
15443 : ExprEvaluatorBaseTy(info), Result(result) {}
15446 Result =
V.getFloat();
15450 bool ZeroInitialization(
const Expr *
E) {
15451 Result = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(
E->
getType()));
15472 return FloatExprEvaluator(Info, Result).Visit(
E);
15479 llvm::APFloat &Result) {
15481 if (!S)
return false;
15488 if (S->getString().empty())
15489 fill = llvm::APInt(32, 0);
15490 else if (S->getString().getAsInteger(0, fill))
15495 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
15497 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
15505 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
15507 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
15513bool FloatExprEvaluator::VisitCallExpr(
const CallExpr *
E) {
15514 if (!IsConstantEvaluatedBuiltinCall(
E))
15515 return ExprEvaluatorBaseTy::VisitCallExpr(
E);
15517 switch (
E->getBuiltinCallee()) {
15521 case Builtin::BI__builtin_huge_val:
15522 case Builtin::BI__builtin_huge_valf:
15523 case Builtin::BI__builtin_huge_vall:
15524 case Builtin::BI__builtin_huge_valf16:
15525 case Builtin::BI__builtin_huge_valf128:
15526 case Builtin::BI__builtin_inf:
15527 case Builtin::BI__builtin_inff:
15528 case Builtin::BI__builtin_infl:
15529 case Builtin::BI__builtin_inff16:
15530 case Builtin::BI__builtin_inff128: {
15531 const llvm::fltSemantics &Sem =
15532 Info.Ctx.getFloatTypeSemantics(
E->
getType());
15533 Result = llvm::APFloat::getInf(Sem);
15537 case Builtin::BI__builtin_nans:
15538 case Builtin::BI__builtin_nansf:
15539 case Builtin::BI__builtin_nansl:
15540 case Builtin::BI__builtin_nansf16:
15541 case Builtin::BI__builtin_nansf128:
15547 case Builtin::BI__builtin_nan:
15548 case Builtin::BI__builtin_nanf:
15549 case Builtin::BI__builtin_nanl:
15550 case Builtin::BI__builtin_nanf16:
15551 case Builtin::BI__builtin_nanf128:
15559 case Builtin::BI__builtin_fabs:
15560 case Builtin::BI__builtin_fabsf:
15561 case Builtin::BI__builtin_fabsl:
15562 case Builtin::BI__builtin_fabsf128:
15571 if (Result.isNegative())
15572 Result.changeSign();
15575 case Builtin::BI__arithmetic_fence:
15582 case Builtin::BI__builtin_copysign:
15583 case Builtin::BI__builtin_copysignf:
15584 case Builtin::BI__builtin_copysignl:
15585 case Builtin::BI__builtin_copysignf128: {
15590 Result.copySign(RHS);
15594 case Builtin::BI__builtin_fmax:
15595 case Builtin::BI__builtin_fmaxf:
15596 case Builtin::BI__builtin_fmaxl:
15597 case Builtin::BI__builtin_fmaxf16:
15598 case Builtin::BI__builtin_fmaxf128: {
15605 if (Result.isZero() && RHS.isZero() && Result.isNegative())
15607 else if (Result.isNaN() || RHS > Result)
15612 case Builtin::BI__builtin_fmin:
15613 case Builtin::BI__builtin_fminf:
15614 case Builtin::BI__builtin_fminl:
15615 case Builtin::BI__builtin_fminf16:
15616 case Builtin::BI__builtin_fminf128: {
15623 if (Result.isZero() && RHS.isZero() && RHS.isNegative())
15625 else if (Result.isNaN() || RHS < Result)
15630 case Builtin::BI__builtin_fmaximum_num:
15631 case Builtin::BI__builtin_fmaximum_numf:
15632 case Builtin::BI__builtin_fmaximum_numl:
15633 case Builtin::BI__builtin_fmaximum_numf16:
15634 case Builtin::BI__builtin_fmaximum_numf128: {
15639 Result = maximumnum(Result, RHS);
15643 case Builtin::BI__builtin_fminimum_num:
15644 case Builtin::BI__builtin_fminimum_numf:
15645 case Builtin::BI__builtin_fminimum_numl:
15646 case Builtin::BI__builtin_fminimum_numf16:
15647 case Builtin::BI__builtin_fminimum_numf128: {
15652 Result = minimumnum(Result, RHS);
15658bool FloatExprEvaluator::VisitUnaryReal(
const UnaryOperator *
E) {
15663 Result = CV.FloatReal;
15667 return Visit(
E->getSubExpr());
15670bool FloatExprEvaluator::VisitUnaryImag(
const UnaryOperator *
E) {
15675 Result = CV.FloatImag;
15679 VisitIgnoredValue(
E->getSubExpr());
15680 const llvm::fltSemantics &Sem = Info.Ctx.getFloatTypeSemantics(
E->
getType());
15681 Result = llvm::APFloat::getZero(Sem);
15685bool FloatExprEvaluator::VisitUnaryOperator(
const UnaryOperator *
E) {
15686 switch (
E->getOpcode()) {
15687 default:
return Error(
E);
15696 Result.changeSign();
15701bool FloatExprEvaluator::VisitBinaryOperator(
const BinaryOperator *
E) {
15702 if (
E->isPtrMemOp() ||
E->isAssignmentOp() ||
E->getOpcode() == BO_Comma)
15703 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
15707 if (!LHSOK && !Info.noteFailure())
15714 Result =
E->getValue();
15718bool FloatExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
15719 const Expr* SubExpr =
E->getSubExpr();
15721 switch (
E->getCastKind()) {
15723 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
15725 case CK_IntegralToFloating: {
15728 Info.Ctx.getLangOpts());
15734 case CK_FixedPointToFloating: {
15735 APFixedPoint FixResult(Info.Ctx.getFixedPointSemantics(SubExpr->
getType()));
15739 FixResult.convertToFloat(Info.Ctx.getFloatTypeSemantics(
E->
getType()));
15743 case CK_FloatingCast: {
15744 if (!Visit(SubExpr))
15750 case CK_FloatingComplexToReal: {
15754 Result =
V.getComplexFloatReal();
15757 case CK_HLSLVectorTruncation: {
15771class ComplexExprEvaluator
15772 :
public ExprEvaluatorBase<ComplexExprEvaluator> {
15773 ComplexValue &Result;
15776 ComplexExprEvaluator(EvalInfo &info, ComplexValue &Result)
15777 : ExprEvaluatorBaseTy(info), Result(Result) {}
15784 bool ZeroInitialization(
const Expr *
E);
15803 return ComplexExprEvaluator(Info, Result).Visit(
E);
15806bool ComplexExprEvaluator::ZeroInitialization(
const Expr *
E) {
15809 Result.makeComplexFloat();
15810 APFloat Zero = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(ElemTy));
15811 Result.FloatReal =
Zero;
15812 Result.FloatImag =
Zero;
15814 Result.makeComplexInt();
15815 APSInt Zero = Info.Ctx.MakeIntValue(0, ElemTy);
15816 Result.IntReal =
Zero;
15817 Result.IntImag =
Zero;
15823 const Expr* SubExpr =
E->getSubExpr();
15826 Result.makeComplexFloat();
15827 APFloat &Imag = Result.FloatImag;
15831 Result.FloatReal =
APFloat(Imag.getSemantics());
15835 "Unexpected imaginary literal.");
15837 Result.makeComplexInt();
15838 APSInt &Imag = Result.IntImag;
15842 Result.IntReal =
APSInt(Imag.getBitWidth(), !Imag.isSigned());
15847bool ComplexExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
15849 switch (
E->getCastKind()) {
15851 case CK_BaseToDerived:
15852 case CK_DerivedToBase:
15853 case CK_UncheckedDerivedToBase:
15856 case CK_ArrayToPointerDecay:
15857 case CK_FunctionToPointerDecay:
15858 case CK_NullToPointer:
15859 case CK_NullToMemberPointer:
15860 case CK_BaseToDerivedMemberPointer:
15861 case CK_DerivedToBaseMemberPointer:
15862 case CK_MemberPointerToBoolean:
15863 case CK_ReinterpretMemberPointer:
15864 case CK_ConstructorConversion:
15865 case CK_IntegralToPointer:
15866 case CK_PointerToIntegral:
15867 case CK_PointerToBoolean:
15869 case CK_VectorSplat:
15870 case CK_IntegralCast:
15871 case CK_BooleanToSignedIntegral:
15872 case CK_IntegralToBoolean:
15873 case CK_IntegralToFloating:
15874 case CK_FloatingToIntegral:
15875 case CK_FloatingToBoolean:
15876 case CK_FloatingCast:
15877 case CK_CPointerToObjCPointerCast:
15878 case CK_BlockPointerToObjCPointerCast:
15879 case CK_AnyPointerToBlockPointerCast:
15880 case CK_ObjCObjectLValueCast:
15881 case CK_FloatingComplexToReal:
15882 case CK_FloatingComplexToBoolean:
15883 case CK_IntegralComplexToReal:
15884 case CK_IntegralComplexToBoolean:
15885 case CK_ARCProduceObject:
15886 case CK_ARCConsumeObject:
15887 case CK_ARCReclaimReturnedObject:
15888 case CK_ARCExtendBlockObject:
15889 case CK_CopyAndAutoreleaseBlockObject:
15890 case CK_BuiltinFnToFnPtr:
15891 case CK_ZeroToOCLOpaqueType:
15892 case CK_NonAtomicToAtomic:
15893 case CK_AddressSpaceConversion:
15894 case CK_IntToOCLSampler:
15895 case CK_FloatingToFixedPoint:
15896 case CK_FixedPointToFloating:
15897 case CK_FixedPointCast:
15898 case CK_FixedPointToBoolean:
15899 case CK_FixedPointToIntegral:
15900 case CK_IntegralToFixedPoint:
15901 case CK_MatrixCast:
15902 case CK_HLSLVectorTruncation:
15903 llvm_unreachable(
"invalid cast kind for complex value");
15905 case CK_LValueToRValue:
15906 case CK_AtomicToNonAtomic:
15908 case CK_LValueToRValueBitCast:
15909 case CK_HLSLArrayRValue:
15910 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
15913 case CK_LValueBitCast:
15914 case CK_UserDefinedConversion:
15917 case CK_FloatingRealToComplex: {
15918 APFloat &Real = Result.FloatReal;
15922 Result.makeComplexFloat();
15923 Result.FloatImag =
APFloat(Real.getSemantics());
15927 case CK_FloatingComplexCast: {
15928 if (!Visit(
E->getSubExpr()))
15939 case CK_FloatingComplexToIntegralComplex: {
15940 if (!Visit(
E->getSubExpr()))
15946 Result.makeComplexInt();
15948 To, Result.IntReal) &&
15950 To, Result.IntImag);
15953 case CK_IntegralRealToComplex: {
15954 APSInt &Real = Result.IntReal;
15958 Result.makeComplexInt();
15959 Result.IntImag =
APSInt(Real.getBitWidth(), !Real.isSigned());
15963 case CK_IntegralComplexCast: {
15964 if (!Visit(
E->getSubExpr()))
15976 case CK_IntegralComplexToFloatingComplex: {
15977 if (!Visit(
E->getSubExpr()))
15981 Info.Ctx.getLangOpts());
15985 Result.makeComplexFloat();
15987 To, Result.FloatReal) &&
15989 To, Result.FloatImag);
15993 llvm_unreachable(
"unknown cast resulting in complex value");
15997 APFloat &ResR, APFloat &ResI) {
16003 APFloat AC = A *
C;
16004 APFloat BD = B *
D;
16005 APFloat AD = A *
D;
16006 APFloat BC = B *
C;
16009 if (ResR.isNaN() && ResI.isNaN()) {
16010 bool Recalc =
false;
16011 if (A.isInfinity() || B.isInfinity()) {
16012 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
16014 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
16017 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
16019 D = APFloat::copySign(APFloat(
D.getSemantics()),
D);
16022 if (
C.isInfinity() ||
D.isInfinity()) {
16023 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
16025 D = APFloat::copySign(APFloat(
D.getSemantics(),
D.isInfinity() ? 1 : 0),
16028 A = APFloat::copySign(APFloat(A.getSemantics()), A);
16030 B = APFloat::copySign(APFloat(B.getSemantics()), B);
16033 if (!Recalc && (AC.isInfinity() || BD.isInfinity() || AD.isInfinity() ||
16034 BC.isInfinity())) {
16036 A = APFloat::copySign(APFloat(A.getSemantics()), A);
16038 B = APFloat::copySign(APFloat(B.getSemantics()), B);
16040 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
16042 D = APFloat::copySign(APFloat(
D.getSemantics()),
D);
16046 ResR = APFloat::getInf(A.getSemantics()) * (A *
C - B *
D);
16047 ResI = APFloat::getInf(A.getSemantics()) * (A *
D + B *
C);
16053 APFloat &ResR, APFloat &ResI) {
16060 APFloat MaxCD = maxnum(
abs(
C),
abs(
D));
16061 if (MaxCD.isFinite()) {
16062 DenomLogB =
ilogb(MaxCD);
16063 C =
scalbn(
C, -DenomLogB, APFloat::rmNearestTiesToEven);
16064 D =
scalbn(
D, -DenomLogB, APFloat::rmNearestTiesToEven);
16066 APFloat Denom =
C *
C +
D *
D;
16068 scalbn((A *
C + B *
D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
16070 scalbn((B *
C - A *
D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
16071 if (ResR.isNaN() && ResI.isNaN()) {
16072 if (Denom.isPosZero() && (!A.isNaN() || !B.isNaN())) {
16073 ResR = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * A;
16074 ResI = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * B;
16075 }
else if ((A.isInfinity() || B.isInfinity()) &&
C.isFinite() &&
16077 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
16079 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
16081 ResR = APFloat::getInf(ResR.getSemantics()) * (A *
C + B *
D);
16082 ResI = APFloat::getInf(ResI.getSemantics()) * (B *
C - A *
D);
16083 }
else if (MaxCD.isInfinity() && A.isFinite() && B.isFinite()) {
16084 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
16086 D = APFloat::copySign(APFloat(
D.getSemantics(),
D.isInfinity() ? 1 : 0),
16088 ResR = APFloat::getZero(ResR.getSemantics()) * (A *
C + B *
D);
16089 ResI = APFloat::getZero(ResI.getSemantics()) * (B *
C - A *
D);
16094bool ComplexExprEvaluator::VisitBinaryOperator(
const BinaryOperator *
E) {
16095 if (
E->isPtrMemOp() ||
E->isAssignmentOp() ||
E->getOpcode() == BO_Comma)
16096 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
16100 bool LHSReal =
false, RHSReal =
false;
16105 APFloat &Real = Result.FloatReal;
16108 Result.makeComplexFloat();
16109 Result.FloatImag =
APFloat(Real.getSemantics());
16112 LHSOK = Visit(
E->getLHS());
16114 if (!LHSOK && !Info.noteFailure())
16120 APFloat &Real = RHS.FloatReal;
16123 RHS.makeComplexFloat();
16124 RHS.FloatImag =
APFloat(Real.getSemantics());
16128 assert(!(LHSReal && RHSReal) &&
16129 "Cannot have both operands of a complex operation be real.");
16130 switch (
E->getOpcode()) {
16131 default:
return Error(
E);
16133 if (Result.isComplexFloat()) {
16134 Result.getComplexFloatReal().
add(RHS.getComplexFloatReal(),
16135 APFloat::rmNearestTiesToEven);
16137 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
16139 Result.getComplexFloatImag().
add(RHS.getComplexFloatImag(),
16140 APFloat::rmNearestTiesToEven);
16142 Result.getComplexIntReal() += RHS.getComplexIntReal();
16143 Result.getComplexIntImag() += RHS.getComplexIntImag();
16147 if (Result.isComplexFloat()) {
16148 Result.getComplexFloatReal().subtract(RHS.getComplexFloatReal(),
16149 APFloat::rmNearestTiesToEven);
16151 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
16152 Result.getComplexFloatImag().changeSign();
16153 }
else if (!RHSReal) {
16154 Result.getComplexFloatImag().subtract(RHS.getComplexFloatImag(),
16155 APFloat::rmNearestTiesToEven);
16158 Result.getComplexIntReal() -= RHS.getComplexIntReal();
16159 Result.getComplexIntImag() -= RHS.getComplexIntImag();
16163 if (Result.isComplexFloat()) {
16168 ComplexValue LHS = Result;
16169 APFloat &A = LHS.getComplexFloatReal();
16170 APFloat &B = LHS.getComplexFloatImag();
16171 APFloat &
C = RHS.getComplexFloatReal();
16172 APFloat &
D = RHS.getComplexFloatImag();
16173 APFloat &ResR = Result.getComplexFloatReal();
16174 APFloat &ResI = Result.getComplexFloatImag();
16176 assert(!RHSReal &&
"Cannot have two real operands for a complex op!");
16184 }
else if (RHSReal) {
16196 ComplexValue LHS = Result;
16197 Result.getComplexIntReal() =
16198 (LHS.getComplexIntReal() * RHS.getComplexIntReal() -
16199 LHS.getComplexIntImag() * RHS.getComplexIntImag());
16200 Result.getComplexIntImag() =
16201 (LHS.getComplexIntReal() * RHS.getComplexIntImag() +
16202 LHS.getComplexIntImag() * RHS.getComplexIntReal());
16206 if (Result.isComplexFloat()) {
16211 ComplexValue LHS = Result;
16212 APFloat &A = LHS.getComplexFloatReal();
16213 APFloat &B = LHS.getComplexFloatImag();
16214 APFloat &
C = RHS.getComplexFloatReal();
16215 APFloat &
D = RHS.getComplexFloatImag();
16216 APFloat &ResR = Result.getComplexFloatReal();
16217 APFloat &ResI = Result.getComplexFloatImag();
16229 B = APFloat::getZero(A.getSemantics());
16234 ComplexValue LHS = Result;
16235 APSInt Den = RHS.getComplexIntReal() * RHS.getComplexIntReal() +
16236 RHS.getComplexIntImag() * RHS.getComplexIntImag();
16238 return Error(
E, diag::note_expr_divide_by_zero);
16240 Result.getComplexIntReal() =
16241 (LHS.getComplexIntReal() * RHS.getComplexIntReal() +
16242 LHS.getComplexIntImag() * RHS.getComplexIntImag()) / Den;
16243 Result.getComplexIntImag() =
16244 (LHS.getComplexIntImag() * RHS.getComplexIntReal() -
16245 LHS.getComplexIntReal() * RHS.getComplexIntImag()) / Den;
16253bool ComplexExprEvaluator::VisitUnaryOperator(
const UnaryOperator *
E) {
16255 if (!Visit(
E->getSubExpr()))
16258 switch (
E->getOpcode()) {
16267 if (Result.isComplexFloat()) {
16268 Result.getComplexFloatReal().changeSign();
16269 Result.getComplexFloatImag().changeSign();
16272 Result.getComplexIntReal() = -Result.getComplexIntReal();
16273 Result.getComplexIntImag() = -Result.getComplexIntImag();
16277 if (Result.isComplexFloat())
16278 Result.getComplexFloatImag().changeSign();
16280 Result.getComplexIntImag() = -Result.getComplexIntImag();
16285bool ComplexExprEvaluator::VisitInitListExpr(
const InitListExpr *
E) {
16286 if (
E->getNumInits() == 2) {
16288 Result.makeComplexFloat();
16294 Result.makeComplexInt();
16302 return ExprEvaluatorBaseTy::VisitInitListExpr(
E);
16305bool ComplexExprEvaluator::VisitCallExpr(
const CallExpr *
E) {
16306 if (!IsConstantEvaluatedBuiltinCall(
E))
16307 return ExprEvaluatorBaseTy::VisitCallExpr(
E);
16309 switch (
E->getBuiltinCallee()) {
16310 case Builtin::BI__builtin_complex:
16311 Result.makeComplexFloat();
16329class AtomicExprEvaluator :
16330 public ExprEvaluatorBase<AtomicExprEvaluator> {
16331 const LValue *
This;
16334 AtomicExprEvaluator(EvalInfo &Info,
const LValue *This,
APValue &Result)
16335 : ExprEvaluatorBaseTy(Info),
This(
This), Result(Result) {}
16342 bool ZeroInitialization(
const Expr *
E) {
16351 bool VisitCastExpr(
const CastExpr *
E) {
16352 switch (
E->getCastKind()) {
16354 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
16355 case CK_NullToPointer:
16356 VisitIgnoredValue(
E->getSubExpr());
16357 return ZeroInitialization(
E);
16358 case CK_NonAtomicToAtomic:
16360 :
Evaluate(Result, Info,
E->getSubExpr());
16370 return AtomicExprEvaluator(Info, This, Result).Visit(
E);
16379class VoidExprEvaluator
16380 :
public ExprEvaluatorBase<VoidExprEvaluator> {
16382 VoidExprEvaluator(EvalInfo &Info) : ExprEvaluatorBaseTy(Info) {}
16386 bool ZeroInitialization(
const Expr *
E) {
return true; }
16388 bool VisitCastExpr(
const CastExpr *
E) {
16389 switch (
E->getCastKind()) {
16391 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
16393 VisitIgnoredValue(
E->getSubExpr());
16398 bool VisitCallExpr(
const CallExpr *
E) {
16399 if (!IsConstantEvaluatedBuiltinCall(
E))
16400 return ExprEvaluatorBaseTy::VisitCallExpr(
E);
16402 switch (
E->getBuiltinCallee()) {
16403 case Builtin::BI__assume:
16404 case Builtin::BI__builtin_assume:
16408 case Builtin::BI__builtin_operator_delete:
16420bool VoidExprEvaluator::VisitCXXDeleteExpr(
const CXXDeleteExpr *
E) {
16422 if (Info.SpeculativeEvaluationDepth)
16426 if (!OperatorDelete->isReplaceableGlobalAllocationFunction()) {
16427 Info.FFDiag(
E, diag::note_constexpr_new_non_replaceable)
16428 << isa<CXXMethodDecl>(OperatorDelete) << OperatorDelete;
16432 const Expr *Arg =
E->getArgument();
16437 if (
Pointer.Designator.Invalid)
16441 if (
Pointer.isNullPointer()) {
16445 if (!Info.getLangOpts().CPlusPlus20)
16446 Info.CCEDiag(
E, diag::note_constexpr_new);
16451 Info,
E,
Pointer,
E->isArrayForm() ? DynAlloc::ArrayNew : DynAlloc::New);
16458 if (!
E->isArrayForm() &&
Pointer.Designator.Entries.size() != 0 &&
16460 Info.FFDiag(
E, diag::note_constexpr_delete_base_nonvirt_dtor)
16467 if (!
E->isArrayForm() && !
E->isGlobalDelete()) {
16469 if (VirtualDelete &&
16471 Info.FFDiag(
E, diag::note_constexpr_new_non_replaceable)
16472 << isa<CXXMethodDecl>(VirtualDelete) << VirtualDelete;
16478 (*Alloc)->Value, AllocType))
16486 Info.FFDiag(
E, diag::note_constexpr_double_delete);
16496 return VoidExprEvaluator(Info).Visit(
E);
16512 LV.moveInto(Result);
16517 if (!IntExprEvaluator(Info, Result).Visit(
E))
16523 LV.moveInto(Result);
16525 llvm::APFloat F(0.0);
16533 C.moveInto(Result);
16535 if (!FixedPointExprEvaluator(Info, Result).Visit(
E))
return false;
16540 P.moveInto(Result);
16545 Info.CurrentCall->createTemporary(
E,
T, ScopeKind::FullExpression, LV);
16552 Info.CurrentCall->createTemporary(
E,
T, ScopeKind::FullExpression, LV);
16557 if (!Info.getLangOpts().CPlusPlus11)
16558 Info.CCEDiag(
E, diag::note_constexpr_nonliteral)
16563 QualType Unqual =
T.getAtomicUnqualifiedType();
16567 E, Unqual, ScopeKind::FullExpression, LV);
16575 }
else if (Info.getLangOpts().CPlusPlus11) {
16576 Info.FFDiag(
E, diag::note_constexpr_nonliteral) <<
E->
getType();
16579 Info.FFDiag(
E, diag::note_invalid_subexpr_in_const_expr);
16590 const Expr *
E,
bool AllowNonLiteralTypes) {
16605 QualType Unqual =
T.getAtomicUnqualifiedType();
16626 if (Info.EnableNewConstInterp) {
16627 if (!Info.Ctx.getInterpContext().evaluateAsRValue(Info,
E, Result))
16630 ConstantExprKind::Normal);
16639 LV.setFrom(Info.Ctx, Result);
16646 ConstantExprKind::Normal) &&
16654 if (
const auto *L = dyn_cast<IntegerLiteral>(Exp)) {
16656 L->getType()->isUnsignedIntegerType()));
16661 if (
const auto *L = dyn_cast<CXXBoolLiteralExpr>(Exp)) {
16667 if (
const auto *FL = dyn_cast<FloatingLiteral>(Exp)) {
16668 Result.Val =
APValue(FL->getValue());
16673 if (
const auto *L = dyn_cast<CharacterLiteral>(Exp)) {
16679 if (
const auto *CE = dyn_cast<ConstantExpr>(Exp)) {
16680 if (CE->hasAPValueResult()) {
16681 APValue APV = CE->getAPValueResult();
16683 Result.Val = std::move(APV);
16759 bool InConstantContext)
const {
16760 assert(!isValueDependent() &&
16761 "Expression evaluator can't be called on a dependent expression.");
16762 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsRValue");
16763 EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
16764 Info.InConstantContext = InConstantContext;
16765 return ::EvaluateAsRValue(
this, Result, Ctx, Info);
16769 bool InConstantContext)
const {
16770 assert(!isValueDependent() &&
16771 "Expression evaluator can't be called on a dependent expression.");
16772 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsBooleanCondition");
16780 bool InConstantContext)
const {
16781 assert(!isValueDependent() &&
16782 "Expression evaluator can't be called on a dependent expression.");
16783 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsInt");
16784 EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
16785 Info.InConstantContext = InConstantContext;
16786 return ::EvaluateAsInt(
this, Result, Ctx, AllowSideEffects, Info);
16791 bool InConstantContext)
const {
16792 assert(!isValueDependent() &&
16793 "Expression evaluator can't be called on a dependent expression.");
16794 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFixedPoint");
16795 EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
16796 Info.InConstantContext = InConstantContext;
16797 return ::EvaluateAsFixedPoint(
this, Result, Ctx, AllowSideEffects, Info);
16802 bool InConstantContext)
const {
16803 assert(!isValueDependent() &&
16804 "Expression evaluator can't be called on a dependent expression.");
16806 if (!getType()->isRealFloatingType())
16809 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFloat");
16821 bool InConstantContext)
const {
16822 assert(!isValueDependent() &&
16823 "Expression evaluator can't be called on a dependent expression.");
16825 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsLValue");
16826 EvalInfo Info(Ctx, Result, EvalInfo::EM_ConstantFold);
16827 Info.InConstantContext = InConstantContext;
16830 if (!
EvaluateLValue(
this, LV, Info) || !Info.discardCleanups() ||
16831 Result.HasSideEffects ||
16834 ConstantExprKind::Normal, CheckedTemps))
16837 LV.moveInto(Result.Val);
16844 bool IsConstantDestruction) {
16845 EvalInfo Info(Ctx, EStatus,
16846 IsConstantDestruction ? EvalInfo::EM_ConstantExpression
16847 : EvalInfo::EM_ConstantFold);
16848 Info.setEvaluatingDecl(
Base, DestroyedValue,
16849 EvalInfo::EvaluatingDeclKind::Dtor);
16850 Info.InConstantContext = IsConstantDestruction;
16859 if (!Info.discardCleanups())
16860 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
16867 assert(!isValueDependent() &&
16868 "Expression evaluator can't be called on a dependent expression.");
16873 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsConstantExpr");
16874 EvalInfo::EvaluationMode EM = EvalInfo::EM_ConstantExpression;
16875 EvalInfo Info(Ctx, Result, EM);
16876 Info.InConstantContext =
true;
16878 if (Info.EnableNewConstInterp) {
16879 if (!Info.Ctx.getInterpContext().evaluate(Info,
this, Result.Val, Kind))
16882 getStorageType(Ctx,
this), Result.Val, Kind);
16887 if (Kind == ConstantExprKind::ClassTemplateArgument)
16895 Info.setEvaluatingDecl(
Base, Result.Val);
16897 if (Info.EnableNewConstInterp) {
16898 if (!Info.Ctx.getInterpContext().evaluateAsRValue(Info,
this, Result.Val))
16907 FullExpressionRAII
Scope(Info);
16909 Result.HasSideEffects || !
Scope.destroy())
16912 if (!Info.discardCleanups())
16913 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
16924 if (Kind == ConstantExprKind::ClassTemplateArgument &&
16927 Result.HasSideEffects)) {
16939 bool IsConstantInitialization)
const {
16940 assert(!isValueDependent() &&
16941 "Expression evaluator can't be called on a dependent expression.");
16943 llvm::TimeTraceScope TimeScope(
"EvaluateAsInitializer", [&] {
16945 llvm::raw_string_ostream OS(Name);
16951 EStatus.
Diag = &Notes;
16953 EvalInfo Info(Ctx, EStatus,
16954 (IsConstantInitialization &&
16956 ? EvalInfo::EM_ConstantExpression
16957 : EvalInfo::EM_ConstantFold);
16958 Info.setEvaluatingDecl(VD,
Value);
16959 Info.InConstantContext = IsConstantInitialization;
16964 if (Info.EnableNewConstInterp) {
16965 auto &InterpCtx =
const_cast<ASTContext &
>(Ctx).getInterpContext();
16966 if (!InterpCtx.evaluateAsInitializer(Info, VD,
Value))
16970 ConstantExprKind::Normal);
16985 FullExpressionRAII
Scope(Info);
16988 EStatus.HasSideEffects)
16994 Info.performLifetimeExtension();
16996 if (!Info.discardCleanups())
16997 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
17001 ConstantExprKind::Normal) &&
17008 EStatus.
Diag = &Notes;
17012 bool IsConstantDestruction = hasConstantInitialization();
17018 if (getEvaluatedValue() && !getEvaluatedValue()->isAbsent())
17019 DestroyedValue = *getEvaluatedValue();
17024 getType(), getLocation(), EStatus,
17025 IsConstantDestruction) ||
17029 ensureEvaluatedStmt()->HasConstantDestruction =
true;
17036 assert(!isValueDependent() &&
17037 "Expression evaluator can't be called on a dependent expression.");
17046 assert(!isValueDependent() &&
17047 "Expression evaluator can't be called on a dependent expression.");
17049 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstInt");
17052 EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
17053 Info.InConstantContext =
true;
17057 assert(Result &&
"Could not evaluate expression");
17058 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
17060 return EVResult.Val.getInt();
17065 assert(!isValueDependent() &&
17066 "Expression evaluator can't be called on a dependent expression.");
17068 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstIntCheckOverflow");
17071 EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
17072 Info.InConstantContext =
true;
17073 Info.CheckingForUndefinedBehavior =
true;
17077 assert(Result &&
"Could not evaluate expression");
17078 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
17080 return EVResult.Val.getInt();
17084 assert(!isValueDependent() &&
17085 "Expression evaluator can't be called on a dependent expression.");
17087 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateForOverflow");
17091 EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
17092 Info.CheckingForUndefinedBehavior =
true;
17125 IK_ICEIfUnevaluated,
17141static ICEDiag
Worst(ICEDiag A, ICEDiag B) {
return A.Kind >= B.Kind ? A : B; }
17146 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
17148 Info.InConstantContext =
true;
17162#define ABSTRACT_STMT(Node)
17163#define STMT(Node, Base) case Expr::Node##Class:
17164#define EXPR(Node, Base)
17165#include "clang/AST/StmtNodes.inc"
17166 case Expr::PredefinedExprClass:
17167 case Expr::FloatingLiteralClass:
17168 case Expr::ImaginaryLiteralClass:
17169 case Expr::StringLiteralClass:
17170 case Expr::ArraySubscriptExprClass:
17171 case Expr::MatrixSubscriptExprClass:
17172 case Expr::ArraySectionExprClass:
17173 case Expr::OMPArrayShapingExprClass:
17174 case Expr::OMPIteratorExprClass:
17175 case Expr::MemberExprClass:
17176 case Expr::CompoundAssignOperatorClass:
17177 case Expr::CompoundLiteralExprClass:
17178 case Expr::ExtVectorElementExprClass:
17179 case Expr::DesignatedInitExprClass:
17180 case Expr::ArrayInitLoopExprClass:
17181 case Expr::ArrayInitIndexExprClass:
17182 case Expr::NoInitExprClass:
17183 case Expr::DesignatedInitUpdateExprClass:
17184 case Expr::ImplicitValueInitExprClass:
17185 case Expr::ParenListExprClass:
17186 case Expr::VAArgExprClass:
17187 case Expr::AddrLabelExprClass:
17188 case Expr::StmtExprClass:
17189 case Expr::CXXMemberCallExprClass:
17190 case Expr::CUDAKernelCallExprClass:
17191 case Expr::CXXAddrspaceCastExprClass:
17192 case Expr::CXXDynamicCastExprClass:
17193 case Expr::CXXTypeidExprClass:
17194 case Expr::CXXUuidofExprClass:
17195 case Expr::MSPropertyRefExprClass:
17196 case Expr::MSPropertySubscriptExprClass:
17197 case Expr::CXXNullPtrLiteralExprClass:
17198 case Expr::UserDefinedLiteralClass:
17199 case Expr::CXXThisExprClass:
17200 case Expr::CXXThrowExprClass:
17201 case Expr::CXXNewExprClass:
17202 case Expr::CXXDeleteExprClass:
17203 case Expr::CXXPseudoDestructorExprClass:
17204 case Expr::UnresolvedLookupExprClass:
17205 case Expr::TypoExprClass:
17206 case Expr::RecoveryExprClass:
17207 case Expr::DependentScopeDeclRefExprClass:
17208 case Expr::CXXConstructExprClass:
17209 case Expr::CXXInheritedCtorInitExprClass:
17210 case Expr::CXXStdInitializerListExprClass:
17211 case Expr::CXXBindTemporaryExprClass:
17212 case Expr::ExprWithCleanupsClass:
17213 case Expr::CXXTemporaryObjectExprClass:
17214 case Expr::CXXUnresolvedConstructExprClass:
17215 case Expr::CXXDependentScopeMemberExprClass:
17216 case Expr::UnresolvedMemberExprClass:
17217 case Expr::ObjCStringLiteralClass:
17218 case Expr::ObjCBoxedExprClass:
17219 case Expr::ObjCArrayLiteralClass:
17220 case Expr::ObjCDictionaryLiteralClass:
17221 case Expr::ObjCEncodeExprClass:
17222 case Expr::ObjCMessageExprClass:
17223 case Expr::ObjCSelectorExprClass:
17224 case Expr::ObjCProtocolExprClass:
17225 case Expr::ObjCIvarRefExprClass:
17226 case Expr::ObjCPropertyRefExprClass:
17227 case Expr::ObjCSubscriptRefExprClass:
17228 case Expr::ObjCIsaExprClass:
17229 case Expr::ObjCAvailabilityCheckExprClass:
17230 case Expr::ShuffleVectorExprClass:
17231 case Expr::ConvertVectorExprClass:
17232 case Expr::BlockExprClass:
17233 case Expr::NoStmtClass:
17234 case Expr::OpaqueValueExprClass:
17235 case Expr::PackExpansionExprClass:
17236 case Expr::SubstNonTypeTemplateParmPackExprClass:
17237 case Expr::FunctionParmPackExprClass:
17238 case Expr::AsTypeExprClass:
17239 case Expr::ObjCIndirectCopyRestoreExprClass:
17240 case Expr::MaterializeTemporaryExprClass:
17241 case Expr::PseudoObjectExprClass:
17242 case Expr::AtomicExprClass:
17243 case Expr::LambdaExprClass:
17244 case Expr::CXXFoldExprClass:
17245 case Expr::CoawaitExprClass:
17246 case Expr::DependentCoawaitExprClass:
17247 case Expr::CoyieldExprClass:
17248 case Expr::SYCLUniqueStableNameExprClass:
17249 case Expr::CXXParenListInitExprClass:
17250 case Expr::HLSLOutArgExprClass:
17253 case Expr::InitListExprClass: {
17259 if (cast<InitListExpr>(
E)->getNumInits() == 1)
17260 return CheckICE(cast<InitListExpr>(
E)->getInit(0), Ctx);
17264 case Expr::SizeOfPackExprClass:
17265 case Expr::GNUNullExprClass:
17266 case Expr::SourceLocExprClass:
17267 case Expr::EmbedExprClass:
17268 case Expr::OpenACCAsteriskSizeExprClass:
17271 case Expr::PackIndexingExprClass:
17272 return CheckICE(cast<PackIndexingExpr>(
E)->getSelectedExpr(), Ctx);
17274 case Expr::SubstNonTypeTemplateParmExprClass:
17276 CheckICE(cast<SubstNonTypeTemplateParmExpr>(
E)->getReplacement(), Ctx);
17278 case Expr::ConstantExprClass:
17279 return CheckICE(cast<ConstantExpr>(
E)->getSubExpr(), Ctx);
17281 case Expr::ParenExprClass:
17282 return CheckICE(cast<ParenExpr>(
E)->getSubExpr(), Ctx);
17283 case Expr::GenericSelectionExprClass:
17284 return CheckICE(cast<GenericSelectionExpr>(
E)->getResultExpr(), Ctx);
17285 case Expr::IntegerLiteralClass:
17286 case Expr::FixedPointLiteralClass:
17287 case Expr::CharacterLiteralClass:
17288 case Expr::ObjCBoolLiteralExprClass:
17289 case Expr::CXXBoolLiteralExprClass:
17290 case Expr::CXXScalarValueInitExprClass:
17291 case Expr::TypeTraitExprClass:
17292 case Expr::ConceptSpecializationExprClass:
17293 case Expr::RequiresExprClass:
17294 case Expr::ArrayTypeTraitExprClass:
17295 case Expr::ExpressionTraitExprClass:
17296 case Expr::CXXNoexceptExprClass:
17298 case Expr::CallExprClass:
17299 case Expr::CXXOperatorCallExprClass: {
17303 const CallExpr *CE = cast<CallExpr>(
E);
17308 case Expr::CXXRewrittenBinaryOperatorClass:
17309 return CheckICE(cast<CXXRewrittenBinaryOperator>(
E)->getSemanticForm(),
17311 case Expr::DeclRefExprClass: {
17312 const NamedDecl *
D = cast<DeclRefExpr>(
E)->getDecl();
17313 if (isa<EnumConstantDecl>(
D))
17325 const VarDecl *VD = dyn_cast<VarDecl>(
D);
17332 case Expr::UnaryOperatorClass: {
17355 llvm_unreachable(
"invalid unary operator class");
17357 case Expr::OffsetOfExprClass: {
17366 case Expr::UnaryExprOrTypeTraitExprClass: {
17368 if ((Exp->
getKind() == UETT_SizeOf) &&
17373 case Expr::BinaryOperatorClass: {
17418 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE) {
17421 return ICEDiag(IK_ICEIfUnevaluated,
E->
getBeginLoc());
17422 if (REval.isSigned() && REval.isAllOnes()) {
17424 if (LEval.isMinSignedValue())
17425 return ICEDiag(IK_ICEIfUnevaluated,
E->
getBeginLoc());
17433 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE)
17434 return ICEDiag(IK_ICEIfUnevaluated,
E->
getBeginLoc());
17440 return Worst(LHSResult, RHSResult);
17446 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICEIfUnevaluated) {
17456 return Worst(LHSResult, RHSResult);
17459 llvm_unreachable(
"invalid binary operator kind");
17461 case Expr::ImplicitCastExprClass:
17462 case Expr::CStyleCastExprClass:
17463 case Expr::CXXFunctionalCastExprClass:
17464 case Expr::CXXStaticCastExprClass:
17465 case Expr::CXXReinterpretCastExprClass:
17466 case Expr::CXXConstCastExprClass:
17467 case Expr::ObjCBridgedCastExprClass: {
17468 const Expr *SubExpr = cast<CastExpr>(
E)->getSubExpr();
17469 if (isa<ExplicitCastExpr>(
E)) {
17474 APSInt IgnoredVal(DestWidth, !DestSigned);
17479 if (FL->getValue().convertToInteger(IgnoredVal,
17480 llvm::APFloat::rmTowardZero,
17481 &Ignored) & APFloat::opInvalidOp)
17486 switch (cast<CastExpr>(
E)->getCastKind()) {
17487 case CK_LValueToRValue:
17488 case CK_AtomicToNonAtomic:
17489 case CK_NonAtomicToAtomic:
17491 case CK_IntegralToBoolean:
17492 case CK_IntegralCast:
17498 case Expr::BinaryConditionalOperatorClass: {
17501 if (CommonResult.Kind == IK_NotICE)
return CommonResult;
17503 if (FalseResult.Kind == IK_NotICE)
return FalseResult;
17504 if (CommonResult.Kind == IK_ICEIfUnevaluated)
return CommonResult;
17505 if (FalseResult.Kind == IK_ICEIfUnevaluated &&
17507 return FalseResult;
17509 case Expr::ConditionalOperatorClass: {
17517 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
17520 if (CondResult.Kind == IK_NotICE)
17526 if (TrueResult.Kind == IK_NotICE)
17528 if (FalseResult.Kind == IK_NotICE)
17529 return FalseResult;
17530 if (CondResult.Kind == IK_ICEIfUnevaluated)
17532 if (TrueResult.Kind == IK_ICE && FalseResult.Kind == IK_ICE)
17538 return FalseResult;
17541 case Expr::CXXDefaultArgExprClass:
17542 return CheckICE(cast<CXXDefaultArgExpr>(
E)->getExpr(), Ctx);
17543 case Expr::CXXDefaultInitExprClass:
17544 return CheckICE(cast<CXXDefaultInitExpr>(
E)->getExpr(), Ctx);
17545 case Expr::ChooseExprClass: {
17546 return CheckICE(cast<ChooseExpr>(
E)->getChosenSubExpr(), Ctx);
17548 case Expr::BuiltinBitCastExprClass: {
17549 if (!checkBitCastConstexprEligibility(
nullptr, Ctx, cast<CastExpr>(
E)))
17551 return CheckICE(cast<CastExpr>(
E)->getSubExpr(), Ctx);
17555 llvm_unreachable(
"Invalid StmtClass!");
17561 llvm::APSInt *
Value,
17572 if (!Result.isInt()) {
17583 assert(!isValueDependent() &&
17584 "Expression evaluator can't be called on a dependent expression.");
17586 ExprTimeTraceScope TimeScope(
this, Ctx,
"isIntegerConstantExpr");
17592 if (
D.
Kind != IK_ICE) {
17599std::optional<llvm::APSInt>
17601 if (isValueDependent()) {
17603 return std::nullopt;
17611 return std::nullopt;
17614 if (!isIntegerConstantExpr(Ctx,
Loc))
17615 return std::nullopt;
17623 EvalInfo Info(Ctx, Status, EvalInfo::EM_IgnoreSideEffects);
17624 Info.InConstantContext =
true;
17627 llvm_unreachable(
"ICE cannot be evaluated!");
17633 assert(!isValueDependent() &&
17634 "Expression evaluator can't be called on a dependent expression.");
17636 return CheckICE(
this, Ctx).Kind == IK_ICE;
17641 assert(!isValueDependent() &&
17642 "Expression evaluator can't be called on a dependent expression.");
17651 Status.Diag = &Diags;
17652 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
17659 Info.discardCleanups() && !Status.HasSideEffects;
17661 if (!Diags.empty()) {
17662 IsConstExpr =
false;
17663 if (
Loc) *
Loc = Diags[0].first;
17664 }
else if (!IsConstExpr) {
17666 if (
Loc) *
Loc = getExprLoc();
17669 return IsConstExpr;
17675 const Expr *This)
const {
17676 assert(!isValueDependent() &&
17677 "Expression evaluator can't be called on a dependent expression.");
17679 llvm::TimeTraceScope TimeScope(
"EvaluateWithSubstitution", [&] {
17681 llvm::raw_string_ostream OS(Name);
17688 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpressionUnevaluated);
17689 Info.InConstantContext =
true;
17692 const LValue *ThisPtr =
nullptr;
17695 auto *MD = dyn_cast<CXXMethodDecl>(Callee);
17696 assert(MD &&
"Don't provide `this` for non-methods.");
17697 assert(MD->isImplicitObjectMemberFunction() &&
17698 "Don't provide `this` for methods without an implicit object.");
17700 if (!This->isValueDependent() &&
17702 !Info.EvalStatus.HasSideEffects)
17703 ThisPtr = &ThisVal;
17707 Info.EvalStatus.HasSideEffects =
false;
17710 CallRef
Call = Info.CurrentCall->createCall(Callee);
17713 unsigned Idx = I - Args.begin();
17714 if (Idx >= Callee->getNumParams())
17716 const ParmVarDecl *PVD = Callee->getParamDecl(Idx);
17717 if ((*I)->isValueDependent() ||
17719 Info.EvalStatus.HasSideEffects) {
17721 if (
APValue *Slot = Info.getParamSlot(
Call, PVD))
17727 Info.EvalStatus.HasSideEffects =
false;
17732 Info.discardCleanups();
17733 Info.EvalStatus.HasSideEffects =
false;
17736 CallStackFrame Frame(Info, Callee->getLocation(), Callee, ThisPtr, This,
17739 FullExpressionRAII
Scope(Info);
17741 !Info.EvalStatus.HasSideEffects;
17753 llvm::TimeTraceScope TimeScope(
"isPotentialConstantExpr", [&] {
17755 llvm::raw_string_ostream OS(Name);
17762 Status.Diag = &Diags;
17764 EvalInfo Info(FD->
getASTContext(), Status, EvalInfo::EM_ConstantExpression);
17765 Info.InConstantContext =
true;
17766 Info.CheckingPotentialConstantExpression =
true;
17769 if (Info.EnableNewConstInterp) {
17770 Info.Ctx.getInterpContext().isPotentialConstantExpr(Info, FD);
17771 return Diags.empty();
17781 This.set({&VIE, Info.CurrentCall->Index});
17789 Info.setEvaluatingDecl(This.getLValueBase(), Scratch);
17795 &VIE, Args, CallRef(), FD->
getBody(), Info, Scratch,
17799 return Diags.empty();
17807 "Expression evaluator can't be called on a dependent expression.");
17810 Status.Diag = &Diags;
17813 EvalInfo::EM_ConstantExpressionUnevaluated);
17814 Info.InConstantContext =
true;
17815 Info.CheckingPotentialConstantExpression =
true;
17819 nullptr, CallRef());
17823 return Diags.empty();
17827 unsigned Type)
const {
17828 if (!getType()->isPointerType())
17832 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantFold);
17837 EvalInfo &Info, std::string *StringResult) {
17849 if (
const StringLiteral *S = dyn_cast_or_null<StringLiteral>(
17850 String.getLValueBase().dyn_cast<
const Expr *>())) {
17851 StringRef Str = S->getBytes();
17852 int64_t Off = String.Offset.getQuantity();
17853 if (Off >= 0 && (uint64_t)Off <= (uint64_t)Str.size() &&
17854 S->getCharByteWidth() == 1 &&
17856 Info.Ctx.hasSameUnqualifiedType(CharTy, Info.Ctx.CharTy)) {
17857 Str = Str.substr(Off);
17859 StringRef::size_type Pos = Str.find(0);
17860 if (Pos != StringRef::npos)
17861 Str = Str.substr(0, Pos);
17863 Result = Str.size();
17865 *StringResult = Str;
17873 for (uint64_t Strlen = 0; ; ++Strlen) {
17881 }
else if (StringResult)
17882 StringResult->push_back(Char.
getInt().getExtValue());
17890 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantFold);
17892 std::string StringResult;
17895 return StringResult;
17900 const Expr *SizeExpression,
17904 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
17905 Info.InConstantContext =
true;
17907 FullExpressionRAII
Scope(Info);
17912 uint64_t Size = SizeValue.getZExtValue();
17918 for (uint64_t I = 0; I < Size; ++I) {
17925 Result.push_back(
static_cast<char>(
C.getExtValue()));
17929 if (!
Scope.destroy())
17940 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantFold);
17945struct IsWithinLifetimeHandler {
17947 static constexpr AccessKinds AccessKind = AccessKinds::AK_IsWithinLifetime;
17948 using result_type = std::optional<bool>;
17949 std::optional<bool> failed() {
return std::nullopt; }
17950 template <
typename T>
17951 std::optional<bool> found(
T &Subobj,
QualType SubobjType) {
17956std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &IEE,
17958 EvalInfo &Info = IEE.Info;
17963 if (!Info.InConstantContext)
17964 return std::nullopt;
17965 assert(
E->getBuiltinCallee() == Builtin::BI__builtin_is_within_lifetime);
17966 const Expr *Arg =
E->getArg(0);
17968 return std::nullopt;
17971 return std::nullopt;
17973 if (Val.allowConstexprUnknown())
17977 bool CalledFromStd =
false;
17978 const auto *
Callee = Info.CurrentCall->getCallee();
17979 if (Callee &&
Callee->isInStdNamespace()) {
17983 Info.CCEDiag(CalledFromStd ? Info.CurrentCall->getCallRange().getBegin()
17985 diag::err_invalid_is_within_lifetime)
17986 << (CalledFromStd ?
"std::is_within_lifetime"
17987 :
"__builtin_is_within_lifetime")
17989 return std::nullopt;
17999 if (Val.isNullPointer() || Val.getLValueBase().isNull())
18001 QualType T = Val.getLValueBase().getType();
18003 "Pointers to functions should have been typed as function pointers "
18004 "which would have been rejected earlier");
18007 if (Val.getLValueDesignator().isOnePastTheEnd())
18009 assert(Val.getLValueDesignator().isValidSubobject() &&
18010 "Unchecked case for valid subobject");
18014 CompleteObject CO =
18018 if (Info.EvaluatingDeclValue && CO.Value == Info.EvaluatingDeclValue)
18023 IsWithinLifetimeHandler handler{Info};
18024 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 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)