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;
584 unsigned CurTempVersion = TempVersionStack.back();
586 unsigned getTempVersion()
const {
return TempVersionStack.back(); }
588 void pushTempVersion() {
589 TempVersionStack.push_back(++CurTempVersion);
592 void popTempVersion() {
593 TempVersionStack.pop_back();
597 return {Callee, Index, ++CurTempVersion};
608 llvm::DenseMap<const ValueDecl *, FieldDecl *> LambdaCaptureFields;
609 FieldDecl *LambdaThisCaptureField =
nullptr;
611 CallStackFrame(EvalInfo &Info,
SourceRange CallRange,
617 APValue *getTemporary(
const void *Key,
unsigned Version) {
618 MapKeyTy KV(Key, Version);
619 auto LB = Temporaries.lower_bound(KV);
620 if (LB != Temporaries.end() && LB->first == KV)
626 APValue *getCurrentTemporary(
const void *Key) {
627 auto UB = Temporaries.upper_bound(MapKeyTy(Key,
UINT_MAX));
628 if (UB != Temporaries.begin() && std::prev(UB)->first.first == Key)
629 return &std::prev(UB)->second;
634 unsigned getCurrentTemporaryVersion(
const void *Key)
const {
635 auto UB = Temporaries.upper_bound(MapKeyTy(Key,
UINT_MAX));
636 if (UB != Temporaries.begin() && std::prev(UB)->first.first == Key)
637 return std::prev(UB)->first.second;
645 template<
typename KeyT>
647 ScopeKind
Scope, LValue &LV);
652 void describe(llvm::raw_ostream &OS)
const override;
654 Frame *getCaller()
const override {
return Caller; }
655 SourceRange getCallRange()
const override {
return CallRange; }
656 const FunctionDecl *getCallee()
const override {
return Callee; }
658 bool isStdFunction()
const {
659 for (
const DeclContext *DC = Callee; DC; DC = DC->getParent())
660 if (DC->isStdNamespace())
667 bool CanEvalMSConstexpr =
false;
675 class ThisOverrideRAII {
677 ThisOverrideRAII(CallStackFrame &Frame,
const LValue *NewThis,
bool Enable)
678 : Frame(Frame), OldThis(Frame.This) {
680 Frame.This = NewThis;
682 ~ThisOverrideRAII() {
683 Frame.This = OldThis;
686 CallStackFrame &Frame;
687 const LValue *OldThis;
692 class ExprTimeTraceScope {
694 ExprTimeTraceScope(
const Expr *
E,
const ASTContext &Ctx, StringRef Name)
695 : TimeScope(Name, [
E, &Ctx] {
700 llvm::TimeTraceScope TimeScope;
705 struct MSConstexprContextRAII {
706 CallStackFrame &Frame;
708 explicit MSConstexprContextRAII(CallStackFrame &Frame,
bool Value)
709 : Frame(Frame), OldValue(Frame.CanEvalMSConstexpr) {
710 Frame.CanEvalMSConstexpr =
Value;
713 ~MSConstexprContextRAII() { Frame.CanEvalMSConstexpr = OldValue; }
718 const LValue &This,
QualType ThisType);
726 llvm::PointerIntPair<APValue*, 2, ScopeKind>
Value;
737 bool isDestroyedAtEndOf(ScopeKind K)
const {
738 return (
int)
Value.getInt() >= (
int)K;
740 bool endLifetime(EvalInfo &Info,
bool RunDestructors) {
741 if (RunDestructors) {
744 Loc = VD->getLocation();
753 bool hasSideEffect() {
754 return T.isDestructedType();
759 struct ObjectUnderConstruction {
762 friend bool operator==(
const ObjectUnderConstruction &LHS,
763 const ObjectUnderConstruction &RHS) {
764 return LHS.Base == RHS.Base && LHS.Path == RHS.Path;
766 friend llvm::hash_code
hash_value(
const ObjectUnderConstruction &Obj) {
767 return llvm::hash_combine(Obj.Base, Obj.Path);
770 enum class ConstructionPhase {
781template<>
struct DenseMapInfo<ObjectUnderConstruction> {
782 using Base = DenseMapInfo<APValue::LValueBase>;
784 return {Base::getEmptyKey(), {}}; }
786 return {Base::getTombstoneKey(), {}};
791 static bool isEqual(
const ObjectUnderConstruction &LHS,
792 const ObjectUnderConstruction &RHS) {
806 const Expr *AllocExpr =
nullptr;
817 if (
auto *NE = dyn_cast<CXXNewExpr>(AllocExpr))
818 return NE->isArray() ? ArrayNew : New;
819 assert(isa<CallExpr>(AllocExpr));
824 struct DynAllocOrder {
852 CallStackFrame *CurrentCall;
855 unsigned CallStackDepth;
858 unsigned NextCallIndex;
867 bool EnableNewConstInterp;
871 CallStackFrame BottomFrame;
881 enum class EvaluatingDeclKind {
888 EvaluatingDeclKind IsEvaluatingDecl = EvaluatingDeclKind::None;
895 llvm::DenseMap<ObjectUnderConstruction, ConstructionPhase>
896 ObjectsUnderConstruction;
901 std::map<DynamicAllocLValue, DynAlloc, DynAllocOrder> HeapAllocs;
904 unsigned NumHeapAllocs = 0;
906 struct EvaluatingConstructorRAII {
908 ObjectUnderConstruction
Object;
910 EvaluatingConstructorRAII(EvalInfo &EI, ObjectUnderConstruction Object,
914 EI.ObjectsUnderConstruction
915 .insert({
Object, HasBases ? ConstructionPhase::Bases
916 : ConstructionPhase::AfterBases})
919 void finishedConstructingBases() {
920 EI.ObjectsUnderConstruction[
Object] = ConstructionPhase::AfterBases;
922 void finishedConstructingFields() {
923 EI.ObjectsUnderConstruction[
Object] = ConstructionPhase::AfterFields;
925 ~EvaluatingConstructorRAII() {
926 if (DidInsert) EI.ObjectsUnderConstruction.erase(Object);
930 struct EvaluatingDestructorRAII {
932 ObjectUnderConstruction
Object;
934 EvaluatingDestructorRAII(EvalInfo &EI, ObjectUnderConstruction Object)
936 DidInsert = EI.ObjectsUnderConstruction
937 .insert({
Object, ConstructionPhase::Destroying})
940 void startedDestroyingBases() {
941 EI.ObjectsUnderConstruction[
Object] =
942 ConstructionPhase::DestroyingBases;
944 ~EvaluatingDestructorRAII() {
946 EI.ObjectsUnderConstruction.erase(Object);
953 return ObjectsUnderConstruction.lookup({
Base,
Path});
958 unsigned SpeculativeEvaluationDepth = 0;
966 bool HasActiveDiagnostic;
970 bool HasFoldFailureDiagnostic;
975 bool CheckingPotentialConstantExpression =
false;
983 bool CheckingForUndefinedBehavior =
false;
985 enum EvaluationMode {
988 EM_ConstantExpression,
995 EM_ConstantExpressionUnevaluated,
1003 EM_IgnoreSideEffects,
1008 bool checkingPotentialConstantExpression()
const override {
1009 return CheckingPotentialConstantExpression;
1015 bool checkingForUndefinedBehavior()
const override {
1016 return CheckingForUndefinedBehavior;
1020 : Ctx(const_cast<
ASTContext &>(
C)), EvalStatus(S), CurrentCall(nullptr),
1021 CallStackDepth(0), NextCallIndex(1),
1022 StepsLeft(
C.getLangOpts().ConstexprStepLimit),
1023 EnableNewConstInterp(
C.getLangOpts().EnableNewConstInterp),
1026 nullptr, CallRef()),
1027 EvaluatingDecl((const
ValueDecl *)nullptr),
1028 EvaluatingDeclValue(nullptr), HasActiveDiagnostic(
false),
1029 HasFoldFailureDiagnostic(
false), EvalMode(Mode) {}
1035 ASTContext &getASTContext()
const override {
return Ctx; }
1038 EvaluatingDeclKind EDK = EvaluatingDeclKind::Ctor) {
1039 EvaluatingDecl =
Base;
1040 IsEvaluatingDecl = EDK;
1041 EvaluatingDeclValue = &
Value;
1047 if (checkingPotentialConstantExpression() && CallStackDepth > 1)
1049 if (NextCallIndex == 0) {
1051 FFDiag(
Loc, diag::note_constexpr_call_limit_exceeded);
1054 if (CallStackDepth <= getLangOpts().ConstexprCallDepth)
1056 FFDiag(
Loc, diag::note_constexpr_depth_limit_exceeded)
1057 << getLangOpts().ConstexprCallDepth;
1062 uint64_t ElemCount,
bool Diag) {
1068 ElemCount >
uint64_t(std::numeric_limits<unsigned>::max())) {
1070 FFDiag(
Loc, diag::note_constexpr_new_too_large) << ElemCount;
1080 if (ElemCount > Limit) {
1082 FFDiag(
Loc, diag::note_constexpr_new_exceeds_limits)
1083 << ElemCount << Limit;
1089 std::pair<CallStackFrame *, unsigned>
1090 getCallFrameAndDepth(
unsigned CallIndex) {
1091 assert(CallIndex &&
"no call index in getCallFrameAndDepth");
1094 unsigned Depth = CallStackDepth;
1095 CallStackFrame *Frame = CurrentCall;
1096 while (Frame->Index > CallIndex) {
1097 Frame = Frame->Caller;
1100 if (Frame->Index == CallIndex)
1101 return {Frame, Depth};
1102 return {
nullptr, 0};
1105 bool nextStep(
const Stmt *S) {
1107 FFDiag(S->getBeginLoc(), diag::note_constexpr_step_limit_exceeded);
1117 std::optional<DynAlloc *> Result;
1118 auto It = HeapAllocs.find(DA);
1119 if (It != HeapAllocs.end())
1120 Result = &It->second;
1126 CallStackFrame *Frame = getCallFrameAndDepth(
Call.CallIndex).first;
1127 return Frame ? Frame->getTemporary(
Call.getOrigParam(PVD),
Call.Version)
1132 struct StdAllocatorCaller {
1133 unsigned FrameIndex;
1135 explicit operator bool()
const {
return FrameIndex != 0; };
1138 StdAllocatorCaller getStdAllocatorCaller(StringRef FnName)
const {
1139 for (
const CallStackFrame *
Call = CurrentCall;
Call != &BottomFrame;
1141 const auto *MD = dyn_cast_or_null<CXXMethodDecl>(
Call->Callee);
1145 if (!FnII || !FnII->
isStr(FnName))
1149 dyn_cast<ClassTemplateSpecializationDecl>(MD->getParent());
1155 if (CTSD->isInStdNamespace() && ClassII &&
1156 ClassII->
isStr(
"allocator") && TAL.
size() >= 1 &&
1158 return {
Call->Index, TAL[0].getAsType()};
1164 void performLifetimeExtension() {
1166 llvm::erase_if(CleanupStack, [](Cleanup &
C) {
1167 return !
C.isDestroyedAtEndOf(ScopeKind::FullExpression);
1174 bool discardCleanups() {
1175 for (Cleanup &
C : CleanupStack) {
1176 if (
C.hasSideEffect() && !noteSideEffect()) {
1177 CleanupStack.clear();
1181 CleanupStack.clear();
1186 interp::Frame *getCurrentFrame()
override {
return CurrentCall; }
1187 const interp::Frame *getBottomFrame()
const override {
return &BottomFrame; }
1189 bool hasActiveDiagnostic()
override {
return HasActiveDiagnostic; }
1190 void setActiveDiagnostic(
bool Flag)
override { HasActiveDiagnostic = Flag; }
1192 void setFoldFailureDiagnostic(
bool Flag)
override {
1193 HasFoldFailureDiagnostic = Flag;
1204 bool hasPriorDiagnostic()
override {
1205 if (!EvalStatus.
Diag->empty()) {
1207 case EM_ConstantFold:
1208 case EM_IgnoreSideEffects:
1209 if (!HasFoldFailureDiagnostic)
1213 case EM_ConstantExpression:
1214 case EM_ConstantExpressionUnevaluated:
1215 setActiveDiagnostic(
false);
1222 unsigned getCallStackDepth()
override {
return CallStackDepth; }
1227 bool keepEvaluatingAfterSideEffect()
const override {
1229 case EM_IgnoreSideEffects:
1232 case EM_ConstantExpression:
1233 case EM_ConstantExpressionUnevaluated:
1234 case EM_ConstantFold:
1237 return checkingPotentialConstantExpression() ||
1238 checkingForUndefinedBehavior();
1240 llvm_unreachable(
"Missed EvalMode case");
1245 bool noteSideEffect()
override {
1247 return keepEvaluatingAfterSideEffect();
1251 bool keepEvaluatingAfterUndefinedBehavior() {
1253 case EM_IgnoreSideEffects:
1254 case EM_ConstantFold:
1257 case EM_ConstantExpression:
1258 case EM_ConstantExpressionUnevaluated:
1259 return checkingForUndefinedBehavior();
1261 llvm_unreachable(
"Missed EvalMode case");
1267 bool noteUndefinedBehavior()
override {
1269 return keepEvaluatingAfterUndefinedBehavior();
1274 bool keepEvaluatingAfterFailure()
const override {
1279 case EM_ConstantExpression:
1280 case EM_ConstantExpressionUnevaluated:
1281 case EM_ConstantFold:
1282 case EM_IgnoreSideEffects:
1283 return checkingPotentialConstantExpression() ||
1284 checkingForUndefinedBehavior();
1286 llvm_unreachable(
"Missed EvalMode case");
1299 [[nodiscard]]
bool noteFailure() {
1307 bool KeepGoing = keepEvaluatingAfterFailure();
1312 class ArrayInitLoopIndex {
1317 ArrayInitLoopIndex(EvalInfo &Info)
1318 : Info(Info), OuterIndex(Info.ArrayInitIndex) {
1319 Info.ArrayInitIndex = 0;
1321 ~ArrayInitLoopIndex() { Info.ArrayInitIndex = OuterIndex; }
1323 operator uint64_t&() {
return Info.ArrayInitIndex; }
1328 struct FoldConstant {
1331 bool HadNoPriorDiags;
1332 EvalInfo::EvaluationMode OldMode;
1334 explicit FoldConstant(EvalInfo &Info,
bool Enabled)
1337 HadNoPriorDiags(Info.EvalStatus.
Diag &&
1338 Info.EvalStatus.
Diag->empty() &&
1339 !Info.EvalStatus.HasSideEffects),
1340 OldMode(Info.EvalMode) {
1342 Info.EvalMode = EvalInfo::EM_ConstantFold;
1344 void keepDiagnostics() { Enabled =
false; }
1346 if (Enabled && HadNoPriorDiags && !Info.EvalStatus.Diag->empty() &&
1347 !Info.EvalStatus.HasSideEffects)
1348 Info.EvalStatus.Diag->clear();
1349 Info.EvalMode = OldMode;
1355 struct IgnoreSideEffectsRAII {
1357 EvalInfo::EvaluationMode OldMode;
1358 explicit IgnoreSideEffectsRAII(EvalInfo &Info)
1359 : Info(Info), OldMode(Info.EvalMode) {
1360 Info.EvalMode = EvalInfo::EM_IgnoreSideEffects;
1363 ~IgnoreSideEffectsRAII() { Info.EvalMode = OldMode; }
1368 class SpeculativeEvaluationRAII {
1369 EvalInfo *Info =
nullptr;
1371 unsigned OldSpeculativeEvaluationDepth = 0;
1373 void moveFromAndCancel(SpeculativeEvaluationRAII &&
Other) {
1375 OldStatus =
Other.OldStatus;
1376 OldSpeculativeEvaluationDepth =
Other.OldSpeculativeEvaluationDepth;
1377 Other.Info =
nullptr;
1380 void maybeRestoreState() {
1384 Info->EvalStatus = OldStatus;
1385 Info->SpeculativeEvaluationDepth = OldSpeculativeEvaluationDepth;
1389 SpeculativeEvaluationRAII() =
default;
1391 SpeculativeEvaluationRAII(
1393 : Info(&Info), OldStatus(Info.EvalStatus),
1394 OldSpeculativeEvaluationDepth(Info.SpeculativeEvaluationDepth) {
1395 Info.EvalStatus.Diag = NewDiag;
1396 Info.SpeculativeEvaluationDepth = Info.CallStackDepth + 1;
1399 SpeculativeEvaluationRAII(
const SpeculativeEvaluationRAII &
Other) =
delete;
1400 SpeculativeEvaluationRAII(SpeculativeEvaluationRAII &&
Other) {
1401 moveFromAndCancel(std::move(
Other));
1404 SpeculativeEvaluationRAII &operator=(SpeculativeEvaluationRAII &&
Other) {
1405 maybeRestoreState();
1406 moveFromAndCancel(std::move(
Other));
1410 ~SpeculativeEvaluationRAII() { maybeRestoreState(); }
1415 template<ScopeKind Kind>
1418 unsigned OldStackSize;
1420 ScopeRAII(EvalInfo &Info)
1421 : Info(Info), OldStackSize(Info.CleanupStack.size()) {
1424 Info.CurrentCall->pushTempVersion();
1426 bool destroy(
bool RunDestructors =
true) {
1427 bool OK =
cleanup(Info, RunDestructors, OldStackSize);
1432 if (OldStackSize != -1U)
1436 Info.CurrentCall->popTempVersion();
1439 static bool cleanup(EvalInfo &Info,
bool RunDestructors,
1440 unsigned OldStackSize) {
1441 assert(OldStackSize <= Info.CleanupStack.size() &&
1442 "running cleanups out of order?");
1447 for (
unsigned I = Info.CleanupStack.size(); I > OldStackSize; --I) {
1448 if (Info.CleanupStack[I - 1].isDestroyedAtEndOf(Kind)) {
1449 if (!Info.CleanupStack[I - 1].endLifetime(Info, RunDestructors)) {
1457 auto NewEnd = Info.CleanupStack.begin() + OldStackSize;
1458 if (Kind != ScopeKind::Block)
1460 std::remove_if(NewEnd, Info.CleanupStack.end(), [](Cleanup &
C) {
1461 return C.isDestroyedAtEndOf(Kind);
1463 Info.CleanupStack.erase(NewEnd, Info.CleanupStack.end());
1467 typedef ScopeRAII<ScopeKind::Block> BlockScopeRAII;
1468 typedef ScopeRAII<ScopeKind::FullExpression> FullExpressionRAII;
1469 typedef ScopeRAII<ScopeKind::Call> CallScopeRAII;
1472bool SubobjectDesignator::checkSubobject(EvalInfo &Info,
const Expr *
E,
1476 if (isOnePastTheEnd()) {
1477 Info.CCEDiag(
E, diag::note_constexpr_past_end_subobject)
1488void SubobjectDesignator::diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info,
1490 Info.CCEDiag(
E, diag::note_constexpr_unsized_array_indexed);
1495void SubobjectDesignator::diagnosePointerArithmetic(EvalInfo &Info,
1500 if (MostDerivedPathLength == Entries.size() && MostDerivedIsArrayElement)
1501 Info.CCEDiag(
E, diag::note_constexpr_array_index)
1503 <<
static_cast<unsigned>(getMostDerivedArraySize());
1505 Info.CCEDiag(
E, diag::note_constexpr_array_index)
1510CallStackFrame::CallStackFrame(EvalInfo &Info,
SourceRange CallRange,
1515 Index(Info.NextCallIndex++) {
1516 Info.CurrentCall =
this;
1517 ++Info.CallStackDepth;
1520CallStackFrame::~CallStackFrame() {
1521 assert(Info.CurrentCall ==
this &&
"calls retired out of order");
1522 --Info.CallStackDepth;
1523 Info.CurrentCall = Caller;
1547 llvm_unreachable(
"unknown access kind");
1583 llvm_unreachable(
"unknown access kind");
1587 struct ComplexValue {
1595 ComplexValue() : FloatReal(
APFloat::Bogus()), FloatImag(
APFloat::Bogus()) {}
1597 void makeComplexFloat() { IsInt =
false; }
1598 bool isComplexFloat()
const {
return !IsInt; }
1599 APFloat &getComplexFloatReal() {
return FloatReal; }
1600 APFloat &getComplexFloatImag() {
return FloatImag; }
1602 void makeComplexInt() { IsInt =
true; }
1603 bool isComplexInt()
const {
return IsInt; }
1604 APSInt &getComplexIntReal() {
return IntReal; }
1605 APSInt &getComplexIntImag() {
return IntImag; }
1608 if (isComplexFloat())
1614 assert(
v.isComplexFloat() ||
v.isComplexInt());
1615 if (
v.isComplexFloat()) {
1617 FloatReal =
v.getComplexFloatReal();
1618 FloatImag =
v.getComplexFloatImag();
1621 IntReal =
v.getComplexIntReal();
1622 IntImag =
v.getComplexIntImag();
1632 bool InvalidBase : 1;
1635 CharUnits &getLValueOffset() {
return Offset; }
1636 const CharUnits &getLValueOffset()
const {
return Offset; }
1637 SubobjectDesignator &getLValueDesignator() {
return Designator; }
1638 const SubobjectDesignator &getLValueDesignator()
const {
return Designator;}
1639 bool isNullPointer()
const {
return IsNullPtr;}
1641 unsigned getLValueCallIndex()
const {
return Base.getCallIndex(); }
1642 unsigned getLValueVersion()
const {
return Base.getVersion(); }
1648 assert(!InvalidBase &&
"APValues can't handle invalid LValue bases");
1654 assert(
V.isLValue() &&
"Setting LValue from a non-LValue?");
1655 Base =
V.getLValueBase();
1656 Offset =
V.getLValueOffset();
1657 InvalidBase =
false;
1659 IsNullPtr =
V.isNullPointer();
1666 const auto *
E = B.
get<
const Expr *>();
1667 assert((isa<MemberExpr>(
E) || tryUnwrapAllocSizeCall(
E)) &&
1668 "Unexpected type of invalid base");
1674 InvalidBase = BInvalid;
1675 Designator = SubobjectDesignator(getType(B));
1683 InvalidBase =
false;
1694 moveInto(Printable);
1701 template <
typename GenDiagType>
1702 bool checkNullPointerDiagnosingWith(
const GenDiagType &GenDiag) {
1714 bool checkNullPointer(EvalInfo &Info,
const Expr *
E,
1716 return checkNullPointerDiagnosingWith([&Info,
E, CSK] {
1717 Info.CCEDiag(
E, diag::note_constexpr_null_subobject) << CSK;
1721 bool checkNullPointerForFoldAccess(EvalInfo &Info,
const Expr *
E,
1723 return checkNullPointerDiagnosingWith([&Info,
E, AK] {
1724 Info.FFDiag(
E, diag::note_constexpr_access_null) << AK;
1735 void addDecl(EvalInfo &Info,
const Expr *
E,
1740 void addUnsizedArray(EvalInfo &Info,
const Expr *
E,
QualType ElemTy) {
1742 Info.CCEDiag(
E, diag::note_constexpr_unsupported_unsized_array);
1747 assert(getType(
Base)->isPointerType() || getType(
Base)->isArrayType());
1748 Designator.FirstEntryIsAnUnsizedArray =
true;
1756 void addComplex(EvalInfo &Info,
const Expr *
E,
QualType EltTy,
bool Imag) {
1760 void addVectorElement(EvalInfo &Info,
const Expr *
E,
QualType EltTy,
1761 uint64_t Size, uint64_t Idx) {
1763 Designator.addVectorElementUnchecked(EltTy, Size, Idx);
1765 void clearIsNullPointer() {
1768 void adjustOffsetAndIndex(EvalInfo &Info,
const Expr *
E,
1778 uint64_t Offset64 = Offset.getQuantity();
1780 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
1785 clearIsNullPointer();
1790 clearIsNullPointer();
1797 : DeclAndIsDerivedMember(
Decl,
false) {}
1802 return DeclAndIsDerivedMember.getPointer();
1805 bool isDerivedMember()
const {
1806 return DeclAndIsDerivedMember.getInt();
1810 return cast<CXXRecordDecl>(
1811 DeclAndIsDerivedMember.getPointer()->getDeclContext());
1818 assert(
V.isMemberPointer());
1819 DeclAndIsDerivedMember.setPointer(
V.getMemberPointerDecl());
1820 DeclAndIsDerivedMember.setInt(
V.isMemberPointerToDerivedMember());
1829 llvm::PointerIntPair<const ValueDecl*, 1, bool> DeclAndIsDerivedMember;
1837 assert(!
Path.empty());
1839 if (
Path.size() >= 2)
1843 if (
Expected->getCanonicalDecl() !=
Class->getCanonicalDecl()) {
1859 if (!isDerivedMember()) {
1860 Path.push_back(Derived);
1863 if (!castBack(Derived))
1866 DeclAndIsDerivedMember.setInt(
false);
1874 DeclAndIsDerivedMember.setInt(
true);
1875 if (isDerivedMember()) {
1879 return castBack(
Base);
1884 static bool operator==(
const MemberPtr &LHS,
const MemberPtr &RHS) {
1885 if (!LHS.getDecl() || !RHS.getDecl())
1886 return !LHS.getDecl() && !RHS.getDecl();
1887 if (LHS.getDecl()->getCanonicalDecl() != RHS.getDecl()->getCanonicalDecl())
1889 return LHS.Path == RHS.Path;
1895 const LValue &This,
const Expr *
E,
1896 bool AllowNonLiteralTypes =
false);
1898 bool InvalidBaseOK =
false);
1900 bool InvalidBaseOK =
false);
1914 std::string *StringResult =
nullptr);
1931 if (Int.isUnsigned() || Int.isMinSignedValue()) {
1932 Int = Int.extend(Int.getBitWidth() + 1);
1933 Int.setIsSigned(
true);
1938template<
typename KeyT>
1940 ScopeKind
Scope, LValue &LV) {
1941 unsigned Version = getTempVersion();
1950 assert(Args.CallIndex == Index &&
"creating parameter in wrong frame");
1956 return createLocal(
Base, PVD, PVD->
getType(), ScopeKind::Call);
1961 assert(
Base.getCallIndex() == Index &&
"lvalue for wrong frame");
1962 unsigned Version =
Base.getVersion();
1963 APValue &Result = Temporaries[MapKeyTy(Key, Version)];
1964 assert(Result.isAbsent() &&
"local created multiple times");
1970 if (Index <= Info.SpeculativeEvaluationDepth) {
1971 if (
T.isDestructedType())
1972 Info.noteSideEffect();
1974 Info.CleanupStack.push_back(Cleanup(&Result,
Base,
T,
Scope));
1981 FFDiag(
E, diag::note_constexpr_heap_alloc_limit_exceeded);
1987 auto Result = HeapAllocs.emplace(std::piecewise_construct,
1988 std::forward_as_tuple(DA), std::tuple<>());
1989 assert(Result.second &&
"reused a heap alloc index?");
1990 Result.first->second.AllocExpr =
E;
1991 return &Result.first->second.Value;
1995void CallStackFrame::describe(raw_ostream &Out)
const {
1996 unsigned ArgIndex = 0;
1998 isa<CXXMethodDecl>(Callee) && !isa<CXXConstructorDecl>(Callee) &&
1999 cast<CXXMethodDecl>(Callee)->isImplicitObjectMemberFunction();
2002 Callee->getNameForDiagnostic(Out, Info.Ctx.getPrintingPolicy(),
2005 if (This && IsMemberCall) {
2006 if (
const auto *MCE = dyn_cast_if_present<CXXMemberCallExpr>(
CallExpr)) {
2007 const Expr *
Object = MCE->getImplicitObjectArgument();
2008 Object->printPretty(Out,
nullptr, Info.Ctx.getPrintingPolicy(),
2010 if (
Object->getType()->isPointerType())
2014 }
else if (
const auto *OCE =
2015 dyn_cast_if_present<CXXOperatorCallExpr>(
CallExpr)) {
2016 OCE->getArg(0)->printPretty(Out,
nullptr,
2017 Info.Ctx.getPrintingPolicy(),
2022 This->moveInto(Val);
2025 Info.Ctx.getLValueReferenceType(
This->Designator.MostDerivedType));
2028 Callee->getNameForDiagnostic(Out, Info.Ctx.getPrintingPolicy(),
2030 IsMemberCall =
false;
2036 E =
Callee->param_end(); I !=
E; ++I, ++ArgIndex) {
2037 if (ArgIndex > (
unsigned)IsMemberCall)
2041 APValue *
V = Info.getParamSlot(Arguments, Param);
2043 V->printPretty(Out, Info.Ctx, Param->
getType());
2047 if (ArgIndex == 0 && IsMemberCall)
2048 Out <<
"->" << *
Callee <<
'(';
2062 return Info.noteSideEffect();
2068 unsigned Builtin =
E->getBuiltinCallee();
2069 return (Builtin == Builtin::BI__builtin___CFStringMakeConstantString ||
2070 Builtin == Builtin::BI__builtin___NSStringMakeConstantString ||
2071 Builtin == Builtin::BI__builtin_ptrauth_sign_constant ||
2072 Builtin == Builtin::BI__builtin_function_start);
2076 const auto *BaseExpr =
2077 llvm::dyn_cast_if_present<CallExpr>(LVal.Base.dyn_cast<
const Expr *>());
2092 if (
const VarDecl *VD = dyn_cast<VarDecl>(
D))
2093 return VD->hasGlobalStorage();
2094 if (isa<TemplateParamObjectDecl>(
D))
2099 return isa<FunctionDecl, MSGuidDecl, UnnamedGlobalConstantDecl>(
D);
2109 case Expr::CompoundLiteralExprClass: {
2113 case Expr::MaterializeTemporaryExprClass:
2116 return cast<MaterializeTemporaryExpr>(
E)->getStorageDuration() ==
SD_Static;
2118 case Expr::StringLiteralClass:
2119 case Expr::PredefinedExprClass:
2120 case Expr::ObjCStringLiteralClass:
2121 case Expr::ObjCEncodeExprClass:
2123 case Expr::ObjCBoxedExprClass:
2124 return cast<ObjCBoxedExpr>(
E)->isExpressibleAsConstantInitializer();
2125 case Expr::CallExprClass:
2128 case Expr::AddrLabelExprClass:
2132 case Expr::BlockExprClass:
2133 return !cast<BlockExpr>(
E)->getBlockDecl()->hasCaptures();
2136 case Expr::SourceLocExprClass:
2138 case Expr::ImplicitValueInitExprClass:
2150 return LVal.Base.dyn_cast<
const ValueDecl*>();
2163 const auto *BaseExpr = LVal.Base.dyn_cast<
const Expr *>();
2168 if (
const auto *EE = dyn_cast<ObjCEncodeExpr>(BaseExpr)) {
2169 Info.Ctx.getObjCEncodingForType(EE->getEncodedType(),
2177 const auto *Lit = dyn_cast<StringLiteral>(BaseExpr);
2178 if (
const auto *PE = dyn_cast<PredefinedExpr>(BaseExpr))
2179 Lit = PE->getFunctionName();
2184 AsString.
Bytes = Lit->getBytes();
2185 AsString.
CharWidth = Lit->getCharByteWidth();
2205 const LValue &RHS) {
2214 CharUnits Offset = RHS.Offset - LHS.Offset;
2215 if (Offset.isNegative())
2216 LHSString.
Bytes = LHSString.
Bytes.drop_front(-Offset.getQuantity());
2218 RHSString.
Bytes = RHSString.
Bytes.drop_front(Offset.getQuantity());
2220 bool LHSIsLonger = LHSString.
Bytes.size() > RHSString.
Bytes.size();
2221 StringRef Longer = LHSIsLonger ? LHSString.
Bytes : RHSString.
Bytes;
2222 StringRef Shorter = LHSIsLonger ? RHSString.
Bytes : LHSString.
Bytes;
2223 int ShorterCharWidth = (LHSIsLonger ? RHSString : LHSString).CharWidth;
2228 for (
int NullByte : llvm::seq(ShorterCharWidth)) {
2229 if (Shorter.size() + NullByte >= Longer.size())
2231 if (Longer[Shorter.size() + NullByte])
2237 return Shorter == Longer.take_front(Shorter.size());
2247 if (isa_and_nonnull<VarDecl>(
Decl)) {
2257 if (!A.getLValueBase())
2258 return !B.getLValueBase();
2259 if (!B.getLValueBase())
2262 if (A.getLValueBase().getOpaqueValue() !=
2263 B.getLValueBase().getOpaqueValue())
2266 return A.getLValueCallIndex() == B.getLValueCallIndex() &&
2267 A.getLValueVersion() == B.getLValueVersion();
2271 assert(
Base &&
"no location for a null lvalue");
2277 if (
auto *PVD = dyn_cast_or_null<ParmVarDecl>(VD)) {
2279 for (CallStackFrame *F = Info.CurrentCall; F; F = F->Caller) {
2280 if (F->Arguments.CallIndex ==
Base.getCallIndex() &&
2281 F->Arguments.Version ==
Base.getVersion() && F->Callee &&
2282 Idx < F->Callee->getNumParams()) {
2283 VD = F->Callee->getParamDecl(Idx);
2290 Info.Note(VD->
getLocation(), diag::note_declared_at);
2292 Info.Note(
E->
getExprLoc(), diag::note_constexpr_temporary_here);
2295 if (std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA))
2296 Info.Note((*Alloc)->AllocExpr->getExprLoc(),
2297 diag::note_constexpr_dynamic_alloc_here);
2330 const SubobjectDesignator &
Designator = LVal.getLValueDesignator();
2338 if (isTemplateArgument(Kind)) {
2339 int InvalidBaseKind = -1;
2342 InvalidBaseKind = 0;
2343 else if (isa_and_nonnull<StringLiteral>(BaseE))
2344 InvalidBaseKind = 1;
2345 else if (isa_and_nonnull<MaterializeTemporaryExpr>(BaseE) ||
2346 isa_and_nonnull<LifetimeExtendedTemporaryDecl>(BaseVD))
2347 InvalidBaseKind = 2;
2348 else if (
auto *PE = dyn_cast_or_null<PredefinedExpr>(BaseE)) {
2349 InvalidBaseKind = 3;
2350 Ident = PE->getIdentKindName();
2353 if (InvalidBaseKind != -1) {
2354 Info.FFDiag(
Loc, diag::note_constexpr_invalid_template_arg)
2355 << IsReferenceType << !
Designator.Entries.empty() << InvalidBaseKind
2361 if (
auto *FD = dyn_cast_or_null<FunctionDecl>(BaseVD);
2362 FD && FD->isImmediateFunction()) {
2363 Info.FFDiag(
Loc, diag::note_consteval_address_accessible)
2365 Info.Note(FD->getLocation(), diag::note_declared_at);
2373 if (Info.getLangOpts().CPlusPlus11) {
2374 Info.FFDiag(
Loc, diag::note_constexpr_non_global, 1)
2375 << IsReferenceType << !
Designator.Entries.empty() << !!BaseVD
2377 auto *VarD = dyn_cast_or_null<VarDecl>(BaseVD);
2378 if (VarD && VarD->isConstexpr()) {
2384 Info.Note(VarD->getLocation(), diag::note_constexpr_not_static)
2396 assert((Info.checkingPotentialConstantExpression() ||
2397 LVal.getLValueCallIndex() == 0) &&
2398 "have call index for global lvalue");
2401 Info.FFDiag(
Loc, diag::note_constexpr_dynamic_alloc)
2402 << IsReferenceType << !
Designator.Entries.empty();
2408 if (
const VarDecl *Var = dyn_cast<const VarDecl>(BaseVD)) {
2410 if (Var->getTLSKind())
2416 if (!isForManglingOnly(Kind) && Var->hasAttr<DLLImportAttr>())
2422 if (Info.getASTContext().getLangOpts().CUDA &&
2423 Info.getASTContext().getLangOpts().CUDAIsDevice &&
2424 Info.getASTContext().CUDAConstantEvalCtx.NoWrongSidedVars) {
2425 if ((!Var->hasAttr<CUDADeviceAttr>() &&
2426 !Var->hasAttr<CUDAConstantAttr>() &&
2427 !Var->getType()->isCUDADeviceBuiltinSurfaceType() &&
2428 !Var->getType()->isCUDADeviceBuiltinTextureType()) ||
2429 Var->hasAttr<HIPManagedAttr>())
2433 if (
const auto *FD = dyn_cast<const FunctionDecl>(BaseVD)) {
2444 if (Info.getLangOpts().CPlusPlus && !isForManglingOnly(Kind) &&
2445 FD->hasAttr<DLLImportAttr>())
2449 }
else if (
const auto *MTE =
2450 dyn_cast_or_null<MaterializeTemporaryExpr>(BaseE)) {
2451 if (CheckedTemps.insert(MTE).second) {
2454 Info.FFDiag(MTE->getExprLoc(),
2455 diag::note_constexpr_unsupported_temporary_nontrivial_dtor)
2460 APValue *
V = MTE->getOrCreateValue(
false);
2461 assert(
V &&
"evasluation result refers to uninitialised temporary");
2463 Info, MTE->getExprLoc(), TempType, *
V, Kind,
2464 nullptr, CheckedTemps))
2471 if (!IsReferenceType)
2483 Info.FFDiag(
Loc, diag::note_constexpr_past_end, 1)
2484 << !
Designator.Entries.empty() << !!BaseVD << BaseVD;
2499 const auto *FD = dyn_cast_or_null<CXXMethodDecl>(
Member);
2502 if (FD->isImmediateFunction()) {
2503 Info.FFDiag(
Loc, diag::note_consteval_address_accessible) << 0;
2504 Info.Note(FD->getLocation(), diag::note_declared_at);
2507 return isForManglingOnly(Kind) || FD->isVirtual() ||
2508 !FD->hasAttr<DLLImportAttr>();
2514 const LValue *This =
nullptr) {
2516 if (Info.getLangOpts().CPlusPlus23)
2535 if (This && Info.EvaluatingDecl == This->getLValueBase())
2539 if (Info.getLangOpts().CPlusPlus11)
2540 Info.FFDiag(
E, diag::note_constexpr_nonliteral)
2543 Info.FFDiag(
E, diag::note_invalid_subexpr_in_const_expr);
2554 if (SubobjectDecl) {
2555 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
2556 << 1 << SubobjectDecl;
2558 diag::note_constexpr_subobject_declared_here);
2560 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
2569 Type = AT->getValueType();
2574 if (
Value.isArray()) {
2576 for (
unsigned I = 0, N =
Value.getArrayInitializedElts(); I != N; ++I) {
2578 Value.getArrayInitializedElt(I), Kind,
2579 SubobjectDecl, CheckedTemps))
2582 if (!
Value.hasArrayFiller())
2585 Value.getArrayFiller(), Kind, SubobjectDecl,
2588 if (
Value.isUnion() &&
Value.getUnionField()) {
2591 Value.getUnionValue(), Kind,
Value.getUnionField(), CheckedTemps);
2593 if (
Value.isStruct()) {
2595 if (
const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {
2596 unsigned BaseIndex = 0;
2598 const APValue &BaseValue =
Value.getStructBase(BaseIndex);
2601 Info.FFDiag(TypeBeginLoc, diag::note_constexpr_uninitialized_base)
2602 << BS.getType() <<
SourceRange(TypeBeginLoc, BS.getEndLoc());
2612 for (
const auto *I : RD->
fields()) {
2613 if (I->isUnnamedBitField())
2617 Value.getStructField(I->getFieldIndex()), Kind,
2623 if (
Value.isLValue() &&
2624 CERK == CheckEvaluationResultKind::ConstantExpression) {
2626 LVal.setFrom(Info.Ctx,
Value);
2631 if (
Value.isMemberPointer() &&
2632 CERK == CheckEvaluationResultKind::ConstantExpression)
2652 nullptr, CheckedTemps);
2661 CheckEvaluationResultKind::FullyInitialized, Info, DiagLoc,
Type,
Value,
2662 ConstantExprKind::Normal,
nullptr, CheckedTemps);
2668 if (!Info.HeapAllocs.empty()) {
2672 Info.CCEDiag(Info.HeapAllocs.begin()->second.AllocExpr,
2673 diag::note_constexpr_memory_leak)
2674 <<
unsigned(Info.HeapAllocs.size() - 1);
2682 if (!
Value.getLValueBase()) {
2684 Result = !
Value.getLValueOffset().isZero();
2702 Result = Val.
getInt().getBoolValue();
2734 llvm_unreachable(
"unknown APValue kind");
2740 assert(
E->
isPRValue() &&
"missing lvalue-to-rvalue conv in bool condition");
2750 Info.CCEDiag(
E, diag::note_constexpr_overflow)
2751 << SrcValue << DestType;
2752 return Info.noteUndefinedBehavior();
2758 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
2762 Result =
APSInt(DestWidth, !DestSigned);
2764 if (
Value.convertToInteger(Result, llvm::APFloat::rmTowardZero, &ignored)
2765 & APFloat::opInvalidOp)
2776 llvm::RoundingMode RM =
2778 if (RM == llvm::RoundingMode::Dynamic)
2779 RM = llvm::RoundingMode::NearestTiesToEven;
2785 APFloat::opStatus St) {
2788 if (Info.InConstantContext)
2792 if ((St & APFloat::opInexact) &&
2796 Info.FFDiag(
E, diag::note_constexpr_dynamic_rounding);
2800 if ((St != APFloat::opOK) &&
2803 FPO.getAllowFEnvAccess())) {
2804 Info.FFDiag(
E, diag::note_constexpr_float_arithmetic_strict);
2808 if ((St & APFloat::opStatus::opInvalidOp) &&
2827 assert((isa<CastExpr>(
E) || isa<CompoundAssignOperator>(
E) ||
2828 isa<ConvertVectorExpr>(
E)) &&
2829 "HandleFloatToFloatCast has been checked with only CastExpr, "
2830 "CompoundAssignOperator and ConvertVectorExpr. Please either validate "
2831 "the new expression or address the root cause of this usage.");
2833 APFloat::opStatus St;
2834 APFloat
Value = Result;
2836 St = Result.convert(Info.Ctx.getFloatTypeSemantics(DestType), RM, &ignored);
2843 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
2849 Result =
Value.getBoolValue();
2856 QualType DestType, APFloat &Result) {
2857 Result = APFloat(Info.Ctx.getFloatTypeSemantics(DestType), 1);
2859 APFloat::opStatus St = Result.convertFromAPInt(
Value,
Value.isSigned(), RM);
2865 assert(FD->
isBitField() &&
"truncateBitfieldValue on non-bitfield");
2867 if (!
Value.isInt()) {
2871 assert(
Value.isLValue() &&
"integral value neither int nor lvalue?");
2877 unsigned OldBitWidth = Int.getBitWidth();
2879 if (NewBitWidth < OldBitWidth)
2880 Int = Int.trunc(NewBitWidth).extend(OldBitWidth);
2887template<
typename Operation>
2890 unsigned BitWidth, Operation Op,
2892 if (LHS.isUnsigned()) {
2893 Result = Op(LHS, RHS);
2897 APSInt Value(Op(LHS.extend(BitWidth), RHS.extend(BitWidth)),
false);
2898 Result =
Value.trunc(LHS.getBitWidth());
2899 if (Result.extend(BitWidth) !=
Value) {
2900 if (Info.checkingForUndefinedBehavior())
2902 diag::warn_integer_constant_overflow)
2903 <<
toString(Result, 10, Result.isSigned(),
false,
2915 bool HandleOverflowResult =
true;
2922 std::multiplies<APSInt>(), Result);
2925 std::plus<APSInt>(), Result);
2928 std::minus<APSInt>(), Result);
2929 case BO_And: Result = LHS & RHS;
return true;
2930 case BO_Xor: Result = LHS ^ RHS;
return true;
2931 case BO_Or: Result = LHS | RHS;
return true;
2935 Info.FFDiag(
E, diag::note_expr_divide_by_zero)
2941 if (RHS.isNegative() && RHS.isAllOnes() && LHS.isSigned() &&
2942 LHS.isMinSignedValue())
2944 Info,
E, -LHS.extend(LHS.getBitWidth() + 1),
E->
getType());
2945 Result = (Opcode == BO_Rem ? LHS % RHS : LHS / RHS);
2946 return HandleOverflowResult;
2948 if (Info.getLangOpts().OpenCL)
2950 RHS &=
APSInt(llvm::APInt(RHS.getBitWidth(),
2951 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2953 else if (RHS.isSigned() && RHS.isNegative()) {
2956 Info.CCEDiag(
E, diag::note_constexpr_negative_shift) << RHS;
2957 if (!Info.noteUndefinedBehavior())
2965 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
2967 Info.CCEDiag(
E, diag::note_constexpr_large_shift)
2968 << RHS <<
E->
getType() << LHS.getBitWidth();
2969 if (!Info.noteUndefinedBehavior())
2971 }
else if (LHS.isSigned() && !Info.getLangOpts().CPlusPlus20) {
2976 if (LHS.isNegative()) {
2977 Info.CCEDiag(
E, diag::note_constexpr_lshift_of_negative) << LHS;
2978 if (!Info.noteUndefinedBehavior())
2980 }
else if (LHS.countl_zero() < SA) {
2981 Info.CCEDiag(
E, diag::note_constexpr_lshift_discards);
2982 if (!Info.noteUndefinedBehavior())
2990 if (Info.getLangOpts().OpenCL)
2992 RHS &=
APSInt(llvm::APInt(RHS.getBitWidth(),
2993 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2995 else if (RHS.isSigned() && RHS.isNegative()) {
2998 Info.CCEDiag(
E, diag::note_constexpr_negative_shift) << RHS;
2999 if (!Info.noteUndefinedBehavior())
3007 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
3009 Info.CCEDiag(
E, diag::note_constexpr_large_shift)
3010 << RHS <<
E->
getType() << LHS.getBitWidth();
3011 if (!Info.noteUndefinedBehavior())
3019 case BO_LT: Result = LHS < RHS;
return true;
3020 case BO_GT: Result = LHS > RHS;
return true;
3021 case BO_LE: Result = LHS <= RHS;
return true;
3022 case BO_GE: Result = LHS >= RHS;
return true;
3023 case BO_EQ: Result = LHS == RHS;
return true;
3024 case BO_NE: Result = LHS != RHS;
return true;
3026 llvm_unreachable(
"BO_Cmp should be handled elsewhere");
3033 const APFloat &RHS) {
3035 APFloat::opStatus St;
3041 St = LHS.multiply(RHS, RM);
3044 St = LHS.add(RHS, RM);
3047 St = LHS.subtract(RHS, RM);
3053 Info.CCEDiag(
E, diag::note_expr_divide_by_zero);
3054 St = LHS.divide(RHS, RM);
3063 Info.CCEDiag(
E, diag::note_constexpr_float_arithmetic) << LHS.isNaN();
3064 return Info.noteUndefinedBehavior();
3072 const APInt &RHSValue, APInt &Result) {
3073 bool LHS = (LHSValue != 0);
3074 bool RHS = (RHSValue != 0);
3076 if (Opcode == BO_LAnd)
3077 Result = LHS && RHS;
3079 Result = LHS || RHS;
3084 const APFloat &RHSValue, APInt &Result) {
3085 bool LHS = !LHSValue.isZero();
3086 bool RHS = !RHSValue.isZero();
3088 if (Opcode == BO_LAnd)
3089 Result = LHS && RHS;
3091 Result = LHS || RHS;
3097 const APValue &RHSValue, APInt &Result) {
3101 RHSValue.
getInt(), Result);
3107template <
typename APTy>
3110 const APTy &RHSValue, APInt &Result) {
3113 llvm_unreachable(
"unsupported binary operator");
3115 Result = (LHSValue == RHSValue);
3118 Result = (LHSValue != RHSValue);
3121 Result = (LHSValue < RHSValue);
3124 Result = (LHSValue > RHSValue);
3127 Result = (LHSValue <= RHSValue);
3130 Result = (LHSValue >= RHSValue);
3144 const APValue &RHSValue, APInt &Result) {
3148 RHSValue.
getInt(), Result);
3159 assert(Opcode != BO_PtrMemD && Opcode != BO_PtrMemI &&
3160 "Operation not supported on vector types");
3164 QualType EltTy = VT->getElementType();
3171 "A vector result that isn't a vector OR uncalculated LValue");
3177 RHSValue.
getVectorLength() == NumElements &&
"Different vector sizes");
3181 for (
unsigned EltNum = 0; EltNum < NumElements; ++EltNum) {
3186 APSInt EltResult{Info.Ctx.getIntWidth(EltTy),
3196 RHSElt.
getInt(), EltResult);
3202 ResultElements.emplace_back(EltResult);
3207 "Mismatched LHS/RHS/Result Type");
3208 APFloat LHSFloat = LHSElt.
getFloat();
3216 ResultElements.emplace_back(LHSFloat);
3220 LHSValue =
APValue(ResultElements.data(), ResultElements.size());
3228 unsigned TruncatedElements) {
3229 SubobjectDesignator &
D = Result.Designator;
3232 if (TruncatedElements ==
D.Entries.size())
3234 assert(TruncatedElements >=
D.MostDerivedPathLength &&
3235 "not casting to a derived class");
3241 for (
unsigned I = TruncatedElements, N =
D.Entries.size(); I != N; ++I) {
3245 if (isVirtualBaseClass(
D.Entries[I]))
3251 D.Entries.resize(TruncatedElements);
3261 RL = &Info.Ctx.getASTRecordLayout(Derived);
3264 Obj.addDecl(Info,
E,
Base,
false);
3265 Obj.getLValueOffset() += RL->getBaseClassOffset(
Base);
3274 if (!
Base->isVirtual())
3277 SubobjectDesignator &
D = Obj.Designator;
3282 DerivedDecl =
D.MostDerivedType->getAsCXXRecordDecl();
3288 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(DerivedDecl);
3289 Obj.addDecl(Info,
E, BaseDecl,
true);
3297 PathE =
E->path_end();
3298 PathI != PathE; ++PathI) {
3302 Type = (*PathI)->getType();
3314 llvm_unreachable(
"Class must be derived from the passed in base class!");
3329 RL = &Info.Ctx.getASTRecordLayout(FD->
getParent());
3333 LVal.addDecl(Info,
E, FD);
3334 LVal.adjustOffset(Info.Ctx.toCharUnitsFromBits(RL->getFieldOffset(I)));
3342 for (
const auto *
C : IFD->
chain())
3375 if (SOT == SizeOfType::SizeOf)
3376 Size = Info.Ctx.getTypeSizeInChars(
Type);
3378 Size = Info.Ctx.getTypeInfoDataSizeInChars(
Type).Width;
3395 LVal.adjustOffsetAndIndex(Info,
E, Adjustment, SizeOfPointee);
3401 int64_t Adjustment) {
3403 APSInt::get(Adjustment));
3418 LVal.Offset += SizeOfComponent;
3420 LVal.addComplex(Info,
E, EltTy, Imag);
3426 uint64_t Size, uint64_t Idx) {
3431 LVal.Offset += SizeOfElement * Idx;
3433 LVal.addVectorElement(Info,
E, EltTy, Size, Idx);
3447 const VarDecl *VD, CallStackFrame *Frame,
3448 unsigned Version,
APValue *&Result) {
3453 Result = Frame->getTemporary(VD, Version);
3457 if (!isa<ParmVarDecl>(VD)) {
3464 "missing value for local variable");
3465 if (Info.checkingPotentialConstantExpression())
3470 diag::note_unimplemented_constexpr_lambda_feature_ast)
3471 <<
"captures not currently allowed";
3478 if (Info.EvaluatingDecl ==
Base) {
3479 Result = Info.EvaluatingDeclValue;
3483 if (isa<ParmVarDecl>(VD)) {
3486 if (!Info.checkingPotentialConstantExpression() ||
3487 !Info.CurrentCall->Callee ||
3489 if (Info.getLangOpts().CPlusPlus11) {
3490 Info.FFDiag(
E, diag::note_constexpr_function_param_value_unknown)
3510 if (!Info.checkingPotentialConstantExpression()) {
3511 Info.FFDiag(
E, diag::note_constexpr_var_init_unknown, 1)
3518 if (
Init->isValueDependent()) {
3525 if (!Info.checkingPotentialConstantExpression()) {
3526 Info.FFDiag(
E, Info.getLangOpts().CPlusPlus11
3527 ? diag::note_constexpr_ltor_non_constexpr
3528 : diag::note_constexpr_ltor_non_integral, 1)
3538 Info.FFDiag(
E, diag::note_constexpr_var_init_non_constant, 1) << VD;
3554 ((Info.getLangOpts().CPlusPlus || Info.getLangOpts().OpenCL) &&
3556 Info.CCEDiag(
E, diag::note_constexpr_var_init_non_constant, 1) << VD;
3563 Info.FFDiag(
E, diag::note_constexpr_var_init_weak) << VD;
3580 if (I->getType()->getAsCXXRecordDecl()->getCanonicalDecl() ==
Base)
3584 llvm_unreachable(
"base class missing from derived class's bases list");
3590 assert(!isa<SourceLocExpr>(Lit) &&
3591 "SourceLocExpr should have already been converted to a StringLiteral");
3594 if (
const auto *ObjCEnc = dyn_cast<ObjCEncodeExpr>(Lit)) {
3596 Info.Ctx.getObjCEncodingForType(ObjCEnc->getEncodedType(), Str);
3597 assert(Index <= Str.size() &&
"Index too large");
3598 return APSInt::getUnsigned(Str.c_str()[Index]);
3601 if (
auto PE = dyn_cast<PredefinedExpr>(Lit))
3602 Lit = PE->getFunctionName();
3605 Info.Ctx.getAsConstantArrayType(S->getType());
3606 assert(CAT &&
"string literal isn't an array");
3608 assert(CharType->
isIntegerType() &&
"unexpected character type");
3611 if (Index < S->getLength())
3612 Value = S->getCodeUnit(Index);
3624 AllocType.isNull() ? S->getType() : AllocType);
3625 assert(CAT &&
"string literal isn't an array");
3627 assert(CharType->
isIntegerType() &&
"unexpected character type");
3631 std::min(S->getLength(), Elts), Elts);
3634 if (Result.hasArrayFiller())
3636 for (
unsigned I = 0, N = Result.getArrayInitializedElts(); I != N; ++I) {
3637 Value = S->getCodeUnit(I);
3644 unsigned Size = Array.getArraySize();
3645 assert(Index < Size);
3648 unsigned OldElts = Array.getArrayInitializedElts();
3649 unsigned NewElts = std::max(Index+1, OldElts * 2);
3650 NewElts = std::min(Size, std::max(NewElts, 8u));
3654 for (
unsigned I = 0; I != OldElts; ++I)
3656 for (
unsigned I = OldElts; I != NewElts; ++I)
3660 Array.swap(NewValue);
3681 for (
auto *Field : RD->
fields())
3682 if (!Field->isUnnamedBitField() &&
3686 for (
auto &BaseSpec : RD->
bases())
3704 for (
auto *Field : RD->
fields()) {
3709 if (Field->isMutable() &&
3711 Info.FFDiag(
E, diag::note_constexpr_access_mutable, 1) << AK << Field;
3712 Info.Note(Field->getLocation(), diag::note_declared_at);
3720 for (
auto &BaseSpec : RD->
bases())
3730 bool MutableSubobject =
false) {
3735 switch (Info.IsEvaluatingDecl) {
3736 case EvalInfo::EvaluatingDeclKind::None:
3739 case EvalInfo::EvaluatingDeclKind::Ctor:
3741 if (Info.EvaluatingDecl ==
Base)
3746 if (
auto *BaseE =
Base.dyn_cast<
const Expr *>())
3747 if (
auto *BaseMTE = dyn_cast<MaterializeTemporaryExpr>(BaseE))
3748 return Info.EvaluatingDecl == BaseMTE->getExtendingDecl();
3751 case EvalInfo::EvaluatingDeclKind::Dtor:
3756 if (MutableSubobject ||
Base != Info.EvaluatingDecl)
3765 llvm_unreachable(
"unknown evaluating decl kind");
3770 return Info.CheckArraySize(
3779struct CompleteObject {
3787 CompleteObject() :
Value(nullptr) {}
3791 bool mayAccessMutableMembers(EvalInfo &Info,
AccessKinds AK)
const {
3802 if (!Info.getLangOpts().CPlusPlus14 &&
3803 AK != AccessKinds::AK_IsWithinLifetime)
3808 explicit operator bool()
const {
return !
Type.isNull(); }
3813 bool IsMutable =
false) {
3827template <
typename Sub
objectHandler>
3828static typename SubobjectHandler::result_type
3830 const SubobjectDesignator &Sub, SubobjectHandler &handler) {
3833 return handler.failed();
3834 if (Sub.isOnePastTheEnd() || Sub.isMostDerivedAnUnsizedArray()) {
3835 if (Info.getLangOpts().CPlusPlus11)
3836 Info.FFDiag(
E, Sub.isOnePastTheEnd()
3837 ? diag::note_constexpr_access_past_end
3838 : diag::note_constexpr_access_unsized_array)
3839 << handler.AccessKind;
3842 return handler.failed();
3848 const FieldDecl *VolatileField =
nullptr;
3851 for (
unsigned I = 0, N = Sub.Entries.size(); ; ++I) {
3862 if (!Info.checkingPotentialConstantExpression())
3863 Info.FFDiag(
E, diag::note_constexpr_access_uninit)
3866 return handler.failed();
3874 Info.isEvaluatingCtorDtor(
3877 ConstructionPhase::None) {
3887 if (Info.getLangOpts().CPlusPlus) {
3891 if (VolatileField) {
3894 Decl = VolatileField;
3895 }
else if (
auto *VD = Obj.Base.dyn_cast<
const ValueDecl*>()) {
3897 Loc = VD->getLocation();
3901 if (
auto *
E = Obj.Base.dyn_cast<
const Expr *>())
3904 Info.FFDiag(
E, diag::note_constexpr_access_volatile_obj, 1)
3905 << handler.AccessKind << DiagKind <<
Decl;
3906 Info.Note(
Loc, diag::note_constexpr_volatile_here) << DiagKind;
3908 Info.FFDiag(
E, diag::note_invalid_subexpr_in_const_expr);
3910 return handler.failed();
3918 !Obj.mayAccessMutableMembers(Info, handler.AccessKind) &&
3920 return handler.failed();
3924 if (!handler.found(*O, ObjType))
3936 LastField =
nullptr;
3940 assert(CAT &&
"vla in literal type?");
3941 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
3942 if (CAT->
getSize().ule(Index)) {
3945 if (Info.getLangOpts().CPlusPlus11)
3946 Info.FFDiag(
E, diag::note_constexpr_access_past_end)
3947 << handler.AccessKind;
3950 return handler.failed();
3957 else if (!
isRead(handler.AccessKind)) {
3959 return handler.failed();
3967 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
3969 if (Info.getLangOpts().CPlusPlus11)
3970 Info.FFDiag(
E, diag::note_constexpr_access_past_end)
3971 << handler.AccessKind;
3974 return handler.failed();
3980 assert(I == N - 1 &&
"extracting subobject of scalar?");
3990 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
3991 unsigned NumElements = VT->getNumElements();
3992 if (Index == NumElements) {
3993 if (Info.getLangOpts().CPlusPlus11)
3994 Info.FFDiag(
E, diag::note_constexpr_access_past_end)
3995 << handler.AccessKind;
3998 return handler.failed();
4001 if (Index > NumElements) {
4002 Info.CCEDiag(
E, diag::note_constexpr_array_index)
4003 << Index << 0 << NumElements;
4004 return handler.failed();
4007 ObjType = VT->getElementType();
4008 assert(I == N - 1 &&
"extracting subobject of scalar?");
4010 }
else if (
const FieldDecl *Field = getAsField(Sub.Entries[I])) {
4011 if (Field->isMutable() &&
4012 !Obj.mayAccessMutableMembers(Info, handler.AccessKind)) {
4013 Info.FFDiag(
E, diag::note_constexpr_access_mutable, 1)
4014 << handler.AccessKind << Field;
4015 Info.Note(Field->getLocation(), diag::note_declared_at);
4016 return handler.failed();
4025 if (I == N - 1 && handler.AccessKind ==
AK_Construct) {
4036 Info.FFDiag(
E, diag::note_constexpr_access_inactive_union_member)
4037 << handler.AccessKind << Field << !UnionField << UnionField;
4038 return handler.failed();
4047 if (Field->getType().isVolatileQualified())
4048 VolatileField = Field;
4061struct ExtractSubobjectHandler {
4067 typedef bool result_type;
4068 bool failed() {
return false; }
4088 const CompleteObject &Obj,
4089 const SubobjectDesignator &Sub,
APValue &Result,
4092 ExtractSubobjectHandler Handler = {Info,
E, Result, AK};
4097struct ModifySubobjectHandler {
4102 typedef bool result_type;
4108 Info.FFDiag(
E, diag::note_constexpr_modify_const_type) << QT;
4114 bool failed() {
return false; }
4116 if (!checkConst(SubobjType))
4119 Subobj.
swap(NewVal);
4123 if (!checkConst(SubobjType))
4125 if (!NewVal.
isInt()) {
4134 if (!checkConst(SubobjType))
4142const AccessKinds ModifySubobjectHandler::AccessKind;
4146 const CompleteObject &Obj,
4147 const SubobjectDesignator &Sub,
4149 ModifySubobjectHandler Handler = { Info, NewVal,
E };
4156 const SubobjectDesignator &A,
4157 const SubobjectDesignator &B,
4158 bool &WasArrayIndex) {
4159 unsigned I = 0, N = std::min(A.Entries.size(), B.Entries.size());
4160 for (; I != N; ++I) {
4164 if (A.Entries[I].getAsArrayIndex() != B.Entries[I].getAsArrayIndex()) {
4165 WasArrayIndex =
true;
4173 if (A.Entries[I].getAsBaseOrMember() !=
4174 B.Entries[I].getAsBaseOrMember()) {
4175 WasArrayIndex =
false;
4178 if (
const FieldDecl *FD = getAsField(A.Entries[I]))
4180 ObjType = FD->getType();
4186 WasArrayIndex =
false;
4193 const SubobjectDesignator &A,
4194 const SubobjectDesignator &B) {
4195 if (A.Entries.size() != B.Entries.size())
4198 bool IsArray = A.MostDerivedIsArrayElement;
4199 if (IsArray && A.MostDerivedPathLength != A.Entries.size())
4208 return CommonLength >= A.Entries.size() - IsArray;
4215 if (LVal.InvalidBase) {
4217 return CompleteObject();
4221 Info.FFDiag(
E, diag::note_constexpr_access_null) << AK;
4222 return CompleteObject();
4225 CallStackFrame *Frame =
nullptr;
4227 if (LVal.getLValueCallIndex()) {
4228 std::tie(Frame, Depth) =
4229 Info.getCallFrameAndDepth(LVal.getLValueCallIndex());
4231 Info.FFDiag(
E, diag::note_constexpr_lifetime_ended, 1)
4232 << AK << LVal.Base.is<
const ValueDecl*>();
4234 return CompleteObject();
4245 if (Info.getLangOpts().CPlusPlus)
4246 Info.FFDiag(
E, diag::note_constexpr_access_volatile_type)
4250 return CompleteObject();
4255 QualType BaseType = getType(LVal.Base);
4257 if (Info.getLangOpts().CPlusPlus14 && LVal.Base == Info.EvaluatingDecl &&
4261 BaseVal = Info.EvaluatingDeclValue;
4264 if (
auto *GD = dyn_cast<MSGuidDecl>(
D)) {
4267 Info.FFDiag(
E, diag::note_constexpr_modify_global);
4268 return CompleteObject();
4272 Info.FFDiag(
E, diag::note_constexpr_unsupported_layout)
4274 return CompleteObject();
4276 return CompleteObject(LVal.Base, &
V, GD->getType());
4280 if (
auto *GCD = dyn_cast<UnnamedGlobalConstantDecl>(
D)) {
4282 Info.FFDiag(
E, diag::note_constexpr_modify_global);
4283 return CompleteObject();
4285 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&GCD->getValue()),
4290 if (
auto *TPO = dyn_cast<TemplateParamObjectDecl>(
D)) {
4292 Info.FFDiag(
E, diag::note_constexpr_modify_global);
4293 return CompleteObject();
4295 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&TPO->getValue()),
4306 const VarDecl *VD = dyn_cast<VarDecl>(
D);
4313 return CompleteObject();
4316 bool IsConstant = BaseType.
isConstant(Info.Ctx);
4317 bool ConstexprVar =
false;
4318 if (
const auto *VD = dyn_cast_if_present<VarDecl>(
4319 Info.EvaluatingDecl.dyn_cast<
const ValueDecl *>()))
4325 if (IsAccess && isa<ParmVarDecl>(VD)) {
4329 }
else if (Info.getLangOpts().CPlusPlus14 &&
4336 Info.FFDiag(
E, diag::note_constexpr_modify_global);
4337 return CompleteObject();
4340 }
else if (Info.getLangOpts().C23 && ConstexprVar) {
4342 return CompleteObject();
4346 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4347 if (Info.getLangOpts().CPlusPlus) {
4348 Info.FFDiag(
E, diag::note_constexpr_ltor_non_const_int, 1) << VD;
4349 Info.Note(VD->
getLocation(), diag::note_declared_at);
4353 return CompleteObject();
4355 }
else if (!IsAccess) {
4356 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4357 }
else if (IsConstant && Info.checkingPotentialConstantExpression() &&
4360 }
else if (IsConstant) {
4364 if (Info.getLangOpts().CPlusPlus) {
4365 Info.CCEDiag(
E, Info.getLangOpts().CPlusPlus11
4366 ? diag::note_constexpr_ltor_non_constexpr
4367 : diag::note_constexpr_ltor_non_integral, 1)
4369 Info.Note(VD->
getLocation(), diag::note_declared_at);
4375 if (Info.getLangOpts().CPlusPlus) {
4376 Info.FFDiag(
E, Info.getLangOpts().CPlusPlus11
4377 ? diag::note_constexpr_ltor_non_constexpr
4378 : diag::note_constexpr_ltor_non_integral, 1)
4380 Info.Note(VD->
getLocation(), diag::note_declared_at);
4384 return CompleteObject();
4389 return CompleteObject();
4391 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
4393 Info.FFDiag(
E, diag::note_constexpr_access_deleted_object) << AK;
4394 return CompleteObject();
4396 return CompleteObject(LVal.Base, &(*Alloc)->Value,
4397 LVal.Base.getDynamicAllocType());
4403 dyn_cast_or_null<MaterializeTemporaryExpr>(
Base)) {
4404 assert(MTE->getStorageDuration() ==
SD_Static &&
4405 "should have a frame for a non-global materialized temporary");
4432 if (!MTE->isUsableInConstantExpressions(Info.Ctx) &&
4435 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4436 Info.FFDiag(
E, diag::note_constexpr_access_static_temporary, 1) << AK;
4437 Info.Note(MTE->getExprLoc(), diag::note_constexpr_temporary_here);
4438 return CompleteObject();
4441 BaseVal = MTE->getOrCreateValue(
false);
4442 assert(BaseVal &&
"got reference to unevaluated temporary");
4445 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4448 Info.FFDiag(
E, diag::note_constexpr_access_unreadable_object)
4451 Info.Ctx.getLValueReferenceType(LValType));
4453 return CompleteObject();
4456 BaseVal = Frame->getTemporary(
Base, LVal.Base.getVersion());
4457 assert(BaseVal &&
"missing value for temporary");
4468 unsigned VisibleDepth = Depth;
4469 if (llvm::isa_and_nonnull<ParmVarDecl>(
4470 LVal.Base.dyn_cast<
const ValueDecl *>()))
4472 if ((Frame && Info.getLangOpts().CPlusPlus14 &&
4473 Info.EvalStatus.HasSideEffects) ||
4474 (
isModification(AK) && VisibleDepth < Info.SpeculativeEvaluationDepth))
4475 return CompleteObject();
4477 return CompleteObject(LVal.getLValueBase(), BaseVal, BaseType);
4496 const LValue &LVal,
APValue &RVal,
4497 bool WantObjectRepresentation =
false) {
4498 if (LVal.Designator.Invalid)
4507 if (
Base && !LVal.getLValueCallIndex() && !
Type.isVolatileQualified()) {
4512 if (
Type.isVolatileQualified()) {
4518 if (!
Evaluate(Lit, Info, CLE->getInitializer()))
4538 Info.Note(CLE->getExprLoc(), diag::note_declared_at);
4543 CompleteObject LitObj(LVal.Base, &Lit,
Base->getType());
4545 }
else if (isa<StringLiteral>(
Base) || isa<PredefinedExpr>(
Base)) {
4548 assert(LVal.Designator.Entries.size() <= 1 &&
4549 "Can only read characters from string literals");
4550 if (LVal.Designator.Entries.empty()) {
4557 if (LVal.Designator.isOnePastTheEnd()) {
4558 if (Info.getLangOpts().CPlusPlus11)
4559 Info.FFDiag(Conv, diag::note_constexpr_access_past_end) << AK;
4564 uint64_t CharIndex = LVal.Designator.Entries[0].getAsArrayIndex();
4571 return Obj &&
extractSubobject(Info, Conv, Obj, LVal.Designator, RVal, AK);
4577 if (LVal.Designator.Invalid)
4580 if (!Info.getLangOpts().CPlusPlus14) {
4590struct CompoundAssignSubobjectHandler {
4599 typedef bool result_type;
4604 Info.FFDiag(
E, diag::note_constexpr_modify_const_type) << QT;
4610 bool failed() {
return false; }
4614 return found(Subobj.
getInt(), SubobjType);
4616 return found(Subobj.
getFloat(), SubobjType);
4623 return foundPointer(Subobj, SubobjType);
4625 return foundVector(Subobj, SubobjType);
4627 Info.FFDiag(
E, diag::note_constexpr_access_uninit)
4639 if (!checkConst(SubobjType))
4650 if (!checkConst(SubobjType))
4669 Info.Ctx.getLangOpts());
4672 PromotedLHSType, FValue) &&
4682 return checkConst(SubobjType) &&
4689 if (!checkConst(SubobjType))
4697 (Opcode != BO_Add && Opcode != BO_Sub)) {
4703 if (Opcode == BO_Sub)
4707 LVal.setFrom(Info.Ctx, Subobj);
4710 LVal.moveInto(Subobj);
4716const AccessKinds CompoundAssignSubobjectHandler::AccessKind;
4721 const LValue &LVal,
QualType LValType,
4725 if (LVal.Designator.Invalid)
4728 if (!Info.getLangOpts().CPlusPlus14) {
4734 CompoundAssignSubobjectHandler Handler = { Info,
E, PromotedLValType, Opcode,
4736 return Obj &&
findSubobject(Info,
E, Obj, LVal.Designator, Handler);
4740struct IncDecSubobjectHandler {
4746 typedef bool result_type;
4751 Info.FFDiag(
E, diag::note_constexpr_modify_const_type) << QT;
4757 bool failed() {
return false; }
4768 return found(Subobj.
getInt(), SubobjType);
4770 return found(Subobj.
getFloat(), SubobjType);
4780 return foundPointer(Subobj, SubobjType);
4788 if (!checkConst(SubobjType))
4810 bool WasNegative =
Value.isNegative();
4814 if (!WasNegative &&
Value.isNegative() &&
E->canOverflow()) {
4821 if (WasNegative && !
Value.isNegative() &&
E->canOverflow()) {
4822 unsigned BitWidth =
Value.getBitWidth();
4823 APSInt ActualValue(
Value.sext(BitWidth + 1),
false);
4824 ActualValue.setBit(BitWidth);
4831 if (!checkConst(SubobjType))
4838 APFloat::opStatus St;
4840 St =
Value.add(One, RM);
4842 St =
Value.subtract(One, RM);
4846 if (!checkConst(SubobjType))
4858 LVal.setFrom(Info.Ctx, Subobj);
4862 LVal.moveInto(Subobj);
4871 if (LVal.Designator.Invalid)
4874 if (!Info.getLangOpts().CPlusPlus14) {
4881 IncDecSubobjectHandler Handler = {Info, cast<UnaryOperator>(
E), AK, Old};
4882 return Obj &&
findSubobject(Info,
E, Obj, LVal.Designator, Handler);
4888 if (Object->getType()->isPointerType() && Object->isPRValue())
4891 if (Object->isGLValue())
4894 if (Object->getType()->isLiteralType(Info.Ctx))
4897 if (Object->getType()->isRecordType() && Object->isPRValue())
4900 Info.FFDiag(Object, diag::note_constexpr_nonliteral) << Object->getType();
4919 bool IncludeMember =
true) {
4926 if (!MemPtr.getDecl()) {
4932 if (MemPtr.isDerivedMember()) {
4936 if (LV.Designator.MostDerivedPathLength + MemPtr.Path.size() >
4937 LV.Designator.Entries.size()) {
4941 unsigned PathLengthToMember =
4942 LV.Designator.Entries.size() - MemPtr.Path.size();
4943 for (
unsigned I = 0, N = MemPtr.Path.size(); I != N; ++I) {
4945 LV.Designator.Entries[PathLengthToMember + I]);
4955 PathLengthToMember))
4957 }
else if (!MemPtr.Path.empty()) {
4959 LV.Designator.Entries.reserve(LV.Designator.Entries.size() +
4960 MemPtr.Path.size() + IncludeMember);
4966 assert(RD &&
"member pointer access on non-class-type expression");
4968 for (
unsigned I = 1, N = MemPtr.Path.size(); I != N; ++I) {
4976 MemPtr.getContainingRecord()))
4981 if (IncludeMember) {
4982 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(MemPtr.getDecl())) {
4986 dyn_cast<IndirectFieldDecl>(MemPtr.getDecl())) {
4990 llvm_unreachable(
"can't construct reference to bound member function");
4994 return MemPtr.getDecl();
5000 bool IncludeMember =
true) {
5004 if (Info.noteFailure()) {
5012 BO->
getRHS(), IncludeMember);
5019 SubobjectDesignator &
D = Result.Designator;
5020 if (
D.Invalid || !Result.checkNullPointer(Info,
E,
CSK_Derived))
5028 if (
D.MostDerivedPathLength +
E->path_size() >
D.Entries.size()) {
5029 Info.CCEDiag(
E, diag::note_constexpr_invalid_downcast)
5030 <<
D.MostDerivedType << TargetQT;
5036 unsigned NewEntriesSize =
D.Entries.size() -
E->path_size();
5039 if (NewEntriesSize ==
D.MostDerivedPathLength)
5040 FinalType =
D.MostDerivedType->getAsCXXRecordDecl();
5042 FinalType = getAsBaseClass(
D.Entries[NewEntriesSize - 1]);
5044 Info.CCEDiag(
E, diag::note_constexpr_invalid_downcast)
5045 <<
D.MostDerivedType << TargetQT;
5059 if (!Result.isAbsent())
5063 if (RD->isInvalidDecl()) {
5067 if (RD->isUnion()) {
5072 std::distance(RD->field_begin(), RD->field_end()));
5076 End = RD->bases_end();
5077 I != End; ++I, ++Index)
5081 for (
const auto *I : RD->fields()) {
5082 if (I->isUnnamedBitField())
5085 I->getType(), Result.getStructField(I->getFieldIndex()));
5093 if (Result.hasArrayFiller())
5105enum EvalStmtResult {
5129 APValue &Val = Info.CurrentCall->createTemporary(VD, VD->
getType(),
5130 ScopeKind::Block, Result);
5135 return Info.noteSideEffect();
5154 if (
const VarDecl *VD = dyn_cast<VarDecl>(
D))
5158 for (
auto *BD : DD->bindings())
5159 if (
auto *VD = BD->getHoldingVar())
5167 if (Info.noteSideEffect())
5169 assert(
E->
containsErrors() &&
"valid value-dependent expression should never "
5170 "reach invalid code path.");
5176 const Expr *Cond,
bool &Result) {
5179 FullExpressionRAII
Scope(Info);
5184 return Scope.destroy();
5197struct TempVersionRAII {
5198 CallStackFrame &Frame;
5200 TempVersionRAII(CallStackFrame &Frame) : Frame(Frame) {
5201 Frame.pushTempVersion();
5204 ~TempVersionRAII() {
5205 Frame.popTempVersion();
5219 BlockScopeRAII
Scope(Info);
5221 EvalStmtResult ESR =
EvaluateStmt(Result, Info, Body, Case);
5222 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5227 return ESR_Succeeded;
5230 return ESR_Continue;
5233 case ESR_CaseNotFound:
5236 llvm_unreachable(
"Invalid EvalStmtResult!");
5242 BlockScopeRAII
Scope(Info);
5249 if (ESR != ESR_Succeeded) {
5250 if (ESR != ESR_Failed && !
Scope.destroy())
5256 FullExpressionRAII CondScope(Info);
5268 if (!CondScope.destroy())
5277 if (isa<DefaultStmt>(SC)) {
5282 const CaseStmt *CS = cast<CaseStmt>(SC);
5293 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5297 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5302 return ESR_Succeeded;
5308 case ESR_CaseNotFound:
5311 Info.FFDiag(
Found->getBeginLoc(),
5312 diag::note_constexpr_stmt_expr_unsupported);
5315 llvm_unreachable(
"Invalid EvalStmtResult!");
5325 Info.CCEDiag(VD->
getLocation(), diag::note_constexpr_static_local)
5335 if (!Info.nextStep(S))
5341 switch (S->getStmtClass()) {
5342 case Stmt::CompoundStmtClass:
5346 case Stmt::LabelStmtClass:
5347 case Stmt::AttributedStmtClass:
5348 case Stmt::DoStmtClass:
5351 case Stmt::CaseStmtClass:
5352 case Stmt::DefaultStmtClass:
5357 case Stmt::IfStmtClass: {
5360 const IfStmt *IS = cast<IfStmt>(S);
5364 BlockScopeRAII
Scope(Info);
5370 if (ESR != ESR_CaseNotFound) {
5371 assert(ESR != ESR_Succeeded);
5382 if (ESR == ESR_Failed)
5384 if (ESR != ESR_CaseNotFound)
5385 return Scope.destroy() ? ESR : ESR_Failed;
5387 return ESR_CaseNotFound;
5390 if (ESR == ESR_Failed)
5392 if (ESR != ESR_CaseNotFound)
5393 return Scope.destroy() ? ESR : ESR_Failed;
5394 return ESR_CaseNotFound;
5397 case Stmt::WhileStmtClass: {
5398 EvalStmtResult ESR =
5400 if (ESR != ESR_Continue)
5405 case Stmt::ForStmtClass: {
5406 const ForStmt *FS = cast<ForStmt>(S);
5407 BlockScopeRAII
Scope(Info);
5411 if (
const Stmt *
Init = FS->getInit()) {
5413 if (ESR != ESR_CaseNotFound) {
5414 assert(ESR != ESR_Succeeded);
5419 EvalStmtResult ESR =
5421 if (ESR != ESR_Continue)
5423 if (
const auto *Inc = FS->getInc()) {
5424 if (Inc->isValueDependent()) {
5428 FullExpressionRAII IncScope(Info);
5436 case Stmt::DeclStmtClass: {
5439 const DeclStmt *DS = cast<DeclStmt>(S);
5440 for (
const auto *
D : DS->
decls()) {
5441 if (
const auto *VD = dyn_cast<VarDecl>(
D)) {
5444 if (VD->hasLocalStorage() && !VD->getInit())
5452 return ESR_CaseNotFound;
5456 return ESR_CaseNotFound;
5460 switch (S->getStmtClass()) {
5462 if (
const Expr *
E = dyn_cast<Expr>(S)) {
5471 FullExpressionRAII
Scope(Info);
5475 return ESR_Succeeded;
5478 Info.FFDiag(S->getBeginLoc()) << S->getSourceRange();
5481 case Stmt::NullStmtClass:
5482 return ESR_Succeeded;
5484 case Stmt::DeclStmtClass: {
5485 const DeclStmt *DS = cast<DeclStmt>(S);
5486 for (
const auto *
D : DS->
decls()) {
5487 const VarDecl *VD = dyn_cast_or_null<VarDecl>(
D);
5491 FullExpressionRAII
Scope(Info);
5494 if (!
Scope.destroy())
5497 return ESR_Succeeded;
5500 case Stmt::ReturnStmtClass: {
5501 const Expr *RetExpr = cast<ReturnStmt>(S)->getRetValue();
5502 FullExpressionRAII
Scope(Info);
5511 :
Evaluate(Result.Value, Info, RetExpr)))
5513 return Scope.destroy() ? ESR_Returned : ESR_Failed;
5516 case Stmt::CompoundStmtClass: {
5517 BlockScopeRAII
Scope(Info);
5520 for (
const auto *BI : CS->
body()) {
5521 EvalStmtResult ESR =
EvaluateStmt(Result, Info, BI, Case);
5522 if (ESR == ESR_Succeeded)
5524 else if (ESR != ESR_CaseNotFound) {
5525 if (ESR != ESR_Failed && !
Scope.destroy())
5531 return ESR_CaseNotFound;
5532 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5535 case Stmt::IfStmtClass: {
5536 const IfStmt *IS = cast<IfStmt>(S);
5539 BlockScopeRAII
Scope(Info);
5542 if (ESR != ESR_Succeeded) {
5543 if (ESR != ESR_Failed && !
Scope.destroy())
5553 if (!Info.InConstantContext)
5560 EvalStmtResult ESR =
EvaluateStmt(Result, Info, SubStmt);
5561 if (ESR != ESR_Succeeded) {
5562 if (ESR != ESR_Failed && !
Scope.destroy())
5567 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5570 case Stmt::WhileStmtClass: {
5571 const WhileStmt *WS = cast<WhileStmt>(S);
5573 BlockScopeRAII
Scope(Info);
5582 if (ESR != ESR_Continue) {
5583 if (ESR != ESR_Failed && !
Scope.destroy())
5587 if (!
Scope.destroy())
5590 return ESR_Succeeded;
5593 case Stmt::DoStmtClass: {
5594 const DoStmt *DS = cast<DoStmt>(S);
5598 if (ESR != ESR_Continue)
5607 FullExpressionRAII CondScope(Info);
5609 !CondScope.destroy())
5612 return ESR_Succeeded;
5615 case Stmt::ForStmtClass: {
5616 const ForStmt *FS = cast<ForStmt>(S);
5617 BlockScopeRAII ForScope(Info);
5618 if (FS->getInit()) {
5619 EvalStmtResult ESR =
EvaluateStmt(Result, Info, FS->getInit());
5620 if (ESR != ESR_Succeeded) {
5621 if (ESR != ESR_Failed && !ForScope.destroy())
5627 BlockScopeRAII IterScope(Info);
5628 bool Continue =
true;
5629 if (FS->getCond() && !
EvaluateCond(Info, FS->getConditionVariable(),
5630 FS->getCond(), Continue))
5636 if (ESR != ESR_Continue) {
5637 if (ESR != ESR_Failed && (!IterScope.destroy() || !ForScope.destroy()))
5642 if (
const auto *Inc = FS->getInc()) {
5643 if (Inc->isValueDependent()) {
5647 FullExpressionRAII IncScope(Info);
5653 if (!IterScope.destroy())
5656 return ForScope.destroy() ? ESR_Succeeded : ESR_Failed;
5659 case Stmt::CXXForRangeStmtClass: {
5661 BlockScopeRAII
Scope(Info);
5664 if (FS->getInit()) {
5665 EvalStmtResult ESR =
EvaluateStmt(Result, Info, FS->getInit());
5666 if (ESR != ESR_Succeeded) {
5667 if (ESR != ESR_Failed && !
Scope.destroy())
5674 EvalStmtResult ESR =
EvaluateStmt(Result, Info, FS->getRangeStmt());
5675 if (ESR != ESR_Succeeded) {
5676 if (ESR != ESR_Failed && !
Scope.destroy())
5683 if (!FS->getBeginStmt() || !FS->getEndStmt() || !FS->getCond())
5688 if (ESR != ESR_Succeeded) {
5689 if (ESR != ESR_Failed && !
Scope.destroy())
5694 if (ESR != ESR_Succeeded) {
5695 if (ESR != ESR_Failed && !
Scope.destroy())
5703 if (FS->getCond()->isValueDependent()) {
5708 bool Continue =
true;
5709 FullExpressionRAII CondExpr(Info);
5717 BlockScopeRAII InnerScope(Info);
5718 ESR =
EvaluateStmt(Result, Info, FS->getLoopVarStmt());
5719 if (ESR != ESR_Succeeded) {
5720 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
5727 if (ESR != ESR_Continue) {
5728 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
5732 if (FS->getInc()->isValueDependent()) {
5741 if (!InnerScope.destroy())
5745 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5748 case Stmt::SwitchStmtClass:
5751 case Stmt::ContinueStmtClass:
5752 return ESR_Continue;
5754 case Stmt::BreakStmtClass:
5757 case Stmt::LabelStmtClass:
5758 return EvaluateStmt(Result, Info, cast<LabelStmt>(S)->getSubStmt(), Case);
5760 case Stmt::AttributedStmtClass: {
5761 const auto *AS = cast<AttributedStmt>(S);
5762 const auto *SS = AS->getSubStmt();
5763 MSConstexprContextRAII ConstexprContext(
5764 *Info.CurrentCall, hasSpecificAttr<MSConstexprAttr>(AS->getAttrs()) &&
5765 isa<ReturnStmt>(SS));
5767 auto LO = Info.getASTContext().getLangOpts();
5768 if (LO.CXXAssumptions && !LO.MSVCCompat) {
5769 for (
auto *
Attr : AS->getAttrs()) {
5770 auto *AA = dyn_cast<CXXAssumeAttr>(
Attr);
5774 auto *Assumption = AA->getAssumption();
5775 if (Assumption->isValueDependent())
5778 if (Assumption->HasSideEffects(Info.getASTContext()))
5785 Info.CCEDiag(Assumption->getExprLoc(),
5786 diag::note_constexpr_assumption_failed);
5795 case Stmt::CaseStmtClass:
5796 case Stmt::DefaultStmtClass:
5797 return EvaluateStmt(Result, Info, cast<SwitchCase>(S)->getSubStmt(), Case);
5798 case Stmt::CXXTryStmtClass:
5800 return EvaluateStmt(Result, Info, cast<CXXTryStmt>(S)->getTryBlock(), Case);
5810 bool IsValueInitialization) {
5817 if (!CD->
isConstexpr() && !IsValueInitialization) {
5818 if (Info.getLangOpts().CPlusPlus11) {
5821 Info.CCEDiag(
Loc, diag::note_constexpr_invalid_function, 1)
5823 Info.Note(CD->
getLocation(), diag::note_declared_at);
5825 Info.CCEDiag(
Loc, diag::note_invalid_subexpr_in_const_expr);
5839 if (Info.checkingPotentialConstantExpression() && !
Definition &&
5847 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
5854 if (!Info.Ctx.getLangOpts().CPlusPlus20 && isa<CXXMethodDecl>(
Declaration) &&
5856 Info.CCEDiag(CallLoc, diag::note_constexpr_virtual_call);
5859 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
5865 (
Definition->isConstexpr() || (Info.CurrentCall->CanEvalMSConstexpr &&
5869 if (Info.getLangOpts().CPlusPlus11) {
5874 auto *CD = dyn_cast<CXXConstructorDecl>(DiagDecl);
5875 if (CD && CD->isInheritingConstructor()) {
5876 auto *Inherited = CD->getInheritedConstructor().getConstructor();
5877 if (!Inherited->isConstexpr())
5878 DiagDecl = CD = Inherited;
5884 if (CD && CD->isInheritingConstructor())
5885 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_inhctor, 1)
5886 << CD->getInheritedConstructor().getConstructor()->
getParent();
5888 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_function, 1)
5890 Info.Note(DiagDecl->
getLocation(), diag::note_declared_at);
5892 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
5898struct CheckDynamicTypeHandler {
5900 typedef bool result_type;
5901 bool failed() {
return false; }
5904 bool found(APFloat &
Value,
QualType SubobjType) {
return true; }
5912 if (This.Designator.Invalid)
5924 if (This.Designator.isOnePastTheEnd() ||
5925 This.Designator.isMostDerivedAnUnsizedArray()) {
5926 Info.FFDiag(
E, This.Designator.isOnePastTheEnd()
5927 ? diag::note_constexpr_access_past_end
5928 : diag::note_constexpr_access_unsized_array)
5931 }
else if (Polymorphic) {
5937 Info.Ctx.getLValueReferenceType(This.Designator.getType(Info.Ctx));
5938 Info.FFDiag(
E, diag::note_constexpr_polymorphic_unknown_dynamic_type)
5945 CheckDynamicTypeHandler Handler{AK};
5946 return Obj &&
findSubobject(Info,
E, Obj, This.Designator, Handler);
5968 unsigned PathLength) {
5969 assert(PathLength >=
Designator.MostDerivedPathLength && PathLength <=
5970 Designator.Entries.size() &&
"invalid path length");
5971 return (PathLength ==
Designator.MostDerivedPathLength)
5972 ?
Designator.MostDerivedType->getAsCXXRecordDecl()
5973 : getAsBaseClass(
Designator.Entries[PathLength - 1]);
5985 return std::nullopt;
5994 This.Designator.MostDerivedType->getAsCXXRecordDecl();
5997 return std::nullopt;
6005 for (
unsigned PathLength = This.Designator.MostDerivedPathLength;
6006 PathLength <=
Path.size(); ++PathLength) {
6007 switch (Info.isEvaluatingCtorDtor(This.getLValueBase(),
6008 Path.slice(0, PathLength))) {
6009 case ConstructionPhase::Bases:
6010 case ConstructionPhase::DestroyingBases:
6015 case ConstructionPhase::None:
6016 case ConstructionPhase::AfterBases:
6017 case ConstructionPhase::AfterFields:
6018 case ConstructionPhase::Destroying:
6030 return std::nullopt;
6048 unsigned PathLength = DynType->PathLength;
6049 for (; PathLength <= This.Designator.Entries.size(); ++PathLength) {
6052 Found->getCorrespondingMethodDeclaredInClass(
Class,
false);
6062 if (Callee->isPureVirtual()) {
6063 Info.FFDiag(
E, diag::note_constexpr_pure_virtual_call, 1) << Callee;
6064 Info.Note(Callee->getLocation(), diag::note_declared_at);
6070 if (!Info.Ctx.hasSameUnqualifiedType(Callee->getReturnType(),
6071 Found->getReturnType())) {
6072 CovariantAdjustmentPath.push_back(Callee->getReturnType());
6073 for (
unsigned CovariantPathLength = PathLength + 1;
6074 CovariantPathLength != This.Designator.Entries.size();
6075 ++CovariantPathLength) {
6079 Found->getCorrespondingMethodDeclaredInClass(NextClass,
false);
6080 if (Next && !Info.Ctx.hasSameUnqualifiedType(
6081 Next->getReturnType(), CovariantAdjustmentPath.back()))
6082 CovariantAdjustmentPath.push_back(Next->getReturnType());
6084 if (!Info.Ctx.hasSameUnqualifiedType(
Found->getReturnType(),
6085 CovariantAdjustmentPath.back()))
6086 CovariantAdjustmentPath.push_back(
Found->getReturnType());
6102 assert(Result.isLValue() &&
6103 "unexpected kind of APValue for covariant return");
6104 if (Result.isNullPointer())
6108 LVal.setFrom(Info.Ctx, Result);
6111 for (
unsigned I = 1; I !=
Path.size(); ++I) {
6113 assert(OldClass && NewClass &&
"unexpected kind of covariant return");
6114 if (OldClass != NewClass &&
6117 OldClass = NewClass;
6120 LVal.moveInto(Result);
6129 auto *BaseClass = BaseSpec.getType()->getAsCXXRecordDecl();
6131 return BaseSpec.getAccessSpecifier() ==
AS_public;
6133 llvm_unreachable(
"Base is not a direct base of Derived");
6143 SubobjectDesignator &
D = Ptr.Designator;
6155 std::optional<DynamicType> DynType =
6166 const CXXRecordDecl *
C =
E->getTypeAsWritten()->getPointeeCXXRecordDecl();
6167 assert(
C &&
"dynamic_cast target is not void pointer nor class");
6168 CanQualType CQT = Info.Ctx.getCanonicalType(Info.Ctx.getRecordType(
C));
6175 Ptr.setNull(Info.Ctx,
E->
getType());
6182 DynType->Type->isDerivedFrom(
C)))
6184 else if (!Paths || Paths->begin() == Paths->end())
6186 else if (Paths->isAmbiguous(CQT))
6189 assert(Paths->front().Access !=
AS_public &&
"why did the cast fail?");
6192 Info.FFDiag(
E, diag::note_constexpr_dynamic_cast_to_reference_failed)
6193 << DiagKind << Ptr.Designator.getType(Info.Ctx)
6194 << Info.Ctx.getRecordType(DynType->Type)
6202 for (
int PathLength = Ptr.Designator.Entries.size();
6203 PathLength >= (
int)DynType->PathLength; --PathLength) {
6208 if (PathLength > (
int)DynType->PathLength &&
6211 return RuntimeCheckFailed(
nullptr);
6218 if (DynType->Type->isDerivedFrom(
C, Paths) && !Paths.isAmbiguous(CQT) &&
6231 return RuntimeCheckFailed(&Paths);
6235struct StartLifetimeOfUnionMemberHandler {
6237 const Expr *LHSExpr;
6240 bool Failed =
false;
6243 typedef bool result_type;
6244 bool failed() {
return Failed; }
6260 }
else if (DuringInit) {
6264 Info.FFDiag(LHSExpr,
6265 diag::note_constexpr_union_member_change_during_init);
6274 llvm_unreachable(
"wrong value kind for union object");
6277 llvm_unreachable(
"wrong value kind for union object");
6282const AccessKinds StartLifetimeOfUnionMemberHandler::AccessKind;
6289 const Expr *LHSExpr,
6290 const LValue &LHS) {
6291 if (LHS.InvalidBase || LHS.Designator.Invalid)
6297 unsigned PathLength = LHS.Designator.Entries.size();
6298 for (
const Expr *
E = LHSExpr;
E !=
nullptr;) {
6300 if (
auto *ME = dyn_cast<MemberExpr>(
E)) {
6301 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
6304 if (!FD || FD->getType()->isReferenceType())
6308 if (FD->getParent()->isUnion()) {
6313 FD->getType()->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
6314 if (!RD || RD->hasTrivialDefaultConstructor())
6315 UnionPathLengths.push_back({PathLength - 1, FD});
6321 LHS.Designator.Entries[PathLength]
6322 .getAsBaseOrMember().getPointer()));
6326 }
else if (
auto *ASE = dyn_cast<ArraySubscriptExpr>(
E)) {
6328 auto *
Base = ASE->getBase()->IgnoreImplicit();
6329 if (!
Base->getType()->isArrayType())
6335 }
else if (
auto *ICE = dyn_cast<ImplicitCastExpr>(
E)) {
6337 E = ICE->getSubExpr();
6338 if (ICE->getCastKind() == CK_NoOp)
6340 if (ICE->getCastKind() != CK_DerivedToBase &&
6341 ICE->getCastKind() != CK_UncheckedDerivedToBase)
6345 if (Elt->isVirtual()) {
6354 LHS.Designator.Entries[PathLength]
6355 .getAsBaseOrMember().getPointer()));
6365 if (UnionPathLengths.empty())
6370 CompleteObject Obj =
6374 for (std::pair<unsigned, const FieldDecl *> LengthAndField :
6375 llvm::reverse(UnionPathLengths)) {
6377 SubobjectDesignator
D = LHS.Designator;
6378 D.truncate(Info.Ctx, LHS.Base, LengthAndField.first);
6380 bool DuringInit = Info.isEvaluatingCtorDtor(LHS.Base,
D.Entries) ==
6381 ConstructionPhase::AfterBases;
6382 StartLifetimeOfUnionMemberHandler StartLifetime{
6383 Info, LHSExpr, LengthAndField.second, DuringInit};
6392 CallRef
Call, EvalInfo &Info,
6400 APValue &
V = PVD ? Info.CurrentCall->createParam(
Call, PVD, LV)
6401 : Info.CurrentCall->createTemporary(Arg, Arg->
getType(),
6402 ScopeKind::Call, LV);
6408 if (
NonNull &&
V.isLValue() &&
V.isNullPointer()) {
6409 Info.CCEDiag(Arg, diag::note_non_null_attribute_failed);
6419 bool RightToLeft =
false) {
6421 llvm::SmallBitVector ForbiddenNullArgs;
6422 if (Callee->hasAttr<NonNullAttr>()) {
6423 ForbiddenNullArgs.resize(Args.size());
6424 for (
const auto *
Attr : Callee->specific_attrs<NonNullAttr>()) {
6425 if (!
Attr->args_size()) {
6426 ForbiddenNullArgs.set();
6429 for (
auto Idx :
Attr->args()) {
6430 unsigned ASTIdx = Idx.getASTIndex();
6431 if (ASTIdx >= Args.size())
6433 ForbiddenNullArgs[ASTIdx] =
true;
6437 for (
unsigned I = 0; I < Args.size(); I++) {
6438 unsigned Idx = RightToLeft ? Args.size() - I - 1 : I;
6440 Idx < Callee->getNumParams() ? Callee->getParamDecl(Idx) :
nullptr;
6441 bool NonNull = !ForbiddenNullArgs.empty() && ForbiddenNullArgs[Idx];
6445 if (!Info.noteFailure())
6457 bool CopyObjectRepresentation) {
6459 CallStackFrame *Frame = Info.CurrentCall;
6460 APValue *RefValue = Info.getParamSlot(Frame->Arguments, Param);
6468 RefLValue.setFrom(Info.Ctx, *RefValue);
6471 CopyObjectRepresentation);
6478 CallRef
Call,
const Stmt *Body, EvalInfo &Info,
6479 APValue &Result,
const LValue *ResultSlot) {
6480 if (!Info.CheckCallLimit(CallLoc))
6505 This->moveInto(Result);
6514 if (!Info.checkingPotentialConstantExpression())
6516 Frame.LambdaThisCaptureField);
6521 if (ESR == ESR_Succeeded) {
6522 if (Callee->getReturnType()->isVoidType())
6524 Info.FFDiag(Callee->getEndLoc(), diag::note_constexpr_no_return);
6526 return ESR == ESR_Returned;
6533 EvalInfo &Info,
APValue &Result) {
6535 if (!Info.CheckCallLimit(CallLoc))
6540 Info.FFDiag(CallLoc, diag::note_constexpr_virtual_base) << RD;
6544 EvalInfo::EvaluatingConstructorRAII EvalObj(
6546 ObjectUnderConstruction{This.getLValueBase(), This.Designator.Entries},
6558 if ((*I)->getInit()->isValueDependent()) {
6562 FullExpressionRAII InitScope(Info);
6564 !InitScope.destroy())
6587 if (!Result.hasValue()) {
6600 BlockScopeRAII LifetimeExtendedScope(Info);
6603 unsigned BasesSeen = 0;
6613 assert(
Indirect &&
"fields out of order?");
6619 assert(FieldIt != RD->
field_end() &&
"missing field?");
6620 if (!FieldIt->isUnnamedBitField())
6623 Result.getStructField(FieldIt->getFieldIndex()));
6628 LValue Subobject = This;
6629 LValue SubobjectParent = This;
6634 if (I->isBaseInitializer()) {
6635 QualType BaseType(I->getBaseClass(), 0);
6639 assert(!BaseIt->
isVirtual() &&
"virtual base for literal type");
6640 assert(Info.Ctx.hasSameUnqualifiedType(BaseIt->
getType(), BaseType) &&
6641 "base class initializers not in expected order");
6647 Value = &Result.getStructBase(BasesSeen++);
6648 }
else if ((FD = I->getMember())) {
6653 Value = &Result.getUnionValue();
6655 SkipToField(FD,
false);
6661 auto IndirectFieldChain = IFD->chain();
6662 for (
auto *
C : IndirectFieldChain) {
6663 FD = cast<FieldDecl>(
C);
6671 (
Value->isUnion() &&
Value->getUnionField() != FD)) {
6683 if (
C == IndirectFieldChain.back())
6684 SubobjectParent = Subobject;
6690 if (
C == IndirectFieldChain.front() && !RD->
isUnion())
6691 SkipToField(FD,
true);
6696 llvm_unreachable(
"unknown base initializer kind");
6703 if (
Init->isValueDependent()) {
6707 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &SubobjectParent,
6708 isa<CXXDefaultInitExpr>(
Init));
6709 FullExpressionRAII InitScope(Info);
6715 if (!Info.noteFailure())
6723 if (I->isBaseInitializer() && BasesSeen == RD->
getNumBases())
6724 EvalObj.finishedConstructingBases();
6729 for (; FieldIt != RD->
field_end(); ++FieldIt) {
6730 if (!FieldIt->isUnnamedBitField())
6733 Result.getStructField(FieldIt->getFieldIndex()));
6737 EvalObj.finishedConstructingFields();
6741 LifetimeExtendedScope.destroy();
6747 EvalInfo &Info,
APValue &Result) {
6748 CallScopeRAII CallScope(Info);
6754 CallScope.destroy();
6766 This.moveInto(Printable);
6768 diag::note_constexpr_destroy_out_of_lifetime)
6769 << Printable.
getAsString(Info.Ctx, Info.Ctx.getLValueReferenceType(
T));
6785 LValue ElemLV = This;
6786 ElemLV.addArray(Info, &LocE, CAT);
6793 if (Size && Size >
Value.getArrayInitializedElts())
6798 for (Size =
Value.getArraySize(); Size != 0; --Size) {
6799 APValue &Elem =
Value.getArrayInitializedElt(Size - 1);
6812 if (
T.isDestructedType()) {
6814 diag::note_constexpr_unsupported_destruction)
6824 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_virtual_base) << RD;
6849 if (!Info.CheckCallLimit(CallRange.
getBegin()))
6858 CallStackFrame Frame(Info, CallRange,
Definition, &This,
nullptr,
6863 EvalInfo::EvaluatingDestructorRAII EvalObj(
6865 ObjectUnderConstruction{This.getLValueBase(), This.Designator.Entries});
6866 if (!EvalObj.DidInsert) {
6873 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_double_destroy);
6893 for (
const FieldDecl *FD : llvm::reverse(Fields)) {
6894 if (FD->isUnnamedBitField())
6897 LValue Subobject = This;
6901 APValue *SubobjectValue = &
Value.getStructField(FD->getFieldIndex());
6908 EvalObj.startedDestroyingBases();
6915 LValue Subobject = This;
6920 APValue *SubobjectValue = &
Value.getStructBase(BasesLeft);
6925 assert(BasesLeft == 0 &&
"NumBases was wrong?");
6933struct DestroyObjectHandler {
6939 typedef bool result_type;
6940 bool failed() {
return false; }
6946 Info.FFDiag(
E, diag::note_constexpr_destroy_complex_elem);
6950 Info.FFDiag(
E, diag::note_constexpr_destroy_complex_elem);
6959 const LValue &This,
QualType ThisType) {
6961 DestroyObjectHandler Handler = {Info,
E, This,
AK_Destroy};
6962 return Obj &&
findSubobject(Info,
E, Obj, This.Designator, Handler);
6971 if (Info.EvalStatus.HasSideEffects)
6982 if (Info.checkingPotentialConstantExpression() ||
6983 Info.SpeculativeEvaluationDepth)
6987 auto Caller = Info.getStdAllocatorCaller(
"allocate");
6989 Info.FFDiag(
E->
getExprLoc(), Info.getLangOpts().CPlusPlus20
6990 ? diag::note_constexpr_new_untyped
6991 : diag::note_constexpr_new);
6995 QualType ElemType = Caller.ElemType;
6998 diag::note_constexpr_new_not_complete_object_type)
7006 bool IsNothrow =
false;
7007 for (
unsigned I = 1, N =
E->getNumArgs(); I != N; ++I) {
7015 APInt Size, Remainder;
7016 APInt ElemSizeAP(ByteSize.getBitWidth(), ElemSize.
getQuantity());
7017 APInt::udivrem(ByteSize, ElemSizeAP, Size, Remainder);
7018 if (Remainder != 0) {
7020 Info.FFDiag(
E->
getExprLoc(), diag::note_constexpr_operator_new_bad_size)
7021 << ByteSize <<
APSInt(ElemSizeAP,
true) << ElemType;
7025 if (!Info.CheckArraySize(
E->
getBeginLoc(), ByteSize.getActiveBits(),
7026 Size.getZExtValue(), !IsNothrow)) {
7028 Result.setNull(Info.Ctx,
E->
getType());
7034 QualType AllocType = Info.Ctx.getConstantArrayType(
7035 ElemType, Size,
nullptr, ArraySizeModifier::Normal, 0);
7036 APValue *Val = Info.createHeapAlloc(
E, AllocType, Result);
7038 Result.addArray(Info,
E, cast<ConstantArrayType>(AllocType));
7045 return DD->isVirtual();
7052 return DD->isVirtual() ? DD->getOperatorDelete() :
nullptr;
7063 DynAlloc::Kind DeallocKind) {
7064 auto PointerAsString = [&] {
7065 return Pointer.toString(Info.Ctx, Info.Ctx.VoidPtrTy);
7070 Info.FFDiag(
E, diag::note_constexpr_delete_not_heap_alloc)
7071 << PointerAsString();
7074 return std::nullopt;
7077 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
7079 Info.FFDiag(
E, diag::note_constexpr_double_delete);
7080 return std::nullopt;
7083 if (DeallocKind != (*Alloc)->getKind()) {
7085 Info.FFDiag(
E, diag::note_constexpr_new_delete_mismatch)
7086 << DeallocKind << (*Alloc)->getKind() << AllocType;
7088 return std::nullopt;
7091 bool Subobject =
false;
7092 if (DeallocKind == DynAlloc::New) {
7093 Subobject =
Pointer.Designator.MostDerivedPathLength != 0 ||
7094 Pointer.Designator.isOnePastTheEnd();
7096 Subobject =
Pointer.Designator.Entries.size() != 1 ||
7097 Pointer.Designator.Entries[0].getAsArrayIndex() != 0;
7100 Info.FFDiag(
E, diag::note_constexpr_delete_subobject)
7101 << PointerAsString() <<
Pointer.Designator.isOnePastTheEnd();
7102 return std::nullopt;
7110 if (Info.checkingPotentialConstantExpression() ||
7111 Info.SpeculativeEvaluationDepth)
7115 if (!Info.getStdAllocatorCaller(
"deallocate")) {
7123 for (
unsigned I = 1, N =
E->getNumArgs(); I != N; ++I)
7126 if (
Pointer.Designator.Invalid)
7131 if (
Pointer.isNullPointer()) {
7132 Info.CCEDiag(
E->
getExprLoc(), diag::note_constexpr_deallocate_null);
7148class BitCastBuffer {
7156 static_assert(std::numeric_limits<unsigned char>::digits >= 8,
7157 "Need at least 8 bit unsigned char");
7159 bool TargetIsLittleEndian;
7162 BitCastBuffer(
CharUnits Width,
bool TargetIsLittleEndian)
7163 : Bytes(Width.getQuantity()),
7164 TargetIsLittleEndian(TargetIsLittleEndian) {}
7168 for (
CharUnits I = Offset,
E = Offset + Width; I !=
E; ++I) {
7171 if (!Bytes[I.getQuantity()])
7173 Output.push_back(*Bytes[I.getQuantity()]);
7175 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
7176 std::reverse(Output.begin(), Output.end());
7181 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
7182 std::reverse(Input.begin(), Input.end());
7185 for (
unsigned char Byte : Input) {
7186 assert(!Bytes[Offset.getQuantity() + Index] &&
"overwriting a byte?");
7187 Bytes[Offset.getQuantity() + Index] = Byte;
7192 size_t size() {
return Bytes.size(); }
7197class APValueToBufferConverter {
7199 BitCastBuffer Buffer;
7202 APValueToBufferConverter(EvalInfo &Info,
CharUnits ObjectWidth,
7205 Buffer(ObjectWidth, Info.Ctx.getTargetInfo().isLittleEndian()),
7214 assert((
size_t)Offset.getQuantity() <= Buffer.size());
7227 return visitInt(Val.
getInt(), Ty, Offset);
7229 return visitFloat(Val.
getFloat(), Ty, Offset);
7231 return visitArray(Val, Ty, Offset);
7233 return visitRecord(Val, Ty, Offset);
7235 return visitVector(Val, Ty, Offset);
7239 return visitComplex(Val, Ty, Offset);
7247 diag::note_constexpr_bit_cast_unsupported_type)
7253 llvm_unreachable(
"LValue subobject in bit_cast?");
7255 llvm_unreachable(
"Unhandled APValue::ValueKind");
7263 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
7264 for (
size_t I = 0,
E = CXXRD->getNumBases(); I !=
E; ++I) {
7275 unsigned FieldIdx = 0;
7277 if (FD->isBitField()) {
7279 diag::note_constexpr_bit_cast_unsupported_bitfield);
7285 assert(FieldOffsetBits % Info.Ctx.getCharWidth() == 0 &&
7286 "only bit-fields can have sub-char alignment");
7288 Info.Ctx.toCharUnitsFromBits(FieldOffsetBits) + Offset;
7308 for (
unsigned I = 0; I != NumInitializedElts; ++I) {
7310 if (!visit(SubObj, CAT->
getElementType(), Offset + I * ElemWidth))
7317 for (
unsigned I = NumInitializedElts; I != ArraySize; ++I) {
7318 if (!visit(Filler, CAT->
getElementType(), Offset + I * ElemWidth))
7329 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
7334 Offset + (0 * EltSizeChars)))
7337 Offset + (1 * EltSizeChars)))
7341 Offset + (0 * EltSizeChars)))
7344 Offset + (1 * EltSizeChars)))
7365 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
7367 llvm::APInt Res = llvm::APInt::getZero(NElts);
7368 for (
unsigned I = 0; I < NElts; ++I) {
7370 assert(EltAsInt.isUnsigned() && EltAsInt.getBitWidth() == 1 &&
7371 "bool vector element must be 1-bit unsigned integer!");
7373 Res.insertBits(EltAsInt, BigEndian ? (NElts - I - 1) : I);
7377 llvm::StoreIntToMemory(Res, &*Bytes.begin(), NElts / 8);
7378 Buffer.writeObject(Offset, Bytes);
7382 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
7383 for (
unsigned I = 0; I < NElts; ++I) {
7384 if (!visit(Val.
getVectorElt(I), EltTy, Offset + I * EltSizeChars))
7393 APSInt AdjustedVal = Val;
7394 unsigned Width = AdjustedVal.getBitWidth();
7396 Width = Info.Ctx.getTypeSize(Ty);
7397 AdjustedVal = AdjustedVal.extend(Width);
7401 llvm::StoreIntToMemory(AdjustedVal, &*Bytes.begin(), Width / 8);
7402 Buffer.writeObject(Offset, Bytes);
7407 APSInt AsInt(Val.bitcastToAPInt());
7408 return visitInt(AsInt, Ty, Offset);
7412 static std::optional<BitCastBuffer>
7415 APValueToBufferConverter Converter(Info, DstSize, BCE);
7417 return std::nullopt;
7418 return Converter.Buffer;
7423class BufferToAPValueConverter {
7425 const BitCastBuffer &Buffer;
7428 BufferToAPValueConverter(EvalInfo &Info,
const BitCastBuffer &Buffer,
7430 : Info(Info), Buffer(Buffer), BCE(BCE) {}
7435 std::nullopt_t unsupportedType(
QualType Ty) {
7437 diag::note_constexpr_bit_cast_unsupported_type)
7439 return std::nullopt;
7442 std::nullopt_t unrepresentableValue(
QualType Ty,
const APSInt &Val) {
7444 diag::note_constexpr_bit_cast_unrepresentable_value)
7446 return std::nullopt;
7450 const EnumType *EnumSugar =
nullptr) {
7464 const llvm::fltSemantics &Semantics =
7465 Info.Ctx.getFloatTypeSemantics(
QualType(
T, 0));
7466 unsigned NumBits = llvm::APFloatBase::getSizeInBits(Semantics);
7467 assert(NumBits % 8 == 0);
7474 if (!Buffer.readObject(Offset,
SizeOf, Bytes)) {
7477 bool IsStdByte = EnumSugar && EnumSugar->isStdByteType();
7481 if (!IsStdByte && !IsUChar) {
7482 QualType DisplayType(EnumSugar ? (
const Type *)EnumSugar :
T, 0);
7484 diag::note_constexpr_bit_cast_indet_dest)
7485 << DisplayType << Info.Ctx.getLangOpts().CharIsSigned;
7486 return std::nullopt;
7492 APSInt Val(
SizeOf.getQuantity() * Info.Ctx.getCharWidth(),
true);
7493 llvm::LoadIntFromMemory(Val, &*Bytes.begin(), Bytes.size());
7498 unsigned IntWidth = Info.Ctx.getIntWidth(
QualType(
T, 0));
7499 if (IntWidth != Val.getBitWidth()) {
7500 APSInt Truncated = Val.trunc(IntWidth);
7501 if (Truncated.extend(Val.getBitWidth()) != Val)
7502 return unrepresentableValue(
QualType(
T, 0), Val);
7510 const llvm::fltSemantics &Semantics =
7511 Info.Ctx.getFloatTypeSemantics(
QualType(
T, 0));
7522 unsigned NumBases = 0;
7523 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
7524 NumBases = CXXRD->getNumBases();
7530 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
7531 for (
size_t I = 0,
E = CXXRD->getNumBases(); I !=
E; ++I) {
7535 std::optional<APValue> SubObj = visitType(
7538 return std::nullopt;
7539 ResultVal.getStructBase(I) = *SubObj;
7544 unsigned FieldIdx = 0;
7548 if (FD->isBitField()) {
7550 diag::note_constexpr_bit_cast_unsupported_bitfield);
7551 return std::nullopt;
7555 assert(FieldOffsetBits % Info.Ctx.getCharWidth() == 0);
7561 std::optional<APValue> SubObj = visitType(FieldTy, FieldOffset);
7563 return std::nullopt;
7564 ResultVal.getStructField(FieldIdx) = *SubObj;
7573 assert(!RepresentationType.
isNull() &&
7574 "enum forward decl should be caught by Sema");
7575 const auto *AsBuiltin =
7579 return visit(AsBuiltin, Offset, Ty);
7587 for (
size_t I = 0; I !=
Size; ++I) {
7588 std::optional<APValue> ElementValue =
7591 return std::nullopt;
7592 ArrayValue.getArrayInitializedElt(I) = std::move(*ElementValue);
7600 CharUnits ElementWidth = Info.Ctx.getTypeSizeInChars(ElementType);
7603 std::optional<APValue> Values[2];
7604 for (
unsigned I = 0; I != 2; ++I) {
7605 Values[I] = visitType(Ty->
getElementType(), Offset + I * ElementWidth);
7607 return std::nullopt;
7611 return APValue(Values[0]->getInt(), Values[1]->getInt());
7612 return APValue(Values[0]->getFloat(), Values[1]->getFloat());
7622 Elts.reserve(NElts);
7632 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
7635 Bytes.reserve(NElts / 8);
7637 return std::nullopt;
7639 APSInt SValInt(NElts,
true);
7640 llvm::LoadIntFromMemory(SValInt, &*Bytes.begin(), Bytes.size());
7642 for (
unsigned I = 0; I < NElts; ++I) {
7644 SValInt.extractBits(1, (BigEndian ? NElts - I - 1 : I) * EltSize);
7651 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
7652 for (
unsigned I = 0; I < NElts; ++I) {
7653 std::optional<APValue> EltValue =
7654 visitType(EltTy, Offset + I * EltSizeChars);
7656 return std::nullopt;
7657 Elts.push_back(std::move(*EltValue));
7661 return APValue(Elts.data(), Elts.size());
7664 std::optional<APValue> visit(
const Type *Ty,
CharUnits Offset) {
7665 return unsupportedType(
QualType(Ty, 0));
7672#define TYPE(Class, Base) \
7674 return visit(cast<Class##Type>(Can.getTypePtr()), Offset);
7675#define ABSTRACT_TYPE(Class, Base)
7676#define NON_CANONICAL_TYPE(Class, Base) \
7678 llvm_unreachable("non-canonical type should be impossible!");
7679#define DEPENDENT_TYPE(Class, Base) \
7682 "dependent types aren't supported in the constant evaluator!");
7683#define NON_CANONICAL_UNLESS_DEPENDENT(Class, Base) \
7685 llvm_unreachable("either dependent or not canonical!");
7686#include "clang/AST/TypeNodes.inc"
7688 llvm_unreachable(
"Unhandled Type::TypeClass");
7693 static std::optional<APValue> convert(EvalInfo &Info, BitCastBuffer &Buffer,
7695 BufferToAPValueConverter Converter(Info, Buffer, BCE);
7703 bool CheckingDest) {
7706 auto diag = [&](
int Reason) {
7708 Info->FFDiag(
Loc, diag::note_constexpr_bit_cast_invalid_type)
7709 << CheckingDest << (Reason == 4) << Reason;
7714 Info->
Note(NoteLoc, diag::note_constexpr_bit_cast_invalid_subtype)
7715 << NoteTy << Construct << Ty;
7729 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(
Record)) {
7731 if (!checkBitCastConstexprEligibilityType(
Loc, BS.
getType(), Info, Ctx,
7736 if (FD->getType()->isReferenceType())
7738 if (!checkBitCastConstexprEligibilityType(
Loc, FD->getType(), Info, Ctx,
7740 return note(0, FD->getType(), FD->getBeginLoc());
7746 Info, Ctx, CheckingDest))
7759 Info->FFDiag(
Loc, diag::note_constexpr_bit_cast_invalid_vector)
7769 Info->FFDiag(
Loc, diag::note_constexpr_bit_cast_unsupported_type)
7778static bool checkBitCastConstexprEligibility(EvalInfo *Info,
7781 bool DestOK = checkBitCastConstexprEligibilityType(
7783 bool SourceOK = DestOK && checkBitCastConstexprEligibilityType(
7789static bool handleRValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
7792 assert(
CHAR_BIT == 8 && Info.Ctx.getTargetInfo().getCharWidth() == 8 &&
7793 "no host or target supports non 8-bit chars");
7795 if (!checkBitCastConstexprEligibility(&Info, Info.Ctx, BCE))
7799 std::optional<BitCastBuffer> Buffer =
7800 APValueToBufferConverter::convert(Info, SourceRValue, BCE);
7805 std::optional<APValue> MaybeDestValue =
7806 BufferToAPValueConverter::convert(Info, *Buffer, BCE);
7807 if (!MaybeDestValue)
7810 DestValue = std::move(*MaybeDestValue);
7814static bool handleLValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
7817 assert(
CHAR_BIT == 8 && Info.Ctx.getTargetInfo().getCharWidth() == 8 &&
7818 "no host or target supports non 8-bit chars");
7820 "LValueToRValueBitcast requires an lvalue operand!");
7822 LValue SourceLValue;
7824 SourceLValue.setFrom(Info.Ctx, SourceValue);
7827 SourceRValue,
true))
7830 return handleRValueToRValueBitCast(Info, DestValue, SourceRValue, BCE);
7833template <
class Derived>
7834class ExprEvaluatorBase
7837 Derived &getDerived() {
return static_cast<Derived&
>(*this); }
7839 return getDerived().Success(
V,
E);
7841 bool DerivedZeroInitialization(
const Expr *
E) {
7842 return getDerived().ZeroInitialization(
E);
7848 template<
typename ConditionalOperator>
7850 assert(Info.checkingPotentialConstantExpression());
7855 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
7856 StmtVisitorTy::Visit(
E->getFalseExpr());
7862 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
7864 StmtVisitorTy::Visit(
E->getTrueExpr());
7869 Error(
E, diag::note_constexpr_conditional_never_const);
7873 template<
typename ConditionalOperator>
7877 if (Info.checkingPotentialConstantExpression() && Info.noteFailure()) {
7878 CheckPotentialConstantConditional(
E);
7881 if (Info.noteFailure()) {
7882 StmtVisitorTy::Visit(
E->getTrueExpr());
7883 StmtVisitorTy::Visit(
E->getFalseExpr());
7888 Expr *EvalExpr = BoolResult ?
E->getTrueExpr() :
E->getFalseExpr();
7889 return StmtVisitorTy::Visit(EvalExpr);
7895 typedef ExprEvaluatorBase ExprEvaluatorBaseTy;
7898 return Info.CCEDiag(
E,
D);
7901 bool ZeroInitialization(
const Expr *
E) {
return Error(
E); }
7903 bool IsConstantEvaluatedBuiltinCall(
const CallExpr *
E) {
7904 unsigned BuiltinOp =
E->getBuiltinCallee();
7905 return BuiltinOp != 0 &&
7906 Info.Ctx.BuiltinInfo.isConstantEvaluated(BuiltinOp);
7910 ExprEvaluatorBase(EvalInfo &Info) : Info(Info) {}
7912 EvalInfo &getEvalInfo() {
return Info; }
7921 return Error(
E, diag::note_invalid_subexpr_in_const_expr);
7924 bool VisitStmt(
const Stmt *) {
7925 llvm_unreachable(
"Expression evaluator should not be called on stmts");
7927 bool VisitExpr(
const Expr *
E) {
7932 const auto It =
E->begin();
7933 return StmtVisitorTy::Visit(*It);
7937 return StmtVisitorTy::Visit(
E->getFunctionName());
7940 if (
E->hasAPValueResult())
7941 return DerivedSuccess(
E->getAPValueResult(),
E);
7943 return StmtVisitorTy::Visit(
E->getSubExpr());
7947 {
return StmtVisitorTy::Visit(
E->getSubExpr()); }
7949 {
return StmtVisitorTy::Visit(
E->getSubExpr()); }
7951 {
return StmtVisitorTy::Visit(
E->getSubExpr()); }
7953 {
return StmtVisitorTy::Visit(
E->getChosenSubExpr()); }
7955 {
return StmtVisitorTy::Visit(
E->getResultExpr()); }
7957 {
return StmtVisitorTy::Visit(
E->getReplacement()); }
7959 TempVersionRAII RAII(*Info.CurrentCall);
7960 SourceLocExprScopeGuard Guard(
E, Info.CurrentCall->CurSourceLocExprScope);
7961 return StmtVisitorTy::Visit(
E->getExpr());
7964 TempVersionRAII RAII(*Info.CurrentCall);
7968 SourceLocExprScopeGuard Guard(
E, Info.CurrentCall->CurSourceLocExprScope);
7969 return StmtVisitorTy::Visit(
E->getExpr());
7973 FullExpressionRAII
Scope(Info);
7974 return StmtVisitorTy::Visit(
E->getSubExpr()) &&
Scope.destroy();
7980 return StmtVisitorTy::Visit(
E->getSubExpr());
7984 CCEDiag(
E, diag::note_constexpr_invalid_cast) << 0;
7985 return static_cast<Derived*
>(
this)->VisitCastExpr(
E);
7988 if (!Info.Ctx.getLangOpts().CPlusPlus20)
7989 CCEDiag(
E, diag::note_constexpr_invalid_cast) << 1;
7990 return static_cast<Derived*
>(
this)->VisitCastExpr(
E);
7993 return static_cast<Derived*
>(
this)->VisitCastExpr(
E);
7997 switch (
E->getOpcode()) {
8002 VisitIgnoredValue(
E->getLHS());
8003 return StmtVisitorTy::Visit(
E->getRHS());
8013 return DerivedSuccess(Result,
E);
8019 return StmtVisitorTy::Visit(
E->getSemanticForm());
8026 if (!
Evaluate(Info.CurrentCall->createTemporary(
8027 E->getOpaqueValue(),
8028 getStorageType(Info.Ctx,
E->getOpaqueValue()),
8029 ScopeKind::FullExpression, CommonLV),
8030 Info,
E->getCommon()))
8033 return HandleConditionalOperator(
E);
8037 bool IsBcpCall =
false;
8044 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
8051 if (Info.checkingPotentialConstantExpression() && IsBcpCall)
8054 FoldConstant Fold(Info, IsBcpCall);
8055 if (!HandleConditionalOperator(
E)) {
8056 Fold.keepDiagnostics();
8064 if (
APValue *
Value = Info.CurrentCall->getCurrentTemporary(
E);
8066 return DerivedSuccess(*
Value,
E);
8068 const Expr *Source =
E->getSourceExpr();
8072 assert(0 &&
"OpaqueValueExpr recursively refers to itself");
8075 return StmtVisitorTy::Visit(Source);
8079 for (
const Expr *SemE :
E->semantics()) {
8080 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
8084 if (SemE ==
E->getResultExpr())
8089 if (OVE->isUnique())
8093 if (!
Evaluate(Info.CurrentCall->createTemporary(
8094 OVE, getStorageType(Info.Ctx, OVE),
8095 ScopeKind::FullExpression, LV),
8096 Info, OVE->getSourceExpr()))
8098 }
else if (SemE ==
E->getResultExpr()) {
8099 if (!StmtVisitorTy::Visit(SemE))
8111 if (!handleCallExpr(
E, Result,
nullptr))
8113 return DerivedSuccess(Result,
E);
8117 const LValue *ResultSlot) {
8118 CallScopeRAII CallScope(Info);
8124 LValue *
This =
nullptr, ThisVal;
8126 bool HasQualifier =
false;
8133 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(Callee)) {
8137 Member = dyn_cast<CXXMethodDecl>(ME->getMemberDecl());
8139 return Error(Callee);
8141 HasQualifier = ME->hasQualifier();
8142 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(Callee)) {
8148 Member = dyn_cast<CXXMethodDecl>(
D);
8150 return Error(Callee);
8152 }
else if (
const auto *PDE = dyn_cast<CXXPseudoDestructorExpr>(Callee)) {
8153 if (!Info.getLangOpts().CPlusPlus20)
8154 Info.CCEDiag(PDE, diag::note_constexpr_pseudo_destructor);
8158 return Error(Callee);
8165 if (!CalleeLV.getLValueOffset().isZero())
8166 return Error(Callee);
8167 if (CalleeLV.isNullPointer()) {
8168 Info.FFDiag(Callee, diag::note_constexpr_null_callee)
8172 FD = dyn_cast_or_null<FunctionDecl>(
8173 CalleeLV.getLValueBase().dyn_cast<
const ValueDecl *>());
8175 return Error(Callee);
8178 if (!Info.Ctx.hasSameFunctionTypeIgnoringExceptionSpec(
8185 auto *OCE = dyn_cast<CXXOperatorCallExpr>(
E);
8186 if (OCE && OCE->isAssignmentOp()) {
8187 assert(Args.size() == 2 &&
"wrong number of arguments in assignment");
8188 Call = Info.CurrentCall->createCall(FD);
8189 bool HasThis =
false;
8190 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FD))
8191 HasThis = MD->isImplicitObjectMemberFunction();
8219 if (Info.getLangOpts().CPlusPlus20 && OCE &&
8220 OCE->getOperator() == OO_Equal && MD->
isTrivial() &&
8224 Args = Args.slice(1);
8233 "Number of captures must be zero for conversion to function-ptr");
8244 "A generic lambda's static-invoker function must be a "
8245 "template specialization");
8249 void *InsertPos =
nullptr;
8252 assert(CorrespondingCallOpSpecialization &&
8253 "We must always have a function call operator specialization "
8254 "that corresponds to our static invoker specialization");
8255 assert(isa<CXXMethodDecl>(CorrespondingCallOpSpecialization));
8256 FD = CorrespondingCallOpSpecialization;
8265 Ptr.moveInto(Result);
8266 return CallScope.destroy();
8276 Call = Info.CurrentCall->createCall(FD);
8283 auto *NamedMember = dyn_cast<CXXMethodDecl>(FD);
8284 if (NamedMember && NamedMember->isVirtual() && !HasQualifier) {
8287 CovariantAdjustmentPath);
8290 }
else if (NamedMember && NamedMember->isImplicitObjectMemberFunction()) {
8300 if (
auto *DD = dyn_cast<CXXDestructorDecl>(FD)) {
8301 assert(This &&
"no 'this' pointer for destructor call");
8303 Info.Ctx.getRecordType(DD->getParent())) &&
8304 CallScope.destroy();
8312 Body, Info, Result, ResultSlot))
8315 if (!CovariantAdjustmentPath.empty() &&
8317 CovariantAdjustmentPath))
8320 return CallScope.destroy();
8324 return StmtVisitorTy::Visit(
E->getInitializer());
8327 if (
E->getNumInits() == 0)
8328 return DerivedZeroInitialization(
E);
8329 if (
E->getNumInits() == 1)
8330 return StmtVisitorTy::Visit(
E->getInit(0));
8334 return DerivedZeroInitialization(
E);
8337 return DerivedZeroInitialization(
E);
8340 return DerivedZeroInitialization(
E);
8345 assert(!Info.Ctx.getLangOpts().CPlusPlus11 &&
8346 "missing temporary materialization conversion");
8347 assert(!
E->isArrow() &&
"missing call to bound member function?");
8355 const FieldDecl *FD = dyn_cast<FieldDecl>(
E->getMemberDecl());
8356 if (!FD)
return Error(
E);
8370 DerivedSuccess(Result,
E);
8380 E->getEncodedElementAccess(Indices);
8381 if (Indices.size() == 1) {
8387 for (
unsigned I = 0; I < Indices.size(); ++I) {
8390 APValue VecResult(Elts.data(), Indices.size());
8391 return DerivedSuccess(VecResult,
E);
8399 switch (
E->getCastKind()) {
8403 case CK_AtomicToNonAtomic: {
8408 if (!
Evaluate(AtomicVal, Info,
E->getSubExpr()))
8410 return DerivedSuccess(AtomicVal,
E);
8414 case CK_UserDefinedConversion:
8415 return StmtVisitorTy::Visit(
E->getSubExpr());
8417 case CK_LValueToRValue: {
8426 return DerivedSuccess(RVal,
E);
8428 case CK_LValueToRValueBitCast: {
8429 APValue DestValue, SourceValue;
8430 if (!
Evaluate(SourceValue, Info,
E->getSubExpr()))
8432 if (!handleLValueToRValueBitCast(Info, DestValue, SourceValue,
E))
8434 return DerivedSuccess(DestValue,
E);
8437 case CK_AddressSpaceConversion: {
8441 return DerivedSuccess(
Value,
E);
8449 return VisitUnaryPostIncDec(UO);
8452 return VisitUnaryPostIncDec(UO);
8455 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
8465 return DerivedSuccess(RVal, UO);
8478 BlockScopeRAII
Scope(Info);
8483 const Expr *FinalExpr = dyn_cast<Expr>(*BI);
8485 Info.FFDiag((*BI)->getBeginLoc(),
8486 diag::note_constexpr_stmt_expr_unsupported);
8489 return this->Visit(FinalExpr) &&
Scope.destroy();
8495 if (ESR != ESR_Succeeded) {
8499 if (ESR != ESR_Failed)
8500 Info.FFDiag((*BI)->getBeginLoc(),
8501 diag::note_constexpr_stmt_expr_unsupported);
8506 llvm_unreachable(
"Return from function from the loop above.");
8510 return StmtVisitorTy::Visit(
E->getSelectedExpr());
8514 void VisitIgnoredValue(
const Expr *
E) {
8519 void VisitIgnoredBaseExpression(
const Expr *
E) {
8524 VisitIgnoredValue(
E);
8534template<
class Derived>
8535class LValueExprEvaluatorBase
8536 :
public ExprEvaluatorBase<Derived> {
8540 typedef LValueExprEvaluatorBase LValueExprEvaluatorBaseTy;
8541 typedef ExprEvaluatorBase<Derived> ExprEvaluatorBaseTy;
8548 bool evaluatePointer(
const Expr *
E, LValue &Result) {
8553 LValueExprEvaluatorBase(EvalInfo &Info, LValue &Result,
bool InvalidBaseOK)
8554 : ExprEvaluatorBaseTy(Info), Result(Result),
8555 InvalidBaseOK(InvalidBaseOK) {}
8558 Result.setFrom(this->Info.Ctx,
V);
8567 EvalOK = evaluatePointer(
E->getBase(), Result);
8574 EvalOK = this->Visit(
E->getBase());
8580 Result.setInvalid(
E);
8585 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(
E->getMemberDecl())) {
8608 switch (
E->getOpcode()) {
8610 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
8619 switch (
E->getCastKind()) {
8621 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
8623 case CK_DerivedToBase:
8624 case CK_UncheckedDerivedToBase:
8625 if (!this->Visit(
E->getSubExpr()))
8671class LValueExprEvaluator
8672 :
public LValueExprEvaluatorBase<LValueExprEvaluator> {
8674 LValueExprEvaluator(EvalInfo &Info, LValue &Result,
bool InvalidBaseOK) :
8675 LValueExprEvaluatorBaseTy(Info, Result, InvalidBaseOK) {}
8688 E, 0, Info.getASTContext().getNextStringLiteralVersion()));
8699 return VisitUnaryPreIncDec(UO);
8702 return VisitUnaryPreIncDec(UO);
8708 switch (
E->getCastKind()) {
8710 return LValueExprEvaluatorBaseTy::VisitCastExpr(
E);
8712 case CK_LValueBitCast:
8713 this->CCEDiag(
E, diag::note_constexpr_invalid_cast)
8714 << 2 << Info.Ctx.getLangOpts().CPlusPlus;
8715 if (!Visit(
E->getSubExpr()))
8717 Result.Designator.setInvalid();
8720 case CK_BaseToDerived:
8721 if (!Visit(
E->getSubExpr()))
8726 if (!Visit(
E->getSubExpr()))
8737 bool LValueToRValueConversion) {
8741 assert(Info.CurrentCall->This ==
nullptr &&
8742 "This should not be set for a static call operator");
8750 if (Self->getType()->isReferenceType()) {
8751 APValue *RefValue = Info.getParamSlot(Info.CurrentCall->Arguments, Self);
8752 Result.setFrom(Info.Ctx, *RefValue);
8754 const ParmVarDecl *VD = Info.CurrentCall->Arguments.getOrigParam(Self);
8755 CallStackFrame *Frame =
8756 Info.getCallFrameAndDepth(Info.CurrentCall->Arguments.CallIndex)
8758 unsigned Version = Info.CurrentCall->Arguments.Version;
8759 Result.set({VD, Frame->Index, Version});
8762 Result = *Info.CurrentCall->This;
8772 if (LValueToRValueConversion) {
8776 Result.setFrom(Info.Ctx, RVal);
8787 bool InvalidBaseOK) {
8791 return LValueExprEvaluator(Info, Result, InvalidBaseOK).Visit(
E);
8794bool LValueExprEvaluator::VisitDeclRefExpr(
const DeclRefExpr *
E) {
8798 return Success(cast<ValueDecl>(
D));
8799 if (
const VarDecl *VD = dyn_cast<VarDecl>(
D))
8800 return VisitVarDecl(
E, VD);
8802 return Visit(BD->getBinding());
8807bool LValueExprEvaluator::VisitVarDecl(
const Expr *
E,
const VarDecl *VD) {
8814 isa<DeclRefExpr>(
E) &&
8815 cast<DeclRefExpr>(
E)->refersToEnclosingVariableOrCapture()) {
8820 if (Info.checkingPotentialConstantExpression())
8823 if (
auto *FD = Info.CurrentCall->LambdaCaptureFields.lookup(VD)) {
8824 const auto *MD = cast<CXXMethodDecl>(Info.CurrentCall->Callee);
8830 CallStackFrame *Frame =
nullptr;
8831 unsigned Version = 0;
8839 CallStackFrame *CurrFrame = Info.CurrentCall;
8840 if (CurrFrame->Callee && CurrFrame->Callee->Equals(VD->
getDeclContext())) {
8844 if (
auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
8845 if (CurrFrame->Arguments) {
8846 VD = CurrFrame->Arguments.getOrigParam(PVD);
8848 Info.getCallFrameAndDepth(CurrFrame->Arguments.CallIndex).first;
8849 Version = CurrFrame->Arguments.Version;
8853 Version = CurrFrame->getCurrentTemporaryVersion(VD);
8860 Result.set({VD, Frame->Index, Version});
8866 if (!Info.getLangOpts().CPlusPlus11) {
8867 Info.CCEDiag(
E, diag::note_constexpr_ltor_non_integral, 1)
8869 Info.Note(VD->
getLocation(), diag::note_declared_at);
8875 if (!
V->hasValue()) {
8878 if (!Info.checkingPotentialConstantExpression())
8879 Info.FFDiag(
E, diag::note_constexpr_use_uninit_reference);
8885bool LValueExprEvaluator::VisitCallExpr(
const CallExpr *
E) {
8886 if (!IsConstantEvaluatedBuiltinCall(
E))
8887 return ExprEvaluatorBaseTy::VisitCallExpr(
E);
8889 switch (
E->getBuiltinCallee()) {
8892 case Builtin::BIas_const:
8893 case Builtin::BIforward:
8894 case Builtin::BIforward_like:
8895 case Builtin::BImove:
8896 case Builtin::BImove_if_noexcept:
8897 if (cast<FunctionDecl>(
E->getCalleeDecl())->isConstexpr())
8898 return Visit(
E->getArg(0));
8902 return ExprEvaluatorBaseTy::VisitCallExpr(
E);
8905bool LValueExprEvaluator::VisitMaterializeTemporaryExpr(
8914 for (
const Expr *
E : CommaLHSs)
8923 if (Info.EvalMode == EvalInfo::EM_ConstantFold)
8926 Value =
E->getOrCreateValue(
true);
8930 Value = &Info.CurrentCall->createTemporary(
8931 E, Inner->getType(),
8946 for (
unsigned I = Adjustments.size(); I != 0; ) {
8948 switch (Adjustments[I].Kind) {
8953 Type = Adjustments[I].DerivedToBase.BasePath->getType();
8959 Type = Adjustments[I].Field->getType();
8964 Adjustments[I].Ptr.RHS))
8966 Type = Adjustments[I].Ptr.MPT->getPointeeType();
8976 assert((!Info.getLangOpts().CPlusPlus ||
E->isFileScope()) &&
8977 "lvalue compound literal in c++?");
8983bool LValueExprEvaluator::VisitCXXTypeidExpr(
const CXXTypeidExpr *
E) {
8986 if (!
E->isPotentiallyEvaluated()) {
8987 if (
E->isTypeOperand())
8992 if (!Info.Ctx.getLangOpts().CPlusPlus20) {
8993 Info.CCEDiag(
E, diag::note_constexpr_typeid_polymorphic)
8998 if (!Visit(
E->getExprOperand()))
9001 std::optional<DynamicType> DynType =
9007 TypeInfoLValue(Info.Ctx.getRecordType(DynType->Type).getTypePtr());
9013bool LValueExprEvaluator::VisitCXXUuidofExpr(
const CXXUuidofExpr *
E) {
9017bool LValueExprEvaluator::VisitMemberExpr(
const MemberExpr *
E) {
9019 if (
const VarDecl *VD = dyn_cast<VarDecl>(
E->getMemberDecl())) {
9020 VisitIgnoredBaseExpression(
E->getBase());
9021 return VisitVarDecl(
E, VD);
9025 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(
E->getMemberDecl())) {
9026 if (MD->isStatic()) {
9027 VisitIgnoredBaseExpression(
E->getBase());
9033 return LValueExprEvaluatorBaseTy::VisitMemberExpr(
E);
9036bool LValueExprEvaluator::VisitExtVectorElementExpr(
9041 if (!
Evaluate(Val, Info,
E->getBase())) {
9042 if (!Info.noteFailure())
9048 E->getEncodedElementAccess(Indices);
9050 if (Indices.size() > 1)
9054 Result.setFrom(Info.Ctx, Val);
9057 VT->getNumElements(), Indices[0]);
9072 if (!
Evaluate(Val, Info,
E->getBase())) {
9073 if (!Info.noteFailure())
9079 if (!Info.noteFailure())
9085 Result.setFrom(Info.Ctx, Val);
9087 VT->getNumElements(), Index.getExtValue());
9095 for (
const Expr *SubExpr : {
E->getLHS(),
E->getRHS()}) {
9096 if (SubExpr ==
E->getBase() ? !evaluatePointer(SubExpr, Result)
9098 if (!Info.noteFailure())
9108bool LValueExprEvaluator::VisitUnaryDeref(
const UnaryOperator *
E) {
9109 return evaluatePointer(
E->getSubExpr(), Result);
9112bool LValueExprEvaluator::VisitUnaryReal(
const UnaryOperator *
E) {
9113 if (!Visit(
E->getSubExpr()))
9121bool LValueExprEvaluator::VisitUnaryImag(
const UnaryOperator *
E) {
9123 "lvalue __imag__ on scalar?");
9124 if (!Visit(
E->getSubExpr()))
9130bool LValueExprEvaluator::VisitUnaryPreIncDec(
const UnaryOperator *UO) {
9131 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9142bool LValueExprEvaluator::VisitCompoundAssignOperator(
9144 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9152 if (!Info.noteFailure())
9168 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9175 if (!
Evaluate(NewVal, this->Info,
E->getRHS())) {
9176 if (!Info.noteFailure())
9181 if (!this->Visit(
E->getLHS()) || !
Success)
9184 if (Info.getLangOpts().CPlusPlus20 &&
9204 llvm::APInt &Result) {
9205 const AllocSizeAttr *AllocSize = getAllocSizeAttr(
Call);
9207 assert(AllocSize && AllocSize->getElemSizeParam().isValid());
9208 unsigned SizeArgNo = AllocSize->getElemSizeParam().getASTIndex();
9210 if (
Call->getNumArgs() <= SizeArgNo)
9213 auto EvaluateAsSizeT = [&](
const Expr *
E,
APSInt &Into) {
9218 if (Into.isNegative() || !Into.isIntN(BitsInSizeT))
9220 Into = Into.zext(BitsInSizeT);
9225 if (!EvaluateAsSizeT(
Call->getArg(SizeArgNo), SizeOfElem))
9228 if (!AllocSize->getNumElemsParam().isValid()) {
9229 Result = std::move(SizeOfElem);
9234 unsigned NumArgNo = AllocSize->getNumElemsParam().getASTIndex();
9235 if (!EvaluateAsSizeT(
Call->getArg(NumArgNo), NumberOfElems))
9239 llvm::APInt BytesAvailable = SizeOfElem.umul_ov(NumberOfElems, Overflow);
9243 Result = std::move(BytesAvailable);
9251 llvm::APInt &Result) {
9252 assert(isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
9253 "Can't get the size of a non alloc_size function");
9254 const auto *
Base = LVal.getLValueBase().get<
const Expr *>();
9274 dyn_cast_or_null<VarDecl>(
Base.dyn_cast<
const ValueDecl *>());
9279 if (!
Init ||
Init->getType().isNull())
9283 if (!tryUnwrapAllocSizeCall(
E))
9288 Result.setInvalid(
E);
9291 Result.addUnsizedArray(Info,
E, Pointee);
9296class PointerExprEvaluator
9297 :
public ExprEvaluatorBase<PointerExprEvaluator> {
9306 bool evaluateLValue(
const Expr *
E, LValue &Result) {
9310 bool evaluatePointer(
const Expr *
E, LValue &Result) {
9314 bool visitNonBuiltinCallExpr(
const CallExpr *
E);
9317 PointerExprEvaluator(EvalInfo &info, LValue &Result,
bool InvalidBaseOK)
9318 : ExprEvaluatorBaseTy(info), Result(Result),
9319 InvalidBaseOK(InvalidBaseOK) {}
9322 Result.setFrom(Info.Ctx,
V);
9325 bool ZeroInitialization(
const Expr *
E) {
9326 Result.setNull(Info.Ctx,
E->
getType());
9336 if (
E->isExpressibleAsConstantInitializer())
9338 if (Info.noteFailure())
9345 bool VisitBuiltinCallExpr(
const CallExpr *
E,
unsigned BuiltinOp);
9347 if (!
E->getBlockDecl()->hasCaptures())
9352 auto DiagnoseInvalidUseOfThis = [&] {
9353 if (Info.getLangOpts().CPlusPlus11)
9354 Info.FFDiag(
E, diag::note_constexpr_this) <<
E->isImplicit();
9360 if (Info.checkingPotentialConstantExpression())
9363 bool IsExplicitLambda =
9365 if (!IsExplicitLambda) {
9366 if (!Info.CurrentCall->This) {
9367 DiagnoseInvalidUseOfThis();
9371 Result = *Info.CurrentCall->This;
9379 if (!Info.CurrentCall->LambdaThisCaptureField) {
9380 if (IsExplicitLambda && !Info.CurrentCall->This) {
9381 DiagnoseInvalidUseOfThis();
9388 const auto *MD = cast<CXXMethodDecl>(Info.CurrentCall->Callee);
9390 Info,
E, Result, MD, Info.CurrentCall->LambdaThisCaptureField,
9399 assert(!
E->isIntType() &&
"SourceLocExpr isn't a pointer type?");
9400 APValue LValResult =
E->EvaluateInContext(
9401 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.getDefaultExpr());
9402 Result.setFrom(Info.Ctx, LValResult);
9407 llvm::report_fatal_error(
"Not yet implemented for ExprConstant.cpp");
9412 std::string ResultStr =
E->ComputeName(Info.Ctx);
9415 APInt Size(Info.Ctx.getTypeSize(Info.Ctx.getSizeType()),
9416 ResultStr.size() + 1);
9417 QualType ArrayTy = Info.Ctx.getConstantArrayType(
9418 CharTy, Size,
nullptr, ArraySizeModifier::Normal, 0);
9422 false, ArrayTy,
E->getLocation());
9424 evaluateLValue(SL, Result);
9425 Result.addArray(Info,
E, cast<ConstantArrayType>(ArrayTy));
9434 bool InvalidBaseOK) {
9437 return PointerExprEvaluator(Info, Result, InvalidBaseOK).Visit(
E);
9440bool PointerExprEvaluator::VisitBinaryOperator(
const BinaryOperator *
E) {
9441 if (
E->getOpcode() != BO_Add &&
9442 E->getOpcode() != BO_Sub)
9443 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
9445 const Expr *PExp =
E->getLHS();
9446 const Expr *IExp =
E->getRHS();
9448 std::swap(PExp, IExp);
9450 bool EvalPtrOK = evaluatePointer(PExp, Result);
9451 if (!EvalPtrOK && !Info.noteFailure())
9454 llvm::APSInt Offset;
9458 if (
E->getOpcode() == BO_Sub)
9465bool PointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *
E) {
9466 return evaluateLValue(
E->getSubExpr(), Result);
9474 if (!FnII || !FnII->
isStr(
"current"))
9477 const auto *RD = dyn_cast<RecordDecl>(FD->
getParent());
9485bool PointerExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
9486 const Expr *SubExpr =
E->getSubExpr();
9488 switch (
E->getCastKind()) {
9492 case CK_CPointerToObjCPointerCast:
9493 case CK_BlockPointerToObjCPointerCast:
9494 case CK_AnyPointerToBlockPointerCast:
9495 case CK_AddressSpaceConversion:
9496 if (!Visit(SubExpr))
9504 bool HasValidResult = !Result.InvalidBase && !Result.Designator.Invalid &&
9506 bool VoidPtrCastMaybeOK =
9509 Info.Ctx.hasSimilarType(Result.Designator.getType(Info.Ctx),
9518 if (VoidPtrCastMaybeOK &&
9519 (Info.getStdAllocatorCaller(
"allocate") ||
9521 Info.getLangOpts().CPlusPlus26)) {
9525 Info.getLangOpts().CPlusPlus) {
9527 CCEDiag(
E, diag::note_constexpr_invalid_void_star_cast)
9528 << SubExpr->
getType() << Info.getLangOpts().CPlusPlus26
9529 << Result.Designator.getType(Info.Ctx).getCanonicalType()
9532 CCEDiag(
E, diag::note_constexpr_invalid_cast)
9535 CCEDiag(
E, diag::note_constexpr_invalid_cast)
9536 << 2 << Info.Ctx.getLangOpts().CPlusPlus;
9537 Result.Designator.setInvalid();
9540 if (
E->getCastKind() == CK_AddressSpaceConversion && Result.IsNullPtr)
9541 ZeroInitialization(
E);
9544 case CK_DerivedToBase:
9545 case CK_UncheckedDerivedToBase:
9546 if (!evaluatePointer(
E->getSubExpr(), Result))
9548 if (!Result.Base && Result.Offset.isZero())
9557 case CK_BaseToDerived:
9558 if (!Visit(
E->getSubExpr()))
9560 if (!Result.Base && Result.Offset.isZero())
9565 if (!Visit(
E->getSubExpr()))
9569 case CK_NullToPointer:
9570 VisitIgnoredValue(
E->getSubExpr());
9571 return ZeroInitialization(
E);
9573 case CK_IntegralToPointer: {
9574 CCEDiag(
E, diag::note_constexpr_invalid_cast)
9575 << 2 << Info.Ctx.getLangOpts().CPlusPlus;
9581 if (
Value.isInt()) {
9583 uint64_t N =
Value.getInt().extOrTrunc(Size).getZExtValue();
9584 Result.Base = (
Expr*)
nullptr;
9585 Result.InvalidBase =
false;
9587 Result.Designator.setInvalid();
9588 Result.IsNullPtr =
false;
9595 if (!
Value.isLValue())
9599 Result.setFrom(Info.Ctx,
Value);
9604 case CK_ArrayToPointerDecay: {
9606 if (!evaluateLValue(SubExpr, Result))
9610 SubExpr, SubExpr->
getType(), ScopeKind::FullExpression, Result);
9615 auto *AT = Info.Ctx.getAsArrayType(SubExpr->
getType());
9616 if (
auto *CAT = dyn_cast<ConstantArrayType>(AT))
9617 Result.addArray(Info,
E, CAT);
9619 Result.addUnsizedArray(Info,
E, AT->getElementType());
9623 case CK_FunctionToPointerDecay:
9624 return evaluateLValue(SubExpr, Result);
9626 case CK_LValueToRValue: {
9628 if (!evaluateLValue(
E->getSubExpr(), LVal))
9635 return InvalidBaseOK &&
9641 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
9649 T =
T.getNonReferenceType();
9651 if (
T.getQualifiers().hasUnaligned())
9654 const bool AlignOfReturnsPreferred =
9655 Ctx.
getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver7;
9660 if (ExprKind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
9663 else if (ExprKind == UETT_AlignOf)
9666 llvm_unreachable(
"GetAlignOfType on a non-alignment ExprKind");
9683 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(
E))
9692 return Info.Ctx.getDeclAlign(VD);
9693 if (
const auto *
E =
Value.Base.dyn_cast<
const Expr *>())
9701 EvalInfo &Info,
APSInt &Alignment) {
9704 if (Alignment < 0 || !Alignment.isPowerOf2()) {
9705 Info.FFDiag(
E, diag::note_constexpr_invalid_alignment) << Alignment;
9708 unsigned SrcWidth = Info.Ctx.getIntWidth(ForType);
9709 APSInt MaxValue(APInt::getOneBitSet(SrcWidth, SrcWidth - 1));
9710 if (APSInt::compareValues(Alignment, MaxValue) > 0) {
9711 Info.FFDiag(
E, diag::note_constexpr_alignment_too_big)
9712 << MaxValue << ForType << Alignment;
9718 APSInt(Alignment.zextOrTrunc(SrcWidth),
true);
9719 assert(APSInt::compareValues(Alignment, ExtAlignment) == 0 &&
9720 "Alignment should not be changed by ext/trunc");
9721 Alignment = ExtAlignment;
9722 assert(Alignment.getBitWidth() == SrcWidth);
9727bool PointerExprEvaluator::visitNonBuiltinCallExpr(
const CallExpr *
E) {
9728 if (ExprEvaluatorBaseTy::VisitCallExpr(
E))
9731 if (!(InvalidBaseOK && getAllocSizeAttr(
E)))
9734 Result.setInvalid(
E);
9736 Result.addUnsizedArray(Info,
E, PointeeTy);
9740bool PointerExprEvaluator::VisitCallExpr(
const CallExpr *
E) {
9741 if (!IsConstantEvaluatedBuiltinCall(
E))
9742 return visitNonBuiltinCallExpr(
E);
9743 return VisitBuiltinCallExpr(
E,
E->getBuiltinCallee());
9752bool PointerExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *
E,
9753 unsigned BuiltinOp) {
9757 switch (BuiltinOp) {
9758 case Builtin::BIaddressof:
9759 case Builtin::BI__addressof:
9760 case Builtin::BI__builtin_addressof:
9761 return evaluateLValue(
E->getArg(0), Result);
9762 case Builtin::BI__builtin_assume_aligned: {
9766 if (!evaluatePointer(
E->getArg(0), Result))
9769 LValue OffsetResult(Result);
9776 if (
E->getNumArgs() > 2) {
9781 int64_t AdditionalOffset = -Offset.getZExtValue();
9786 if (OffsetResult.Base) {
9789 if (BaseAlignment < Align) {
9790 Result.Designator.setInvalid();
9791 CCEDiag(
E->getArg(0), diag::note_constexpr_baa_insufficient_alignment)
9798 if (OffsetResult.Offset.alignTo(Align) != OffsetResult.Offset) {
9799 Result.Designator.setInvalid();
9802 ? CCEDiag(
E->getArg(0),
9803 diag::note_constexpr_baa_insufficient_alignment)
9805 : CCEDiag(
E->getArg(0),
9806 diag::note_constexpr_baa_value_insufficient_alignment))
9807 << OffsetResult.Offset.getQuantity() << Align.
getQuantity();
9813 case Builtin::BI__builtin_align_up:
9814 case Builtin::BI__builtin_align_down: {
9815 if (!evaluatePointer(
E->getArg(0), Result))
9834 assert(Alignment.getBitWidth() <= 64 &&
9835 "Cannot handle > 64-bit address-space");
9836 uint64_t Alignment64 = Alignment.getZExtValue();
9838 BuiltinOp == Builtin::BI__builtin_align_down
9839 ? llvm::alignDown(Result.Offset.getQuantity(), Alignment64)
9840 : llvm::alignTo(Result.Offset.getQuantity(), Alignment64));
9841 Result.adjustOffset(NewOffset - Result.Offset);
9846 Info.FFDiag(
E->getArg(0), diag::note_constexpr_alignment_adjust)
9850 case Builtin::BI__builtin_operator_new:
9852 case Builtin::BI__builtin_launder:
9853 return evaluatePointer(
E->getArg(0), Result);
9854 case Builtin::BIstrchr:
9855 case Builtin::BIwcschr:
9856 case Builtin::BImemchr:
9857 case Builtin::BIwmemchr:
9858 if (Info.getLangOpts().CPlusPlus11)
9859 Info.CCEDiag(
E, diag::note_constexpr_invalid_function)
9861 << (
"'" + Info.Ctx.BuiltinInfo.getName(BuiltinOp) +
"'").str();
9863 Info.CCEDiag(
E, diag::note_invalid_subexpr_in_const_expr);
9865 case Builtin::BI__builtin_strchr:
9866 case Builtin::BI__builtin_wcschr:
9867 case Builtin::BI__builtin_memchr:
9868 case Builtin::BI__builtin_char_memchr:
9869 case Builtin::BI__builtin_wmemchr: {
9870 if (!Visit(
E->getArg(0)))
9876 if (BuiltinOp != Builtin::BIstrchr &&
9877 BuiltinOp != Builtin::BIwcschr &&
9878 BuiltinOp != Builtin::BI__builtin_strchr &&
9879 BuiltinOp != Builtin::BI__builtin_wcschr) {
9883 MaxLength = N.getZExtValue();
9886 if (MaxLength == 0u)
9887 return ZeroInitialization(
E);
9888 if (!Result.checkNullPointerForFoldAccess(Info,
E,
AK_Read) ||
9889 Result.Designator.Invalid)
9891 QualType CharTy = Result.Designator.getType(Info.Ctx);
9892 bool IsRawByte = BuiltinOp == Builtin::BImemchr ||
9893 BuiltinOp == Builtin::BI__builtin_memchr;
9895 Info.Ctx.hasSameUnqualifiedType(
9899 Info.FFDiag(
E, diag::note_constexpr_ltor_incomplete_type) << CharTy;
9905 Info.FFDiag(
E, diag::note_constexpr_memchr_unsupported)
9906 << (
"'" + Info.Ctx.BuiltinInfo.getName(BuiltinOp) +
"'").str()
9913 bool StopAtNull =
false;
9914 switch (BuiltinOp) {
9915 case Builtin::BIstrchr:
9916 case Builtin::BI__builtin_strchr:
9923 return ZeroInitialization(
E);
9926 case Builtin::BImemchr:
9927 case Builtin::BI__builtin_memchr:
9928 case Builtin::BI__builtin_char_memchr:
9932 DesiredVal = Desired.trunc(Info.Ctx.getCharWidth()).getZExtValue();
9935 case Builtin::BIwcschr:
9936 case Builtin::BI__builtin_wcschr:
9939 case Builtin::BIwmemchr:
9940 case Builtin::BI__builtin_wmemchr:
9942 DesiredVal = Desired.getZExtValue();
9946 for (; MaxLength; --MaxLength) {
9951 if (Char.
getInt().getZExtValue() == DesiredVal)
9953 if (StopAtNull && !Char.
getInt())
9959 return ZeroInitialization(
E);
9962 case Builtin::BImemcpy:
9963 case Builtin::BImemmove:
9964 case Builtin::BIwmemcpy:
9965 case Builtin::BIwmemmove:
9966 if (Info.getLangOpts().CPlusPlus11)
9967 Info.CCEDiag(
E, diag::note_constexpr_invalid_function)
9969 << (
"'" + Info.Ctx.BuiltinInfo.getName(BuiltinOp) +
"'").str();
9971 Info.CCEDiag(
E, diag::note_invalid_subexpr_in_const_expr);
9973 case Builtin::BI__builtin_memcpy:
9974 case Builtin::BI__builtin_memmove:
9975 case Builtin::BI__builtin_wmemcpy:
9976 case Builtin::BI__builtin_wmemmove: {
9977 bool WChar = BuiltinOp == Builtin::BIwmemcpy ||
9978 BuiltinOp == Builtin::BIwmemmove ||
9979 BuiltinOp == Builtin::BI__builtin_wmemcpy ||
9980 BuiltinOp == Builtin::BI__builtin_wmemmove;
9981 bool Move = BuiltinOp == Builtin::BImemmove ||
9982 BuiltinOp == Builtin::BIwmemmove ||
9983 BuiltinOp == Builtin::BI__builtin_memmove ||
9984 BuiltinOp == Builtin::BI__builtin_wmemmove;
9987 if (!Visit(
E->getArg(0)))
9989 LValue Dest = Result;
9998 assert(!N.isSigned() &&
"memcpy and friends take an unsigned size");
10008 if (!Src.Base || !Dest.Base) {
10010 (!Src.Base ? Src : Dest).moveInto(Val);
10011 Info.FFDiag(
E, diag::note_constexpr_memcpy_null)
10012 <<
Move << WChar << !!Src.Base
10016 if (Src.Designator.Invalid || Dest.Designator.Invalid)
10022 QualType T = Dest.Designator.getType(Info.Ctx);
10023 QualType SrcT = Src.Designator.getType(Info.Ctx);
10024 if (!Info.Ctx.hasSameUnqualifiedType(
T, SrcT)) {
10026 Info.FFDiag(
E, diag::note_constexpr_memcpy_type_pun) <<
Move << SrcT <<
T;
10030 Info.FFDiag(
E, diag::note_constexpr_memcpy_incomplete_type) <<
Move <<
T;
10033 if (!
T.isTriviallyCopyableType(Info.Ctx)) {
10034 Info.FFDiag(
E, diag::note_constexpr_memcpy_nontrivial) <<
Move <<
T;
10039 uint64_t TSize = Info.Ctx.getTypeSizeInChars(
T).getQuantity();
10044 llvm::APInt OrigN = N;
10045 llvm::APInt::udivrem(OrigN, TSize, N, Remainder);
10047 Info.FFDiag(
E, diag::note_constexpr_memcpy_unsupported)
10057 uint64_t RemainingSrcSize = Src.Designator.validIndexAdjustments().second;
10058 uint64_t RemainingDestSize = Dest.Designator.validIndexAdjustments().second;
10059 if (N.ugt(RemainingSrcSize) || N.ugt(RemainingDestSize)) {
10060 Info.FFDiag(
E, diag::note_constexpr_memcpy_unsupported)
10061 <<
Move << WChar << (N.ugt(RemainingSrcSize) ? 1 : 2) <<
T
10065 uint64_t NElems = N.getZExtValue();
10071 uint64_t SrcOffset = Src.getLValueOffset().getQuantity();
10072 uint64_t DestOffset = Dest.getLValueOffset().getQuantity();
10073 if (DestOffset >= SrcOffset && DestOffset - SrcOffset < NBytes) {
10076 Info.FFDiag(
E, diag::note_constexpr_memcpy_overlap) << WChar;
10084 }
else if (!Move && SrcOffset >= DestOffset &&
10085 SrcOffset - DestOffset < NBytes) {
10087 Info.FFDiag(
E, diag::note_constexpr_memcpy_overlap) << WChar;
10122bool PointerExprEvaluator::VisitCXXNewExpr(
const CXXNewExpr *
E) {
10123 if (!Info.getLangOpts().CPlusPlus20)
10124 Info.CCEDiag(
E, diag::note_constexpr_new);
10127 if (Info.SpeculativeEvaluationDepth)
10131 QualType AllocType =
E->getAllocatedType();
10134 bool IsNothrow =
false;
10135 bool IsPlacement =
false;
10137 if (
E->getNumPlacementArgs() == 1 &&
10153 }
else if (OperatorNew->isReservedGlobalPlacementOperator()) {
10154 if (Info.CurrentCall->isStdFunction() || Info.getLangOpts().CPlusPlus26 ||
10155 (Info.CurrentCall->CanEvalMSConstexpr &&
10156 OperatorNew->hasAttr<MSConstexprAttr>())) {
10159 if (Result.Designator.Invalid)
10161 TargetType =
E->getPlacementArg(0)->
getType();
10162 IsPlacement =
true;
10164 Info.FFDiag(
E, diag::note_constexpr_new_placement)
10168 }
else if (
E->getNumPlacementArgs()) {
10169 Info.FFDiag(
E, diag::note_constexpr_new_placement)
10172 }
else if (!OperatorNew->isReplaceableGlobalAllocationFunction()) {
10173 Info.FFDiag(
E, diag::note_constexpr_new_non_replaceable)
10174 << isa<CXXMethodDecl>(OperatorNew) << OperatorNew;
10178 const Expr *
Init =
E->getInitializer();
10181 bool ValueInit =
false;
10183 if (std::optional<const Expr *> ArraySize =
E->getArraySize()) {
10184 const Expr *Stripped = *ArraySize;
10185 for (;
auto *ICE = dyn_cast<ImplicitCastExpr>(Stripped);
10186 Stripped = ICE->getSubExpr())
10187 if (ICE->getCastKind() != CK_NoOp &&
10188 ICE->getCastKind() != CK_IntegralCast)
10191 llvm::APSInt ArrayBound;
10199 if (ArrayBound.isSigned() && ArrayBound.isNegative()) {
10201 return ZeroInitialization(
E);
10203 Info.FFDiag(*ArraySize, diag::note_constexpr_new_negative)
10204 << ArrayBound << (*ArraySize)->getSourceRange();
10210 if (!Info.CheckArraySize(ArraySize.value()->getExprLoc(),
10212 Info.Ctx, AllocType, ArrayBound),
10213 ArrayBound.getZExtValue(), !IsNothrow)) {
10215 return ZeroInitialization(
E);
10224 }
else if (isa<CXXScalarValueInitExpr>(
Init) ||
10225 isa<ImplicitValueInitExpr>(
Init)) {
10227 }
else if (
auto *CCE = dyn_cast<CXXConstructExpr>(
Init)) {
10228 ResizedArrayCCE = CCE;
10230 auto *CAT = Info.Ctx.getAsConstantArrayType(
Init->getType());
10231 assert(CAT &&
"unexpected type for array initializer");
10235 llvm::APInt InitBound = CAT->
getSize().zext(Bits);
10236 llvm::APInt AllocBound = ArrayBound.zext(Bits);
10237 if (InitBound.ugt(AllocBound)) {
10239 return ZeroInitialization(
E);
10241 Info.FFDiag(*ArraySize, diag::note_constexpr_new_too_small)
10242 <<
toString(AllocBound, 10,
false)
10244 << (*ArraySize)->getSourceRange();
10250 if (InitBound != AllocBound)
10251 ResizedArrayILE = cast<InitListExpr>(
Init);
10254 AllocType = Info.Ctx.getConstantArrayType(AllocType, ArrayBound,
nullptr,
10255 ArraySizeModifier::Normal, 0);
10258 "array allocation with non-array new");
10264 struct FindObjectHandler {
10271 typedef bool result_type;
10272 bool failed() {
return false; }
10276 unsigned SubobjectSize = 1;
10277 unsigned AllocSize = 1;
10278 if (
auto *CAT = dyn_cast<ConstantArrayType>(AllocType))
10280 if (
auto *CAT = dyn_cast<ConstantArrayType>(SubobjType))
10282 if (SubobjectSize < AllocSize ||
10283 !Info.Ctx.hasSimilarType(Info.Ctx.getBaseElementType(SubobjType),
10284 Info.Ctx.getBaseElementType(AllocType))) {
10285 Info.FFDiag(
E, diag::note_constexpr_placement_new_wrong_type)
10286 << SubobjType << AllocType;
10293 Info.FFDiag(
E, diag::note_constexpr_construct_complex_elem);
10297 Info.FFDiag(
E, diag::note_constexpr_construct_complex_elem);
10300 } Handler = {Info,
E, AllocType, AK,
nullptr};
10303 if (!Obj || !
findSubobject(Info,
E, Obj, Result.Designator, Handler))
10306 Val = Handler.Value;
10315 Val = Info.createHeapAlloc(
E, AllocType, Result);
10324 }
else if (ResizedArrayILE) {
10328 }
else if (ResizedArrayCCE) {
10342 Result.addArray(Info,
E, cast<ConstantArrayType>(AT));
10351class MemberPointerExprEvaluator
10352 :
public ExprEvaluatorBase<MemberPointerExprEvaluator> {
10356 Result = MemberPtr(
D);
10361 MemberPointerExprEvaluator(EvalInfo &Info, MemberPtr &Result)
10362 : ExprEvaluatorBaseTy(Info), Result(Result) {}
10368 bool ZeroInitialization(
const Expr *
E) {
10381 return MemberPointerExprEvaluator(Info, Result).Visit(
E);
10384bool MemberPointerExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
10385 switch (
E->getCastKind()) {
10387 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
10389 case CK_NullToMemberPointer:
10390 VisitIgnoredValue(
E->getSubExpr());
10391 return ZeroInitialization(
E);
10393 case CK_BaseToDerivedMemberPointer: {
10394 if (!Visit(
E->getSubExpr()))
10396 if (
E->path_empty())
10401 typedef std::reverse_iterator<CastExpr::path_const_iterator> ReverseIter;
10402 for (ReverseIter PathI(
E->path_end() - 1), PathE(
E->path_begin());
10403 PathI != PathE; ++PathI) {
10404 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
10405 const CXXRecordDecl *Derived = (*PathI)->getType()->getAsCXXRecordDecl();
10406 if (!Result.castToDerived(Derived))
10415 case CK_DerivedToBaseMemberPointer:
10416 if (!Visit(
E->getSubExpr()))
10419 PathE =
E->path_end(); PathI != PathE; ++PathI) {
10420 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
10422 if (!Result.castToBase(
Base))
10429bool MemberPointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *
E) {
10432 return Success(cast<DeclRefExpr>(
E->getSubExpr())->getDecl());
10440 class RecordExprEvaluator
10441 :
public ExprEvaluatorBase<RecordExprEvaluator> {
10442 const LValue &
This;
10446 RecordExprEvaluator(EvalInfo &info,
const LValue &This,
APValue &Result)
10447 : ExprEvaluatorBaseTy(info),
This(
This), Result(Result) {}
10453 bool ZeroInitialization(
const Expr *
E) {
10454 return ZeroInitialization(
E,
E->
getType());
10458 bool VisitCallExpr(
const CallExpr *
E) {
10459 return handleCallExpr(
E, Result, &This);
10464 return VisitCXXConstructExpr(
E,
E->
getType());
10472 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
10486 const LValue &This,
APValue &Result) {
10487 assert(!RD->
isUnion() &&
"Expected non-union class type");
10496 unsigned Index = 0;
10498 End = CD->
bases_end(); I != End; ++I, ++Index) {
10500 LValue Subobject = This;
10504 Result.getStructBase(Index)))
10509 for (
const auto *I : RD->
fields()) {
10511 if (I->isUnnamedBitField() || I->getType()->isReferenceType())
10514 LValue Subobject = This;
10520 Result.getStructField(I->getFieldIndex()), Info, Subobject, &VIE))
10527bool RecordExprEvaluator::ZeroInitialization(
const Expr *
E,
QualType T) {
10534 while (I != RD->
field_end() && (*I)->isUnnamedBitField())
10541 LValue Subobject =
This;
10546 return EvaluateInPlace(Result.getUnionValue(), Info, Subobject, &VIE);
10549 if (isa<CXXRecordDecl>(RD) && cast<CXXRecordDecl>(RD)->getNumVBases()) {
10550 Info.FFDiag(
E, diag::note_constexpr_virtual_base) << RD;
10557bool RecordExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
10558 switch (
E->getCastKind()) {
10560 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
10562 case CK_ConstructorConversion:
10563 return Visit(
E->getSubExpr());
10565 case CK_DerivedToBase:
10566 case CK_UncheckedDerivedToBase: {
10568 if (!
Evaluate(DerivedObject, Info,
E->getSubExpr()))
10571 return Error(
E->getSubExpr());
10577 PathE =
E->path_end(); PathI != PathE; ++PathI) {
10578 assert(!(*PathI)->isVirtual() &&
"record rvalue with virtual base");
10589bool RecordExprEvaluator::VisitInitListExpr(
const InitListExpr *
E) {
10590 if (
E->isTransparent())
10591 return Visit(
E->getInit(0));
10592 return VisitCXXParenListOrInitListExpr(
E,
E->inits());
10595bool RecordExprEvaluator::VisitCXXParenListOrInitListExpr(
10601 auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
10603 EvalInfo::EvaluatingConstructorRAII EvalObj(
10605 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries},
10606 CXXRD && CXXRD->getNumBases());
10610 if (
auto *ILE = dyn_cast<InitListExpr>(ExprToVisit)) {
10611 Field = ILE->getInitializedFieldInUnion();
10612 }
else if (
auto *PLIE = dyn_cast<CXXParenListInitExpr>(ExprToVisit)) {
10613 Field = PLIE->getInitializedFieldInUnion();
10616 "Expression is neither an init list nor a C++ paren list");
10629 const Expr *InitExpr = Args.empty() ? &VIE : Args[0];
10631 LValue Subobject =
This;
10636 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
10637 isa<CXXDefaultInitExpr>(InitExpr));
10639 if (
EvaluateInPlace(Result.getUnionValue(), Info, Subobject, InitExpr)) {
10640 if (
Field->isBitField())
10649 if (!Result.hasValue())
10652 unsigned ElementNo = 0;
10656 if (CXXRD && CXXRD->getNumBases()) {
10657 for (
const auto &
Base : CXXRD->bases()) {
10658 assert(ElementNo < Args.size() &&
"missing init for base class");
10659 const Expr *
Init = Args[ElementNo];
10661 LValue Subobject =
This;
10665 APValue &FieldVal = Result.getStructBase(ElementNo);
10667 if (!Info.noteFailure())
10674 EvalObj.finishedConstructingBases();
10678 for (
const auto *Field : RD->
fields()) {
10681 if (
Field->isUnnamedBitField())
10684 LValue Subobject =
This;
10686 bool HaveInit = ElementNo < Args.size();
10691 Subobject, Field, &Layout))
10697 const Expr *
Init = HaveInit ? Args[ElementNo++] : &VIE;
10699 if (
Field->getType()->isIncompleteArrayType()) {
10700 if (
auto *CAT = Info.Ctx.getAsConstantArrayType(
Init->getType())) {
10704 Info.FFDiag(
Init, diag::note_constexpr_unsupported_flexible_array);
10711 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
10712 isa<CXXDefaultInitExpr>(
Init));
10714 APValue &FieldVal = Result.getStructField(
Field->getFieldIndex());
10717 FieldVal, Field))) {
10718 if (!Info.noteFailure())
10724 EvalObj.finishedConstructingFields();
10736 bool ZeroInit =
E->requiresZeroInitialization();
10739 if (Result.hasValue())
10743 return ZeroInitialization(
E,
T);
10755 if (
E->isElidable() && !ZeroInit) {
10761 const Expr *SrcObj =
E->getArg(0);
10763 assert(Info.Ctx.hasSameUnqualifiedType(
E->
getType(), SrcObj->
getType()));
10765 dyn_cast<MaterializeTemporaryExpr>(SrcObj))
10766 return Visit(ME->getSubExpr());
10769 if (ZeroInit && !ZeroInitialization(
E,
T))
10778bool RecordExprEvaluator::VisitCXXInheritedCtorInitExpr(
10780 if (!Info.CurrentCall) {
10781 assert(Info.checkingPotentialConstantExpression());
10800bool RecordExprEvaluator::VisitCXXStdInitializerListExpr(
10803 Info.Ctx.getAsConstantArrayType(
E->getSubExpr()->
getType());
10809 assert(
ArrayType &&
"unexpected type for array initializer");
10816 Array.moveInto(Result.getStructField(0));
10820 assert(Field !=
Record->field_end() &&
10821 Info.Ctx.hasSameType(
Field->getType()->getPointeeType(),
10823 "Expected std::initializer_list first field to be const E *");
10825 assert(Field !=
Record->field_end() &&
10826 "Expected std::initializer_list to have two fields");
10828 if (Info.Ctx.hasSameType(
Field->getType(), Info.Ctx.getSizeType())) {
10833 assert(Info.Ctx.hasSameType(
Field->getType()->getPointeeType(),
10835 "Expected std::initializer_list second field to be const E *");
10840 Array.moveInto(Result.getStructField(1));
10843 assert(++Field ==
Record->field_end() &&
10844 "Expected std::initializer_list to only have two fields");
10849bool RecordExprEvaluator::VisitLambdaExpr(
const LambdaExpr *
E) {
10854 const size_t NumFields =
10857 assert(NumFields == (
size_t)std::distance(
E->capture_init_begin(),
10858 E->capture_init_end()) &&
10859 "The number of lambda capture initializers should equal the number of "
10860 "fields within the closure type");
10865 auto *CaptureInitIt =
E->capture_init_begin();
10867 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(ClosureClass);
10868 for (
const auto *Field : ClosureClass->
fields()) {
10869 assert(CaptureInitIt !=
E->capture_init_end());
10871 Expr *
const CurFieldInit = *CaptureInitIt++;
10878 LValue Subobject =
This;
10883 APValue &FieldVal = Result.getStructField(
Field->getFieldIndex());
10885 if (!Info.keepEvaluatingAfterFailure())
10894 APValue &Result, EvalInfo &Info) {
10897 "can't evaluate expression as a record rvalue");
10898 return RecordExprEvaluator(Info, This, Result).Visit(
E);
10909class TemporaryExprEvaluator
10910 :
public LValueExprEvaluatorBase<TemporaryExprEvaluator> {
10912 TemporaryExprEvaluator(EvalInfo &Info, LValue &Result) :
10913 LValueExprEvaluatorBaseTy(Info, Result,
false) {}
10916 bool VisitConstructExpr(
const Expr *
E) {
10918 E,
E->
getType(), ScopeKind::FullExpression, Result);
10922 bool VisitCastExpr(
const CastExpr *
E) {
10923 switch (
E->getCastKind()) {
10925 return LValueExprEvaluatorBaseTy::VisitCastExpr(
E);
10927 case CK_ConstructorConversion:
10928 return VisitConstructExpr(
E->getSubExpr());
10932 return VisitConstructExpr(
E);
10935 return VisitConstructExpr(
E);
10937 bool VisitCallExpr(
const CallExpr *
E) {
10938 return VisitConstructExpr(
E);
10941 return VisitConstructExpr(
E);
10944 return VisitConstructExpr(
E);
10953 return TemporaryExprEvaluator(Info, Result).Visit(
E);
10961 class VectorExprEvaluator
10962 :
public ExprEvaluatorBase<VectorExprEvaluator> {
10966 VectorExprEvaluator(EvalInfo &info,
APValue &Result)
10967 : ExprEvaluatorBaseTy(info), Result(Result) {}
10976 assert(
V.isVector());
10980 bool ZeroInitialization(
const Expr *
E);
10983 {
return Visit(
E->getSubExpr()); }
11000 "not a vector prvalue");
11001 return VectorExprEvaluator(Info, Result).Visit(
E);
11004bool VectorExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
11008 const Expr *SE =
E->getSubExpr();
11011 switch (
E->getCastKind()) {
11012 case CK_VectorSplat: {
11018 Val =
APValue(std::move(IntResult));
11023 Val =
APValue(std::move(FloatResult));
11040 Info.FFDiag(
E, diag::note_constexpr_invalid_cast)
11041 << 2 << Info.Ctx.getLangOpts().CPlusPlus;
11045 if (!handleRValueToRValueBitCast(Info, Result, SVal,
E))
11050 case CK_HLSLVectorTruncation: {
11055 for (
unsigned I = 0; I < NElts; I++)
11060 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
11065VectorExprEvaluator::VisitInitListExpr(
const InitListExpr *
E) {
11067 unsigned NumInits =
E->getNumInits();
11077 unsigned CountInits = 0, CountElts = 0;
11078 while (CountElts < NumElements) {
11080 if (CountInits < NumInits
11085 unsigned vlen =
v.getVectorLength();
11086 for (
unsigned j = 0; j < vlen; j++)
11087 Elements.push_back(
v.getVectorElt(j));
11090 llvm::APSInt sInt(32);
11091 if (CountInits < NumInits) {
11095 sInt = Info.Ctx.MakeIntValue(0, EltTy);
11096 Elements.push_back(
APValue(sInt));
11099 llvm::APFloat f(0.0);
11100 if (CountInits < NumInits) {
11104 f = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy));
11105 Elements.push_back(
APValue(f));
11114VectorExprEvaluator::ZeroInitialization(
const Expr *
E) {
11118 if (EltTy->isIntegerType())
11119 ZeroElement =
APValue(Info.Ctx.MakeIntValue(0, EltTy));
11122 APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy)));
11128bool VectorExprEvaluator::VisitUnaryImag(
const UnaryOperator *
E) {
11129 VisitIgnoredValue(
E->getSubExpr());
11130 return ZeroInitialization(
E);
11133bool VectorExprEvaluator::VisitBinaryOperator(
const BinaryOperator *
E) {
11135 assert(Op != BO_PtrMemD && Op != BO_PtrMemI && Op != BO_Cmp &&
11136 "Operation not supported on vector types");
11138 if (Op == BO_Comma)
11139 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
11141 Expr *LHS =
E->getLHS();
11142 Expr *RHS =
E->getRHS();
11145 "Must both be vector types");
11152 "All operands must be the same size.");
11156 bool LHSOK =
Evaluate(LHSValue, Info, LHS);
11157 if (!LHSOK && !Info.noteFailure())
11159 if (!
Evaluate(RHSValue, Info, RHS) || !LHSOK)
11181 "Vector can only be int or float type");
11189 "Vector operator ~ can only be int");
11190 Elt.
getInt().flipAllBits();
11200 "Vector can only be int or float type");
11206 EltResult.setAllBits();
11208 EltResult.clearAllBits();
11214 return std::nullopt;
11218bool VectorExprEvaluator::VisitUnaryOperator(
const UnaryOperator *
E) {
11219 Expr *SubExpr =
E->getSubExpr();
11224 const QualType ResultEltTy = VD->getElementType();
11228 if (!
Evaluate(SubExprValue, Info, SubExpr))
11241 "Vector length doesn't match type?");
11244 for (
unsigned EltNum = 0; EltNum < VD->getNumElements(); ++EltNum) {
11246 Info.Ctx, ResultEltTy, Op, SubExprValue.
getVectorElt(EltNum));
11249 ResultElements.push_back(*Elt);
11251 return Success(
APValue(ResultElements.data(), ResultElements.size()),
E);
11260 Result =
APValue(APFloat(0.0));
11262 DestTy, Result.getFloat());
11273 Result.getFloat());
11278 DestTy, Result.getInt());
11282 Info.FFDiag(
E, diag::err_convertvector_constexpr_unsupported_vector_cast)
11283 << SourceTy << DestTy;
11287bool VectorExprEvaluator::VisitCallExpr(
const CallExpr *
E) {
11288 if (!IsConstantEvaluatedBuiltinCall(
E))
11289 return ExprEvaluatorBaseTy::VisitCallExpr(
E);
11291 switch (
E->getBuiltinCallee()) {
11294 case Builtin::BI__builtin_elementwise_popcount:
11295 case Builtin::BI__builtin_elementwise_bitreverse: {
11303 ResultElements.reserve(SourceLen);
11305 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11307 switch (
E->getBuiltinCallee()) {
11308 case Builtin::BI__builtin_elementwise_popcount:
11309 ResultElements.push_back(
APValue(
11310 APSInt(
APInt(Info.Ctx.getIntWidth(DestEltTy), Elt.popcount()),
11313 case Builtin::BI__builtin_elementwise_bitreverse:
11314 ResultElements.push_back(
11321 return Success(
APValue(ResultElements.data(), ResultElements.size()),
E);
11323 case Builtin::BI__builtin_elementwise_add_sat:
11324 case Builtin::BI__builtin_elementwise_sub_sat: {
11325 APValue SourceLHS, SourceRHS;
11333 ResultElements.reserve(SourceLen);
11335 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11338 switch (
E->getBuiltinCallee()) {
11339 case Builtin::BI__builtin_elementwise_add_sat:
11340 ResultElements.push_back(
APValue(
11341 APSInt(LHS.isSigned() ? LHS.sadd_sat(RHS) : RHS.uadd_sat(RHS),
11344 case Builtin::BI__builtin_elementwise_sub_sat:
11345 ResultElements.push_back(
APValue(
11346 APSInt(LHS.isSigned() ? LHS.ssub_sat(RHS) : RHS.usub_sat(RHS),
11352 return Success(
APValue(ResultElements.data(), ResultElements.size()),
E);
11370 ResultElements.reserve(SourceLen);
11371 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11376 ResultElements.push_back(std::move(Elt));
11379 return Success(
APValue(ResultElements.data(), ResultElements.size()),
E);
11384 APValue const &VecVal2,
unsigned EltNum,
11386 unsigned const TotalElementsInInputVector1 = VecVal1.
getVectorLength();
11387 unsigned const TotalElementsInInputVector2 = VecVal2.
getVectorLength();
11389 APSInt IndexVal =
E->getShuffleMaskIdx(Info.Ctx, EltNum);
11390 int64_t index = IndexVal.getExtValue();
11397 E, diag::err_shufflevector_minus_one_is_undefined_behavior_constexpr)
11403 index >= TotalElementsInInputVector1 + TotalElementsInInputVector2)
11404 llvm_unreachable(
"Out of bounds shuffle index");
11406 if (index >= TotalElementsInInputVector1)
11407 Result = VecVal2.
getVectorElt(index - TotalElementsInInputVector1);
11415 const Expr *Vec1 =
E->getExpr(0);
11419 const Expr *Vec2 =
E->getExpr(1);
11429 ResultElements.reserve(TotalElementsInOutputVector);
11430 for (
unsigned EltNum = 0; EltNum < TotalElementsInOutputVector; ++EltNum) {
11434 ResultElements.push_back(std::move(Elt));
11437 return Success(
APValue(ResultElements.data(), ResultElements.size()),
E);
11445 class ArrayExprEvaluator
11446 :
public ExprEvaluatorBase<ArrayExprEvaluator> {
11447 const LValue &
This;
11451 ArrayExprEvaluator(EvalInfo &Info,
const LValue &This,
APValue &Result)
11452 : ExprEvaluatorBaseTy(Info),
This(
This), Result(Result) {}
11455 assert(
V.isArray() &&
"expected array");
11460 bool ZeroInitialization(
const Expr *
E) {
11462 Info.Ctx.getAsConstantArrayType(
E->
getType());
11476 if (!Result.hasArrayFiller())
11480 LValue Subobject =
This;
11481 Subobject.addArray(Info,
E, CAT);
11483 return EvaluateInPlace(Result.getArrayFiller(), Info, Subobject, &VIE);
11486 bool VisitCallExpr(
const CallExpr *
E) {
11487 return handleCallExpr(
E, Result, &This);
11494 const LValue &Subobject,
11502 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
11504 const Expr *ArrayFiller,
11510 APValue &Result, EvalInfo &Info) {
11513 "not an array prvalue");
11514 return ArrayExprEvaluator(Info, This, Result).Visit(
E);
11522 "not an array prvalue");
11523 return ArrayExprEvaluator(Info, This, Result)
11524 .VisitInitListExpr(ILE, AllocType);
11533 "not an array prvalue");
11534 return ArrayExprEvaluator(Info, This, Result)
11535 .VisitCXXConstructExpr(CCE, This, &Result, AllocType);
11542 if (isa<ImplicitValueInitExpr>(FillerExpr))
11544 if (
const InitListExpr *ILE = dyn_cast<InitListExpr>(FillerExpr)) {
11545 for (
unsigned I = 0,
E = ILE->getNumInits(); I !=
E; ++I) {
11550 if (ILE->hasArrayFiller() &&
11559bool ArrayExprEvaluator::VisitInitListExpr(
const InitListExpr *
E,
11568 if (
E->isStringLiteralInit()) {
11574 return VisitStringLiteral(SL, AllocType);
11578 assert(!
E->isTransparent() &&
11579 "transparent array list initialization is not string literal init?");
11581 return VisitCXXParenListOrInitListExpr(
E,
E->inits(),
E->getArrayFiller(),
11585bool ArrayExprEvaluator::VisitCXXParenListOrInitListExpr(
11593 assert((!Result.isArray() || Result.getArrayInitializedElts() == 0) &&
11594 "zero-initialized array shouldn't have any initialized elts");
11596 if (Result.isArray() && Result.hasArrayFiller())
11597 Filler = Result.getArrayFiller();
11599 unsigned NumEltsToInit = Args.size();
11604 if (NumEltsToInit != NumElts &&
11606 NumEltsToInit = NumElts;
11608 for (
auto *
Init : Args) {
11609 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts()))
11610 NumEltsToInit += EmbedS->getDataElementCount() - 1;
11612 if (NumEltsToInit > NumElts)
11613 NumEltsToInit = NumElts;
11616 LLVM_DEBUG(llvm::dbgs() <<
"The number of elements to initialize: "
11617 << NumEltsToInit <<
".\n");
11624 for (
unsigned I = 0,
E = Result.getArrayInitializedElts(); I !=
E; ++I)
11625 Result.getArrayInitializedElt(I) = Filler;
11626 if (Result.hasArrayFiller())
11627 Result.getArrayFiller() = Filler;
11630 LValue Subobject =
This;
11631 Subobject.addArray(Info, ExprToVisit, CAT);
11632 auto Eval = [&](
const Expr *
Init,
unsigned ArrayIndex) {
11633 if (
Init->isValueDependent())
11636 if (!
EvaluateInPlace(Result.getArrayInitializedElt(ArrayIndex), Info,
11637 Subobject,
Init) ||
11640 if (!Info.noteFailure())
11646 unsigned ArrayIndex = 0;
11649 for (
unsigned Index = 0; Index != NumEltsToInit; ++Index) {
11650 const Expr *
Init = Index < Args.size() ? Args[Index] : ArrayFiller;
11651 if (ArrayIndex >= NumEltsToInit)
11653 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
11655 for (
unsigned I = EmbedS->getStartingElementPos(),
11656 N = EmbedS->getDataElementCount();
11657 I != EmbedS->getStartingElementPos() + N; ++I) {
11660 Result.getArrayInitializedElt(ArrayIndex) =
APValue(
Value);
11664 Init->getFPFeaturesInEffect(Info.Ctx.getLangOpts());
11669 Result.getArrayInitializedElt(ArrayIndex) =
APValue(FValue);
11674 if (!Eval(
Init, ArrayIndex))
11680 if (!Result.hasArrayFiller())
11685 assert(ArrayFiller &&
"no array filler for incomplete init list");
11693 if (
E->getCommonExpr() &&
11694 !
Evaluate(Info.CurrentCall->createTemporary(
11695 E->getCommonExpr(),
11696 getStorageType(Info.Ctx,
E->getCommonExpr()),
11697 ScopeKind::FullExpression, CommonLV),
11698 Info,
E->getCommonExpr()->getSourceExpr()))
11706 LValue Subobject =
This;
11707 Subobject.addArray(Info,
E, CAT);
11710 for (EvalInfo::ArrayInitLoopIndex Index(Info); Index != Elements; ++Index) {
11719 FullExpressionRAII
Scope(Info);
11722 Info, Subobject,
E->getSubExpr()) ||
11725 if (!Info.noteFailure())
11738 return VisitCXXConstructExpr(
E, This, &Result,
E->
getType());
11742 const LValue &Subobject,
11752 HadZeroInit &&
Value->hasArrayFiller() ?
Value->getArrayFiller()
11756 if (FinalSize == 0)
11761 E->requiresZeroInitialization());
11762 LValue ArrayElt = Subobject;
11763 ArrayElt.addArray(Info,
E, CAT);
11769 for (
const unsigned N : {1u, FinalSize}) {
11770 unsigned OldElts =
Value->getArrayInitializedElts();
11776 for (
unsigned I = 0; I < OldElts; ++I)
11777 NewValue.getArrayInitializedElt(I).swap(
11778 Value->getArrayInitializedElt(I));
11779 Value->swap(NewValue);
11782 for (
unsigned I = OldElts; I < N; ++I)
11783 Value->getArrayInitializedElt(I) = Filler;
11785 if (HasTrivialConstructor && N == FinalSize && FinalSize != 1) {
11788 APValue &FirstResult =
Value->getArrayInitializedElt(0);
11789 for (
unsigned I = OldElts; I < FinalSize; ++I)
11790 Value->getArrayInitializedElt(I) = FirstResult;
11792 for (
unsigned I = OldElts; I < N; ++I) {
11793 if (!VisitCXXConstructExpr(
E, ArrayElt,
11794 &
Value->getArrayInitializedElt(I),
11801 if (Info.EvalStatus.Diag && !Info.EvalStatus.Diag->empty() &&
11802 !Info.keepEvaluatingAfterFailure())
11814 return RecordExprEvaluator(Info, Subobject, *
Value)
11815 .VisitCXXConstructExpr(
E,
Type);
11818bool ArrayExprEvaluator::VisitCXXParenListInitExpr(
11821 "Expression result is not a constant array type");
11823 return VisitCXXParenListOrInitListExpr(
E,
E->getInitExprs(),
11824 E->getArrayFiller());
11836class IntExprEvaluator
11837 :
public ExprEvaluatorBase<IntExprEvaluator> {
11840 IntExprEvaluator(EvalInfo &info,
APValue &result)
11841 : ExprEvaluatorBaseTy(info), Result(result) {}
11845 "Invalid evaluation result.");
11847 "Invalid evaluation result.");
11848 assert(SI.getBitWidth() == Info.Ctx.getIntWidth(
E->
getType()) &&
11849 "Invalid evaluation result.");
11859 "Invalid evaluation result.");
11860 assert(I.getBitWidth() == Info.Ctx.getIntWidth(
E->
getType()) &&
11861 "Invalid evaluation result.");
11863 Result.getInt().setIsUnsigned(
11873 "Invalid evaluation result.");
11886 if (
V.isLValue() ||
V.isAddrLabelDiff() ||
V.isIndeterminate()) {
11893 bool ZeroInitialization(
const Expr *
E) {
return Success(0,
E); }
11895 friend std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &,
11909 bool CheckReferencedDecl(
const Expr *
E,
const Decl *
D);
11911 if (CheckReferencedDecl(
E,
E->getDecl()))
11914 return ExprEvaluatorBaseTy::VisitDeclRefExpr(
E);
11917 if (CheckReferencedDecl(
E,
E->getMemberDecl())) {
11918 VisitIgnoredBaseExpression(
E->getBase());
11922 return ExprEvaluatorBaseTy::VisitMemberExpr(
E);
11926 bool VisitBuiltinCallExpr(
const CallExpr *
E,
unsigned BuiltinOp);
11943 if (Info.ArrayInitIndex ==
uint64_t(-1)) {
11949 return Success(Info.ArrayInitIndex,
E);
11954 return ZeroInitialization(
E);
11987class FixedPointExprEvaluator
11988 :
public ExprEvaluatorBase<FixedPointExprEvaluator> {
11992 FixedPointExprEvaluator(EvalInfo &info,
APValue &result)
11993 : ExprEvaluatorBaseTy(info), Result(result) {}
11997 APFixedPoint(I, Info.Ctx.getFixedPointSemantics(
E->
getType())),
E);
12002 APFixedPoint(
Value, Info.Ctx.getFixedPointSemantics(
E->
getType())),
E);
12011 assert(
V.getWidth() == Info.Ctx.getIntWidth(
E->
getType()) &&
12012 "Invalid evaluation result.");
12017 bool ZeroInitialization(
const Expr *
E) {
12047 return IntExprEvaluator(Info, Result).Visit(
E);
12055 if (!Val.
isInt()) {
12058 Info.FFDiag(
E, diag::note_invalid_subexpr_in_const_expr);
12065bool IntExprEvaluator::VisitSourceLocExpr(
const SourceLocExpr *
E) {
12067 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.getDefaultExpr());
12076 if (!FixedPointExprEvaluator(Info, Val).Visit(
E))
12091 auto FXSema = Info.Ctx.getFixedPointSemantics(
E->
getType());
12095 Result = APFixedPoint(Val, FXSema);
12106bool IntExprEvaluator::CheckReferencedDecl(
const Expr*
E,
const Decl*
D) {
12110 bool SameSign = (ECD->getInitVal().isSigned()
12112 bool SameWidth = (ECD->getInitVal().getBitWidth()
12113 == Info.Ctx.getIntWidth(
E->
getType()));
12114 if (SameSign && SameWidth)
12115 return Success(ECD->getInitVal(),
E);
12119 llvm::APSInt Val = ECD->getInitVal();
12121 Val.setIsSigned(!ECD->getInitVal().isSigned());
12123 Val = Val.extOrTrunc(Info.Ctx.getIntWidth(
E->
getType()));
12139#define TYPE(ID, BASE)
12140#define DEPENDENT_TYPE(ID, BASE) case Type::ID:
12141#define NON_CANONICAL_TYPE(ID, BASE) case Type::ID:
12142#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(ID, BASE) case Type::ID:
12143#include "clang/AST/TypeNodes.inc"
12145 case Type::DeducedTemplateSpecialization:
12146 llvm_unreachable(
"unexpected non-canonical or dependent type");
12148 case Type::Builtin:
12149 switch (cast<BuiltinType>(CanTy)->
getKind()) {
12150#define BUILTIN_TYPE(ID, SINGLETON_ID)
12151#define SIGNED_TYPE(ID, SINGLETON_ID) \
12152 case BuiltinType::ID: return GCCTypeClass::Integer;
12153#define FLOATING_TYPE(ID, SINGLETON_ID) \
12154 case BuiltinType::ID: return GCCTypeClass::RealFloat;
12155#define PLACEHOLDER_TYPE(ID, SINGLETON_ID) \
12156 case BuiltinType::ID: break;
12157#include "clang/AST/BuiltinTypes.def"
12158 case BuiltinType::Void:
12159 return GCCTypeClass::Void;
12161 case BuiltinType::Bool:
12162 return GCCTypeClass::Bool;
12164 case BuiltinType::Char_U:
12165 case BuiltinType::UChar:
12166 case BuiltinType::WChar_U:
12167 case BuiltinType::Char8:
12168 case BuiltinType::Char16:
12169 case BuiltinType::Char32:
12170 case BuiltinType::UShort:
12171 case BuiltinType::UInt:
12172 case BuiltinType::ULong:
12173 case BuiltinType::ULongLong:
12174 case BuiltinType::UInt128:
12175 return GCCTypeClass::Integer;
12177 case BuiltinType::UShortAccum:
12178 case BuiltinType::UAccum:
12179 case BuiltinType::ULongAccum:
12180 case BuiltinType::UShortFract:
12181 case BuiltinType::UFract:
12182 case BuiltinType::ULongFract:
12183 case BuiltinType::SatUShortAccum:
12184 case BuiltinType::SatUAccum:
12185 case BuiltinType::SatULongAccum:
12186 case BuiltinType::SatUShortFract:
12187 case BuiltinType::SatUFract:
12188 case BuiltinType::SatULongFract:
12189 return GCCTypeClass::None;
12191 case BuiltinType::NullPtr:
12193 case BuiltinType::ObjCId:
12194 case BuiltinType::ObjCClass:
12195 case BuiltinType::ObjCSel:
12196#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
12197 case BuiltinType::Id:
12198#include "clang/Basic/OpenCLImageTypes.def"
12199#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
12200 case BuiltinType::Id:
12201#include "clang/Basic/OpenCLExtensionTypes.def"
12202 case BuiltinType::OCLSampler:
12203 case BuiltinType::OCLEvent:
12204 case BuiltinType::OCLClkEvent:
12205 case BuiltinType::OCLQueue:
12206 case BuiltinType::OCLReserveID:
12207#define SVE_TYPE(Name, Id, SingletonId) \
12208 case BuiltinType::Id:
12209#include "clang/Basic/AArch64SVEACLETypes.def"
12210#define PPC_VECTOR_TYPE(Name, Id, Size) \
12211 case BuiltinType::Id:
12212#include "clang/Basic/PPCTypes.def"
12213#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
12214#include "clang/Basic/RISCVVTypes.def"
12215#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
12216#include "clang/Basic/WebAssemblyReferenceTypes.def"
12217#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
12218#include "clang/Basic/AMDGPUTypes.def"
12219#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
12220#include "clang/Basic/HLSLIntangibleTypes.def"
12221 return GCCTypeClass::None;
12223 case BuiltinType::Dependent:
12224 llvm_unreachable(
"unexpected dependent type");
12226 llvm_unreachable(
"unexpected placeholder type");
12229 return LangOpts.CPlusPlus ? GCCTypeClass::Enum : GCCTypeClass::Integer;
12231 case Type::Pointer:
12232 case Type::ConstantArray:
12233 case Type::VariableArray:
12234 case Type::IncompleteArray:
12235 case Type::FunctionNoProto:
12236 case Type::FunctionProto:
12237 case Type::ArrayParameter:
12238 return GCCTypeClass::Pointer;
12240 case Type::MemberPointer:
12242 ? GCCTypeClass::PointerToDataMember
12243 : GCCTypeClass::PointerToMemberFunction;
12245 case Type::Complex:
12246 return GCCTypeClass::Complex;
12249 return CanTy->
isUnionType() ? GCCTypeClass::Union
12250 : GCCTypeClass::ClassOrStruct;
12258 case Type::ExtVector:
12259 return GCCTypeClass::Vector;
12261 case Type::BlockPointer:
12262 case Type::ConstantMatrix:
12263 case Type::ObjCObject:
12264 case Type::ObjCInterface:
12265 case Type::ObjCObjectPointer:
12267 case Type::HLSLAttributedResource:
12270 return GCCTypeClass::None;
12273 return GCCTypeClass::BitInt;
12275 case Type::LValueReference:
12276 case Type::RValueReference:
12277 llvm_unreachable(
"invalid type for expression");
12280 llvm_unreachable(
"unexpected type class");
12289 if (
E->getNumArgs() == 0)
12290 return GCCTypeClass::None;
12305 if (
Base.isNull()) {
12308 }
else if (
const Expr *
E =
Base.dyn_cast<
const Expr *>()) {
12309 if (!isa<StringLiteral>(
E))
12327 SpeculativeEvaluationRAII SpeculativeEval(Info);
12332 FoldConstant Fold(Info,
true);
12355 Fold.keepDiagnostics();
12364 return V.hasValue();
12375 if (
const VarDecl *VD = dyn_cast<VarDecl>(
D))
12378 if (isa<CompoundLiteralExpr>(
E))
12399 const auto *Cast = dyn_cast<CastExpr>(NoParens);
12400 if (Cast ==
nullptr)
12405 auto CastKind = Cast->getCastKind();
12407 CastKind != CK_AddressSpaceConversion)
12410 const auto *SubExpr = Cast->getSubExpr();
12432 assert(!LVal.Designator.Invalid);
12434 auto IsLastOrInvalidFieldDecl = [&Ctx](
const FieldDecl *FD,
bool &
Invalid) {
12443 auto &
Base = LVal.getLValueBase();
12444 if (
auto *ME = dyn_cast_or_null<MemberExpr>(
Base.dyn_cast<
const Expr *>())) {
12445 if (
auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
12447 if (!IsLastOrInvalidFieldDecl(FD,
Invalid))
12449 }
else if (
auto *IFD = dyn_cast<IndirectFieldDecl>(ME->getMemberDecl())) {
12450 for (
auto *FD : IFD->chain()) {
12452 if (!IsLastOrInvalidFieldDecl(cast<FieldDecl>(FD),
Invalid))
12460 if (LVal.Designator.FirstEntryIsAnUnsizedArray) {
12470 for (
unsigned E = LVal.Designator.Entries.size(); I !=
E; ++I) {
12471 const auto &Entry = LVal.Designator.Entries[I];
12477 const auto *CAT = cast<ConstantArrayType>(Ctx.
getAsArrayType(BaseType));
12478 uint64_t Index = Entry.getAsArrayIndex();
12484 uint64_t Index = Entry.getAsArrayIndex();
12487 BaseType = CT->getElementType();
12488 }
else if (
auto *FD = getAsField(Entry)) {
12490 if (!IsLastOrInvalidFieldDecl(FD,
Invalid))
12494 assert(getAsBaseClass(Entry) &&
"Expecting cast to a base class");
12506 if (LVal.Designator.Invalid)
12509 if (!LVal.Designator.Entries.empty())
12510 return LVal.Designator.isMostDerivedAnUnsizedArray();
12512 if (!LVal.InvalidBase)
12517 const auto *
E = LVal.Base.dyn_cast<
const Expr *>();
12518 return !
E || !isa<MemberExpr>(
E);
12524 const SubobjectDesignator &
Designator = LVal.Designator;
12536 auto isFlexibleArrayMember = [&] {
12538 FAMKind StrictFlexArraysLevel =
12541 if (
Designator.isMostDerivedAnUnsizedArray())
12544 if (StrictFlexArraysLevel == FAMKind::Default)
12547 if (
Designator.getMostDerivedArraySize() == 0 &&
12548 StrictFlexArraysLevel != FAMKind::IncompleteOnly)
12551 if (
Designator.getMostDerivedArraySize() == 1 &&
12552 StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete)
12558 return LVal.InvalidBase &&
12560 Designator.MostDerivedIsArrayElement && isFlexibleArrayMember() &&
12568 auto CharUnitsMax = std::numeric_limits<CharUnits::QuantityType>::max();
12569 if (Int.ugt(CharUnitsMax))
12581 if (
const auto *
V = LV.getLValueBase().dyn_cast<
const ValueDecl *>())
12582 if (
const auto *VD = dyn_cast<VarDecl>(
V))
12594 unsigned Type,
const LValue &LVal,
12607 if (!(
Type & 1) || LVal.Designator.Invalid || DetermineForCompleteObject) {
12609 if (
Type == 3 && !DetermineForCompleteObject)
12612 llvm::APInt APEndOffset;
12613 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
12617 if (LVal.InvalidBase)
12621 const bool Ret = CheckedHandleSizeof(BaseTy, EndOffset);
12627 const SubobjectDesignator &
Designator = LVal.Designator;
12639 llvm::APInt APEndOffset;
12640 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
12652 if (!CheckedHandleSizeof(
Designator.MostDerivedType, BytesPerElem))
12658 int64_t ElemsRemaining;
12661 uint64_t ArraySize =
Designator.getMostDerivedArraySize();
12662 uint64_t ArrayIndex =
Designator.Entries.back().getAsArrayIndex();
12663 ElemsRemaining = ArraySize <= ArrayIndex ? 0 : ArraySize - ArrayIndex;
12665 ElemsRemaining =
Designator.isOnePastTheEnd() ? 0 : 1;
12668 EndOffset = LVal.getLValueOffset() + BytesPerElem * ElemsRemaining;
12678 EvalInfo &Info, uint64_t &Size) {
12685 SpeculativeEvaluationRAII SpeculativeEval(Info);
12686 IgnoreSideEffectsRAII Fold(Info);
12694 LVal.setFrom(Info.Ctx, RVal);
12702 if (LVal.getLValueOffset().isNegative()) {
12713 if (EndOffset <= LVal.getLValueOffset())
12716 Size = (EndOffset - LVal.getLValueOffset()).getQuantity();
12720bool IntExprEvaluator::VisitCallExpr(
const CallExpr *
E) {
12721 if (!IsConstantEvaluatedBuiltinCall(
E))
12722 return ExprEvaluatorBaseTy::VisitCallExpr(
E);
12723 return VisitBuiltinCallExpr(
E,
E->getBuiltinCallee());
12739 Info.FFDiag(
E->getArg(0));
12745 assert(SrcInt.getBitWidth() >= Alignment.getBitWidth() &&
12746 "Bit widths must be the same");
12753bool IntExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *
E,
12754 unsigned BuiltinOp) {
12755 switch (BuiltinOp) {
12759 case Builtin::BI__builtin_dynamic_object_size:
12760 case Builtin::BI__builtin_object_size: {
12764 assert(
Type <= 3 &&
"unexpected type");
12775 switch (Info.EvalMode) {
12776 case EvalInfo::EM_ConstantExpression:
12777 case EvalInfo::EM_ConstantFold:
12778 case EvalInfo::EM_IgnoreSideEffects:
12781 case EvalInfo::EM_ConstantExpressionUnevaluated:
12786 llvm_unreachable(
"unexpected EvalMode");
12789 case Builtin::BI__builtin_os_log_format_buffer_size: {
12795 case Builtin::BI__builtin_is_aligned: {
12803 Ptr.setFrom(Info.Ctx, Src);
12809 assert(Alignment.isPowerOf2());
12822 Info.FFDiag(
E->getArg(0), diag::note_constexpr_alignment_compute)
12826 assert(Src.
isInt());
12827 return Success((Src.
getInt() & (Alignment - 1)) == 0 ? 1 : 0,
E);
12829 case Builtin::BI__builtin_align_up: {
12837 APSInt((Src.
getInt() + (Alignment - 1)) & ~(Alignment - 1),
12838 Src.
getInt().isUnsigned());
12839 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
12842 case Builtin::BI__builtin_align_down: {
12851 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
12855 case Builtin::BI__builtin_bitreverse8:
12856 case Builtin::BI__builtin_bitreverse16:
12857 case Builtin::BI__builtin_bitreverse32:
12858 case Builtin::BI__builtin_bitreverse64:
12859 case Builtin::BI__builtin_elementwise_bitreverse: {
12864 return Success(Val.reverseBits(),
E);
12867 case Builtin::BI__builtin_bswap16:
12868 case Builtin::BI__builtin_bswap32:
12869 case Builtin::BI__builtin_bswap64: {
12874 return Success(Val.byteSwap(),
E);
12877 case Builtin::BI__builtin_classify_type:
12880 case Builtin::BI__builtin_clrsb:
12881 case Builtin::BI__builtin_clrsbl:
12882 case Builtin::BI__builtin_clrsbll: {
12887 return Success(Val.getBitWidth() - Val.getSignificantBits(),
E);
12890 case Builtin::BI__builtin_clz:
12891 case Builtin::BI__builtin_clzl:
12892 case Builtin::BI__builtin_clzll:
12893 case Builtin::BI__builtin_clzs:
12894 case Builtin::BI__builtin_clzg:
12895 case Builtin::BI__lzcnt16:
12896 case Builtin::BI__lzcnt:
12897 case Builtin::BI__lzcnt64: {
12902 std::optional<APSInt> Fallback;
12903 if (BuiltinOp == Builtin::BI__builtin_clzg &&
E->getNumArgs() > 1) {
12907 Fallback = FallbackTemp;
12917 bool ZeroIsUndefined = BuiltinOp != Builtin::BI__lzcnt16 &&
12918 BuiltinOp != Builtin::BI__lzcnt &&
12919 BuiltinOp != Builtin::BI__lzcnt64;
12921 if (ZeroIsUndefined)
12925 return Success(Val.countl_zero(),
E);
12928 case Builtin::BI__builtin_constant_p: {
12929 const Expr *Arg =
E->getArg(0);
12938 Info.FFDiag(
E, diag::note_invalid_subexpr_in_const_expr);
12942 case Builtin::BI__noop:
12946 case Builtin::BI__builtin_is_constant_evaluated: {
12947 const auto *
Callee = Info.CurrentCall->getCallee();
12948 if (Info.InConstantContext && !Info.CheckingPotentialConstantExpression &&
12949 (Info.CallStackDepth == 1 ||
12950 (Info.CallStackDepth == 2 &&
Callee->isInStdNamespace() &&
12951 Callee->getIdentifier() &&
12952 Callee->getIdentifier()->isStr(
"is_constant_evaluated")))) {
12954 if (Info.EvalStatus.Diag)
12955 Info.report((Info.CallStackDepth == 1)
12957 : Info.CurrentCall->getCallRange().getBegin(),
12958 diag::warn_is_constant_evaluated_always_true_constexpr)
12959 << (Info.CallStackDepth == 1 ?
"__builtin_is_constant_evaluated"
12960 :
"std::is_constant_evaluated");
12963 return Success(Info.InConstantContext,
E);
12966 case Builtin::BI__builtin_is_within_lifetime:
12967 if (
auto result = EvaluateBuiltinIsWithinLifetime(*
this,
E))
12971 case Builtin::BI__builtin_ctz:
12972 case Builtin::BI__builtin_ctzl:
12973 case Builtin::BI__builtin_ctzll:
12974 case Builtin::BI__builtin_ctzs:
12975 case Builtin::BI__builtin_ctzg: {
12980 std::optional<APSInt> Fallback;
12981 if (BuiltinOp == Builtin::BI__builtin_ctzg &&
E->getNumArgs() > 1) {
12985 Fallback = FallbackTemp;
12995 return Success(Val.countr_zero(),
E);
12998 case Builtin::BI__builtin_eh_return_data_regno: {
13000 Operand = Info.Ctx.getTargetInfo().getEHDataRegisterNumber(Operand);
13004 case Builtin::BI__builtin_expect:
13005 case Builtin::BI__builtin_expect_with_probability:
13006 return Visit(
E->getArg(0));
13008 case Builtin::BI__builtin_ptrauth_string_discriminator: {
13015 case Builtin::BI__builtin_ffs:
13016 case Builtin::BI__builtin_ffsl:
13017 case Builtin::BI__builtin_ffsll: {
13022 unsigned N = Val.countr_zero();
13023 return Success(N == Val.getBitWidth() ? 0 : N + 1,
E);
13026 case Builtin::BI__builtin_fpclassify: {
13031 switch (Val.getCategory()) {
13032 case APFloat::fcNaN: Arg = 0;
break;
13033 case APFloat::fcInfinity: Arg = 1;
break;
13034 case APFloat::fcNormal: Arg = Val.isDenormal() ? 3 : 2;
break;
13035 case APFloat::fcZero: Arg = 4;
break;
13037 return Visit(
E->getArg(Arg));
13040 case Builtin::BI__builtin_isinf_sign: {
13043 Success(Val.isInfinity() ? (Val.isNegative() ? -1 : 1) : 0,
E);
13046 case Builtin::BI__builtin_isinf: {
13049 Success(Val.isInfinity() ? 1 : 0,
E);
13052 case Builtin::BI__builtin_isfinite: {
13055 Success(Val.isFinite() ? 1 : 0,
E);
13058 case Builtin::BI__builtin_isnan: {
13064 case Builtin::BI__builtin_isnormal: {
13067 Success(Val.isNormal() ? 1 : 0,
E);
13070 case Builtin::BI__builtin_issubnormal: {
13073 Success(Val.isDenormal() ? 1 : 0,
E);
13076 case Builtin::BI__builtin_iszero: {
13082 case Builtin::BI__builtin_signbit:
13083 case Builtin::BI__builtin_signbitf:
13084 case Builtin::BI__builtin_signbitl: {
13087 Success(Val.isNegative() ? 1 : 0,
E);
13090 case Builtin::BI__builtin_isgreater:
13091 case Builtin::BI__builtin_isgreaterequal:
13092 case Builtin::BI__builtin_isless:
13093 case Builtin::BI__builtin_islessequal:
13094 case Builtin::BI__builtin_islessgreater:
13095 case Builtin::BI__builtin_isunordered: {
13104 switch (BuiltinOp) {
13105 case Builtin::BI__builtin_isgreater:
13107 case Builtin::BI__builtin_isgreaterequal:
13109 case Builtin::BI__builtin_isless:
13111 case Builtin::BI__builtin_islessequal:
13113 case Builtin::BI__builtin_islessgreater: {
13114 APFloat::cmpResult cmp = LHS.compare(RHS);
13115 return cmp == APFloat::cmpResult::cmpLessThan ||
13116 cmp == APFloat::cmpResult::cmpGreaterThan;
13118 case Builtin::BI__builtin_isunordered:
13119 return LHS.compare(RHS) == APFloat::cmpResult::cmpUnordered;
13121 llvm_unreachable(
"Unexpected builtin ID: Should be a floating "
13122 "point comparison function");
13130 case Builtin::BI__builtin_issignaling: {
13133 Success(Val.isSignaling() ? 1 : 0,
E);
13136 case Builtin::BI__builtin_isfpclass: {
13140 unsigned Test =
static_cast<llvm::FPClassTest
>(MaskVal.getZExtValue());
13143 Success((Val.classify() & Test) ? 1 : 0,
E);
13146 case Builtin::BI__builtin_parity:
13147 case Builtin::BI__builtin_parityl:
13148 case Builtin::BI__builtin_parityll: {
13153 return Success(Val.popcount() % 2,
E);
13156 case Builtin::BI__builtin_abs:
13157 case Builtin::BI__builtin_labs:
13158 case Builtin::BI__builtin_llabs: {
13162 if (Val ==
APSInt(APInt::getSignedMinValue(Val.getBitWidth()),
13165 if (Val.isNegative())
13170 case Builtin::BI__builtin_popcount:
13171 case Builtin::BI__builtin_popcountl:
13172 case Builtin::BI__builtin_popcountll:
13173 case Builtin::BI__builtin_popcountg:
13174 case Builtin::BI__builtin_elementwise_popcount:
13175 case Builtin::BI__popcnt16:
13176 case Builtin::BI__popcnt:
13177 case Builtin::BI__popcnt64: {
13182 return Success(Val.popcount(),
E);
13185 case Builtin::BI__builtin_rotateleft8:
13186 case Builtin::BI__builtin_rotateleft16:
13187 case Builtin::BI__builtin_rotateleft32:
13188 case Builtin::BI__builtin_rotateleft64:
13189 case Builtin::BI_rotl8:
13190 case Builtin::BI_rotl16:
13191 case Builtin::BI_rotl:
13192 case Builtin::BI_lrotl:
13193 case Builtin::BI_rotl64: {
13199 return Success(Val.rotl(Amt.urem(Val.getBitWidth())),
E);
13202 case Builtin::BI__builtin_rotateright8:
13203 case Builtin::BI__builtin_rotateright16:
13204 case Builtin::BI__builtin_rotateright32:
13205 case Builtin::BI__builtin_rotateright64:
13206 case Builtin::BI_rotr8:
13207 case Builtin::BI_rotr16:
13208 case Builtin::BI_rotr:
13209 case Builtin::BI_lrotr:
13210 case Builtin::BI_rotr64: {
13216 return Success(Val.rotr(Amt.urem(Val.getBitWidth())),
E);
13219 case Builtin::BI__builtin_elementwise_add_sat: {
13225 APInt Result = LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS);
13228 case Builtin::BI__builtin_elementwise_sub_sat: {
13234 APInt Result = LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
13238 case Builtin::BIstrlen:
13239 case Builtin::BIwcslen:
13241 if (Info.getLangOpts().CPlusPlus11)
13242 Info.CCEDiag(
E, diag::note_constexpr_invalid_function)
13244 << (
"'" + Info.Ctx.BuiltinInfo.getName(BuiltinOp) +
"'").str();
13246 Info.CCEDiag(
E, diag::note_invalid_subexpr_in_const_expr);
13248 case Builtin::BI__builtin_strlen:
13249 case Builtin::BI__builtin_wcslen: {
13258 case Builtin::BIstrcmp:
13259 case Builtin::BIwcscmp:
13260 case Builtin::BIstrncmp:
13261 case Builtin::BIwcsncmp:
13262 case Builtin::BImemcmp:
13263 case Builtin::BIbcmp:
13264 case Builtin::BIwmemcmp:
13266 if (Info.getLangOpts().CPlusPlus11)
13267 Info.CCEDiag(
E, diag::note_constexpr_invalid_function)
13269 << (
"'" + Info.Ctx.BuiltinInfo.getName(BuiltinOp) +
"'").str();
13271 Info.CCEDiag(
E, diag::note_invalid_subexpr_in_const_expr);
13273 case Builtin::BI__builtin_strcmp:
13274 case Builtin::BI__builtin_wcscmp:
13275 case Builtin::BI__builtin_strncmp:
13276 case Builtin::BI__builtin_wcsncmp:
13277 case Builtin::BI__builtin_memcmp:
13278 case Builtin::BI__builtin_bcmp:
13279 case Builtin::BI__builtin_wmemcmp: {
13280 LValue String1, String2;
13286 if (BuiltinOp != Builtin::BIstrcmp &&
13287 BuiltinOp != Builtin::BIwcscmp &&
13288 BuiltinOp != Builtin::BI__builtin_strcmp &&
13289 BuiltinOp != Builtin::BI__builtin_wcscmp) {
13293 MaxLength = N.getZExtValue();
13297 if (MaxLength == 0u)
13300 if (!String1.checkNullPointerForFoldAccess(Info,
E,
AK_Read) ||
13301 !String2.checkNullPointerForFoldAccess(Info,
E,
AK_Read) ||
13302 String1.Designator.Invalid || String2.Designator.Invalid)
13305 QualType CharTy1 = String1.Designator.getType(Info.Ctx);
13306 QualType CharTy2 = String2.Designator.getType(Info.Ctx);
13308 bool IsRawByte = BuiltinOp == Builtin::BImemcmp ||
13309 BuiltinOp == Builtin::BIbcmp ||
13310 BuiltinOp == Builtin::BI__builtin_memcmp ||
13311 BuiltinOp == Builtin::BI__builtin_bcmp;
13313 assert(IsRawByte ||
13314 (Info.Ctx.hasSameUnqualifiedType(
13316 Info.Ctx.hasSameUnqualifiedType(CharTy1, CharTy2)));
13323 Info.FFDiag(
E, diag::note_constexpr_memcmp_unsupported)
13324 << (
"'" + Info.Ctx.BuiltinInfo.getName(BuiltinOp) +
"'").str()
13325 << CharTy1 << CharTy2;
13329 const auto &ReadCurElems = [&](
APValue &Char1,
APValue &Char2) {
13332 Char1.
isInt() && Char2.isInt();
13334 const auto &AdvanceElems = [&] {
13340 (BuiltinOp != Builtin::BImemcmp && BuiltinOp != Builtin::BIbcmp &&
13341 BuiltinOp != Builtin::BIwmemcmp &&
13342 BuiltinOp != Builtin::BI__builtin_memcmp &&
13343 BuiltinOp != Builtin::BI__builtin_bcmp &&
13344 BuiltinOp != Builtin::BI__builtin_wmemcmp);
13345 bool IsWide = BuiltinOp == Builtin::BIwcscmp ||
13346 BuiltinOp == Builtin::BIwcsncmp ||
13347 BuiltinOp == Builtin::BIwmemcmp ||
13348 BuiltinOp == Builtin::BI__builtin_wcscmp ||
13349 BuiltinOp == Builtin::BI__builtin_wcsncmp ||
13350 BuiltinOp == Builtin::BI__builtin_wmemcmp;
13352 for (; MaxLength; --MaxLength) {
13354 if (!ReadCurElems(Char1, Char2))
13362 if (StopAtNull && !Char1.
getInt())
13364 assert(!(StopAtNull && !Char2.
getInt()));
13365 if (!AdvanceElems())
13372 case Builtin::BI__atomic_always_lock_free:
13373 case Builtin::BI__atomic_is_lock_free:
13374 case Builtin::BI__c11_atomic_is_lock_free: {
13390 if (
Size.isPowerOfTwo()) {
13392 unsigned InlineWidthBits =
13393 Info.Ctx.getTargetInfo().getMaxAtomicInlineWidth();
13394 if (Size <= Info.Ctx.toCharUnitsFromBits(InlineWidthBits)) {
13395 if (BuiltinOp == Builtin::BI__c11_atomic_is_lock_free ||
13401 const Expr *PtrArg =
E->getArg(1);
13407 IntResult.isAligned(
Size.getAsAlign()))
13411 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(PtrArg)) {
13414 if (ICE->getCastKind() == CK_BitCast)
13415 PtrArg = ICE->getSubExpr();
13421 Info.Ctx.getTypeAlignInChars(PointeeType) >= Size) {
13429 return BuiltinOp == Builtin::BI__atomic_always_lock_free ?
13432 case Builtin::BI__builtin_addcb:
13433 case Builtin::BI__builtin_addcs:
13434 case Builtin::BI__builtin_addc:
13435 case Builtin::BI__builtin_addcl:
13436 case Builtin::BI__builtin_addcll:
13437 case Builtin::BI__builtin_subcb:
13438 case Builtin::BI__builtin_subcs:
13439 case Builtin::BI__builtin_subc:
13440 case Builtin::BI__builtin_subcl:
13441 case Builtin::BI__builtin_subcll: {
13442 LValue CarryOutLValue;
13443 APSInt LHS, RHS, CarryIn, CarryOut, Result;
13454 bool FirstOverflowed =
false;
13455 bool SecondOverflowed =
false;
13456 switch (BuiltinOp) {
13458 llvm_unreachable(
"Invalid value for BuiltinOp");
13459 case Builtin::BI__builtin_addcb:
13460 case Builtin::BI__builtin_addcs:
13461 case Builtin::BI__builtin_addc:
13462 case Builtin::BI__builtin_addcl:
13463 case Builtin::BI__builtin_addcll:
13465 LHS.uadd_ov(RHS, FirstOverflowed).uadd_ov(CarryIn, SecondOverflowed);
13467 case Builtin::BI__builtin_subcb:
13468 case Builtin::BI__builtin_subcs:
13469 case Builtin::BI__builtin_subc:
13470 case Builtin::BI__builtin_subcl:
13471 case Builtin::BI__builtin_subcll:
13473 LHS.usub_ov(RHS, FirstOverflowed).usub_ov(CarryIn, SecondOverflowed);
13479 CarryOut = (
uint64_t)(FirstOverflowed | SecondOverflowed);
13485 case Builtin::BI__builtin_add_overflow:
13486 case Builtin::BI__builtin_sub_overflow:
13487 case Builtin::BI__builtin_mul_overflow:
13488 case Builtin::BI__builtin_sadd_overflow:
13489 case Builtin::BI__builtin_uadd_overflow:
13490 case Builtin::BI__builtin_uaddl_overflow:
13491 case Builtin::BI__builtin_uaddll_overflow:
13492 case Builtin::BI__builtin_usub_overflow:
13493 case Builtin::BI__builtin_usubl_overflow:
13494 case Builtin::BI__builtin_usubll_overflow:
13495 case Builtin::BI__builtin_umul_overflow:
13496 case Builtin::BI__builtin_umull_overflow:
13497 case Builtin::BI__builtin_umulll_overflow:
13498 case Builtin::BI__builtin_saddl_overflow:
13499 case Builtin::BI__builtin_saddll_overflow:
13500 case Builtin::BI__builtin_ssub_overflow:
13501 case Builtin::BI__builtin_ssubl_overflow:
13502 case Builtin::BI__builtin_ssubll_overflow:
13503 case Builtin::BI__builtin_smul_overflow:
13504 case Builtin::BI__builtin_smull_overflow:
13505 case Builtin::BI__builtin_smulll_overflow: {
13506 LValue ResultLValue;
13516 bool DidOverflow =
false;
13519 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
13520 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
13521 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
13522 bool IsSigned = LHS.isSigned() || RHS.isSigned() ||
13524 bool AllSigned = LHS.isSigned() && RHS.isSigned() &&
13526 uint64_t LHSSize = LHS.getBitWidth();
13527 uint64_t RHSSize = RHS.getBitWidth();
13528 uint64_t ResultSize = Info.Ctx.getTypeSize(ResultType);
13529 uint64_t MaxBits = std::max(std::max(LHSSize, RHSSize), ResultSize);
13535 if (IsSigned && !AllSigned)
13538 LHS =
APSInt(LHS.extOrTrunc(MaxBits), !IsSigned);
13539 RHS =
APSInt(RHS.extOrTrunc(MaxBits), !IsSigned);
13540 Result =
APSInt(MaxBits, !IsSigned);
13544 switch (BuiltinOp) {
13546 llvm_unreachable(
"Invalid value for BuiltinOp");
13547 case Builtin::BI__builtin_add_overflow:
13548 case Builtin::BI__builtin_sadd_overflow:
13549 case Builtin::BI__builtin_saddl_overflow:
13550 case Builtin::BI__builtin_saddll_overflow:
13551 case Builtin::BI__builtin_uadd_overflow:
13552 case Builtin::BI__builtin_uaddl_overflow:
13553 case Builtin::BI__builtin_uaddll_overflow:
13554 Result = LHS.isSigned() ? LHS.sadd_ov(RHS, DidOverflow)
13555 : LHS.uadd_ov(RHS, DidOverflow);
13557 case Builtin::BI__builtin_sub_overflow:
13558 case Builtin::BI__builtin_ssub_overflow:
13559 case Builtin::BI__builtin_ssubl_overflow:
13560 case Builtin::BI__builtin_ssubll_overflow:
13561 case Builtin::BI__builtin_usub_overflow:
13562 case Builtin::BI__builtin_usubl_overflow:
13563 case Builtin::BI__builtin_usubll_overflow:
13564 Result = LHS.isSigned() ? LHS.ssub_ov(RHS, DidOverflow)
13565 : LHS.usub_ov(RHS, DidOverflow);
13567 case Builtin::BI__builtin_mul_overflow:
13568 case Builtin::BI__builtin_smul_overflow:
13569 case Builtin::BI__builtin_smull_overflow:
13570 case Builtin::BI__builtin_smulll_overflow:
13571 case Builtin::BI__builtin_umul_overflow:
13572 case Builtin::BI__builtin_umull_overflow:
13573 case Builtin::BI__builtin_umulll_overflow:
13574 Result = LHS.isSigned() ? LHS.smul_ov(RHS, DidOverflow)
13575 : LHS.umul_ov(RHS, DidOverflow);
13581 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
13582 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
13583 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
13589 APSInt Temp = Result.extOrTrunc(Info.Ctx.getTypeSize(ResultType));
13592 if (!APSInt::isSameValue(Temp, Result))
13593 DidOverflow =
true;
13603 case Builtin::BI__builtin_reduce_add:
13604 case Builtin::BI__builtin_reduce_mul:
13605 case Builtin::BI__builtin_reduce_and:
13606 case Builtin::BI__builtin_reduce_or:
13607 case Builtin::BI__builtin_reduce_xor:
13608 case Builtin::BI__builtin_reduce_min:
13609 case Builtin::BI__builtin_reduce_max: {
13616 for (
unsigned EltNum = 1; EltNum < SourceLen; ++EltNum) {
13617 switch (BuiltinOp) {
13620 case Builtin::BI__builtin_reduce_add: {
13623 Reduced.getBitWidth() + 1, std::plus<APSInt>(), Reduced))
13627 case Builtin::BI__builtin_reduce_mul: {
13630 Reduced.getBitWidth() * 2, std::multiplies<APSInt>(), Reduced))
13634 case Builtin::BI__builtin_reduce_and: {
13638 case Builtin::BI__builtin_reduce_or: {
13642 case Builtin::BI__builtin_reduce_xor: {
13646 case Builtin::BI__builtin_reduce_min: {
13650 case Builtin::BI__builtin_reduce_max: {
13660 case clang::X86::BI__builtin_ia32_addcarryx_u32:
13661 case clang::X86::BI__builtin_ia32_addcarryx_u64:
13662 case clang::X86::BI__builtin_ia32_subborrow_u32:
13663 case clang::X86::BI__builtin_ia32_subborrow_u64: {
13664 LValue ResultLValue;
13665 APSInt CarryIn, LHS, RHS;
13673 bool IsAdd = BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u32 ||
13674 BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u64;
13676 unsigned BitWidth = LHS.getBitWidth();
13677 unsigned CarryInBit = CarryIn.ugt(0) ? 1 : 0;
13680 ? (LHS.zext(BitWidth + 1) + (RHS.zext(BitWidth + 1) + CarryInBit))
13681 : (LHS.zext(BitWidth + 1) - (RHS.zext(BitWidth + 1) + CarryInBit));
13683 APInt Result = ExResult.extractBits(BitWidth, 0);
13684 uint64_t CarryOut = ExResult.extractBitsAsZExtValue(1, BitWidth);
13692 case clang::X86::BI__builtin_ia32_bextr_u32:
13693 case clang::X86::BI__builtin_ia32_bextr_u64:
13694 case clang::X86::BI__builtin_ia32_bextri_u32:
13695 case clang::X86::BI__builtin_ia32_bextri_u64: {
13701 unsigned BitWidth = Val.getBitWidth();
13703 uint64_t Length = Idx.extractBitsAsZExtValue(8, 8);
13704 Length = Length > BitWidth ? BitWidth : Length;
13707 if (Length == 0 || Shift >= BitWidth)
13711 Result &= llvm::maskTrailingOnes<uint64_t>(Length);
13715 case clang::X86::BI__builtin_ia32_bzhi_si:
13716 case clang::X86::BI__builtin_ia32_bzhi_di: {
13722 unsigned BitWidth = Val.getBitWidth();
13723 unsigned Index = Idx.extractBitsAsZExtValue(8, 0);
13724 if (Index < BitWidth)
13725 Val.clearHighBits(BitWidth - Index);
13729 case clang::X86::BI__builtin_ia32_lzcnt_u16:
13730 case clang::X86::BI__builtin_ia32_lzcnt_u32:
13731 case clang::X86::BI__builtin_ia32_lzcnt_u64: {
13735 return Success(Val.countLeadingZeros(),
E);
13738 case clang::X86::BI__builtin_ia32_tzcnt_u16:
13739 case clang::X86::BI__builtin_ia32_tzcnt_u32:
13740 case clang::X86::BI__builtin_ia32_tzcnt_u64: {
13744 return Success(Val.countTrailingZeros(),
E);
13747 case clang::X86::BI__builtin_ia32_pdep_si:
13748 case clang::X86::BI__builtin_ia32_pdep_di: {
13754 unsigned BitWidth = Val.getBitWidth();
13755 APInt Result = APInt::getZero(BitWidth);
13756 for (
unsigned I = 0,
P = 0; I != BitWidth; ++I)
13758 Result.setBitVal(I, Val[
P++]);
13762 case clang::X86::BI__builtin_ia32_pext_si:
13763 case clang::X86::BI__builtin_ia32_pext_di: {
13769 unsigned BitWidth = Val.getBitWidth();
13770 APInt Result = APInt::getZero(BitWidth);
13771 for (
unsigned I = 0,
P = 0; I != BitWidth; ++I)
13773 Result.setBitVal(
P++, Val[I]);
13782 const LValue &LV) {
13785 if (!LV.getLValueBase())
13790 if (!LV.getLValueDesignator().Invalid &&
13791 !LV.getLValueDesignator().isOnePastTheEnd())
13796 QualType Ty = getType(LV.getLValueBase());
13801 if (LV.getLValueDesignator().Invalid)
13807 return LV.getLValueOffset() == Size;
13817class DataRecursiveIntBinOpEvaluator {
13818 struct EvalResult {
13820 bool Failed =
false;
13822 EvalResult() =
default;
13824 void swap(EvalResult &RHS) {
13826 Failed = RHS.Failed;
13827 RHS.Failed =
false;
13833 EvalResult LHSResult;
13834 enum { AnyExprKind, BinOpKind, BinOpVisitedLHSKind }
Kind;
13837 Job(Job &&) =
default;
13839 void startSpeculativeEval(EvalInfo &Info) {
13840 SpecEvalRAII = SpeculativeEvaluationRAII(Info);
13844 SpeculativeEvaluationRAII SpecEvalRAII;
13849 IntExprEvaluator &IntEval;
13854 DataRecursiveIntBinOpEvaluator(IntExprEvaluator &IntEval,
APValue &Result)
13855 : IntEval(IntEval), Info(IntEval.getEvalInfo()), FinalResult(Result) { }
13862 return E->getOpcode() == BO_Comma ||
E->isLogicalOp() ||
13870 EvalResult PrevResult;
13871 while (!Queue.empty())
13872 process(PrevResult);
13874 if (PrevResult.Failed)
return false;
13876 FinalResult.
swap(PrevResult.Val);
13882 return IntEval.Success(
Value,
E, Result);
13885 return IntEval.Success(
Value,
E, Result);
13888 return IntEval.Error(
E);
13891 return IntEval.Error(
E,
D);
13895 return Info.CCEDiag(
E,
D);
13899 bool VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *
E,
13900 bool &SuppressRHSDiags);
13902 bool VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
13905 void EvaluateExpr(
const Expr *
E, EvalResult &Result) {
13906 Result.Failed = !
Evaluate(Result.Val, Info,
E);
13911 void process(EvalResult &Result);
13913 void enqueue(
const Expr *
E) {
13915 Queue.resize(Queue.size()+1);
13916 Queue.back().E =
E;
13917 Queue.back().Kind = Job::AnyExprKind;
13923bool DataRecursiveIntBinOpEvaluator::
13925 bool &SuppressRHSDiags) {
13926 if (
E->getOpcode() == BO_Comma) {
13928 if (LHSResult.Failed)
13929 return Info.noteSideEffect();
13933 if (
E->isLogicalOp()) {
13938 if (LHSAsBool == (
E->getOpcode() == BO_LOr)) {
13939 Success(LHSAsBool,
E, LHSResult.Val);
13943 LHSResult.Failed =
true;
13947 if (!Info.noteSideEffect())
13953 SuppressRHSDiags =
true;
13962 if (LHSResult.Failed && !Info.noteFailure())
13973 assert(!LVal.
hasLValuePath() &&
"have designator for integer lvalue");
13975 uint64_t Offset64 = Offset.getQuantity();
13976 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
13978 : Offset64 + Index64);
13981bool DataRecursiveIntBinOpEvaluator::
13982 VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
13984 if (
E->getOpcode() == BO_Comma) {
13985 if (RHSResult.Failed)
13987 Result = RHSResult.Val;
13991 if (
E->isLogicalOp()) {
13992 bool lhsResult, rhsResult;
13998 if (
E->getOpcode() == BO_LOr)
13999 return Success(lhsResult || rhsResult,
E, Result);
14001 return Success(lhsResult && rhsResult,
E, Result);
14007 if (rhsResult == (
E->getOpcode() == BO_LOr))
14008 return Success(rhsResult,
E, Result);
14018 if (LHSResult.Failed || RHSResult.Failed)
14021 const APValue &LHSVal = LHSResult.Val;
14022 const APValue &RHSVal = RHSResult.Val;
14032 if (
E->getOpcode() == BO_Add &&
14046 if (!LHSExpr || !RHSExpr)
14048 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
14049 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
14050 if (!LHSAddrExpr || !RHSAddrExpr)
14056 Result =
APValue(LHSAddrExpr, RHSAddrExpr);
14075void DataRecursiveIntBinOpEvaluator::process(EvalResult &Result) {
14076 Job &job = Queue.back();
14078 switch (job.Kind) {
14079 case Job::AnyExprKind: {
14080 if (
const BinaryOperator *Bop = dyn_cast<BinaryOperator>(job.E)) {
14081 if (shouldEnqueue(Bop)) {
14082 job.Kind = Job::BinOpKind;
14083 enqueue(Bop->getLHS());
14088 EvaluateExpr(job.E, Result);
14093 case Job::BinOpKind: {
14095 bool SuppressRHSDiags =
false;
14096 if (!VisitBinOpLHSOnly(Result, Bop, SuppressRHSDiags)) {
14100 if (SuppressRHSDiags)
14101 job.startSpeculativeEval(Info);
14102 job.LHSResult.swap(Result);
14103 job.Kind = Job::BinOpVisitedLHSKind;
14108 case Job::BinOpVisitedLHSKind: {
14112 Result.Failed = !VisitBinOp(job.LHSResult, RHS, Bop, Result.Val);
14118 llvm_unreachable(
"Invalid Job::Kind!");
14122enum class CmpResult {
14131template <
class SuccessCB,
class AfterCB>
14134 SuccessCB &&
Success, AfterCB &&DoAfter) {
14136 assert(
E->isComparisonOp() &&
"expected comparison operator");
14137 assert((
E->getOpcode() == BO_Cmp ||
14139 "unsupported binary expression evaluation");
14140 auto Error = [&](
const Expr *
E) {
14141 Info.FFDiag(
E, diag::note_invalid_subexpr_in_const_expr);
14145 bool IsRelational =
E->isRelationalOp() ||
E->getOpcode() == BO_Cmp;
14146 bool IsEquality =
E->isEqualityOp();
14155 if (!LHSOK && !Info.noteFailure())
14160 return Success(CmpResult::Less,
E);
14162 return Success(CmpResult::Greater,
E);
14163 return Success(CmpResult::Equal,
E);
14167 APFixedPoint LHSFX(Info.Ctx.getFixedPointSemantics(LHSTy));
14168 APFixedPoint RHSFX(Info.Ctx.getFixedPointSemantics(RHSTy));
14171 if (!LHSOK && !Info.noteFailure())
14176 return Success(CmpResult::Less,
E);
14178 return Success(CmpResult::Greater,
E);
14179 return Success(CmpResult::Equal,
E);
14183 ComplexValue LHS, RHS;
14185 if (
E->isAssignmentOp()) {
14192 LHS.makeComplexFloat();
14193 LHS.FloatImag = APFloat(LHS.FloatReal.getSemantics());
14198 if (!LHSOK && !Info.noteFailure())
14204 RHS.makeComplexFloat();
14205 RHS.FloatImag = APFloat(RHS.FloatReal.getSemantics());
14209 if (LHS.isComplexFloat()) {
14210 APFloat::cmpResult CR_r =
14211 LHS.getComplexFloatReal().compare(RHS.getComplexFloatReal());
14212 APFloat::cmpResult CR_i =
14213 LHS.getComplexFloatImag().compare(RHS.getComplexFloatImag());
14214 bool IsEqual = CR_r == APFloat::cmpEqual && CR_i == APFloat::cmpEqual;
14215 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal,
E);
14217 assert(IsEquality &&
"invalid complex comparison");
14218 bool IsEqual = LHS.getComplexIntReal() == RHS.getComplexIntReal() &&
14219 LHS.getComplexIntImag() == RHS.getComplexIntImag();
14220 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal,
E);
14226 APFloat RHS(0.0), LHS(0.0);
14229 if (!LHSOK && !Info.noteFailure())
14235 assert(
E->isComparisonOp() &&
"Invalid binary operator!");
14236 llvm::APFloatBase::cmpResult APFloatCmpResult = LHS.compare(RHS);
14237 if (!Info.InConstantContext &&
14238 APFloatCmpResult == APFloat::cmpUnordered &&
14241 Info.FFDiag(
E, diag::note_constexpr_float_arithmetic_strict);
14244 auto GetCmpRes = [&]() {
14245 switch (APFloatCmpResult) {
14246 case APFloat::cmpEqual:
14247 return CmpResult::Equal;
14248 case APFloat::cmpLessThan:
14249 return CmpResult::Less;
14250 case APFloat::cmpGreaterThan:
14251 return CmpResult::Greater;
14252 case APFloat::cmpUnordered:
14253 return CmpResult::Unordered;
14255 llvm_unreachable(
"Unrecognised APFloat::cmpResult enum");
14261 LValue LHSValue, RHSValue;
14264 if (!LHSOK && !Info.noteFailure())
14273 auto DiagComparison = [&] (
unsigned DiagID,
bool Reversed =
false) {
14274 std::string LHS = LHSValue.toString(Info.Ctx,
E->getLHS()->
getType());
14275 std::string RHS = RHSValue.toString(Info.Ctx,
E->getRHS()->
getType());
14276 Info.FFDiag(
E, DiagID)
14283 return DiagComparison(
14284 diag::note_constexpr_pointer_comparison_unspecified);
14290 if ((!LHSValue.Base && !LHSValue.Offset.isZero()) ||
14291 (!RHSValue.Base && !RHSValue.Offset.isZero()))
14292 return DiagComparison(diag::note_constexpr_pointer_constant_comparison,
14306 return DiagComparison(diag::note_constexpr_literal_comparison);
14308 return DiagComparison(diag::note_constexpr_opaque_call_comparison,
14313 return DiagComparison(diag::note_constexpr_pointer_weak_comparison,
14317 if (LHSValue.Base && LHSValue.Offset.isZero() &&
14319 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
14321 if (RHSValue.Base && RHSValue.Offset.isZero() &&
14323 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
14329 return DiagComparison(
14330 diag::note_constexpr_pointer_comparison_zero_sized);
14331 return Success(CmpResult::Unequal,
E);
14334 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
14335 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
14337 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
14338 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
14348 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid && IsRelational) {
14349 bool WasArrayIndex;
14351 getType(LHSValue.Base), LHSDesignator, RHSDesignator, WasArrayIndex);
14358 if (!WasArrayIndex && Mismatch < LHSDesignator.Entries.size() &&
14359 Mismatch < RHSDesignator.Entries.size()) {
14360 const FieldDecl *LF = getAsField(LHSDesignator.Entries[Mismatch]);
14361 const FieldDecl *RF = getAsField(RHSDesignator.Entries[Mismatch]);
14363 Info.CCEDiag(
E, diag::note_constexpr_pointer_comparison_base_classes);
14365 Info.CCEDiag(
E, diag::note_constexpr_pointer_comparison_base_field)
14366 << getAsBaseClass(LHSDesignator.Entries[Mismatch])
14369 Info.CCEDiag(
E, diag::note_constexpr_pointer_comparison_base_field)
14370 << getAsBaseClass(RHSDesignator.Entries[Mismatch])
14375 diag::note_constexpr_pointer_comparison_differing_access)
14383 unsigned PtrSize = Info.Ctx.getTypeSize(LHSTy);
14386 assert(PtrSize <= 64 &&
"Unexpected pointer width");
14387 uint64_t Mask = ~0ULL >> (64 - PtrSize);
14388 CompareLHS &= Mask;
14389 CompareRHS &= Mask;
14394 if (!LHSValue.Base.isNull() && IsRelational) {
14395 QualType BaseTy = getType(LHSValue.Base);
14398 CharUnits Size = Info.Ctx.getTypeSizeInChars(BaseTy);
14399 uint64_t OffsetLimit = Size.getQuantity();
14400 if (CompareLHS > OffsetLimit || CompareRHS > OffsetLimit)
14404 if (CompareLHS < CompareRHS)
14405 return Success(CmpResult::Less,
E);
14406 if (CompareLHS > CompareRHS)
14407 return Success(CmpResult::Greater,
E);
14408 return Success(CmpResult::Equal,
E);
14412 assert(IsEquality &&
"unexpected member pointer operation");
14415 MemberPtr LHSValue, RHSValue;
14418 if (!LHSOK && !Info.noteFailure())
14426 if (LHSValue.getDecl() && LHSValue.getDecl()->isWeak()) {
14427 Info.FFDiag(
E, diag::note_constexpr_mem_pointer_weak_comparison)
14428 << LHSValue.getDecl();
14431 if (RHSValue.getDecl() && RHSValue.getDecl()->isWeak()) {
14432 Info.FFDiag(
E, diag::note_constexpr_mem_pointer_weak_comparison)
14433 << RHSValue.getDecl();
14440 if (!LHSValue.getDecl() || !RHSValue.getDecl()) {
14441 bool Equal = !LHSValue.getDecl() && !RHSValue.getDecl();
14442 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal,
E);
14447 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(LHSValue.getDecl()))
14448 if (MD->isVirtual())
14449 Info.CCEDiag(
E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
14450 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(RHSValue.getDecl()))
14451 if (MD->isVirtual())
14452 Info.CCEDiag(
E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
14458 bool Equal = LHSValue == RHSValue;
14459 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal,
E);
14463 assert(
E->isComparisonOp() &&
"unexpected nullptr operation");
14464 assert(RHSTy->
isNullPtrType() &&
"missing pointer conversion");
14472 return Success(CmpResult::Equal,
E);
14485 case CmpResult::Unequal:
14486 llvm_unreachable(
"should never produce Unequal for three-way comparison");
14487 case CmpResult::Less:
14488 CCR = ComparisonCategoryResult::Less;
14490 case CmpResult::Equal:
14491 CCR = ComparisonCategoryResult::Equal;
14493 case CmpResult::Greater:
14494 CCR = ComparisonCategoryResult::Greater;
14496 case CmpResult::Unordered:
14497 CCR = ComparisonCategoryResult::Unordered;
14511 ConstantExprKind::Normal);
14514 return ExprEvaluatorBaseTy::VisitBinCmp(
E);
14518bool RecordExprEvaluator::VisitCXXParenListInitExpr(
14520 return VisitCXXParenListOrInitListExpr(
E,
E->getInitExprs());
14526 if (
E->isAssignmentOp()) {
14528 if (!Info.noteFailure())
14532 if (DataRecursiveIntBinOpEvaluator::shouldEnqueue(
E))
14533 return DataRecursiveIntBinOpEvaluator(*
this, Result).Traverse(
E);
14537 "DataRecursiveIntBinOpEvaluator should have handled integral types");
14539 if (
E->isComparisonOp()) {
14543 assert((CR != CmpResult::Unequal ||
E->isEqualityOp()) &&
14544 "should only produce Unequal for equality comparisons");
14545 bool IsEqual = CR == CmpResult::Equal,
14546 IsLess = CR == CmpResult::Less,
14547 IsGreater = CR == CmpResult::Greater;
14548 auto Op =
E->getOpcode();
14551 llvm_unreachable(
"unsupported binary operator");
14554 return Success(IsEqual == (Op == BO_EQ),
E);
14560 return Success(IsEqual || IsLess,
E);
14562 return Success(IsEqual || IsGreater,
E);
14566 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
14574 E->getOpcode() == BO_Sub) {
14575 LValue LHSValue, RHSValue;
14578 if (!LHSOK && !Info.noteFailure())
14588 if (!LHSValue.Offset.isZero() || !RHSValue.Offset.isZero())
14590 const Expr *LHSExpr = LHSValue.Base.dyn_cast<
const Expr *>();
14591 const Expr *RHSExpr = RHSValue.Base.dyn_cast<
const Expr *>();
14592 if (!LHSExpr || !RHSExpr)
14594 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
14595 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
14596 if (!LHSAddrExpr || !RHSAddrExpr)
14604 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
14605 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
14607 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
14608 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
14614 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid &&
14617 Info.CCEDiag(
E, diag::note_constexpr_pointer_subtraction_not_same_array);
14629 if (ElementSize.
isZero()) {
14630 Info.FFDiag(
E, diag::note_constexpr_pointer_subtraction_zero_size)
14647 APSInt TrueResult = (LHS - RHS) / ElemSize;
14648 APSInt Result = TrueResult.trunc(Info.Ctx.getIntWidth(
E->
getType()));
14650 if (Result.extend(65) != TrueResult &&
14656 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
14661bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr(
14663 switch(
E->getKind()) {
14664 case UETT_PreferredAlignOf:
14665 case UETT_AlignOf: {
14666 if (
E->isArgumentType())
14674 case UETT_PtrAuthTypeDiscriminator: {
14675 if (
E->getArgumentType()->isDependentType())
14678 Info.Ctx.getPointerAuthTypeDiscriminator(
E->getArgumentType()),
E);
14680 case UETT_VecStep: {
14696 case UETT_DataSizeOf:
14697 case UETT_SizeOf: {
14698 QualType SrcTy =
E->getTypeOfArgument();
14706 E->getKind() == UETT_DataSizeOf ? SizeOfType::DataSizeOf
14707 : SizeOfType::SizeOf)) {
14712 case UETT_OpenMPRequiredSimdAlign:
14713 assert(
E->isArgumentType());
14715 Info.Ctx.toCharUnitsFromBits(
14716 Info.Ctx.getOpenMPDefaultSimdAlign(
E->getArgumentType()))
14719 case UETT_VectorElements: {
14727 if (Info.InConstantContext)
14728 Info.CCEDiag(
E, diag::note_constexpr_non_const_vectorelements)
14735 llvm_unreachable(
"unknown expr/type trait");
14738bool IntExprEvaluator::VisitOffsetOfExpr(
const OffsetOfExpr *OOE) {
14744 for (
unsigned i = 0; i != n; ++i) {
14752 const ArrayType *AT = Info.Ctx.getAsArrayType(CurrentType);
14756 CharUnits ElementSize = Info.Ctx.getTypeSizeInChars(CurrentType);
14757 Result += IdxResult.getSExtValue() * ElementSize;
14770 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
14777 llvm_unreachable(
"dependent __builtin_offsetof");
14793 CurrentType = BaseSpec->
getType();
14807bool IntExprEvaluator::VisitUnaryOperator(
const UnaryOperator *
E) {
14808 switch (
E->getOpcode()) {
14816 return Visit(
E->getSubExpr());
14819 return Visit(
E->getSubExpr());
14821 if (!Visit(
E->getSubExpr()))
14823 if (!Result.isInt())
return Error(
E);
14825 if (
Value.isSigned() &&
Value.isMinSignedValue() &&
E->canOverflow()) {
14826 if (Info.checkingForUndefinedBehavior())
14827 Info.Ctx.getDiagnostics().Report(
E->
getExprLoc(),
14828 diag::warn_integer_constant_overflow)
14840 if (!Visit(
E->getSubExpr()))
14842 if (!Result.isInt())
return Error(
E);
14843 return Success(~Result.getInt(),
E);
14856bool IntExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
14857 const Expr *SubExpr =
E->getSubExpr();
14861 switch (
E->getCastKind()) {
14862 case CK_BaseToDerived:
14863 case CK_DerivedToBase:
14864 case CK_UncheckedDerivedToBase:
14867 case CK_ArrayToPointerDecay:
14868 case CK_FunctionToPointerDecay:
14869 case CK_NullToPointer:
14870 case CK_NullToMemberPointer:
14871 case CK_BaseToDerivedMemberPointer:
14872 case CK_DerivedToBaseMemberPointer:
14873 case CK_ReinterpretMemberPointer:
14874 case CK_ConstructorConversion:
14875 case CK_IntegralToPointer:
14877 case CK_VectorSplat:
14878 case CK_IntegralToFloating:
14879 case CK_FloatingCast:
14880 case CK_CPointerToObjCPointerCast:
14881 case CK_BlockPointerToObjCPointerCast:
14882 case CK_AnyPointerToBlockPointerCast:
14883 case CK_ObjCObjectLValueCast:
14884 case CK_FloatingRealToComplex:
14885 case CK_FloatingComplexToReal:
14886 case CK_FloatingComplexCast:
14887 case CK_FloatingComplexToIntegralComplex:
14888 case CK_IntegralRealToComplex:
14889 case CK_IntegralComplexCast:
14890 case CK_IntegralComplexToFloatingComplex:
14891 case CK_BuiltinFnToFnPtr:
14892 case CK_ZeroToOCLOpaqueType:
14893 case CK_NonAtomicToAtomic:
14894 case CK_AddressSpaceConversion:
14895 case CK_IntToOCLSampler:
14896 case CK_FloatingToFixedPoint:
14897 case CK_FixedPointToFloating:
14898 case CK_FixedPointCast:
14899 case CK_IntegralToFixedPoint:
14900 case CK_MatrixCast:
14901 llvm_unreachable(
"invalid cast kind for integral value");
14905 case CK_LValueBitCast:
14906 case CK_ARCProduceObject:
14907 case CK_ARCConsumeObject:
14908 case CK_ARCReclaimReturnedObject:
14909 case CK_ARCExtendBlockObject:
14910 case CK_CopyAndAutoreleaseBlockObject:
14913 case CK_UserDefinedConversion:
14914 case CK_LValueToRValue:
14915 case CK_AtomicToNonAtomic:
14917 case CK_LValueToRValueBitCast:
14918 case CK_HLSLArrayRValue:
14919 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
14921 case CK_MemberPointerToBoolean:
14922 case CK_PointerToBoolean:
14923 case CK_IntegralToBoolean:
14924 case CK_FloatingToBoolean:
14925 case CK_BooleanToSignedIntegral:
14926 case CK_FloatingComplexToBoolean:
14927 case CK_IntegralComplexToBoolean: {
14932 if (BoolResult &&
E->getCastKind() == CK_BooleanToSignedIntegral)
14937 case CK_FixedPointToIntegral: {
14938 APFixedPoint Src(Info.Ctx.getFixedPointSemantics(SrcType));
14942 llvm::APSInt Result = Src.convertToInt(
14943 Info.Ctx.getIntWidth(DestType),
14950 case CK_FixedPointToBoolean: {
14953 if (!
Evaluate(Val, Info, SubExpr))
14958 case CK_IntegralCast: {
14959 if (!Visit(SubExpr))
14962 if (!Result.isInt()) {
14968 if (Result.isAddrLabelDiff())
14969 return Info.Ctx.getTypeSize(DestType) <= Info.Ctx.getTypeSize(SrcType);
14971 return Info.Ctx.getTypeSize(DestType) == Info.Ctx.getTypeSize(SrcType);
14974 if (Info.Ctx.getLangOpts().CPlusPlus && Info.InConstantContext &&
14975 Info.EvalMode == EvalInfo::EM_ConstantExpression &&
14978 bool ConstexprVar =
true;
14985 if (
const auto *VD = dyn_cast_or_null<VarDecl>(
14986 Info.EvaluatingDecl.dyn_cast<
const ValueDecl *>()))
15009 (
Max.slt(Result.getInt().getSExtValue()) ||
15010 Min.sgt(Result.getInt().getSExtValue())))
15011 Info.CCEDiag(
E, diag::note_constexpr_unscoped_enum_out_of_range)
15012 << llvm::toString(Result.getInt(), 10) <<
Min.getSExtValue()
15013 <<
Max.getSExtValue() << ED;
15015 Max.ult(Result.getInt().getZExtValue()))
15016 Info.CCEDiag(
E, diag::note_constexpr_unscoped_enum_out_of_range)
15017 << llvm::toString(Result.getInt(), 10) <<
Min.getZExtValue()
15018 <<
Max.getZExtValue() << ED;
15023 Result.getInt()),
E);
15026 case CK_PointerToIntegral: {
15027 CCEDiag(
E, diag::note_constexpr_invalid_cast)
15034 if (LV.getLValueBase()) {
15039 if (Info.Ctx.getTypeSize(DestType) != Info.Ctx.getTypeSize(SrcType))
15042 LV.Designator.setInvalid();
15043 LV.moveInto(Result);
15050 if (!
V.toIntegralConstant(AsInt, SrcType, Info.Ctx))
15051 llvm_unreachable(
"Can't cast this!");
15056 case CK_IntegralComplexToReal: {
15060 return Success(
C.getComplexIntReal(),
E);
15063 case CK_FloatingToIntegral: {
15073 case CK_HLSLVectorTruncation: {
15081 llvm_unreachable(
"unknown cast resulting in integral value");
15089 if (!LV.isComplexInt())
15091 return Success(LV.getComplexIntReal(),
E);
15094 return Visit(
E->getSubExpr());
15102 if (!LV.isComplexInt())
15104 return Success(LV.getComplexIntImag(),
E);
15107 VisitIgnoredValue(
E->getSubExpr());
15119bool IntExprEvaluator::VisitConceptSpecializationExpr(
15124bool IntExprEvaluator::VisitRequiresExpr(
const RequiresExpr *
E) {
15128bool FixedPointExprEvaluator::VisitUnaryOperator(
const UnaryOperator *
E) {
15129 switch (
E->getOpcode()) {
15135 return Visit(
E->getSubExpr());
15137 if (!Visit(
E->getSubExpr()))
return false;
15138 if (!Result.isFixedPoint())
15141 APFixedPoint Negated = Result.getFixedPoint().negate(&Overflowed);
15155bool FixedPointExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
15156 const Expr *SubExpr =
E->getSubExpr();
15159 "Expected destination type to be a fixed point type");
15160 auto DestFXSema = Info.Ctx.getFixedPointSemantics(DestType);
15162 switch (
E->getCastKind()) {
15163 case CK_FixedPointCast: {
15164 APFixedPoint Src(Info.Ctx.getFixedPointSemantics(SubExpr->
getType()));
15168 APFixedPoint Result = Src.convert(DestFXSema, &Overflowed);
15170 if (Info.checkingForUndefinedBehavior())
15171 Info.Ctx.getDiagnostics().Report(
E->
getExprLoc(),
15172 diag::warn_fixedpoint_constant_overflow)
15173 << Result.toString() <<
E->
getType();
15179 case CK_IntegralToFixedPoint: {
15185 APFixedPoint IntResult = APFixedPoint::getFromIntValue(
15186 Src, Info.Ctx.getFixedPointSemantics(DestType), &Overflowed);
15189 if (Info.checkingForUndefinedBehavior())
15190 Info.Ctx.getDiagnostics().Report(
E->
getExprLoc(),
15191 diag::warn_fixedpoint_constant_overflow)
15192 << IntResult.toString() <<
E->
getType();
15199 case CK_FloatingToFixedPoint: {
15205 APFixedPoint Result = APFixedPoint::getFromFloatValue(
15206 Src, Info.Ctx.getFixedPointSemantics(DestType), &Overflowed);
15209 if (Info.checkingForUndefinedBehavior())
15210 Info.Ctx.getDiagnostics().Report(
E->
getExprLoc(),
15211 diag::warn_fixedpoint_constant_overflow)
15212 << Result.toString() <<
E->
getType();
15220 case CK_LValueToRValue:
15221 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
15227bool FixedPointExprEvaluator::VisitBinaryOperator(
const BinaryOperator *
E) {
15228 if (
E->isPtrMemOp() ||
E->isAssignmentOp() ||
E->getOpcode() == BO_Comma)
15229 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
15231 const Expr *LHS =
E->getLHS();
15232 const Expr *RHS =
E->getRHS();
15234 Info.Ctx.getFixedPointSemantics(
E->
getType());
15236 APFixedPoint LHSFX(Info.Ctx.getFixedPointSemantics(LHS->
getType()));
15239 APFixedPoint RHSFX(Info.Ctx.getFixedPointSemantics(RHS->
getType()));
15243 bool OpOverflow =
false, ConversionOverflow =
false;
15244 APFixedPoint Result(LHSFX.getSemantics());
15245 switch (
E->getOpcode()) {
15247 Result = LHSFX.
add(RHSFX, &OpOverflow)
15248 .convert(ResultFXSema, &ConversionOverflow);
15252 Result = LHSFX.sub(RHSFX, &OpOverflow)
15253 .convert(ResultFXSema, &ConversionOverflow);
15257 Result = LHSFX.mul(RHSFX, &OpOverflow)
15258 .convert(ResultFXSema, &ConversionOverflow);
15262 if (RHSFX.getValue() == 0) {
15263 Info.FFDiag(
E, diag::note_expr_divide_by_zero);
15266 Result = LHSFX.div(RHSFX, &OpOverflow)
15267 .convert(ResultFXSema, &ConversionOverflow);
15273 llvm::APSInt RHSVal = RHSFX.getValue();
15276 LHSSema.getWidth() - (
unsigned)LHSSema.hasUnsignedPadding();
15277 unsigned Amt = RHSVal.getLimitedValue(ShiftBW - 1);
15281 if (RHSVal.isNegative())
15282 Info.CCEDiag(
E, diag::note_constexpr_negative_shift) << RHSVal;
15283 else if (Amt != RHSVal)
15284 Info.CCEDiag(
E, diag::note_constexpr_large_shift)
15285 << RHSVal <<
E->
getType() << ShiftBW;
15287 if (
E->getOpcode() == BO_Shl)
15288 Result = LHSFX.shl(Amt, &OpOverflow);
15290 Result = LHSFX.shr(Amt, &OpOverflow);
15296 if (OpOverflow || ConversionOverflow) {
15297 if (Info.checkingForUndefinedBehavior())
15298 Info.Ctx.getDiagnostics().Report(
E->
getExprLoc(),
15299 diag::warn_fixedpoint_constant_overflow)
15300 << Result.toString() <<
E->
getType();
15312class FloatExprEvaluator
15313 :
public ExprEvaluatorBase<FloatExprEvaluator> {
15316 FloatExprEvaluator(EvalInfo &info, APFloat &result)
15317 : ExprEvaluatorBaseTy(info), Result(result) {}
15320 Result =
V.getFloat();
15324 bool ZeroInitialization(
const Expr *
E) {
15325 Result = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(
E->
getType()));
15346 return FloatExprEvaluator(Info, Result).Visit(
E);
15353 llvm::APFloat &Result) {
15355 if (!S)
return false;
15362 if (S->getString().empty())
15363 fill = llvm::APInt(32, 0);
15364 else if (S->getString().getAsInteger(0, fill))
15369 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
15371 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
15379 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
15381 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
15387bool FloatExprEvaluator::VisitCallExpr(
const CallExpr *
E) {
15388 if (!IsConstantEvaluatedBuiltinCall(
E))
15389 return ExprEvaluatorBaseTy::VisitCallExpr(
E);
15391 switch (
E->getBuiltinCallee()) {
15395 case Builtin::BI__builtin_huge_val:
15396 case Builtin::BI__builtin_huge_valf:
15397 case Builtin::BI__builtin_huge_vall:
15398 case Builtin::BI__builtin_huge_valf16:
15399 case Builtin::BI__builtin_huge_valf128:
15400 case Builtin::BI__builtin_inf:
15401 case Builtin::BI__builtin_inff:
15402 case Builtin::BI__builtin_infl:
15403 case Builtin::BI__builtin_inff16:
15404 case Builtin::BI__builtin_inff128: {
15405 const llvm::fltSemantics &Sem =
15406 Info.Ctx.getFloatTypeSemantics(
E->
getType());
15407 Result = llvm::APFloat::getInf(Sem);
15411 case Builtin::BI__builtin_nans:
15412 case Builtin::BI__builtin_nansf:
15413 case Builtin::BI__builtin_nansl:
15414 case Builtin::BI__builtin_nansf16:
15415 case Builtin::BI__builtin_nansf128:
15421 case Builtin::BI__builtin_nan:
15422 case Builtin::BI__builtin_nanf:
15423 case Builtin::BI__builtin_nanl:
15424 case Builtin::BI__builtin_nanf16:
15425 case Builtin::BI__builtin_nanf128:
15433 case Builtin::BI__builtin_fabs:
15434 case Builtin::BI__builtin_fabsf:
15435 case Builtin::BI__builtin_fabsl:
15436 case Builtin::BI__builtin_fabsf128:
15445 if (Result.isNegative())
15446 Result.changeSign();
15449 case Builtin::BI__arithmetic_fence:
15456 case Builtin::BI__builtin_copysign:
15457 case Builtin::BI__builtin_copysignf:
15458 case Builtin::BI__builtin_copysignl:
15459 case Builtin::BI__builtin_copysignf128: {
15464 Result.copySign(RHS);
15468 case Builtin::BI__builtin_fmax:
15469 case Builtin::BI__builtin_fmaxf:
15470 case Builtin::BI__builtin_fmaxl:
15471 case Builtin::BI__builtin_fmaxf16:
15472 case Builtin::BI__builtin_fmaxf128: {
15479 if (Result.isZero() && RHS.isZero() && Result.isNegative())
15481 else if (Result.isNaN() || RHS > Result)
15486 case Builtin::BI__builtin_fmin:
15487 case Builtin::BI__builtin_fminf:
15488 case Builtin::BI__builtin_fminl:
15489 case Builtin::BI__builtin_fminf16:
15490 case Builtin::BI__builtin_fminf128: {
15497 if (Result.isZero() && RHS.isZero() && RHS.isNegative())
15499 else if (Result.isNaN() || RHS < Result)
15504 case Builtin::BI__builtin_fmaximum_num:
15505 case Builtin::BI__builtin_fmaximum_numf:
15506 case Builtin::BI__builtin_fmaximum_numl:
15507 case Builtin::BI__builtin_fmaximum_numf16:
15508 case Builtin::BI__builtin_fmaximum_numf128: {
15513 Result = maximumnum(Result, RHS);
15517 case Builtin::BI__builtin_fminimum_num:
15518 case Builtin::BI__builtin_fminimum_numf:
15519 case Builtin::BI__builtin_fminimum_numl:
15520 case Builtin::BI__builtin_fminimum_numf16:
15521 case Builtin::BI__builtin_fminimum_numf128: {
15526 Result = minimumnum(Result, RHS);
15532bool FloatExprEvaluator::VisitUnaryReal(
const UnaryOperator *
E) {
15537 Result = CV.FloatReal;
15541 return Visit(
E->getSubExpr());
15544bool FloatExprEvaluator::VisitUnaryImag(
const UnaryOperator *
E) {
15549 Result = CV.FloatImag;
15553 VisitIgnoredValue(
E->getSubExpr());
15554 const llvm::fltSemantics &Sem = Info.Ctx.getFloatTypeSemantics(
E->
getType());
15555 Result = llvm::APFloat::getZero(Sem);
15559bool FloatExprEvaluator::VisitUnaryOperator(
const UnaryOperator *
E) {
15560 switch (
E->getOpcode()) {
15561 default:
return Error(
E);
15570 Result.changeSign();
15575bool FloatExprEvaluator::VisitBinaryOperator(
const BinaryOperator *
E) {
15576 if (
E->isPtrMemOp() ||
E->isAssignmentOp() ||
E->getOpcode() == BO_Comma)
15577 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
15581 if (!LHSOK && !Info.noteFailure())
15588 Result =
E->getValue();
15592bool FloatExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
15593 const Expr* SubExpr =
E->getSubExpr();
15595 switch (
E->getCastKind()) {
15597 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
15599 case CK_IntegralToFloating: {
15602 Info.Ctx.getLangOpts());
15608 case CK_FixedPointToFloating: {
15609 APFixedPoint FixResult(Info.Ctx.getFixedPointSemantics(SubExpr->
getType()));
15613 FixResult.convertToFloat(Info.Ctx.getFloatTypeSemantics(
E->
getType()));
15617 case CK_FloatingCast: {
15618 if (!Visit(SubExpr))
15624 case CK_FloatingComplexToReal: {
15628 Result =
V.getComplexFloatReal();
15631 case CK_HLSLVectorTruncation: {
15645class ComplexExprEvaluator
15646 :
public ExprEvaluatorBase<ComplexExprEvaluator> {
15647 ComplexValue &Result;
15650 ComplexExprEvaluator(EvalInfo &info, ComplexValue &Result)
15651 : ExprEvaluatorBaseTy(info), Result(Result) {}
15658 bool ZeroInitialization(
const Expr *
E);
15677 return ComplexExprEvaluator(Info, Result).Visit(
E);
15680bool ComplexExprEvaluator::ZeroInitialization(
const Expr *
E) {
15683 Result.makeComplexFloat();
15684 APFloat Zero = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(ElemTy));
15685 Result.FloatReal =
Zero;
15686 Result.FloatImag =
Zero;
15688 Result.makeComplexInt();
15689 APSInt Zero = Info.Ctx.MakeIntValue(0, ElemTy);
15690 Result.IntReal =
Zero;
15691 Result.IntImag =
Zero;
15697 const Expr* SubExpr =
E->getSubExpr();
15700 Result.makeComplexFloat();
15701 APFloat &Imag = Result.FloatImag;
15705 Result.FloatReal =
APFloat(Imag.getSemantics());
15709 "Unexpected imaginary literal.");
15711 Result.makeComplexInt();
15712 APSInt &Imag = Result.IntImag;
15716 Result.IntReal =
APSInt(Imag.getBitWidth(), !Imag.isSigned());
15721bool ComplexExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
15723 switch (
E->getCastKind()) {
15725 case CK_BaseToDerived:
15726 case CK_DerivedToBase:
15727 case CK_UncheckedDerivedToBase:
15730 case CK_ArrayToPointerDecay:
15731 case CK_FunctionToPointerDecay:
15732 case CK_NullToPointer:
15733 case CK_NullToMemberPointer:
15734 case CK_BaseToDerivedMemberPointer:
15735 case CK_DerivedToBaseMemberPointer:
15736 case CK_MemberPointerToBoolean:
15737 case CK_ReinterpretMemberPointer:
15738 case CK_ConstructorConversion:
15739 case CK_IntegralToPointer:
15740 case CK_PointerToIntegral:
15741 case CK_PointerToBoolean:
15743 case CK_VectorSplat:
15744 case CK_IntegralCast:
15745 case CK_BooleanToSignedIntegral:
15746 case CK_IntegralToBoolean:
15747 case CK_IntegralToFloating:
15748 case CK_FloatingToIntegral:
15749 case CK_FloatingToBoolean:
15750 case CK_FloatingCast:
15751 case CK_CPointerToObjCPointerCast:
15752 case CK_BlockPointerToObjCPointerCast:
15753 case CK_AnyPointerToBlockPointerCast:
15754 case CK_ObjCObjectLValueCast:
15755 case CK_FloatingComplexToReal:
15756 case CK_FloatingComplexToBoolean:
15757 case CK_IntegralComplexToReal:
15758 case CK_IntegralComplexToBoolean:
15759 case CK_ARCProduceObject:
15760 case CK_ARCConsumeObject:
15761 case CK_ARCReclaimReturnedObject:
15762 case CK_ARCExtendBlockObject:
15763 case CK_CopyAndAutoreleaseBlockObject:
15764 case CK_BuiltinFnToFnPtr:
15765 case CK_ZeroToOCLOpaqueType:
15766 case CK_NonAtomicToAtomic:
15767 case CK_AddressSpaceConversion:
15768 case CK_IntToOCLSampler:
15769 case CK_FloatingToFixedPoint:
15770 case CK_FixedPointToFloating:
15771 case CK_FixedPointCast:
15772 case CK_FixedPointToBoolean:
15773 case CK_FixedPointToIntegral:
15774 case CK_IntegralToFixedPoint:
15775 case CK_MatrixCast:
15776 case CK_HLSLVectorTruncation:
15777 llvm_unreachable(
"invalid cast kind for complex value");
15779 case CK_LValueToRValue:
15780 case CK_AtomicToNonAtomic:
15782 case CK_LValueToRValueBitCast:
15783 case CK_HLSLArrayRValue:
15784 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
15787 case CK_LValueBitCast:
15788 case CK_UserDefinedConversion:
15791 case CK_FloatingRealToComplex: {
15792 APFloat &Real = Result.FloatReal;
15796 Result.makeComplexFloat();
15797 Result.FloatImag =
APFloat(Real.getSemantics());
15801 case CK_FloatingComplexCast: {
15802 if (!Visit(
E->getSubExpr()))
15813 case CK_FloatingComplexToIntegralComplex: {
15814 if (!Visit(
E->getSubExpr()))
15820 Result.makeComplexInt();
15822 To, Result.IntReal) &&
15824 To, Result.IntImag);
15827 case CK_IntegralRealToComplex: {
15828 APSInt &Real = Result.IntReal;
15832 Result.makeComplexInt();
15833 Result.IntImag =
APSInt(Real.getBitWidth(), !Real.isSigned());
15837 case CK_IntegralComplexCast: {
15838 if (!Visit(
E->getSubExpr()))
15850 case CK_IntegralComplexToFloatingComplex: {
15851 if (!Visit(
E->getSubExpr()))
15855 Info.Ctx.getLangOpts());
15859 Result.makeComplexFloat();
15861 To, Result.FloatReal) &&
15863 To, Result.FloatImag);
15867 llvm_unreachable(
"unknown cast resulting in complex value");
15871 APFloat &ResR, APFloat &ResI) {
15877 APFloat AC = A *
C;
15878 APFloat BD = B *
D;
15879 APFloat AD = A *
D;
15880 APFloat BC = B *
C;
15883 if (ResR.isNaN() && ResI.isNaN()) {
15884 bool Recalc =
false;
15885 if (A.isInfinity() || B.isInfinity()) {
15886 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
15888 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
15891 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
15893 D = APFloat::copySign(APFloat(
D.getSemantics()),
D);
15896 if (
C.isInfinity() ||
D.isInfinity()) {
15897 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
15899 D = APFloat::copySign(APFloat(
D.getSemantics(),
D.isInfinity() ? 1 : 0),
15902 A = APFloat::copySign(APFloat(A.getSemantics()), A);
15904 B = APFloat::copySign(APFloat(B.getSemantics()), B);
15907 if (!Recalc && (AC.isInfinity() || BD.isInfinity() || AD.isInfinity() ||
15908 BC.isInfinity())) {
15910 A = APFloat::copySign(APFloat(A.getSemantics()), A);
15912 B = APFloat::copySign(APFloat(B.getSemantics()), B);
15914 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
15916 D = APFloat::copySign(APFloat(
D.getSemantics()),
D);
15920 ResR = APFloat::getInf(A.getSemantics()) * (A *
C - B *
D);
15921 ResI = APFloat::getInf(A.getSemantics()) * (A *
D + B *
C);
15927 APFloat &ResR, APFloat &ResI) {
15934 APFloat MaxCD = maxnum(
abs(
C),
abs(
D));
15935 if (MaxCD.isFinite()) {
15936 DenomLogB =
ilogb(MaxCD);
15937 C =
scalbn(
C, -DenomLogB, APFloat::rmNearestTiesToEven);
15938 D =
scalbn(
D, -DenomLogB, APFloat::rmNearestTiesToEven);
15940 APFloat Denom =
C *
C +
D *
D;
15942 scalbn((A *
C + B *
D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
15944 scalbn((B *
C - A *
D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
15945 if (ResR.isNaN() && ResI.isNaN()) {
15946 if (Denom.isPosZero() && (!A.isNaN() || !B.isNaN())) {
15947 ResR = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * A;
15948 ResI = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * B;
15949 }
else if ((A.isInfinity() || B.isInfinity()) &&
C.isFinite() &&
15951 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
15953 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
15955 ResR = APFloat::getInf(ResR.getSemantics()) * (A *
C + B *
D);
15956 ResI = APFloat::getInf(ResI.getSemantics()) * (B *
C - A *
D);
15957 }
else if (MaxCD.isInfinity() && A.isFinite() && B.isFinite()) {
15958 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
15960 D = APFloat::copySign(APFloat(
D.getSemantics(),
D.isInfinity() ? 1 : 0),
15962 ResR = APFloat::getZero(ResR.getSemantics()) * (A *
C + B *
D);
15963 ResI = APFloat::getZero(ResI.getSemantics()) * (B *
C - A *
D);
15968bool ComplexExprEvaluator::VisitBinaryOperator(
const BinaryOperator *
E) {
15969 if (
E->isPtrMemOp() ||
E->isAssignmentOp() ||
E->getOpcode() == BO_Comma)
15970 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
15974 bool LHSReal =
false, RHSReal =
false;
15979 APFloat &Real = Result.FloatReal;
15982 Result.makeComplexFloat();
15983 Result.FloatImag =
APFloat(Real.getSemantics());
15986 LHSOK = Visit(
E->getLHS());
15988 if (!LHSOK && !Info.noteFailure())
15994 APFloat &Real = RHS.FloatReal;
15997 RHS.makeComplexFloat();
15998 RHS.FloatImag =
APFloat(Real.getSemantics());
16002 assert(!(LHSReal && RHSReal) &&
16003 "Cannot have both operands of a complex operation be real.");
16004 switch (
E->getOpcode()) {
16005 default:
return Error(
E);
16007 if (Result.isComplexFloat()) {
16008 Result.getComplexFloatReal().
add(RHS.getComplexFloatReal(),
16009 APFloat::rmNearestTiesToEven);
16011 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
16013 Result.getComplexFloatImag().
add(RHS.getComplexFloatImag(),
16014 APFloat::rmNearestTiesToEven);
16016 Result.getComplexIntReal() += RHS.getComplexIntReal();
16017 Result.getComplexIntImag() += RHS.getComplexIntImag();
16021 if (Result.isComplexFloat()) {
16022 Result.getComplexFloatReal().subtract(RHS.getComplexFloatReal(),
16023 APFloat::rmNearestTiesToEven);
16025 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
16026 Result.getComplexFloatImag().changeSign();
16027 }
else if (!RHSReal) {
16028 Result.getComplexFloatImag().subtract(RHS.getComplexFloatImag(),
16029 APFloat::rmNearestTiesToEven);
16032 Result.getComplexIntReal() -= RHS.getComplexIntReal();
16033 Result.getComplexIntImag() -= RHS.getComplexIntImag();
16037 if (Result.isComplexFloat()) {
16042 ComplexValue LHS = Result;
16043 APFloat &A = LHS.getComplexFloatReal();
16044 APFloat &B = LHS.getComplexFloatImag();
16045 APFloat &
C = RHS.getComplexFloatReal();
16046 APFloat &
D = RHS.getComplexFloatImag();
16047 APFloat &ResR = Result.getComplexFloatReal();
16048 APFloat &ResI = Result.getComplexFloatImag();
16050 assert(!RHSReal &&
"Cannot have two real operands for a complex op!");
16058 }
else if (RHSReal) {
16070 ComplexValue LHS = Result;
16071 Result.getComplexIntReal() =
16072 (LHS.getComplexIntReal() * RHS.getComplexIntReal() -
16073 LHS.getComplexIntImag() * RHS.getComplexIntImag());
16074 Result.getComplexIntImag() =
16075 (LHS.getComplexIntReal() * RHS.getComplexIntImag() +
16076 LHS.getComplexIntImag() * RHS.getComplexIntReal());
16080 if (Result.isComplexFloat()) {
16085 ComplexValue LHS = Result;
16086 APFloat &A = LHS.getComplexFloatReal();
16087 APFloat &B = LHS.getComplexFloatImag();
16088 APFloat &
C = RHS.getComplexFloatReal();
16089 APFloat &
D = RHS.getComplexFloatImag();
16090 APFloat &ResR = Result.getComplexFloatReal();
16091 APFloat &ResI = Result.getComplexFloatImag();
16103 B = APFloat::getZero(A.getSemantics());
16108 ComplexValue LHS = Result;
16109 APSInt Den = RHS.getComplexIntReal() * RHS.getComplexIntReal() +
16110 RHS.getComplexIntImag() * RHS.getComplexIntImag();
16112 return Error(
E, diag::note_expr_divide_by_zero);
16114 Result.getComplexIntReal() =
16115 (LHS.getComplexIntReal() * RHS.getComplexIntReal() +
16116 LHS.getComplexIntImag() * RHS.getComplexIntImag()) / Den;
16117 Result.getComplexIntImag() =
16118 (LHS.getComplexIntImag() * RHS.getComplexIntReal() -
16119 LHS.getComplexIntReal() * RHS.getComplexIntImag()) / Den;
16127bool ComplexExprEvaluator::VisitUnaryOperator(
const UnaryOperator *
E) {
16129 if (!Visit(
E->getSubExpr()))
16132 switch (
E->getOpcode()) {
16141 if (Result.isComplexFloat()) {
16142 Result.getComplexFloatReal().changeSign();
16143 Result.getComplexFloatImag().changeSign();
16146 Result.getComplexIntReal() = -Result.getComplexIntReal();
16147 Result.getComplexIntImag() = -Result.getComplexIntImag();
16151 if (Result.isComplexFloat())
16152 Result.getComplexFloatImag().changeSign();
16154 Result.getComplexIntImag() = -Result.getComplexIntImag();
16159bool ComplexExprEvaluator::VisitInitListExpr(
const InitListExpr *
E) {
16160 if (
E->getNumInits() == 2) {
16162 Result.makeComplexFloat();
16168 Result.makeComplexInt();
16176 return ExprEvaluatorBaseTy::VisitInitListExpr(
E);
16179bool ComplexExprEvaluator::VisitCallExpr(
const CallExpr *
E) {
16180 if (!IsConstantEvaluatedBuiltinCall(
E))
16181 return ExprEvaluatorBaseTy::VisitCallExpr(
E);
16183 switch (
E->getBuiltinCallee()) {
16184 case Builtin::BI__builtin_complex:
16185 Result.makeComplexFloat();
16203class AtomicExprEvaluator :
16204 public ExprEvaluatorBase<AtomicExprEvaluator> {
16205 const LValue *
This;
16208 AtomicExprEvaluator(EvalInfo &Info,
const LValue *This,
APValue &Result)
16209 : ExprEvaluatorBaseTy(Info),
This(
This), Result(Result) {}
16216 bool ZeroInitialization(
const Expr *
E) {
16225 bool VisitCastExpr(
const CastExpr *
E) {
16226 switch (
E->getCastKind()) {
16228 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
16229 case CK_NullToPointer:
16230 VisitIgnoredValue(
E->getSubExpr());
16231 return ZeroInitialization(
E);
16232 case CK_NonAtomicToAtomic:
16234 :
Evaluate(Result, Info,
E->getSubExpr());
16244 return AtomicExprEvaluator(Info, This, Result).Visit(
E);
16253class VoidExprEvaluator
16254 :
public ExprEvaluatorBase<VoidExprEvaluator> {
16256 VoidExprEvaluator(EvalInfo &Info) : ExprEvaluatorBaseTy(Info) {}
16260 bool ZeroInitialization(
const Expr *
E) {
return true; }
16262 bool VisitCastExpr(
const CastExpr *
E) {
16263 switch (
E->getCastKind()) {
16265 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
16267 VisitIgnoredValue(
E->getSubExpr());
16272 bool VisitCallExpr(
const CallExpr *
E) {
16273 if (!IsConstantEvaluatedBuiltinCall(
E))
16274 return ExprEvaluatorBaseTy::VisitCallExpr(
E);
16276 switch (
E->getBuiltinCallee()) {
16277 case Builtin::BI__assume:
16278 case Builtin::BI__builtin_assume:
16282 case Builtin::BI__builtin_operator_delete:
16294bool VoidExprEvaluator::VisitCXXDeleteExpr(
const CXXDeleteExpr *
E) {
16296 if (Info.SpeculativeEvaluationDepth)
16300 if (!OperatorDelete->isReplaceableGlobalAllocationFunction()) {
16301 Info.FFDiag(
E, diag::note_constexpr_new_non_replaceable)
16302 << isa<CXXMethodDecl>(OperatorDelete) << OperatorDelete;
16306 const Expr *Arg =
E->getArgument();
16311 if (
Pointer.Designator.Invalid)
16315 if (
Pointer.isNullPointer()) {
16319 if (!Info.getLangOpts().CPlusPlus20)
16320 Info.CCEDiag(
E, diag::note_constexpr_new);
16325 Info,
E,
Pointer,
E->isArrayForm() ? DynAlloc::ArrayNew : DynAlloc::New);
16332 if (!
E->isArrayForm() &&
Pointer.Designator.Entries.size() != 0 &&
16334 Info.FFDiag(
E, diag::note_constexpr_delete_base_nonvirt_dtor)
16341 if (!
E->isArrayForm() && !
E->isGlobalDelete()) {
16343 if (VirtualDelete &&
16345 Info.FFDiag(
E, diag::note_constexpr_new_non_replaceable)
16346 << isa<CXXMethodDecl>(VirtualDelete) << VirtualDelete;
16352 (*Alloc)->Value, AllocType))
16360 Info.FFDiag(
E, diag::note_constexpr_double_delete);
16370 return VoidExprEvaluator(Info).Visit(
E);
16386 LV.moveInto(Result);
16391 if (!IntExprEvaluator(Info, Result).Visit(
E))
16397 LV.moveInto(Result);
16399 llvm::APFloat F(0.0);
16407 C.moveInto(Result);
16409 if (!FixedPointExprEvaluator(Info, Result).Visit(
E))
return false;
16414 P.moveInto(Result);
16419 Info.CurrentCall->createTemporary(
E,
T, ScopeKind::FullExpression, LV);
16426 Info.CurrentCall->createTemporary(
E,
T, ScopeKind::FullExpression, LV);
16431 if (!Info.getLangOpts().CPlusPlus11)
16432 Info.CCEDiag(
E, diag::note_constexpr_nonliteral)
16437 QualType Unqual =
T.getAtomicUnqualifiedType();
16441 E, Unqual, ScopeKind::FullExpression, LV);
16449 }
else if (Info.getLangOpts().CPlusPlus11) {
16450 Info.FFDiag(
E, diag::note_constexpr_nonliteral) <<
E->
getType();
16453 Info.FFDiag(
E, diag::note_invalid_subexpr_in_const_expr);
16464 const Expr *
E,
bool AllowNonLiteralTypes) {
16479 QualType Unqual =
T.getAtomicUnqualifiedType();
16500 if (Info.EnableNewConstInterp) {
16501 if (!Info.Ctx.getInterpContext().evaluateAsRValue(Info,
E, Result))
16504 ConstantExprKind::Normal);
16513 LV.setFrom(Info.Ctx, Result);
16520 ConstantExprKind::Normal) &&
16528 if (
const auto *L = dyn_cast<IntegerLiteral>(Exp)) {
16530 L->getType()->isUnsignedIntegerType()));
16535 if (
const auto *L = dyn_cast<CXXBoolLiteralExpr>(Exp)) {
16541 if (
const auto *FL = dyn_cast<FloatingLiteral>(Exp)) {
16542 Result.Val =
APValue(FL->getValue());
16547 if (
const auto *L = dyn_cast<CharacterLiteral>(Exp)) {
16553 if (
const auto *CE = dyn_cast<ConstantExpr>(Exp)) {
16554 if (CE->hasAPValueResult()) {
16555 APValue APV = CE->getAPValueResult();
16557 Result.Val = std::move(APV);
16633 bool InConstantContext)
const {
16634 assert(!isValueDependent() &&
16635 "Expression evaluator can't be called on a dependent expression.");
16636 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsRValue");
16637 EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
16638 Info.InConstantContext = InConstantContext;
16639 return ::EvaluateAsRValue(
this, Result, Ctx, Info);
16643 bool InConstantContext)
const {
16644 assert(!isValueDependent() &&
16645 "Expression evaluator can't be called on a dependent expression.");
16646 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsBooleanCondition");
16654 bool InConstantContext)
const {
16655 assert(!isValueDependent() &&
16656 "Expression evaluator can't be called on a dependent expression.");
16657 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsInt");
16658 EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
16659 Info.InConstantContext = InConstantContext;
16660 return ::EvaluateAsInt(
this, Result, Ctx, AllowSideEffects, Info);
16665 bool InConstantContext)
const {
16666 assert(!isValueDependent() &&
16667 "Expression evaluator can't be called on a dependent expression.");
16668 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFixedPoint");
16669 EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
16670 Info.InConstantContext = InConstantContext;
16671 return ::EvaluateAsFixedPoint(
this, Result, Ctx, AllowSideEffects, Info);
16676 bool InConstantContext)
const {
16677 assert(!isValueDependent() &&
16678 "Expression evaluator can't be called on a dependent expression.");
16680 if (!getType()->isRealFloatingType())
16683 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFloat");
16695 bool InConstantContext)
const {
16696 assert(!isValueDependent() &&
16697 "Expression evaluator can't be called on a dependent expression.");
16699 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsLValue");
16700 EvalInfo Info(Ctx, Result, EvalInfo::EM_ConstantFold);
16701 Info.InConstantContext = InConstantContext;
16704 if (!
EvaluateLValue(
this, LV, Info) || !Info.discardCleanups() ||
16705 Result.HasSideEffects ||
16708 ConstantExprKind::Normal, CheckedTemps))
16711 LV.moveInto(Result.Val);
16718 bool IsConstantDestruction) {
16719 EvalInfo Info(Ctx, EStatus,
16720 IsConstantDestruction ? EvalInfo::EM_ConstantExpression
16721 : EvalInfo::EM_ConstantFold);
16722 Info.setEvaluatingDecl(
Base, DestroyedValue,
16723 EvalInfo::EvaluatingDeclKind::Dtor);
16724 Info.InConstantContext = IsConstantDestruction;
16733 if (!Info.discardCleanups())
16734 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
16741 assert(!isValueDependent() &&
16742 "Expression evaluator can't be called on a dependent expression.");
16747 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsConstantExpr");
16748 EvalInfo::EvaluationMode EM = EvalInfo::EM_ConstantExpression;
16749 EvalInfo Info(Ctx, Result, EM);
16750 Info.InConstantContext =
true;
16752 if (Info.EnableNewConstInterp) {
16753 if (!Info.Ctx.getInterpContext().evaluate(Info,
this, Result.Val, Kind))
16756 getStorageType(Ctx,
this), Result.Val, Kind);
16761 if (Kind == ConstantExprKind::ClassTemplateArgument)
16769 Info.setEvaluatingDecl(
Base, Result.Val);
16771 if (Info.EnableNewConstInterp) {
16772 if (!Info.Ctx.getInterpContext().evaluateAsRValue(Info,
this, Result.Val))
16781 FullExpressionRAII
Scope(Info);
16783 Result.HasSideEffects || !
Scope.destroy())
16786 if (!Info.discardCleanups())
16787 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
16798 if (Kind == ConstantExprKind::ClassTemplateArgument &&
16801 Result.HasSideEffects)) {
16813 bool IsConstantInitialization)
const {
16814 assert(!isValueDependent() &&
16815 "Expression evaluator can't be called on a dependent expression.");
16817 llvm::TimeTraceScope TimeScope(
"EvaluateAsInitializer", [&] {
16819 llvm::raw_string_ostream OS(Name);
16825 EStatus.
Diag = &Notes;
16827 EvalInfo Info(Ctx, EStatus,
16828 (IsConstantInitialization &&
16830 ? EvalInfo::EM_ConstantExpression
16831 : EvalInfo::EM_ConstantFold);
16832 Info.setEvaluatingDecl(VD,
Value);
16833 Info.InConstantContext = IsConstantInitialization;
16838 if (Info.EnableNewConstInterp) {
16839 auto &InterpCtx =
const_cast<ASTContext &
>(Ctx).getInterpContext();
16840 if (!InterpCtx.evaluateAsInitializer(Info, VD,
Value))
16844 ConstantExprKind::Normal);
16859 FullExpressionRAII
Scope(Info);
16862 EStatus.HasSideEffects)
16868 Info.performLifetimeExtension();
16870 if (!Info.discardCleanups())
16871 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
16875 ConstantExprKind::Normal) &&
16882 EStatus.
Diag = &Notes;
16886 bool IsConstantDestruction = hasConstantInitialization();
16892 if (getEvaluatedValue() && !getEvaluatedValue()->isAbsent())
16893 DestroyedValue = *getEvaluatedValue();
16898 getType(), getLocation(), EStatus,
16899 IsConstantDestruction) ||
16903 ensureEvaluatedStmt()->HasConstantDestruction =
true;
16910 assert(!isValueDependent() &&
16911 "Expression evaluator can't be called on a dependent expression.");
16920 assert(!isValueDependent() &&
16921 "Expression evaluator can't be called on a dependent expression.");
16923 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstInt");
16926 EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
16927 Info.InConstantContext =
true;
16931 assert(Result &&
"Could not evaluate expression");
16932 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
16934 return EVResult.Val.getInt();
16939 assert(!isValueDependent() &&
16940 "Expression evaluator can't be called on a dependent expression.");
16942 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstIntCheckOverflow");
16945 EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
16946 Info.InConstantContext =
true;
16947 Info.CheckingForUndefinedBehavior =
true;
16951 assert(Result &&
"Could not evaluate expression");
16952 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
16954 return EVResult.Val.getInt();
16958 assert(!isValueDependent() &&
16959 "Expression evaluator can't be called on a dependent expression.");
16961 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateForOverflow");
16965 EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
16966 Info.CheckingForUndefinedBehavior =
true;
16999 IK_ICEIfUnevaluated,
17015static ICEDiag
Worst(ICEDiag A, ICEDiag B) {
return A.Kind >= B.Kind ? A : B; }
17020 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
17022 Info.InConstantContext =
true;
17036#define ABSTRACT_STMT(Node)
17037#define STMT(Node, Base) case Expr::Node##Class:
17038#define EXPR(Node, Base)
17039#include "clang/AST/StmtNodes.inc"
17040 case Expr::PredefinedExprClass:
17041 case Expr::FloatingLiteralClass:
17042 case Expr::ImaginaryLiteralClass:
17043 case Expr::StringLiteralClass:
17044 case Expr::ArraySubscriptExprClass:
17045 case Expr::MatrixSubscriptExprClass:
17046 case Expr::ArraySectionExprClass:
17047 case Expr::OMPArrayShapingExprClass:
17048 case Expr::OMPIteratorExprClass:
17049 case Expr::MemberExprClass:
17050 case Expr::CompoundAssignOperatorClass:
17051 case Expr::CompoundLiteralExprClass:
17052 case Expr::ExtVectorElementExprClass:
17053 case Expr::DesignatedInitExprClass:
17054 case Expr::ArrayInitLoopExprClass:
17055 case Expr::ArrayInitIndexExprClass:
17056 case Expr::NoInitExprClass:
17057 case Expr::DesignatedInitUpdateExprClass:
17058 case Expr::ImplicitValueInitExprClass:
17059 case Expr::ParenListExprClass:
17060 case Expr::VAArgExprClass:
17061 case Expr::AddrLabelExprClass:
17062 case Expr::StmtExprClass:
17063 case Expr::CXXMemberCallExprClass:
17064 case Expr::CUDAKernelCallExprClass:
17065 case Expr::CXXAddrspaceCastExprClass:
17066 case Expr::CXXDynamicCastExprClass:
17067 case Expr::CXXTypeidExprClass:
17068 case Expr::CXXUuidofExprClass:
17069 case Expr::MSPropertyRefExprClass:
17070 case Expr::MSPropertySubscriptExprClass:
17071 case Expr::CXXNullPtrLiteralExprClass:
17072 case Expr::UserDefinedLiteralClass:
17073 case Expr::CXXThisExprClass:
17074 case Expr::CXXThrowExprClass:
17075 case Expr::CXXNewExprClass:
17076 case Expr::CXXDeleteExprClass:
17077 case Expr::CXXPseudoDestructorExprClass:
17078 case Expr::UnresolvedLookupExprClass:
17079 case Expr::TypoExprClass:
17080 case Expr::RecoveryExprClass:
17081 case Expr::DependentScopeDeclRefExprClass:
17082 case Expr::CXXConstructExprClass:
17083 case Expr::CXXInheritedCtorInitExprClass:
17084 case Expr::CXXStdInitializerListExprClass:
17085 case Expr::CXXBindTemporaryExprClass:
17086 case Expr::ExprWithCleanupsClass:
17087 case Expr::CXXTemporaryObjectExprClass:
17088 case Expr::CXXUnresolvedConstructExprClass:
17089 case Expr::CXXDependentScopeMemberExprClass:
17090 case Expr::UnresolvedMemberExprClass:
17091 case Expr::ObjCStringLiteralClass:
17092 case Expr::ObjCBoxedExprClass:
17093 case Expr::ObjCArrayLiteralClass:
17094 case Expr::ObjCDictionaryLiteralClass:
17095 case Expr::ObjCEncodeExprClass:
17096 case Expr::ObjCMessageExprClass:
17097 case Expr::ObjCSelectorExprClass:
17098 case Expr::ObjCProtocolExprClass:
17099 case Expr::ObjCIvarRefExprClass:
17100 case Expr::ObjCPropertyRefExprClass:
17101 case Expr::ObjCSubscriptRefExprClass:
17102 case Expr::ObjCIsaExprClass:
17103 case Expr::ObjCAvailabilityCheckExprClass:
17104 case Expr::ShuffleVectorExprClass:
17105 case Expr::ConvertVectorExprClass:
17106 case Expr::BlockExprClass:
17107 case Expr::NoStmtClass:
17108 case Expr::OpaqueValueExprClass:
17109 case Expr::PackExpansionExprClass:
17110 case Expr::SubstNonTypeTemplateParmPackExprClass:
17111 case Expr::FunctionParmPackExprClass:
17112 case Expr::AsTypeExprClass:
17113 case Expr::ObjCIndirectCopyRestoreExprClass:
17114 case Expr::MaterializeTemporaryExprClass:
17115 case Expr::PseudoObjectExprClass:
17116 case Expr::AtomicExprClass:
17117 case Expr::LambdaExprClass:
17118 case Expr::CXXFoldExprClass:
17119 case Expr::CoawaitExprClass:
17120 case Expr::DependentCoawaitExprClass:
17121 case Expr::CoyieldExprClass:
17122 case Expr::SYCLUniqueStableNameExprClass:
17123 case Expr::CXXParenListInitExprClass:
17124 case Expr::HLSLOutArgExprClass:
17127 case Expr::InitListExprClass: {
17133 if (cast<InitListExpr>(
E)->getNumInits() == 1)
17134 return CheckICE(cast<InitListExpr>(
E)->getInit(0), Ctx);
17138 case Expr::SizeOfPackExprClass:
17139 case Expr::GNUNullExprClass:
17140 case Expr::SourceLocExprClass:
17141 case Expr::EmbedExprClass:
17142 case Expr::OpenACCAsteriskSizeExprClass:
17145 case Expr::PackIndexingExprClass:
17146 return CheckICE(cast<PackIndexingExpr>(
E)->getSelectedExpr(), Ctx);
17148 case Expr::SubstNonTypeTemplateParmExprClass:
17150 CheckICE(cast<SubstNonTypeTemplateParmExpr>(
E)->getReplacement(), Ctx);
17152 case Expr::ConstantExprClass:
17153 return CheckICE(cast<ConstantExpr>(
E)->getSubExpr(), Ctx);
17155 case Expr::ParenExprClass:
17156 return CheckICE(cast<ParenExpr>(
E)->getSubExpr(), Ctx);
17157 case Expr::GenericSelectionExprClass:
17158 return CheckICE(cast<GenericSelectionExpr>(
E)->getResultExpr(), Ctx);
17159 case Expr::IntegerLiteralClass:
17160 case Expr::FixedPointLiteralClass:
17161 case Expr::CharacterLiteralClass:
17162 case Expr::ObjCBoolLiteralExprClass:
17163 case Expr::CXXBoolLiteralExprClass:
17164 case Expr::CXXScalarValueInitExprClass:
17165 case Expr::TypeTraitExprClass:
17166 case Expr::ConceptSpecializationExprClass:
17167 case Expr::RequiresExprClass:
17168 case Expr::ArrayTypeTraitExprClass:
17169 case Expr::ExpressionTraitExprClass:
17170 case Expr::CXXNoexceptExprClass:
17172 case Expr::CallExprClass:
17173 case Expr::CXXOperatorCallExprClass: {
17177 const CallExpr *CE = cast<CallExpr>(
E);
17182 case Expr::CXXRewrittenBinaryOperatorClass:
17183 return CheckICE(cast<CXXRewrittenBinaryOperator>(
E)->getSemanticForm(),
17185 case Expr::DeclRefExprClass: {
17186 const NamedDecl *
D = cast<DeclRefExpr>(
E)->getDecl();
17187 if (isa<EnumConstantDecl>(
D))
17199 const VarDecl *VD = dyn_cast<VarDecl>(
D);
17206 case Expr::UnaryOperatorClass: {
17229 llvm_unreachable(
"invalid unary operator class");
17231 case Expr::OffsetOfExprClass: {
17240 case Expr::UnaryExprOrTypeTraitExprClass: {
17242 if ((Exp->
getKind() == UETT_SizeOf) &&
17247 case Expr::BinaryOperatorClass: {
17292 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE) {
17295 return ICEDiag(IK_ICEIfUnevaluated,
E->
getBeginLoc());
17296 if (REval.isSigned() && REval.isAllOnes()) {
17298 if (LEval.isMinSignedValue())
17299 return ICEDiag(IK_ICEIfUnevaluated,
E->
getBeginLoc());
17307 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE)
17308 return ICEDiag(IK_ICEIfUnevaluated,
E->
getBeginLoc());
17314 return Worst(LHSResult, RHSResult);
17320 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICEIfUnevaluated) {
17330 return Worst(LHSResult, RHSResult);
17333 llvm_unreachable(
"invalid binary operator kind");
17335 case Expr::ImplicitCastExprClass:
17336 case Expr::CStyleCastExprClass:
17337 case Expr::CXXFunctionalCastExprClass:
17338 case Expr::CXXStaticCastExprClass:
17339 case Expr::CXXReinterpretCastExprClass:
17340 case Expr::CXXConstCastExprClass:
17341 case Expr::ObjCBridgedCastExprClass: {
17342 const Expr *SubExpr = cast<CastExpr>(
E)->getSubExpr();
17343 if (isa<ExplicitCastExpr>(
E)) {
17348 APSInt IgnoredVal(DestWidth, !DestSigned);
17353 if (FL->getValue().convertToInteger(IgnoredVal,
17354 llvm::APFloat::rmTowardZero,
17355 &Ignored) & APFloat::opInvalidOp)
17360 switch (cast<CastExpr>(
E)->getCastKind()) {
17361 case CK_LValueToRValue:
17362 case CK_AtomicToNonAtomic:
17363 case CK_NonAtomicToAtomic:
17365 case CK_IntegralToBoolean:
17366 case CK_IntegralCast:
17372 case Expr::BinaryConditionalOperatorClass: {
17375 if (CommonResult.Kind == IK_NotICE)
return CommonResult;
17377 if (FalseResult.Kind == IK_NotICE)
return FalseResult;
17378 if (CommonResult.Kind == IK_ICEIfUnevaluated)
return CommonResult;
17379 if (FalseResult.Kind == IK_ICEIfUnevaluated &&
17381 return FalseResult;
17383 case Expr::ConditionalOperatorClass: {
17391 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
17394 if (CondResult.Kind == IK_NotICE)
17400 if (TrueResult.Kind == IK_NotICE)
17402 if (FalseResult.Kind == IK_NotICE)
17403 return FalseResult;
17404 if (CondResult.Kind == IK_ICEIfUnevaluated)
17406 if (TrueResult.Kind == IK_ICE && FalseResult.Kind == IK_ICE)
17412 return FalseResult;
17415 case Expr::CXXDefaultArgExprClass:
17416 return CheckICE(cast<CXXDefaultArgExpr>(
E)->getExpr(), Ctx);
17417 case Expr::CXXDefaultInitExprClass:
17418 return CheckICE(cast<CXXDefaultInitExpr>(
E)->getExpr(), Ctx);
17419 case Expr::ChooseExprClass: {
17420 return CheckICE(cast<ChooseExpr>(
E)->getChosenSubExpr(), Ctx);
17422 case Expr::BuiltinBitCastExprClass: {
17423 if (!checkBitCastConstexprEligibility(
nullptr, Ctx, cast<CastExpr>(
E)))
17425 return CheckICE(cast<CastExpr>(
E)->getSubExpr(), Ctx);
17429 llvm_unreachable(
"Invalid StmtClass!");
17435 llvm::APSInt *
Value,
17446 if (!Result.isInt()) {
17457 assert(!isValueDependent() &&
17458 "Expression evaluator can't be called on a dependent expression.");
17460 ExprTimeTraceScope TimeScope(
this, Ctx,
"isIntegerConstantExpr");
17466 if (
D.
Kind != IK_ICE) {
17473std::optional<llvm::APSInt>
17475 if (isValueDependent()) {
17477 return std::nullopt;
17485 return std::nullopt;
17488 if (!isIntegerConstantExpr(Ctx,
Loc))
17489 return std::nullopt;
17497 EvalInfo Info(Ctx, Status, EvalInfo::EM_IgnoreSideEffects);
17498 Info.InConstantContext =
true;
17501 llvm_unreachable(
"ICE cannot be evaluated!");
17507 assert(!isValueDependent() &&
17508 "Expression evaluator can't be called on a dependent expression.");
17510 return CheckICE(
this, Ctx).Kind == IK_ICE;
17515 assert(!isValueDependent() &&
17516 "Expression evaluator can't be called on a dependent expression.");
17525 Status.Diag = &Diags;
17526 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
17533 Info.discardCleanups() && !Status.HasSideEffects;
17535 if (!Diags.empty()) {
17536 IsConstExpr =
false;
17537 if (
Loc) *
Loc = Diags[0].first;
17538 }
else if (!IsConstExpr) {
17540 if (
Loc) *
Loc = getExprLoc();
17543 return IsConstExpr;
17549 const Expr *This)
const {
17550 assert(!isValueDependent() &&
17551 "Expression evaluator can't be called on a dependent expression.");
17553 llvm::TimeTraceScope TimeScope(
"EvaluateWithSubstitution", [&] {
17555 llvm::raw_string_ostream OS(Name);
17562 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpressionUnevaluated);
17563 Info.InConstantContext =
true;
17566 const LValue *ThisPtr =
nullptr;
17569 auto *MD = dyn_cast<CXXMethodDecl>(Callee);
17570 assert(MD &&
"Don't provide `this` for non-methods.");
17571 assert(MD->isImplicitObjectMemberFunction() &&
17572 "Don't provide `this` for methods without an implicit object.");
17574 if (!This->isValueDependent() &&
17576 !Info.EvalStatus.HasSideEffects)
17577 ThisPtr = &ThisVal;
17581 Info.EvalStatus.HasSideEffects =
false;
17584 CallRef
Call = Info.CurrentCall->createCall(Callee);
17587 unsigned Idx = I - Args.begin();
17588 if (Idx >= Callee->getNumParams())
17590 const ParmVarDecl *PVD = Callee->getParamDecl(Idx);
17591 if ((*I)->isValueDependent() ||
17593 Info.EvalStatus.HasSideEffects) {
17595 if (
APValue *Slot = Info.getParamSlot(
Call, PVD))
17601 Info.EvalStatus.HasSideEffects =
false;
17606 Info.discardCleanups();
17607 Info.EvalStatus.HasSideEffects =
false;
17610 CallStackFrame Frame(Info, Callee->getLocation(), Callee, ThisPtr, This,
17613 FullExpressionRAII
Scope(Info);
17615 !Info.EvalStatus.HasSideEffects;
17627 llvm::TimeTraceScope TimeScope(
"isPotentialConstantExpr", [&] {
17629 llvm::raw_string_ostream OS(Name);
17636 Status.Diag = &Diags;
17638 EvalInfo Info(FD->
getASTContext(), Status, EvalInfo::EM_ConstantExpression);
17639 Info.InConstantContext =
true;
17640 Info.CheckingPotentialConstantExpression =
true;
17643 if (Info.EnableNewConstInterp) {
17644 Info.Ctx.getInterpContext().isPotentialConstantExpr(Info, FD);
17645 return Diags.empty();
17655 This.set({&VIE, Info.CurrentCall->Index});
17663 Info.setEvaluatingDecl(This.getLValueBase(), Scratch);
17669 &VIE, Args, CallRef(), FD->
getBody(), Info, Scratch,
17673 return Diags.empty();
17681 "Expression evaluator can't be called on a dependent expression.");
17684 Status.Diag = &Diags;
17687 EvalInfo::EM_ConstantExpressionUnevaluated);
17688 Info.InConstantContext =
true;
17689 Info.CheckingPotentialConstantExpression =
true;
17693 nullptr, CallRef());
17697 return Diags.empty();
17701 unsigned Type)
const {
17702 if (!getType()->isPointerType())
17706 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantFold);
17711 EvalInfo &Info, std::string *StringResult) {
17723 if (
const StringLiteral *S = dyn_cast_or_null<StringLiteral>(
17724 String.getLValueBase().dyn_cast<
const Expr *>())) {
17725 StringRef Str = S->getBytes();
17726 int64_t Off = String.Offset.getQuantity();
17727 if (Off >= 0 && (uint64_t)Off <= (uint64_t)Str.size() &&
17728 S->getCharByteWidth() == 1 &&
17730 Info.Ctx.hasSameUnqualifiedType(CharTy, Info.Ctx.CharTy)) {
17731 Str = Str.substr(Off);
17733 StringRef::size_type Pos = Str.find(0);
17734 if (Pos != StringRef::npos)
17735 Str = Str.substr(0, Pos);
17737 Result = Str.size();
17739 *StringResult = Str;
17747 for (uint64_t Strlen = 0; ; ++Strlen) {
17755 }
else if (StringResult)
17756 StringResult->push_back(Char.
getInt().getExtValue());
17764 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantFold);
17766 std::string StringResult;
17769 return StringResult;
17774 const Expr *SizeExpression,
17778 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
17779 Info.InConstantContext =
true;
17781 FullExpressionRAII
Scope(Info);
17786 uint64_t Size = SizeValue.getZExtValue();
17792 for (uint64_t I = 0; I < Size; ++I) {
17799 Result.push_back(
static_cast<char>(
C.getExtValue()));
17803 if (!
Scope.destroy())
17814 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantFold);
17819struct IsWithinLifetimeHandler {
17821 static constexpr AccessKinds AccessKind = AccessKinds::AK_IsWithinLifetime;
17822 using result_type = std::optional<bool>;
17823 std::optional<bool> failed() {
return std::nullopt; }
17824 template <
typename T>
17825 std::optional<bool> found(
T &Subobj,
QualType SubobjType) {
17830std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &IEE,
17832 EvalInfo &Info = IEE.Info;
17837 if (!Info.InConstantContext)
17838 return std::nullopt;
17839 assert(
E->getBuiltinCallee() == Builtin::BI__builtin_is_within_lifetime);
17840 const Expr *Arg =
E->getArg(0);
17842 return std::nullopt;
17845 return std::nullopt;
17848 bool CalledFromStd =
false;
17849 const auto *
Callee = Info.CurrentCall->getCallee();
17850 if (Callee &&
Callee->isInStdNamespace()) {
17854 Info.CCEDiag(CalledFromStd ? Info.CurrentCall->getCallRange().getBegin()
17856 diag::err_invalid_is_within_lifetime)
17857 << (CalledFromStd ?
"std::is_within_lifetime"
17858 :
"__builtin_is_within_lifetime")
17860 return std::nullopt;
17870 if (Val.isNullPointer() || Val.getLValueBase().isNull())
17872 QualType T = Val.getLValueBase().getType();
17874 "Pointers to functions should have been typed as function pointers "
17875 "which would have been rejected earlier");
17878 if (Val.getLValueDesignator().isOnePastTheEnd())
17880 assert(Val.getLValueDesignator().isValidSubobject() &&
17881 "Unchecked case for valid subobject");
17885 CompleteObject CO =
17889 if (Info.EvaluatingDeclValue && CO.Value == Info.EvaluatingDeclValue)
17894 IsWithinLifetimeHandler handler{Info};
17895 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::@1718::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
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 getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
unsigned getBitWidthValue(const ASTContext &Ctx) const
Computes the bit width of this field, if this is a bit field.
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
FieldDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this field.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
ForStmt - This represents a 'for (init;cond;inc)' stmt.
Represents a function declaration or definition.
const ParmVarDecl * getParamDecl(unsigned i) const
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
bool isFunctionTemplateSpecialization() const
Determine whether this function is a function template specialization.
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
ArrayRef< ParmVarDecl * >::const_iterator param_const_iterator
bool isConstexpr() const
Whether this is a (C++11) constexpr function or constexpr constructor.
bool 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)