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.getQuotedName(BuiltinOp);
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.getQuotedName(BuiltinOp) << CharTy;
9912 bool StopAtNull =
false;
9913 switch (BuiltinOp) {
9914 case Builtin::BIstrchr:
9915 case Builtin::BI__builtin_strchr:
9922 return ZeroInitialization(
E);
9925 case Builtin::BImemchr:
9926 case Builtin::BI__builtin_memchr:
9927 case Builtin::BI__builtin_char_memchr:
9931 DesiredVal = Desired.trunc(Info.Ctx.getCharWidth()).getZExtValue();
9934 case Builtin::BIwcschr:
9935 case Builtin::BI__builtin_wcschr:
9938 case Builtin::BIwmemchr:
9939 case Builtin::BI__builtin_wmemchr:
9941 DesiredVal = Desired.getZExtValue();
9945 for (; MaxLength; --MaxLength) {
9950 if (Char.
getInt().getZExtValue() == DesiredVal)
9952 if (StopAtNull && !Char.
getInt())
9958 return ZeroInitialization(
E);
9961 case Builtin::BImemcpy:
9962 case Builtin::BImemmove:
9963 case Builtin::BIwmemcpy:
9964 case Builtin::BIwmemmove:
9965 if (Info.getLangOpts().CPlusPlus11)
9966 Info.CCEDiag(
E, diag::note_constexpr_invalid_function)
9968 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
9970 Info.CCEDiag(
E, diag::note_invalid_subexpr_in_const_expr);
9972 case Builtin::BI__builtin_memcpy:
9973 case Builtin::BI__builtin_memmove:
9974 case Builtin::BI__builtin_wmemcpy:
9975 case Builtin::BI__builtin_wmemmove: {
9976 bool WChar = BuiltinOp == Builtin::BIwmemcpy ||
9977 BuiltinOp == Builtin::BIwmemmove ||
9978 BuiltinOp == Builtin::BI__builtin_wmemcpy ||
9979 BuiltinOp == Builtin::BI__builtin_wmemmove;
9980 bool Move = BuiltinOp == Builtin::BImemmove ||
9981 BuiltinOp == Builtin::BIwmemmove ||
9982 BuiltinOp == Builtin::BI__builtin_memmove ||
9983 BuiltinOp == Builtin::BI__builtin_wmemmove;
9986 if (!Visit(
E->getArg(0)))
9988 LValue Dest = Result;
9997 assert(!N.isSigned() &&
"memcpy and friends take an unsigned size");
10007 if (!Src.Base || !Dest.Base) {
10009 (!Src.Base ? Src : Dest).moveInto(Val);
10010 Info.FFDiag(
E, diag::note_constexpr_memcpy_null)
10011 <<
Move << WChar << !!Src.Base
10015 if (Src.Designator.Invalid || Dest.Designator.Invalid)
10021 QualType T = Dest.Designator.getType(Info.Ctx);
10022 QualType SrcT = Src.Designator.getType(Info.Ctx);
10023 if (!Info.Ctx.hasSameUnqualifiedType(
T, SrcT)) {
10025 Info.FFDiag(
E, diag::note_constexpr_memcpy_type_pun) <<
Move << SrcT <<
T;
10029 Info.FFDiag(
E, diag::note_constexpr_memcpy_incomplete_type) <<
Move <<
T;
10032 if (!
T.isTriviallyCopyableType(Info.Ctx)) {
10033 Info.FFDiag(
E, diag::note_constexpr_memcpy_nontrivial) <<
Move <<
T;
10038 uint64_t TSize = Info.Ctx.getTypeSizeInChars(
T).getQuantity();
10043 llvm::APInt OrigN = N;
10044 llvm::APInt::udivrem(OrigN, TSize, N, Remainder);
10046 Info.FFDiag(
E, diag::note_constexpr_memcpy_unsupported)
10056 uint64_t RemainingSrcSize = Src.Designator.validIndexAdjustments().second;
10057 uint64_t RemainingDestSize = Dest.Designator.validIndexAdjustments().second;
10058 if (N.ugt(RemainingSrcSize) || N.ugt(RemainingDestSize)) {
10059 Info.FFDiag(
E, diag::note_constexpr_memcpy_unsupported)
10060 <<
Move << WChar << (N.ugt(RemainingSrcSize) ? 1 : 2) <<
T
10064 uint64_t NElems = N.getZExtValue();
10070 uint64_t SrcOffset = Src.getLValueOffset().getQuantity();
10071 uint64_t DestOffset = Dest.getLValueOffset().getQuantity();
10072 if (DestOffset >= SrcOffset && DestOffset - SrcOffset < NBytes) {
10075 Info.FFDiag(
E, diag::note_constexpr_memcpy_overlap) << WChar;
10083 }
else if (!Move && SrcOffset >= DestOffset &&
10084 SrcOffset - DestOffset < NBytes) {
10086 Info.FFDiag(
E, diag::note_constexpr_memcpy_overlap) << WChar;
10121bool PointerExprEvaluator::VisitCXXNewExpr(
const CXXNewExpr *
E) {
10122 if (!Info.getLangOpts().CPlusPlus20)
10123 Info.CCEDiag(
E, diag::note_constexpr_new);
10126 if (Info.SpeculativeEvaluationDepth)
10130 QualType AllocType =
E->getAllocatedType();
10133 bool IsNothrow =
false;
10134 bool IsPlacement =
false;
10136 if (
E->getNumPlacementArgs() == 1 &&
10152 }
else if (OperatorNew->isReservedGlobalPlacementOperator()) {
10153 if (Info.CurrentCall->isStdFunction() || Info.getLangOpts().CPlusPlus26 ||
10154 (Info.CurrentCall->CanEvalMSConstexpr &&
10155 OperatorNew->hasAttr<MSConstexprAttr>())) {
10158 if (Result.Designator.Invalid)
10160 TargetType =
E->getPlacementArg(0)->
getType();
10161 IsPlacement =
true;
10163 Info.FFDiag(
E, diag::note_constexpr_new_placement)
10167 }
else if (
E->getNumPlacementArgs()) {
10168 Info.FFDiag(
E, diag::note_constexpr_new_placement)
10171 }
else if (!OperatorNew->isReplaceableGlobalAllocationFunction()) {
10172 Info.FFDiag(
E, diag::note_constexpr_new_non_replaceable)
10173 << isa<CXXMethodDecl>(OperatorNew) << OperatorNew;
10177 const Expr *
Init =
E->getInitializer();
10180 bool ValueInit =
false;
10182 if (std::optional<const Expr *> ArraySize =
E->getArraySize()) {
10183 const Expr *Stripped = *ArraySize;
10184 for (;
auto *ICE = dyn_cast<ImplicitCastExpr>(Stripped);
10185 Stripped = ICE->getSubExpr())
10186 if (ICE->getCastKind() != CK_NoOp &&
10187 ICE->getCastKind() != CK_IntegralCast)
10190 llvm::APSInt ArrayBound;
10198 if (ArrayBound.isSigned() && ArrayBound.isNegative()) {
10200 return ZeroInitialization(
E);
10202 Info.FFDiag(*ArraySize, diag::note_constexpr_new_negative)
10203 << ArrayBound << (*ArraySize)->getSourceRange();
10209 if (!Info.CheckArraySize(ArraySize.value()->getExprLoc(),
10211 Info.Ctx, AllocType, ArrayBound),
10212 ArrayBound.getZExtValue(), !IsNothrow)) {
10214 return ZeroInitialization(
E);
10223 }
else if (isa<CXXScalarValueInitExpr>(
Init) ||
10224 isa<ImplicitValueInitExpr>(
Init)) {
10226 }
else if (
auto *CCE = dyn_cast<CXXConstructExpr>(
Init)) {
10227 ResizedArrayCCE = CCE;
10229 auto *CAT = Info.Ctx.getAsConstantArrayType(
Init->getType());
10230 assert(CAT &&
"unexpected type for array initializer");
10234 llvm::APInt InitBound = CAT->
getSize().zext(Bits);
10235 llvm::APInt AllocBound = ArrayBound.zext(Bits);
10236 if (InitBound.ugt(AllocBound)) {
10238 return ZeroInitialization(
E);
10240 Info.FFDiag(*ArraySize, diag::note_constexpr_new_too_small)
10241 <<
toString(AllocBound, 10,
false)
10243 << (*ArraySize)->getSourceRange();
10249 if (InitBound != AllocBound)
10250 ResizedArrayILE = cast<InitListExpr>(
Init);
10253 AllocType = Info.Ctx.getConstantArrayType(AllocType, ArrayBound,
nullptr,
10254 ArraySizeModifier::Normal, 0);
10257 "array allocation with non-array new");
10263 struct FindObjectHandler {
10270 typedef bool result_type;
10271 bool failed() {
return false; }
10275 unsigned SubobjectSize = 1;
10276 unsigned AllocSize = 1;
10277 if (
auto *CAT = dyn_cast<ConstantArrayType>(AllocType))
10279 if (
auto *CAT = dyn_cast<ConstantArrayType>(SubobjType))
10281 if (SubobjectSize < AllocSize ||
10282 !Info.Ctx.hasSimilarType(Info.Ctx.getBaseElementType(SubobjType),
10283 Info.Ctx.getBaseElementType(AllocType))) {
10284 Info.FFDiag(
E, diag::note_constexpr_placement_new_wrong_type)
10285 << SubobjType << AllocType;
10292 Info.FFDiag(
E, diag::note_constexpr_construct_complex_elem);
10296 Info.FFDiag(
E, diag::note_constexpr_construct_complex_elem);
10299 } Handler = {Info,
E, AllocType, AK,
nullptr};
10302 if (!Obj || !
findSubobject(Info,
E, Obj, Result.Designator, Handler))
10305 Val = Handler.Value;
10314 Val = Info.createHeapAlloc(
E, AllocType, Result);
10323 }
else if (ResizedArrayILE) {
10327 }
else if (ResizedArrayCCE) {
10341 Result.addArray(Info,
E, cast<ConstantArrayType>(AT));
10350class MemberPointerExprEvaluator
10351 :
public ExprEvaluatorBase<MemberPointerExprEvaluator> {
10355 Result = MemberPtr(
D);
10360 MemberPointerExprEvaluator(EvalInfo &Info, MemberPtr &Result)
10361 : ExprEvaluatorBaseTy(Info), Result(Result) {}
10367 bool ZeroInitialization(
const Expr *
E) {
10380 return MemberPointerExprEvaluator(Info, Result).Visit(
E);
10383bool MemberPointerExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
10384 switch (
E->getCastKind()) {
10386 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
10388 case CK_NullToMemberPointer:
10389 VisitIgnoredValue(
E->getSubExpr());
10390 return ZeroInitialization(
E);
10392 case CK_BaseToDerivedMemberPointer: {
10393 if (!Visit(
E->getSubExpr()))
10395 if (
E->path_empty())
10400 typedef std::reverse_iterator<CastExpr::path_const_iterator> ReverseIter;
10401 for (ReverseIter PathI(
E->path_end() - 1), PathE(
E->path_begin());
10402 PathI != PathE; ++PathI) {
10403 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
10404 const CXXRecordDecl *Derived = (*PathI)->getType()->getAsCXXRecordDecl();
10405 if (!Result.castToDerived(Derived))
10414 case CK_DerivedToBaseMemberPointer:
10415 if (!Visit(
E->getSubExpr()))
10418 PathE =
E->path_end(); PathI != PathE; ++PathI) {
10419 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
10421 if (!Result.castToBase(
Base))
10428bool MemberPointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *
E) {
10431 return Success(cast<DeclRefExpr>(
E->getSubExpr())->getDecl());
10439 class RecordExprEvaluator
10440 :
public ExprEvaluatorBase<RecordExprEvaluator> {
10441 const LValue &
This;
10445 RecordExprEvaluator(EvalInfo &info,
const LValue &This,
APValue &Result)
10446 : ExprEvaluatorBaseTy(info),
This(
This), Result(Result) {}
10452 bool ZeroInitialization(
const Expr *
E) {
10453 return ZeroInitialization(
E,
E->
getType());
10457 bool VisitCallExpr(
const CallExpr *
E) {
10458 return handleCallExpr(
E, Result, &This);
10463 return VisitCXXConstructExpr(
E,
E->
getType());
10471 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
10485 const LValue &This,
APValue &Result) {
10486 assert(!RD->
isUnion() &&
"Expected non-union class type");
10495 unsigned Index = 0;
10497 End = CD->
bases_end(); I != End; ++I, ++Index) {
10499 LValue Subobject = This;
10503 Result.getStructBase(Index)))
10508 for (
const auto *I : RD->
fields()) {
10510 if (I->isUnnamedBitField() || I->getType()->isReferenceType())
10513 LValue Subobject = This;
10519 Result.getStructField(I->getFieldIndex()), Info, Subobject, &VIE))
10526bool RecordExprEvaluator::ZeroInitialization(
const Expr *
E,
QualType T) {
10533 while (I != RD->
field_end() && (*I)->isUnnamedBitField())
10540 LValue Subobject =
This;
10545 return EvaluateInPlace(Result.getUnionValue(), Info, Subobject, &VIE);
10548 if (isa<CXXRecordDecl>(RD) && cast<CXXRecordDecl>(RD)->getNumVBases()) {
10549 Info.FFDiag(
E, diag::note_constexpr_virtual_base) << RD;
10556bool RecordExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
10557 switch (
E->getCastKind()) {
10559 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
10561 case CK_ConstructorConversion:
10562 return Visit(
E->getSubExpr());
10564 case CK_DerivedToBase:
10565 case CK_UncheckedDerivedToBase: {
10567 if (!
Evaluate(DerivedObject, Info,
E->getSubExpr()))
10570 return Error(
E->getSubExpr());
10576 PathE =
E->path_end(); PathI != PathE; ++PathI) {
10577 assert(!(*PathI)->isVirtual() &&
"record rvalue with virtual base");
10588bool RecordExprEvaluator::VisitInitListExpr(
const InitListExpr *
E) {
10589 if (
E->isTransparent())
10590 return Visit(
E->getInit(0));
10591 return VisitCXXParenListOrInitListExpr(
E,
E->inits());
10594bool RecordExprEvaluator::VisitCXXParenListOrInitListExpr(
10600 auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
10602 EvalInfo::EvaluatingConstructorRAII EvalObj(
10604 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries},
10605 CXXRD && CXXRD->getNumBases());
10609 if (
auto *ILE = dyn_cast<InitListExpr>(ExprToVisit)) {
10610 Field = ILE->getInitializedFieldInUnion();
10611 }
else if (
auto *PLIE = dyn_cast<CXXParenListInitExpr>(ExprToVisit)) {
10612 Field = PLIE->getInitializedFieldInUnion();
10615 "Expression is neither an init list nor a C++ paren list");
10628 const Expr *InitExpr = Args.empty() ? &VIE : Args[0];
10630 LValue Subobject =
This;
10635 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
10636 isa<CXXDefaultInitExpr>(InitExpr));
10638 if (
EvaluateInPlace(Result.getUnionValue(), Info, Subobject, InitExpr)) {
10639 if (
Field->isBitField())
10648 if (!Result.hasValue())
10651 unsigned ElementNo = 0;
10655 if (CXXRD && CXXRD->getNumBases()) {
10656 for (
const auto &
Base : CXXRD->bases()) {
10657 assert(ElementNo < Args.size() &&
"missing init for base class");
10658 const Expr *
Init = Args[ElementNo];
10660 LValue Subobject =
This;
10664 APValue &FieldVal = Result.getStructBase(ElementNo);
10666 if (!Info.noteFailure())
10673 EvalObj.finishedConstructingBases();
10677 for (
const auto *Field : RD->
fields()) {
10680 if (
Field->isUnnamedBitField())
10683 LValue Subobject =
This;
10685 bool HaveInit = ElementNo < Args.size();
10690 Subobject, Field, &Layout))
10696 const Expr *
Init = HaveInit ? Args[ElementNo++] : &VIE;
10698 if (
Field->getType()->isIncompleteArrayType()) {
10699 if (
auto *CAT = Info.Ctx.getAsConstantArrayType(
Init->getType())) {
10703 Info.FFDiag(
Init, diag::note_constexpr_unsupported_flexible_array);
10710 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
10711 isa<CXXDefaultInitExpr>(
Init));
10713 APValue &FieldVal = Result.getStructField(
Field->getFieldIndex());
10716 FieldVal, Field))) {
10717 if (!Info.noteFailure())
10723 EvalObj.finishedConstructingFields();
10735 bool ZeroInit =
E->requiresZeroInitialization();
10738 if (Result.hasValue())
10742 return ZeroInitialization(
E,
T);
10754 if (
E->isElidable() && !ZeroInit) {
10760 const Expr *SrcObj =
E->getArg(0);
10762 assert(Info.Ctx.hasSameUnqualifiedType(
E->
getType(), SrcObj->
getType()));
10764 dyn_cast<MaterializeTemporaryExpr>(SrcObj))
10765 return Visit(ME->getSubExpr());
10768 if (ZeroInit && !ZeroInitialization(
E,
T))
10777bool RecordExprEvaluator::VisitCXXInheritedCtorInitExpr(
10779 if (!Info.CurrentCall) {
10780 assert(Info.checkingPotentialConstantExpression());
10799bool RecordExprEvaluator::VisitCXXStdInitializerListExpr(
10802 Info.Ctx.getAsConstantArrayType(
E->getSubExpr()->
getType());
10808 assert(
ArrayType &&
"unexpected type for array initializer");
10815 Array.moveInto(Result.getStructField(0));
10819 assert(Field !=
Record->field_end() &&
10820 Info.Ctx.hasSameType(
Field->getType()->getPointeeType(),
10822 "Expected std::initializer_list first field to be const E *");
10824 assert(Field !=
Record->field_end() &&
10825 "Expected std::initializer_list to have two fields");
10827 if (Info.Ctx.hasSameType(
Field->getType(), Info.Ctx.getSizeType())) {
10832 assert(Info.Ctx.hasSameType(
Field->getType()->getPointeeType(),
10834 "Expected std::initializer_list second field to be const E *");
10839 Array.moveInto(Result.getStructField(1));
10842 assert(++Field ==
Record->field_end() &&
10843 "Expected std::initializer_list to only have two fields");
10848bool RecordExprEvaluator::VisitLambdaExpr(
const LambdaExpr *
E) {
10853 const size_t NumFields =
10856 assert(NumFields == (
size_t)std::distance(
E->capture_init_begin(),
10857 E->capture_init_end()) &&
10858 "The number of lambda capture initializers should equal the number of "
10859 "fields within the closure type");
10864 auto *CaptureInitIt =
E->capture_init_begin();
10866 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(ClosureClass);
10867 for (
const auto *Field : ClosureClass->
fields()) {
10868 assert(CaptureInitIt !=
E->capture_init_end());
10870 Expr *
const CurFieldInit = *CaptureInitIt++;
10877 LValue Subobject =
This;
10882 APValue &FieldVal = Result.getStructField(
Field->getFieldIndex());
10884 if (!Info.keepEvaluatingAfterFailure())
10893 APValue &Result, EvalInfo &Info) {
10896 "can't evaluate expression as a record rvalue");
10897 return RecordExprEvaluator(Info, This, Result).Visit(
E);
10908class TemporaryExprEvaluator
10909 :
public LValueExprEvaluatorBase<TemporaryExprEvaluator> {
10911 TemporaryExprEvaluator(EvalInfo &Info, LValue &Result) :
10912 LValueExprEvaluatorBaseTy(Info, Result,
false) {}
10915 bool VisitConstructExpr(
const Expr *
E) {
10917 E,
E->
getType(), ScopeKind::FullExpression, Result);
10921 bool VisitCastExpr(
const CastExpr *
E) {
10922 switch (
E->getCastKind()) {
10924 return LValueExprEvaluatorBaseTy::VisitCastExpr(
E);
10926 case CK_ConstructorConversion:
10927 return VisitConstructExpr(
E->getSubExpr());
10931 return VisitConstructExpr(
E);
10934 return VisitConstructExpr(
E);
10936 bool VisitCallExpr(
const CallExpr *
E) {
10937 return VisitConstructExpr(
E);
10940 return VisitConstructExpr(
E);
10943 return VisitConstructExpr(
E);
10952 return TemporaryExprEvaluator(Info, Result).Visit(
E);
10960 class VectorExprEvaluator
10961 :
public ExprEvaluatorBase<VectorExprEvaluator> {
10965 VectorExprEvaluator(EvalInfo &info,
APValue &Result)
10966 : ExprEvaluatorBaseTy(info), Result(Result) {}
10975 assert(
V.isVector());
10979 bool ZeroInitialization(
const Expr *
E);
10982 {
return Visit(
E->getSubExpr()); }
10999 "not a vector prvalue");
11000 return VectorExprEvaluator(Info, Result).Visit(
E);
11003bool VectorExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
11007 const Expr *SE =
E->getSubExpr();
11010 switch (
E->getCastKind()) {
11011 case CK_VectorSplat: {
11017 Val =
APValue(std::move(IntResult));
11022 Val =
APValue(std::move(FloatResult));
11039 Info.FFDiag(
E, diag::note_constexpr_invalid_cast)
11040 << 2 << Info.Ctx.getLangOpts().CPlusPlus;
11044 if (!handleRValueToRValueBitCast(Info, Result, SVal,
E))
11049 case CK_HLSLVectorTruncation: {
11054 for (
unsigned I = 0; I < NElts; I++)
11059 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
11064VectorExprEvaluator::VisitInitListExpr(
const InitListExpr *
E) {
11066 unsigned NumInits =
E->getNumInits();
11076 unsigned CountInits = 0, CountElts = 0;
11077 while (CountElts < NumElements) {
11079 if (CountInits < NumInits
11084 unsigned vlen =
v.getVectorLength();
11085 for (
unsigned j = 0; j < vlen; j++)
11086 Elements.push_back(
v.getVectorElt(j));
11089 llvm::APSInt sInt(32);
11090 if (CountInits < NumInits) {
11094 sInt = Info.Ctx.MakeIntValue(0, EltTy);
11095 Elements.push_back(
APValue(sInt));
11098 llvm::APFloat f(0.0);
11099 if (CountInits < NumInits) {
11103 f = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy));
11104 Elements.push_back(
APValue(f));
11113VectorExprEvaluator::ZeroInitialization(
const Expr *
E) {
11117 if (EltTy->isIntegerType())
11118 ZeroElement =
APValue(Info.Ctx.MakeIntValue(0, EltTy));
11121 APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy)));
11127bool VectorExprEvaluator::VisitUnaryImag(
const UnaryOperator *
E) {
11128 VisitIgnoredValue(
E->getSubExpr());
11129 return ZeroInitialization(
E);
11132bool VectorExprEvaluator::VisitBinaryOperator(
const BinaryOperator *
E) {
11134 assert(Op != BO_PtrMemD && Op != BO_PtrMemI && Op != BO_Cmp &&
11135 "Operation not supported on vector types");
11137 if (Op == BO_Comma)
11138 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
11140 Expr *LHS =
E->getLHS();
11141 Expr *RHS =
E->getRHS();
11144 "Must both be vector types");
11151 "All operands must be the same size.");
11155 bool LHSOK =
Evaluate(LHSValue, Info, LHS);
11156 if (!LHSOK && !Info.noteFailure())
11158 if (!
Evaluate(RHSValue, Info, RHS) || !LHSOK)
11180 "Vector can only be int or float type");
11188 "Vector operator ~ can only be int");
11189 Elt.
getInt().flipAllBits();
11199 "Vector can only be int or float type");
11205 EltResult.setAllBits();
11207 EltResult.clearAllBits();
11213 return std::nullopt;
11217bool VectorExprEvaluator::VisitUnaryOperator(
const UnaryOperator *
E) {
11218 Expr *SubExpr =
E->getSubExpr();
11223 const QualType ResultEltTy = VD->getElementType();
11227 if (!
Evaluate(SubExprValue, Info, SubExpr))
11240 "Vector length doesn't match type?");
11243 for (
unsigned EltNum = 0; EltNum < VD->getNumElements(); ++EltNum) {
11245 Info.Ctx, ResultEltTy, Op, SubExprValue.
getVectorElt(EltNum));
11248 ResultElements.push_back(*Elt);
11250 return Success(
APValue(ResultElements.data(), ResultElements.size()),
E);
11259 Result =
APValue(APFloat(0.0));
11261 DestTy, Result.getFloat());
11272 Result.getFloat());
11277 DestTy, Result.getInt());
11281 Info.FFDiag(
E, diag::err_convertvector_constexpr_unsupported_vector_cast)
11282 << SourceTy << DestTy;
11286bool VectorExprEvaluator::VisitCallExpr(
const CallExpr *
E) {
11287 if (!IsConstantEvaluatedBuiltinCall(
E))
11288 return ExprEvaluatorBaseTy::VisitCallExpr(
E);
11290 switch (
E->getBuiltinCallee()) {
11293 case Builtin::BI__builtin_elementwise_popcount:
11294 case Builtin::BI__builtin_elementwise_bitreverse: {
11302 ResultElements.reserve(SourceLen);
11304 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11306 switch (
E->getBuiltinCallee()) {
11307 case Builtin::BI__builtin_elementwise_popcount:
11308 ResultElements.push_back(
APValue(
11309 APSInt(
APInt(Info.Ctx.getIntWidth(DestEltTy), Elt.popcount()),
11312 case Builtin::BI__builtin_elementwise_bitreverse:
11313 ResultElements.push_back(
11320 return Success(
APValue(ResultElements.data(), ResultElements.size()),
E);
11322 case Builtin::BI__builtin_elementwise_add_sat:
11323 case Builtin::BI__builtin_elementwise_sub_sat: {
11324 APValue SourceLHS, SourceRHS;
11332 ResultElements.reserve(SourceLen);
11334 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11337 switch (
E->getBuiltinCallee()) {
11338 case Builtin::BI__builtin_elementwise_add_sat:
11339 ResultElements.push_back(
APValue(
11340 APSInt(LHS.isSigned() ? LHS.sadd_sat(RHS) : RHS.uadd_sat(RHS),
11343 case Builtin::BI__builtin_elementwise_sub_sat:
11344 ResultElements.push_back(
APValue(
11345 APSInt(LHS.isSigned() ? LHS.ssub_sat(RHS) : RHS.usub_sat(RHS),
11351 return Success(
APValue(ResultElements.data(), ResultElements.size()),
E);
11369 ResultElements.reserve(SourceLen);
11370 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11375 ResultElements.push_back(std::move(Elt));
11378 return Success(
APValue(ResultElements.data(), ResultElements.size()),
E);
11383 APValue const &VecVal2,
unsigned EltNum,
11385 unsigned const TotalElementsInInputVector1 = VecVal1.
getVectorLength();
11386 unsigned const TotalElementsInInputVector2 = VecVal2.
getVectorLength();
11388 APSInt IndexVal =
E->getShuffleMaskIdx(Info.Ctx, EltNum);
11389 int64_t index = IndexVal.getExtValue();
11396 E, diag::err_shufflevector_minus_one_is_undefined_behavior_constexpr)
11402 index >= TotalElementsInInputVector1 + TotalElementsInInputVector2)
11403 llvm_unreachable(
"Out of bounds shuffle index");
11405 if (index >= TotalElementsInInputVector1)
11406 Result = VecVal2.
getVectorElt(index - TotalElementsInInputVector1);
11414 const Expr *Vec1 =
E->getExpr(0);
11418 const Expr *Vec2 =
E->getExpr(1);
11428 ResultElements.reserve(TotalElementsInOutputVector);
11429 for (
unsigned EltNum = 0; EltNum < TotalElementsInOutputVector; ++EltNum) {
11433 ResultElements.push_back(std::move(Elt));
11436 return Success(
APValue(ResultElements.data(), ResultElements.size()),
E);
11444 class ArrayExprEvaluator
11445 :
public ExprEvaluatorBase<ArrayExprEvaluator> {
11446 const LValue &
This;
11450 ArrayExprEvaluator(EvalInfo &Info,
const LValue &This,
APValue &Result)
11451 : ExprEvaluatorBaseTy(Info),
This(
This), Result(Result) {}
11454 assert(
V.isArray() &&
"expected array");
11459 bool ZeroInitialization(
const Expr *
E) {
11461 Info.Ctx.getAsConstantArrayType(
E->
getType());
11475 if (!Result.hasArrayFiller())
11479 LValue Subobject =
This;
11480 Subobject.addArray(Info,
E, CAT);
11482 return EvaluateInPlace(Result.getArrayFiller(), Info, Subobject, &VIE);
11485 bool VisitCallExpr(
const CallExpr *
E) {
11486 return handleCallExpr(
E, Result, &This);
11493 const LValue &Subobject,
11501 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
11503 const Expr *ArrayFiller,
11509 APValue &Result, EvalInfo &Info) {
11512 "not an array prvalue");
11513 return ArrayExprEvaluator(Info, This, Result).Visit(
E);
11521 "not an array prvalue");
11522 return ArrayExprEvaluator(Info, This, Result)
11523 .VisitInitListExpr(ILE, AllocType);
11532 "not an array prvalue");
11533 return ArrayExprEvaluator(Info, This, Result)
11534 .VisitCXXConstructExpr(CCE, This, &Result, AllocType);
11541 if (isa<ImplicitValueInitExpr>(FillerExpr))
11543 if (
const InitListExpr *ILE = dyn_cast<InitListExpr>(FillerExpr)) {
11544 for (
unsigned I = 0,
E = ILE->getNumInits(); I !=
E; ++I) {
11549 if (ILE->hasArrayFiller() &&
11558bool ArrayExprEvaluator::VisitInitListExpr(
const InitListExpr *
E,
11567 if (
E->isStringLiteralInit()) {
11573 return VisitStringLiteral(SL, AllocType);
11577 assert(!
E->isTransparent() &&
11578 "transparent array list initialization is not string literal init?");
11580 return VisitCXXParenListOrInitListExpr(
E,
E->inits(),
E->getArrayFiller(),
11584bool ArrayExprEvaluator::VisitCXXParenListOrInitListExpr(
11592 assert((!Result.isArray() || Result.getArrayInitializedElts() == 0) &&
11593 "zero-initialized array shouldn't have any initialized elts");
11595 if (Result.isArray() && Result.hasArrayFiller())
11596 Filler = Result.getArrayFiller();
11598 unsigned NumEltsToInit = Args.size();
11603 if (NumEltsToInit != NumElts &&
11605 NumEltsToInit = NumElts;
11607 for (
auto *
Init : Args) {
11608 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts()))
11609 NumEltsToInit += EmbedS->getDataElementCount() - 1;
11611 if (NumEltsToInit > NumElts)
11612 NumEltsToInit = NumElts;
11615 LLVM_DEBUG(llvm::dbgs() <<
"The number of elements to initialize: "
11616 << NumEltsToInit <<
".\n");
11623 for (
unsigned I = 0,
E = Result.getArrayInitializedElts(); I !=
E; ++I)
11624 Result.getArrayInitializedElt(I) = Filler;
11625 if (Result.hasArrayFiller())
11626 Result.getArrayFiller() = Filler;
11629 LValue Subobject =
This;
11630 Subobject.addArray(Info, ExprToVisit, CAT);
11631 auto Eval = [&](
const Expr *
Init,
unsigned ArrayIndex) {
11632 if (
Init->isValueDependent())
11635 if (!
EvaluateInPlace(Result.getArrayInitializedElt(ArrayIndex), Info,
11636 Subobject,
Init) ||
11639 if (!Info.noteFailure())
11645 unsigned ArrayIndex = 0;
11648 for (
unsigned Index = 0; Index != NumEltsToInit; ++Index) {
11649 const Expr *
Init = Index < Args.size() ? Args[Index] : ArrayFiller;
11650 if (ArrayIndex >= NumEltsToInit)
11652 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
11654 for (
unsigned I = EmbedS->getStartingElementPos(),
11655 N = EmbedS->getDataElementCount();
11656 I != EmbedS->getStartingElementPos() + N; ++I) {
11659 Result.getArrayInitializedElt(ArrayIndex) =
APValue(
Value);
11663 Init->getFPFeaturesInEffect(Info.Ctx.getLangOpts());
11668 Result.getArrayInitializedElt(ArrayIndex) =
APValue(FValue);
11673 if (!Eval(
Init, ArrayIndex))
11679 if (!Result.hasArrayFiller())
11684 assert(ArrayFiller &&
"no array filler for incomplete init list");
11692 if (
E->getCommonExpr() &&
11693 !
Evaluate(Info.CurrentCall->createTemporary(
11694 E->getCommonExpr(),
11695 getStorageType(Info.Ctx,
E->getCommonExpr()),
11696 ScopeKind::FullExpression, CommonLV),
11697 Info,
E->getCommonExpr()->getSourceExpr()))
11705 LValue Subobject =
This;
11706 Subobject.addArray(Info,
E, CAT);
11709 for (EvalInfo::ArrayInitLoopIndex Index(Info); Index != Elements; ++Index) {
11718 FullExpressionRAII
Scope(Info);
11721 Info, Subobject,
E->getSubExpr()) ||
11724 if (!Info.noteFailure())
11737 return VisitCXXConstructExpr(
E, This, &Result,
E->
getType());
11741 const LValue &Subobject,
11751 HadZeroInit &&
Value->hasArrayFiller() ?
Value->getArrayFiller()
11755 if (FinalSize == 0)
11760 E->requiresZeroInitialization());
11761 LValue ArrayElt = Subobject;
11762 ArrayElt.addArray(Info,
E, CAT);
11768 for (
const unsigned N : {1u, FinalSize}) {
11769 unsigned OldElts =
Value->getArrayInitializedElts();
11775 for (
unsigned I = 0; I < OldElts; ++I)
11776 NewValue.getArrayInitializedElt(I).swap(
11777 Value->getArrayInitializedElt(I));
11778 Value->swap(NewValue);
11781 for (
unsigned I = OldElts; I < N; ++I)
11782 Value->getArrayInitializedElt(I) = Filler;
11784 if (HasTrivialConstructor && N == FinalSize && FinalSize != 1) {
11787 APValue &FirstResult =
Value->getArrayInitializedElt(0);
11788 for (
unsigned I = OldElts; I < FinalSize; ++I)
11789 Value->getArrayInitializedElt(I) = FirstResult;
11791 for (
unsigned I = OldElts; I < N; ++I) {
11792 if (!VisitCXXConstructExpr(
E, ArrayElt,
11793 &
Value->getArrayInitializedElt(I),
11800 if (Info.EvalStatus.Diag && !Info.EvalStatus.Diag->empty() &&
11801 !Info.keepEvaluatingAfterFailure())
11813 return RecordExprEvaluator(Info, Subobject, *
Value)
11814 .VisitCXXConstructExpr(
E,
Type);
11817bool ArrayExprEvaluator::VisitCXXParenListInitExpr(
11820 "Expression result is not a constant array type");
11822 return VisitCXXParenListOrInitListExpr(
E,
E->getInitExprs(),
11823 E->getArrayFiller());
11835class IntExprEvaluator
11836 :
public ExprEvaluatorBase<IntExprEvaluator> {
11839 IntExprEvaluator(EvalInfo &info,
APValue &result)
11840 : ExprEvaluatorBaseTy(info), Result(result) {}
11844 "Invalid evaluation result.");
11846 "Invalid evaluation result.");
11847 assert(SI.getBitWidth() == Info.Ctx.getIntWidth(
E->
getType()) &&
11848 "Invalid evaluation result.");
11858 "Invalid evaluation result.");
11859 assert(I.getBitWidth() == Info.Ctx.getIntWidth(
E->
getType()) &&
11860 "Invalid evaluation result.");
11862 Result.getInt().setIsUnsigned(
11872 "Invalid evaluation result.");
11885 if (
V.isLValue() ||
V.isAddrLabelDiff() ||
V.isIndeterminate()) {
11892 bool ZeroInitialization(
const Expr *
E) {
return Success(0,
E); }
11894 friend std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &,
11908 bool CheckReferencedDecl(
const Expr *
E,
const Decl *
D);
11910 if (CheckReferencedDecl(
E,
E->getDecl()))
11913 return ExprEvaluatorBaseTy::VisitDeclRefExpr(
E);
11916 if (CheckReferencedDecl(
E,
E->getMemberDecl())) {
11917 VisitIgnoredBaseExpression(
E->getBase());
11921 return ExprEvaluatorBaseTy::VisitMemberExpr(
E);
11925 bool VisitBuiltinCallExpr(
const CallExpr *
E,
unsigned BuiltinOp);
11942 if (Info.ArrayInitIndex ==
uint64_t(-1)) {
11948 return Success(Info.ArrayInitIndex,
E);
11953 return ZeroInitialization(
E);
11986class FixedPointExprEvaluator
11987 :
public ExprEvaluatorBase<FixedPointExprEvaluator> {
11991 FixedPointExprEvaluator(EvalInfo &info,
APValue &result)
11992 : ExprEvaluatorBaseTy(info), Result(result) {}
11996 APFixedPoint(I, Info.Ctx.getFixedPointSemantics(
E->
getType())),
E);
12001 APFixedPoint(
Value, Info.Ctx.getFixedPointSemantics(
E->
getType())),
E);
12010 assert(
V.getWidth() == Info.Ctx.getIntWidth(
E->
getType()) &&
12011 "Invalid evaluation result.");
12016 bool ZeroInitialization(
const Expr *
E) {
12046 return IntExprEvaluator(Info, Result).Visit(
E);
12054 if (!Val.
isInt()) {
12057 Info.FFDiag(
E, diag::note_invalid_subexpr_in_const_expr);
12064bool IntExprEvaluator::VisitSourceLocExpr(
const SourceLocExpr *
E) {
12066 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.getDefaultExpr());
12075 if (!FixedPointExprEvaluator(Info, Val).Visit(
E))
12090 auto FXSema = Info.Ctx.getFixedPointSemantics(
E->
getType());
12094 Result = APFixedPoint(Val, FXSema);
12105bool IntExprEvaluator::CheckReferencedDecl(
const Expr*
E,
const Decl*
D) {
12109 bool SameSign = (ECD->getInitVal().isSigned()
12111 bool SameWidth = (ECD->getInitVal().getBitWidth()
12112 == Info.Ctx.getIntWidth(
E->
getType()));
12113 if (SameSign && SameWidth)
12114 return Success(ECD->getInitVal(),
E);
12118 llvm::APSInt Val = ECD->getInitVal();
12120 Val.setIsSigned(!ECD->getInitVal().isSigned());
12122 Val = Val.extOrTrunc(Info.Ctx.getIntWidth(
E->
getType()));
12138#define TYPE(ID, BASE)
12139#define DEPENDENT_TYPE(ID, BASE) case Type::ID:
12140#define NON_CANONICAL_TYPE(ID, BASE) case Type::ID:
12141#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(ID, BASE) case Type::ID:
12142#include "clang/AST/TypeNodes.inc"
12144 case Type::DeducedTemplateSpecialization:
12145 llvm_unreachable(
"unexpected non-canonical or dependent type");
12147 case Type::Builtin:
12148 switch (cast<BuiltinType>(CanTy)->
getKind()) {
12149#define BUILTIN_TYPE(ID, SINGLETON_ID)
12150#define SIGNED_TYPE(ID, SINGLETON_ID) \
12151 case BuiltinType::ID: return GCCTypeClass::Integer;
12152#define FLOATING_TYPE(ID, SINGLETON_ID) \
12153 case BuiltinType::ID: return GCCTypeClass::RealFloat;
12154#define PLACEHOLDER_TYPE(ID, SINGLETON_ID) \
12155 case BuiltinType::ID: break;
12156#include "clang/AST/BuiltinTypes.def"
12157 case BuiltinType::Void:
12158 return GCCTypeClass::Void;
12160 case BuiltinType::Bool:
12161 return GCCTypeClass::Bool;
12163 case BuiltinType::Char_U:
12164 case BuiltinType::UChar:
12165 case BuiltinType::WChar_U:
12166 case BuiltinType::Char8:
12167 case BuiltinType::Char16:
12168 case BuiltinType::Char32:
12169 case BuiltinType::UShort:
12170 case BuiltinType::UInt:
12171 case BuiltinType::ULong:
12172 case BuiltinType::ULongLong:
12173 case BuiltinType::UInt128:
12174 return GCCTypeClass::Integer;
12176 case BuiltinType::UShortAccum:
12177 case BuiltinType::UAccum:
12178 case BuiltinType::ULongAccum:
12179 case BuiltinType::UShortFract:
12180 case BuiltinType::UFract:
12181 case BuiltinType::ULongFract:
12182 case BuiltinType::SatUShortAccum:
12183 case BuiltinType::SatUAccum:
12184 case BuiltinType::SatULongAccum:
12185 case BuiltinType::SatUShortFract:
12186 case BuiltinType::SatUFract:
12187 case BuiltinType::SatULongFract:
12188 return GCCTypeClass::None;
12190 case BuiltinType::NullPtr:
12192 case BuiltinType::ObjCId:
12193 case BuiltinType::ObjCClass:
12194 case BuiltinType::ObjCSel:
12195#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
12196 case BuiltinType::Id:
12197#include "clang/Basic/OpenCLImageTypes.def"
12198#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
12199 case BuiltinType::Id:
12200#include "clang/Basic/OpenCLExtensionTypes.def"
12201 case BuiltinType::OCLSampler:
12202 case BuiltinType::OCLEvent:
12203 case BuiltinType::OCLClkEvent:
12204 case BuiltinType::OCLQueue:
12205 case BuiltinType::OCLReserveID:
12206#define SVE_TYPE(Name, Id, SingletonId) \
12207 case BuiltinType::Id:
12208#include "clang/Basic/AArch64SVEACLETypes.def"
12209#define PPC_VECTOR_TYPE(Name, Id, Size) \
12210 case BuiltinType::Id:
12211#include "clang/Basic/PPCTypes.def"
12212#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
12213#include "clang/Basic/RISCVVTypes.def"
12214#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
12215#include "clang/Basic/WebAssemblyReferenceTypes.def"
12216#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
12217#include "clang/Basic/AMDGPUTypes.def"
12218#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
12219#include "clang/Basic/HLSLIntangibleTypes.def"
12220 return GCCTypeClass::None;
12222 case BuiltinType::Dependent:
12223 llvm_unreachable(
"unexpected dependent type");
12225 llvm_unreachable(
"unexpected placeholder type");
12228 return LangOpts.CPlusPlus ? GCCTypeClass::Enum : GCCTypeClass::Integer;
12230 case Type::Pointer:
12231 case Type::ConstantArray:
12232 case Type::VariableArray:
12233 case Type::IncompleteArray:
12234 case Type::FunctionNoProto:
12235 case Type::FunctionProto:
12236 case Type::ArrayParameter:
12237 return GCCTypeClass::Pointer;
12239 case Type::MemberPointer:
12241 ? GCCTypeClass::PointerToDataMember
12242 : GCCTypeClass::PointerToMemberFunction;
12244 case Type::Complex:
12245 return GCCTypeClass::Complex;
12248 return CanTy->
isUnionType() ? GCCTypeClass::Union
12249 : GCCTypeClass::ClassOrStruct;
12257 case Type::ExtVector:
12258 return GCCTypeClass::Vector;
12260 case Type::BlockPointer:
12261 case Type::ConstantMatrix:
12262 case Type::ObjCObject:
12263 case Type::ObjCInterface:
12264 case Type::ObjCObjectPointer:
12266 case Type::HLSLAttributedResource:
12269 return GCCTypeClass::None;
12272 return GCCTypeClass::BitInt;
12274 case Type::LValueReference:
12275 case Type::RValueReference:
12276 llvm_unreachable(
"invalid type for expression");
12279 llvm_unreachable(
"unexpected type class");
12288 if (
E->getNumArgs() == 0)
12289 return GCCTypeClass::None;
12304 if (
Base.isNull()) {
12307 }
else if (
const Expr *
E =
Base.dyn_cast<
const Expr *>()) {
12308 if (!isa<StringLiteral>(
E))
12326 SpeculativeEvaluationRAII SpeculativeEval(Info);
12331 FoldConstant Fold(Info,
true);
12354 Fold.keepDiagnostics();
12363 return V.hasValue();
12374 if (
const VarDecl *VD = dyn_cast<VarDecl>(
D))
12377 if (isa<CompoundLiteralExpr>(
E))
12398 const auto *Cast = dyn_cast<CastExpr>(NoParens);
12399 if (Cast ==
nullptr)
12404 auto CastKind = Cast->getCastKind();
12406 CastKind != CK_AddressSpaceConversion)
12409 const auto *SubExpr = Cast->getSubExpr();
12431 assert(!LVal.Designator.Invalid);
12433 auto IsLastOrInvalidFieldDecl = [&Ctx](
const FieldDecl *FD,
bool &
Invalid) {
12442 auto &
Base = LVal.getLValueBase();
12443 if (
auto *ME = dyn_cast_or_null<MemberExpr>(
Base.dyn_cast<
const Expr *>())) {
12444 if (
auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
12446 if (!IsLastOrInvalidFieldDecl(FD,
Invalid))
12448 }
else if (
auto *IFD = dyn_cast<IndirectFieldDecl>(ME->getMemberDecl())) {
12449 for (
auto *FD : IFD->chain()) {
12451 if (!IsLastOrInvalidFieldDecl(cast<FieldDecl>(FD),
Invalid))
12459 if (LVal.Designator.FirstEntryIsAnUnsizedArray) {
12469 for (
unsigned E = LVal.Designator.Entries.size(); I !=
E; ++I) {
12470 const auto &Entry = LVal.Designator.Entries[I];
12476 const auto *CAT = cast<ConstantArrayType>(Ctx.
getAsArrayType(BaseType));
12477 uint64_t Index = Entry.getAsArrayIndex();
12483 uint64_t Index = Entry.getAsArrayIndex();
12486 BaseType = CT->getElementType();
12487 }
else if (
auto *FD = getAsField(Entry)) {
12489 if (!IsLastOrInvalidFieldDecl(FD,
Invalid))
12493 assert(getAsBaseClass(Entry) &&
"Expecting cast to a base class");
12505 if (LVal.Designator.Invalid)
12508 if (!LVal.Designator.Entries.empty())
12509 return LVal.Designator.isMostDerivedAnUnsizedArray();
12511 if (!LVal.InvalidBase)
12516 const auto *
E = LVal.Base.dyn_cast<
const Expr *>();
12517 return !
E || !isa<MemberExpr>(
E);
12523 const SubobjectDesignator &
Designator = LVal.Designator;
12535 auto isFlexibleArrayMember = [&] {
12537 FAMKind StrictFlexArraysLevel =
12540 if (
Designator.isMostDerivedAnUnsizedArray())
12543 if (StrictFlexArraysLevel == FAMKind::Default)
12546 if (
Designator.getMostDerivedArraySize() == 0 &&
12547 StrictFlexArraysLevel != FAMKind::IncompleteOnly)
12550 if (
Designator.getMostDerivedArraySize() == 1 &&
12551 StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete)
12557 return LVal.InvalidBase &&
12559 Designator.MostDerivedIsArrayElement && isFlexibleArrayMember() &&
12567 auto CharUnitsMax = std::numeric_limits<CharUnits::QuantityType>::max();
12568 if (Int.ugt(CharUnitsMax))
12580 if (
const auto *
V = LV.getLValueBase().dyn_cast<
const ValueDecl *>())
12581 if (
const auto *VD = dyn_cast<VarDecl>(
V))
12593 unsigned Type,
const LValue &LVal,
12606 if (!(
Type & 1) || LVal.Designator.Invalid || DetermineForCompleteObject) {
12608 if (
Type == 3 && !DetermineForCompleteObject)
12611 llvm::APInt APEndOffset;
12612 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
12616 if (LVal.InvalidBase)
12620 const bool Ret = CheckedHandleSizeof(BaseTy, EndOffset);
12626 const SubobjectDesignator &
Designator = LVal.Designator;
12638 llvm::APInt APEndOffset;
12639 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
12651 if (!CheckedHandleSizeof(
Designator.MostDerivedType, BytesPerElem))
12657 int64_t ElemsRemaining;
12660 uint64_t ArraySize =
Designator.getMostDerivedArraySize();
12661 uint64_t ArrayIndex =
Designator.Entries.back().getAsArrayIndex();
12662 ElemsRemaining = ArraySize <= ArrayIndex ? 0 : ArraySize - ArrayIndex;
12664 ElemsRemaining =
Designator.isOnePastTheEnd() ? 0 : 1;
12667 EndOffset = LVal.getLValueOffset() + BytesPerElem * ElemsRemaining;
12677 EvalInfo &Info, uint64_t &Size) {
12684 SpeculativeEvaluationRAII SpeculativeEval(Info);
12685 IgnoreSideEffectsRAII Fold(Info);
12693 LVal.setFrom(Info.Ctx, RVal);
12701 if (LVal.getLValueOffset().isNegative()) {
12712 if (EndOffset <= LVal.getLValueOffset())
12715 Size = (EndOffset - LVal.getLValueOffset()).getQuantity();
12719bool IntExprEvaluator::VisitCallExpr(
const CallExpr *
E) {
12720 if (!IsConstantEvaluatedBuiltinCall(
E))
12721 return ExprEvaluatorBaseTy::VisitCallExpr(
E);
12722 return VisitBuiltinCallExpr(
E,
E->getBuiltinCallee());
12738 Info.FFDiag(
E->getArg(0));
12744 assert(SrcInt.getBitWidth() >= Alignment.getBitWidth() &&
12745 "Bit widths must be the same");
12752bool IntExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *
E,
12753 unsigned BuiltinOp) {
12754 switch (BuiltinOp) {
12758 case Builtin::BI__builtin_dynamic_object_size:
12759 case Builtin::BI__builtin_object_size: {
12763 assert(
Type <= 3 &&
"unexpected type");
12774 switch (Info.EvalMode) {
12775 case EvalInfo::EM_ConstantExpression:
12776 case EvalInfo::EM_ConstantFold:
12777 case EvalInfo::EM_IgnoreSideEffects:
12780 case EvalInfo::EM_ConstantExpressionUnevaluated:
12785 llvm_unreachable(
"unexpected EvalMode");
12788 case Builtin::BI__builtin_os_log_format_buffer_size: {
12794 case Builtin::BI__builtin_is_aligned: {
12802 Ptr.setFrom(Info.Ctx, Src);
12808 assert(Alignment.isPowerOf2());
12821 Info.FFDiag(
E->getArg(0), diag::note_constexpr_alignment_compute)
12825 assert(Src.
isInt());
12826 return Success((Src.
getInt() & (Alignment - 1)) == 0 ? 1 : 0,
E);
12828 case Builtin::BI__builtin_align_up: {
12836 APSInt((Src.
getInt() + (Alignment - 1)) & ~(Alignment - 1),
12837 Src.
getInt().isUnsigned());
12838 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
12841 case Builtin::BI__builtin_align_down: {
12850 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
12854 case Builtin::BI__builtin_bitreverse8:
12855 case Builtin::BI__builtin_bitreverse16:
12856 case Builtin::BI__builtin_bitreverse32:
12857 case Builtin::BI__builtin_bitreverse64:
12858 case Builtin::BI__builtin_elementwise_bitreverse: {
12863 return Success(Val.reverseBits(),
E);
12866 case Builtin::BI__builtin_bswap16:
12867 case Builtin::BI__builtin_bswap32:
12868 case Builtin::BI__builtin_bswap64: {
12873 return Success(Val.byteSwap(),
E);
12876 case Builtin::BI__builtin_classify_type:
12879 case Builtin::BI__builtin_clrsb:
12880 case Builtin::BI__builtin_clrsbl:
12881 case Builtin::BI__builtin_clrsbll: {
12886 return Success(Val.getBitWidth() - Val.getSignificantBits(),
E);
12889 case Builtin::BI__builtin_clz:
12890 case Builtin::BI__builtin_clzl:
12891 case Builtin::BI__builtin_clzll:
12892 case Builtin::BI__builtin_clzs:
12893 case Builtin::BI__builtin_clzg:
12894 case Builtin::BI__lzcnt16:
12895 case Builtin::BI__lzcnt:
12896 case Builtin::BI__lzcnt64: {
12901 std::optional<APSInt> Fallback;
12902 if (BuiltinOp == Builtin::BI__builtin_clzg &&
E->getNumArgs() > 1) {
12906 Fallback = FallbackTemp;
12916 bool ZeroIsUndefined = BuiltinOp != Builtin::BI__lzcnt16 &&
12917 BuiltinOp != Builtin::BI__lzcnt &&
12918 BuiltinOp != Builtin::BI__lzcnt64;
12920 if (ZeroIsUndefined)
12924 return Success(Val.countl_zero(),
E);
12927 case Builtin::BI__builtin_constant_p: {
12928 const Expr *Arg =
E->getArg(0);
12937 Info.FFDiag(
E, diag::note_invalid_subexpr_in_const_expr);
12941 case Builtin::BI__noop:
12945 case Builtin::BI__builtin_is_constant_evaluated: {
12946 const auto *
Callee = Info.CurrentCall->getCallee();
12947 if (Info.InConstantContext && !Info.CheckingPotentialConstantExpression &&
12948 (Info.CallStackDepth == 1 ||
12949 (Info.CallStackDepth == 2 &&
Callee->isInStdNamespace() &&
12950 Callee->getIdentifier() &&
12951 Callee->getIdentifier()->isStr(
"is_constant_evaluated")))) {
12953 if (Info.EvalStatus.Diag)
12954 Info.report((Info.CallStackDepth == 1)
12956 : Info.CurrentCall->getCallRange().getBegin(),
12957 diag::warn_is_constant_evaluated_always_true_constexpr)
12958 << (Info.CallStackDepth == 1 ?
"__builtin_is_constant_evaluated"
12959 :
"std::is_constant_evaluated");
12962 return Success(Info.InConstantContext,
E);
12965 case Builtin::BI__builtin_is_within_lifetime:
12966 if (
auto result = EvaluateBuiltinIsWithinLifetime(*
this,
E))
12970 case Builtin::BI__builtin_ctz:
12971 case Builtin::BI__builtin_ctzl:
12972 case Builtin::BI__builtin_ctzll:
12973 case Builtin::BI__builtin_ctzs:
12974 case Builtin::BI__builtin_ctzg: {
12979 std::optional<APSInt> Fallback;
12980 if (BuiltinOp == Builtin::BI__builtin_ctzg &&
E->getNumArgs() > 1) {
12984 Fallback = FallbackTemp;
12994 return Success(Val.countr_zero(),
E);
12997 case Builtin::BI__builtin_eh_return_data_regno: {
12999 Operand = Info.Ctx.getTargetInfo().getEHDataRegisterNumber(Operand);
13003 case Builtin::BI__builtin_expect:
13004 case Builtin::BI__builtin_expect_with_probability:
13005 return Visit(
E->getArg(0));
13007 case Builtin::BI__builtin_ptrauth_string_discriminator: {
13014 case Builtin::BI__builtin_ffs:
13015 case Builtin::BI__builtin_ffsl:
13016 case Builtin::BI__builtin_ffsll: {
13021 unsigned N = Val.countr_zero();
13022 return Success(N == Val.getBitWidth() ? 0 : N + 1,
E);
13025 case Builtin::BI__builtin_fpclassify: {
13030 switch (Val.getCategory()) {
13031 case APFloat::fcNaN: Arg = 0;
break;
13032 case APFloat::fcInfinity: Arg = 1;
break;
13033 case APFloat::fcNormal: Arg = Val.isDenormal() ? 3 : 2;
break;
13034 case APFloat::fcZero: Arg = 4;
break;
13036 return Visit(
E->getArg(Arg));
13039 case Builtin::BI__builtin_isinf_sign: {
13042 Success(Val.isInfinity() ? (Val.isNegative() ? -1 : 1) : 0,
E);
13045 case Builtin::BI__builtin_isinf: {
13048 Success(Val.isInfinity() ? 1 : 0,
E);
13051 case Builtin::BI__builtin_isfinite: {
13054 Success(Val.isFinite() ? 1 : 0,
E);
13057 case Builtin::BI__builtin_isnan: {
13063 case Builtin::BI__builtin_isnormal: {
13066 Success(Val.isNormal() ? 1 : 0,
E);
13069 case Builtin::BI__builtin_issubnormal: {
13072 Success(Val.isDenormal() ? 1 : 0,
E);
13075 case Builtin::BI__builtin_iszero: {
13081 case Builtin::BI__builtin_signbit:
13082 case Builtin::BI__builtin_signbitf:
13083 case Builtin::BI__builtin_signbitl: {
13086 Success(Val.isNegative() ? 1 : 0,
E);
13089 case Builtin::BI__builtin_isgreater:
13090 case Builtin::BI__builtin_isgreaterequal:
13091 case Builtin::BI__builtin_isless:
13092 case Builtin::BI__builtin_islessequal:
13093 case Builtin::BI__builtin_islessgreater:
13094 case Builtin::BI__builtin_isunordered: {
13103 switch (BuiltinOp) {
13104 case Builtin::BI__builtin_isgreater:
13106 case Builtin::BI__builtin_isgreaterequal:
13108 case Builtin::BI__builtin_isless:
13110 case Builtin::BI__builtin_islessequal:
13112 case Builtin::BI__builtin_islessgreater: {
13113 APFloat::cmpResult cmp = LHS.compare(RHS);
13114 return cmp == APFloat::cmpResult::cmpLessThan ||
13115 cmp == APFloat::cmpResult::cmpGreaterThan;
13117 case Builtin::BI__builtin_isunordered:
13118 return LHS.compare(RHS) == APFloat::cmpResult::cmpUnordered;
13120 llvm_unreachable(
"Unexpected builtin ID: Should be a floating "
13121 "point comparison function");
13129 case Builtin::BI__builtin_issignaling: {
13132 Success(Val.isSignaling() ? 1 : 0,
E);
13135 case Builtin::BI__builtin_isfpclass: {
13139 unsigned Test =
static_cast<llvm::FPClassTest
>(MaskVal.getZExtValue());
13142 Success((Val.classify() & Test) ? 1 : 0,
E);
13145 case Builtin::BI__builtin_parity:
13146 case Builtin::BI__builtin_parityl:
13147 case Builtin::BI__builtin_parityll: {
13152 return Success(Val.popcount() % 2,
E);
13155 case Builtin::BI__builtin_abs:
13156 case Builtin::BI__builtin_labs:
13157 case Builtin::BI__builtin_llabs: {
13161 if (Val ==
APSInt(APInt::getSignedMinValue(Val.getBitWidth()),
13164 if (Val.isNegative())
13169 case Builtin::BI__builtin_popcount:
13170 case Builtin::BI__builtin_popcountl:
13171 case Builtin::BI__builtin_popcountll:
13172 case Builtin::BI__builtin_popcountg:
13173 case Builtin::BI__builtin_elementwise_popcount:
13174 case Builtin::BI__popcnt16:
13175 case Builtin::BI__popcnt:
13176 case Builtin::BI__popcnt64: {
13181 return Success(Val.popcount(),
E);
13184 case Builtin::BI__builtin_rotateleft8:
13185 case Builtin::BI__builtin_rotateleft16:
13186 case Builtin::BI__builtin_rotateleft32:
13187 case Builtin::BI__builtin_rotateleft64:
13188 case Builtin::BI_rotl8:
13189 case Builtin::BI_rotl16:
13190 case Builtin::BI_rotl:
13191 case Builtin::BI_lrotl:
13192 case Builtin::BI_rotl64: {
13198 return Success(Val.rotl(Amt.urem(Val.getBitWidth())),
E);
13201 case Builtin::BI__builtin_rotateright8:
13202 case Builtin::BI__builtin_rotateright16:
13203 case Builtin::BI__builtin_rotateright32:
13204 case Builtin::BI__builtin_rotateright64:
13205 case Builtin::BI_rotr8:
13206 case Builtin::BI_rotr16:
13207 case Builtin::BI_rotr:
13208 case Builtin::BI_lrotr:
13209 case Builtin::BI_rotr64: {
13215 return Success(Val.rotr(Amt.urem(Val.getBitWidth())),
E);
13218 case Builtin::BI__builtin_elementwise_add_sat: {
13224 APInt Result = LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS);
13227 case Builtin::BI__builtin_elementwise_sub_sat: {
13233 APInt Result = LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
13237 case Builtin::BIstrlen:
13238 case Builtin::BIwcslen:
13240 if (Info.getLangOpts().CPlusPlus11)
13241 Info.CCEDiag(
E, diag::note_constexpr_invalid_function)
13243 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
13245 Info.CCEDiag(
E, diag::note_invalid_subexpr_in_const_expr);
13247 case Builtin::BI__builtin_strlen:
13248 case Builtin::BI__builtin_wcslen: {
13257 case Builtin::BIstrcmp:
13258 case Builtin::BIwcscmp:
13259 case Builtin::BIstrncmp:
13260 case Builtin::BIwcsncmp:
13261 case Builtin::BImemcmp:
13262 case Builtin::BIbcmp:
13263 case Builtin::BIwmemcmp:
13265 if (Info.getLangOpts().CPlusPlus11)
13266 Info.CCEDiag(
E, diag::note_constexpr_invalid_function)
13268 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
13270 Info.CCEDiag(
E, diag::note_invalid_subexpr_in_const_expr);
13272 case Builtin::BI__builtin_strcmp:
13273 case Builtin::BI__builtin_wcscmp:
13274 case Builtin::BI__builtin_strncmp:
13275 case Builtin::BI__builtin_wcsncmp:
13276 case Builtin::BI__builtin_memcmp:
13277 case Builtin::BI__builtin_bcmp:
13278 case Builtin::BI__builtin_wmemcmp: {
13279 LValue String1, String2;
13285 if (BuiltinOp != Builtin::BIstrcmp &&
13286 BuiltinOp != Builtin::BIwcscmp &&
13287 BuiltinOp != Builtin::BI__builtin_strcmp &&
13288 BuiltinOp != Builtin::BI__builtin_wcscmp) {
13292 MaxLength = N.getZExtValue();
13296 if (MaxLength == 0u)
13299 if (!String1.checkNullPointerForFoldAccess(Info,
E,
AK_Read) ||
13300 !String2.checkNullPointerForFoldAccess(Info,
E,
AK_Read) ||
13301 String1.Designator.Invalid || String2.Designator.Invalid)
13304 QualType CharTy1 = String1.Designator.getType(Info.Ctx);
13305 QualType CharTy2 = String2.Designator.getType(Info.Ctx);
13307 bool IsRawByte = BuiltinOp == Builtin::BImemcmp ||
13308 BuiltinOp == Builtin::BIbcmp ||
13309 BuiltinOp == Builtin::BI__builtin_memcmp ||
13310 BuiltinOp == Builtin::BI__builtin_bcmp;
13312 assert(IsRawByte ||
13313 (Info.Ctx.hasSameUnqualifiedType(
13315 Info.Ctx.hasSameUnqualifiedType(CharTy1, CharTy2)));
13322 Info.FFDiag(
E, diag::note_constexpr_memcmp_unsupported)
13323 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp) << CharTy1
13328 const auto &ReadCurElems = [&](
APValue &Char1,
APValue &Char2) {
13331 Char1.
isInt() && Char2.isInt();
13333 const auto &AdvanceElems = [&] {
13339 (BuiltinOp != Builtin::BImemcmp && BuiltinOp != Builtin::BIbcmp &&
13340 BuiltinOp != Builtin::BIwmemcmp &&
13341 BuiltinOp != Builtin::BI__builtin_memcmp &&
13342 BuiltinOp != Builtin::BI__builtin_bcmp &&
13343 BuiltinOp != Builtin::BI__builtin_wmemcmp);
13344 bool IsWide = BuiltinOp == Builtin::BIwcscmp ||
13345 BuiltinOp == Builtin::BIwcsncmp ||
13346 BuiltinOp == Builtin::BIwmemcmp ||
13347 BuiltinOp == Builtin::BI__builtin_wcscmp ||
13348 BuiltinOp == Builtin::BI__builtin_wcsncmp ||
13349 BuiltinOp == Builtin::BI__builtin_wmemcmp;
13351 for (; MaxLength; --MaxLength) {
13353 if (!ReadCurElems(Char1, Char2))
13361 if (StopAtNull && !Char1.
getInt())
13363 assert(!(StopAtNull && !Char2.
getInt()));
13364 if (!AdvanceElems())
13371 case Builtin::BI__atomic_always_lock_free:
13372 case Builtin::BI__atomic_is_lock_free:
13373 case Builtin::BI__c11_atomic_is_lock_free: {
13389 if (
Size.isPowerOfTwo()) {
13391 unsigned InlineWidthBits =
13392 Info.Ctx.getTargetInfo().getMaxAtomicInlineWidth();
13393 if (Size <= Info.Ctx.toCharUnitsFromBits(InlineWidthBits)) {
13394 if (BuiltinOp == Builtin::BI__c11_atomic_is_lock_free ||
13400 const Expr *PtrArg =
E->getArg(1);
13406 IntResult.isAligned(
Size.getAsAlign()))
13410 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(PtrArg)) {
13413 if (ICE->getCastKind() == CK_BitCast)
13414 PtrArg = ICE->getSubExpr();
13420 Info.Ctx.getTypeAlignInChars(PointeeType) >= Size) {
13428 return BuiltinOp == Builtin::BI__atomic_always_lock_free ?
13431 case Builtin::BI__builtin_addcb:
13432 case Builtin::BI__builtin_addcs:
13433 case Builtin::BI__builtin_addc:
13434 case Builtin::BI__builtin_addcl:
13435 case Builtin::BI__builtin_addcll:
13436 case Builtin::BI__builtin_subcb:
13437 case Builtin::BI__builtin_subcs:
13438 case Builtin::BI__builtin_subc:
13439 case Builtin::BI__builtin_subcl:
13440 case Builtin::BI__builtin_subcll: {
13441 LValue CarryOutLValue;
13442 APSInt LHS, RHS, CarryIn, CarryOut, Result;
13453 bool FirstOverflowed =
false;
13454 bool SecondOverflowed =
false;
13455 switch (BuiltinOp) {
13457 llvm_unreachable(
"Invalid value for BuiltinOp");
13458 case Builtin::BI__builtin_addcb:
13459 case Builtin::BI__builtin_addcs:
13460 case Builtin::BI__builtin_addc:
13461 case Builtin::BI__builtin_addcl:
13462 case Builtin::BI__builtin_addcll:
13464 LHS.uadd_ov(RHS, FirstOverflowed).uadd_ov(CarryIn, SecondOverflowed);
13466 case Builtin::BI__builtin_subcb:
13467 case Builtin::BI__builtin_subcs:
13468 case Builtin::BI__builtin_subc:
13469 case Builtin::BI__builtin_subcl:
13470 case Builtin::BI__builtin_subcll:
13472 LHS.usub_ov(RHS, FirstOverflowed).usub_ov(CarryIn, SecondOverflowed);
13478 CarryOut = (
uint64_t)(FirstOverflowed | SecondOverflowed);
13484 case Builtin::BI__builtin_add_overflow:
13485 case Builtin::BI__builtin_sub_overflow:
13486 case Builtin::BI__builtin_mul_overflow:
13487 case Builtin::BI__builtin_sadd_overflow:
13488 case Builtin::BI__builtin_uadd_overflow:
13489 case Builtin::BI__builtin_uaddl_overflow:
13490 case Builtin::BI__builtin_uaddll_overflow:
13491 case Builtin::BI__builtin_usub_overflow:
13492 case Builtin::BI__builtin_usubl_overflow:
13493 case Builtin::BI__builtin_usubll_overflow:
13494 case Builtin::BI__builtin_umul_overflow:
13495 case Builtin::BI__builtin_umull_overflow:
13496 case Builtin::BI__builtin_umulll_overflow:
13497 case Builtin::BI__builtin_saddl_overflow:
13498 case Builtin::BI__builtin_saddll_overflow:
13499 case Builtin::BI__builtin_ssub_overflow:
13500 case Builtin::BI__builtin_ssubl_overflow:
13501 case Builtin::BI__builtin_ssubll_overflow:
13502 case Builtin::BI__builtin_smul_overflow:
13503 case Builtin::BI__builtin_smull_overflow:
13504 case Builtin::BI__builtin_smulll_overflow: {
13505 LValue ResultLValue;
13515 bool DidOverflow =
false;
13518 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
13519 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
13520 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
13521 bool IsSigned = LHS.isSigned() || RHS.isSigned() ||
13523 bool AllSigned = LHS.isSigned() && RHS.isSigned() &&
13525 uint64_t LHSSize = LHS.getBitWidth();
13526 uint64_t RHSSize = RHS.getBitWidth();
13527 uint64_t ResultSize = Info.Ctx.getTypeSize(ResultType);
13528 uint64_t MaxBits = std::max(std::max(LHSSize, RHSSize), ResultSize);
13534 if (IsSigned && !AllSigned)
13537 LHS =
APSInt(LHS.extOrTrunc(MaxBits), !IsSigned);
13538 RHS =
APSInt(RHS.extOrTrunc(MaxBits), !IsSigned);
13539 Result =
APSInt(MaxBits, !IsSigned);
13543 switch (BuiltinOp) {
13545 llvm_unreachable(
"Invalid value for BuiltinOp");
13546 case Builtin::BI__builtin_add_overflow:
13547 case Builtin::BI__builtin_sadd_overflow:
13548 case Builtin::BI__builtin_saddl_overflow:
13549 case Builtin::BI__builtin_saddll_overflow:
13550 case Builtin::BI__builtin_uadd_overflow:
13551 case Builtin::BI__builtin_uaddl_overflow:
13552 case Builtin::BI__builtin_uaddll_overflow:
13553 Result = LHS.isSigned() ? LHS.sadd_ov(RHS, DidOverflow)
13554 : LHS.uadd_ov(RHS, DidOverflow);
13556 case Builtin::BI__builtin_sub_overflow:
13557 case Builtin::BI__builtin_ssub_overflow:
13558 case Builtin::BI__builtin_ssubl_overflow:
13559 case Builtin::BI__builtin_ssubll_overflow:
13560 case Builtin::BI__builtin_usub_overflow:
13561 case Builtin::BI__builtin_usubl_overflow:
13562 case Builtin::BI__builtin_usubll_overflow:
13563 Result = LHS.isSigned() ? LHS.ssub_ov(RHS, DidOverflow)
13564 : LHS.usub_ov(RHS, DidOverflow);
13566 case Builtin::BI__builtin_mul_overflow:
13567 case Builtin::BI__builtin_smul_overflow:
13568 case Builtin::BI__builtin_smull_overflow:
13569 case Builtin::BI__builtin_smulll_overflow:
13570 case Builtin::BI__builtin_umul_overflow:
13571 case Builtin::BI__builtin_umull_overflow:
13572 case Builtin::BI__builtin_umulll_overflow:
13573 Result = LHS.isSigned() ? LHS.smul_ov(RHS, DidOverflow)
13574 : LHS.umul_ov(RHS, DidOverflow);
13580 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
13581 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
13582 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
13588 APSInt Temp = Result.extOrTrunc(Info.Ctx.getTypeSize(ResultType));
13591 if (!APSInt::isSameValue(Temp, Result))
13592 DidOverflow =
true;
13602 case Builtin::BI__builtin_reduce_add:
13603 case Builtin::BI__builtin_reduce_mul:
13604 case Builtin::BI__builtin_reduce_and:
13605 case Builtin::BI__builtin_reduce_or:
13606 case Builtin::BI__builtin_reduce_xor:
13607 case Builtin::BI__builtin_reduce_min:
13608 case Builtin::BI__builtin_reduce_max: {
13615 for (
unsigned EltNum = 1; EltNum < SourceLen; ++EltNum) {
13616 switch (BuiltinOp) {
13619 case Builtin::BI__builtin_reduce_add: {
13622 Reduced.getBitWidth() + 1, std::plus<APSInt>(), Reduced))
13626 case Builtin::BI__builtin_reduce_mul: {
13629 Reduced.getBitWidth() * 2, std::multiplies<APSInt>(), Reduced))
13633 case Builtin::BI__builtin_reduce_and: {
13637 case Builtin::BI__builtin_reduce_or: {
13641 case Builtin::BI__builtin_reduce_xor: {
13645 case Builtin::BI__builtin_reduce_min: {
13649 case Builtin::BI__builtin_reduce_max: {
13659 case clang::X86::BI__builtin_ia32_addcarryx_u32:
13660 case clang::X86::BI__builtin_ia32_addcarryx_u64:
13661 case clang::X86::BI__builtin_ia32_subborrow_u32:
13662 case clang::X86::BI__builtin_ia32_subborrow_u64: {
13663 LValue ResultLValue;
13664 APSInt CarryIn, LHS, RHS;
13672 bool IsAdd = BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u32 ||
13673 BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u64;
13675 unsigned BitWidth = LHS.getBitWidth();
13676 unsigned CarryInBit = CarryIn.ugt(0) ? 1 : 0;
13679 ? (LHS.zext(BitWidth + 1) + (RHS.zext(BitWidth + 1) + CarryInBit))
13680 : (LHS.zext(BitWidth + 1) - (RHS.zext(BitWidth + 1) + CarryInBit));
13682 APInt Result = ExResult.extractBits(BitWidth, 0);
13683 uint64_t CarryOut = ExResult.extractBitsAsZExtValue(1, BitWidth);
13691 case clang::X86::BI__builtin_ia32_bextr_u32:
13692 case clang::X86::BI__builtin_ia32_bextr_u64:
13693 case clang::X86::BI__builtin_ia32_bextri_u32:
13694 case clang::X86::BI__builtin_ia32_bextri_u64: {
13700 unsigned BitWidth = Val.getBitWidth();
13702 uint64_t Length = Idx.extractBitsAsZExtValue(8, 8);
13703 Length = Length > BitWidth ? BitWidth : Length;
13706 if (Length == 0 || Shift >= BitWidth)
13710 Result &= llvm::maskTrailingOnes<uint64_t>(Length);
13714 case clang::X86::BI__builtin_ia32_bzhi_si:
13715 case clang::X86::BI__builtin_ia32_bzhi_di: {
13721 unsigned BitWidth = Val.getBitWidth();
13722 unsigned Index = Idx.extractBitsAsZExtValue(8, 0);
13723 if (Index < BitWidth)
13724 Val.clearHighBits(BitWidth - Index);
13728 case clang::X86::BI__builtin_ia32_lzcnt_u16:
13729 case clang::X86::BI__builtin_ia32_lzcnt_u32:
13730 case clang::X86::BI__builtin_ia32_lzcnt_u64: {
13734 return Success(Val.countLeadingZeros(),
E);
13737 case clang::X86::BI__builtin_ia32_tzcnt_u16:
13738 case clang::X86::BI__builtin_ia32_tzcnt_u32:
13739 case clang::X86::BI__builtin_ia32_tzcnt_u64: {
13743 return Success(Val.countTrailingZeros(),
E);
13746 case clang::X86::BI__builtin_ia32_pdep_si:
13747 case clang::X86::BI__builtin_ia32_pdep_di: {
13753 unsigned BitWidth = Val.getBitWidth();
13754 APInt Result = APInt::getZero(BitWidth);
13755 for (
unsigned I = 0,
P = 0; I != BitWidth; ++I)
13757 Result.setBitVal(I, Val[
P++]);
13761 case clang::X86::BI__builtin_ia32_pext_si:
13762 case clang::X86::BI__builtin_ia32_pext_di: {
13768 unsigned BitWidth = Val.getBitWidth();
13769 APInt Result = APInt::getZero(BitWidth);
13770 for (
unsigned I = 0,
P = 0; I != BitWidth; ++I)
13772 Result.setBitVal(
P++, Val[I]);
13781 const LValue &LV) {
13784 if (!LV.getLValueBase())
13789 if (!LV.getLValueDesignator().Invalid &&
13790 !LV.getLValueDesignator().isOnePastTheEnd())
13795 QualType Ty = getType(LV.getLValueBase());
13800 if (LV.getLValueDesignator().Invalid)
13806 return LV.getLValueOffset() == Size;
13816class DataRecursiveIntBinOpEvaluator {
13817 struct EvalResult {
13819 bool Failed =
false;
13821 EvalResult() =
default;
13823 void swap(EvalResult &RHS) {
13825 Failed = RHS.Failed;
13826 RHS.Failed =
false;
13832 EvalResult LHSResult;
13833 enum { AnyExprKind, BinOpKind, BinOpVisitedLHSKind }
Kind;
13836 Job(Job &&) =
default;
13838 void startSpeculativeEval(EvalInfo &Info) {
13839 SpecEvalRAII = SpeculativeEvaluationRAII(Info);
13843 SpeculativeEvaluationRAII SpecEvalRAII;
13848 IntExprEvaluator &IntEval;
13853 DataRecursiveIntBinOpEvaluator(IntExprEvaluator &IntEval,
APValue &Result)
13854 : IntEval(IntEval), Info(IntEval.getEvalInfo()), FinalResult(Result) { }
13861 return E->getOpcode() == BO_Comma ||
E->isLogicalOp() ||
13869 EvalResult PrevResult;
13870 while (!Queue.empty())
13871 process(PrevResult);
13873 if (PrevResult.Failed)
return false;
13875 FinalResult.
swap(PrevResult.Val);
13881 return IntEval.Success(
Value,
E, Result);
13884 return IntEval.Success(
Value,
E, Result);
13887 return IntEval.Error(
E);
13890 return IntEval.Error(
E,
D);
13894 return Info.CCEDiag(
E,
D);
13898 bool VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *
E,
13899 bool &SuppressRHSDiags);
13901 bool VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
13904 void EvaluateExpr(
const Expr *
E, EvalResult &Result) {
13905 Result.Failed = !
Evaluate(Result.Val, Info,
E);
13910 void process(EvalResult &Result);
13912 void enqueue(
const Expr *
E) {
13914 Queue.resize(Queue.size()+1);
13915 Queue.back().E =
E;
13916 Queue.back().Kind = Job::AnyExprKind;
13922bool DataRecursiveIntBinOpEvaluator::
13924 bool &SuppressRHSDiags) {
13925 if (
E->getOpcode() == BO_Comma) {
13927 if (LHSResult.Failed)
13928 return Info.noteSideEffect();
13932 if (
E->isLogicalOp()) {
13937 if (LHSAsBool == (
E->getOpcode() == BO_LOr)) {
13938 Success(LHSAsBool,
E, LHSResult.Val);
13942 LHSResult.Failed =
true;
13946 if (!Info.noteSideEffect())
13952 SuppressRHSDiags =
true;
13961 if (LHSResult.Failed && !Info.noteFailure())
13972 assert(!LVal.
hasLValuePath() &&
"have designator for integer lvalue");
13974 uint64_t Offset64 = Offset.getQuantity();
13975 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
13977 : Offset64 + Index64);
13980bool DataRecursiveIntBinOpEvaluator::
13981 VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
13983 if (
E->getOpcode() == BO_Comma) {
13984 if (RHSResult.Failed)
13986 Result = RHSResult.Val;
13990 if (
E->isLogicalOp()) {
13991 bool lhsResult, rhsResult;
13997 if (
E->getOpcode() == BO_LOr)
13998 return Success(lhsResult || rhsResult,
E, Result);
14000 return Success(lhsResult && rhsResult,
E, Result);
14006 if (rhsResult == (
E->getOpcode() == BO_LOr))
14007 return Success(rhsResult,
E, Result);
14017 if (LHSResult.Failed || RHSResult.Failed)
14020 const APValue &LHSVal = LHSResult.Val;
14021 const APValue &RHSVal = RHSResult.Val;
14031 if (
E->getOpcode() == BO_Add &&
14045 if (!LHSExpr || !RHSExpr)
14047 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
14048 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
14049 if (!LHSAddrExpr || !RHSAddrExpr)
14055 Result =
APValue(LHSAddrExpr, RHSAddrExpr);
14074void DataRecursiveIntBinOpEvaluator::process(EvalResult &Result) {
14075 Job &job = Queue.back();
14077 switch (job.Kind) {
14078 case Job::AnyExprKind: {
14079 if (
const BinaryOperator *Bop = dyn_cast<BinaryOperator>(job.E)) {
14080 if (shouldEnqueue(Bop)) {
14081 job.Kind = Job::BinOpKind;
14082 enqueue(Bop->getLHS());
14087 EvaluateExpr(job.E, Result);
14092 case Job::BinOpKind: {
14094 bool SuppressRHSDiags =
false;
14095 if (!VisitBinOpLHSOnly(Result, Bop, SuppressRHSDiags)) {
14099 if (SuppressRHSDiags)
14100 job.startSpeculativeEval(Info);
14101 job.LHSResult.swap(Result);
14102 job.Kind = Job::BinOpVisitedLHSKind;
14107 case Job::BinOpVisitedLHSKind: {
14111 Result.Failed = !VisitBinOp(job.LHSResult, RHS, Bop, Result.Val);
14117 llvm_unreachable(
"Invalid Job::Kind!");
14121enum class CmpResult {
14130template <
class SuccessCB,
class AfterCB>
14133 SuccessCB &&
Success, AfterCB &&DoAfter) {
14135 assert(
E->isComparisonOp() &&
"expected comparison operator");
14136 assert((
E->getOpcode() == BO_Cmp ||
14138 "unsupported binary expression evaluation");
14139 auto Error = [&](
const Expr *
E) {
14140 Info.FFDiag(
E, diag::note_invalid_subexpr_in_const_expr);
14144 bool IsRelational =
E->isRelationalOp() ||
E->getOpcode() == BO_Cmp;
14145 bool IsEquality =
E->isEqualityOp();
14154 if (!LHSOK && !Info.noteFailure())
14159 return Success(CmpResult::Less,
E);
14161 return Success(CmpResult::Greater,
E);
14162 return Success(CmpResult::Equal,
E);
14166 APFixedPoint LHSFX(Info.Ctx.getFixedPointSemantics(LHSTy));
14167 APFixedPoint RHSFX(Info.Ctx.getFixedPointSemantics(RHSTy));
14170 if (!LHSOK && !Info.noteFailure())
14175 return Success(CmpResult::Less,
E);
14177 return Success(CmpResult::Greater,
E);
14178 return Success(CmpResult::Equal,
E);
14182 ComplexValue LHS, RHS;
14184 if (
E->isAssignmentOp()) {
14191 LHS.makeComplexFloat();
14192 LHS.FloatImag = APFloat(LHS.FloatReal.getSemantics());
14197 if (!LHSOK && !Info.noteFailure())
14203 RHS.makeComplexFloat();
14204 RHS.FloatImag = APFloat(RHS.FloatReal.getSemantics());
14208 if (LHS.isComplexFloat()) {
14209 APFloat::cmpResult CR_r =
14210 LHS.getComplexFloatReal().compare(RHS.getComplexFloatReal());
14211 APFloat::cmpResult CR_i =
14212 LHS.getComplexFloatImag().compare(RHS.getComplexFloatImag());
14213 bool IsEqual = CR_r == APFloat::cmpEqual && CR_i == APFloat::cmpEqual;
14214 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal,
E);
14216 assert(IsEquality &&
"invalid complex comparison");
14217 bool IsEqual = LHS.getComplexIntReal() == RHS.getComplexIntReal() &&
14218 LHS.getComplexIntImag() == RHS.getComplexIntImag();
14219 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal,
E);
14225 APFloat RHS(0.0), LHS(0.0);
14228 if (!LHSOK && !Info.noteFailure())
14234 assert(
E->isComparisonOp() &&
"Invalid binary operator!");
14235 llvm::APFloatBase::cmpResult APFloatCmpResult = LHS.compare(RHS);
14236 if (!Info.InConstantContext &&
14237 APFloatCmpResult == APFloat::cmpUnordered &&
14240 Info.FFDiag(
E, diag::note_constexpr_float_arithmetic_strict);
14243 auto GetCmpRes = [&]() {
14244 switch (APFloatCmpResult) {
14245 case APFloat::cmpEqual:
14246 return CmpResult::Equal;
14247 case APFloat::cmpLessThan:
14248 return CmpResult::Less;
14249 case APFloat::cmpGreaterThan:
14250 return CmpResult::Greater;
14251 case APFloat::cmpUnordered:
14252 return CmpResult::Unordered;
14254 llvm_unreachable(
"Unrecognised APFloat::cmpResult enum");
14260 LValue LHSValue, RHSValue;
14263 if (!LHSOK && !Info.noteFailure())
14272 auto DiagComparison = [&] (
unsigned DiagID,
bool Reversed =
false) {
14273 std::string LHS = LHSValue.toString(Info.Ctx,
E->getLHS()->
getType());
14274 std::string RHS = RHSValue.toString(Info.Ctx,
E->getRHS()->
getType());
14275 Info.FFDiag(
E, DiagID)
14282 return DiagComparison(
14283 diag::note_constexpr_pointer_comparison_unspecified);
14289 if ((!LHSValue.Base && !LHSValue.Offset.isZero()) ||
14290 (!RHSValue.Base && !RHSValue.Offset.isZero()))
14291 return DiagComparison(diag::note_constexpr_pointer_constant_comparison,
14305 return DiagComparison(diag::note_constexpr_literal_comparison);
14307 return DiagComparison(diag::note_constexpr_opaque_call_comparison,
14312 return DiagComparison(diag::note_constexpr_pointer_weak_comparison,
14316 if (LHSValue.Base && LHSValue.Offset.isZero() &&
14318 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
14320 if (RHSValue.Base && RHSValue.Offset.isZero() &&
14322 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
14328 return DiagComparison(
14329 diag::note_constexpr_pointer_comparison_zero_sized);
14330 return Success(CmpResult::Unequal,
E);
14333 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
14334 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
14336 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
14337 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
14347 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid && IsRelational) {
14348 bool WasArrayIndex;
14350 getType(LHSValue.Base), LHSDesignator, RHSDesignator, WasArrayIndex);
14357 if (!WasArrayIndex && Mismatch < LHSDesignator.Entries.size() &&
14358 Mismatch < RHSDesignator.Entries.size()) {
14359 const FieldDecl *LF = getAsField(LHSDesignator.Entries[Mismatch]);
14360 const FieldDecl *RF = getAsField(RHSDesignator.Entries[Mismatch]);
14362 Info.CCEDiag(
E, diag::note_constexpr_pointer_comparison_base_classes);
14364 Info.CCEDiag(
E, diag::note_constexpr_pointer_comparison_base_field)
14365 << getAsBaseClass(LHSDesignator.Entries[Mismatch])
14368 Info.CCEDiag(
E, diag::note_constexpr_pointer_comparison_base_field)
14369 << getAsBaseClass(RHSDesignator.Entries[Mismatch])
14374 diag::note_constexpr_pointer_comparison_differing_access)
14382 unsigned PtrSize = Info.Ctx.getTypeSize(LHSTy);
14385 assert(PtrSize <= 64 &&
"Unexpected pointer width");
14386 uint64_t Mask = ~0ULL >> (64 - PtrSize);
14387 CompareLHS &= Mask;
14388 CompareRHS &= Mask;
14393 if (!LHSValue.Base.isNull() && IsRelational) {
14394 QualType BaseTy = getType(LHSValue.Base);
14397 CharUnits Size = Info.Ctx.getTypeSizeInChars(BaseTy);
14398 uint64_t OffsetLimit = Size.getQuantity();
14399 if (CompareLHS > OffsetLimit || CompareRHS > OffsetLimit)
14403 if (CompareLHS < CompareRHS)
14404 return Success(CmpResult::Less,
E);
14405 if (CompareLHS > CompareRHS)
14406 return Success(CmpResult::Greater,
E);
14407 return Success(CmpResult::Equal,
E);
14411 assert(IsEquality &&
"unexpected member pointer operation");
14414 MemberPtr LHSValue, RHSValue;
14417 if (!LHSOK && !Info.noteFailure())
14425 if (LHSValue.getDecl() && LHSValue.getDecl()->isWeak()) {
14426 Info.FFDiag(
E, diag::note_constexpr_mem_pointer_weak_comparison)
14427 << LHSValue.getDecl();
14430 if (RHSValue.getDecl() && RHSValue.getDecl()->isWeak()) {
14431 Info.FFDiag(
E, diag::note_constexpr_mem_pointer_weak_comparison)
14432 << RHSValue.getDecl();
14439 if (!LHSValue.getDecl() || !RHSValue.getDecl()) {
14440 bool Equal = !LHSValue.getDecl() && !RHSValue.getDecl();
14441 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal,
E);
14446 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(LHSValue.getDecl()))
14447 if (MD->isVirtual())
14448 Info.CCEDiag(
E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
14449 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(RHSValue.getDecl()))
14450 if (MD->isVirtual())
14451 Info.CCEDiag(
E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
14457 bool Equal = LHSValue == RHSValue;
14458 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal,
E);
14462 assert(
E->isComparisonOp() &&
"unexpected nullptr operation");
14463 assert(RHSTy->
isNullPtrType() &&
"missing pointer conversion");
14471 return Success(CmpResult::Equal,
E);
14484 case CmpResult::Unequal:
14485 llvm_unreachable(
"should never produce Unequal for three-way comparison");
14486 case CmpResult::Less:
14487 CCR = ComparisonCategoryResult::Less;
14489 case CmpResult::Equal:
14490 CCR = ComparisonCategoryResult::Equal;
14492 case CmpResult::Greater:
14493 CCR = ComparisonCategoryResult::Greater;
14495 case CmpResult::Unordered:
14496 CCR = ComparisonCategoryResult::Unordered;
14510 ConstantExprKind::Normal);
14513 return ExprEvaluatorBaseTy::VisitBinCmp(
E);
14517bool RecordExprEvaluator::VisitCXXParenListInitExpr(
14519 return VisitCXXParenListOrInitListExpr(
E,
E->getInitExprs());
14525 if (
E->isAssignmentOp()) {
14527 if (!Info.noteFailure())
14531 if (DataRecursiveIntBinOpEvaluator::shouldEnqueue(
E))
14532 return DataRecursiveIntBinOpEvaluator(*
this, Result).Traverse(
E);
14536 "DataRecursiveIntBinOpEvaluator should have handled integral types");
14538 if (
E->isComparisonOp()) {
14542 assert((CR != CmpResult::Unequal ||
E->isEqualityOp()) &&
14543 "should only produce Unequal for equality comparisons");
14544 bool IsEqual = CR == CmpResult::Equal,
14545 IsLess = CR == CmpResult::Less,
14546 IsGreater = CR == CmpResult::Greater;
14547 auto Op =
E->getOpcode();
14550 llvm_unreachable(
"unsupported binary operator");
14553 return Success(IsEqual == (Op == BO_EQ),
E);
14559 return Success(IsEqual || IsLess,
E);
14561 return Success(IsEqual || IsGreater,
E);
14565 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
14573 E->getOpcode() == BO_Sub) {
14574 LValue LHSValue, RHSValue;
14577 if (!LHSOK && !Info.noteFailure())
14587 if (!LHSValue.Offset.isZero() || !RHSValue.Offset.isZero())
14589 const Expr *LHSExpr = LHSValue.Base.dyn_cast<
const Expr *>();
14590 const Expr *RHSExpr = RHSValue.Base.dyn_cast<
const Expr *>();
14591 if (!LHSExpr || !RHSExpr)
14593 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
14594 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
14595 if (!LHSAddrExpr || !RHSAddrExpr)
14603 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
14604 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
14606 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
14607 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
14613 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid &&
14616 Info.CCEDiag(
E, diag::note_constexpr_pointer_subtraction_not_same_array);
14628 if (ElementSize.
isZero()) {
14629 Info.FFDiag(
E, diag::note_constexpr_pointer_subtraction_zero_size)
14646 APSInt TrueResult = (LHS - RHS) / ElemSize;
14647 APSInt Result = TrueResult.trunc(Info.Ctx.getIntWidth(
E->
getType()));
14649 if (Result.extend(65) != TrueResult &&
14655 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
14660bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr(
14662 switch(
E->getKind()) {
14663 case UETT_PreferredAlignOf:
14664 case UETT_AlignOf: {
14665 if (
E->isArgumentType())
14673 case UETT_PtrAuthTypeDiscriminator: {
14674 if (
E->getArgumentType()->isDependentType())
14677 Info.Ctx.getPointerAuthTypeDiscriminator(
E->getArgumentType()),
E);
14679 case UETT_VecStep: {
14695 case UETT_DataSizeOf:
14696 case UETT_SizeOf: {
14697 QualType SrcTy =
E->getTypeOfArgument();
14705 E->getKind() == UETT_DataSizeOf ? SizeOfType::DataSizeOf
14706 : SizeOfType::SizeOf)) {
14711 case UETT_OpenMPRequiredSimdAlign:
14712 assert(
E->isArgumentType());
14714 Info.Ctx.toCharUnitsFromBits(
14715 Info.Ctx.getOpenMPDefaultSimdAlign(
E->getArgumentType()))
14718 case UETT_VectorElements: {
14726 if (Info.InConstantContext)
14727 Info.CCEDiag(
E, diag::note_constexpr_non_const_vectorelements)
14734 llvm_unreachable(
"unknown expr/type trait");
14737bool IntExprEvaluator::VisitOffsetOfExpr(
const OffsetOfExpr *OOE) {
14743 for (
unsigned i = 0; i != n; ++i) {
14751 const ArrayType *AT = Info.Ctx.getAsArrayType(CurrentType);
14755 CharUnits ElementSize = Info.Ctx.getTypeSizeInChars(CurrentType);
14756 Result += IdxResult.getSExtValue() * ElementSize;
14769 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
14776 llvm_unreachable(
"dependent __builtin_offsetof");
14792 CurrentType = BaseSpec->
getType();
14806bool IntExprEvaluator::VisitUnaryOperator(
const UnaryOperator *
E) {
14807 switch (
E->getOpcode()) {
14815 return Visit(
E->getSubExpr());
14818 return Visit(
E->getSubExpr());
14820 if (!Visit(
E->getSubExpr()))
14822 if (!Result.isInt())
return Error(
E);
14824 if (
Value.isSigned() &&
Value.isMinSignedValue() &&
E->canOverflow()) {
14825 if (Info.checkingForUndefinedBehavior())
14826 Info.Ctx.getDiagnostics().Report(
E->
getExprLoc(),
14827 diag::warn_integer_constant_overflow)
14839 if (!Visit(
E->getSubExpr()))
14841 if (!Result.isInt())
return Error(
E);
14842 return Success(~Result.getInt(),
E);
14855bool IntExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
14856 const Expr *SubExpr =
E->getSubExpr();
14860 switch (
E->getCastKind()) {
14861 case CK_BaseToDerived:
14862 case CK_DerivedToBase:
14863 case CK_UncheckedDerivedToBase:
14866 case CK_ArrayToPointerDecay:
14867 case CK_FunctionToPointerDecay:
14868 case CK_NullToPointer:
14869 case CK_NullToMemberPointer:
14870 case CK_BaseToDerivedMemberPointer:
14871 case CK_DerivedToBaseMemberPointer:
14872 case CK_ReinterpretMemberPointer:
14873 case CK_ConstructorConversion:
14874 case CK_IntegralToPointer:
14876 case CK_VectorSplat:
14877 case CK_IntegralToFloating:
14878 case CK_FloatingCast:
14879 case CK_CPointerToObjCPointerCast:
14880 case CK_BlockPointerToObjCPointerCast:
14881 case CK_AnyPointerToBlockPointerCast:
14882 case CK_ObjCObjectLValueCast:
14883 case CK_FloatingRealToComplex:
14884 case CK_FloatingComplexToReal:
14885 case CK_FloatingComplexCast:
14886 case CK_FloatingComplexToIntegralComplex:
14887 case CK_IntegralRealToComplex:
14888 case CK_IntegralComplexCast:
14889 case CK_IntegralComplexToFloatingComplex:
14890 case CK_BuiltinFnToFnPtr:
14891 case CK_ZeroToOCLOpaqueType:
14892 case CK_NonAtomicToAtomic:
14893 case CK_AddressSpaceConversion:
14894 case CK_IntToOCLSampler:
14895 case CK_FloatingToFixedPoint:
14896 case CK_FixedPointToFloating:
14897 case CK_FixedPointCast:
14898 case CK_IntegralToFixedPoint:
14899 case CK_MatrixCast:
14900 llvm_unreachable(
"invalid cast kind for integral value");
14904 case CK_LValueBitCast:
14905 case CK_ARCProduceObject:
14906 case CK_ARCConsumeObject:
14907 case CK_ARCReclaimReturnedObject:
14908 case CK_ARCExtendBlockObject:
14909 case CK_CopyAndAutoreleaseBlockObject:
14912 case CK_UserDefinedConversion:
14913 case CK_LValueToRValue:
14914 case CK_AtomicToNonAtomic:
14916 case CK_LValueToRValueBitCast:
14917 case CK_HLSLArrayRValue:
14918 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
14920 case CK_MemberPointerToBoolean:
14921 case CK_PointerToBoolean:
14922 case CK_IntegralToBoolean:
14923 case CK_FloatingToBoolean:
14924 case CK_BooleanToSignedIntegral:
14925 case CK_FloatingComplexToBoolean:
14926 case CK_IntegralComplexToBoolean: {
14931 if (BoolResult &&
E->getCastKind() == CK_BooleanToSignedIntegral)
14936 case CK_FixedPointToIntegral: {
14937 APFixedPoint Src(Info.Ctx.getFixedPointSemantics(SrcType));
14941 llvm::APSInt Result = Src.convertToInt(
14942 Info.Ctx.getIntWidth(DestType),
14949 case CK_FixedPointToBoolean: {
14952 if (!
Evaluate(Val, Info, SubExpr))
14957 case CK_IntegralCast: {
14958 if (!Visit(SubExpr))
14961 if (!Result.isInt()) {
14967 if (Result.isAddrLabelDiff())
14968 return Info.Ctx.getTypeSize(DestType) <= Info.Ctx.getTypeSize(SrcType);
14970 return Info.Ctx.getTypeSize(DestType) == Info.Ctx.getTypeSize(SrcType);
14973 if (Info.Ctx.getLangOpts().CPlusPlus && Info.InConstantContext &&
14974 Info.EvalMode == EvalInfo::EM_ConstantExpression &&
14977 bool ConstexprVar =
true;
14984 if (
const auto *VD = dyn_cast_or_null<VarDecl>(
14985 Info.EvaluatingDecl.dyn_cast<
const ValueDecl *>()))
15008 (
Max.slt(Result.getInt().getSExtValue()) ||
15009 Min.sgt(Result.getInt().getSExtValue())))
15010 Info.CCEDiag(
E, diag::note_constexpr_unscoped_enum_out_of_range)
15011 << llvm::toString(Result.getInt(), 10) <<
Min.getSExtValue()
15012 <<
Max.getSExtValue() << ED;
15014 Max.ult(Result.getInt().getZExtValue()))
15015 Info.CCEDiag(
E, diag::note_constexpr_unscoped_enum_out_of_range)
15016 << llvm::toString(Result.getInt(), 10) <<
Min.getZExtValue()
15017 <<
Max.getZExtValue() << ED;
15022 Result.getInt()),
E);
15025 case CK_PointerToIntegral: {
15026 CCEDiag(
E, diag::note_constexpr_invalid_cast)
15033 if (LV.getLValueBase()) {
15038 if (Info.Ctx.getTypeSize(DestType) != Info.Ctx.getTypeSize(SrcType))
15041 LV.Designator.setInvalid();
15042 LV.moveInto(Result);
15049 if (!
V.toIntegralConstant(AsInt, SrcType, Info.Ctx))
15050 llvm_unreachable(
"Can't cast this!");
15055 case CK_IntegralComplexToReal: {
15059 return Success(
C.getComplexIntReal(),
E);
15062 case CK_FloatingToIntegral: {
15072 case CK_HLSLVectorTruncation: {
15080 llvm_unreachable(
"unknown cast resulting in integral value");
15088 if (!LV.isComplexInt())
15090 return Success(LV.getComplexIntReal(),
E);
15093 return Visit(
E->getSubExpr());
15101 if (!LV.isComplexInt())
15103 return Success(LV.getComplexIntImag(),
E);
15106 VisitIgnoredValue(
E->getSubExpr());
15118bool IntExprEvaluator::VisitConceptSpecializationExpr(
15123bool IntExprEvaluator::VisitRequiresExpr(
const RequiresExpr *
E) {
15127bool FixedPointExprEvaluator::VisitUnaryOperator(
const UnaryOperator *
E) {
15128 switch (
E->getOpcode()) {
15134 return Visit(
E->getSubExpr());
15136 if (!Visit(
E->getSubExpr()))
return false;
15137 if (!Result.isFixedPoint())
15140 APFixedPoint Negated = Result.getFixedPoint().negate(&Overflowed);
15154bool FixedPointExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
15155 const Expr *SubExpr =
E->getSubExpr();
15158 "Expected destination type to be a fixed point type");
15159 auto DestFXSema = Info.Ctx.getFixedPointSemantics(DestType);
15161 switch (
E->getCastKind()) {
15162 case CK_FixedPointCast: {
15163 APFixedPoint Src(Info.Ctx.getFixedPointSemantics(SubExpr->
getType()));
15167 APFixedPoint Result = Src.convert(DestFXSema, &Overflowed);
15169 if (Info.checkingForUndefinedBehavior())
15170 Info.Ctx.getDiagnostics().Report(
E->
getExprLoc(),
15171 diag::warn_fixedpoint_constant_overflow)
15172 << Result.toString() <<
E->
getType();
15178 case CK_IntegralToFixedPoint: {
15184 APFixedPoint IntResult = APFixedPoint::getFromIntValue(
15185 Src, Info.Ctx.getFixedPointSemantics(DestType), &Overflowed);
15188 if (Info.checkingForUndefinedBehavior())
15189 Info.Ctx.getDiagnostics().Report(
E->
getExprLoc(),
15190 diag::warn_fixedpoint_constant_overflow)
15191 << IntResult.toString() <<
E->
getType();
15198 case CK_FloatingToFixedPoint: {
15204 APFixedPoint Result = APFixedPoint::getFromFloatValue(
15205 Src, Info.Ctx.getFixedPointSemantics(DestType), &Overflowed);
15208 if (Info.checkingForUndefinedBehavior())
15209 Info.Ctx.getDiagnostics().Report(
E->
getExprLoc(),
15210 diag::warn_fixedpoint_constant_overflow)
15211 << Result.toString() <<
E->
getType();
15219 case CK_LValueToRValue:
15220 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
15226bool FixedPointExprEvaluator::VisitBinaryOperator(
const BinaryOperator *
E) {
15227 if (
E->isPtrMemOp() ||
E->isAssignmentOp() ||
E->getOpcode() == BO_Comma)
15228 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
15230 const Expr *LHS =
E->getLHS();
15231 const Expr *RHS =
E->getRHS();
15233 Info.Ctx.getFixedPointSemantics(
E->
getType());
15235 APFixedPoint LHSFX(Info.Ctx.getFixedPointSemantics(LHS->
getType()));
15238 APFixedPoint RHSFX(Info.Ctx.getFixedPointSemantics(RHS->
getType()));
15242 bool OpOverflow =
false, ConversionOverflow =
false;
15243 APFixedPoint Result(LHSFX.getSemantics());
15244 switch (
E->getOpcode()) {
15246 Result = LHSFX.
add(RHSFX, &OpOverflow)
15247 .convert(ResultFXSema, &ConversionOverflow);
15251 Result = LHSFX.sub(RHSFX, &OpOverflow)
15252 .convert(ResultFXSema, &ConversionOverflow);
15256 Result = LHSFX.mul(RHSFX, &OpOverflow)
15257 .convert(ResultFXSema, &ConversionOverflow);
15261 if (RHSFX.getValue() == 0) {
15262 Info.FFDiag(
E, diag::note_expr_divide_by_zero);
15265 Result = LHSFX.div(RHSFX, &OpOverflow)
15266 .convert(ResultFXSema, &ConversionOverflow);
15272 llvm::APSInt RHSVal = RHSFX.getValue();
15275 LHSSema.getWidth() - (
unsigned)LHSSema.hasUnsignedPadding();
15276 unsigned Amt = RHSVal.getLimitedValue(ShiftBW - 1);
15280 if (RHSVal.isNegative())
15281 Info.CCEDiag(
E, diag::note_constexpr_negative_shift) << RHSVal;
15282 else if (Amt != RHSVal)
15283 Info.CCEDiag(
E, diag::note_constexpr_large_shift)
15284 << RHSVal <<
E->
getType() << ShiftBW;
15286 if (
E->getOpcode() == BO_Shl)
15287 Result = LHSFX.shl(Amt, &OpOverflow);
15289 Result = LHSFX.shr(Amt, &OpOverflow);
15295 if (OpOverflow || ConversionOverflow) {
15296 if (Info.checkingForUndefinedBehavior())
15297 Info.Ctx.getDiagnostics().Report(
E->
getExprLoc(),
15298 diag::warn_fixedpoint_constant_overflow)
15299 << Result.toString() <<
E->
getType();
15311class FloatExprEvaluator
15312 :
public ExprEvaluatorBase<FloatExprEvaluator> {
15315 FloatExprEvaluator(EvalInfo &info, APFloat &result)
15316 : ExprEvaluatorBaseTy(info), Result(result) {}
15319 Result =
V.getFloat();
15323 bool ZeroInitialization(
const Expr *
E) {
15324 Result = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(
E->
getType()));
15345 return FloatExprEvaluator(Info, Result).Visit(
E);
15352 llvm::APFloat &Result) {
15354 if (!S)
return false;
15361 if (S->getString().empty())
15362 fill = llvm::APInt(32, 0);
15363 else if (S->getString().getAsInteger(0, fill))
15368 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
15370 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
15378 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
15380 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
15386bool FloatExprEvaluator::VisitCallExpr(
const CallExpr *
E) {
15387 if (!IsConstantEvaluatedBuiltinCall(
E))
15388 return ExprEvaluatorBaseTy::VisitCallExpr(
E);
15390 switch (
E->getBuiltinCallee()) {
15394 case Builtin::BI__builtin_huge_val:
15395 case Builtin::BI__builtin_huge_valf:
15396 case Builtin::BI__builtin_huge_vall:
15397 case Builtin::BI__builtin_huge_valf16:
15398 case Builtin::BI__builtin_huge_valf128:
15399 case Builtin::BI__builtin_inf:
15400 case Builtin::BI__builtin_inff:
15401 case Builtin::BI__builtin_infl:
15402 case Builtin::BI__builtin_inff16:
15403 case Builtin::BI__builtin_inff128: {
15404 const llvm::fltSemantics &Sem =
15405 Info.Ctx.getFloatTypeSemantics(
E->
getType());
15406 Result = llvm::APFloat::getInf(Sem);
15410 case Builtin::BI__builtin_nans:
15411 case Builtin::BI__builtin_nansf:
15412 case Builtin::BI__builtin_nansl:
15413 case Builtin::BI__builtin_nansf16:
15414 case Builtin::BI__builtin_nansf128:
15420 case Builtin::BI__builtin_nan:
15421 case Builtin::BI__builtin_nanf:
15422 case Builtin::BI__builtin_nanl:
15423 case Builtin::BI__builtin_nanf16:
15424 case Builtin::BI__builtin_nanf128:
15432 case Builtin::BI__builtin_fabs:
15433 case Builtin::BI__builtin_fabsf:
15434 case Builtin::BI__builtin_fabsl:
15435 case Builtin::BI__builtin_fabsf128:
15444 if (Result.isNegative())
15445 Result.changeSign();
15448 case Builtin::BI__arithmetic_fence:
15455 case Builtin::BI__builtin_copysign:
15456 case Builtin::BI__builtin_copysignf:
15457 case Builtin::BI__builtin_copysignl:
15458 case Builtin::BI__builtin_copysignf128: {
15463 Result.copySign(RHS);
15467 case Builtin::BI__builtin_fmax:
15468 case Builtin::BI__builtin_fmaxf:
15469 case Builtin::BI__builtin_fmaxl:
15470 case Builtin::BI__builtin_fmaxf16:
15471 case Builtin::BI__builtin_fmaxf128: {
15478 if (Result.isZero() && RHS.isZero() && Result.isNegative())
15480 else if (Result.isNaN() || RHS > Result)
15485 case Builtin::BI__builtin_fmin:
15486 case Builtin::BI__builtin_fminf:
15487 case Builtin::BI__builtin_fminl:
15488 case Builtin::BI__builtin_fminf16:
15489 case Builtin::BI__builtin_fminf128: {
15496 if (Result.isZero() && RHS.isZero() && RHS.isNegative())
15498 else if (Result.isNaN() || RHS < Result)
15503 case Builtin::BI__builtin_fmaximum_num:
15504 case Builtin::BI__builtin_fmaximum_numf:
15505 case Builtin::BI__builtin_fmaximum_numl:
15506 case Builtin::BI__builtin_fmaximum_numf16:
15507 case Builtin::BI__builtin_fmaximum_numf128: {
15512 Result = maximumnum(Result, RHS);
15516 case Builtin::BI__builtin_fminimum_num:
15517 case Builtin::BI__builtin_fminimum_numf:
15518 case Builtin::BI__builtin_fminimum_numl:
15519 case Builtin::BI__builtin_fminimum_numf16:
15520 case Builtin::BI__builtin_fminimum_numf128: {
15525 Result = minimumnum(Result, RHS);
15531bool FloatExprEvaluator::VisitUnaryReal(
const UnaryOperator *
E) {
15536 Result = CV.FloatReal;
15540 return Visit(
E->getSubExpr());
15543bool FloatExprEvaluator::VisitUnaryImag(
const UnaryOperator *
E) {
15548 Result = CV.FloatImag;
15552 VisitIgnoredValue(
E->getSubExpr());
15553 const llvm::fltSemantics &Sem = Info.Ctx.getFloatTypeSemantics(
E->
getType());
15554 Result = llvm::APFloat::getZero(Sem);
15558bool FloatExprEvaluator::VisitUnaryOperator(
const UnaryOperator *
E) {
15559 switch (
E->getOpcode()) {
15560 default:
return Error(
E);
15569 Result.changeSign();
15574bool FloatExprEvaluator::VisitBinaryOperator(
const BinaryOperator *
E) {
15575 if (
E->isPtrMemOp() ||
E->isAssignmentOp() ||
E->getOpcode() == BO_Comma)
15576 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
15580 if (!LHSOK && !Info.noteFailure())
15587 Result =
E->getValue();
15591bool FloatExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
15592 const Expr* SubExpr =
E->getSubExpr();
15594 switch (
E->getCastKind()) {
15596 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
15598 case CK_IntegralToFloating: {
15601 Info.Ctx.getLangOpts());
15607 case CK_FixedPointToFloating: {
15608 APFixedPoint FixResult(Info.Ctx.getFixedPointSemantics(SubExpr->
getType()));
15612 FixResult.convertToFloat(Info.Ctx.getFloatTypeSemantics(
E->
getType()));
15616 case CK_FloatingCast: {
15617 if (!Visit(SubExpr))
15623 case CK_FloatingComplexToReal: {
15627 Result =
V.getComplexFloatReal();
15630 case CK_HLSLVectorTruncation: {
15644class ComplexExprEvaluator
15645 :
public ExprEvaluatorBase<ComplexExprEvaluator> {
15646 ComplexValue &Result;
15649 ComplexExprEvaluator(EvalInfo &info, ComplexValue &Result)
15650 : ExprEvaluatorBaseTy(info), Result(Result) {}
15657 bool ZeroInitialization(
const Expr *
E);
15676 return ComplexExprEvaluator(Info, Result).Visit(
E);
15679bool ComplexExprEvaluator::ZeroInitialization(
const Expr *
E) {
15682 Result.makeComplexFloat();
15683 APFloat Zero = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(ElemTy));
15684 Result.FloatReal =
Zero;
15685 Result.FloatImag =
Zero;
15687 Result.makeComplexInt();
15688 APSInt Zero = Info.Ctx.MakeIntValue(0, ElemTy);
15689 Result.IntReal =
Zero;
15690 Result.IntImag =
Zero;
15696 const Expr* SubExpr =
E->getSubExpr();
15699 Result.makeComplexFloat();
15700 APFloat &Imag = Result.FloatImag;
15704 Result.FloatReal =
APFloat(Imag.getSemantics());
15708 "Unexpected imaginary literal.");
15710 Result.makeComplexInt();
15711 APSInt &Imag = Result.IntImag;
15715 Result.IntReal =
APSInt(Imag.getBitWidth(), !Imag.isSigned());
15720bool ComplexExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
15722 switch (
E->getCastKind()) {
15724 case CK_BaseToDerived:
15725 case CK_DerivedToBase:
15726 case CK_UncheckedDerivedToBase:
15729 case CK_ArrayToPointerDecay:
15730 case CK_FunctionToPointerDecay:
15731 case CK_NullToPointer:
15732 case CK_NullToMemberPointer:
15733 case CK_BaseToDerivedMemberPointer:
15734 case CK_DerivedToBaseMemberPointer:
15735 case CK_MemberPointerToBoolean:
15736 case CK_ReinterpretMemberPointer:
15737 case CK_ConstructorConversion:
15738 case CK_IntegralToPointer:
15739 case CK_PointerToIntegral:
15740 case CK_PointerToBoolean:
15742 case CK_VectorSplat:
15743 case CK_IntegralCast:
15744 case CK_BooleanToSignedIntegral:
15745 case CK_IntegralToBoolean:
15746 case CK_IntegralToFloating:
15747 case CK_FloatingToIntegral:
15748 case CK_FloatingToBoolean:
15749 case CK_FloatingCast:
15750 case CK_CPointerToObjCPointerCast:
15751 case CK_BlockPointerToObjCPointerCast:
15752 case CK_AnyPointerToBlockPointerCast:
15753 case CK_ObjCObjectLValueCast:
15754 case CK_FloatingComplexToReal:
15755 case CK_FloatingComplexToBoolean:
15756 case CK_IntegralComplexToReal:
15757 case CK_IntegralComplexToBoolean:
15758 case CK_ARCProduceObject:
15759 case CK_ARCConsumeObject:
15760 case CK_ARCReclaimReturnedObject:
15761 case CK_ARCExtendBlockObject:
15762 case CK_CopyAndAutoreleaseBlockObject:
15763 case CK_BuiltinFnToFnPtr:
15764 case CK_ZeroToOCLOpaqueType:
15765 case CK_NonAtomicToAtomic:
15766 case CK_AddressSpaceConversion:
15767 case CK_IntToOCLSampler:
15768 case CK_FloatingToFixedPoint:
15769 case CK_FixedPointToFloating:
15770 case CK_FixedPointCast:
15771 case CK_FixedPointToBoolean:
15772 case CK_FixedPointToIntegral:
15773 case CK_IntegralToFixedPoint:
15774 case CK_MatrixCast:
15775 case CK_HLSLVectorTruncation:
15776 llvm_unreachable(
"invalid cast kind for complex value");
15778 case CK_LValueToRValue:
15779 case CK_AtomicToNonAtomic:
15781 case CK_LValueToRValueBitCast:
15782 case CK_HLSLArrayRValue:
15783 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
15786 case CK_LValueBitCast:
15787 case CK_UserDefinedConversion:
15790 case CK_FloatingRealToComplex: {
15791 APFloat &Real = Result.FloatReal;
15795 Result.makeComplexFloat();
15796 Result.FloatImag =
APFloat(Real.getSemantics());
15800 case CK_FloatingComplexCast: {
15801 if (!Visit(
E->getSubExpr()))
15812 case CK_FloatingComplexToIntegralComplex: {
15813 if (!Visit(
E->getSubExpr()))
15819 Result.makeComplexInt();
15821 To, Result.IntReal) &&
15823 To, Result.IntImag);
15826 case CK_IntegralRealToComplex: {
15827 APSInt &Real = Result.IntReal;
15831 Result.makeComplexInt();
15832 Result.IntImag =
APSInt(Real.getBitWidth(), !Real.isSigned());
15836 case CK_IntegralComplexCast: {
15837 if (!Visit(
E->getSubExpr()))
15849 case CK_IntegralComplexToFloatingComplex: {
15850 if (!Visit(
E->getSubExpr()))
15854 Info.Ctx.getLangOpts());
15858 Result.makeComplexFloat();
15860 To, Result.FloatReal) &&
15862 To, Result.FloatImag);
15866 llvm_unreachable(
"unknown cast resulting in complex value");
15870 APFloat &ResR, APFloat &ResI) {
15876 APFloat AC = A *
C;
15877 APFloat BD = B *
D;
15878 APFloat AD = A *
D;
15879 APFloat BC = B *
C;
15882 if (ResR.isNaN() && ResI.isNaN()) {
15883 bool Recalc =
false;
15884 if (A.isInfinity() || B.isInfinity()) {
15885 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
15887 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
15890 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
15892 D = APFloat::copySign(APFloat(
D.getSemantics()),
D);
15895 if (
C.isInfinity() ||
D.isInfinity()) {
15896 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
15898 D = APFloat::copySign(APFloat(
D.getSemantics(),
D.isInfinity() ? 1 : 0),
15901 A = APFloat::copySign(APFloat(A.getSemantics()), A);
15903 B = APFloat::copySign(APFloat(B.getSemantics()), B);
15906 if (!Recalc && (AC.isInfinity() || BD.isInfinity() || AD.isInfinity() ||
15907 BC.isInfinity())) {
15909 A = APFloat::copySign(APFloat(A.getSemantics()), A);
15911 B = APFloat::copySign(APFloat(B.getSemantics()), B);
15913 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
15915 D = APFloat::copySign(APFloat(
D.getSemantics()),
D);
15919 ResR = APFloat::getInf(A.getSemantics()) * (A *
C - B *
D);
15920 ResI = APFloat::getInf(A.getSemantics()) * (A *
D + B *
C);
15926 APFloat &ResR, APFloat &ResI) {
15933 APFloat MaxCD = maxnum(
abs(
C),
abs(
D));
15934 if (MaxCD.isFinite()) {
15935 DenomLogB =
ilogb(MaxCD);
15936 C =
scalbn(
C, -DenomLogB, APFloat::rmNearestTiesToEven);
15937 D =
scalbn(
D, -DenomLogB, APFloat::rmNearestTiesToEven);
15939 APFloat Denom =
C *
C +
D *
D;
15941 scalbn((A *
C + B *
D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
15943 scalbn((B *
C - A *
D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
15944 if (ResR.isNaN() && ResI.isNaN()) {
15945 if (Denom.isPosZero() && (!A.isNaN() || !B.isNaN())) {
15946 ResR = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * A;
15947 ResI = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * B;
15948 }
else if ((A.isInfinity() || B.isInfinity()) &&
C.isFinite() &&
15950 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
15952 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
15954 ResR = APFloat::getInf(ResR.getSemantics()) * (A *
C + B *
D);
15955 ResI = APFloat::getInf(ResI.getSemantics()) * (B *
C - A *
D);
15956 }
else if (MaxCD.isInfinity() && A.isFinite() && B.isFinite()) {
15957 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
15959 D = APFloat::copySign(APFloat(
D.getSemantics(),
D.isInfinity() ? 1 : 0),
15961 ResR = APFloat::getZero(ResR.getSemantics()) * (A *
C + B *
D);
15962 ResI = APFloat::getZero(ResI.getSemantics()) * (B *
C - A *
D);
15967bool ComplexExprEvaluator::VisitBinaryOperator(
const BinaryOperator *
E) {
15968 if (
E->isPtrMemOp() ||
E->isAssignmentOp() ||
E->getOpcode() == BO_Comma)
15969 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
15973 bool LHSReal =
false, RHSReal =
false;
15978 APFloat &Real = Result.FloatReal;
15981 Result.makeComplexFloat();
15982 Result.FloatImag =
APFloat(Real.getSemantics());
15985 LHSOK = Visit(
E->getLHS());
15987 if (!LHSOK && !Info.noteFailure())
15993 APFloat &Real = RHS.FloatReal;
15996 RHS.makeComplexFloat();
15997 RHS.FloatImag =
APFloat(Real.getSemantics());
16001 assert(!(LHSReal && RHSReal) &&
16002 "Cannot have both operands of a complex operation be real.");
16003 switch (
E->getOpcode()) {
16004 default:
return Error(
E);
16006 if (Result.isComplexFloat()) {
16007 Result.getComplexFloatReal().
add(RHS.getComplexFloatReal(),
16008 APFloat::rmNearestTiesToEven);
16010 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
16012 Result.getComplexFloatImag().
add(RHS.getComplexFloatImag(),
16013 APFloat::rmNearestTiesToEven);
16015 Result.getComplexIntReal() += RHS.getComplexIntReal();
16016 Result.getComplexIntImag() += RHS.getComplexIntImag();
16020 if (Result.isComplexFloat()) {
16021 Result.getComplexFloatReal().subtract(RHS.getComplexFloatReal(),
16022 APFloat::rmNearestTiesToEven);
16024 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
16025 Result.getComplexFloatImag().changeSign();
16026 }
else if (!RHSReal) {
16027 Result.getComplexFloatImag().subtract(RHS.getComplexFloatImag(),
16028 APFloat::rmNearestTiesToEven);
16031 Result.getComplexIntReal() -= RHS.getComplexIntReal();
16032 Result.getComplexIntImag() -= RHS.getComplexIntImag();
16036 if (Result.isComplexFloat()) {
16041 ComplexValue LHS = Result;
16042 APFloat &A = LHS.getComplexFloatReal();
16043 APFloat &B = LHS.getComplexFloatImag();
16044 APFloat &
C = RHS.getComplexFloatReal();
16045 APFloat &
D = RHS.getComplexFloatImag();
16046 APFloat &ResR = Result.getComplexFloatReal();
16047 APFloat &ResI = Result.getComplexFloatImag();
16049 assert(!RHSReal &&
"Cannot have two real operands for a complex op!");
16057 }
else if (RHSReal) {
16069 ComplexValue LHS = Result;
16070 Result.getComplexIntReal() =
16071 (LHS.getComplexIntReal() * RHS.getComplexIntReal() -
16072 LHS.getComplexIntImag() * RHS.getComplexIntImag());
16073 Result.getComplexIntImag() =
16074 (LHS.getComplexIntReal() * RHS.getComplexIntImag() +
16075 LHS.getComplexIntImag() * RHS.getComplexIntReal());
16079 if (Result.isComplexFloat()) {
16084 ComplexValue LHS = Result;
16085 APFloat &A = LHS.getComplexFloatReal();
16086 APFloat &B = LHS.getComplexFloatImag();
16087 APFloat &
C = RHS.getComplexFloatReal();
16088 APFloat &
D = RHS.getComplexFloatImag();
16089 APFloat &ResR = Result.getComplexFloatReal();
16090 APFloat &ResI = Result.getComplexFloatImag();
16102 B = APFloat::getZero(A.getSemantics());
16107 ComplexValue LHS = Result;
16108 APSInt Den = RHS.getComplexIntReal() * RHS.getComplexIntReal() +
16109 RHS.getComplexIntImag() * RHS.getComplexIntImag();
16111 return Error(
E, diag::note_expr_divide_by_zero);
16113 Result.getComplexIntReal() =
16114 (LHS.getComplexIntReal() * RHS.getComplexIntReal() +
16115 LHS.getComplexIntImag() * RHS.getComplexIntImag()) / Den;
16116 Result.getComplexIntImag() =
16117 (LHS.getComplexIntImag() * RHS.getComplexIntReal() -
16118 LHS.getComplexIntReal() * RHS.getComplexIntImag()) / Den;
16126bool ComplexExprEvaluator::VisitUnaryOperator(
const UnaryOperator *
E) {
16128 if (!Visit(
E->getSubExpr()))
16131 switch (
E->getOpcode()) {
16140 if (Result.isComplexFloat()) {
16141 Result.getComplexFloatReal().changeSign();
16142 Result.getComplexFloatImag().changeSign();
16145 Result.getComplexIntReal() = -Result.getComplexIntReal();
16146 Result.getComplexIntImag() = -Result.getComplexIntImag();
16150 if (Result.isComplexFloat())
16151 Result.getComplexFloatImag().changeSign();
16153 Result.getComplexIntImag() = -Result.getComplexIntImag();
16158bool ComplexExprEvaluator::VisitInitListExpr(
const InitListExpr *
E) {
16159 if (
E->getNumInits() == 2) {
16161 Result.makeComplexFloat();
16167 Result.makeComplexInt();
16175 return ExprEvaluatorBaseTy::VisitInitListExpr(
E);
16178bool ComplexExprEvaluator::VisitCallExpr(
const CallExpr *
E) {
16179 if (!IsConstantEvaluatedBuiltinCall(
E))
16180 return ExprEvaluatorBaseTy::VisitCallExpr(
E);
16182 switch (
E->getBuiltinCallee()) {
16183 case Builtin::BI__builtin_complex:
16184 Result.makeComplexFloat();
16202class AtomicExprEvaluator :
16203 public ExprEvaluatorBase<AtomicExprEvaluator> {
16204 const LValue *
This;
16207 AtomicExprEvaluator(EvalInfo &Info,
const LValue *This,
APValue &Result)
16208 : ExprEvaluatorBaseTy(Info),
This(
This), Result(Result) {}
16215 bool ZeroInitialization(
const Expr *
E) {
16224 bool VisitCastExpr(
const CastExpr *
E) {
16225 switch (
E->getCastKind()) {
16227 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
16228 case CK_NullToPointer:
16229 VisitIgnoredValue(
E->getSubExpr());
16230 return ZeroInitialization(
E);
16231 case CK_NonAtomicToAtomic:
16233 :
Evaluate(Result, Info,
E->getSubExpr());
16243 return AtomicExprEvaluator(Info, This, Result).Visit(
E);
16252class VoidExprEvaluator
16253 :
public ExprEvaluatorBase<VoidExprEvaluator> {
16255 VoidExprEvaluator(EvalInfo &Info) : ExprEvaluatorBaseTy(Info) {}
16259 bool ZeroInitialization(
const Expr *
E) {
return true; }
16261 bool VisitCastExpr(
const CastExpr *
E) {
16262 switch (
E->getCastKind()) {
16264 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
16266 VisitIgnoredValue(
E->getSubExpr());
16271 bool VisitCallExpr(
const CallExpr *
E) {
16272 if (!IsConstantEvaluatedBuiltinCall(
E))
16273 return ExprEvaluatorBaseTy::VisitCallExpr(
E);
16275 switch (
E->getBuiltinCallee()) {
16276 case Builtin::BI__assume:
16277 case Builtin::BI__builtin_assume:
16281 case Builtin::BI__builtin_operator_delete:
16293bool VoidExprEvaluator::VisitCXXDeleteExpr(
const CXXDeleteExpr *
E) {
16295 if (Info.SpeculativeEvaluationDepth)
16299 if (!OperatorDelete->isReplaceableGlobalAllocationFunction()) {
16300 Info.FFDiag(
E, diag::note_constexpr_new_non_replaceable)
16301 << isa<CXXMethodDecl>(OperatorDelete) << OperatorDelete;
16305 const Expr *Arg =
E->getArgument();
16310 if (
Pointer.Designator.Invalid)
16314 if (
Pointer.isNullPointer()) {
16318 if (!Info.getLangOpts().CPlusPlus20)
16319 Info.CCEDiag(
E, diag::note_constexpr_new);
16324 Info,
E,
Pointer,
E->isArrayForm() ? DynAlloc::ArrayNew : DynAlloc::New);
16331 if (!
E->isArrayForm() &&
Pointer.Designator.Entries.size() != 0 &&
16333 Info.FFDiag(
E, diag::note_constexpr_delete_base_nonvirt_dtor)
16340 if (!
E->isArrayForm() && !
E->isGlobalDelete()) {
16342 if (VirtualDelete &&
16344 Info.FFDiag(
E, diag::note_constexpr_new_non_replaceable)
16345 << isa<CXXMethodDecl>(VirtualDelete) << VirtualDelete;
16351 (*Alloc)->Value, AllocType))
16359 Info.FFDiag(
E, diag::note_constexpr_double_delete);
16369 return VoidExprEvaluator(Info).Visit(
E);
16385 LV.moveInto(Result);
16390 if (!IntExprEvaluator(Info, Result).Visit(
E))
16396 LV.moveInto(Result);
16398 llvm::APFloat F(0.0);
16406 C.moveInto(Result);
16408 if (!FixedPointExprEvaluator(Info, Result).Visit(
E))
return false;
16413 P.moveInto(Result);
16418 Info.CurrentCall->createTemporary(
E,
T, ScopeKind::FullExpression, LV);
16425 Info.CurrentCall->createTemporary(
E,
T, ScopeKind::FullExpression, LV);
16430 if (!Info.getLangOpts().CPlusPlus11)
16431 Info.CCEDiag(
E, diag::note_constexpr_nonliteral)
16436 QualType Unqual =
T.getAtomicUnqualifiedType();
16440 E, Unqual, ScopeKind::FullExpression, LV);
16448 }
else if (Info.getLangOpts().CPlusPlus11) {
16449 Info.FFDiag(
E, diag::note_constexpr_nonliteral) <<
E->
getType();
16452 Info.FFDiag(
E, diag::note_invalid_subexpr_in_const_expr);
16463 const Expr *
E,
bool AllowNonLiteralTypes) {
16478 QualType Unqual =
T.getAtomicUnqualifiedType();
16499 if (Info.EnableNewConstInterp) {
16500 if (!Info.Ctx.getInterpContext().evaluateAsRValue(Info,
E, Result))
16503 ConstantExprKind::Normal);
16512 LV.setFrom(Info.Ctx, Result);
16519 ConstantExprKind::Normal) &&
16527 if (
const auto *L = dyn_cast<IntegerLiteral>(Exp)) {
16529 L->getType()->isUnsignedIntegerType()));
16534 if (
const auto *L = dyn_cast<CXXBoolLiteralExpr>(Exp)) {
16540 if (
const auto *FL = dyn_cast<FloatingLiteral>(Exp)) {
16541 Result.Val =
APValue(FL->getValue());
16546 if (
const auto *L = dyn_cast<CharacterLiteral>(Exp)) {
16552 if (
const auto *CE = dyn_cast<ConstantExpr>(Exp)) {
16553 if (CE->hasAPValueResult()) {
16554 APValue APV = CE->getAPValueResult();
16556 Result.Val = std::move(APV);
16632 bool InConstantContext)
const {
16633 assert(!isValueDependent() &&
16634 "Expression evaluator can't be called on a dependent expression.");
16635 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsRValue");
16636 EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
16637 Info.InConstantContext = InConstantContext;
16638 return ::EvaluateAsRValue(
this, Result, Ctx, Info);
16642 bool InConstantContext)
const {
16643 assert(!isValueDependent() &&
16644 "Expression evaluator can't be called on a dependent expression.");
16645 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsBooleanCondition");
16653 bool InConstantContext)
const {
16654 assert(!isValueDependent() &&
16655 "Expression evaluator can't be called on a dependent expression.");
16656 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsInt");
16657 EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
16658 Info.InConstantContext = InConstantContext;
16659 return ::EvaluateAsInt(
this, Result, Ctx, AllowSideEffects, Info);
16664 bool InConstantContext)
const {
16665 assert(!isValueDependent() &&
16666 "Expression evaluator can't be called on a dependent expression.");
16667 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFixedPoint");
16668 EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
16669 Info.InConstantContext = InConstantContext;
16670 return ::EvaluateAsFixedPoint(
this, Result, Ctx, AllowSideEffects, Info);
16675 bool InConstantContext)
const {
16676 assert(!isValueDependent() &&
16677 "Expression evaluator can't be called on a dependent expression.");
16679 if (!getType()->isRealFloatingType())
16682 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFloat");
16694 bool InConstantContext)
const {
16695 assert(!isValueDependent() &&
16696 "Expression evaluator can't be called on a dependent expression.");
16698 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsLValue");
16699 EvalInfo Info(Ctx, Result, EvalInfo::EM_ConstantFold);
16700 Info.InConstantContext = InConstantContext;
16703 if (!
EvaluateLValue(
this, LV, Info) || !Info.discardCleanups() ||
16704 Result.HasSideEffects ||
16707 ConstantExprKind::Normal, CheckedTemps))
16710 LV.moveInto(Result.Val);
16717 bool IsConstantDestruction) {
16718 EvalInfo Info(Ctx, EStatus,
16719 IsConstantDestruction ? EvalInfo::EM_ConstantExpression
16720 : EvalInfo::EM_ConstantFold);
16721 Info.setEvaluatingDecl(
Base, DestroyedValue,
16722 EvalInfo::EvaluatingDeclKind::Dtor);
16723 Info.InConstantContext = IsConstantDestruction;
16732 if (!Info.discardCleanups())
16733 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
16740 assert(!isValueDependent() &&
16741 "Expression evaluator can't be called on a dependent expression.");
16746 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsConstantExpr");
16747 EvalInfo::EvaluationMode EM = EvalInfo::EM_ConstantExpression;
16748 EvalInfo Info(Ctx, Result, EM);
16749 Info.InConstantContext =
true;
16751 if (Info.EnableNewConstInterp) {
16752 if (!Info.Ctx.getInterpContext().evaluate(Info,
this, Result.Val, Kind))
16755 getStorageType(Ctx,
this), Result.Val, Kind);
16760 if (Kind == ConstantExprKind::ClassTemplateArgument)
16768 Info.setEvaluatingDecl(
Base, Result.Val);
16770 if (Info.EnableNewConstInterp) {
16771 if (!Info.Ctx.getInterpContext().evaluateAsRValue(Info,
this, Result.Val))
16780 FullExpressionRAII
Scope(Info);
16782 Result.HasSideEffects || !
Scope.destroy())
16785 if (!Info.discardCleanups())
16786 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
16797 if (Kind == ConstantExprKind::ClassTemplateArgument &&
16800 Result.HasSideEffects)) {
16812 bool IsConstantInitialization)
const {
16813 assert(!isValueDependent() &&
16814 "Expression evaluator can't be called on a dependent expression.");
16816 llvm::TimeTraceScope TimeScope(
"EvaluateAsInitializer", [&] {
16818 llvm::raw_string_ostream OS(Name);
16824 EStatus.
Diag = &Notes;
16826 EvalInfo Info(Ctx, EStatus,
16827 (IsConstantInitialization &&
16829 ? EvalInfo::EM_ConstantExpression
16830 : EvalInfo::EM_ConstantFold);
16831 Info.setEvaluatingDecl(VD,
Value);
16832 Info.InConstantContext = IsConstantInitialization;
16837 if (Info.EnableNewConstInterp) {
16838 auto &InterpCtx =
const_cast<ASTContext &
>(Ctx).getInterpContext();
16839 if (!InterpCtx.evaluateAsInitializer(Info, VD,
Value))
16843 ConstantExprKind::Normal);
16858 FullExpressionRAII
Scope(Info);
16861 EStatus.HasSideEffects)
16867 Info.performLifetimeExtension();
16869 if (!Info.discardCleanups())
16870 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
16874 ConstantExprKind::Normal) &&
16881 EStatus.
Diag = &Notes;
16885 bool IsConstantDestruction = hasConstantInitialization();
16891 if (getEvaluatedValue() && !getEvaluatedValue()->isAbsent())
16892 DestroyedValue = *getEvaluatedValue();
16897 getType(), getLocation(), EStatus,
16898 IsConstantDestruction) ||
16902 ensureEvaluatedStmt()->HasConstantDestruction =
true;
16909 assert(!isValueDependent() &&
16910 "Expression evaluator can't be called on a dependent expression.");
16919 assert(!isValueDependent() &&
16920 "Expression evaluator can't be called on a dependent expression.");
16922 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstInt");
16925 EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
16926 Info.InConstantContext =
true;
16930 assert(Result &&
"Could not evaluate expression");
16931 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
16933 return EVResult.Val.getInt();
16938 assert(!isValueDependent() &&
16939 "Expression evaluator can't be called on a dependent expression.");
16941 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstIntCheckOverflow");
16944 EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
16945 Info.InConstantContext =
true;
16946 Info.CheckingForUndefinedBehavior =
true;
16950 assert(Result &&
"Could not evaluate expression");
16951 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
16953 return EVResult.Val.getInt();
16957 assert(!isValueDependent() &&
16958 "Expression evaluator can't be called on a dependent expression.");
16960 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateForOverflow");
16964 EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
16965 Info.CheckingForUndefinedBehavior =
true;
16998 IK_ICEIfUnevaluated,
17014static ICEDiag
Worst(ICEDiag A, ICEDiag B) {
return A.Kind >= B.Kind ? A : B; }
17019 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
17021 Info.InConstantContext =
true;
17035#define ABSTRACT_STMT(Node)
17036#define STMT(Node, Base) case Expr::Node##Class:
17037#define EXPR(Node, Base)
17038#include "clang/AST/StmtNodes.inc"
17039 case Expr::PredefinedExprClass:
17040 case Expr::FloatingLiteralClass:
17041 case Expr::ImaginaryLiteralClass:
17042 case Expr::StringLiteralClass:
17043 case Expr::ArraySubscriptExprClass:
17044 case Expr::MatrixSubscriptExprClass:
17045 case Expr::ArraySectionExprClass:
17046 case Expr::OMPArrayShapingExprClass:
17047 case Expr::OMPIteratorExprClass:
17048 case Expr::MemberExprClass:
17049 case Expr::CompoundAssignOperatorClass:
17050 case Expr::CompoundLiteralExprClass:
17051 case Expr::ExtVectorElementExprClass:
17052 case Expr::DesignatedInitExprClass:
17053 case Expr::ArrayInitLoopExprClass:
17054 case Expr::ArrayInitIndexExprClass:
17055 case Expr::NoInitExprClass:
17056 case Expr::DesignatedInitUpdateExprClass:
17057 case Expr::ImplicitValueInitExprClass:
17058 case Expr::ParenListExprClass:
17059 case Expr::VAArgExprClass:
17060 case Expr::AddrLabelExprClass:
17061 case Expr::StmtExprClass:
17062 case Expr::CXXMemberCallExprClass:
17063 case Expr::CUDAKernelCallExprClass:
17064 case Expr::CXXAddrspaceCastExprClass:
17065 case Expr::CXXDynamicCastExprClass:
17066 case Expr::CXXTypeidExprClass:
17067 case Expr::CXXUuidofExprClass:
17068 case Expr::MSPropertyRefExprClass:
17069 case Expr::MSPropertySubscriptExprClass:
17070 case Expr::CXXNullPtrLiteralExprClass:
17071 case Expr::UserDefinedLiteralClass:
17072 case Expr::CXXThisExprClass:
17073 case Expr::CXXThrowExprClass:
17074 case Expr::CXXNewExprClass:
17075 case Expr::CXXDeleteExprClass:
17076 case Expr::CXXPseudoDestructorExprClass:
17077 case Expr::UnresolvedLookupExprClass:
17078 case Expr::TypoExprClass:
17079 case Expr::RecoveryExprClass:
17080 case Expr::DependentScopeDeclRefExprClass:
17081 case Expr::CXXConstructExprClass:
17082 case Expr::CXXInheritedCtorInitExprClass:
17083 case Expr::CXXStdInitializerListExprClass:
17084 case Expr::CXXBindTemporaryExprClass:
17085 case Expr::ExprWithCleanupsClass:
17086 case Expr::CXXTemporaryObjectExprClass:
17087 case Expr::CXXUnresolvedConstructExprClass:
17088 case Expr::CXXDependentScopeMemberExprClass:
17089 case Expr::UnresolvedMemberExprClass:
17090 case Expr::ObjCStringLiteralClass:
17091 case Expr::ObjCBoxedExprClass:
17092 case Expr::ObjCArrayLiteralClass:
17093 case Expr::ObjCDictionaryLiteralClass:
17094 case Expr::ObjCEncodeExprClass:
17095 case Expr::ObjCMessageExprClass:
17096 case Expr::ObjCSelectorExprClass:
17097 case Expr::ObjCProtocolExprClass:
17098 case Expr::ObjCIvarRefExprClass:
17099 case Expr::ObjCPropertyRefExprClass:
17100 case Expr::ObjCSubscriptRefExprClass:
17101 case Expr::ObjCIsaExprClass:
17102 case Expr::ObjCAvailabilityCheckExprClass:
17103 case Expr::ShuffleVectorExprClass:
17104 case Expr::ConvertVectorExprClass:
17105 case Expr::BlockExprClass:
17106 case Expr::NoStmtClass:
17107 case Expr::OpaqueValueExprClass:
17108 case Expr::PackExpansionExprClass:
17109 case Expr::SubstNonTypeTemplateParmPackExprClass:
17110 case Expr::FunctionParmPackExprClass:
17111 case Expr::AsTypeExprClass:
17112 case Expr::ObjCIndirectCopyRestoreExprClass:
17113 case Expr::MaterializeTemporaryExprClass:
17114 case Expr::PseudoObjectExprClass:
17115 case Expr::AtomicExprClass:
17116 case Expr::LambdaExprClass:
17117 case Expr::CXXFoldExprClass:
17118 case Expr::CoawaitExprClass:
17119 case Expr::DependentCoawaitExprClass:
17120 case Expr::CoyieldExprClass:
17121 case Expr::SYCLUniqueStableNameExprClass:
17122 case Expr::CXXParenListInitExprClass:
17123 case Expr::HLSLOutArgExprClass:
17126 case Expr::InitListExprClass: {
17132 if (cast<InitListExpr>(
E)->getNumInits() == 1)
17133 return CheckICE(cast<InitListExpr>(
E)->getInit(0), Ctx);
17137 case Expr::SizeOfPackExprClass:
17138 case Expr::GNUNullExprClass:
17139 case Expr::SourceLocExprClass:
17140 case Expr::EmbedExprClass:
17141 case Expr::OpenACCAsteriskSizeExprClass:
17144 case Expr::PackIndexingExprClass:
17145 return CheckICE(cast<PackIndexingExpr>(
E)->getSelectedExpr(), Ctx);
17147 case Expr::SubstNonTypeTemplateParmExprClass:
17149 CheckICE(cast<SubstNonTypeTemplateParmExpr>(
E)->getReplacement(), Ctx);
17151 case Expr::ConstantExprClass:
17152 return CheckICE(cast<ConstantExpr>(
E)->getSubExpr(), Ctx);
17154 case Expr::ParenExprClass:
17155 return CheckICE(cast<ParenExpr>(
E)->getSubExpr(), Ctx);
17156 case Expr::GenericSelectionExprClass:
17157 return CheckICE(cast<GenericSelectionExpr>(
E)->getResultExpr(), Ctx);
17158 case Expr::IntegerLiteralClass:
17159 case Expr::FixedPointLiteralClass:
17160 case Expr::CharacterLiteralClass:
17161 case Expr::ObjCBoolLiteralExprClass:
17162 case Expr::CXXBoolLiteralExprClass:
17163 case Expr::CXXScalarValueInitExprClass:
17164 case Expr::TypeTraitExprClass:
17165 case Expr::ConceptSpecializationExprClass:
17166 case Expr::RequiresExprClass:
17167 case Expr::ArrayTypeTraitExprClass:
17168 case Expr::ExpressionTraitExprClass:
17169 case Expr::CXXNoexceptExprClass:
17171 case Expr::CallExprClass:
17172 case Expr::CXXOperatorCallExprClass: {
17176 const CallExpr *CE = cast<CallExpr>(
E);
17181 case Expr::CXXRewrittenBinaryOperatorClass:
17182 return CheckICE(cast<CXXRewrittenBinaryOperator>(
E)->getSemanticForm(),
17184 case Expr::DeclRefExprClass: {
17185 const NamedDecl *
D = cast<DeclRefExpr>(
E)->getDecl();
17186 if (isa<EnumConstantDecl>(
D))
17198 const VarDecl *VD = dyn_cast<VarDecl>(
D);
17205 case Expr::UnaryOperatorClass: {
17228 llvm_unreachable(
"invalid unary operator class");
17230 case Expr::OffsetOfExprClass: {
17239 case Expr::UnaryExprOrTypeTraitExprClass: {
17241 if ((Exp->
getKind() == UETT_SizeOf) &&
17246 case Expr::BinaryOperatorClass: {
17291 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE) {
17294 return ICEDiag(IK_ICEIfUnevaluated,
E->
getBeginLoc());
17295 if (REval.isSigned() && REval.isAllOnes()) {
17297 if (LEval.isMinSignedValue())
17298 return ICEDiag(IK_ICEIfUnevaluated,
E->
getBeginLoc());
17306 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE)
17307 return ICEDiag(IK_ICEIfUnevaluated,
E->
getBeginLoc());
17313 return Worst(LHSResult, RHSResult);
17319 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICEIfUnevaluated) {
17329 return Worst(LHSResult, RHSResult);
17332 llvm_unreachable(
"invalid binary operator kind");
17334 case Expr::ImplicitCastExprClass:
17335 case Expr::CStyleCastExprClass:
17336 case Expr::CXXFunctionalCastExprClass:
17337 case Expr::CXXStaticCastExprClass:
17338 case Expr::CXXReinterpretCastExprClass:
17339 case Expr::CXXConstCastExprClass:
17340 case Expr::ObjCBridgedCastExprClass: {
17341 const Expr *SubExpr = cast<CastExpr>(
E)->getSubExpr();
17342 if (isa<ExplicitCastExpr>(
E)) {
17347 APSInt IgnoredVal(DestWidth, !DestSigned);
17352 if (FL->getValue().convertToInteger(IgnoredVal,
17353 llvm::APFloat::rmTowardZero,
17354 &Ignored) & APFloat::opInvalidOp)
17359 switch (cast<CastExpr>(
E)->getCastKind()) {
17360 case CK_LValueToRValue:
17361 case CK_AtomicToNonAtomic:
17362 case CK_NonAtomicToAtomic:
17364 case CK_IntegralToBoolean:
17365 case CK_IntegralCast:
17371 case Expr::BinaryConditionalOperatorClass: {
17374 if (CommonResult.Kind == IK_NotICE)
return CommonResult;
17376 if (FalseResult.Kind == IK_NotICE)
return FalseResult;
17377 if (CommonResult.Kind == IK_ICEIfUnevaluated)
return CommonResult;
17378 if (FalseResult.Kind == IK_ICEIfUnevaluated &&
17380 return FalseResult;
17382 case Expr::ConditionalOperatorClass: {
17390 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
17393 if (CondResult.Kind == IK_NotICE)
17399 if (TrueResult.Kind == IK_NotICE)
17401 if (FalseResult.Kind == IK_NotICE)
17402 return FalseResult;
17403 if (CondResult.Kind == IK_ICEIfUnevaluated)
17405 if (TrueResult.Kind == IK_ICE && FalseResult.Kind == IK_ICE)
17411 return FalseResult;
17414 case Expr::CXXDefaultArgExprClass:
17415 return CheckICE(cast<CXXDefaultArgExpr>(
E)->getExpr(), Ctx);
17416 case Expr::CXXDefaultInitExprClass:
17417 return CheckICE(cast<CXXDefaultInitExpr>(
E)->getExpr(), Ctx);
17418 case Expr::ChooseExprClass: {
17419 return CheckICE(cast<ChooseExpr>(
E)->getChosenSubExpr(), Ctx);
17421 case Expr::BuiltinBitCastExprClass: {
17422 if (!checkBitCastConstexprEligibility(
nullptr, Ctx, cast<CastExpr>(
E)))
17424 return CheckICE(cast<CastExpr>(
E)->getSubExpr(), Ctx);
17428 llvm_unreachable(
"Invalid StmtClass!");
17434 llvm::APSInt *
Value,
17445 if (!Result.isInt()) {
17456 assert(!isValueDependent() &&
17457 "Expression evaluator can't be called on a dependent expression.");
17459 ExprTimeTraceScope TimeScope(
this, Ctx,
"isIntegerConstantExpr");
17465 if (
D.
Kind != IK_ICE) {
17472std::optional<llvm::APSInt>
17474 if (isValueDependent()) {
17476 return std::nullopt;
17484 return std::nullopt;
17487 if (!isIntegerConstantExpr(Ctx,
Loc))
17488 return std::nullopt;
17496 EvalInfo Info(Ctx, Status, EvalInfo::EM_IgnoreSideEffects);
17497 Info.InConstantContext =
true;
17500 llvm_unreachable(
"ICE cannot be evaluated!");
17506 assert(!isValueDependent() &&
17507 "Expression evaluator can't be called on a dependent expression.");
17509 return CheckICE(
this, Ctx).Kind == IK_ICE;
17514 assert(!isValueDependent() &&
17515 "Expression evaluator can't be called on a dependent expression.");
17524 Status.Diag = &Diags;
17525 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
17532 Info.discardCleanups() && !Status.HasSideEffects;
17534 if (!Diags.empty()) {
17535 IsConstExpr =
false;
17536 if (
Loc) *
Loc = Diags[0].first;
17537 }
else if (!IsConstExpr) {
17539 if (
Loc) *
Loc = getExprLoc();
17542 return IsConstExpr;
17548 const Expr *This)
const {
17549 assert(!isValueDependent() &&
17550 "Expression evaluator can't be called on a dependent expression.");
17552 llvm::TimeTraceScope TimeScope(
"EvaluateWithSubstitution", [&] {
17554 llvm::raw_string_ostream OS(Name);
17561 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpressionUnevaluated);
17562 Info.InConstantContext =
true;
17565 const LValue *ThisPtr =
nullptr;
17568 auto *MD = dyn_cast<CXXMethodDecl>(Callee);
17569 assert(MD &&
"Don't provide `this` for non-methods.");
17570 assert(MD->isImplicitObjectMemberFunction() &&
17571 "Don't provide `this` for methods without an implicit object.");
17573 if (!This->isValueDependent() &&
17575 !Info.EvalStatus.HasSideEffects)
17576 ThisPtr = &ThisVal;
17580 Info.EvalStatus.HasSideEffects =
false;
17583 CallRef
Call = Info.CurrentCall->createCall(Callee);
17586 unsigned Idx = I - Args.begin();
17587 if (Idx >= Callee->getNumParams())
17589 const ParmVarDecl *PVD = Callee->getParamDecl(Idx);
17590 if ((*I)->isValueDependent() ||
17592 Info.EvalStatus.HasSideEffects) {
17594 if (
APValue *Slot = Info.getParamSlot(
Call, PVD))
17600 Info.EvalStatus.HasSideEffects =
false;
17605 Info.discardCleanups();
17606 Info.EvalStatus.HasSideEffects =
false;
17609 CallStackFrame Frame(Info, Callee->getLocation(), Callee, ThisPtr, This,
17612 FullExpressionRAII
Scope(Info);
17614 !Info.EvalStatus.HasSideEffects;
17626 llvm::TimeTraceScope TimeScope(
"isPotentialConstantExpr", [&] {
17628 llvm::raw_string_ostream OS(Name);
17635 Status.Diag = &Diags;
17637 EvalInfo Info(FD->
getASTContext(), Status, EvalInfo::EM_ConstantExpression);
17638 Info.InConstantContext =
true;
17639 Info.CheckingPotentialConstantExpression =
true;
17642 if (Info.EnableNewConstInterp) {
17643 Info.Ctx.getInterpContext().isPotentialConstantExpr(Info, FD);
17644 return Diags.empty();
17654 This.set({&VIE, Info.CurrentCall->Index});
17662 Info.setEvaluatingDecl(This.getLValueBase(), Scratch);
17668 &VIE, Args, CallRef(), FD->
getBody(), Info, Scratch,
17672 return Diags.empty();
17680 "Expression evaluator can't be called on a dependent expression.");
17683 Status.Diag = &Diags;
17686 EvalInfo::EM_ConstantExpressionUnevaluated);
17687 Info.InConstantContext =
true;
17688 Info.CheckingPotentialConstantExpression =
true;
17692 nullptr, CallRef());
17696 return Diags.empty();
17700 unsigned Type)
const {
17701 if (!getType()->isPointerType())
17705 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantFold);
17710 EvalInfo &Info, std::string *StringResult) {
17722 if (
const StringLiteral *S = dyn_cast_or_null<StringLiteral>(
17723 String.getLValueBase().dyn_cast<
const Expr *>())) {
17724 StringRef Str = S->getBytes();
17725 int64_t Off = String.Offset.getQuantity();
17726 if (Off >= 0 && (uint64_t)Off <= (uint64_t)Str.size() &&
17727 S->getCharByteWidth() == 1 &&
17729 Info.Ctx.hasSameUnqualifiedType(CharTy, Info.Ctx.CharTy)) {
17730 Str = Str.substr(Off);
17732 StringRef::size_type Pos = Str.find(0);
17733 if (Pos != StringRef::npos)
17734 Str = Str.substr(0, Pos);
17736 Result = Str.size();
17738 *StringResult = Str;
17746 for (uint64_t Strlen = 0; ; ++Strlen) {
17754 }
else if (StringResult)
17755 StringResult->push_back(Char.
getInt().getExtValue());
17763 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantFold);
17765 std::string StringResult;
17768 return StringResult;
17773 const Expr *SizeExpression,
17777 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
17778 Info.InConstantContext =
true;
17780 FullExpressionRAII
Scope(Info);
17785 uint64_t Size = SizeValue.getZExtValue();
17791 for (uint64_t I = 0; I < Size; ++I) {
17798 Result.push_back(
static_cast<char>(
C.getExtValue()));
17802 if (!
Scope.destroy())
17813 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantFold);
17818struct IsWithinLifetimeHandler {
17820 static constexpr AccessKinds AccessKind = AccessKinds::AK_IsWithinLifetime;
17821 using result_type = std::optional<bool>;
17822 std::optional<bool> failed() {
return std::nullopt; }
17823 template <
typename T>
17824 std::optional<bool> found(
T &Subobj,
QualType SubobjType) {
17829std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &IEE,
17831 EvalInfo &Info = IEE.Info;
17836 if (!Info.InConstantContext)
17837 return std::nullopt;
17838 assert(
E->getBuiltinCallee() == Builtin::BI__builtin_is_within_lifetime);
17839 const Expr *Arg =
E->getArg(0);
17841 return std::nullopt;
17844 return std::nullopt;
17847 bool CalledFromStd =
false;
17848 const auto *
Callee = Info.CurrentCall->getCallee();
17849 if (Callee &&
Callee->isInStdNamespace()) {
17853 Info.CCEDiag(CalledFromStd ? Info.CurrentCall->getCallRange().getBegin()
17855 diag::err_invalid_is_within_lifetime)
17856 << (CalledFromStd ?
"std::is_within_lifetime"
17857 :
"__builtin_is_within_lifetime")
17859 return std::nullopt;
17869 if (Val.isNullPointer() || Val.getLValueBase().isNull())
17871 QualType T = Val.getLValueBase().getType();
17873 "Pointers to functions should have been typed as function pointers "
17874 "which would have been rejected earlier");
17877 if (Val.getLValueDesignator().isOnePastTheEnd())
17879 assert(Val.getLValueDesignator().isValidSubobject() &&
17880 "Unchecked case for valid subobject");
17884 CompleteObject CO =
17888 if (Info.EvaluatingDeclValue && CO.Value == Info.EvaluatingDeclValue)
17893 IsWithinLifetimeHandler handler{Info};
17894 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::@1724::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)